mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 23:18:47 +00:00
Compare commits
212 Commits
ben/shell-
...
fix-test-h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ab5ff37d8 | ||
|
|
7b566e2cfc | ||
|
|
6ae4158762 | ||
|
|
8dc95b041a | ||
|
|
211fd4fa06 | ||
|
|
10665821c4 | ||
|
|
a3585ff961 | ||
|
|
2aeff10a85 | ||
|
|
f2c8e63ae1 | ||
|
|
40bfda0f87 | ||
|
|
9888570456 | ||
|
|
a1690cd708 | ||
|
|
e602e2b887 | ||
|
|
eae2d61f12 | ||
|
|
8e246e1e67 | ||
|
|
f30ca39242 | ||
|
|
9f68db4818 | ||
|
|
f1cd5abfaa | ||
|
|
a8a7da3466 | ||
|
|
da9c980d26 | ||
|
|
27cf0d5eaf | ||
|
|
b5cbf16cb8 | ||
|
|
2024fa09d7 | ||
|
|
46b2a58c25 | ||
|
|
d871b2ebdc | ||
|
|
dc51dab7bc | ||
|
|
e39305dd91 | ||
|
|
6e1f1c4da7 | ||
|
|
21a42a0dee | ||
|
|
982083b3e9 | ||
|
|
40e222c43b | ||
|
|
c8634668e7 | ||
|
|
fa9bb75ad3 | ||
|
|
c47e402025 | ||
|
|
a3f48c1d47 | ||
|
|
de048cb474 | ||
|
|
0c5ee31707 | ||
|
|
c820b0c5e1 | ||
|
|
d09e381cbc | ||
|
|
53d631f1bd | ||
|
|
74768449bc | ||
|
|
294adc2269 | ||
|
|
ff97424667 | ||
|
|
cbf8d7cad6 | ||
|
|
0c41951b58 | ||
|
|
50b36696f8 | ||
|
|
de4182f305 | ||
|
|
4214cc0aaa | ||
|
|
d1c77f5061 | ||
|
|
45e01cdaf2 | ||
|
|
2fc19daeec | ||
|
|
60c0b9ab96 | ||
|
|
7f948f9c3e | ||
|
|
66fb9f1097 | ||
|
|
062a5b9bf8 | ||
|
|
5bedf15462 | ||
|
|
d7aee40387 | ||
|
|
26f08fabd7 | ||
|
|
05b48ce57c | ||
|
|
1ed87f4e83 | ||
|
|
b089558674 | ||
|
|
45df1dbba0 | ||
|
|
beb32770f0 | ||
|
|
3eec297282 | ||
|
|
b0b6c979ee | ||
|
|
7d69ac03ec | ||
|
|
d7e08abce8 | ||
|
|
d907942966 | ||
|
|
fe0e737f7b | ||
|
|
8da959df85 | ||
|
|
d7a047a533 | ||
|
|
c260223127 | ||
|
|
e834a80b7b | ||
|
|
7011dd6524 | ||
|
|
cde668b54c | ||
|
|
01db86e915 | ||
|
|
85376147a4 | ||
|
|
d2ecce272c | ||
|
|
7ee0b428d6 | ||
|
|
9482e4c86a | ||
|
|
42276a9500 | ||
|
|
ae8f78c84d | ||
|
|
9636852224 | ||
|
|
5f72715a42 | ||
|
|
c60b5dd4d6 | ||
|
|
42c474a21f | ||
|
|
04078fbf61 | ||
|
|
28ebbb3f20 | ||
|
|
96fa32bcc1 | ||
|
|
b3246b6971 | ||
|
|
0345414ded | ||
|
|
01d214b276 | ||
|
|
fdd181d68d | ||
|
|
5c7df736bf | ||
|
|
29870cb572 | ||
|
|
32223e90e3 | ||
|
|
31198cdbd9 | ||
|
|
971f2b1ed7 | ||
|
|
832cf91e88 | ||
|
|
2e010073aa | ||
|
|
4c93b72906 | ||
|
|
7091fd5791 | ||
|
|
e5edd388a0 | ||
|
|
b887270e25 | ||
|
|
fc0d0ad8d3 | ||
|
|
ddfc8555f7 | ||
|
|
6d0739f7d9 | ||
|
|
fdd750e4b5 | ||
|
|
9a5afe371a | ||
|
|
5123561889 | ||
|
|
ba7f59355f | ||
|
|
a79f92df9e | ||
|
|
8bc88763ec | ||
|
|
4a0e982bb2 | ||
|
|
013fdddc6e | ||
|
|
a9ca465ad0 | ||
|
|
cd4d75ee7b | ||
|
|
aa2e109f5f | ||
|
|
45e3c9da70 | ||
|
|
cee026b87e | ||
|
|
1a68ce05dc | ||
|
|
bf0253df1d | ||
|
|
2e3e6a15e0 | ||
|
|
589fa6274d | ||
|
|
4cf0d39e58 | ||
|
|
a1952c71f7 | ||
|
|
48df26462d | ||
|
|
66cf62c3c4 | ||
|
|
9d6729fef3 | ||
|
|
20144ced54 | ||
|
|
2e6cbd9a4d | ||
|
|
85f49a7a1a | ||
|
|
6ba858dfbb | ||
|
|
7b423d5ff8 | ||
|
|
ae19729a72 | ||
|
|
2d45ae7441 | ||
|
|
e6cb0de539 | ||
|
|
924e50b6e9 | ||
|
|
1d32e78cf4 | ||
|
|
b5bca2d976 | ||
|
|
1acd4039b6 | ||
|
|
438ec5d1eb | ||
|
|
1a9cadf5f4 | ||
|
|
304b471281 | ||
|
|
6028683f87 | ||
|
|
0b58e791b3 | ||
|
|
1570d4f0a7 | ||
|
|
b6b6efc839 | ||
|
|
d502df353c | ||
|
|
7161326baa | ||
|
|
903d6d058c | ||
|
|
96b305389f | ||
|
|
2a74f0d8f4 | ||
|
|
6e99733320 | ||
|
|
94ab3007a4 | ||
|
|
4645c309ca | ||
|
|
852830eb54 | ||
|
|
4840217156 | ||
|
|
78fb3ce64d | ||
|
|
368ddfdd14 | ||
|
|
f9ebabe898 | ||
|
|
60eb2c4ecb | ||
|
|
8a177f6c85 | ||
|
|
5053d0eaaf | ||
|
|
6ec2b98336 | ||
|
|
bae0921ef7 | ||
|
|
7eab65df99 | ||
|
|
a41d773aaa | ||
|
|
4ef7a43939 | ||
|
|
7dc2e8e98e | ||
|
|
63636f19f1 | ||
|
|
23314188ca | ||
|
|
d429e35cdf | ||
|
|
99d85be529 | ||
|
|
2d0cadc949 | ||
|
|
821f42dd8e | ||
|
|
0d4bd61ae0 | ||
|
|
483302d09d | ||
|
|
5aa2913bce | ||
|
|
1803f73b15 | ||
|
|
9141337c7d | ||
|
|
70dbf582a6 | ||
|
|
1a6a34700f | ||
|
|
6e140b4b13 | ||
|
|
ac07af11de | ||
|
|
078318f33c | ||
|
|
a620db7025 | ||
|
|
99cbdfb004 | ||
|
|
887173c3c3 | ||
|
|
184506ae86 | ||
|
|
25c95f3bdc | ||
|
|
1bf13aa671 | ||
|
|
671d876cf3 | ||
|
|
50856459e6 | ||
|
|
8db2844e80 | ||
|
|
2d74c0162a | ||
|
|
7882418c5f | ||
|
|
01fb872095 | ||
|
|
12a2f412fc | ||
|
|
ee6bdc1588 | ||
|
|
11979f69eb | ||
|
|
65b8b220d2 | ||
|
|
c9e4153826 | ||
|
|
febf6593a6 | ||
|
|
e7790894d9 | ||
|
|
cef38030df | ||
|
|
2fb121e2ed | ||
|
|
7ad46cb118 | ||
|
|
4f58ff7933 | ||
|
|
838c3bbb8b | ||
|
|
fe49ac1a3d | ||
|
|
fbe4d57bae |
@@ -1,12 +1,12 @@
|
||||
ARG LLVM_VERSION="18"
|
||||
ARG REPORTED_LLVM_VERSION="18.1.8"
|
||||
ARG LLVM_VERSION="19"
|
||||
ARG REPORTED_LLVM_VERSION="19.1.7"
|
||||
ARG OLD_BUN_VERSION="1.1.38"
|
||||
ARG DEFAULT_CFLAGS="-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -ffunction-sections -fdata-sections -faddrsig -fno-unwind-tables -fno-asynchronous-unwind-tables"
|
||||
ARG DEFAULT_CXXFLAGS="-flto=full -fwhole-program-vtables -fforce-emit-vtables"
|
||||
ARG BUILDKITE_AGENT_TAGS="queue=linux,os=linux,arch=${TARGETARCH}"
|
||||
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:20.04 as base-arm64
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:18.04 as base-amd64
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:20.04 as base-amd64
|
||||
FROM base-$TARGETARCH as base
|
||||
|
||||
ARG LLVM_VERSION
|
||||
|
||||
@@ -107,9 +107,9 @@ const buildPlatforms = [
|
||||
{ os: "linux", arch: "aarch64", distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "x64", distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.20" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.20" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.20" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.21" },
|
||||
{ os: "windows", arch: "x64", release: "2019" },
|
||||
{ os: "windows", arch: "x64", baseline: true, release: "2019" },
|
||||
];
|
||||
@@ -134,9 +134,9 @@ const testPlatforms = [
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "24.04", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "22.04", tier: "previous" },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "20.04", tier: "oldest" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.20", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.20", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.20", tier: "latest" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "windows", arch: "x64", release: "2019", tier: "oldest" },
|
||||
{ os: "windows", arch: "x64", release: "2019", baseline: true, tier: "oldest" },
|
||||
];
|
||||
@@ -323,6 +323,7 @@ function getCppAgent(platform, options) {
|
||||
*/
|
||||
function getZigAgent(platform, options) {
|
||||
const { arch } = platform;
|
||||
|
||||
return {
|
||||
queue: "build-zig",
|
||||
};
|
||||
@@ -383,15 +384,21 @@ function getBuildEnv(target, options) {
|
||||
const { canary } = options;
|
||||
const revision = typeof canary === "number" ? canary : 1;
|
||||
|
||||
const isMusl = abi === "musl";
|
||||
|
||||
let CMAKE_BUILD_TYPE = release ? "Release" : profile === "debug" ? "Debug" : "RelWithDebInfo";
|
||||
if (isMusl && release) {
|
||||
CMAKE_BUILD_TYPE = "MinSizeRel";
|
||||
}
|
||||
|
||||
return {
|
||||
CMAKE_BUILD_TYPE: release ? "Release" : profile === "debug" ? "Debug" : "RelWithDebInfo",
|
||||
CMAKE_BUILD_TYPE,
|
||||
ENABLE_BASELINE: baseline ? "ON" : "OFF",
|
||||
ENABLE_CANARY: revision > 0 ? "ON" : "OFF",
|
||||
CANARY_REVISION: revision,
|
||||
ENABLE_ASSERTIONS: release ? "OFF" : "ON",
|
||||
ENABLE_LOGS: release ? "OFF" : "ON",
|
||||
ABI: abi === "musl" ? "musl" : undefined,
|
||||
|
||||
ABI: isMusl ? "musl" : undefined,
|
||||
CMAKE_TLS_VERIFY: "0",
|
||||
};
|
||||
}
|
||||
@@ -464,7 +471,7 @@ function getBuildZigStep(platform, options) {
|
||||
cancel_on_build_failing: isMergeQueue(),
|
||||
env: getBuildEnv(platform, options),
|
||||
command: `bun run build:ci --target bun-zig --toolchain ${toolchain}`,
|
||||
timeout_in_minutes: 25,
|
||||
timeout_in_minutes: 35,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ function create_release() {
|
||||
local artifacts=(
|
||||
bun-darwin-aarch64.zip
|
||||
bun-darwin-aarch64-profile.zip
|
||||
bun-darwin-x64.zip
|
||||
bun-darwin-x64-profile.zip
|
||||
bun-linux-aarch64.zip
|
||||
bun-linux-aarch64-profile.zip
|
||||
bun-linux-x64.zip
|
||||
|
||||
27
.cursor/rules/building-bun.mdc
Normal file
27
.cursor/rules/building-bun.mdc
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
description: How to build Bun
|
||||
globs:
|
||||
---
|
||||
# How to build Bun
|
||||
|
||||
## CMake
|
||||
|
||||
Bun is built using CMake, which you can find in `CMakeLists.txt` and in the `cmake/` directory.
|
||||
|
||||
* `CMakeLists.txt`
|
||||
* `cmake/`
|
||||
* `Globals.cmake` - macros and functions used by all the other files
|
||||
* `Options.cmake` - build options for configuring the build (e.g. debug/release mode)
|
||||
* `CompilerFlags.cmake` - compiler and linker flags used by all the targets
|
||||
* `tools/` - setup scripts for various build tools (e.g. llvm, zig, webkit, rust, etc.)
|
||||
* `targets/` - targets for bun and its dependencies (e.g. brotli, boringssl, libuv, etc.)
|
||||
|
||||
## How to
|
||||
|
||||
There are `package.json` scripts that make it easy to build Bun without calling CMake directly, for example:
|
||||
|
||||
```sh
|
||||
bun run build # builds a debug build: `build/debug/bun-debug`
|
||||
bun run build:release # builds a release build: `build/release/bun`
|
||||
bun run build:assert # builds a release build with debug assertions: `build/assert/bun`
|
||||
```
|
||||
139
.cursor/rules/dev-server-tests.mdc
Normal file
139
.cursor/rules/dev-server-tests.mdc
Normal file
@@ -0,0 +1,139 @@
|
||||
---
|
||||
description: Writing HMR/Dev Server tests
|
||||
globs: test/bake/*
|
||||
---
|
||||
|
||||
# Writing HMR/Dev Server tests
|
||||
|
||||
Dev server tests validate that hot-reloading is robust, correct, and reliable. Remember to write thorough, yet concise tests.
|
||||
|
||||
## File Structure
|
||||
|
||||
- `test/bake/bake-harness.ts` - shared utilities and test harness
|
||||
- primary test functions `devTest` / `prodTest` / `devAndProductionTest`
|
||||
- class `Dev` (controls subprocess for dev server)
|
||||
- class `Client` (controls a happy-dom subprocess for having the page open)
|
||||
- more helpers
|
||||
- `test/bake/client-fixture.mjs` - subprocess for what `Client` controls. it loads a page and uses IPC to query parts of the page, run javascript, and much more.
|
||||
- `test/bake/dev/*.test.ts` - these call `devTest` to test dev server and hot reloading
|
||||
- `test/bake/dev-and-prod.ts` - these use `devAndProductionTest` to run the same test on dev and production mode. these tests cannot really test hot reloading for obvious reasons.
|
||||
|
||||
## Categories
|
||||
|
||||
bundle.test.ts - Bundle tests are tests concerning bundling bugs that only occur in DevServer.
|
||||
css.test.ts - CSS tests concern bundling bugs with CSS files
|
||||
plugins.test.ts - Plugin tests concern plugins in development mode.
|
||||
ecosystem.test.ts - These tests involve ensuring certain libraries are correct. It is preferred to test more concrete bugs than testing entire packages.
|
||||
esm.test.ts - ESM tests are about various esm features in development mode.
|
||||
html.test.ts - HTML tests are tests relating to HTML files themselves.
|
||||
react-spa.test.ts - Tests relating to React, our react-refresh transform, and basic server component transforms.
|
||||
sourcemap.test.ts - Tests verifying source-maps are correct.
|
||||
|
||||
## `devTest` Basics
|
||||
|
||||
A test takes in two primary inputs: `files` and `async test(dev) {`
|
||||
|
||||
```ts
|
||||
import { devTest, emptyHtmlFile } from "../bake-harness";
|
||||
|
||||
devTest("html file is watched", {
|
||||
files: {
|
||||
"index.html": emptyHtmlFile({
|
||||
scripts: ["/script.ts"],
|
||||
body: "<h1>Hello</h1>",
|
||||
}),
|
||||
"script.ts": `
|
||||
console.log("hello");
|
||||
`,
|
||||
},
|
||||
async test(dev) {
|
||||
await dev.fetch("/").expect.toInclude("<h1>Hello</h1>");
|
||||
await dev.fetch("/").expect.toInclude("<h1>Hello</h1>");
|
||||
await dev.patch("index.html", {
|
||||
find: "Hello",
|
||||
replace: "World",
|
||||
});
|
||||
await dev.fetch("/").expect.toInclude("<h1>World</h1>");
|
||||
|
||||
// Works
|
||||
await using c = await dev.client("/");
|
||||
await c.expectMessage("hello");
|
||||
|
||||
// Editing HTML reloads
|
||||
await c.expectReload(async () => {
|
||||
await dev.patch("index.html", {
|
||||
find: "World",
|
||||
replace: "Hello",
|
||||
});
|
||||
await dev.fetch("/").expect.toInclude("<h1>Hello</h1>");
|
||||
});
|
||||
await c.expectMessage("hello");
|
||||
|
||||
await c.expectReload(async () => {
|
||||
await dev.patch("index.html", {
|
||||
find: "Hello",
|
||||
replace: "Bar",
|
||||
});
|
||||
await dev.fetch("/").expect.toInclude("<h1>Bar</h1>");
|
||||
});
|
||||
await c.expectMessage("hello");
|
||||
|
||||
await c.expectReload(async () => {
|
||||
await dev.patch("script.ts", {
|
||||
find: "hello",
|
||||
replace: "world",
|
||||
});
|
||||
});
|
||||
await c.expectMessage("world");
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
`files` holds the initial state, and the callback runs with the server running. `dev.fetch()` runs HTTP requests, while `dev.client()` opens a browser instance to the code.
|
||||
|
||||
Functions `dev.write` and `dev.patch` and `dev.delete` mutate the filesystem. Do not use `node:fs` APIs, as the dev server ones are hooked to wait for hot-reload, and all connected clients to recieve changes.
|
||||
|
||||
When a change performs a hard-reload, that must be explicitly annotated with `expectReload`. This tells `client-fixture.mjs` that the test is meant to reload the page once; All other hard reloads automatically fail the test.
|
||||
|
||||
Client's have `console.log` instrumented, so that any unasserted logs fail the test. This makes it more obvious when an extra reload or re-evaluation. Messages are awaited via `c.expectMessage("log")` or with multiple arguments if there are multiple logs.
|
||||
|
||||
## Testing for bundling errors
|
||||
|
||||
By default, a client opening a page to an error will fail the test. This makes testing errors explicit.
|
||||
|
||||
```ts
|
||||
devTest("import then create", {
|
||||
files: {
|
||||
"index.html": `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="module" src="/script.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
"script.ts": `
|
||||
import data from "./data";
|
||||
console.log(data);
|
||||
`,
|
||||
},
|
||||
async test(dev) {
|
||||
const c = await dev.client("/", {
|
||||
errors: ['script.ts:1:18: error: Could not resolve: "./data"'],
|
||||
});
|
||||
await c.expectReload(async () => {
|
||||
await dev.write("data.ts", "export default 'data';");
|
||||
});
|
||||
await c.expectMessage("data");
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Many functions take an options value to allow specifying it will produce errors. For example, this delete is going to cause a resolution failure.
|
||||
|
||||
```ts
|
||||
await dev.delete("other.ts", {
|
||||
errors: ['index.ts:1:16: error: Could not resolve: "./other"'],
|
||||
});
|
||||
```
|
||||
91
.cursor/rules/writing-tests.mdc
Normal file
91
.cursor/rules/writing-tests.mdc
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
description: Writing tests for Bun
|
||||
globs:
|
||||
---
|
||||
# Writing tests for Bun
|
||||
|
||||
## Where tests are found
|
||||
|
||||
You'll find all of Bun's tests in the `test/` directory.
|
||||
|
||||
* `test/`
|
||||
* `cli/` - CLI command tests, like `bun install` or `bun init`
|
||||
* `js/` - JavaScript & TypeScript tests
|
||||
* `bun/` - `Bun` APIs tests, seperated by category, for example: `glob/` for `Bun.Glob` tests
|
||||
* `node/` - Node.js module tests, seperated by module, for example: `assert/` for `node:assert` tests
|
||||
* `test/` - Vendored Node.js tests, taken from the Node.js repository (does not conform to Bun's test style)
|
||||
* `web/` - Web API tests, seperated by category, for example: `fetch/` for `Request` and `Response` tests
|
||||
* `third_party/` - npm package tests, to validate that basic usage works in Bun
|
||||
* `napi/` - N-API tests
|
||||
* `v8/` - V8 C++ API tests
|
||||
* `bundler/` - Bundler, transpiler, CSS, and `bun build` tests
|
||||
* `regression/issue/[number]` - Regression tests, always make one when fixing a particular issue
|
||||
|
||||
## How tests are written
|
||||
|
||||
Bun's tests are written as JavaScript and TypeScript files with the Jest-style APIs, like `test`, `describe`, and `expect`. They are tested using Bun's own test runner, `bun test`.
|
||||
|
||||
```js
|
||||
import { describe, test, expect } from "bun:test";
|
||||
import assert, { AssertionError } from "assert";
|
||||
|
||||
describe("assert(expr)", () => {
|
||||
test.each([true, 1, "foo"])(`assert(%p) does not throw`, expr => {
|
||||
expect(() => assert(expr)).not.toThrow();
|
||||
});
|
||||
|
||||
test.each([false, 0, "", null, undefined])(`assert(%p) throws`, expr => {
|
||||
expect(() => assert(expr)).toThrow(AssertionError);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Testing conventions
|
||||
|
||||
* See `test/harness.ts` for common test utilities and helpers
|
||||
* Be rigorous and test for edge-cases and unexpected inputs
|
||||
* Use data-driven tests, e.g. `test.each`, to reduce boilerplate when possible
|
||||
* When you need to test Bun as a CLI, use the following pattern:
|
||||
|
||||
```js
|
||||
import { test, expect } from "bun:test";
|
||||
import { spawn } from "bun";
|
||||
import { bunExe, bunEnv } from "harness";
|
||||
|
||||
test("bun --version", async () => {
|
||||
const { exited, stdout: stdoutStream, stderr: stderrStream } = spawn({
|
||||
cmd: [bunExe(), "--version"],
|
||||
env: bunEnv,
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const [ exitCode, stdout, stderr ] = await Promise.all([
|
||||
exited,
|
||||
new Response(stdoutStream).text(),
|
||||
new Response(stderrStream).text(),
|
||||
]);
|
||||
expect({ exitCode, stdout, stderr }).toMatchObject({
|
||||
exitCode: 0,
|
||||
stdout: expect.stringContaining(Bun.version),
|
||||
stderr: "",
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Before writing a test
|
||||
|
||||
* If you are fixing a bug, write the test first and make sure it fails (as expected) with the canary version of Bun
|
||||
* If you are fixing a Node.js compatibility bug, create a throw-away snippet of code and test that it works as you expect in Node.js, then that it fails (as expected) with the canary version of Bun
|
||||
* When the expected behaviour is ambigious, defer to matching what happens in Node.js
|
||||
* Always attempt to find related tests in an existing test file before creating a new test file
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
4
.github/workflows/clang-format.yml
vendored
4
.github/workflows/clang-format.yml
vendored
@@ -11,8 +11,8 @@ on:
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.2.0"
|
||||
LLVM_VERSION: "18.1.8"
|
||||
LLVM_VERSION_MAJOR: "18"
|
||||
LLVM_VERSION: "19.1.7"
|
||||
LLVM_VERSION_MAJOR: "19"
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
|
||||
4
.github/workflows/clang-tidy.yml
vendored
4
.github/workflows/clang-tidy.yml
vendored
@@ -11,8 +11,8 @@ on:
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.2.0"
|
||||
LLVM_VERSION: "18.1.8"
|
||||
LLVM_VERSION_MAJOR: "18"
|
||||
LLVM_VERSION: "19.1.7"
|
||||
LLVM_VERSION_MAJOR: "19"
|
||||
|
||||
jobs:
|
||||
clang-tidy:
|
||||
|
||||
55
.github/workflows/packages-ci.yml
vendored
Normal file
55
.github/workflows/packages-ci.yml
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
name: Packages CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "packages/**"
|
||||
- .prettierrc
|
||||
- .prettierignore
|
||||
- tsconfig.json
|
||||
- oxlint.json
|
||||
- "!**/*.md"
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "packages/**"
|
||||
- .prettierrc
|
||||
- .prettierignore
|
||||
- tsconfig.json
|
||||
- oxlint.json
|
||||
- "!**/*.md"
|
||||
|
||||
env:
|
||||
BUN_VERSION: "canary"
|
||||
|
||||
jobs:
|
||||
bun-plugin-svelte:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
bun install
|
||||
pushd ./packages/bun-plugin-svelte && bun install
|
||||
|
||||
- name: Lint
|
||||
run: |
|
||||
bunx oxlint@0.15 --format github --deny-warnings
|
||||
bunx prettier --config ../../.prettierrc --check .
|
||||
working-directory: ./packages/bun-plugin-svelte
|
||||
|
||||
- name: Check types
|
||||
run: bun check:types
|
||||
working-directory: ./packages/bun-plugin-svelte
|
||||
|
||||
- name: Test
|
||||
run: bun test
|
||||
working-directory: ./packages/bun-plugin-svelte
|
||||
1
.github/workflows/run-lint.yml
vendored
1
.github/workflows/run-lint.yml
vendored
@@ -3,7 +3,6 @@ name: Lint
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
LLVM_VERSION: 16
|
||||
BUN_VERSION: "1.2.0"
|
||||
|
||||
on:
|
||||
|
||||
2
.github/workflows/update-cares.yml
vendored
2
.github/workflows/update-cares.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates c-ares to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/c-ares/c-ares/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-cares.yml)
|
||||
|
||||
2
.github/workflows/update-libarchive.yml
vendored
2
.github/workflows/update-libarchive.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates libarchive to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/libarchive/libarchive/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-libarchive.yml)
|
||||
|
||||
2
.github/workflows/update-libdeflate.yml
vendored
2
.github/workflows/update-libdeflate.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates libdeflate to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/ebiggers/libdeflate/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-libdeflate.yml)
|
||||
|
||||
2
.github/workflows/update-lolhtml.yml
vendored
2
.github/workflows/update-lolhtml.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates lolhtml to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/cloudflare/lol-html/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-lolhtml.yml)
|
||||
|
||||
2
.github/workflows/update-lshpack.yml
vendored
2
.github/workflows/update-lshpack.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates lshpack to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/litespeedtech/ls-hpack/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-lshpack.yml)
|
||||
|
||||
82
.github/workflows/update-root-certs.yml
vendored
Normal file
82
.github/workflows/update-root-certs.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: Daily Root Certs Update Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Runs at 00:00 UTC every day
|
||||
workflow_dispatch: # Allows manual trigger
|
||||
|
||||
jobs:
|
||||
check-and-update:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Generate root certs and capture output
|
||||
id: generate-certs
|
||||
run: |
|
||||
cd packages/bun-usockets/
|
||||
OUTPUT=$(bun generate-root-certs.mjs -v)
|
||||
echo "cert_output<<EOF" >> $GITHUB_ENV
|
||||
echo "$OUTPUT" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Check for changes and stage files
|
||||
id: check-changes
|
||||
run: |
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
echo "Found changes, staging modified files..."
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Get list of modified files and add them
|
||||
git status --porcelain | while read -r status file; do
|
||||
# Remove leading status and whitespace
|
||||
file=$(echo "$file" | sed 's/^.* //')
|
||||
echo "Adding changed file: $file"
|
||||
git add "$file"
|
||||
done
|
||||
|
||||
echo "changes=true" >> $GITHUB_OUTPUT
|
||||
|
||||
# Store the list of changed files
|
||||
CHANGED_FILES=$(git status --porcelain)
|
||||
echo "changed_files<<EOF" >> $GITHUB_ENV
|
||||
echo "$CHANGED_FILES" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
else
|
||||
echo "No changes detected"
|
||||
echo "changes=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Create Pull Request
|
||||
if: steps.check-changes.outputs.changes == 'true'
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: "update(root_certs): Update root certificates $(date +'%Y-%m-%d')"
|
||||
title: "update(root_certs) $(date +'%Y-%m-%d')"
|
||||
body: |
|
||||
Automated root certificates update
|
||||
|
||||
${{ env.cert_output }}
|
||||
|
||||
## Changed Files:
|
||||
```
|
||||
${{ env.changed_files }}
|
||||
```
|
||||
branch: certs/update-root-certs-${{ github.run_number }}
|
||||
base: main
|
||||
delete-branch: true
|
||||
labels:
|
||||
- "automation"
|
||||
- "root-certs"
|
||||
2
.github/workflows/update-sqlite3.yml
vendored
2
.github/workflows/update-sqlite3.yml
vendored
@@ -106,4 +106,6 @@ jobs:
|
||||
|
||||
Updates SQLite to version ${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Compare: https://sqlite.org/src/vdiff?from=${{ steps.check-version.outputs.current }}&to=${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-sqlite3.yml)
|
||||
|
||||
18
.lldbinit
18
.lldbinit
@@ -1,4 +1,16 @@
|
||||
# command script import vendor/zig/tools/lldb_pretty_printers.py
|
||||
command script import vendor/WebKit/Tools/lldb/lldb_webkit.py
|
||||
# Tell LLDB what to do when the debugged process receives SIGPWR: pass it through to the process
|
||||
# (-p), but do not stop the process (-s) or notify the user (-n).
|
||||
#
|
||||
# JSC's garbage collector sends this signal (as configured by Bun WebKit in
|
||||
# Thread::initializePlatformThreading() in ThreadingPOSIX.cpp) to the JS thread to suspend or resume
|
||||
# it. So stopping the process would just create noise when debugging any long-running script.
|
||||
process handle -p true -s false -n false SIGPWR
|
||||
|
||||
# type summary add --summary-string "${var} | inner=${var[0-30]}, source=${var[33-64]}, tag=${var[31-32]}" "unsigned long"
|
||||
command script import misctools/lldb/lldb_pretty_printers.py
|
||||
type category enable zig.lang
|
||||
type category enable zig.std
|
||||
|
||||
command script import misctools/lldb/lldb_webkit.py
|
||||
|
||||
command script delete btjs
|
||||
command alias btjs p {printf("gathering btjs trace...\n");printf("%s\n", (char*)dumpBtjsTrace())}
|
||||
47
.vscode/launch.json
generated
vendored
47
.vscode/launch.json
generated
vendored
@@ -22,7 +22,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -38,7 +37,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -60,7 +58,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -76,7 +73,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -92,7 +88,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -108,7 +103,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -125,7 +119,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -147,7 +140,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -169,7 +161,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -188,7 +179,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -203,7 +193,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -221,7 +210,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -236,7 +224,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -253,7 +240,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -275,7 +261,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -297,7 +282,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -313,7 +297,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -329,7 +312,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -345,7 +327,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -361,7 +342,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -378,7 +358,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -400,7 +379,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -421,7 +399,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
// bun test [*]
|
||||
{
|
||||
@@ -437,7 +414,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -452,7 +428,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -468,7 +443,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -488,7 +462,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -503,7 +476,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
// Windows: bun test [file]
|
||||
{
|
||||
@@ -1129,7 +1101,24 @@
|
||||
],
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "bun",
|
||||
"name": "[JS] bun test [file]",
|
||||
"runtime": "${workspaceFolder}/build/debug/bun-debug",
|
||||
"runtimeArgs": ["test", "${file}"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {
|
||||
"BUN_DEBUG_QUIET_LOGS": "1",
|
||||
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "midas-rr",
|
||||
"request": "attach",
|
||||
"name": "rr",
|
||||
"trace": "Off",
|
||||
"setupCommands": ["handle SIGPWR nostop noprint pass"],
|
||||
},
|
||||
],
|
||||
"inputs": [
|
||||
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -141,9 +141,11 @@
|
||||
"packages/bun-uws/fuzzing": true,
|
||||
},
|
||||
"files.associations": {
|
||||
"*.css": "tailwindcss",
|
||||
"*.idl": "cpp",
|
||||
"*.mdc": "markdown",
|
||||
"array": "cpp",
|
||||
"ios": "cpp",
|
||||
},
|
||||
"C_Cpp.files.exclude": {
|
||||
"**/.vscode": true,
|
||||
|
||||
@@ -80,7 +80,7 @@ $ sudo zypper install clang18 lld18 llvm18
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.8).
|
||||
If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-19.1.7).
|
||||
|
||||
Make sure Clang/LLVM 18 is in your path:
|
||||
|
||||
@@ -205,18 +205,30 @@ WebKit is not cloned by default (to save time and disk space). To clone and buil
|
||||
# Clone WebKit into ./vendor/WebKit
|
||||
$ git clone https://github.com/oven-sh/WebKit vendor/WebKit
|
||||
|
||||
# Check out the commit hash specified in `set(WEBKIT_VERSION <commit_hash>)` in cmake/tools/SetupWebKit.cmake
|
||||
$ git -C vendor/WebKit checkout <commit_hash>
|
||||
|
||||
# Make a debug build of JSC. This will output build artifacts in ./vendor/WebKit/WebKitBuild/Debug
|
||||
# Optionally, you can use `make jsc` for a release build
|
||||
$ make jsc-debug
|
||||
$ make jsc-debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
|
||||
|
||||
# Build bun with the local JSC build
|
||||
$ bun run build:local
|
||||
```
|
||||
|
||||
Using `bun run build:local` will build Bun in the `./build/debug-local` directory (instead of `./build/debug`), you'll have to change a couple of places to use this new directory:
|
||||
|
||||
- The first line in [`src/js/builtins.d.ts`](/src/js/builtins.d.ts)
|
||||
- The `CompilationDatabase` line in [`.clangd` config](/.clangd) should be `CompilationDatabase: build/debug-local`
|
||||
- In [`build.zig`](/build.zig), the `codegen_path` option should be `build/debug-local/codegen` (instead of `build/debug/codegen`)
|
||||
- In [`.vscode/launch.json`](/.vscode/launch.json), many configurations use `./build/debug/`, change them as you see fit
|
||||
|
||||
Note that the WebKit folder, including build artifacts, is 8GB+ in size.
|
||||
|
||||
If you are using a JSC debug build and using VScode, make sure to run the `C/C++: Select a Configuration` command to configure intellisense to find the debug headers.
|
||||
|
||||
Note that if you change make changes to our [WebKit fork](https://github.com/oven-sh/WebKit), you will also have to change [`SetupWebKit.cmake`](/cmake/tools/SetupWebKit.cmake) to point to the commit hash.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 'span' file not found on Ubuntu
|
||||
|
||||
22
Makefile
22
Makefile
@@ -91,9 +91,9 @@ ZIG ?= $(shell which zig 2>/dev/null || echo -e "error: Missing zig. Please make
|
||||
# This is easier to happen than you'd expect.
|
||||
# Using realpath here causes issues because clang uses clang++ as a symlink
|
||||
# so if that's resolved, it won't build for C++
|
||||
REAL_CC = $(shell which clang-18 2>/dev/null || which clang 2>/dev/null)
|
||||
REAL_CXX = $(shell which clang++-18 2>/dev/null || which clang++ 2>/dev/null)
|
||||
CLANG_FORMAT = $(shell which clang-format-18 2>/dev/null || which clang-format 2>/dev/null)
|
||||
REAL_CC = $(shell which clang-19 2>/dev/null || which clang 2>/dev/null)
|
||||
REAL_CXX = $(shell which clang++-19 2>/dev/null || which clang++ 2>/dev/null)
|
||||
CLANG_FORMAT = $(shell which clang-format-19 2>/dev/null || which clang-format 2>/dev/null)
|
||||
|
||||
CC = $(REAL_CC)
|
||||
CXX = $(REAL_CXX)
|
||||
@@ -117,14 +117,14 @@ CC_WITH_CCACHE = $(CCACHE_PATH) $(CC)
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
# Find LLVM
|
||||
ifeq ($(wildcard $(LLVM_PREFIX)),)
|
||||
LLVM_PREFIX = $(shell brew --prefix llvm@18)
|
||||
LLVM_PREFIX = $(shell brew --prefix llvm@19)
|
||||
endif
|
||||
ifeq ($(wildcard $(LLVM_PREFIX)),)
|
||||
LLVM_PREFIX = $(shell brew --prefix llvm)
|
||||
endif
|
||||
ifeq ($(wildcard $(LLVM_PREFIX)),)
|
||||
# This is kinda ugly, but I can't find a better way to error :(
|
||||
LLVM_PREFIX = $(shell echo -e "error: Unable to find llvm. Please run 'brew install llvm@18' or set LLVM_PREFIX=/path/to/llvm")
|
||||
LLVM_PREFIX = $(shell echo -e "error: Unable to find llvm. Please run 'brew install llvm@19' or set LLVM_PREFIX=/path/to/llvm")
|
||||
endif
|
||||
|
||||
LDFLAGS += -L$(LLVM_PREFIX)/lib
|
||||
@@ -164,7 +164,7 @@ CMAKE_FLAGS_WITHOUT_RELEASE = -DCMAKE_C_COMPILER=$(CC) \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION) \
|
||||
$(CMAKE_CXX_COMPILER_LAUNCHER_FLAG) \
|
||||
-DCMAKE_AR=$(AR) \
|
||||
-DCMAKE_RANLIB=$(which llvm-18-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) \
|
||||
-DCMAKE_RANLIB=$(which llvm-19-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) \
|
||||
-DCMAKE_CXX_STANDARD=20 \
|
||||
-DCMAKE_C_STANDARD=17 \
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
|
||||
@@ -191,7 +191,7 @@ endif
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
LIBICONV_PATH =
|
||||
AR = $(shell which llvm-ar-18 2>/dev/null || which llvm-ar 2>/dev/null || which ar 2>/dev/null)
|
||||
AR = $(shell which llvm-ar-19 2>/dev/null || which llvm-ar 2>/dev/null || which ar 2>/dev/null)
|
||||
endif
|
||||
|
||||
OPTIMIZATION_LEVEL=-O3 $(MARCH_NATIVE)
|
||||
@@ -255,7 +255,7 @@ DEFAULT_LINKER_FLAGS= -pthread -ldl
|
||||
endif
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
_MIMALLOC_OBJECT_FILE = 0
|
||||
JSC_BUILD_STEPS += jsc-build-mac jsc-copy-headers
|
||||
JSC_BUILD_STEPS += jsc-build-mac
|
||||
JSC_BUILD_STEPS_DEBUG += jsc-build-mac-debug
|
||||
_MIMALLOC_FILE = libmimalloc.a
|
||||
_MIMALLOC_INPUT_PATH = libmimalloc.a
|
||||
@@ -286,7 +286,7 @@ STRIP=/usr/bin/strip
|
||||
endif
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
STRIP=$(shell which llvm-strip 2>/dev/null || which llvm-strip-18 2>/dev/null || which strip 2>/dev/null || echo "Missing strip")
|
||||
STRIP=$(shell which llvm-strip 2>/dev/null || which llvm-strip-19 2>/dev/null || which strip 2>/dev/null || echo "Missing strip")
|
||||
endif
|
||||
|
||||
|
||||
@@ -674,7 +674,7 @@ endif
|
||||
.PHONY: assert-deps
|
||||
assert-deps:
|
||||
@echo "Checking if the required utilities are available..."
|
||||
@if [ $(CLANG_VERSION) -lt "18" ]; then echo -e "ERROR: clang version >=18 required, found: $(CLANG_VERSION). Install with:\n\n $(POSIX_PKG_MANAGER) install llvm@18"; exit 1; fi
|
||||
@if [ $(CLANG_VERSION) -lt "19" ]; then echo -e "ERROR: clang version >=19 required, found: $(CLANG_VERSION). Install with:\n\n $(POSIX_PKG_MANAGER) install llvm@19"; exit 1; fi
|
||||
@cmake --version >/dev/null 2>&1 || (echo -e "ERROR: cmake is required."; exit 1)
|
||||
@$(PYTHON) --version >/dev/null 2>&1 || (echo -e "ERROR: python is required."; exit 1)
|
||||
@$(ESBUILD) --version >/dev/null 2>&1 || (echo -e "ERROR: esbuild is required."; exit 1)
|
||||
@@ -924,7 +924,7 @@ bun-codesign-release-local-debug:
|
||||
|
||||
|
||||
.PHONY: jsc
|
||||
jsc: jsc-build jsc-copy-headers jsc-bindings
|
||||
jsc: jsc-build
|
||||
.PHONY: jsc-debug
|
||||
jsc-debug: jsc-build-debug
|
||||
.PHONY: jsc-build
|
||||
|
||||
53
bench/crypto/diffie-hellman.mjs
Normal file
53
bench/crypto/diffie-hellman.mjs
Normal file
@@ -0,0 +1,53 @@
|
||||
import crypto from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
// Pre-generate DH params to avoid including setup in benchmarks
|
||||
const dhSize = 1024; // Reduced from 2048 for faster testing
|
||||
const dh = crypto.createDiffieHellman(dhSize);
|
||||
const dhPrime = dh.getPrime();
|
||||
const dhGenerator = dh.getGenerator();
|
||||
|
||||
// Classical Diffie-Hellman
|
||||
bench("DH - generateKeys", () => {
|
||||
const alice = crypto.createDiffieHellman(dhPrime, dhGenerator);
|
||||
return alice.generateKeys();
|
||||
});
|
||||
|
||||
bench("DH - computeSecret", () => {
|
||||
// Setup
|
||||
const alice = crypto.createDiffieHellman(dhPrime, dhGenerator);
|
||||
const aliceKey = alice.generateKeys();
|
||||
const bob = crypto.createDiffieHellman(dhPrime, dhGenerator);
|
||||
const bobKey = bob.generateKeys();
|
||||
|
||||
// Benchmark just the secret computation
|
||||
return alice.computeSecret(bobKey);
|
||||
});
|
||||
|
||||
// ECDH with prime256v1 (P-256)
|
||||
bench("ECDH-P256 - generateKeys", () => {
|
||||
const ecdh = crypto.createECDH("prime256v1");
|
||||
return ecdh.generateKeys();
|
||||
});
|
||||
|
||||
bench("ECDH-P256 - computeSecret", () => {
|
||||
// Setup
|
||||
const alice = crypto.createECDH("prime256v1");
|
||||
const aliceKey = alice.generateKeys();
|
||||
const bob = crypto.createECDH("prime256v1");
|
||||
const bobKey = bob.generateKeys();
|
||||
|
||||
// Benchmark just the secret computation
|
||||
return alice.computeSecret(bobKey);
|
||||
});
|
||||
|
||||
// ECDH with secp384r1 (P-384)
|
||||
bench("ECDH-P384 - computeSecret", () => {
|
||||
const alice = crypto.createECDH("secp384r1");
|
||||
const aliceKey = alice.generateKeys();
|
||||
const bob = crypto.createECDH("secp384r1");
|
||||
const bobKey = bob.generateKeys();
|
||||
return alice.computeSecret(bobKey);
|
||||
});
|
||||
|
||||
await run();
|
||||
44
bench/crypto/ecdh-convert-key.mjs
Normal file
44
bench/crypto/ecdh-convert-key.mjs
Normal file
@@ -0,0 +1,44 @@
|
||||
import crypto from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
function generateTestKeyPairs() {
|
||||
const curves = crypto.getCurves();
|
||||
const keys = {};
|
||||
|
||||
for (const curve of curves) {
|
||||
const ecdh = crypto.createECDH(curve);
|
||||
ecdh.generateKeys();
|
||||
|
||||
keys[curve] = {
|
||||
compressed: ecdh.getPublicKey("hex", "compressed"),
|
||||
uncompressed: ecdh.getPublicKey("hex", "uncompressed"),
|
||||
instance: ecdh,
|
||||
};
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
const testKeys = generateTestKeyPairs();
|
||||
|
||||
bench("ECDH key format - P256 compressed to uncompressed", () => {
|
||||
const publicKey = testKeys["prime256v1"].compressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "prime256v1", "hex", "hex", "uncompressed");
|
||||
});
|
||||
|
||||
bench("ECDH key format - P256 uncompressed to compressed", () => {
|
||||
const publicKey = testKeys["prime256v1"].uncompressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "prime256v1", "hex", "hex", "compressed");
|
||||
});
|
||||
|
||||
bench("ECDH key format - P384 compressed to uncompressed", () => {
|
||||
const publicKey = testKeys["secp384r1"].compressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "secp384r1", "hex", "hex", "uncompressed");
|
||||
});
|
||||
|
||||
bench("ECDH key format - P384 uncompressed to compressed", () => {
|
||||
const publicKey = testKeys["secp384r1"].uncompressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "secp384r1", "hex", "hex", "compressed");
|
||||
});
|
||||
|
||||
await run();
|
||||
50
bench/crypto/hkdf.mjs
Normal file
50
bench/crypto/hkdf.mjs
Normal file
@@ -0,0 +1,50 @@
|
||||
import crypto from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
// Sample keys with different lengths
|
||||
const keys = {
|
||||
short: "secret",
|
||||
long: "this-is-a-much-longer-secret-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
};
|
||||
|
||||
// Test parameters
|
||||
const salts = ["", "salt"];
|
||||
const infos = ["", "info"];
|
||||
const hashes = ["sha256", "sha512"];
|
||||
const sizes = [10, 1024];
|
||||
|
||||
// Benchmark sync HKDF
|
||||
for (const hash of hashes) {
|
||||
for (const keyName of Object.keys(keys)) {
|
||||
const key = keys[keyName];
|
||||
for (const size of sizes) {
|
||||
bench(`hkdfSync ${hash} ${keyName}-key ${size} bytes`, () => {
|
||||
return crypto.hkdfSync(hash, key, "salt", "info", size);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark different combinations of salt and info
|
||||
for (const salt of salts) {
|
||||
for (const info of infos) {
|
||||
bench(`hkdfSync sha256 with ${salt ? "salt" : "no-salt"} and ${info ? "info" : "no-info"}`, () => {
|
||||
return crypto.hkdfSync("sha256", "secret", salt, info, 64);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark async HKDF (using promises for cleaner benchmark)
|
||||
// Note: async benchmarks in Mitata require returning a Promise
|
||||
for (const hash of hashes) {
|
||||
bench(`hkdf ${hash} async`, async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
crypto.hkdf(hash, "secret", "salt", "info", 64, (err, derivedKey) => {
|
||||
if (err) reject(err);
|
||||
else resolve(derivedKey);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await run();
|
||||
43
bench/crypto/primes.mjs
Normal file
43
bench/crypto/primes.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
import { checkPrime, checkPrimeSync, generatePrime, generatePrimeSync } from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
const prime512 = generatePrimeSync(512);
|
||||
const prime2048 = generatePrimeSync(2048);
|
||||
|
||||
bench("checkPrimeSync 512", () => {
|
||||
return checkPrimeSync(prime512);
|
||||
});
|
||||
|
||||
bench("checkPrimeSync 2048", () => {
|
||||
return checkPrimeSync(prime2048);
|
||||
});
|
||||
|
||||
bench("checkPrime 512", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => checkPrime(prime512, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
bench("checkPrime 2048", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => checkPrime(prime2048, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
bench("generatePrimeSync 512", () => {
|
||||
return generatePrimeSync(512);
|
||||
});
|
||||
|
||||
bench("generatePrimeSync 2048", () => {
|
||||
return generatePrimeSync(2048);
|
||||
});
|
||||
|
||||
bench("generatePrime 512", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => generatePrime(512, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
bench("generatePrime 2048", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => generatePrime(2048, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
await run();
|
||||
50
bench/crypto/random.mjs
Normal file
50
bench/crypto/random.mjs
Normal file
@@ -0,0 +1,50 @@
|
||||
import crypto from "crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
bench("randomInt - sync", () => {
|
||||
crypto.randomInt(1000);
|
||||
});
|
||||
|
||||
bench("randomInt - async", async () => {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
crypto.randomInt(1000, () => {
|
||||
resolve();
|
||||
});
|
||||
await promise;
|
||||
});
|
||||
|
||||
bench("randonBytes - 32", () => {
|
||||
crypto.randomBytes(32);
|
||||
});
|
||||
|
||||
bench("randomBytes - 256", () => {
|
||||
crypto.randomBytes(256);
|
||||
});
|
||||
|
||||
const buf = Buffer.alloc(256);
|
||||
|
||||
bench("randomFill - 32", async () => {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
crypto.randomFill(buf, 0, 32, () => {
|
||||
resolve();
|
||||
});
|
||||
await promise;
|
||||
});
|
||||
|
||||
bench("randomFill - 256", async () => {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
crypto.randomFill(buf, 0, 256, () => {
|
||||
resolve();
|
||||
});
|
||||
await promise;
|
||||
});
|
||||
|
||||
bench("randomFillSync - 32", () => {
|
||||
crypto.randomFillSync(buf, 0, 32);
|
||||
});
|
||||
|
||||
bench("randomFillSync - 256", () => {
|
||||
crypto.randomFillSync(buf, 0, 256);
|
||||
});
|
||||
|
||||
await run();
|
||||
@@ -12,6 +12,7 @@
|
||||
"eventemitter3": "^5.0.0",
|
||||
"execa": "^8.0.1",
|
||||
"fast-glob": "3.3.1",
|
||||
"fastify": "^5.0.0",
|
||||
"fdir": "^6.1.0",
|
||||
"mitata": "^1.0.25",
|
||||
"react": "^18.3.1",
|
||||
|
||||
13
bench/snippets/express-hello.mjs
Normal file
13
bench/snippets/express-hello.mjs
Normal file
@@ -0,0 +1,13 @@
|
||||
import express from "express";
|
||||
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
var i = 0;
|
||||
app.get("/", (req, res) => {
|
||||
res.send("Hello World!" + i++);
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Express app listening at http://localhost:${port}`);
|
||||
});
|
||||
20
bench/snippets/fastify.mjs
Normal file
20
bench/snippets/fastify.mjs
Normal file
@@ -0,0 +1,20 @@
|
||||
import Fastify from "fastify";
|
||||
|
||||
const fastify = Fastify({
|
||||
logger: false,
|
||||
});
|
||||
|
||||
fastify.get("/", async (request, reply) => {
|
||||
return { hello: "world" };
|
||||
});
|
||||
|
||||
const start = async () => {
|
||||
try {
|
||||
await fastify.listen({ port: 3000 });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
start();
|
||||
36
build.zig
36
build.zig
@@ -19,16 +19,17 @@ const OperatingSystem = @import("src/env.zig").OperatingSystem;
|
||||
const pathRel = fs.path.relative;
|
||||
|
||||
/// Do not rename this constant. It is scanned by some scripts to determine which zig version to install.
|
||||
const recommended_zig_version = "0.14.0-dev.2987+183bb8b08";
|
||||
const recommended_zig_version = "0.14.0";
|
||||
|
||||
comptime {
|
||||
if (!std.mem.eql(u8, builtin.zig_version_string, recommended_zig_version)) {
|
||||
@compileError(
|
||||
"" ++
|
||||
"Bun requires Zig version " ++ recommended_zig_version ++ ". This is" ++
|
||||
"automatically configured via Bun's CMake setup. You likely meant to run" ++
|
||||
"`bun setup`. If you are trying to upgrade the Zig compiler," ++
|
||||
"run `./scripts/download-zig.sh master` or comment this message out.",
|
||||
"Bun requires Zig version " ++ recommended_zig_version ++ ", but you have " ++
|
||||
builtin.zig_version_string ++ ". This is automatically configured via Bun's " ++
|
||||
"CMake setup. You likely meant to run `bun run build`. If you are trying to " ++
|
||||
"upgrade the Zig compiler, edit ZIG_COMMIT in cmake/tools/SetupZig.cmake or " ++
|
||||
"comment this error out.",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -318,7 +319,21 @@ pub fn build(b: *Build) !void {
|
||||
.{ .os = .linux, .arch = .aarch64 },
|
||||
.{ .os = .linux, .arch = .x86_64, .musl = true },
|
||||
.{ .os = .linux, .arch = .aarch64, .musl = true },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
|
||||
// zig build check-all-debug
|
||||
{
|
||||
const step = b.step("check-all-debug", "Check for semantic analysis errors on all supported platforms in debug mode");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .windows, .arch = .x86_64 },
|
||||
.{ .os = .mac, .arch = .x86_64 },
|
||||
.{ .os = .mac, .arch = .aarch64 },
|
||||
.{ .os = .linux, .arch = .x86_64 },
|
||||
.{ .os = .linux, .arch = .aarch64 },
|
||||
.{ .os = .linux, .arch = .x86_64, .musl = true },
|
||||
.{ .os = .linux, .arch = .aarch64, .musl = true },
|
||||
}, &.{.Debug});
|
||||
}
|
||||
|
||||
// zig build check-windows
|
||||
@@ -326,21 +341,21 @@ pub fn build(b: *Build) !void {
|
||||
const step = b.step("check-windows", "Check for semantic analysis errors on Windows");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .windows, .arch = .x86_64 },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
{
|
||||
const step = b.step("check-macos", "Check for semantic analysis errors on Windows");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .mac, .arch = .x86_64 },
|
||||
.{ .os = .mac, .arch = .aarch64 },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
{
|
||||
const step = b.step("check-linux", "Check for semantic analysis errors on Windows");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .linux, .arch = .x86_64 },
|
||||
.{ .os = .linux, .arch = .aarch64 },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
|
||||
// zig build translate-c-headers
|
||||
@@ -368,9 +383,10 @@ pub fn addMultiCheck(
|
||||
parent_step: *Step,
|
||||
root_build_options: BunBuildOptions,
|
||||
to_check: []const struct { os: OperatingSystem, arch: Arch, musl: bool = false },
|
||||
optimize: []const std.builtin.OptimizeMode,
|
||||
) void {
|
||||
for (to_check) |check| {
|
||||
for ([_]std.builtin.Mode{ .Debug, .ReleaseFast }) |mode| {
|
||||
for (optimize) |mode| {
|
||||
const check_target = b.resolveTargetQuery(.{
|
||||
.os_tag = OperatingSystem.stdOSTag(check.os),
|
||||
.cpu_arch = check.arch,
|
||||
|
||||
4
bun.lock
4
bun.lock
@@ -151,13 +151,13 @@
|
||||
|
||||
"@qiwi/npm-registry-client": ["@qiwi/npm-registry-client@8.9.1", "", { "dependencies": { "concat-stream": "^2.0.0", "graceful-fs": "^4.2.4", "normalize-package-data": "~1.0.1 || ^2.0.0 || ^3.0.0", "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^8.0.0", "once": "^1.4.0", "request": "^2.88.2", "retry": "^0.12.0", "safe-buffer": "^5.2.1", "semver": "2 >=2.2.1 || 3.x || 4 || 5 || 7", "slide": "^1.1.6", "ssri": "^8.0.0" }, "optionalDependencies": { "npmlog": "2 || ^3.1.0 || ^4.0.0" } }, "sha512-rZF+mG+NfijR0SHphhTLHRr4aM4gtfdwoAMY6we2VGQam8vkN1cxGG1Lg/Llrj8Dd0Mu6VjdFQRyMMRZxtZR2A=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.1.17", "", { "dependencies": { "bun-types": "1.1.44" } }, "sha512-zZt0Kao/8hAwNOXh4bmt8nKbMEd4QD8n7PeTGF+NZTVY5ouXhU/TX7jUj4He1p7mgY+WdplnU1B6MB1j17vdzg=="],
|
||||
"@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||
|
||||
"@types/node": ["@types/node@22.10.7", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg=="],
|
||||
"@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="],
|
||||
|
||||
"@types/prop-types": ["@types/prop-types@15.7.12", "", {}, "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q=="],
|
||||
|
||||
|
||||
@@ -2,3 +2,7 @@
|
||||
# https://github.com/oven-sh/bun/issues/16289
|
||||
[test]
|
||||
preload = ["./test/js/node/harness.ts", "./test/preload.ts"]
|
||||
|
||||
[install]
|
||||
# Node.js never auto-installs modules.
|
||||
auto = "disable"
|
||||
|
||||
@@ -419,7 +419,15 @@ function(register_command)
|
||||
list(APPEND CMD_EFFECTIVE_OUTPUTS ${artifact})
|
||||
if(BUILDKITE)
|
||||
file(RELATIVE_PATH filename ${BUILD_PATH} ${artifact})
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload ${filename})
|
||||
if(filename STREQUAL "libbun-profile.a")
|
||||
# libbun-profile.a is now over 5gb in size, compress it first
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} rm -r ${BUILD_PATH}/codegen)
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} rm -r ${CACHE_PATH})
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} gzip -6 libbun-profile.a)
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload libbun-profile.a.gz)
|
||||
else()
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload ${filename})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
if(DEBUG)
|
||||
set(bun bun-debug)
|
||||
elseif(ENABLE_SMOL)
|
||||
set(bun bun-smol-profile)
|
||||
set(bunStrip bun-smol)
|
||||
# elseif(ENABLE_SMOL)
|
||||
# set(bun bun-smol-profile)
|
||||
# set(bunStrip bun-smol)
|
||||
elseif(ENABLE_VALGRIND)
|
||||
set(bun bun-valgrind)
|
||||
elseif(ENABLE_ASSERTIONS)
|
||||
@@ -622,6 +622,7 @@ file(GLOB BUN_CXX_SOURCES ${CONFIGURE_DEPENDS}
|
||||
${CWD}/src/bun.js/bindings/sqlite/*.cpp
|
||||
${CWD}/src/bun.js/bindings/webcrypto/*.cpp
|
||||
${CWD}/src/bun.js/bindings/webcrypto/*/*.cpp
|
||||
${CWD}/src/bun.js/bindings/node/crypto/*.cpp
|
||||
${CWD}/src/bun.js/bindings/v8/*.cpp
|
||||
${CWD}/src/bun.js/bindings/v8/shim/*.cpp
|
||||
${CWD}/src/bake/*.cpp
|
||||
@@ -737,7 +738,7 @@ endif()
|
||||
# --- C/C++ Properties ---
|
||||
|
||||
set_target_properties(${bun} PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD 23
|
||||
CXX_STANDARD_REQUIRED YES
|
||||
CXX_EXTENSIONS YES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
@@ -746,6 +747,18 @@ set_target_properties(${bun} PROPERTIES
|
||||
VISIBILITY_INLINES_HIDDEN YES
|
||||
)
|
||||
|
||||
if (NOT WIN32)
|
||||
# Enable precompiled headers
|
||||
# Only enable in these scenarios:
|
||||
# 1. NOT in CI, OR
|
||||
# 2. In CI AND BUN_CPP_ONLY is enabled
|
||||
if(NOT CI OR (CI AND BUN_CPP_ONLY))
|
||||
target_precompile_headers(${bun} PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:${CWD}/src/bun.js/bindings/root.h>"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- C/C++ Includes ---
|
||||
|
||||
if(WIN32)
|
||||
@@ -759,6 +772,7 @@ target_include_directories(${bun} PRIVATE
|
||||
${CWD}/src/bun.js/bindings
|
||||
${CWD}/src/bun.js/bindings/webcore
|
||||
${CWD}/src/bun.js/bindings/webcrypto
|
||||
${CWD}/src/bun.js/bindings/node/crypto
|
||||
${CWD}/src/bun.js/bindings/sqlite
|
||||
${CWD}/src/bun.js/bindings/v8
|
||||
${CWD}/src/bun.js/modules
|
||||
@@ -899,6 +913,10 @@ if(NOT WIN32)
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
target_compile_options(${bun} PUBLIC
|
||||
-Wno-nullability-completeness
|
||||
)
|
||||
endif()
|
||||
|
||||
# --- Linker options ---
|
||||
@@ -941,28 +959,17 @@ endif()
|
||||
|
||||
if(LINUX)
|
||||
if(NOT ABI STREQUAL "musl")
|
||||
# on arm64
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64")
|
||||
target_link_options(${bun} PUBLIC
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=fcntl64
|
||||
-Wl,--wrap=log
|
||||
-Wl,--wrap=log2
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=pow
|
||||
-Wl,--wrap=powf
|
||||
)
|
||||
else()
|
||||
target_link_options(${bun} PUBLIC
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=powf
|
||||
)
|
||||
endif()
|
||||
target_link_options(${bun} PUBLIC
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=fcntl64
|
||||
-Wl,--wrap=log
|
||||
-Wl,--wrap=log2
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=pow
|
||||
-Wl,--wrap=powf
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT ABI STREQUAL "musl")
|
||||
|
||||
@@ -4,7 +4,7 @@ register_repository(
|
||||
REPOSITORY
|
||||
cloudflare/lol-html
|
||||
COMMIT
|
||||
4f8becea13a0021c8b71abd2dcc5899384973b66
|
||||
67f1d4ffd6b74db7e053fb129dcce620193c180d
|
||||
)
|
||||
|
||||
set(LOLHTML_CWD ${VENDOR_PATH}/lolhtml/c-api)
|
||||
|
||||
@@ -120,6 +120,9 @@ foreach(i RANGE ${BUILDKITE_JOBS_MAX_INDEX})
|
||||
endif()
|
||||
|
||||
if(BUILDKITE)
|
||||
if(BUILDKITE_ARTIFACT_PATH STREQUAL "libbun-profile.a")
|
||||
set(BUILDKITE_ARTIFACT_PATH libbun-profile.a.gz)
|
||||
endif()
|
||||
set(BUILDKITE_DOWNLOAD_COMMAND buildkite-agent artifact download ${BUILDKITE_ARTIFACT_PATH} . --build ${BUILDKITE_BUILD_UUID} --step ${BUILDKITE_JOB_ID})
|
||||
else()
|
||||
set(BUILDKITE_DOWNLOAD_COMMAND curl -L -o ${BUILDKITE_ARTIFACT_PATH} ${BUILDKITE_ARTIFACTS_URL}/${BUILDKITE_ARTIFACT_ID})
|
||||
@@ -135,6 +138,20 @@ foreach(i RANGE ${BUILDKITE_JOBS_MAX_INDEX})
|
||||
OUTPUT
|
||||
${BUILD_PATH}/${BUILDKITE_ARTIFACT_PATH}
|
||||
)
|
||||
if(BUILDKITE_ARTIFACT_PATH STREQUAL "libbun-profile.a.gz")
|
||||
add_custom_command(
|
||||
COMMENT
|
||||
"Unpacking libbun-profile.a.gz"
|
||||
VERBATIM COMMAND
|
||||
gunzip libbun-profile.a.gz
|
||||
WORKING_DIRECTORY
|
||||
${BUILD_PATH}
|
||||
OUTPUT
|
||||
${BUILD_PATH}/libbun-profile.a
|
||||
DEPENDS
|
||||
${BUILD_PATH}/libbun-profile.a.gz
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(APPEND BUILDKITE_JOBS_MATCH ${BUILDKITE_JOB_NAME})
|
||||
|
||||
@@ -36,7 +36,8 @@ endif()
|
||||
string(REPLACE "\n" ";" GIT_CHANGED_SOURCES "${GIT_DIFF}")
|
||||
|
||||
if(CI)
|
||||
setx(GIT_CHANGED_SOURCES ${GIT_CHANGED_SOURCES})
|
||||
set(GIT_CHANGED_SOURCES "${GIT_CHANGED_SOURCES}")
|
||||
message(STATUS "Set GIT_CHANGED_SOURCES: ${GIT_CHANGED_SOURCES}")
|
||||
endif()
|
||||
|
||||
list(TRANSFORM GIT_CHANGED_SOURCES PREPEND ${CWD}/)
|
||||
|
||||
@@ -12,7 +12,7 @@ if(NOT ENABLE_LLVM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(DEFAULT_LLVM_VERSION "18.1.8")
|
||||
set(DEFAULT_LLVM_VERSION "19.1.7")
|
||||
|
||||
optionx(LLVM_VERSION STRING "The version of LLVM to use" DEFAULT ${DEFAULT_LLVM_VERSION})
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
|
||||
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
|
||||
|
||||
if(NOT WEBKIT_VERSION)
|
||||
set(WEBKIT_VERSION c333de54223425d7148603d63dd3f6152d0bc348)
|
||||
set(WEBKIT_VERSION 91bf2baced1b1309c7e05f19177c97fefec20976)
|
||||
endif()
|
||||
|
||||
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
|
||||
|
||||
@@ -20,7 +20,7 @@ else()
|
||||
unsupported(CMAKE_SYSTEM_NAME)
|
||||
endif()
|
||||
|
||||
set(ZIG_COMMIT "bb9d6ab2c0bbbf20cc24dad03e88f3b3ffdb7de7")
|
||||
set(ZIG_COMMIT "cd1995944508e4c946deb75bd70947d302e0db37")
|
||||
optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
@@ -204,7 +204,7 @@ To customize the TLS validation, use the `checkServerIdentity` option in `tls`
|
||||
await fetch("https://example.com", {
|
||||
tls: {
|
||||
checkServerIdentity: (hostname, peerCertificate) => {
|
||||
// Return an error if the certificate is invalid
|
||||
// Return an Error if the certificate is invalid
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -12,5 +12,3 @@ Alternatively, use `process.dlopen`:
|
||||
let mod = { exports: {} };
|
||||
process.dlopen(mod, "./my-node-module.node");
|
||||
```
|
||||
|
||||
Bun polyfills the [`detect-libc`](https://npmjs.com/package/detect-libc) package, which is used by many Node-API modules to detect which `.node` binding to `require`.
|
||||
|
||||
@@ -715,7 +715,7 @@ await S3Client.delete("my-file.txt", credentials);
|
||||
await S3Client.unlink("my-file.txt", credentials);
|
||||
```
|
||||
|
||||
## s3:// protocol
|
||||
## `s3://` protocol
|
||||
|
||||
To make it easier to use the same code for local files and S3 files, the `s3://` protocol is supported in `fetch` and `Bun.file()`.
|
||||
|
||||
|
||||
@@ -77,6 +77,16 @@ console.log(text); // "const input = "hello world".repeat(400); ..."
|
||||
|
||||
---
|
||||
|
||||
- `ReadableStream`
|
||||
- Use a readable stream as input.
|
||||
|
||||
---
|
||||
|
||||
- `Blob`
|
||||
- Use a blob as input.
|
||||
|
||||
---
|
||||
|
||||
- `number`
|
||||
- Read from the file with a given file descriptor.
|
||||
|
||||
@@ -129,13 +139,13 @@ Configure the output stream by passing one of the following values to `stdout/st
|
||||
|
||||
---
|
||||
|
||||
- `Bun.file()`
|
||||
- Write to the specified file.
|
||||
- `"ignore"`
|
||||
- Discard the output.
|
||||
|
||||
---
|
||||
|
||||
- `null`
|
||||
- Write to `/dev/null`.
|
||||
- `Bun.file()`
|
||||
- Write to the specified file.
|
||||
|
||||
---
|
||||
|
||||
@@ -174,7 +184,8 @@ const proc = Bun.spawn(["bun", "--version"]);
|
||||
proc.kill();
|
||||
proc.killed; // true
|
||||
|
||||
proc.kill(); // specify an exit code
|
||||
proc.kill(15); // specify a signal code
|
||||
proc.kill("SIGTERM"); // specify a signal name
|
||||
```
|
||||
|
||||
The parent `bun` process will not terminate until all child processes have exited. Use `proc.unref()` to detach the child process from the parent.
|
||||
@@ -184,6 +195,64 @@ const proc = Bun.spawn(["bun", "--version"]);
|
||||
proc.unref();
|
||||
```
|
||||
|
||||
## Resource usage
|
||||
|
||||
You can get information about the process's resource usage after it has exited:
|
||||
|
||||
```ts
|
||||
const proc = Bun.spawn(["bun", "--version"]);
|
||||
await proc.exited;
|
||||
|
||||
const usage = proc.resourceUsage();
|
||||
console.log(`Max memory used: ${usage.maxRSS} bytes`);
|
||||
console.log(`CPU time (user): ${usage.cpuTime.user} µs`);
|
||||
console.log(`CPU time (system): ${usage.cpuTime.system} µs`);
|
||||
```
|
||||
|
||||
## Using AbortSignal
|
||||
|
||||
You can abort a subprocess using an `AbortSignal`:
|
||||
|
||||
```ts
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["sleep", "100"],
|
||||
signal,
|
||||
});
|
||||
|
||||
// Later, to abort the process:
|
||||
controller.abort();
|
||||
```
|
||||
|
||||
## Using timeout and killSignal
|
||||
|
||||
You can set a timeout for a subprocess to automatically terminate after a specific duration:
|
||||
|
||||
```ts
|
||||
// Kill the process after 5 seconds
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["sleep", "10"],
|
||||
timeout: 5000, // 5 seconds in milliseconds
|
||||
});
|
||||
|
||||
await proc.exited; // Will resolve after 5 seconds
|
||||
```
|
||||
|
||||
By default, timed-out processes are killed with the `SIGTERM` signal. You can specify a different signal with the `killSignal` option:
|
||||
|
||||
```ts
|
||||
// Kill the process with SIGKILL after 5 seconds
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["sleep", "10"],
|
||||
timeout: 5000,
|
||||
killSignal: "SIGKILL", // Can be string name or signal number
|
||||
});
|
||||
```
|
||||
|
||||
The `killSignal` option also controls which signal is sent when an AbortSignal is aborted.
|
||||
|
||||
## Inter-process communication (IPC)
|
||||
|
||||
Bun supports direct inter-process communication channel between two `bun` processes. To receive messages from a spawned Bun subprocess, specify an `ipc` handler.
|
||||
@@ -233,11 +302,17 @@ process.send("Hello from child as string");
|
||||
process.send({ message: "Hello from child as object" });
|
||||
```
|
||||
|
||||
The `ipcMode` option controls the underlying communication format between the two processes:
|
||||
The `serialization` option controls the underlying communication format between the two processes:
|
||||
|
||||
- `advanced`: (default) Messages are serialized using the JSC `serialize` API, which supports cloning [everything `structuredClone` supports](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). This does not support transferring ownership of objects.
|
||||
- `json`: Messages are serialized using `JSON.stringify` and `JSON.parse`, which does not support as many object types as `advanced` does.
|
||||
|
||||
To disconnect the IPC channel from the parent process, call:
|
||||
|
||||
```ts
|
||||
childProc.disconnect();
|
||||
```
|
||||
|
||||
### IPC between Bun & Node.js
|
||||
|
||||
To use IPC between a `bun` process and a Node.js process, set `serialization: "json"` in `Bun.spawn`. This is because Node.js and Bun use different JavaScript engines with different object serialization formats.
|
||||
@@ -310,7 +385,7 @@ spawnSync echo hi 1.47 ms/iter (1.14 ms … 2.64 ms) 1.57 ms 2.37 ms
|
||||
|
||||
## Reference
|
||||
|
||||
A simple reference of the Spawn API and types are shown below. The real types have complex generics to strongly type the `Subprocess` streams with the options passed to `Bun.spawn` and `Bun.spawnSync`. For full details, find these types as defined [bun.d.ts](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts).
|
||||
A reference of the Spawn API and types are shown below. The real types have complex generics to strongly type the `Subprocess` streams with the options passed to `Bun.spawn` and `Bun.spawnSync`. For full details, find these types as defined [bun.d.ts](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts).
|
||||
|
||||
```ts
|
||||
interface Bun {
|
||||
@@ -329,16 +404,25 @@ interface Bun {
|
||||
namespace SpawnOptions {
|
||||
interface OptionsObject {
|
||||
cwd?: string;
|
||||
env?: Record<string, string>;
|
||||
stdin?: SpawnOptions.Readable;
|
||||
stdout?: SpawnOptions.Writable;
|
||||
stderr?: SpawnOptions.Writable;
|
||||
onExit?: (
|
||||
proc: Subprocess,
|
||||
env?: Record<string, string | undefined>;
|
||||
stdio?: [Writable, Readable, Readable];
|
||||
stdin?: Writable;
|
||||
stdout?: Readable;
|
||||
stderr?: Readable;
|
||||
onExit?(
|
||||
subprocess: Subprocess,
|
||||
exitCode: number | null,
|
||||
signalCode: string | null,
|
||||
error: Error | null,
|
||||
) => void;
|
||||
signalCode: number | null,
|
||||
error?: ErrorLike,
|
||||
): void | Promise<void>;
|
||||
ipc?(message: any, subprocess: Subprocess): void;
|
||||
serialization?: "json" | "advanced";
|
||||
windowsHide?: boolean;
|
||||
windowsVerbatimArguments?: boolean;
|
||||
argv0?: string;
|
||||
signal?: AbortSignal;
|
||||
timeout?: number;
|
||||
killSignal?: string | number;
|
||||
}
|
||||
|
||||
type Readable =
|
||||
@@ -366,39 +450,62 @@ namespace SpawnOptions {
|
||||
| Request;
|
||||
}
|
||||
|
||||
interface Subprocess<Stdin, Stdout, Stderr> {
|
||||
interface Subprocess extends AsyncDisposable {
|
||||
readonly stdin: FileSink | number | undefined;
|
||||
readonly stdout: ReadableStream<Uint8Array> | number | undefined;
|
||||
readonly stderr: ReadableStream<Uint8Array> | number | undefined;
|
||||
readonly readable: ReadableStream<Uint8Array> | number | undefined;
|
||||
readonly pid: number;
|
||||
// the exact stream types here are derived from the generic parameters
|
||||
readonly stdin: number | ReadableStream | FileSink | undefined;
|
||||
readonly stdout: number | ReadableStream | undefined;
|
||||
readonly stderr: number | ReadableStream | undefined;
|
||||
|
||||
readonly exited: Promise<number>;
|
||||
|
||||
readonly exitCode: number | undefined;
|
||||
readonly signalCode: Signal | null;
|
||||
readonly exitCode: number | null;
|
||||
readonly signalCode: NodeJS.Signals | null;
|
||||
readonly killed: boolean;
|
||||
|
||||
kill(exitCode?: number | NodeJS.Signals): void;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
kill(code?: number): void;
|
||||
|
||||
send(message: any): void;
|
||||
disconnect(): void;
|
||||
resourceUsage(): ResourceUsage | undefined;
|
||||
}
|
||||
|
||||
interface SyncSubprocess<Stdout, Stderr> {
|
||||
readonly pid: number;
|
||||
readonly success: boolean;
|
||||
// the exact buffer types here are derived from the generic parameters
|
||||
readonly stdout: Buffer | undefined;
|
||||
readonly stderr: Buffer | undefined;
|
||||
interface SyncSubprocess {
|
||||
stdout: Buffer | undefined;
|
||||
stderr: Buffer | undefined;
|
||||
exitCode: number;
|
||||
success: boolean;
|
||||
resourceUsage: ResourceUsage;
|
||||
signalCode?: string;
|
||||
exitedDueToTimeout?: true;
|
||||
pid: number;
|
||||
}
|
||||
|
||||
type ReadableSubprocess = Subprocess<any, "pipe", "pipe">;
|
||||
type WritableSubprocess = Subprocess<"pipe", any, any>;
|
||||
type PipedSubprocess = Subprocess<"pipe", "pipe", "pipe">;
|
||||
type NullSubprocess = Subprocess<null, null, null>;
|
||||
interface ResourceUsage {
|
||||
contextSwitches: {
|
||||
voluntary: number;
|
||||
involuntary: number;
|
||||
};
|
||||
|
||||
type ReadableSyncSubprocess = SyncSubprocess<"pipe", "pipe">;
|
||||
type NullSyncSubprocess = SyncSubprocess<null, null>;
|
||||
cpuTime: {
|
||||
user: number;
|
||||
system: number;
|
||||
total: number;
|
||||
};
|
||||
maxRSS: number;
|
||||
|
||||
messages: {
|
||||
sent: number;
|
||||
received: number;
|
||||
};
|
||||
ops: {
|
||||
in: number;
|
||||
out: number;
|
||||
};
|
||||
shmSize: number;
|
||||
signalCount: number;
|
||||
swapCount: number;
|
||||
}
|
||||
|
||||
type Signal =
|
||||
| "SIGABRT"
|
||||
|
||||
@@ -11,7 +11,7 @@ Bun.listen({
|
||||
socket: {
|
||||
data(socket, data) {}, // message received from client
|
||||
open(socket) {}, // socket opened
|
||||
close(socket) {}, // socket closed
|
||||
close(socket, error) {}, // socket closed
|
||||
drain(socket) {}, // socket ready for more data
|
||||
error(socket, error) {}, // error handler
|
||||
},
|
||||
@@ -30,7 +30,7 @@ Bun.listen({
|
||||
open(socket) {},
|
||||
data(socket, data) {},
|
||||
drain(socket) {},
|
||||
close(socket) {},
|
||||
close(socket, error) {},
|
||||
error(socket, error) {},
|
||||
},
|
||||
});
|
||||
@@ -122,7 +122,7 @@ const socket = await Bun.connect({
|
||||
socket: {
|
||||
data(socket, data) {},
|
||||
open(socket) {},
|
||||
close(socket) {},
|
||||
close(socket, error) {},
|
||||
drain(socket) {},
|
||||
error(socket, error) {},
|
||||
|
||||
|
||||
1028
docs/bundler/css.md
Normal file
1028
docs/bundler/css.md
Normal file
File diff suppressed because it is too large
Load Diff
145
docs/bundler/css_modules.md
Normal file
145
docs/bundler/css_modules.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# CSS Modules
|
||||
|
||||
Bun's bundler also supports bundling [CSS modules](https://css-tricks.com/css-modules-part-1-need/) in addition to [regular CSS](/docs/bundler/css) with support for the following features:
|
||||
|
||||
- Automatically detecting CSS module files (`.module.css`) with zero configuration
|
||||
- Composition (`composes` property)
|
||||
- Importing CSS modules into JSX/TSX
|
||||
- Warnings/errors for invalid usages of CSS modules
|
||||
|
||||
A CSS module is a CSS file (with the `.module.css` extension) where are all class names and animations are scoped to the file. This helps you avoid class name collisions as CSS declarations are globally scoped by default.
|
||||
|
||||
Under the hood, Bun's bundler transforms locally scoped class names into unique identifiers.
|
||||
|
||||
## Getting started
|
||||
|
||||
Create a CSS file with the `.module.css` extension:
|
||||
|
||||
```css
|
||||
/* styles.module.css */
|
||||
.button {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* other-styles.module.css */
|
||||
.button {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
You can then import this file, for example into a TSX file:
|
||||
|
||||
```tsx
|
||||
import styles from "./styles.module.css";
|
||||
import otherStyles from "./other-styles.module.css";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<button className={styles.button}>Red button!</button>
|
||||
<button className={otherStyles.button}>Blue button!</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The `styles` object from importing the CSS module file will be an object with all class names as keys and
|
||||
their unique identifiers as values:
|
||||
|
||||
```tsx
|
||||
import styles from "./styles.module.css";
|
||||
import otherStyles from "./other-styles.module.css";
|
||||
|
||||
console.log(styles);
|
||||
console.log(otherStyles);
|
||||
```
|
||||
|
||||
This will output:
|
||||
|
||||
```ts
|
||||
{
|
||||
button: "button_123";
|
||||
}
|
||||
|
||||
{
|
||||
button: "button_456";
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, the class names are unique to each file, avoiding any collisions!
|
||||
|
||||
### Composition
|
||||
|
||||
CSS modules allow you to _compose_ class selectors together. This lets you reuse style rules across multiple classes.
|
||||
|
||||
For example:
|
||||
|
||||
```css
|
||||
/* styles.module.css */
|
||||
.button {
|
||||
composes: background;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
Would be the same as writing:
|
||||
|
||||
```css
|
||||
.button {
|
||||
background-color: blue;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
There are a couple rules to keep in mind when using `composes`:
|
||||
|
||||
- A `composes` property must come before any regular CSS properties or declarations
|
||||
- You can only use `composes` on a **simple selector with a single class name**:
|
||||
|
||||
```css
|
||||
#button {
|
||||
/* Invalid! `#button` is not a class selector */
|
||||
composes: background;
|
||||
}
|
||||
|
||||
.button,
|
||||
.button-secondary {
|
||||
/* Invalid! `.button, .button-secondary` is not a simple selector */
|
||||
composes: background;
|
||||
}
|
||||
```
|
||||
|
||||
{% /callout %}
|
||||
|
||||
### Composing from a separate CSS module file
|
||||
|
||||
You can also compose from a separate CSS module file:
|
||||
|
||||
```css
|
||||
/* background.module.css */
|
||||
.background {
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
/* styles.module.css */
|
||||
.button {
|
||||
composes: background from "./background.module.css";
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
When composing classes from separate files, be sure that they do not contain the same properties.
|
||||
|
||||
The CSS module spec says that composing classes from separate files with conflicting properties is
|
||||
undefined behavior, meaning that the output may differ and be unreliable.
|
||||
{% /callout %}
|
||||
@@ -309,5 +309,4 @@ This works similarly to how [`Bun.build` processes HTML files](/docs/bundler/htm
|
||||
|
||||
## This is a work in progress
|
||||
|
||||
- ~Client-side hot reloading isn't wired up yet. It will be in the future.~ New in Bun v1.2.3
|
||||
- This doesn't support `bun build` yet. It also will in the future.
|
||||
|
||||
234
docs/bundler/hmr.md
Normal file
234
docs/bundler/hmr.md
Normal file
@@ -0,0 +1,234 @@
|
||||
Hot Module Replacement (HMR) allows you to update modules in a running
|
||||
application without needing a full page reload. This preserves the application
|
||||
state and improves the development experience.
|
||||
|
||||
HMR is enabled by default when using Bun's full-stack development server.
|
||||
|
||||
## `import.meta.hot` API Reference
|
||||
|
||||
Bun implements a client-side HMR API modeled after [Vite's `import.meta.hot` API](https://vitejs.dev/guide/api-hmr.html). It can be checked for with `if (import.meta.hot)`, tree-shaking it in production
|
||||
|
||||
```ts
|
||||
if (import.meta.hot) {
|
||||
// HMR APIs are available.
|
||||
}
|
||||
```
|
||||
|
||||
However, **this check is often not needed** as Bun will dead-code-eliminate
|
||||
calls to all of the HMR APIs in production builds.
|
||||
|
||||
```ts
|
||||
// This entire function call will be removed in production!
|
||||
import.meta.hot.dispose(() => {
|
||||
console.log("dispose");
|
||||
});
|
||||
```
|
||||
|
||||
For this to work, Bun forces these APIs to be called without indirection. That means the following do not work:
|
||||
|
||||
```ts#invalid-hmr-usage.ts
|
||||
// INVALID: Assigning `hot` to a variable
|
||||
const hot = import.meta.hot;
|
||||
hot.accept();
|
||||
|
||||
// INVALID: Assigning `import.meta` to a variable
|
||||
const meta = import.meta;
|
||||
meta.hot.accept();
|
||||
console.log(meta.hot.data);
|
||||
|
||||
// INVALID: Passing to a function
|
||||
doSomething(import.meta.hot.dispose);
|
||||
|
||||
// OK: The full phrase "import.meta.hot.<API>" must be called directly:
|
||||
import.meta.hot.accept();
|
||||
|
||||
// OK: `data` can be passed to functions:
|
||||
doSomething(import.meta.hot.data);
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
|
||||
**Note** — The HMR API is still a work in progress. Some features are missing. HMR can be disabled in `Bun.serve` by setting the `development` option to `{ hmr: false }`.
|
||||
|
||||
{% endcallout %}
|
||||
|
||||
| | Method | Notes |
|
||||
| --- | ------------------ | --------------------------------------------------------------------- |
|
||||
| ✅ | `hot.accept()` | Indicate that a hot update can be replaced gracefully. |
|
||||
| ✅ | `hot.data` | Persist data between module evaluations. |
|
||||
| ✅ | `hot.dispose()` | Add a callback function to run when a module is about to be replaced. |
|
||||
| ❌ | `hot.invalidate()` | |
|
||||
| ✅ | `hot.on()` | Attach an event listener |
|
||||
| ✅ | `hot.off()` | Remove an event listener from `on`. |
|
||||
| ❌ | `hot.send()` | |
|
||||
| 🚧 | `hot.prune()` | **NOTE**: Callback is currently never called. |
|
||||
| ✅ | `hot.decline()` | No-op to match Vite's `import.meta.hot` |
|
||||
|
||||
### `import.meta.hot.accept()`
|
||||
|
||||
The `accept()` method indicates that a module can be hot-replaced. When called
|
||||
without arguments, it indicates that this module can be replaced simply by
|
||||
re-evaluating the file. After a hot update, importers of this module will be
|
||||
automatically patched.
|
||||
|
||||
```ts#index.ts
|
||||
import { getCount } from "./foo.ts";
|
||||
|
||||
console.log("count is ", getCount());
|
||||
|
||||
import.meta.hot.accept();
|
||||
|
||||
export function getNegativeCount() {
|
||||
return -getCount();
|
||||
}
|
||||
```
|
||||
|
||||
This creates a hot-reloading boundary for all of the files that `index.ts`
|
||||
imports. That means whenever `foo.ts` or any of its dependencies are saved, the
|
||||
update will bubble up to `index.ts` will re-evaluate. Files that import
|
||||
`index.ts` will then be patched to import the new version of
|
||||
`getNegativeCount()`. If only `index.ts` is updated, only the one file will be
|
||||
re-evaluated, and the counter in `foo.ts` is reused.
|
||||
|
||||
This may be used in combination with `import.meta.hot.data` to transfer state
|
||||
from the previous module to the new one.
|
||||
|
||||
When no modules call `import.meta.hot.accept()` (and there isn't React Fast
|
||||
Refresh or a plugin calling it for you), the page will reload when the file
|
||||
updates, and a console warning shows which files were invalidated. This warning
|
||||
is safe to ignore if it makes more sense to rely on full page reloads.
|
||||
|
||||
#### With callback
|
||||
|
||||
When provided one callback, `import.meta.hot.accept` will function how it does
|
||||
in Vite. Instead of patching the importers of this module, it will call the
|
||||
callback with the new module.
|
||||
|
||||
```ts
|
||||
export const count = 0;
|
||||
|
||||
import.meta.hot.accept(newModule => {
|
||||
if (newModule) {
|
||||
// newModule is undefined when SyntaxError happened
|
||||
console.log("updated: count is now ", newModule.count);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Prefer using `import.meta.hot.accept()` without an argument as it usually makes your code easier to understand.
|
||||
|
||||
#### Accepting other modules
|
||||
|
||||
```ts
|
||||
import { count } from "./foo";
|
||||
|
||||
import.meta.hot.accept("./foo", () => {
|
||||
if (!newModule) return;
|
||||
|
||||
console.log("updated: count is now ", count);
|
||||
});
|
||||
```
|
||||
|
||||
Indicates that a dependency's module can be accepted. When the dependency is updated, the callback will be called with the new module.
|
||||
|
||||
#### With multiple dependencies
|
||||
|
||||
```ts
|
||||
import.meta.hot.accept(["./foo", "./bar"], newModules => {
|
||||
// newModules is an array where each item corresponds to the updated module
|
||||
// or undefined if that module had a syntax error
|
||||
});
|
||||
```
|
||||
|
||||
Indicates that multiple dependencies' modules can be accepted. This variant accepts an array of dependencies, where the callback will receive the updated modules, and `undefined` for any that had errors.
|
||||
|
||||
### `import.meta.hot.data`
|
||||
|
||||
`import.meta.hot.data` maintains state between module instances during hot
|
||||
replacement, enabling data transfer from previous to new versions. When
|
||||
`import.meta.hot.data` is written into, Bun will also mark this module as
|
||||
capable of self-accepting (equivalent of calling `import.meta.hot.accept()`).
|
||||
|
||||
```ts
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { App } from "./app";
|
||||
|
||||
const root = import.meta.hot.data.root ??= createRoot(elem);
|
||||
root.render(<App />); // re-use an existing root
|
||||
```
|
||||
|
||||
In production, `data` is inlined to be `{}`, meaning it cannot be used as a state holder.
|
||||
|
||||
The above pattern is recommended for stateful modules because Bun knows it can minify `{}.prop ??= value` into `value` in production.
|
||||
|
||||
### `import.meta.hot.dispose()`
|
||||
|
||||
Attaches an on-dispose callback. This is called:
|
||||
|
||||
- Just before the module is replaced with another copy (before the next is loaded)
|
||||
- After the module is detached (removing all imports to this module, see `import.meta.hot.prune()`)
|
||||
|
||||
```ts
|
||||
const sideEffect = setupSideEffect();
|
||||
|
||||
import.meta.hot.dispose(() => {
|
||||
sideEffect.cleanup();
|
||||
});
|
||||
```
|
||||
|
||||
This callback is not called on route navigation or when the browser tab closes.
|
||||
|
||||
Returning a promise will delay module replacement until the module is disposed.
|
||||
All dispose callbacks are called in parallel.
|
||||
|
||||
### `import.meta.hot.prune()`
|
||||
|
||||
Attaches an on-prune callback. This is called when all imports to this module
|
||||
are removed, but the module was previously loaded.
|
||||
|
||||
This can be used to clean up resources that were created when the module was
|
||||
loaded. Unlike `import.meta.hot.dispose()`, this pairs much better with `accept`
|
||||
and `data` to manage stateful resources. A full example managing a `WebSocket`:
|
||||
|
||||
```ts
|
||||
import { something } from "./something";
|
||||
|
||||
// Initialize or re-use a WebSocket connection
|
||||
export const ws = (import.meta.hot.data.ws ??= new WebSocket(location.origin));
|
||||
|
||||
// If the module's import is removed, clean up the WebSocket connection.
|
||||
import.meta.hot.prune(() => {
|
||||
ws.close();
|
||||
});
|
||||
```
|
||||
|
||||
If `dispose` was used instead, the WebSocket would close and re-open on every
|
||||
hot update. Both versions of the code will prevent page reloads when imported
|
||||
files are updated.
|
||||
|
||||
### `import.meta.hot.on()` and `off()`
|
||||
|
||||
`on()` and `off()` are used to listen for events from the HMR runtime. Event names are prefixed with a prefix so that plugins do not conflict with each other.
|
||||
|
||||
```ts
|
||||
import.meta.hot.on("bun:beforeUpdate", () => {
|
||||
console.log("before a hot update");
|
||||
});
|
||||
```
|
||||
|
||||
When a file is replaced, all of its event listeners are automatically removed.
|
||||
|
||||
A list of all built-in events:
|
||||
|
||||
| Event | Emitted when |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `bun:beforeUpdate` | before a hot update is applied. |
|
||||
| `bun:afterUpdate` | after a hot update is applied. |
|
||||
| `bun:beforeFullReload` | before a full page reload happens. |
|
||||
| `bun:beforePrune` | before prune callbacks are called. |
|
||||
| `bun:invalidate` | when a module is invalidated with `import.meta.hot.invalidate()` |
|
||||
| `bun:error` | when a build or runtime error occurs |
|
||||
| `bun:ws:disconnect` | when the HMR WebSocket connection is lost. This can indicate the development server is offline. |
|
||||
| `bun:ws:connect` | when the HMR WebSocket connects or re-connects. |
|
||||
|
||||
For compatibility with Vite, the above events are also available via `vite:*` prefix instead of `bun:*`.
|
||||
@@ -4,6 +4,12 @@ The Bun bundler implements a set of default loaders out of the box. As a rule of
|
||||
|
||||
Bun uses the file extension to determine which built-in _loader_ should be used to parse the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building [plugins](https://bun.sh/docs/bundler/plugins) that extend Bun with custom loaders.
|
||||
|
||||
You can explicitly specify which loader to use using the 'loader' import attribute.
|
||||
|
||||
```ts
|
||||
import my_toml from "./my_file" with { loader: "toml" };
|
||||
```
|
||||
|
||||
## Built-in loaders
|
||||
|
||||
### `js`
|
||||
|
||||
@@ -82,6 +82,11 @@ The `--dry-run` flag can be used to simulate the publish process without actuall
|
||||
$ bun publish --dry-run
|
||||
```
|
||||
|
||||
### `--gzip-level`
|
||||
|
||||
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
||||
{% bunCLIUsage command="publish" /%}
|
||||
|
||||
### `--auth-type`
|
||||
|
||||
If you have 2FA enabled for your npm account, `bun publish` will prompt you for a one-time password. This can be done through a browser or the CLI. The `--auth-type` flag can be used to tell the npm registry which method you prefer. The possible values are `web` and `legacy`, with `web` being the default.
|
||||
@@ -102,7 +107,6 @@ Provide a one-time password directly to the CLI. If the password is valid, this
|
||||
$ bun publish --otp 123456
|
||||
```
|
||||
|
||||
### `--gzip-level`
|
||||
|
||||
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
||||
{% bunCLIUsage command="publish" /%}
|
||||
{% callout %}
|
||||
**Note** - `bun publish` respects the `NPM_CONFIG_TOKEN` environment variable which can be used when publishing in github actions or automated workflows.
|
||||
{% /callout %}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
Running `bun install` will create a lockfile called `bun.lock`.
|
||||
|
||||
https://bun.sh/blog/bun-lock-text-lockfile
|
||||
|
||||
#### Should it be committed to git?
|
||||
|
||||
Yes
|
||||
|
||||
@@ -215,12 +215,19 @@ export default {
|
||||
page("bundler", "`Bun.build`", {
|
||||
description: "Bundle code for consumption in the browser with Bun's native bundler.",
|
||||
}),
|
||||
page("bundler/html", "Bundle frontend & static sites", {
|
||||
page("bundler/html", "HTML & static sites", {
|
||||
description: `Zero-config HTML bundler for single-page apps and multi-page apps. Automatic bundling, TailwindCSS plugins, TypeScript, JSX, React support, and incredibly fast builds`,
|
||||
}),
|
||||
page("bundler/css", "CSS", {
|
||||
description: `Production ready CSS bundler with support for modern CSS features, CSS modules, and more.`,
|
||||
}),
|
||||
page("bundler/fullstack", "Fullstack Dev Server", {
|
||||
description: "Serve your frontend and backend from the same app with Bun's dev server.",
|
||||
}),
|
||||
page("bundler/hmr", "Hot reloading", {
|
||||
description: `Update modules in a running application without reloading the page using import.meta.hot`,
|
||||
}),
|
||||
|
||||
page("bundler/loaders", "Loaders", {
|
||||
description: "Bun's built-in loaders for the bundler and runtime",
|
||||
}),
|
||||
|
||||
@@ -60,7 +60,7 @@ Visual Studio can be installed graphically using the wizard or through WinGet:
|
||||
|
||||
After Visual Studio, you need the following:
|
||||
|
||||
- LLVM 18.1.8
|
||||
- LLVM 19.1.7
|
||||
- Go
|
||||
- Rust
|
||||
- NASM
|
||||
@@ -81,7 +81,7 @@ After Visual Studio, you need the following:
|
||||
> irm https://get.scoop.sh | iex
|
||||
> scoop install nodejs-lts go rust nasm ruby perl ccache
|
||||
# scoop seems to be buggy if you install llvm and the rest at the same time
|
||||
> scoop install llvm@18.1.8
|
||||
> scoop install llvm@19.1.7
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
@@ -142,7 +142,7 @@ Some methods are not optimized yet.
|
||||
|
||||
### [`node:util`](https://nodejs.org/api/util.html)
|
||||
|
||||
🟡 Missing `MIMEParams` `MIMEType` `debug` `getSystemErrorMap` `transferableAbortController` `transferableAbortSignal` `stripVTControlCharacters`
|
||||
🟡 Missing `getCallSite` `getCallSites` `getSystemErrorMap` `getSystemErrorMessage` `transferableAbortSignal` `transferableAbortController` `MIMEType` `MIMEParams`
|
||||
|
||||
### [`node:v8`](https://nodejs.org/api/v8.html)
|
||||
|
||||
@@ -174,7 +174,7 @@ Some methods are not optimized yet.
|
||||
|
||||
### [`node:test`](https://nodejs.org/api/test.html)
|
||||
|
||||
🔴 Not implemented. Use [`bun:test`](https://bun.sh/docs/cli/test) instead.
|
||||
🟡 Partly implemented. Missing mocks, snapshots, timers. Use [`bun:test`](https://bun.sh/docs/cli/test) instead.
|
||||
|
||||
### [`node:trace_events`](https://nodejs.org/api/tracing.html)
|
||||
|
||||
@@ -346,7 +346,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
|
||||
|
||||
### [`process`](https://nodejs.org/api/process.html)
|
||||
|
||||
🟡 Mostly implemented. `process.binding` (internal Node.js bindings some packages rely on) is partially implemented. `process.title` is a currently a no-op on macOS & Linux. `getActiveResourcesInfo` `setActiveResourcesInfo`, `getActiveResources` and `setSourceMapsEnabled` are stubs. Newer APIs like `process.loadEnvFile` and `process.getBuiltinModule` are not implemented yet.
|
||||
🟡 Mostly implemented. `process.binding` (internal Node.js bindings some packages rely on) is partially implemented. `process.title` is currently a no-op on macOS & Linux. `getActiveResourcesInfo` `setActiveResourcesInfo`, `getActiveResources` and `setSourceMapsEnabled` are stubs. Newer APIs like `process.loadEnvFile` and `process.getBuiltinModule` are not implemented yet.
|
||||
|
||||
### [`queueMicrotask()`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask)
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ await Bun.build({
|
||||
|
||||
{% callout %}
|
||||
|
||||
**NOTE**: Plugin lifcycle callbacks (`onStart()`, `onResolve()`, etc.) do not have the ability to modify the `build.config` object in the `setup()` function. If you want to mutate `build.config`, you must do so directly in the `setup()` function:
|
||||
**NOTE**: Plugin lifecycle callbacks (`onStart()`, `onResolve()`, etc.) do not have the ability to modify the `build.config` object in the `setup()` function. If you want to mutate `build.config`, you must do so directly in the `setup()` function:
|
||||
|
||||
```ts
|
||||
await Bun.build({
|
||||
@@ -400,7 +400,7 @@ type Loader = "js" | "jsx" | "ts" | "tsx" | "css" | "json" | "toml" | "object";
|
||||
|
||||
### Namespaces
|
||||
|
||||
`onLoad` and `onResolve` accept an optional `namespace` string. What is a namespaace?
|
||||
`onLoad` and `onResolve` accept an optional `namespace` string. What is a namespace?
|
||||
|
||||
Every module has a namespace. Namespaces are used to prefix the import in transpiled code; for instance, a loader with a `filter: /\.yaml$/` and `namespace: "yaml:"` will transform an import from `./myfile.yaml` into `yaml:./myfile.yaml`.
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Tell LLDB what to do when the debugged process receives SIGPWR: pass it through to the process
|
||||
# (-p), but do not stop the process (-s) or notify the user (-n).
|
||||
#
|
||||
# JSC's garbage collector sends this signal (as configured by Bun WebKit in
|
||||
# Thread::initializePlatformThreading() in ThreadingPOSIX.cpp) to the JS thread to suspend or resume
|
||||
# it. So stopping the process would just create noise when debugging any long-running script.
|
||||
process handle -p true -s false -n false SIGPWR
|
||||
|
||||
command script import misctools/lldb/lldb_pretty_printers.py
|
||||
type category enable zig.lang
|
||||
type category enable zig.std
|
||||
|
||||
command script import misctools/lldb/lldb_webkit.py
|
||||
@@ -329,7 +329,7 @@ def btjs(debugger, command, result, internal_dict):
|
||||
addressFormat = '#0{width}x'.format(width=target.GetAddressByteSize() * 2 + 2)
|
||||
process = target.GetProcess()
|
||||
thread = process.GetSelectedThread()
|
||||
jscModule = target.module["JavaScriptCore"]
|
||||
jscModule = target.module["JavaScriptCore"] or target.module["bun"] or target.module["bun-debug"]
|
||||
|
||||
if jscModule.FindSymbol("JSC::CallFrame::describeFrame").GetSize() or jscModule.FindSymbol("_ZN3JSC9CallFrame13describeFrameEv").GetSize():
|
||||
annotateJSFrames = True
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "bun",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"workspaces": [
|
||||
"./packages/bun-types"
|
||||
],
|
||||
@@ -53,7 +53,7 @@
|
||||
"lint:fix": "oxlint --config oxlint.json --fix",
|
||||
"test": "node scripts/runner.node.mjs --exec-path ./build/debug/bun-debug",
|
||||
"test:release": "node scripts/runner.node.mjs --exec-path ./build/release/bun",
|
||||
"banned": "bun packages/bun-internal-test/src/linter.ts",
|
||||
"banned": "bun test test/internal/ban-words.test.ts",
|
||||
"zig": "vendor/zig/zig.exe",
|
||||
"zig:fmt": "bun run zig-format",
|
||||
"zig:check": "bun run zig build check --summary new",
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
" != undefined": "This is by definition Undefined Behavior.",
|
||||
" == undefined": "This is by definition Undefined Behavior.",
|
||||
"@import(\"root\").bun.": "Only import 'bun' once",
|
||||
"std.debug.assert": "Use bun.assert instead",
|
||||
"std.debug.dumpStackTrace": "Use bun.handleErrorReturnTrace or bun.crash_handler.dumpStackTrace instead",
|
||||
"std.debug.print": "Don't let this be committed",
|
||||
"std.mem.indexOfAny(u8": "Use bun.strings.indexOfAny",
|
||||
"undefined != ": "This is by definition Undefined Behavior.",
|
||||
"undefined == ": "This is by definition Undefined Behavior.",
|
||||
"bun.toFD(std.fs.cwd().fd)": "Use bun.FD.cwd()",
|
||||
"std.StringArrayHashMapUnmanaged(": "bun.StringArrayHashMapUnmanaged has a faster `eql`",
|
||||
"std.StringArrayHashMap(": "bun.StringArrayHashMap has a faster `eql`",
|
||||
"std.StringHashMapUnmanaged(": "bun.StringHashMapUnmanaged has a faster `eql`",
|
||||
"std.StringHashMap(": "bun.StringHashMaphas a faster `eql`",
|
||||
"std.enums.tagName(": "Use bun.tagName instead",
|
||||
"": ""
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
import { $ } from "bun";
|
||||
import BANNED from "./banned.json";
|
||||
import * as action from "@actions/core";
|
||||
|
||||
const IGNORED_FOLDERS = [
|
||||
// list of folders to ignore
|
||||
"windows-shim",
|
||||
];
|
||||
|
||||
const ci = !!process.env["GITHUB_ACTIONS"];
|
||||
process.chdir(require("path").join(import.meta.dir, "../../../"));
|
||||
let bad = [];
|
||||
let report = "";
|
||||
const write = (text: string) => {
|
||||
process.stdout.write(text);
|
||||
report += text;
|
||||
};
|
||||
for (const [banned, suggestion] of Object.entries(BANNED)) {
|
||||
if (banned.length === 0) continue;
|
||||
// Run git grep to find occurrences of std.debug.assert in .zig files
|
||||
// .nothrow() is here since git will exit with non-zero if no matches are found.
|
||||
let stdout = await $`git grep -n -F "${banned}" "src/**.zig" | grep -v -F '//' | grep -v -F bench`.nothrow().text();
|
||||
|
||||
stdout = stdout.trim();
|
||||
if (stdout.length === 0) continue;
|
||||
|
||||
let lines = stdout.split("\n");
|
||||
// Parse each line to extract filename and line number
|
||||
const matches = lines
|
||||
.filter(line => !IGNORED_FOLDERS.some(folder => line.includes(folder)))
|
||||
.map(line => {
|
||||
const [path, lineNumber, ...text] = line.split(":");
|
||||
return { path, lineNumber, banned, suggestion, text: text.join(":") };
|
||||
});
|
||||
// Check if we got any output
|
||||
// Split the output into lines
|
||||
if (matches.length === 0) continue;
|
||||
|
||||
write(`Banned **'${banned}'** found in the following locations:` + "\n");
|
||||
matches.forEach(match => {
|
||||
write(`${match.path}:${match.lineNumber}: ${match.text.trim()}` + "\n");
|
||||
});
|
||||
bad = bad.concat(matches);
|
||||
}
|
||||
|
||||
if (report.length === 0) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
function link({ path, lineNumber, suggestion, banned }) {
|
||||
action.error(`Lint failure: ${banned} is banned, ${suggestion}`, {
|
||||
file: path,
|
||||
startLine: Number(lineNumber),
|
||||
endLine: Number(lineNumber),
|
||||
});
|
||||
return `[\`${path}:${lineNumber}\`](https://github.com/oven-sh/bun/blob/${process.env.GITHUB_SHA}/${path}#L${lineNumber})`;
|
||||
}
|
||||
|
||||
if (ci) {
|
||||
if (report.length > 0) {
|
||||
action.setFailed(`${bad.length} lint failures`);
|
||||
}
|
||||
action.setOutput("count", bad.length);
|
||||
action.setOutput("text_output", bad.map(m => `- ${link(m)}: ${m.banned} is banned, ${m.suggestion}`).join("\n"));
|
||||
action.setOutput("json_output", JSON.stringify(bad));
|
||||
action.summary.addRaw(report);
|
||||
await action.summary.write();
|
||||
}
|
||||
|
||||
process.exit(1);
|
||||
34
packages/bun-plugin-svelte/.gitignore
vendored
Normal file
34
packages/bun-plugin-svelte/.gitignore
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# dependencies (bun install)
|
||||
node_modules
|
||||
|
||||
# output
|
||||
out
|
||||
dist
|
||||
*.tgz
|
||||
|
||||
# code coverage
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# logs
|
||||
logs
|
||||
_.log
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# caches
|
||||
.eslintcache
|
||||
.cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
69
packages/bun-plugin-svelte/README.md
Normal file
69
packages/bun-plugin-svelte/README.md
Normal file
@@ -0,0 +1,69 @@
|
||||
<p align="center">
|
||||
<a href="https://bun.sh"><img src="https://github.com/user-attachments/assets/50282090-adfd-4ddb-9e27-c30753c6b161" alt="Logo" height=170></a>
|
||||
</p>
|
||||
<h1 align="center"><code>bun-plugin-svelte</code></h1>
|
||||
|
||||
The official [Svelte](https://svelte.dev/) plugin for [Bun](https://bun.sh/).
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ bun add -D bun-plugin-svelte
|
||||
```
|
||||
|
||||
## Dev Server Usage
|
||||
|
||||
`bun-plugin-svelte` integrates with Bun's [Fullstack Dev Server](https://bun.sh/docs/bundler/fullstack), giving you
|
||||
HMR when developing your Svelte app.
|
||||
|
||||
Start by registering it in your [bunfig.toml](https://bun.sh/docs/runtime/bunfig):
|
||||
|
||||
```toml
|
||||
[serve.static]
|
||||
plugins = ["bun-plugin-svelte"]
|
||||
```
|
||||
|
||||
Then start your dev server:
|
||||
|
||||
```
|
||||
$ bun index.html
|
||||
```
|
||||
|
||||
See the [example](https://github.com/oven-sh/bun/tree/main/packages/bun-plugin-svelte/example) for a complete example.
|
||||
|
||||
## Bundler Usage
|
||||
|
||||
`bun-plugin-svelte` lets you bundle Svelte components with [`Bun.build`](https://bun.sh/docs/bundler).
|
||||
|
||||
```ts
|
||||
// build.ts
|
||||
// to use: bun run build.ts
|
||||
import { SveltePlugin } from "bun-plugin-svelte"; // NOTE: not published to npm yet
|
||||
|
||||
Bun.build({
|
||||
entrypoints: ["src/index.ts"],
|
||||
outdir: "dist",
|
||||
target: "browser",
|
||||
sourcemap: true, // sourcemaps not yet supported
|
||||
plugins: [
|
||||
SveltePlugin({
|
||||
development: true, // turn off for prod builds. Defaults to false
|
||||
}),
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
## Server-Side Usage
|
||||
|
||||
`bun-plugin-svelte` does not yet support server-side imports (e.g. for SSR).
|
||||
This will be added in the near future.
|
||||
|
||||
## Not Yet Supported
|
||||
|
||||
Support for these features will be added in the near future
|
||||
|
||||
- Server-side imports/rendering
|
||||
- Source maps
|
||||
- CSS extensions (e.g. tailwind) in `<style>` blocks
|
||||
- TypeScript-specific features (e.g. enums and namespaces). If you're using
|
||||
TypeScript 5.8, consider enabling [`--erasableSyntaxOnly`](https://devblogs.microsoft.com/typescript/announcing-typescript-5-8-beta/#the---erasablesyntaxonly-option)
|
||||
65
packages/bun-plugin-svelte/bun.lock
Normal file
65
packages/bun-plugin-svelte/bun.lock
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "bun-plugin-svelte",
|
||||
"devDependencies": {
|
||||
"bun-types": "canary",
|
||||
"svelte": "^5.20.4",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^5",
|
||||
"typescript": "^5",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||
|
||||
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="],
|
||||
|
||||
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||
|
||||
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
|
||||
|
||||
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
|
||||
|
||||
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
|
||||
|
||||
"@types/node": ["@types/node@22.13.5", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg=="],
|
||||
|
||||
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
|
||||
|
||||
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
|
||||
|
||||
"acorn-typescript": ["acorn-typescript@1.4.13", "", { "peerDependencies": { "acorn": ">=8.9.0" } }, "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q=="],
|
||||
|
||||
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
||||
|
||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.4-canary.20250226T140704", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-P8b2CGLtbvi/kQ4dPHBhU5qkguIjHMYCjNqjWDTKSnodWDTbcv9reBdktZJ7m5SF4m15JLthfFq2PtwKpA9a+w=="],
|
||||
|
||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||
|
||||
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
||||
|
||||
"esrap": ["esrap@1.4.5", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g=="],
|
||||
|
||||
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||
|
||||
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||
|
||||
"svelte": ["svelte@5.20.4", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "acorn-typescript": "^1.4.13", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^1.4.3", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-2Mo/AfObaw9zuD0u1JJ7sOVzRCGcpETEyDkLbtkcctWpCMCIyT0iz83xD8JT29SR7O4SgswuPRIDYReYF/607A=="],
|
||||
|
||||
"typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="],
|
||||
|
||||
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
|
||||
|
||||
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
||||
}
|
||||
}
|
||||
311
packages/bun-plugin-svelte/example/App.svelte
Normal file
311
packages/bun-plugin-svelte/example/App.svelte
Normal file
@@ -0,0 +1,311 @@
|
||||
<script lang="ts">
|
||||
import FeatureCard from "./FeatureCard.svelte";
|
||||
|
||||
const links = [
|
||||
{ text: "Bun Documentation", url: "https://bun.sh/docs" },
|
||||
{ text: "Svelte Documentation", url: "https://svelte.dev/docs" },
|
||||
{ text: "GitHub", url: "https://github.com/oven-sh/bun/tree/main/packages/bun-plugin-svelte" },
|
||||
];
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="hero">
|
||||
<div class="logo-container">
|
||||
<a href="https://bun.sh" class="bun-logo">
|
||||
<img
|
||||
src="https://github.com/user-attachments/assets/50282090-adfd-4ddb-9e27-c30753c6b161"
|
||||
alt="Bun Logo"
|
||||
height="42"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<h1><span class="highlight">bun-plugin-svelte</span></h1>
|
||||
<p class="tagline">The official Svelte plugin for <a href="https://bun.sh" target="_blank">Bun</a></p>
|
||||
|
||||
<div class="cta-buttons">
|
||||
<a href="https://bun.sh/docs/bundler/html" class="button primary">🚀 Get Started</a>
|
||||
<a href="https://github.com/oven-sh/bun/tree/main/packages/bun-plugin-svelte/example" class="button secondary"
|
||||
>👀 View Examples</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="usage">
|
||||
<h2>🏃➡️ Quick Start</h2>
|
||||
|
||||
<div class="flex-grid">
|
||||
<div>
|
||||
<h3>1. Install from <a href="https://npmjs.com/package/bun-plugin-svelte" target="_blank">NPM</a></h3>
|
||||
<pre><code class="language-bash">bun add -D bun-plugin-svelte</code></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h3>2. Add it to your <a href="https://bun.sh/docs/runtime/bunfig" target="_blank">bunfig.toml</a></h3>
|
||||
<pre><code class="language-toml">
|
||||
[serve.static]
|
||||
plugins = ["bun-plugin-svelte"];
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="features">
|
||||
<h2>✨ Features</h2>
|
||||
<div class="feature-grid">
|
||||
<FeatureCard title="🔥 HMR Support" link="https://bun.sh/docs/bundler/html">
|
||||
Integrates with Bun's Fullstack Dev Server for hot module replacement
|
||||
</FeatureCard>
|
||||
<FeatureCard title="📦 Bundling" link="https://bun.sh/docs/bundler">
|
||||
Bundle Svelte components with <a href="https://bun.sh/docs/bundler">Bun.build</a>
|
||||
</FeatureCard>
|
||||
</div>
|
||||
|
||||
<section class="resources">
|
||||
<h2>📖 Resources</h2>
|
||||
<ul class="resource-links">
|
||||
{#each links as link}
|
||||
<li><a href={link.url} target="_blank" rel="noopener noreferrer">{link.text}</a></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p>Made with ❤️ by the Bun team</p>
|
||||
</footer>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
|
||||
"Helvetica Neue", sans-serif;
|
||||
background-color: #f9f9f9;
|
||||
color: #333;
|
||||
}
|
||||
:global(a) {
|
||||
color: #ff3e00;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:global(a::after) {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #ff3e00;
|
||||
transform: scaleX(0);
|
||||
transform-origin: bottom right;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
:global(a:hover::after) {
|
||||
transform: scaleX(1);
|
||||
transform-origin: bottom left;
|
||||
}
|
||||
|
||||
:global(a:visited) {
|
||||
color: #ff3e00;
|
||||
}
|
||||
|
||||
:global(pre > code.hljs) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 3rem 1rem;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
margin-bottom: 1.5rem;
|
||||
margin: auto 25%;
|
||||
}
|
||||
|
||||
.bun-logo {
|
||||
display: block;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.bun-logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.bun-logo img {
|
||||
max-width: 33vw;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: #ff3e00;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Don't apply the underline effect to buttons and resource links */
|
||||
.button::after,
|
||||
.resource-links li a::after,
|
||||
.bun-logo::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.button.primary {
|
||||
background-color: #ff3e00;
|
||||
color: white;
|
||||
box-shadow: 0 2px 10px rgba(255, 62, 0, 0.2);
|
||||
}
|
||||
|
||||
.button.primary:hover {
|
||||
background-color: #e63600;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(255, 62, 0, 0.3);
|
||||
}
|
||||
|
||||
.button.secondary {
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button.secondary:hover {
|
||||
background-color: #e6e6e6;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 3rem;
|
||||
padding: 2rem;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 1.5rem;
|
||||
color: #333;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.flex-grid {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
.flex-grid > div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feature-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f5f5f5;
|
||||
padding: 1rem;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.resource-links {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.resource-links li a {
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.resource-links li a:hover {
|
||||
background-color: #ff3e00;
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 2rem 0;
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.feature-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
margin-bottom: 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.resource-links {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
28
packages/bun-plugin-svelte/example/FeatureCard.svelte
Normal file
28
packages/bun-plugin-svelte/example/FeatureCard.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
let { title, link, children } = $props();
|
||||
</script>
|
||||
|
||||
<div class="feature-card">
|
||||
<h3>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</h3>
|
||||
<p>
|
||||
{@render children()}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.feature-card {
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-card h3 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
2
packages/bun-plugin-svelte/example/bunfig.toml
Normal file
2
packages/bun-plugin-svelte/example/bunfig.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[serve.static]
|
||||
plugins = ["bun-plugin-svelte"]
|
||||
25
packages/bun-plugin-svelte/example/index.html
Normal file
25
packages/bun-plugin-svelte/example/index.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<script type="module" src="./index.ts"></script>
|
||||
|
||||
<link rel="prefetch" href="https://bun.sh/docs/bundler/plugins" />
|
||||
<link rel="preconnect" href="https://bun.sh" />
|
||||
<link rel="preconnect" href="https://github.com" />
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/default.min.css"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/languages/toml.min.js"></script>
|
||||
|
||||
<script>
|
||||
hljs.highlightAll();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
29
packages/bun-plugin-svelte/example/index.ts
Normal file
29
packages/bun-plugin-svelte/example/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { mount, unmount } from "svelte";
|
||||
import App from "./App.svelte";
|
||||
|
||||
declare global {
|
||||
var didMount: boolean | undefined;
|
||||
var hljs: any;
|
||||
}
|
||||
|
||||
let app: Record<string, any> | undefined;
|
||||
|
||||
// mount the application entrypoint to the DOM on first load. On subsequent hot
|
||||
// updates, the app will be unmounted and re-mounted via the accept handler.
|
||||
|
||||
const root = document.getElementById("root")!;
|
||||
if (!globalThis.didMount) {
|
||||
app = mount(App, { target: root });
|
||||
}
|
||||
globalThis.didMount = true;
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept(async () => {
|
||||
// avoid unmounting twice when another update gets accepted while outros are playing
|
||||
if (!app) return;
|
||||
const prevApp = app;
|
||||
app = undefined;
|
||||
await unmount(prevApp, { outro: true });
|
||||
app = mount(App, { target: root });
|
||||
});
|
||||
}
|
||||
42
packages/bun-plugin-svelte/package.json
Normal file
42
packages/bun-plugin-svelte/package.json
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "bun-plugin-svelte",
|
||||
"version": "0.0.5",
|
||||
"description": "Official Svelte plugin for Bun",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oven-sh/bun",
|
||||
"directory": "packages/bun-plugin-svelte"
|
||||
},
|
||||
"homepage": "https://bun.sh",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"module": "src/index.ts",
|
||||
"index": "src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"example": "bun --config=./example/bunfig.toml example/index.html",
|
||||
"lint": "oxlint .",
|
||||
"fmt": "prettier --write .",
|
||||
"check:types": "tsc --noEmit",
|
||||
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir ./dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "canary",
|
||||
"svelte": "^5.20.4",
|
||||
"@threlte/core": "8.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^5"
|
||||
},
|
||||
"files": [
|
||||
"README.md",
|
||||
"bunfig.toml",
|
||||
"tsconfig.json",
|
||||
"modules.d.ts",
|
||||
"dist",
|
||||
"src",
|
||||
"!src/**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
17
packages/bun-plugin-svelte/src/index.spec.ts
Normal file
17
packages/bun-plugin-svelte/src/index.spec.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { describe, it, expect } from "bun:test";
|
||||
import { SveltePlugin } from "./index";
|
||||
|
||||
describe("SveltePlugin", () => {
|
||||
it.each([true, false, 0, 1, "hi"])("throws if passed a non-object (%p)", (badOptions: any) => {
|
||||
expect(() => SveltePlugin(badOptions)).toThrow(TypeError);
|
||||
});
|
||||
it("may be nullish or not provided", () => {
|
||||
expect(() => SveltePlugin()).not.toThrow();
|
||||
expect(() => SveltePlugin(null as any)).not.toThrow();
|
||||
expect(() => SveltePlugin(undefined)).not.toThrow();
|
||||
});
|
||||
|
||||
it.each([null, 1, "hi", {}, "Client"])("throws if forceSide is not 'client' or 'server' (%p)", (forceSide: any) => {
|
||||
expect(() => SveltePlugin({ forceSide })).toThrow(TypeError);
|
||||
});
|
||||
});
|
||||
144
packages/bun-plugin-svelte/src/index.ts
Normal file
144
packages/bun-plugin-svelte/src/index.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
import type { BunPlugin, BuildConfig, OnLoadResult } from "bun";
|
||||
import { basename } from "node:path";
|
||||
import { compile, compileModule } from "svelte/compiler";
|
||||
import {
|
||||
getBaseCompileOptions,
|
||||
validateOptions,
|
||||
type SvelteOptions,
|
||||
hash,
|
||||
getBaseModuleCompileOptions,
|
||||
} from "./options";
|
||||
|
||||
const kEmptyObject = Object.create(null);
|
||||
const virtualNamespace = "bun-svelte";
|
||||
|
||||
function SveltePlugin(options: SvelteOptions = kEmptyObject as SvelteOptions): BunPlugin {
|
||||
if (options != null) validateOptions(options);
|
||||
|
||||
/**
|
||||
* import specifier -> CSS source code
|
||||
*/
|
||||
const virtualCssModules = new Map<string, VirtualCSSModule>();
|
||||
type VirtualCSSModule = {
|
||||
/** Path to the svelte file whose css this is for */
|
||||
sourcePath: string;
|
||||
/** Source code */
|
||||
source: string;
|
||||
};
|
||||
|
||||
return {
|
||||
name: "bun-plugin-svelte",
|
||||
setup(builder) {
|
||||
// resolve "svelte" export conditions
|
||||
//
|
||||
// FIXME: the dev server does not currently respect bundler configs; it
|
||||
// just passes a fake one to plugins and then never uses it. we need to to
|
||||
// update it to ~not~ do this.
|
||||
if (builder?.config) {
|
||||
var conditions = builder.config.conditions ?? [];
|
||||
if (typeof conditions === "string") {
|
||||
conditions = [conditions];
|
||||
}
|
||||
conditions.push("svelte");
|
||||
builder.config.conditions = conditions;
|
||||
}
|
||||
|
||||
const { config = kEmptyObject as Partial<BuildConfig> } = builder;
|
||||
const baseCompileOptions = getBaseCompileOptions(options ?? (kEmptyObject as Partial<SvelteOptions>), config);
|
||||
const baseModuleCompileOptions = getBaseModuleCompileOptions(
|
||||
options ?? (kEmptyObject as Partial<SvelteOptions>),
|
||||
config,
|
||||
);
|
||||
|
||||
const ts = new Bun.Transpiler({
|
||||
loader: "ts",
|
||||
target: config.target,
|
||||
});
|
||||
|
||||
builder
|
||||
.onLoad({ filter: /\.svelte$/ }, async function onLoadSvelte(args) {
|
||||
const { path } = args;
|
||||
|
||||
const sourceText = await Bun.file(path).text();
|
||||
|
||||
const side =
|
||||
args && "side" in args // "side" only passed when run from dev server
|
||||
? (args as { side: "client" | "server" }).side
|
||||
: "server";
|
||||
const generate = baseCompileOptions.generate ?? side;
|
||||
|
||||
const hmr = Boolean((args as { hmr?: boolean })["hmr"] ?? process.env.NODE_ENV !== "production");
|
||||
const result = compile(sourceText, {
|
||||
...baseCompileOptions,
|
||||
generate,
|
||||
filename: args.path,
|
||||
hmr,
|
||||
});
|
||||
|
||||
var { js, css } = result;
|
||||
if (css?.code && generate != "server") {
|
||||
const uid = `${basename(path)}-${hash(path)}-style`.replaceAll(`"`, `'`);
|
||||
const virtualName = virtualNamespace + ":" + uid + ".css";
|
||||
virtualCssModules.set(virtualName, { sourcePath: path, source: css.code });
|
||||
js.code += `\nimport "${virtualName}";`;
|
||||
}
|
||||
|
||||
return {
|
||||
contents: result.js.code,
|
||||
loader: "ts",
|
||||
} satisfies OnLoadResult;
|
||||
// TODO: allow plugins to return multiple results.
|
||||
// TODO: support layered sourcemaps
|
||||
})
|
||||
.onLoad({ filter: /\.svelte.[tj]s$/ }, async function onLoadSvelteModule(args) {
|
||||
const { path } = args;
|
||||
|
||||
const side =
|
||||
args && "side" in args // "side" only passed when run from dev server
|
||||
? (args as { side: "client" | "server" }).side
|
||||
: "server";
|
||||
const generate = baseModuleCompileOptions.generate ?? side;
|
||||
|
||||
var sourceText = await Bun.file(path).text();
|
||||
if (path.endsWith(".ts")) {
|
||||
sourceText = await ts.transform(sourceText);
|
||||
}
|
||||
const result = compileModule(sourceText, {
|
||||
...baseModuleCompileOptions,
|
||||
generate,
|
||||
filename: args.path,
|
||||
});
|
||||
|
||||
// NOTE: we assume js/ts modules won't have CSS blocks in them, so no
|
||||
// virtual modules get created.
|
||||
return {
|
||||
contents: result.js.code,
|
||||
loader: "js",
|
||||
};
|
||||
})
|
||||
.onResolve({ filter: /^bun-svelte:/ }, args => {
|
||||
return {
|
||||
path: args.path,
|
||||
namespace: "bun-svelte",
|
||||
};
|
||||
})
|
||||
.onLoad({ filter: /\.css$/, namespace: virtualNamespace }, args => {
|
||||
const { path } = args;
|
||||
|
||||
const mod = virtualCssModules.get(path);
|
||||
if (!mod) throw new Error("Virtual CSS module not found: " + path);
|
||||
const { sourcePath, source } = mod;
|
||||
virtualCssModules.delete(path);
|
||||
|
||||
return {
|
||||
contents: source,
|
||||
loader: "css",
|
||||
watchFiles: [sourcePath],
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default SveltePlugin({ development: true }) as BunPlugin;
|
||||
export { SveltePlugin, type SvelteOptions };
|
||||
4
packages/bun-plugin-svelte/src/modules.d.ts
vendored
Normal file
4
packages/bun-plugin-svelte/src/modules.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
declare module "*.svelte" {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
||||
45
packages/bun-plugin-svelte/src/options.spec.ts
Normal file
45
packages/bun-plugin-svelte/src/options.spec.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { describe, beforeAll, it, expect } from "bun:test";
|
||||
import type { BuildConfig } from "bun";
|
||||
import type { CompileOptions } from "svelte/compiler";
|
||||
|
||||
import { getBaseCompileOptions, type SvelteOptions } from "./options";
|
||||
|
||||
describe("getBaseCompileOptions", () => {
|
||||
describe("when no options are provided", () => {
|
||||
const pluginOptions: SvelteOptions = {};
|
||||
let fullDefault: Readonly<CompileOptions>;
|
||||
|
||||
beforeAll(() => {
|
||||
fullDefault = Object.freeze(getBaseCompileOptions(pluginOptions, {}));
|
||||
});
|
||||
|
||||
it("when minification is disabled, whitespace and comments are preserved", () => {
|
||||
expect(getBaseCompileOptions(pluginOptions, { minify: false })).toEqual(
|
||||
expect.objectContaining({
|
||||
preserveWhitespace: true,
|
||||
preserveComments: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("defaults to production mode", () => {
|
||||
expect(fullDefault.dev).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
it.each([{}, { side: "server" }, { side: "client" }, { side: undefined }] as Partial<BuildConfig>[])(
|
||||
"when present, forceSide takes precedence over config (%o)",
|
||||
buildConfig => {
|
||||
expect(getBaseCompileOptions({ forceSide: "client" }, buildConfig)).toEqual(
|
||||
expect.objectContaining({
|
||||
generate: "client",
|
||||
}),
|
||||
);
|
||||
expect(getBaseCompileOptions({ forceSide: "server" }, buildConfig)).toEqual(
|
||||
expect.objectContaining({
|
||||
generate: "server",
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
111
packages/bun-plugin-svelte/src/options.ts
Normal file
111
packages/bun-plugin-svelte/src/options.ts
Normal file
@@ -0,0 +1,111 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import { type BuildConfig } from "bun";
|
||||
import type { CompileOptions, ModuleCompileOptions } from "svelte/compiler";
|
||||
|
||||
export interface SvelteOptions {
|
||||
/**
|
||||
* Force client-side or server-side generation.
|
||||
*
|
||||
* By default, this plugin will detect the side of the build based on how
|
||||
* it's used. For example, `"client"` code will be generated when used with {@link Bun.build}.
|
||||
*/
|
||||
forceSide?: "client" | "server";
|
||||
|
||||
/**
|
||||
* When `true`, this plugin will generate development-only checks and other
|
||||
* niceties.
|
||||
*
|
||||
* When `false`, this plugin will generate production-ready code
|
||||
*
|
||||
* Defaults to `true` when run via Bun's dev server, `false` otherwise.
|
||||
*/
|
||||
development?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function validateOptions(options: unknown): asserts options is SvelteOptions {
|
||||
assert(options && typeof options === "object", new TypeError("bun-svelte-plugin: options must be an object"));
|
||||
if ("forceSide" in options) {
|
||||
switch (options.forceSide) {
|
||||
case "client":
|
||||
case "server":
|
||||
break;
|
||||
default:
|
||||
throw new TypeError(
|
||||
`bun-svelte-plugin: forceSide must be either 'client' or 'server', got ${options.forceSide}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export function getBaseCompileOptions(pluginOptions: SvelteOptions, config: Partial<BuildConfig>): CompileOptions {
|
||||
let { development = false } = pluginOptions;
|
||||
const { minify = false } = config;
|
||||
|
||||
const shouldMinify = Boolean(minify);
|
||||
const {
|
||||
whitespace: minifyWhitespace,
|
||||
syntax: _minifySyntax,
|
||||
identifiers: _minifyIdentifiers,
|
||||
} = typeof minify === "object"
|
||||
? minify
|
||||
: {
|
||||
whitespace: shouldMinify,
|
||||
syntax: shouldMinify,
|
||||
identifiers: shouldMinify,
|
||||
};
|
||||
|
||||
const generate = generateSide(pluginOptions, config);
|
||||
|
||||
return {
|
||||
css: "external",
|
||||
generate,
|
||||
preserveWhitespace: !minifyWhitespace,
|
||||
preserveComments: !shouldMinify,
|
||||
dev: development,
|
||||
cssHash({ css }) {
|
||||
// same prime number seed used by svelte/compiler.
|
||||
// TODO: ensure this provides enough entropy
|
||||
return `svelte-${hash(css)}`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function getBaseModuleCompileOptions(
|
||||
pluginOptions: SvelteOptions,
|
||||
config: Partial<BuildConfig>,
|
||||
): ModuleCompileOptions {
|
||||
const { development = false } = pluginOptions;
|
||||
const generate = generateSide(pluginOptions, config);
|
||||
return {
|
||||
dev: development,
|
||||
generate,
|
||||
};
|
||||
}
|
||||
|
||||
function generateSide(pluginOptions: SvelteOptions, config: Partial<BuildConfig>) {
|
||||
let { forceSide } = pluginOptions;
|
||||
const { target } = config;
|
||||
|
||||
if (forceSide == null && typeof target === "string") {
|
||||
switch (target) {
|
||||
case "browser":
|
||||
forceSide = "client";
|
||||
break;
|
||||
case "node":
|
||||
case "bun":
|
||||
forceSide = "server";
|
||||
break;
|
||||
default:
|
||||
// warn? throw?
|
||||
}
|
||||
}
|
||||
return forceSide;
|
||||
}
|
||||
|
||||
export const hash = (content: string): string => Bun.hash(content, 5381).toString(36);
|
||||
@@ -0,0 +1,91 @@
|
||||
// Bun Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Bun.plugin using { forceSide: 'server' } allows for imported components to be SSR'd: foo.svelte - head 1`] = `""`;
|
||||
|
||||
exports[`Bun.plugin using { forceSide: 'server' } allows for imported components to be SSR'd: foo.svelte - body 1`] = `
|
||||
"<!--[--><!---->
|
||||
|
||||
<main class="app svelte-30r5b3lexyb64">
|
||||
<h1 class="svelte-30r5b3lexyb64">Hello World!</h1>
|
||||
</main>
|
||||
|
||||
<!--]-->"
|
||||
`;
|
||||
|
||||
exports[`Bun.plugin Generates server-side code: foo.svelte - head 1`] = `""`;
|
||||
|
||||
exports[`Bun.plugin Generates server-side code: foo.svelte - body 1`] = `
|
||||
"<!--[--><!---->
|
||||
|
||||
<main class="app svelte-30r5b3lexyb64">
|
||||
<h1 class="svelte-30r5b3lexyb64">Hello World!</h1>
|
||||
</main>
|
||||
|
||||
<!--]-->"
|
||||
`;
|
||||
|
||||
exports[`Bun.build Generates server-side code when targeting "node" or "bun": foo.svelte - server-side (node) 1`] = `
|
||||
{
|
||||
"body":
|
||||
"<!--[--><!---->
|
||||
|
||||
<main class="app svelte-30r5b3lexyb64">
|
||||
<h1 class="svelte-30r5b3lexyb64">Hello World!</h1>
|
||||
</main>
|
||||
|
||||
<!--]-->"
|
||||
,
|
||||
"head": "",
|
||||
"html":
|
||||
"<!--[--><!---->
|
||||
|
||||
<main class="app svelte-30r5b3lexyb64">
|
||||
<h1 class="svelte-30r5b3lexyb64">Hello World!</h1>
|
||||
</main>
|
||||
|
||||
<!--]-->"
|
||||
,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Bun.build Generates server-side code when targeting "node" or "bun": foo.svelte - server-side (bun) 1`] = `
|
||||
{
|
||||
"body":
|
||||
"<!--[--><!---->
|
||||
|
||||
<main class="app svelte-30r5b3lexyb64">
|
||||
<h1 class="svelte-30r5b3lexyb64">Hello World!</h1>
|
||||
</main>
|
||||
|
||||
<!--]-->"
|
||||
,
|
||||
"head": "",
|
||||
"html":
|
||||
"<!--[--><!---->
|
||||
|
||||
<main class="app svelte-30r5b3lexyb64">
|
||||
<h1 class="svelte-30r5b3lexyb64">Hello World!</h1>
|
||||
</main>
|
||||
|
||||
<!--]-->"
|
||||
,
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Bun.build Generates client-side code when targeting 'browser': foo.svelte - client-side 1`] = `
|
||||
"// test/fixtures/foo.svelte
|
||||
var foo_default = "./foo-y5ajevk1.svelte";
|
||||
export {
|
||||
foo_default as default
|
||||
};
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`Bun.build Generates client-side code when targeting 'browser': foo.svelte - client-side index 1`] = `
|
||||
"// test/fixtures/foo.svelte
|
||||
var foo_default = "./foo-y5ajevk1.svelte";
|
||||
export {
|
||||
foo_default as default
|
||||
};
|
||||
"
|
||||
`;
|
||||
19
packages/bun-plugin-svelte/test/fixtures/foo.svelte
vendored
Normal file
19
packages/bun-plugin-svelte/test/fixtures/foo.svelte
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<script>
|
||||
let name = "World";
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Hello {name}!</h1>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
}
|
||||
.app {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
17
packages/bun-plugin-svelte/test/fixtures/svelte-export-condition.svelte
vendored
Normal file
17
packages/bun-plugin-svelte/test/fixtures/svelte-export-condition.svelte
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<script>
|
||||
import { Canvas } from "@threlte/core";
|
||||
let name = "Bun";
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Cookin up apps with {name}</h1>
|
||||
<Canvas />
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
</style>
|
||||
15
packages/bun-plugin-svelte/test/fixtures/todo-cjs.svelte.ts
vendored
Normal file
15
packages/bun-plugin-svelte/test/fixtures/todo-cjs.svelte.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
class Todo {
|
||||
title: string | undefined = $state();
|
||||
done: boolean = $state(false);
|
||||
createdAt: Date = $state(new Date());
|
||||
|
||||
constructor(title: string) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public toggle(): void {
|
||||
this.done = !this.done;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Todo;
|
||||
13
packages/bun-plugin-svelte/test/fixtures/todo.svelte.ts
vendored
Normal file
13
packages/bun-plugin-svelte/test/fixtures/todo.svelte.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export class Todo {
|
||||
title: string | undefined = $state();
|
||||
done: boolean = $state(false);
|
||||
createdAt: Date = $state(new Date());
|
||||
|
||||
constructor(title: string) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public toggle(): void {
|
||||
this.done = !this.done;
|
||||
}
|
||||
}
|
||||
25
packages/bun-plugin-svelte/test/fixtures/with-cjs.svelte
vendored
Normal file
25
packages/bun-plugin-svelte/test/fixtures/with-cjs.svelte
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
const Todo = require("./todo-cjs.svelte.ts");
|
||||
|
||||
let name = "World";
|
||||
let todo: Todo = $state(new Todo("Hello World!"));
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Hello {todo.title}!</h1>
|
||||
<!-- clicking calls toggle -->
|
||||
<input type="checkbox" bind:checked={todo.done} />
|
||||
<button onclick={todo.toggle}>Toggle</button>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
}
|
||||
.app {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
25
packages/bun-plugin-svelte/test/fixtures/with-modules.svelte
vendored
Normal file
25
packages/bun-plugin-svelte/test/fixtures/with-modules.svelte
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { Todo } from "./todo.svelte";
|
||||
|
||||
let name = "World";
|
||||
let todo: Todo = $state(new Todo("Hello World!"));
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Hello {todo.title}!</h1>
|
||||
<!-- clicking calls toggle -->
|
||||
<input type="checkbox" bind:checked={todo.done} />
|
||||
<button onclick={todo.toggle}>Toggle</button>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
}
|
||||
.app {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
138
packages/bun-plugin-svelte/test/index.test.ts
Normal file
138
packages/bun-plugin-svelte/test/index.test.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
import { describe, beforeAll, it, expect, afterEach, afterAll } from "bun:test";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import { render } from "svelte/server";
|
||||
import { SveltePlugin } from "../src";
|
||||
import type { BuildOutput } from "bun";
|
||||
|
||||
const fixturePath = (...segs: string[]) => path.join(import.meta.dirname, "fixtures", ...segs);
|
||||
|
||||
// temp dir that gets deleted after all tests
|
||||
let outdir: string;
|
||||
|
||||
beforeAll(() => {
|
||||
const prefix = `svelte-test-${Math.random().toString(36).substring(2, 15)}`;
|
||||
outdir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
try {
|
||||
fs.rmSync(outdir, { recursive: true, force: true });
|
||||
} catch {
|
||||
// suppress
|
||||
}
|
||||
});
|
||||
|
||||
it("hello world component", async () => {
|
||||
const res = await Bun.build({
|
||||
entrypoints: [fixturePath("foo.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
|
||||
describe("when importing `.svelte.ts` files with ESM", () => {
|
||||
let res: BuildOutput;
|
||||
|
||||
beforeAll(async () => {
|
||||
res = await Bun.build({
|
||||
entrypoints: [fixturePath("with-modules.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds successfully", () => {
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
|
||||
it(`handles "svelte" export condition`, async () => {
|
||||
const res = await Bun.build({
|
||||
entrypoints: [fixturePath("svelte-export-condition.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when importing `.svelte.ts` files with CJS", () => {
|
||||
let res: BuildOutput;
|
||||
|
||||
beforeAll(async () => {
|
||||
res = await Bun.build({
|
||||
entrypoints: [fixturePath("with-cjs.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds successfully", () => {
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
|
||||
it("does not double-wrap the module with function(module, exports, __filename, __dirname)", async () => {
|
||||
const ts = res.outputs.find(output => output.loader === "ts");
|
||||
expect(ts).toBeDefined();
|
||||
const code = await ts!.text();
|
||||
expect(code).toContain("require_todo_cjs_svelte");
|
||||
expect(code).toContain("var require_todo_cjs_svelte = __commonJS((exports, module) => {\n");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Bun.build", () => {
|
||||
it.each(["node", "bun"] as const)('Generates server-side code when targeting "node" or "bun"', async target => {
|
||||
const res = await Bun.build({
|
||||
entrypoints: [fixturePath("foo.svelte")],
|
||||
outdir,
|
||||
target,
|
||||
plugins: [SveltePlugin({ forceSide: "server" })],
|
||||
});
|
||||
expect(res.success).toBeTrue();
|
||||
const componentPath = res.outputs[0].path;
|
||||
const component = await import(componentPath);
|
||||
expect(component.default).toBeTypeOf("function");
|
||||
expect(render(component.default)).toMatchSnapshot(`foo.svelte - server-side (${target})`);
|
||||
});
|
||||
|
||||
it("Generates client-side code when targeting 'browser'", async () => {
|
||||
const res = await Bun.build({
|
||||
entrypoints: [fixturePath("foo.svelte")],
|
||||
outdir,
|
||||
target: "browser",
|
||||
});
|
||||
|
||||
expect(res.success).toBeTrue();
|
||||
const componentPath = path.resolve(res.outputs[0].path);
|
||||
const entrypoint = await res.outputs[0].text();
|
||||
expect(entrypoint).toMatchSnapshot(`foo.svelte - client-side index`);
|
||||
expect(await Bun.file(componentPath).text()).toMatchSnapshot(`foo.svelte - client-side`);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Bun.plugin", () => {
|
||||
afterEach(() => {
|
||||
Bun.plugin.clearAll();
|
||||
});
|
||||
|
||||
// test.only("using { forceSide: 'server' } allows for imported components to be SSR'd", async () => {
|
||||
it("Generates server-side code", async () => {
|
||||
Bun.plugin(SveltePlugin());
|
||||
|
||||
const foo = await import(fixturePath("foo.svelte"));
|
||||
expect(foo).toBeTypeOf("object");
|
||||
expect(foo).toHaveProperty("default");
|
||||
|
||||
const actual = render(foo.default);
|
||||
expect(actual).toEqual(
|
||||
expect.objectContaining({
|
||||
head: expect.any(String),
|
||||
body: expect.any(String),
|
||||
}),
|
||||
);
|
||||
expect(actual.head).toMatchSnapshot("foo.svelte - head");
|
||||
expect(actual.body).toMatchSnapshot("foo.svelte - body");
|
||||
});
|
||||
});
|
||||
34
packages/bun-plugin-svelte/tsconfig.json
Normal file
34
packages/bun-plugin-svelte/tsconfig.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"emitDeclarationOnly": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"stripInternal": true,
|
||||
|
||||
// thank you Titian
|
||||
"isolatedDeclarations": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noImplicitAny": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
||||
6
packages/bun-types/ambient.d.ts
vendored
6
packages/bun-types/ambient.d.ts
vendored
@@ -23,3 +23,9 @@ declare module "*.html" {
|
||||
var contents: any;
|
||||
export = contents;
|
||||
}
|
||||
|
||||
declare module "*.svg" {
|
||||
// Bun 1.2.3 added support for frontend dev server
|
||||
var contents: `${string}.svg`;
|
||||
export = contents;
|
||||
}
|
||||
|
||||
426
packages/bun-types/bun.d.ts
vendored
426
packages/bun-types/bun.d.ts
vendored
@@ -16,9 +16,13 @@
|
||||
declare module "bun" {
|
||||
import type { FFIFunctionCallableSymbol } from "bun:ffi";
|
||||
import type { Encoding as CryptoEncoding } from "crypto";
|
||||
import type { CipherNameAndProtocol, EphemeralKeyInfo, PeerCertificate } from "tls";
|
||||
import type { Stats } from "node:fs";
|
||||
import type { X509Certificate } from "node:crypto";
|
||||
import type { Stats } from "node:fs";
|
||||
import type { CipherNameAndProtocol, EphemeralKeyInfo, PeerCertificate } from "tls";
|
||||
|
||||
type DistributedOmit<T, K extends keyof T> = T extends T ? Omit<T, K> : never;
|
||||
type PathLike = string | NodeJS.TypedArray | ArrayBufferLike | URL;
|
||||
|
||||
interface Env {
|
||||
NODE_ENV?: string;
|
||||
/**
|
||||
@@ -303,6 +307,10 @@ declare module "bun" {
|
||||
export interface Shell {
|
||||
(strings: TemplateStringsArray, ...expressions: ShellExpression[]): ShellPromise;
|
||||
|
||||
readonly Shell: ShellConstructor;
|
||||
readonly ShellError: typeof ShellError;
|
||||
readonly ShellPromise: typeof ShellPromise;
|
||||
|
||||
/**
|
||||
* Perform bash-like brace expansion on the given pattern.
|
||||
* @param pattern - Brace pattern to expand
|
||||
@@ -354,9 +362,6 @@ declare module "bun" {
|
||||
* Configure whether or not the shell should throw an exception on non-zero exit codes.
|
||||
*/
|
||||
throws(shouldThrow: boolean): this;
|
||||
|
||||
readonly ShellPromise: typeof ShellPromise;
|
||||
readonly Shell: ShellConstructor;
|
||||
}
|
||||
|
||||
export interface ShellOutput {
|
||||
@@ -2301,10 +2306,68 @@ declare module "bun" {
|
||||
*/
|
||||
interface SavepointSQL extends SQL {}
|
||||
|
||||
type CSRFAlgorithm = "blake2b256" | "blake2b512" | "sha256" | "sha384" | "sha512" | "sha512-256";
|
||||
interface CSRFGenerateOptions {
|
||||
/**
|
||||
* The number of milliseconds until the token expires. 0 means the token never expires.
|
||||
* @default 24 * 60 * 60 * 1000 (24 hours)
|
||||
*/
|
||||
expiresIn?: number;
|
||||
/**
|
||||
* The encoding of the token.
|
||||
* @default "base64url"
|
||||
*/
|
||||
encoding?: "base64" | "base64url" | "hex";
|
||||
/**
|
||||
* The algorithm to use for the token.
|
||||
* @default "sha256"
|
||||
*/
|
||||
algorithm?: CSRFAlgorithm;
|
||||
}
|
||||
|
||||
interface CSRFVerifyOptions {
|
||||
/**
|
||||
* The secret to use for the token. If not provided, a random default secret will be generated in memory and used.
|
||||
*/
|
||||
secret?: string;
|
||||
/**
|
||||
* The encoding of the token.
|
||||
* @default "base64url"
|
||||
*/
|
||||
encoding?: "base64" | "base64url" | "hex";
|
||||
/**
|
||||
* The algorithm to use for the token.
|
||||
* @default "sha256"
|
||||
*/
|
||||
algorithm?: CSRFAlgorithm;
|
||||
/**
|
||||
* The number of milliseconds until the token expires. 0 means the token never expires.
|
||||
* @default 24 * 60 * 60 * 1000 (24 hours)
|
||||
*/
|
||||
maxAge?: number;
|
||||
}
|
||||
interface CSRF {
|
||||
/**
|
||||
* Generate a CSRF token.
|
||||
* @param secret The secret to use for the token. If not provided, a random default secret will be generated in memory and used.
|
||||
* @param options The options for the token.
|
||||
* @returns The generated token.
|
||||
*/
|
||||
generate(secret?: string, options?: CSRFGenerateOptions): string;
|
||||
/**
|
||||
* Verify a CSRF token.
|
||||
* @param token The token to verify.
|
||||
* @param options The options for the token.
|
||||
* @returns True if the token is valid, false otherwise.
|
||||
*/
|
||||
verify(token: string, options?: CSRFVerifyOptions): boolean;
|
||||
}
|
||||
|
||||
var sql: SQL;
|
||||
var postgres: SQL;
|
||||
var SQL: SQL;
|
||||
|
||||
var CSRF: CSRF;
|
||||
/**
|
||||
* This lets you use macros as regular imports
|
||||
* @example
|
||||
@@ -2595,9 +2658,15 @@ declare module "bun" {
|
||||
kind: ImportKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [Bun.build API docs](https://bun.sh/docs/bundler#api)
|
||||
*/
|
||||
interface BuildConfig {
|
||||
entrypoints: string[]; // list of file path
|
||||
outdir?: string; // output directory
|
||||
/**
|
||||
* @default "browser"
|
||||
*/
|
||||
target?: Target; // default: "browser"
|
||||
/**
|
||||
* Output module format. Top-level await is only supported for `"esm"`.
|
||||
@@ -2641,7 +2710,25 @@ declare module "bun" {
|
||||
define?: Record<string, string>;
|
||||
// origin?: string; // e.g. http://mydomain.com
|
||||
loader?: { [k in string]: Loader };
|
||||
sourcemap?: "none" | "linked" | "inline" | "external" | "linked" | boolean; // default: "none", true -> "inline"
|
||||
/**
|
||||
* Specifies if and how to generate source maps.
|
||||
*
|
||||
* - `"none"` - No source maps are generated
|
||||
* - `"linked"` - A separate `*.ext.map` file is generated alongside each
|
||||
* `*.ext` file. A `//# sourceMappingURL` comment is added to the output
|
||||
* file to link the two. Requires `outdir` to be set.
|
||||
* - `"inline"` - an inline source map is appended to the output file.
|
||||
* - `"external"` - Generate a separate source map file for each input file.
|
||||
* No `//# sourceMappingURL` comment is added to the output file.
|
||||
*
|
||||
* `true` and `false` are aliasees for `"inline"` and `"none"`, respectively.
|
||||
*
|
||||
* @default "none"
|
||||
*
|
||||
* @see {@link outdir} required for `"linked"` maps
|
||||
* @see {@link publicPath} to customize the base url of linked source maps
|
||||
*/
|
||||
sourcemap?: "none" | "linked" | "inline" | "external" | "linked" | boolean;
|
||||
/**
|
||||
* package.json `exports` conditions used when resolving imports
|
||||
*
|
||||
@@ -2670,6 +2757,14 @@ declare module "bun" {
|
||||
* ```
|
||||
*/
|
||||
env?: "inline" | "disable" | `${string}*`;
|
||||
/**
|
||||
* Whether to enable minification.
|
||||
*
|
||||
* Use `true`/`false` to enable/disable all minification options. Alternatively,
|
||||
* you can pass an object for granular control over certain minifications.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
minify?:
|
||||
| boolean
|
||||
| {
|
||||
@@ -3665,6 +3760,7 @@ declare module "bun" {
|
||||
|
||||
interface BunRequest<T extends string = string> extends Request {
|
||||
params: RouterTypes.ExtractRouteParams<T>;
|
||||
readonly cookies: CookieMap;
|
||||
}
|
||||
|
||||
interface GenericServeOptions {
|
||||
@@ -3940,13 +4036,14 @@ declare module "bun" {
|
||||
|
||||
interface TLSWebSocketServeOptions<WebSocketDataType = undefined>
|
||||
extends WebSocketServeOptions<WebSocketDataType>,
|
||||
TLSOptions {
|
||||
TLSOptionsAsDeprecated {
|
||||
unix?: never;
|
||||
tls?: TLSOptions | TLSOptions[];
|
||||
}
|
||||
|
||||
interface UnixTLSWebSocketServeOptions<WebSocketDataType = undefined>
|
||||
extends UnixWebSocketServeOptions<WebSocketDataType>,
|
||||
TLSOptions {
|
||||
TLSOptionsAsDeprecated {
|
||||
/**
|
||||
* If set, the HTTP server will listen on a unix socket instead of a port.
|
||||
* (Cannot be used with hostname+port)
|
||||
@@ -3954,6 +4051,7 @@ declare module "bun" {
|
||||
unix: string;
|
||||
tls?: TLSOptions | TLSOptions[];
|
||||
}
|
||||
|
||||
interface ErrorLike extends Error {
|
||||
code?: string;
|
||||
errno?: number;
|
||||
@@ -4033,11 +4131,129 @@ declare module "bun" {
|
||||
secureOptions?: number | undefined; // Value is a numeric bitmask of the `SSL_OP_*` options
|
||||
}
|
||||
|
||||
interface TLSServeOptions extends ServeOptions, TLSOptions {
|
||||
// Note for contributors: TLSOptionsAsDeprecated should be considered immutable
|
||||
// and new TLS option keys should only be supported on the `.tls` property (which comes
|
||||
// from the TLSOptions interface above).
|
||||
/**
|
||||
* This exists because Bun.serve() extends the TLSOptions object, but
|
||||
* they're now considered deprecated. You should be passing the
|
||||
* options on `.tls` instead.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* //// OLD ////
|
||||
* Bun.serve({
|
||||
* fetch: () => new Response("Hello World"),
|
||||
* passphrase: "secret",
|
||||
* });
|
||||
*
|
||||
* //// NEW ////
|
||||
* Bun.serve({
|
||||
* fetch: () => new Response("Hello World"),
|
||||
* tls: {
|
||||
* passphrase: "secret",
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
interface TLSOptionsAsDeprecated {
|
||||
/**
|
||||
* Passphrase for the TLS key
|
||||
*
|
||||
* @deprecated Use `.tls.passphrase` instead
|
||||
*/
|
||||
passphrase?: string;
|
||||
|
||||
/**
|
||||
* File path to a .pem file custom Diffie Helman parameters
|
||||
*
|
||||
* @deprecated Use `.tls.dhParamsFile` instead
|
||||
*/
|
||||
dhParamsFile?: string;
|
||||
|
||||
/**
|
||||
* Explicitly set a server name
|
||||
*
|
||||
* @deprecated Use `.tls.serverName` instead
|
||||
*/
|
||||
serverName?: string;
|
||||
|
||||
/**
|
||||
* This sets `OPENSSL_RELEASE_BUFFERS` to 1.
|
||||
* It reduces overall performance but saves some memory.
|
||||
* @default false
|
||||
*
|
||||
* @deprecated Use `.tls.lowMemoryMode` instead
|
||||
*/
|
||||
lowMemoryMode?: boolean;
|
||||
|
||||
/**
|
||||
* If set to `false`, any certificate is accepted.
|
||||
* Default is `$NODE_TLS_REJECT_UNAUTHORIZED` environment variable, or `true` if it is not set.
|
||||
*
|
||||
* @deprecated Use `.tls.rejectUnauthorized` instead
|
||||
*/
|
||||
rejectUnauthorized?: boolean;
|
||||
|
||||
/**
|
||||
* If set to `true`, the server will request a client certificate.
|
||||
*
|
||||
* Default is `false`.
|
||||
*
|
||||
* @deprecated Use `.tls.requestCert` instead
|
||||
*/
|
||||
requestCert?: boolean;
|
||||
|
||||
/**
|
||||
* Optionally override the trusted CA certificates. Default is to trust
|
||||
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
|
||||
* replaced when CAs are explicitly specified using this option.
|
||||
*
|
||||
* @deprecated Use `.tls.ca` instead
|
||||
*/
|
||||
ca?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
|
||||
/**
|
||||
* Cert chains in PEM format. One cert chain should be provided per
|
||||
* private key. Each cert chain should consist of the PEM formatted
|
||||
* certificate for a provided private key, followed by the PEM
|
||||
* formatted intermediate certificates (if any), in order, and not
|
||||
* including the root CA (the root CA must be pre-known to the peer,
|
||||
* see ca). When providing multiple cert chains, they do not have to
|
||||
* be in the same order as their private keys in key. If the
|
||||
* intermediate certificates are not provided, the peer will not be
|
||||
* able to validate the certificate, and the handshake will fail.
|
||||
*
|
||||
* @deprecated Use `.tls.cert` instead
|
||||
*/
|
||||
cert?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
|
||||
/**
|
||||
* Private keys in PEM format. PEM allows the option of private keys
|
||||
* being encrypted. Encrypted keys will be decrypted with
|
||||
* options.passphrase. Multiple keys using different algorithms can be
|
||||
* provided either as an array of unencrypted key strings or buffers,
|
||||
* or an array of objects in the form {pem: <string|buffer>[,
|
||||
* passphrase: <string>]}. The object form can only occur in an array.
|
||||
* object.passphrase is optional. Encrypted keys will be decrypted with
|
||||
* object.passphrase if provided, or options.passphrase if it is not.
|
||||
*
|
||||
* @deprecated Use `.tls.key` instead
|
||||
*/
|
||||
key?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined;
|
||||
/**
|
||||
* Optionally affect the OpenSSL protocol behavior, which is not
|
||||
* usually necessary. This should be used carefully if at all! Value is
|
||||
* a numeric bitmask of the SSL_OP_* options from OpenSSL Options
|
||||
*
|
||||
* @deprecated `Use .tls.secureOptions` instead
|
||||
*/
|
||||
secureOptions?: number | undefined; // Value is a numeric bitmask of the `SSL_OP_*` options
|
||||
}
|
||||
|
||||
interface TLSServeOptions extends ServeOptions, TLSOptionsAsDeprecated {
|
||||
tls?: TLSOptions | TLSOptions[];
|
||||
}
|
||||
|
||||
interface UnixTLSServeOptions extends UnixServeOptions, TLSOptions {
|
||||
interface UnixTLSServeOptions extends UnixServeOptions, TLSOptionsAsDeprecated {
|
||||
tls?: TLSOptions | TLSOptions[];
|
||||
}
|
||||
|
||||
@@ -4105,17 +4321,7 @@ declare module "bun" {
|
||||
* Passing other options such as `port` or `hostname` won't do anything.
|
||||
*/
|
||||
reload<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }>(
|
||||
options: (
|
||||
| (Omit<ServeOptions, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (Omit<ServeOptions, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| WebSocketServeOptions<T>
|
||||
) & {
|
||||
options: ServeFunctionOptions<T, R> & {
|
||||
/**
|
||||
* @deprecated Use `routes` instead in new code. This will continue to work for awhile though.
|
||||
*/
|
||||
@@ -4493,24 +4699,40 @@ declare module "bun" {
|
||||
@param options.routes - Route definitions mapping paths to handlers
|
||||
*/
|
||||
function serve<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }>(
|
||||
options: (
|
||||
| (Omit<ServeOptions, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (Omit<ServeOptions, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| WebSocketServeOptions<T>
|
||||
) & {
|
||||
options: ServeFunctionOptions<T, R> & {
|
||||
/**
|
||||
* @deprecated Use `routes` instead in new code. This will continue to work for awhile though.
|
||||
* @deprecated Use `routes` instead in new code. This will continue to work for a while though.
|
||||
*/
|
||||
static?: R;
|
||||
},
|
||||
): Server;
|
||||
|
||||
type ServeFunctionOptions<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }> =
|
||||
| (DistributedOmit<Exclude<Serve<T>, WebSocketServeOptions<T>>, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (DistributedOmit<Exclude<Serve<T>, WebSocketServeOptions<T>>, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (WebSocketServeOptions<T> & {
|
||||
routes: R;
|
||||
fetch?: (
|
||||
this: Server,
|
||||
request: Request,
|
||||
server: Server,
|
||||
) => Response | Promise<Response | void | undefined> | void | undefined;
|
||||
})
|
||||
| (WebSocketServeOptions<T> & {
|
||||
routes?: never;
|
||||
fetch: (
|
||||
this: Server,
|
||||
request: Request,
|
||||
server: Server,
|
||||
) => Response | Promise<Response | void | undefined> | void | undefined;
|
||||
});
|
||||
|
||||
/**
|
||||
* [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) powered by the fastest system calls available for operating on files.
|
||||
*
|
||||
@@ -4918,7 +5140,7 @@ declare module "bun" {
|
||||
*/
|
||||
function openInEditor(path: string, options?: EditorOptions): void;
|
||||
|
||||
const fetch: typeof globalThis.fetch & {
|
||||
var fetch: typeof globalThis.fetch & {
|
||||
preconnect(url: string): void;
|
||||
};
|
||||
|
||||
@@ -5542,7 +5764,11 @@ declare module "bun" {
|
||||
onStart(callback: OnStartCallback): this;
|
||||
onBeforeParse(
|
||||
constraints: PluginConstraints,
|
||||
callback: { napiModule: unknown; symbol: string; external?: unknown | undefined },
|
||||
callback: {
|
||||
napiModule: unknown;
|
||||
symbol: string;
|
||||
external?: unknown | undefined;
|
||||
},
|
||||
): this;
|
||||
/**
|
||||
* Register a callback to load imports with a specific import specifier
|
||||
@@ -5632,13 +5858,15 @@ declare module "bun" {
|
||||
*
|
||||
* If unspecified, it is assumed that the plugin is compatible with all targets.
|
||||
*
|
||||
* This field is not read by Bun.plugin
|
||||
* This field is not read by {@link Bun.plugin}
|
||||
*/
|
||||
target?: Target;
|
||||
/**
|
||||
* A function that will be called when the plugin is loaded.
|
||||
*
|
||||
* This function may be called in the same tick that it is registered, or it may be called later. It could potentially be called multiple times for different targets.
|
||||
* This function may be called in the same tick that it is registered, or it
|
||||
* may be called later. It could potentially be called multiple times for
|
||||
* different targets.
|
||||
*/
|
||||
setup(
|
||||
/**
|
||||
@@ -6073,7 +6301,7 @@ declare module "bun" {
|
||||
* @param socket
|
||||
*/
|
||||
open?(socket: Socket<Data>): void | Promise<void>;
|
||||
close?(socket: Socket<Data>): void | Promise<void>;
|
||||
close?(socket: Socket<Data>, error?: Error): void | Promise<void>;
|
||||
error?(socket: Socket<Data>, error: Error): void | Promise<void>;
|
||||
data?(socket: Socket<Data>, data: BinaryTypeList[DataBinaryType]): void | Promise<void>;
|
||||
drain?(socket: Socket<Data>): void | Promise<void>;
|
||||
@@ -6472,7 +6700,8 @@ declare module "bun" {
|
||||
* This is useful for aborting a subprocess when some other part of the
|
||||
* program is aborted, such as a `fetch` response.
|
||||
*
|
||||
* Internally, this works by calling `subprocess.kill(1)`.
|
||||
* If the signal is aborted, the process will be killed with the signal
|
||||
* specified by `killSignal` (defaults to SIGTERM).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
@@ -6491,6 +6720,41 @@ declare module "bun" {
|
||||
* ```
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
|
||||
/**
|
||||
* The maximum amount of time the process is allowed to run in milliseconds.
|
||||
*
|
||||
* If the timeout is reached, the process will be killed with the signal
|
||||
* specified by `killSignal` (defaults to SIGTERM).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Kill the process after 5 seconds
|
||||
* const subprocess = Bun.spawn({
|
||||
* cmd: ["sleep", "10"],
|
||||
* timeout: 5000,
|
||||
* });
|
||||
* await subprocess.exited; // Will resolve after 5 seconds
|
||||
* ```
|
||||
*/
|
||||
timeout?: number;
|
||||
|
||||
/**
|
||||
* The signal to use when killing the process after a timeout or when the AbortSignal is aborted.
|
||||
*
|
||||
* @default "SIGTERM" (signal 15)
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Kill the process with SIGKILL after 5 seconds
|
||||
* const subprocess = Bun.spawn({
|
||||
* cmd: ["sleep", "10"],
|
||||
* timeout: 5000,
|
||||
* killSignal: "SIGKILL",
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
killSignal?: string | number;
|
||||
}
|
||||
|
||||
type OptionsToSubprocess<Opts extends OptionsObject> =
|
||||
@@ -6736,6 +7000,8 @@ declare module "bun" {
|
||||
resourceUsage: ResourceUsage;
|
||||
|
||||
signalCode?: string;
|
||||
exitedDueToTimeout?: true;
|
||||
pid: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7263,4 +7529,86 @@ declare module "bun" {
|
||||
| [pkg: string, info: BunLockFilePackageInfo, bunTag: string]
|
||||
/** root */
|
||||
| [pkg: string, info: Pick<BunLockFileBasePackageInfo, "bin" | "binDir">];
|
||||
|
||||
interface CookieInit {
|
||||
name?: string;
|
||||
value?: string;
|
||||
domain?: string;
|
||||
path?: string;
|
||||
expires?: number | Date;
|
||||
secure?: boolean;
|
||||
sameSite?: CookieSameSite;
|
||||
httpOnly?: boolean;
|
||||
partitioned?: boolean;
|
||||
maxAge?: number;
|
||||
}
|
||||
|
||||
interface CookieStoreDeleteOptions {
|
||||
name: string;
|
||||
domain?: string | null;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
interface CookieStoreGetOptions {
|
||||
name?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
type CookieSameSite = "strict" | "lax" | "none";
|
||||
|
||||
class Cookie {
|
||||
constructor(name: string, value: string, options?: CookieInit);
|
||||
constructor(cookieString: string);
|
||||
constructor(cookieObject?: CookieInit);
|
||||
|
||||
name: string;
|
||||
value: string;
|
||||
domain?: string;
|
||||
path: string;
|
||||
expires?: number;
|
||||
secure: boolean;
|
||||
sameSite: CookieSameSite;
|
||||
partitioned: boolean;
|
||||
maxAge?: number;
|
||||
httpOnly: boolean;
|
||||
|
||||
isExpired(): boolean;
|
||||
|
||||
toString(): string;
|
||||
toJSON(): CookieInit;
|
||||
|
||||
static parse(cookieString: string): Cookie;
|
||||
static from(name: string, value: string, options?: CookieInit): Cookie;
|
||||
static serialize(...cookies: Cookie[]): string;
|
||||
}
|
||||
|
||||
class CookieMap implements Iterable<[string, Cookie]> {
|
||||
constructor(init?: string[][] | Record<string, string> | string);
|
||||
|
||||
get(name: string): Cookie | null;
|
||||
get(options?: CookieStoreGetOptions): Cookie | null;
|
||||
|
||||
getAll(name: string): Cookie[];
|
||||
getAll(options?: CookieStoreGetOptions): Cookie[];
|
||||
|
||||
has(name: string, value?: string): boolean;
|
||||
|
||||
set(name: string, value: string): void;
|
||||
set(options: CookieInit): void;
|
||||
|
||||
delete(name: string): void;
|
||||
delete(options: CookieStoreDeleteOptions): void;
|
||||
|
||||
toString(): string;
|
||||
|
||||
toJSON(): Record<string, ReturnType<Cookie["toJSON"]>>;
|
||||
readonly size: number;
|
||||
|
||||
entries(): IterableIterator<[string, Cookie]>;
|
||||
keys(): IterableIterator<string>;
|
||||
values(): IterableIterator<Cookie>;
|
||||
forEach(callback: (value: Cookie, key: string, map: CookieMap) => void, thisArg?: any): void;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[string, Cookie]>;
|
||||
}
|
||||
}
|
||||
|
||||
192
packages/bun-types/devserver.d.ts
vendored
Normal file
192
packages/bun-types/devserver.d.ts
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
namespace Bun {
|
||||
type HMREventNames =
|
||||
| "bun:ready"
|
||||
| "bun:beforeUpdate"
|
||||
| "bun:afterUpdate"
|
||||
| "bun:beforeFullReload"
|
||||
| "bun:beforePrune"
|
||||
| "bun:invalidate"
|
||||
| "bun:error"
|
||||
| "bun:ws:disconnect"
|
||||
| "bun:ws:connect";
|
||||
|
||||
/**
|
||||
* The event names for the dev server
|
||||
*/
|
||||
type HMREvent = `bun:${HMREventNames}` | (string & {});
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
/**
|
||||
* Hot module replacement APIs. This value is `undefined` in production and
|
||||
* can be used in an `if` statement to check if HMR APIs are available
|
||||
*
|
||||
* ```ts
|
||||
* if (import.meta.hot) {
|
||||
* // HMR APIs are available
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* However, this check is usually not needed as Bun will dead-code-eliminate
|
||||
* calls to all of the HMR APIs in production builds.
|
||||
*
|
||||
* https://bun.sh/docs/bundler/hmr
|
||||
*/
|
||||
hot: {
|
||||
/**
|
||||
* `import.meta.hot.data` maintains state between module instances during
|
||||
* hot replacement, enabling data transfer from previous to new versions.
|
||||
* When `import.meta.hot.data` is written to, Bun will mark this module as
|
||||
* capable of self-accepting (equivalent of calling `accept()`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const root = import.meta.hot.data.root ??= createRoot(elem);
|
||||
* root.render(<App />); // re-use an existing root
|
||||
* ```
|
||||
*
|
||||
* In production, `data` is inlined to be `{}`. This is handy because Bun
|
||||
* knows it can minify `{}.prop ??= value` into `value` in production.
|
||||
*/
|
||||
data: any;
|
||||
|
||||
/**
|
||||
* Indicate that this module can be replaced simply by re-evaluating the
|
||||
* file. After a hot update, importers of this module will be
|
||||
* automatically patched.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getCount } from "./foo";
|
||||
*
|
||||
* console.log("count is ", getCount());
|
||||
*
|
||||
* import.meta.hot.accept();
|
||||
* ```
|
||||
*/
|
||||
accept(): void;
|
||||
|
||||
/**
|
||||
* Indicate that this module can be replaced by evaluating the new module,
|
||||
* and then calling the callback with the new module. In this mode, the
|
||||
* importers do not get patched. This is to match Vite, which is unable
|
||||
* to patch their import statements. Prefer using `import.meta.hot.accept()`
|
||||
* without an argument as it usually makes your code easier to understand.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* export const count = 0;
|
||||
*
|
||||
* import.meta.hot.accept((newModule) => {
|
||||
* if (newModule) {
|
||||
* // newModule is undefined when SyntaxError happened
|
||||
* console.log('updated: count is now ', newModule.count)
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* In production, calls to this are dead-code-eliminated.
|
||||
*/
|
||||
accept(cb: (newModule: any | undefined) => void): void;
|
||||
|
||||
/**
|
||||
* Indicate that a dependency's module can be accepted. When the dependency
|
||||
* is updated, the callback will be called with the new module.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import.meta.hot.accept('./foo', (newModule) => {
|
||||
* if (newModule) {
|
||||
* // newModule is undefined when SyntaxError happened
|
||||
* console.log('updated: count is now ', newModule.count)
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
accept(specifier: string, callback: (newModule: any) => void): void;
|
||||
|
||||
/**
|
||||
* Indicate that a dependency's module can be accepted. This variant
|
||||
* accepts an array of dependencies, where the callback will receive
|
||||
* the one updated module, and `undefined` for the rest.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*/
|
||||
accept(specifiers: string[], callback: (newModules: (any | undefined)[]) => void): void;
|
||||
|
||||
/**
|
||||
* Attach an on-dispose callback. This is called:
|
||||
* - Just before the module is replaced with another copy (before the next is loaded)
|
||||
* - After the module is detached (removing all imports to this module)
|
||||
*
|
||||
* This callback is not called on route navigation or when the browser tab closes.
|
||||
*
|
||||
* Returning a promise will delay module replacement until the module is
|
||||
* disposed. All dispose callbacks are called in parallel.
|
||||
*/
|
||||
dispose(cb: (data: any) => void | Promise<void>): void;
|
||||
|
||||
/**
|
||||
* No-op
|
||||
* @deprecated
|
||||
*/
|
||||
decline(): void;
|
||||
|
||||
// NOTE TO CONTRIBUTORS ////////////////////////////////////////
|
||||
// Callback is currently never called for `.prune()` //
|
||||
// so the types are commented out until we support it. //
|
||||
////////////////////////////////////////////////////////////////
|
||||
// /**
|
||||
// * Attach a callback that is called when the module is removed from the module graph.
|
||||
// *
|
||||
// * This can be used to clean up resources that were created when the module was loaded.
|
||||
// * Unlike `import.meta.hot.dispose()`, this pairs much better with `accept` and `data` to manage stateful resources.
|
||||
// *
|
||||
// * @example
|
||||
// * ```ts
|
||||
// * export const ws = (import.meta.hot.data.ws ??= new WebSocket(location.origin));
|
||||
// *
|
||||
// * import.meta.hot.prune(() => {
|
||||
// * ws.close();
|
||||
// * });
|
||||
// * ```
|
||||
// */
|
||||
// prune(callback: () => void): void;
|
||||
|
||||
/**
|
||||
* Listen for an event from the dev server
|
||||
*
|
||||
* For compatibility with Vite, event names are also available via vite:* prefix instead of bun:*.
|
||||
*
|
||||
* https://bun.sh/docs/bundler/hmr#import-meta-hot-on-and-off
|
||||
* @param event The event to listen to
|
||||
* @param callback The callback to call when the event is emitted
|
||||
*/
|
||||
on(event: Bun.HMREvent, callback: () => void): void;
|
||||
|
||||
/**
|
||||
* Stop listening for an event from the dev server
|
||||
*
|
||||
* For compatibility with Vite, event names are also available via vite:* prefix instead of bun:*.
|
||||
*
|
||||
* https://bun.sh/docs/bundler/hmr#import-meta-hot-on-and-off
|
||||
* @param event The event to stop listening to
|
||||
* @param callback The callback to stop listening to
|
||||
*/
|
||||
off(event: Bun.HMREvent, callback: () => void): void;
|
||||
};
|
||||
}
|
||||
}
|
||||
124
packages/bun-types/fetch.d.ts
vendored
124
packages/bun-types/fetch.d.ts
vendored
@@ -1,9 +1,56 @@
|
||||
type _Response = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").Response;
|
||||
interface Headers {
|
||||
/**
|
||||
* Convert {@link Headers} to a plain JavaScript object.
|
||||
*
|
||||
* About 10x faster than `Object.fromEntries(headers.entries())`
|
||||
*
|
||||
* Called when you run `JSON.stringify(headers)`
|
||||
*
|
||||
* Does not preserve insertion order. Well-known header names are lowercased. Other header names are left as-is.
|
||||
*/
|
||||
toJSON(): Record<string, string>;
|
||||
/**
|
||||
* Get the total number of headers
|
||||
*/
|
||||
readonly count: number;
|
||||
/**
|
||||
* Get all headers matching the name
|
||||
*
|
||||
* Only supports `"Set-Cookie"`. All other headers are empty arrays.
|
||||
*
|
||||
* @param name - The header name to get
|
||||
*
|
||||
* @returns An array of header values
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const headers = new Headers();
|
||||
* headers.append("Set-Cookie", "foo=bar");
|
||||
* headers.append("Set-Cookie", "baz=qux");
|
||||
* headers.getAll("Set-Cookie"); // ["foo=bar", "baz=qux"]
|
||||
* ```
|
||||
*/
|
||||
getAll(name: "set-cookie" | "Set-Cookie"): string[];
|
||||
}
|
||||
|
||||
export interface Response extends _Response {}
|
||||
export declare class Response {
|
||||
constructor(body?: Bun.BodyInit | null | undefined, init?: Bun.ResponseInit | undefined);
|
||||
var Headers: {
|
||||
prototype: Headers;
|
||||
new (init?: Bun.HeadersInit): Headers;
|
||||
};
|
||||
|
||||
interface Request {
|
||||
headers: Headers;
|
||||
}
|
||||
|
||||
var Request: {
|
||||
prototype: Request;
|
||||
new (requestInfo: string, requestInit?: RequestInit): Request;
|
||||
new (requestInfo: RequestInit & { url: string }): Request;
|
||||
new (requestInfo: Request, requestInit?: RequestInit): Request;
|
||||
};
|
||||
|
||||
var Response: {
|
||||
new (body?: Bun.BodyInit | null | undefined, init?: Bun.ResponseInit | undefined): Response;
|
||||
/**
|
||||
* Create a new {@link Response} with a JSON body
|
||||
*
|
||||
@@ -27,7 +74,8 @@ export declare class Response {
|
||||
* ```
|
||||
* @link https://github.com/whatwg/fetch/issues/1389
|
||||
*/
|
||||
static json(body?: any, options?: Bun.ResponseInit | number): Response;
|
||||
json(body?: any, options?: Bun.ResponseInit | number): Response;
|
||||
|
||||
/**
|
||||
* Create a new {@link Response} that redirects to url
|
||||
*
|
||||
@@ -35,7 +83,7 @@ export declare class Response {
|
||||
* @param status - the HTTP status code to use for the redirect
|
||||
*/
|
||||
// tslint:disable-next-line:unified-signatures
|
||||
static redirect(url: string, status?: number): Response;
|
||||
redirect(url: string, status?: number): Response;
|
||||
|
||||
/**
|
||||
* Create a new {@link Response} that redirects to url
|
||||
@@ -44,10 +92,70 @@ export declare class Response {
|
||||
* @param options - options to pass to the response
|
||||
*/
|
||||
// tslint:disable-next-line:unified-signatures
|
||||
static redirect(url: string, options?: Bun.ResponseInit): Response;
|
||||
redirect(url: string, options?: Bun.ResponseInit): Response;
|
||||
|
||||
/**
|
||||
* Create a new {@link Response} that has a network error
|
||||
*/
|
||||
static error(): Response;
|
||||
error(): Response;
|
||||
};
|
||||
|
||||
type _BunTLSOptions = import("bun").TLSOptions;
|
||||
interface BunFetchRequestInitTLS extends _BunTLSOptions {
|
||||
/**
|
||||
* Custom function to check the server identity
|
||||
* @param hostname - The hostname of the server
|
||||
* @param cert - The certificate of the server
|
||||
* @returns An error if the server is unauthorized, otherwise undefined
|
||||
*/
|
||||
checkServerIdentity?: NonNullable<import("node:tls").ConnectionOptions["checkServerIdentity"]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* BunFetchRequestInit represents additional options that Bun supports in `fetch()` only.
|
||||
*
|
||||
* Bun extends the `fetch` API with some additional options, except
|
||||
* this interface is not quite a `RequestInit`, because they won't work
|
||||
* if passed to `new Request()`. This is why it's a separate type.
|
||||
*/
|
||||
interface BunFetchRequestInit extends RequestInit {
|
||||
/**
|
||||
* Override the default TLS options
|
||||
*/
|
||||
tls?: BunFetchRequestInitTLS;
|
||||
}
|
||||
|
||||
var fetch: {
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
*
|
||||
* @param request Request object
|
||||
* @param init A structured value that contains settings for the fetch() request.
|
||||
*
|
||||
* @returns A promise that resolves to {@link Response} object.
|
||||
*/
|
||||
(request: Request, init?: BunFetchRequestInit): Promise<Response>;
|
||||
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
*
|
||||
* @param url URL string
|
||||
* @param init A structured value that contains settings for the fetch() request.
|
||||
*
|
||||
* @returns A promise that resolves to {@link Response} object.
|
||||
*/
|
||||
(url: string | URL | Request, init?: BunFetchRequestInit): Promise<Response>;
|
||||
|
||||
(input: string | URL | globalThis.Request, init?: BunFetchRequestInit): Promise<Response>;
|
||||
|
||||
/**
|
||||
* Start the DNS resolution, TCP connection, and TLS handshake for a request
|
||||
* before the request is actually sent.
|
||||
*
|
||||
* This can reduce the latency of a request when you know there's some
|
||||
* long-running task that will delay the request starting.
|
||||
*
|
||||
* This is a bun-specific API and is not part of the Fetch API specification.
|
||||
*/
|
||||
preconnect(url: string | URL): void;
|
||||
};
|
||||
|
||||
608
packages/bun-types/globals.d.ts
vendored
608
packages/bun-types/globals.d.ts
vendored
@@ -1,144 +1,66 @@
|
||||
type _ReadableStream<T> = typeof globalThis extends {
|
||||
onerror: any;
|
||||
ReadableStream: infer T;
|
||||
}
|
||||
? T
|
||||
: import("stream/web").ReadableStream<T>;
|
||||
type _WritableStream<T> = typeof globalThis extends {
|
||||
onerror: any;
|
||||
WritableStream: infer T;
|
||||
}
|
||||
? T
|
||||
: import("stream/web").WritableStream<T>;
|
||||
export {};
|
||||
|
||||
type _TextEncoder = typeof globalThis extends {
|
||||
onerror: any;
|
||||
TextEncoder: infer T;
|
||||
}
|
||||
? T
|
||||
: Bun.TextEncoder;
|
||||
type _Event = {
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
readonly bubbles: boolean;
|
||||
/** Alias for event.stopPropagation(). This is not used in Node.js and is provided purely for completeness. */
|
||||
cancelBubble: () => void;
|
||||
/** True if the event was created with the cancelable option */
|
||||
readonly cancelable: boolean;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
readonly composed: boolean;
|
||||
/** Returns an array containing the current EventTarget as the only entry or empty if the event is not being dispatched. This is not used in Node.js and is provided purely for completeness. */
|
||||
composedPath(): [EventTarget?];
|
||||
/** Alias for event.target. */
|
||||
readonly currentTarget: EventTarget | null;
|
||||
/** Is true if cancelable is true and event.preventDefault() has been called. */
|
||||
readonly defaultPrevented: boolean;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
readonly eventPhase: 0 | 2;
|
||||
/** The `AbortSignal` "abort" event is emitted with `isTrusted` set to `true`. The value is `false` in all other cases. */
|
||||
readonly isTrusted: boolean;
|
||||
/** Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. */
|
||||
preventDefault(): void;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
returnValue: boolean;
|
||||
/** Alias for event.target. */
|
||||
readonly srcElement: EventTarget | null;
|
||||
/** Stops the invocation of event listeners after the current one completes. */
|
||||
stopImmediatePropagation(): void;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
stopPropagation(): void;
|
||||
/** The `EventTarget` dispatching the event */
|
||||
readonly target: EventTarget | null;
|
||||
/** The millisecond timestamp when the Event object was created. */
|
||||
readonly timeStamp: number;
|
||||
/** Returns the type of event, e.g. "click", "hashchange", or "submit". */
|
||||
readonly type: string;
|
||||
};
|
||||
|
||||
type _TextDecoder = typeof globalThis extends {
|
||||
onerror: any;
|
||||
TextDecoder: infer T;
|
||||
}
|
||||
? T
|
||||
: Bun.TextDecoder;
|
||||
|
||||
type _Performance = typeof globalThis extends {
|
||||
onerror: any;
|
||||
}
|
||||
? {}
|
||||
: import("perf_hooks").Performance;
|
||||
|
||||
type _Worker = typeof globalThis extends { onerror: any; Worker: infer T } ? T : Bun.Worker;
|
||||
|
||||
type _Event = typeof globalThis extends { onerror: any; Event: any }
|
||||
? {}
|
||||
: {
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
readonly bubbles: boolean;
|
||||
/** Alias for event.stopPropagation(). This is not used in Node.js and is provided purely for completeness. */
|
||||
cancelBubble: () => void;
|
||||
/** True if the event was created with the cancelable option */
|
||||
readonly cancelable: boolean;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
readonly composed: boolean;
|
||||
/** Returns an array containing the current EventTarget as the only entry or empty if the event is not being dispatched. This is not used in Node.js and is provided purely for completeness. */
|
||||
composedPath(): [EventTarget?];
|
||||
/** Alias for event.target. */
|
||||
readonly currentTarget: EventTarget | null;
|
||||
/** Is true if cancelable is true and event.preventDefault() has been called. */
|
||||
readonly defaultPrevented: boolean;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
readonly eventPhase: 0 | 2;
|
||||
/** The `AbortSignal` "abort" event is emitted with `isTrusted` set to `true`. The value is `false` in all other cases. */
|
||||
readonly isTrusted: boolean;
|
||||
/** Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. */
|
||||
preventDefault(): void;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
returnValue: boolean;
|
||||
/** Alias for event.target. */
|
||||
readonly srcElement: EventTarget | null;
|
||||
/** Stops the invocation of event listeners after the current one completes. */
|
||||
stopImmediatePropagation(): void;
|
||||
/** This is not used in Node.js and is provided purely for completeness. */
|
||||
stopPropagation(): void;
|
||||
/** The `EventTarget` dispatching the event */
|
||||
readonly target: EventTarget | null;
|
||||
/** The millisecond timestamp when the Event object was created. */
|
||||
readonly timeStamp: number;
|
||||
/** Returns the type of event, e.g. "click", "hashchange", or "submit". */
|
||||
readonly type: string;
|
||||
};
|
||||
|
||||
type _EventTarget = typeof globalThis extends {
|
||||
onerror: any;
|
||||
EventTarget: any;
|
||||
}
|
||||
? {}
|
||||
: {
|
||||
/**
|
||||
* Adds a new handler for the `type` event. Any given `listener` is added only once per `type` and per `capture` option value.
|
||||
*
|
||||
* If the `once` option is true, the `listener` is removed after the next time a `type` event is dispatched.
|
||||
*
|
||||
* The `capture` option is not used by Node.js in any functional way other than tracking registered event listeners per the `EventTarget` specification.
|
||||
* Specifically, the `capture` option is used as part of the key when registering a `listener`.
|
||||
* Any individual `listener` may be added once with `capture = false`, and once with `capture = true`.
|
||||
*/
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: EventListener | EventListenerObject,
|
||||
options?: AddEventListenerOptions | boolean,
|
||||
): void;
|
||||
/** Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. */
|
||||
dispatchEvent(event: Event): boolean;
|
||||
/** Removes the event listener in target's event listener list with the same type, callback, and options. */
|
||||
removeEventListener(
|
||||
type: string,
|
||||
listener: EventListener | EventListenerObject,
|
||||
options?: Bun.EventListenerOptions | boolean,
|
||||
): void;
|
||||
};
|
||||
|
||||
type _Crypto = typeof globalThis extends {
|
||||
onerror: any;
|
||||
Crypto: infer T;
|
||||
}
|
||||
? T
|
||||
: import("crypto").webcrypto.Crypto;
|
||||
|
||||
type _SubtleCrypto = typeof globalThis extends {
|
||||
onerror: any;
|
||||
SubtleCrypto: infer T;
|
||||
}
|
||||
? T
|
||||
: import("crypto").webcrypto.SubtleCrypto;
|
||||
|
||||
type _CryptoKey = typeof globalThis extends {
|
||||
onerror: any;
|
||||
CryptoKey: infer T;
|
||||
}
|
||||
? T
|
||||
: import("crypto").webcrypto.CryptoKey;
|
||||
|
||||
type _Body = typeof globalThis extends { onerror: any }
|
||||
? {}
|
||||
: {
|
||||
readonly body: ReadableStream | null;
|
||||
readonly bodyUsed: boolean;
|
||||
readonly arrayBuffer: () => Promise<ArrayBuffer>;
|
||||
readonly blob: () => Promise<Blob>;
|
||||
readonly formData: () => Promise<FormData>;
|
||||
readonly json: () => Promise<unknown>;
|
||||
readonly text: () => Promise<string>;
|
||||
};
|
||||
|
||||
import { S3FileOptions } from "bun";
|
||||
import type { TextDecoder as NodeTextDecoder, TextEncoder as NodeTextEncoder } from "util";
|
||||
import type { MessagePort } from "worker_threads";
|
||||
import type { WebSocket as _WebSocket } from "ws";
|
||||
type _EventTarget = {
|
||||
/**
|
||||
* Adds a new handler for the `type` event. Any given `listener` is added only once per `type` and per `capture` option value.
|
||||
*
|
||||
* If the `once` option is true, the `listener` is removed after the next time a `type` event is dispatched.
|
||||
*
|
||||
* The `capture` option is not used by Node.js in any functional way other than tracking registered event listeners per the `EventTarget` specification.
|
||||
* Specifically, the `capture` option is used as part of the key when registering a `listener`.
|
||||
* Any individual `listener` may be added once with `capture = false`, and once with `capture = true`.
|
||||
*/
|
||||
addEventListener(
|
||||
type: string,
|
||||
listener: EventListener | EventListenerObject,
|
||||
options?: AddEventListenerOptions | boolean,
|
||||
): void;
|
||||
/** Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. */
|
||||
dispatchEvent(event: Event): boolean;
|
||||
/** Removes the event listener in target's event listener list with the same type, callback, and options. */
|
||||
removeEventListener(
|
||||
type: string,
|
||||
listener: EventListener | EventListenerObject,
|
||||
options?: Bun.EventListenerOptions | boolean,
|
||||
): void;
|
||||
};
|
||||
|
||||
declare global {
|
||||
var Bun: typeof import("bun");
|
||||
@@ -149,18 +71,29 @@ declare global {
|
||||
browser: boolean;
|
||||
|
||||
/** Whether you are using Bun */
|
||||
isBun: 1; // FIXME: this should actually return a boolean
|
||||
isBun: true;
|
||||
/** The current git sha of Bun **/
|
||||
revision: string;
|
||||
reallyExit(code?: number): never;
|
||||
dlopen(module: { exports: any }, filename: string, flags?: number): void;
|
||||
_exiting: boolean;
|
||||
noDeprecation: boolean;
|
||||
|
||||
binding(m: string): object;
|
||||
binding(m: "constants"): {
|
||||
os: typeof import("node:os").constants;
|
||||
fs: typeof import("node:fs").constants;
|
||||
crypto: typeof import("node:crypto").constants;
|
||||
zlib: typeof import("node:zlib").constants;
|
||||
trace: typeof import("node:trace").constants;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
namespace Bun {
|
||||
type ArrayBufferView = NodeJS.TypedArray | DataView;
|
||||
type StringOrBuffer = string | NodeJS.TypedArray | ArrayBufferLike;
|
||||
type PathLike = string | NodeJS.TypedArray | ArrayBufferLike | URL;
|
||||
type PathLike = import("bun").PathLike;
|
||||
type BodyInit = ReadableStream | XMLHttpRequestBodyInit | URLSearchParams;
|
||||
type XMLHttpRequestBodyInit = Blob | BufferSource | string | FormData;
|
||||
type ReadableStreamController<T> = ReadableStreamDefaultController<T>;
|
||||
@@ -168,7 +101,7 @@ declare global {
|
||||
| ReadableStreamDefaultReadValueResult<T>
|
||||
| ReadableStreamDefaultReadDoneResult;
|
||||
type ReadableStreamReader<T> = ReadableStreamDefaultReader<T>;
|
||||
type Transferable = ArrayBuffer | MessagePort;
|
||||
type Transferable = ArrayBuffer | import("worker_threads").MessagePort;
|
||||
type MessageEventSource = undefined;
|
||||
type Encoding = "utf-8" | "windows-1252" | "utf-16";
|
||||
type UncaughtExceptionOrigin = "uncaughtException" | "unhandledRejection";
|
||||
@@ -216,7 +149,8 @@ declare global {
|
||||
|
||||
type ResponseType = "basic" | "cors" | "default" | "error" | "opaque" | "opaqueredirect";
|
||||
|
||||
interface TextEncoder extends NodeTextEncoder {
|
||||
type _TextEncoder = import("util").TextEncoder;
|
||||
interface TextEncoder extends _TextEncoder {
|
||||
new (encoding?: Bun.Encoding, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextEncoder;
|
||||
/**
|
||||
* UTF-8 encodes the `src` string to the `dest` Uint8Array and returns an object
|
||||
@@ -234,7 +168,8 @@ declare global {
|
||||
encodeInto(src?: string, dest?: Bun.BufferSource): import("util").EncodeIntoResult;
|
||||
}
|
||||
|
||||
interface TextDecoder extends NodeTextDecoder {
|
||||
type _TextDecoder = import("util").TextDecoder;
|
||||
interface TextDecoder extends _TextDecoder {
|
||||
new (encoding?: Bun.Encoding, options?: { fatal?: boolean; ignoreBOM?: boolean }): TextDecoder;
|
||||
}
|
||||
|
||||
@@ -282,7 +217,7 @@ declare global {
|
||||
/** Returns the origin of the message, for server-sent events and cross-document messaging. */
|
||||
readonly origin: string;
|
||||
/** Returns the MessagePort array sent with the message, for cross-document messaging and channel messaging. */
|
||||
readonly ports: readonly MessagePort[]; // ReadonlyArray<typeof import("worker_threads").MessagePort["prototype"]>;
|
||||
readonly ports: readonly (typeof MessagePort)[]; // ReadonlyArray<typeof import("worker_threads").MessagePort["prototype"]>;
|
||||
readonly source: Bun.MessageEventSource | null;
|
||||
}
|
||||
|
||||
@@ -470,7 +405,6 @@ declare global {
|
||||
type?: undefined;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface DirectUnderlyingSource<R = any> {
|
||||
cancel?: UnderlyingSourceCancelCallback;
|
||||
pull: (controller: ReadableStreamDirectController) => void | PromiseLike<void>;
|
||||
@@ -642,6 +576,7 @@ declare global {
|
||||
* @since v10.5.0
|
||||
*/
|
||||
ref(): void;
|
||||
|
||||
/**
|
||||
* Calling `unref()` on a worker allows the thread to exit if this is the only
|
||||
* active handle in the event system. If the worker is already `unref()`ed calling`unref()` again has no effect.
|
||||
@@ -659,74 +594,44 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
interface ReadableStream<R = any> extends _ReadableStream<R> {}
|
||||
var ReadableStream: typeof globalThis extends {
|
||||
onerror: any;
|
||||
ReadableStream: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: ReadableStream;
|
||||
new <R = any>(underlyingSource?: Bun.UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
|
||||
new <R = any>(
|
||||
underlyingSource?: Bun.DirectUnderlyingSource<R>,
|
||||
strategy?: QueuingStrategy<R>,
|
||||
): ReadableStream<R>;
|
||||
};
|
||||
type _ReadableStream = import("stream/web").ReadableStream;
|
||||
interface ReadableStream<R = any> extends _ReadableStream {}
|
||||
var ReadableStream: {
|
||||
prototype: ReadableStream;
|
||||
new <R = any>(underlyingSource?: Bun.UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
|
||||
new <R = any>(underlyingSource?: Bun.DirectUnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
|
||||
};
|
||||
|
||||
interface WritableStream<W = any> extends _WritableStream<W> {}
|
||||
var WritableStream: typeof globalThis extends {
|
||||
onerror: any;
|
||||
WritableStream: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: WritableStream;
|
||||
new <W = any>(underlyingSink?: Bun.UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;
|
||||
};
|
||||
type _WritableStream = import("stream/web").WritableStream;
|
||||
interface WritableStream<W = any> extends _WritableStream {}
|
||||
var WritableStream: {
|
||||
prototype: WritableStream;
|
||||
new <W = any>(underlyingSink?: Bun.UnderlyingSink<W>, strategy?: QueuingStrategy<W>): WritableStream<W>;
|
||||
};
|
||||
|
||||
type _Worker = import("worker_threads").Worker;
|
||||
interface Worker extends _Worker {}
|
||||
var Worker: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Worker: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: Worker;
|
||||
new (scriptURL: string | URL, options?: Bun.WorkerOptions | undefined): Worker;
|
||||
/**
|
||||
* This is the cloned value of the `data` property passed to `new Worker()`
|
||||
*
|
||||
* This is Bun's equivalent of `workerData` in Node.js.
|
||||
*/
|
||||
data: any;
|
||||
};
|
||||
var Worker: {
|
||||
prototype: Worker;
|
||||
new (scriptURL: string | URL, options?: Bun.WorkerOptions | undefined): Worker;
|
||||
/**
|
||||
* This is the cloned value of the `data` property passed to `new Worker()`
|
||||
*
|
||||
* This is Bun's equivalent of `workerData` in Node.js.
|
||||
*/
|
||||
data: any;
|
||||
};
|
||||
|
||||
interface WebSocket extends _WebSocket {}
|
||||
var WebSocket: typeof globalThis extends {
|
||||
onerror: any;
|
||||
WebSocket: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof _WebSocket;
|
||||
var WebSocket: typeof import("ws").WebSocket;
|
||||
|
||||
type _Crypto = import("crypto").webcrypto.Crypto;
|
||||
interface Crypto extends _Crypto {}
|
||||
var Crypto: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Crypto: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: Crypto;
|
||||
new (): Crypto;
|
||||
};
|
||||
var Crypto: {
|
||||
prototype: Crypto;
|
||||
new (): Crypto;
|
||||
};
|
||||
|
||||
var crypto: typeof globalThis extends {
|
||||
onerror: any;
|
||||
crypto: infer T;
|
||||
}
|
||||
? T
|
||||
: Crypto;
|
||||
var crypto: Crypto;
|
||||
|
||||
/**
|
||||
* An implementation of the [WHATWG Encoding Standard](https://encoding.spec.whatwg.org/) `TextEncoder` API. All
|
||||
@@ -737,49 +642,27 @@ declare global {
|
||||
* const uint8array = encoder.encode('this is some data');
|
||||
* ```
|
||||
*/
|
||||
interface TextEncoder extends _TextEncoder {}
|
||||
var TextEncoder: typeof globalThis extends {
|
||||
onerror: any;
|
||||
TextEncoder: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof TextEncoder;
|
||||
interface TextEncoder extends Bun.TextEncoder {}
|
||||
var TextEncoder: typeof TextEncoder;
|
||||
|
||||
interface TextDecoder extends _TextDecoder {}
|
||||
var TextDecoder: typeof globalThis extends {
|
||||
onerror: any;
|
||||
TextDecoder: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof TextDecoder;
|
||||
interface TextDecoder extends Bun.TextDecoder {}
|
||||
var TextDecoder: typeof TextDecoder;
|
||||
|
||||
type _Performance = import("perf_hooks").Performance;
|
||||
interface Performance extends _Performance {}
|
||||
var performance: typeof globalThis extends {
|
||||
onerror: any;
|
||||
performance: infer T;
|
||||
}
|
||||
? T
|
||||
: Performance;
|
||||
var performance: Performance;
|
||||
|
||||
interface Event extends _Event {}
|
||||
var Event: typeof globalThis extends { onerror: any; Event: infer T }
|
||||
? T
|
||||
: {
|
||||
prototype: Event;
|
||||
new (type: string, eventInitDict?: Bun.EventInit): Event;
|
||||
};
|
||||
interface EventTarget extends _EventTarget {}
|
||||
var EventTarget: typeof globalThis extends {
|
||||
onerror: any;
|
||||
EventTarget: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: EventTarget;
|
||||
new (): EventTarget;
|
||||
};
|
||||
var Event: {
|
||||
prototype: Event;
|
||||
new (type: string, eventInitDict?: Bun.EventInit): Event;
|
||||
};
|
||||
|
||||
interface Body extends _Body {}
|
||||
interface EventTarget extends _EventTarget {}
|
||||
var EventTarget: {
|
||||
prototype: EventTarget;
|
||||
new (): EventTarget;
|
||||
};
|
||||
|
||||
interface File extends Blob {
|
||||
/**
|
||||
@@ -793,9 +676,11 @@ declare global {
|
||||
readonly lastModified: number;
|
||||
readonly name: string;
|
||||
}
|
||||
var File: typeof globalThis extends { onerror: any; File: infer T } ? T : typeof File;
|
||||
|
||||
interface FetchRequestInit extends RequestInit {
|
||||
var File: typeof File;
|
||||
|
||||
type _RequestInit = import("undici-types").RequestInit;
|
||||
interface RequestInit extends _RequestInit {
|
||||
/**
|
||||
* Log the raw HTTP request & response to stdout. This API may be
|
||||
* removed in a future version of Bun without notice.
|
||||
@@ -809,18 +694,10 @@ declare global {
|
||||
*/
|
||||
proxy?: string;
|
||||
|
||||
/**
|
||||
* Override the default TLS options
|
||||
*/
|
||||
tls?: {
|
||||
rejectUnauthorized?: boolean | undefined; // Defaults to true
|
||||
checkServerIdentity?: any; // TODO: change `any` to `checkServerIdentity`
|
||||
};
|
||||
|
||||
/**
|
||||
* Override the default S3 options
|
||||
*/
|
||||
s3?: S3FileOptions;
|
||||
s3?: import("bun").S3Options;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -909,43 +786,6 @@ declare global {
|
||||
new (): ShadowRealm;
|
||||
};
|
||||
|
||||
interface Fetch {
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
*
|
||||
* @param request Request object
|
||||
* @param init A structured value that contains settings for the fetch() request.
|
||||
*
|
||||
* @returns A promise that resolves to {@link Response} object.
|
||||
*/
|
||||
(request: Request, init?: RequestInit): Promise<Response>;
|
||||
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
*
|
||||
* @param url URL string
|
||||
* @param init A structured value that contains settings for the fetch() request.
|
||||
*
|
||||
* @returns A promise that resolves to {@link Response} object.
|
||||
*/
|
||||
(url: string | URL | Request, init?: FetchRequestInit): Promise<Response>;
|
||||
|
||||
(input: string | URL | globalThis.Request, init?: RequestInit): Promise<Response>;
|
||||
|
||||
/**
|
||||
* Start the DNS resolution, TCP connection, and TLS handshake for a request
|
||||
* before the request is actually sent.
|
||||
*
|
||||
* This can reduce the latency of a request when you know there's some
|
||||
* long-running task that will delay the request starting.
|
||||
*
|
||||
* This is a bun-specific API and is not part of the Fetch API specification.
|
||||
*/
|
||||
preconnect(url: string | URL): void;
|
||||
}
|
||||
|
||||
var fetch: Fetch;
|
||||
|
||||
function queueMicrotask(callback: (...args: any[]) => void): void;
|
||||
/**
|
||||
* Log an error using the default exception handler
|
||||
@@ -1048,15 +888,10 @@ declare global {
|
||||
};
|
||||
|
||||
interface MessageEvent<T = any> extends Bun.MessageEvent<T> {}
|
||||
var MessageEvent: typeof globalThis extends {
|
||||
onerror: any;
|
||||
MessageEvent: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: MessageEvent;
|
||||
new <T>(type: string, eventInitDict?: Bun.MessageEventInit<T>): MessageEvent<T>;
|
||||
};
|
||||
var MessageEvent: {
|
||||
prototype: MessageEvent;
|
||||
new <T>(type: string, eventInitDict?: Bun.MessageEventInit<T>): MessageEvent<T>;
|
||||
};
|
||||
|
||||
interface CustomEvent<T = any> extends Event {
|
||||
/** Returns any custom data event was created with. Typically used for synthetic events. */
|
||||
@@ -1068,25 +903,25 @@ declare global {
|
||||
new <T>(type: string, eventInitDict?: Bun.CustomEventInit<T>): CustomEvent<T>;
|
||||
};
|
||||
|
||||
/**
|
||||
* The URL interface represents an object providing static methods used for
|
||||
* creating object URLs.
|
||||
*/
|
||||
interface URL {
|
||||
new (url: string | URL, base?: string | URL): URL;
|
||||
/** Not implemented yet */
|
||||
createObjectURL(obj: Blob): string;
|
||||
/** Not implemented yet */
|
||||
revokeObjectURL(url: string): void;
|
||||
// /**
|
||||
// * The URL interface represents an object providing static methods used for
|
||||
// * creating object URLs.
|
||||
// */
|
||||
// interface URL extends _URL {
|
||||
// new (url: string | URL, base?: string | URL): URL;
|
||||
// /** Not implemented yet */
|
||||
// createObjectURL(obj: Blob): string;
|
||||
// /** Not implemented yet */
|
||||
// revokeObjectURL(url: string): void;
|
||||
|
||||
/**
|
||||
* Check if `url` is a valid URL string
|
||||
*
|
||||
* @param url URL string to parse
|
||||
* @param base URL to resolve against
|
||||
*/
|
||||
canParse(url: string, base?: string): boolean;
|
||||
}
|
||||
// /**
|
||||
// * Check if `url` is a valid URL string
|
||||
// *
|
||||
// * @param url URL string to parse
|
||||
// * @param base URL to resolve against
|
||||
// */
|
||||
// canParse(url: string, base?: string): boolean;
|
||||
// }
|
||||
|
||||
interface EventListener {
|
||||
(evt: Event): void;
|
||||
@@ -1450,30 +1285,22 @@ declare global {
|
||||
readonly DATA_CLONE_ERR: 25;
|
||||
}
|
||||
|
||||
var DOMException: typeof globalThis extends {
|
||||
onerror: any;
|
||||
DOMException: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: DOMException;
|
||||
new (message?: string, name?: string): DOMException;
|
||||
};
|
||||
var DOMException: {
|
||||
prototype: DOMException;
|
||||
new (message?: string, name?: string): DOMException;
|
||||
};
|
||||
|
||||
function alert(message?: string): void;
|
||||
function confirm(message?: string): boolean;
|
||||
function prompt(message?: string, _default?: string): string | null;
|
||||
|
||||
var SubtleCrypto: typeof globalThis extends {
|
||||
onerror: any;
|
||||
SubtleCrypto: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: _SubtleCrypto;
|
||||
new (): _SubtleCrypto;
|
||||
};
|
||||
type _SubtleCrypto = import("crypto").webcrypto.SubtleCrypto;
|
||||
var SubtleCrypto: {
|
||||
prototype: _SubtleCrypto;
|
||||
new (): _SubtleCrypto;
|
||||
};
|
||||
|
||||
type _CryptoKey = import("crypto").webcrypto.CryptoKey;
|
||||
interface CryptoKey extends _CryptoKey {}
|
||||
var CryptoKey: {
|
||||
prototype: CryptoKey;
|
||||
@@ -1949,64 +1776,71 @@ declare global {
|
||||
*/
|
||||
bytes(): Promise<Uint8Array>;
|
||||
}
|
||||
var Blob: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Blob: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof Blob;
|
||||
var Blob: typeof Blob;
|
||||
|
||||
var Response: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Response: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof import("./fetch").Response;
|
||||
interface Uint8Array {
|
||||
/**
|
||||
* Convert the Uint8Array to a base64 encoded string
|
||||
* @returns The base64 encoded string representation of the Uint8Array
|
||||
*/
|
||||
toBase64(options?: { alphabet?: "base64" | "base64url"; omitPadding?: boolean }): string;
|
||||
|
||||
var Request: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Request: infer T;
|
||||
}
|
||||
? T
|
||||
: {
|
||||
prototype: Request;
|
||||
new (requestInfo: string, requestInit?: RequestInit): Request;
|
||||
new (requestInfo: RequestInit & { url: string }): Request;
|
||||
new (requestInfo: Request, requestInit?: RequestInit): Request;
|
||||
};
|
||||
/**
|
||||
* Set the contents of the Uint8Array from a base64 encoded string
|
||||
* @param base64 The base64 encoded string to decode into the array
|
||||
* @param offset Optional starting index to begin setting the decoded bytes (default: 0)
|
||||
*/
|
||||
setFromBase64(
|
||||
base64: string,
|
||||
offset?: number,
|
||||
): {
|
||||
/**
|
||||
* The number of bytes read from the base64 string
|
||||
*/
|
||||
read: number;
|
||||
/**
|
||||
* The number of bytes written to the Uint8Array
|
||||
* Will never be greater than the `.byteLength` of this Uint8Array
|
||||
*/
|
||||
written: number;
|
||||
};
|
||||
|
||||
interface Headers {
|
||||
/**
|
||||
* Convert {@link Headers} to a plain JavaScript object.
|
||||
*
|
||||
* About 10x faster than `Object.fromEntries(headers.entries())`
|
||||
*
|
||||
* Called when you run `JSON.stringify(headers)`
|
||||
*
|
||||
* Does not preserve insertion order. Well-known header names are lowercased. Other header names are left as-is.
|
||||
* Convert the Uint8Array to a hex encoded string
|
||||
* @returns The hex encoded string representation of the Uint8Array
|
||||
*/
|
||||
toJSON(): Record<string, string>;
|
||||
toHex(): string;
|
||||
|
||||
/**
|
||||
* Get the total number of headers
|
||||
* Set the contents of the Uint8Array from a hex encoded string
|
||||
* @param hex The hex encoded string to decode into the array. The string must have
|
||||
* an even number of characters, be valid hexadecimal characters and contain no whitespace.
|
||||
*/
|
||||
readonly count: number;
|
||||
setFromHex(hex: string): {
|
||||
/**
|
||||
* The number of bytes read from the hex string
|
||||
*/
|
||||
read: number;
|
||||
/**
|
||||
* The number of bytes written to the Uint8Array
|
||||
* Will never be greater than the `.byteLength` of this Uint8Array
|
||||
*/
|
||||
written: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface Uint8ArrayConstructor {
|
||||
/**
|
||||
* Get all headers matching the name
|
||||
*
|
||||
* Only supports `"Set-Cookie"`. All other headers are empty arrays.
|
||||
*
|
||||
* @param name - The header name to get
|
||||
*
|
||||
* @returns An array of header values
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const headers = new Headers();
|
||||
* headers.append("Set-Cookie", "foo=bar");
|
||||
* headers.append("Set-Cookie", "baz=qux");
|
||||
* headers.getAll("Set-Cookie"); // ["foo=bar", "baz=qux"]
|
||||
* ```
|
||||
* Create a new Uint8Array from a base64 encoded string
|
||||
* @param base64 The base64 encoded string to convert to a Uint8Array
|
||||
* @returns A new Uint8Array containing the decoded data
|
||||
*/
|
||||
getAll(name: "set-cookie" | "Set-Cookie"): string[];
|
||||
fromBase64(
|
||||
base64: string,
|
||||
options?: {
|
||||
alphabet?: "base64" | "base64url";
|
||||
lastChunkHandling?: "loose" | "strict" | "stop-before-partial";
|
||||
},
|
||||
): Uint8Array;
|
||||
}
|
||||
}
|
||||
|
||||
9
packages/bun-types/index.d.ts
vendored
9
packages/bun-types/index.d.ts
vendored
@@ -3,16 +3,16 @@
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
/// <reference lib="esnext" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="ws" />
|
||||
/// <reference types="node" />
|
||||
|
||||
// contributors: uncomment this to detect conflicts with lib.dom.d.ts
|
||||
//// <reference lib="dom" />
|
||||
// /// <reference lib="dom" />
|
||||
|
||||
/// <reference path="./globals.d.ts" />
|
||||
/// <reference path="./bun.d.ts" />
|
||||
/// <reference path="./overrides.d.ts" />
|
||||
/// <reference path="./globals.d.ts" />
|
||||
/// <reference path="./fetch.d.ts" />
|
||||
/// <reference path="./overrides.d.ts" />
|
||||
/// <reference path="./ffi.d.ts" />
|
||||
/// <reference path="./test.d.ts" />
|
||||
/// <reference path="./html-rewriter.d.ts" />
|
||||
@@ -21,3 +21,4 @@
|
||||
/// <reference path="./wasm.d.ts" />
|
||||
/// <reference path="./deprecated.d.ts" />
|
||||
/// <reference path="./ambient.d.ts" />
|
||||
/// <reference path="./devserver.d.ts" />
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"name": "bun-types",
|
||||
"license": "MIT",
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"types": "./index.d.ts",
|
||||
"description": "Type definitions and documentation for Bun, an incredibly fast JavaScript runtime",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,7 +26,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"prebuild": "echo $(pwd)",
|
||||
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v:-1.0.0}\"'/g' {} +",
|
||||
"copy-docs": "rm -rf docs && cp -rL ../../docs/ ./docs && find ./docs -type f -name '*.md' -exec sed -i 's/\\$BUN_LATEST_VERSION/'\"${BUN_VERSION#bun-v}\"'/g' {} +",
|
||||
"build": "bun run copy-docs && bun scripts/build.ts && bun run fmt",
|
||||
"test": "tsc",
|
||||
"fmt": "echo $(which biome) && biome format --write ."
|
||||
|
||||
@@ -2,6 +2,13 @@ import { join } from "node:path";
|
||||
|
||||
import pkg from "../package.json";
|
||||
|
||||
const BUN_VERSION = (process.env.BUN_VERSION || Bun.version || process.versions.bun).replace(/^.*v/, "");
|
||||
const BUN_VERSION = (
|
||||
process.env.BUN_VERSION ||
|
||||
Bun.version ||
|
||||
process.versions.bun
|
||||
).replace(/^.*v/, "");
|
||||
|
||||
Bun.write(join(import.meta.dir, "..", "package.json"), JSON.stringify({ version: BUN_VERSION, ...pkg }, null, 2));
|
||||
Bun.write(
|
||||
join(import.meta.dir, "..", "package.json"),
|
||||
JSON.stringify({ version: BUN_VERSION, ...pkg }, null, 2),
|
||||
);
|
||||
|
||||
73
packages/bun-types/sqlite.d.ts
vendored
73
packages/bun-types/sqlite.d.ts
vendored
@@ -477,6 +477,79 @@ declare module "bun:sqlite" {
|
||||
*/
|
||||
static deserialize(serialized: NodeJS.TypedArray | ArrayBufferLike, isReadOnly?: boolean): Database;
|
||||
|
||||
/**
|
||||
* Load a serialized SQLite3 database. This version enables you to specify
|
||||
* additional options such as `strict` to put the database into strict mode.
|
||||
*
|
||||
* Internally, this calls `sqlite3_deserialize`.
|
||||
*
|
||||
* @param serialized Data to load
|
||||
* @returns `Database` instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* test("supports serialize/deserialize", () => {
|
||||
* const db = Database.open(":memory:");
|
||||
* db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)");
|
||||
* db.exec('INSERT INTO test (name) VALUES ("Hello")');
|
||||
* db.exec('INSERT INTO test (name) VALUES ("World")');
|
||||
*
|
||||
* const input = db.serialize();
|
||||
* const db2 = Database.deserialize(input, { strict: true });
|
||||
*
|
||||
* const stmt = db2.prepare("SELECT * FROM test");
|
||||
* expect(JSON.stringify(stmt.get())).toBe(
|
||||
* JSON.stringify({
|
||||
* id: 1,
|
||||
* name: "Hello",
|
||||
* }),
|
||||
* );
|
||||
*
|
||||
* expect(JSON.stringify(stmt.all())).toBe(
|
||||
* JSON.stringify([
|
||||
* {
|
||||
* id: 1,
|
||||
* name: "Hello",
|
||||
* },
|
||||
* {
|
||||
* id: 2,
|
||||
* name: "World",
|
||||
* },
|
||||
* ]),
|
||||
* );
|
||||
* db2.exec("insert into test (name) values ($foo)", { foo: "baz" });
|
||||
* expect(JSON.stringify(stmt.all())).toBe(
|
||||
* JSON.stringify([
|
||||
* {
|
||||
* id: 1,
|
||||
* name: "Hello",
|
||||
* },
|
||||
* {
|
||||
* id: 2,
|
||||
* name: "World",
|
||||
* },
|
||||
* {
|
||||
* id: 3,
|
||||
* name: "baz",
|
||||
* },
|
||||
* ]),
|
||||
* );
|
||||
*
|
||||
* const db3 = Database.deserialize(input, { readonly: true, strict: true });
|
||||
* try {
|
||||
* db3.exec("insert into test (name) values ($foo)", { foo: "baz" });
|
||||
* throw new Error("Expected error");
|
||||
* } catch (e) {
|
||||
* expect(e.message).toBe("attempt to write a readonly database");
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
static deserialize(
|
||||
serialized: NodeJS.TypedArray | ArrayBufferLike,
|
||||
options?: { readonly?: boolean; strict?: boolean; safeIntegers?: boolean },
|
||||
): Database;
|
||||
|
||||
/**
|
||||
* See `sqlite3_file_control` for more information.
|
||||
* @link https://www.sqlite.org/c3ref/file_control.html
|
||||
|
||||
26
packages/bun-types/test.d.ts
vendored
26
packages/bun-types/test.d.ts
vendored
@@ -165,8 +165,14 @@ declare module "bun:test" {
|
||||
* @param label the label for the tests
|
||||
* @param fn the function that defines the tests
|
||||
*/
|
||||
|
||||
interface FunctionLike {
|
||||
readonly name: string;
|
||||
}
|
||||
export interface Describe {
|
||||
(label: string, fn: () => void): void;
|
||||
(fn: () => void): void;
|
||||
|
||||
(label: number | string | Function | FunctionLike, fn: () => void): void;
|
||||
/**
|
||||
* Skips all other tests, except this group of tests.
|
||||
*
|
||||
@@ -401,6 +407,22 @@ declare module "bun:test" {
|
||||
fn?: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void),
|
||||
options?: number | TestOptions,
|
||||
): void;
|
||||
/**
|
||||
* Marks this test as failing.
|
||||
*
|
||||
* Use `test.failing` when you are writing a test and expecting it to fail.
|
||||
* These tests will behave the other way normal tests do. If failing test
|
||||
* will throw any errors then it will pass. If it does not throw it will
|
||||
* fail.
|
||||
*
|
||||
* `test.failing` is very similar to {@link test.todo} except that it always
|
||||
* runs, regardless of the `--todo` flag.
|
||||
*
|
||||
* @param label the label for the test
|
||||
* @param fn the test function
|
||||
* @param options the test timeout or options
|
||||
*/
|
||||
failing(label: string, fn?: (() => void | Promise<unknown>) | ((done: (err?: unknown) => void) => void)): void;
|
||||
/**
|
||||
* Runs this test, if `condition` is true.
|
||||
*
|
||||
@@ -1060,7 +1082,7 @@ declare module "bun:test" {
|
||||
|
||||
/**
|
||||
* Asserts that an `object` contains all the provided keys.
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* expect({ a: 'foo', b: 'bar', c: 'baz' }).toContainKeys(['a', 'b']);
|
||||
* expect({ a: 'foo', b: 'bar', c: 'baz' }).toContainKeys(['a', 'b', 'c']);
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"skipLibCheck": false,
|
||||
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"noEmit": false,
|
||||
"declarationDir": "out"
|
||||
},
|
||||
"files": ["ambient.d.ts"], // ambient defines .txt and .toml loaders
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"skipLibCheck": true,
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"noEmit": false,
|
||||
"declarationDir": "out"
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
|
||||
@@ -2347,174 +2347,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SwissSign Silver CA - G2"
|
||||
#
|
||||
# Issuer: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Serial Number:4f:1b:d4:2f:54:bb:2f:4b
|
||||
# Subject: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Not Valid Before: Wed Oct 25 08:32:46 2006
|
||||
# Not Valid After : Sat Oct 25 08:32:46 2036
|
||||
# Fingerprint (SHA-256): BE:6C:4D:A2:BB:B9:BA:59:B6:F3:93:97:68:37:42:46:C3:C0:05:99:3F:A9:8F:02:0D:1D:ED:BE:D4:8A:81:D5
|
||||
# Fingerprint (SHA1): 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SwissSign Silver CA - G2"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
|
||||
\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
|
||||
\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
|
||||
\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
|
||||
\162\040\103\101\040\055\040\107\062
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
|
||||
\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
|
||||
\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
|
||||
\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
|
||||
\162\040\103\101\040\055\040\107\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\010\117\033\324\057\124\273\057\113
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\275\060\202\003\245\240\003\002\001\002\002\010\117
|
||||
\033\324\057\124\273\057\113\060\015\006\011\052\206\110\206\367
|
||||
\015\001\001\005\005\000\060\107\061\013\060\011\006\003\125\004
|
||||
\006\023\002\103\110\061\025\060\023\006\003\125\004\012\023\014
|
||||
\123\167\151\163\163\123\151\147\156\040\101\107\061\041\060\037
|
||||
\006\003\125\004\003\023\030\123\167\151\163\163\123\151\147\156
|
||||
\040\123\151\154\166\145\162\040\103\101\040\055\040\107\062\060
|
||||
\036\027\015\060\066\061\060\062\065\060\070\063\062\064\066\132
|
||||
\027\015\063\066\061\060\062\065\060\070\063\062\064\066\132\060
|
||||
\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061\025
|
||||
\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123\151
|
||||
\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023\030
|
||||
\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145\162
|
||||
\040\103\101\040\055\040\107\062\060\202\002\042\060\015\006\011
|
||||
\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000
|
||||
\060\202\002\012\002\202\002\001\000\304\361\207\177\323\170\061
|
||||
\367\070\311\370\303\231\103\274\307\367\274\067\347\116\161\272
|
||||
\113\217\245\163\035\134\156\230\256\003\127\256\070\067\103\057
|
||||
\027\075\037\310\316\150\020\301\170\256\031\003\053\020\372\054
|
||||
\171\203\366\350\271\150\271\125\362\004\104\247\071\371\374\004
|
||||
\213\036\361\242\115\047\371\141\173\272\267\345\242\023\266\353
|
||||
\141\076\320\154\321\346\373\372\136\355\035\264\236\240\065\133
|
||||
\241\222\313\360\111\222\376\205\012\005\076\346\331\013\342\117
|
||||
\273\334\225\067\374\221\351\062\065\042\321\037\072\116\047\205
|
||||
\235\260\025\224\062\332\141\015\107\115\140\102\256\222\107\350
|
||||
\203\132\120\130\351\212\213\271\135\241\334\335\231\112\037\066
|
||||
\147\273\110\344\203\266\067\353\110\072\257\017\147\217\027\007
|
||||
\350\004\312\357\152\061\207\324\300\266\371\224\161\173\147\144
|
||||
\270\266\221\112\102\173\145\056\060\152\014\365\220\356\225\346
|
||||
\362\315\202\354\331\241\112\354\366\262\113\345\105\205\346\155
|
||||
\170\223\004\056\234\202\155\066\251\304\061\144\037\206\203\013
|
||||
\052\364\065\012\170\311\125\317\101\260\107\351\060\237\231\276
|
||||
\141\250\006\204\271\050\172\137\070\331\033\251\070\260\203\177
|
||||
\163\301\303\073\110\052\202\017\041\233\270\314\250\065\303\204
|
||||
\033\203\263\076\276\244\225\151\001\072\211\000\170\004\331\311
|
||||
\364\231\031\253\126\176\133\213\206\071\025\221\244\020\054\011
|
||||
\062\200\140\263\223\300\052\266\030\013\235\176\215\111\362\020
|
||||
\112\177\371\325\106\057\031\222\243\231\247\046\254\273\214\074
|
||||
\346\016\274\107\007\334\163\121\361\160\144\057\010\371\264\107
|
||||
\035\060\154\104\352\051\067\205\222\150\146\274\203\070\376\173
|
||||
\071\056\323\120\360\037\373\136\140\266\251\246\372\047\101\361
|
||||
\233\030\162\362\365\204\164\112\311\147\304\124\256\110\144\337
|
||||
\214\321\156\260\035\341\007\217\010\036\231\234\161\351\114\330
|
||||
\245\367\107\022\037\164\321\121\236\206\363\302\242\043\100\013
|
||||
\163\333\113\246\347\163\006\214\301\240\351\301\131\254\106\372
|
||||
\346\057\370\317\161\234\106\155\271\304\025\215\070\171\003\105
|
||||
\110\357\304\135\327\010\356\207\071\042\206\262\015\017\130\103
|
||||
\367\161\251\110\056\375\352\326\037\002\003\001\000\001\243\201
|
||||
\254\060\201\251\060\016\006\003\125\035\017\001\001\377\004\004
|
||||
\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005
|
||||
\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024
|
||||
\027\240\315\301\344\101\266\072\133\073\313\105\235\275\034\302
|
||||
\230\372\206\130\060\037\006\003\125\035\043\004\030\060\026\200
|
||||
\024\027\240\315\301\344\101\266\072\133\073\313\105\235\275\034
|
||||
\302\230\372\206\130\060\106\006\003\125\035\040\004\077\060\075
|
||||
\060\073\006\011\140\205\164\001\131\001\003\001\001\060\056\060
|
||||
\054\006\010\053\006\001\005\005\007\002\001\026\040\150\164\164
|
||||
\160\072\057\057\162\145\160\157\163\151\164\157\162\171\056\163
|
||||
\167\151\163\163\163\151\147\156\056\143\157\155\057\060\015\006
|
||||
\011\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001
|
||||
\000\163\306\201\340\047\322\055\017\340\225\060\342\232\101\177
|
||||
\120\054\137\137\142\141\251\206\152\151\030\014\164\111\326\135
|
||||
\204\352\101\122\030\157\130\255\120\126\040\152\306\275\050\151
|
||||
\130\221\334\221\021\065\251\072\035\274\032\245\140\236\330\037
|
||||
\177\105\221\151\331\176\273\170\162\301\006\017\052\316\217\205
|
||||
\160\141\254\240\315\013\270\071\051\126\204\062\116\206\273\075
|
||||
\304\052\331\327\037\162\356\376\121\241\042\101\261\161\002\143
|
||||
\032\202\260\142\253\136\127\022\037\337\313\335\165\240\300\135
|
||||
\171\220\214\033\340\120\346\336\061\376\230\173\160\137\245\220
|
||||
\330\255\370\002\266\157\323\140\335\100\113\042\305\075\255\072
|
||||
\172\237\032\032\107\221\171\063\272\202\334\062\151\003\226\156
|
||||
\037\113\360\161\376\343\147\162\240\261\277\134\213\344\372\231
|
||||
\042\307\204\271\033\215\043\227\077\355\045\340\317\145\273\365
|
||||
\141\004\357\335\036\262\132\101\042\132\241\237\135\054\350\133
|
||||
\311\155\251\014\014\170\252\140\306\126\217\001\132\014\150\274
|
||||
\151\031\171\304\037\176\227\005\277\305\351\044\121\136\324\325
|
||||
\113\123\355\331\043\132\066\003\145\243\301\003\255\101\060\363
|
||||
\106\033\205\220\257\145\265\325\261\344\026\133\170\165\035\227
|
||||
\172\155\131\251\052\217\173\336\303\207\211\020\231\111\163\170
|
||||
\310\075\275\121\065\164\052\325\361\176\151\033\052\273\073\275
|
||||
\045\270\232\132\075\162\141\220\146\207\356\014\326\115\324\021
|
||||
\164\013\152\376\013\003\374\243\125\127\211\376\112\313\256\133
|
||||
\027\005\310\362\215\043\061\123\070\322\055\152\077\202\271\215
|
||||
\010\152\367\136\101\164\156\303\021\176\007\254\051\140\221\077
|
||||
\070\312\127\020\015\275\060\057\307\245\346\101\240\332\256\005
|
||||
\207\232\240\244\145\154\114\011\014\211\272\270\323\271\300\223
|
||||
\212\060\372\215\345\232\153\025\001\116\147\252\332\142\126\076
|
||||
\204\010\146\322\304\066\175\247\076\020\374\210\340\324\200\345
|
||||
\000\275\252\363\116\006\243\172\152\371\142\162\343\011\117\353
|
||||
\233\016\001\043\361\237\273\174\334\334\154\021\227\045\262\362
|
||||
\264\143\024\322\006\052\147\214\203\365\316\352\007\330\232\152
|
||||
\036\354\344\012\273\052\114\353\011\140\071\316\312\142\330\056
|
||||
\156
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "SwissSign Silver CA - G2"
|
||||
# Issuer: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Serial Number:4f:1b:d4:2f:54:bb:2f:4b
|
||||
# Subject: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Not Valid Before: Wed Oct 25 08:32:46 2006
|
||||
# Not Valid After : Sat Oct 25 08:32:46 2036
|
||||
# Fingerprint (SHA-256): BE:6C:4D:A2:BB:B9:BA:59:B6:F3:93:97:68:37:42:46:C3:C0:05:99:3F:A9:8F:02:0D:1D:ED:BE:D4:8A:81:D5
|
||||
# Fingerprint (SHA1): 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SwissSign Silver CA - G2"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\233\252\345\237\126\356\041\313\103\132\276\045\223\337\247\360
|
||||
\100\321\035\313
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\340\006\241\311\175\317\311\374\015\300\126\165\226\330\142\023
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
|
||||
\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
|
||||
\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
|
||||
\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
|
||||
\162\040\103\101\040\055\040\107\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\010\117\033\324\057\124\273\057\113
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SecureTrust CA"
|
||||
#
|
||||
@@ -21231,7 +21063,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\011\000\326\135\233\263\170\201\056\353
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -21399,7 +21231,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\154\040
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -21514,7 +21346,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\112\353
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -25970,3 +25802,339 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "D-TRUST BR Root CA 2 2023"
|
||||
#
|
||||
# Issuer: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:73:3b:30:04:48:5b:d9:4d:78:2e:73:4b:c9:a1:dc:66
|
||||
# Subject: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 08:56:31 2023
|
||||
# Not Valid After : Sun May 09 08:56:30 2038
|
||||
# Fingerprint (SHA-256): 05:52:E6:F8:3F:DF:65:E8:FA:96:70:E6:66:DF:28:A4:E2:13:40:B5:10:CB:E5:25:66:F9:7C:4F:B9:4B:2B:D1
|
||||
# Fingerprint (SHA1): 2D:B0:70:EE:71:94:AF:69:68:17:DB:79:CE:58:9F:A0:6B:96:F7:87
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST BR Root CA 2 2023"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\102\122\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\102\122\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\163\073\060\004\110\133\331\115\170\056\163\113\311\241
|
||||
\334\146
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\251\060\202\003\221\240\003\002\001\002\002\020\163
|
||||
\073\060\004\110\133\331\115\170\056\163\113\311\241\334\146\060
|
||||
\015\006\011\052\206\110\206\367\015\001\001\015\005\000\060\110
|
||||
\061\013\060\011\006\003\125\004\006\023\002\104\105\061\025\060
|
||||
\023\006\003\125\004\012\023\014\104\055\124\162\165\163\164\040
|
||||
\107\155\142\110\061\042\060\040\006\003\125\004\003\023\031\104
|
||||
\055\124\122\125\123\124\040\102\122\040\122\157\157\164\040\103
|
||||
\101\040\062\040\062\060\062\063\060\036\027\015\062\063\060\065
|
||||
\060\071\060\070\065\066\063\061\132\027\015\063\070\060\065\060
|
||||
\071\060\070\065\066\063\060\132\060\110\061\013\060\011\006\003
|
||||
\125\004\006\023\002\104\105\061\025\060\023\006\003\125\004\012
|
||||
\023\014\104\055\124\162\165\163\164\040\107\155\142\110\061\042
|
||||
\060\040\006\003\125\004\003\023\031\104\055\124\122\125\123\124
|
||||
\040\102\122\040\122\157\157\164\040\103\101\040\062\040\062\060
|
||||
\062\063\060\202\002\042\060\015\006\011\052\206\110\206\367\015
|
||||
\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
|
||||
\002\001\000\256\377\011\131\221\200\012\112\150\346\044\077\270
|
||||
\247\344\310\072\012\072\026\315\311\043\141\240\223\161\362\253
|
||||
\213\163\217\240\147\145\140\322\124\153\143\121\157\111\063\340
|
||||
\162\007\023\175\070\315\006\222\007\051\122\153\116\167\154\004
|
||||
\323\225\372\335\114\214\331\135\301\141\175\113\347\050\263\104
|
||||
\201\173\121\257\335\063\261\150\174\326\116\114\376\053\150\271
|
||||
\312\146\151\304\354\136\127\177\367\015\307\234\066\066\345\007
|
||||
\140\254\300\114\352\010\154\357\006\174\117\133\050\172\010\374
|
||||
\223\135\233\366\234\264\213\206\272\041\271\364\360\350\131\132
|
||||
\050\241\064\204\032\045\221\266\265\217\357\262\371\200\372\371
|
||||
\075\074\021\162\330\343\057\206\166\305\171\054\301\251\220\223
|
||||
\106\230\147\313\203\152\240\120\043\247\073\366\201\071\340\355
|
||||
\360\271\277\145\361\330\313\172\373\357\163\003\316\000\364\175
|
||||
\327\340\135\073\146\270\334\216\272\203\313\207\166\003\374\045
|
||||
\331\347\043\157\006\375\147\363\340\377\204\274\107\277\265\026
|
||||
\030\106\151\024\314\005\367\333\323\111\254\153\314\253\344\265
|
||||
\013\103\044\136\113\153\115\147\337\326\265\076\117\170\037\224
|
||||
\161\044\352\336\160\374\361\223\376\236\223\132\344\224\132\227
|
||||
\124\014\065\173\137\154\356\000\037\044\354\003\272\002\365\166
|
||||
\364\237\324\232\355\205\054\070\042\057\307\330\057\166\021\117
|
||||
\375\154\134\350\365\216\047\207\177\031\112\041\107\220\035\171
|
||||
\215\034\133\370\317\112\205\344\355\263\133\215\276\304\144\050
|
||||
\135\101\304\156\254\070\132\117\043\164\164\251\022\303\366\322
|
||||
\271\021\025\063\007\221\330\073\067\072\143\060\006\321\305\042
|
||||
\066\050\142\043\020\340\106\314\227\254\326\053\135\144\044\325
|
||||
\356\034\016\336\373\010\132\165\052\366\143\155\316\013\102\276
|
||||
\321\272\160\034\234\041\345\017\061\151\027\327\374\012\264\336
|
||||
\355\200\234\313\222\264\213\365\336\131\242\130\011\245\143\107
|
||||
\013\341\101\062\064\101\331\232\261\331\250\260\033\132\336\015
|
||||
\015\364\342\262\135\065\200\271\201\324\204\151\221\002\313\165
|
||||
\320\215\305\265\075\011\221\011\217\024\241\024\164\171\076\326
|
||||
\311\025\035\244\131\131\042\334\366\212\105\075\074\022\326\076
|
||||
\135\062\057\002\003\001\000\001\243\201\216\060\201\213\060\017
|
||||
\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
|
||||
\035\006\003\125\035\016\004\026\004\024\147\220\360\326\336\265
|
||||
\030\325\106\051\176\134\253\370\236\010\274\144\225\020\060\016
|
||||
\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\111
|
||||
\006\003\125\035\037\004\102\060\100\060\076\240\074\240\072\206
|
||||
\070\150\164\164\160\072\057\057\143\162\154\056\144\055\164\162
|
||||
\165\163\164\056\156\145\164\057\143\162\154\057\144\055\164\162
|
||||
\165\163\164\137\142\162\137\162\157\157\164\137\143\141\137\062
|
||||
\137\062\060\062\063\056\143\162\154\060\015\006\011\052\206\110
|
||||
\206\367\015\001\001\015\005\000\003\202\002\001\000\064\367\263
|
||||
\167\123\333\060\026\271\055\245\041\361\100\041\165\353\353\110
|
||||
\026\201\075\163\340\236\047\052\353\167\251\023\244\152\012\132
|
||||
\132\024\063\075\150\037\201\256\151\375\214\237\145\154\064\102
|
||||
\331\055\320\177\170\026\261\072\254\043\061\255\136\177\256\347
|
||||
\256\053\372\272\374\074\227\225\100\223\137\303\055\003\243\355
|
||||
\244\157\123\327\372\100\016\060\365\000\040\054\000\114\214\073
|
||||
\264\243\037\266\277\221\062\253\257\222\230\323\026\346\324\321
|
||||
\124\134\103\133\056\256\357\127\052\250\264\157\244\357\015\126
|
||||
\024\332\041\253\040\166\236\003\374\046\270\236\077\076\003\046
|
||||
\346\114\333\235\137\102\204\075\105\003\003\034\131\210\312\334
|
||||
\056\141\044\132\244\352\047\013\163\022\276\122\263\012\317\062
|
||||
\027\342\036\207\032\026\225\110\155\132\340\320\317\011\222\046
|
||||
\146\221\330\243\141\016\252\201\201\177\350\122\202\321\102\347
|
||||
\340\035\030\372\244\205\066\347\206\340\015\353\274\324\311\326
|
||||
\074\103\361\135\111\156\176\201\233\151\265\211\142\217\210\122
|
||||
\330\327\376\047\301\043\305\313\053\002\273\261\137\376\373\103
|
||||
\205\003\106\276\135\306\312\041\046\377\327\002\236\164\112\334
|
||||
\370\023\025\261\201\127\066\313\145\134\321\035\061\167\351\045
|
||||
\303\303\262\062\067\325\361\230\011\344\155\143\200\010\253\006
|
||||
\222\201\324\351\160\217\247\077\262\355\206\214\202\152\065\310
|
||||
\102\132\202\321\122\032\105\017\025\245\000\360\224\173\145\047
|
||||
\127\071\103\317\174\177\346\275\065\263\173\361\031\114\336\072
|
||||
\226\317\351\166\356\003\347\302\103\122\074\152\201\350\301\132
|
||||
\200\275\021\135\223\153\373\307\346\144\077\273\151\034\351\335
|
||||
\045\213\257\164\311\124\100\312\313\223\023\012\355\373\146\222
|
||||
\021\312\365\300\372\330\203\125\003\174\323\305\042\106\165\160
|
||||
\153\171\110\006\052\202\232\277\346\353\026\016\042\105\001\274
|
||||
\335\066\224\064\251\065\046\212\327\227\271\356\010\162\277\064
|
||||
\222\160\203\200\253\070\252\131\150\335\100\244\030\220\262\363
|
||||
\325\003\312\046\312\357\325\307\340\217\123\216\360\000\343\250
|
||||
\355\237\371\255\167\340\053\143\117\236\303\356\067\273\170\011
|
||||
\204\236\271\156\373\051\231\220\350\200\323\237\044
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "D-TRUST BR Root CA 2 2023"
|
||||
# Issuer: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:73:3b:30:04:48:5b:d9:4d:78:2e:73:4b:c9:a1:dc:66
|
||||
# Subject: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 08:56:31 2023
|
||||
# Not Valid After : Sun May 09 08:56:30 2038
|
||||
# Fingerprint (SHA-256): 05:52:E6:F8:3F:DF:65:E8:FA:96:70:E6:66:DF:28:A4:E2:13:40:B5:10:CB:E5:25:66:F9:7C:4F:B9:4B:2B:D1
|
||||
# Fingerprint (SHA1): 2D:B0:70:EE:71:94:AF:69:68:17:DB:79:CE:58:9F:A0:6B:96:F7:87
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST BR Root CA 2 2023"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\055\260\160\356\161\224\257\151\150\027\333\171\316\130\237\240
|
||||
\153\226\367\207
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\341\011\355\323\140\324\126\033\107\037\267\014\137\033\137\205
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\102\122\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\163\073\060\004\110\133\331\115\170\056\163\113\311\241
|
||||
\334\146
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "D-TRUST EV Root CA 2 2023"
|
||||
#
|
||||
# Issuer: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:69:26:09:7e:80:4b:4c:a0:a7:8c:78:62:53:5f:5a:6f
|
||||
# Subject: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 09:10:33 2023
|
||||
# Not Valid After : Sun May 09 09:10:32 2038
|
||||
# Fingerprint (SHA-256): 8E:82:21:B2:E7:D4:00:78:36:A1:67:2F:0D:CC:29:9C:33:BC:07:D3:16:F1:32:FA:1A:20:6D:58:71:50:F1:CE
|
||||
# Fingerprint (SHA1): A5:5B:D8:47:6C:8F:19:F7:4C:F4:6D:6B:B6:C2:79:82:22:DF:54:8B
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST EV Root CA 2 2023"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\105\126\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\105\126\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\151\046\011\176\200\113\114\240\247\214\170\142\123\137
|
||||
\132\157
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\251\060\202\003\221\240\003\002\001\002\002\020\151
|
||||
\046\011\176\200\113\114\240\247\214\170\142\123\137\132\157\060
|
||||
\015\006\011\052\206\110\206\367\015\001\001\015\005\000\060\110
|
||||
\061\013\060\011\006\003\125\004\006\023\002\104\105\061\025\060
|
||||
\023\006\003\125\004\012\023\014\104\055\124\162\165\163\164\040
|
||||
\107\155\142\110\061\042\060\040\006\003\125\004\003\023\031\104
|
||||
\055\124\122\125\123\124\040\105\126\040\122\157\157\164\040\103
|
||||
\101\040\062\040\062\060\062\063\060\036\027\015\062\063\060\065
|
||||
\060\071\060\071\061\060\063\063\132\027\015\063\070\060\065\060
|
||||
\071\060\071\061\060\063\062\132\060\110\061\013\060\011\006\003
|
||||
\125\004\006\023\002\104\105\061\025\060\023\006\003\125\004\012
|
||||
\023\014\104\055\124\162\165\163\164\040\107\155\142\110\061\042
|
||||
\060\040\006\003\125\004\003\023\031\104\055\124\122\125\123\124
|
||||
\040\105\126\040\122\157\157\164\040\103\101\040\062\040\062\060
|
||||
\062\063\060\202\002\042\060\015\006\011\052\206\110\206\367\015
|
||||
\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
|
||||
\002\001\000\330\216\243\211\200\013\262\127\122\334\251\123\114
|
||||
\067\271\177\143\027\023\357\247\133\043\133\151\165\260\231\012
|
||||
\027\301\213\304\333\250\340\314\061\272\302\362\315\135\351\267
|
||||
\370\035\257\152\304\225\207\327\107\311\225\330\202\004\120\075
|
||||
\201\010\377\344\075\263\261\326\305\262\375\210\011\333\234\204
|
||||
\354\045\027\024\207\177\060\170\233\152\130\311\266\163\050\074
|
||||
\064\367\231\367\177\323\246\370\034\105\174\255\054\214\224\077
|
||||
\330\147\020\123\176\042\315\116\045\121\360\045\044\065\021\136
|
||||
\020\306\354\207\146\211\201\150\272\314\053\235\107\163\037\275
|
||||
\315\221\244\162\152\234\242\033\030\240\157\354\120\364\175\100
|
||||
\302\250\060\317\275\163\310\023\053\020\023\036\213\232\250\072
|
||||
\224\163\323\030\151\012\112\377\301\001\003\377\171\177\265\110
|
||||
\177\173\356\350\051\157\066\114\225\141\206\330\371\242\163\212
|
||||
\356\256\057\226\356\150\315\075\115\050\102\371\105\053\062\033
|
||||
\106\125\026\152\246\113\051\371\273\225\126\277\106\035\354\035
|
||||
\223\035\300\145\262\037\241\103\256\126\236\240\261\217\153\022
|
||||
\267\140\155\170\013\312\212\134\355\036\226\016\203\246\110\225
|
||||
\215\073\243\041\304\256\130\306\000\262\204\264\043\244\226\206
|
||||
\065\270\330\236\330\254\064\111\230\143\225\305\313\155\110\107
|
||||
\342\362\056\030\036\320\061\253\335\164\354\371\334\214\270\034
|
||||
\216\150\043\272\320\363\120\334\317\145\217\163\072\062\307\174
|
||||
\376\312\202\042\117\276\216\142\107\146\345\315\207\342\350\325
|
||||
\017\030\237\345\004\162\113\106\074\020\362\104\302\144\126\161
|
||||
\116\165\350\234\311\046\164\305\175\131\321\012\133\017\155\376
|
||||
\236\165\034\030\306\032\072\174\330\015\004\314\315\267\105\145
|
||||
\172\261\217\270\256\204\110\076\263\172\115\250\003\342\342\176
|
||||
\001\026\131\150\030\103\063\260\322\334\260\032\103\065\356\245
|
||||
\332\251\106\134\256\206\201\101\001\112\164\046\354\237\006\277
|
||||
\302\005\067\144\165\170\051\150\375\305\365\353\376\107\371\344
|
||||
\205\260\341\173\061\235\246\177\162\243\271\304\054\056\314\231
|
||||
\127\016\041\014\105\001\224\145\353\145\011\306\143\042\013\063
|
||||
\111\222\110\074\374\315\316\260\076\216\236\213\370\376\111\305
|
||||
\065\162\107\002\003\001\000\001\243\201\216\060\201\213\060\017
|
||||
\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
|
||||
\035\006\003\125\035\016\004\026\004\024\252\374\221\020\033\207
|
||||
\221\137\026\271\277\117\113\221\136\000\034\261\062\200\060\016
|
||||
\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\111
|
||||
\006\003\125\035\037\004\102\060\100\060\076\240\074\240\072\206
|
||||
\070\150\164\164\160\072\057\057\143\162\154\056\144\055\164\162
|
||||
\165\163\164\056\156\145\164\057\143\162\154\057\144\055\164\162
|
||||
\165\163\164\137\145\166\137\162\157\157\164\137\143\141\137\062
|
||||
\137\062\060\062\063\056\143\162\154\060\015\006\011\052\206\110
|
||||
\206\367\015\001\001\015\005\000\003\202\002\001\000\223\313\245
|
||||
\037\231\021\354\232\015\137\054\025\223\306\077\276\020\215\170
|
||||
\102\360\156\220\107\107\216\243\222\062\215\160\217\366\133\215
|
||||
\276\211\316\107\001\152\033\040\040\211\133\310\202\020\154\340
|
||||
\347\231\252\153\306\052\240\143\065\221\152\205\045\255\027\070
|
||||
\245\233\176\120\362\166\352\205\005\052\047\101\053\261\201\321
|
||||
\242\366\100\165\251\016\313\361\125\110\330\354\321\354\263\350
|
||||
\316\024\241\065\354\302\136\065\032\253\246\026\001\006\216\352
|
||||
\334\057\243\212\312\054\221\353\122\216\137\014\233\027\317\313
|
||||
\163\007\031\304\152\302\163\124\357\174\103\122\143\301\021\312
|
||||
\302\105\261\364\073\123\365\151\256\074\343\245\336\254\350\124
|
||||
\267\262\221\375\254\251\037\362\207\344\027\306\111\250\174\330
|
||||
\012\101\364\362\076\347\167\064\004\122\335\350\201\362\115\057
|
||||
\124\105\235\025\341\117\314\345\336\064\127\020\311\043\162\027
|
||||
\160\215\120\160\037\126\154\314\271\377\072\132\117\143\172\303
|
||||
\156\145\007\035\204\241\377\251\014\143\211\155\262\100\210\071
|
||||
\327\037\167\150\265\374\234\325\326\147\151\133\250\164\333\374
|
||||
\211\366\033\062\367\244\044\246\166\267\107\123\357\215\111\217
|
||||
\251\266\203\132\245\226\220\105\141\365\336\003\117\046\017\250
|
||||
\213\360\003\226\260\254\025\320\161\132\152\173\224\346\160\223
|
||||
\332\361\151\340\262\142\115\236\217\377\211\235\233\135\315\105
|
||||
\351\224\002\042\215\340\065\177\350\361\004\171\161\154\124\203
|
||||
\370\063\271\005\062\033\130\125\021\117\320\345\047\107\161\354
|
||||
\355\332\147\326\142\246\113\115\017\151\242\311\274\354\042\113
|
||||
\224\307\150\224\027\176\342\216\050\076\266\306\352\365\064\154
|
||||
\237\067\210\007\070\333\206\161\372\315\225\110\103\156\243\117
|
||||
\202\207\327\064\230\156\113\223\171\140\165\151\017\360\032\325
|
||||
\123\372\041\014\302\077\351\077\037\030\214\222\135\170\247\166
|
||||
\147\031\273\262\352\177\351\160\011\126\126\243\260\014\013\055
|
||||
\066\136\305\351\304\325\203\313\206\027\227\054\154\023\157\207
|
||||
\132\257\111\246\035\333\315\070\004\056\137\342\112\065\016\055
|
||||
\113\370\242\044\004\215\330\341\143\136\002\222\064\332\230\141
|
||||
\134\034\157\130\166\144\263\374\002\270\365\235\012
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "D-TRUST EV Root CA 2 2023"
|
||||
# Issuer: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:69:26:09:7e:80:4b:4c:a0:a7:8c:78:62:53:5f:5a:6f
|
||||
# Subject: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 09:10:33 2023
|
||||
# Not Valid After : Sun May 09 09:10:32 2038
|
||||
# Fingerprint (SHA-256): 8E:82:21:B2:E7:D4:00:78:36:A1:67:2F:0D:CC:29:9C:33:BC:07:D3:16:F1:32:FA:1A:20:6D:58:71:50:F1:CE
|
||||
# Fingerprint (SHA1): A5:5B:D8:47:6C:8F:19:F7:4C:F4:6D:6B:B6:C2:79:82:22:DF:54:8B
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST EV Root CA 2 2023"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\245\133\330\107\154\217\031\367\114\364\155\153\266\302\171\202
|
||||
\042\337\124\213
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\226\264\170\011\360\011\313\167\353\273\033\115\157\066\274\266
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\105\126\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\151\046\011\176\200\113\114\240\247\214\170\142\123\137
|
||||
\132\157
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -72,7 +72,7 @@ void us_socket_context_close(int ssl, struct us_socket_context_t *context) {
|
||||
while (ls) {
|
||||
struct us_listen_socket_t *nextLS = (struct us_listen_socket_t *) ls->s.next;
|
||||
us_listen_socket_close(ssl, ls);
|
||||
|
||||
|
||||
ls = nextLS;
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ struct us_bun_verify_error_t us_socket_verify_error(int ssl, struct us_socket_t
|
||||
}
|
||||
#endif
|
||||
|
||||
return (struct us_bun_verify_error_t) { .error = 0, .code = NULL, .reason = NULL };
|
||||
return (struct us_bun_verify_error_t) { .error = 0, .code = NULL, .reason = NULL };
|
||||
}
|
||||
|
||||
void us_internal_socket_context_free(int ssl, struct us_socket_context_t *context) {
|
||||
@@ -337,7 +337,7 @@ void us_socket_context_ref(int ssl, struct us_socket_context_t *context) {
|
||||
}
|
||||
void us_socket_context_unref(int ssl, struct us_socket_context_t *context) {
|
||||
uint32_t ref_count = context->ref_count;
|
||||
context->ref_count--;
|
||||
context->ref_count--;
|
||||
if (ref_count == 1) {
|
||||
us_internal_socket_context_free(ssl, context);
|
||||
}
|
||||
@@ -520,7 +520,7 @@ void *us_socket_context_connect(int ssl, struct us_socket_context_t *context, co
|
||||
}
|
||||
|
||||
struct us_connecting_socket_t *c = us_calloc(1, sizeof(struct us_connecting_socket_t) + socket_ext_size);
|
||||
c->socket_ext_size = socket_ext_size;
|
||||
c->socket_ext_size = socket_ext_size;
|
||||
c->options = options;
|
||||
c->ssl = ssl > 0;
|
||||
c->timeout = 255;
|
||||
@@ -641,9 +641,9 @@ void us_internal_socket_after_open(struct us_socket_t *s, int error) {
|
||||
|
||||
/* Emit error, close without emitting on_close */
|
||||
|
||||
/* There are two possible states here:
|
||||
1. It's a us_connecting_socket_t*. DNS resolution failed, or a connection failed.
|
||||
2. It's a us_socket_t*
|
||||
/* There are two possible states here:
|
||||
1. It's a us_connecting_socket_t*. DNS resolution failed, or a connection failed.
|
||||
2. It's a us_socket_t*
|
||||
|
||||
We differentiate between these two cases by checking if the connect_state is null.
|
||||
*/
|
||||
@@ -887,7 +887,7 @@ void us_socket_context_on_connect_error(int ssl, struct us_socket_context_t *con
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
context->on_connect_error = on_connect_error;
|
||||
}
|
||||
|
||||
@@ -898,7 +898,7 @@ void us_socket_context_on_socket_connect_error(int ssl, struct us_socket_context
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
context->on_socket_connect_error = on_connect_error;
|
||||
}
|
||||
|
||||
|
||||
@@ -381,38 +381,6 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"W8mw0FfB+j564ZfJ\n"
|
||||
"-----END CERTIFICATE-----",.len=2041},
|
||||
|
||||
/* SwissSign Silver CA - G2 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gx\n"
|
||||
"FTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAt\n"
|
||||
"IEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTAT\n"
|
||||
"BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcy\n"
|
||||
"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dO\n"
|
||||
"cbpLj6VzHVxumK4DV644N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGi\n"
|
||||
"TSf5YXu6t+WiE7brYT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi\n"
|
||||
"0R86TieFnbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH\n"
|
||||
"6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyC\n"
|
||||
"bTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jM\n"
|
||||
"qDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/\n"
|
||||
"+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBsROopN4WSaGa8gzj+ezku01DwH/te\n"
|
||||
"YLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIj\n"
|
||||
"QAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calI\n"
|
||||
"Lv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n"
|
||||
"HQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c\n"
|
||||
"wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0cDovL3Jl\n"
|
||||
"cG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P4JUw\n"
|
||||
"4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F\n"
|
||||
"kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcS\n"
|
||||
"H9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkD\n"
|
||||
"lm4fS/Bx/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakM\n"
|
||||
"DHiqYMZWjwFaDGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHk\n"
|
||||
"Flt4dR2Xem1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR\n"
|
||||
"dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29\n"
|
||||
"MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI\n"
|
||||
"4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s\n"
|
||||
"5Aq7KkzrCWA5zspi2C5u\n"
|
||||
"-----END CERTIFICATE-----",.len=2045},
|
||||
|
||||
/* SecureTrust CA */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYD\n"
|
||||
@@ -3625,4 +3593,66 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr\n"
|
||||
"62Nuk22rGwlgMU4=\n"
|
||||
"-----END CERTIFICATE-----",.len=800},
|
||||
|
||||
/* D-TRUST BR Root CA 2 2023 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBIMQswCQYD\n"
|
||||
"VQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJv\n"
|
||||
"b3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUwOTA4NTYzMFowSDELMAkGA1UE\n"
|
||||
"BhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290\n"
|
||||
"IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYk\n"
|
||||
"P7in5Mg6CjoWzckjYaCTcfKri3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrd\n"
|
||||
"TIzZXcFhfUvnKLNEgXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8\n"
|
||||
"T1soegj8k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT\n"
|
||||
"Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl2ecjbwb9\n"
|
||||
"Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+UcSTq3nD88ZP+npNa\n"
|
||||
"5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP/Wxc6PWOJ4d/GUohR5AdeY0c\n"
|
||||
"W/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bSuREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbM\n"
|
||||
"l6zWK11kJNXuHA7e+whadSr2Y23OC0K+0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAml\n"
|
||||
"Y0cL4UEyNEHZmrHZqLAbWt4NDfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2k\n"
|
||||
"WVki3PaKRT08EtY+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\n"
|
||||
"Z5Dw1t61GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG\n"
|
||||
"OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8yXzIwMjMu\n"
|
||||
"Y3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tIFoE9c+CeJyrrd6kT\n"
|
||||
"pGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67nriv6uvw8l5VAk1/DLQOj7aRv\n"
|
||||
"U9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTRVFxDWy6u71cqqLRvpO8NVhTaIasgdp4D\n"
|
||||
"/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrcLmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8J\n"
|
||||
"kiZmkdijYQ6qgYF/6FKC0ULn4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4n\n"
|
||||
"wSPFyysCu7Ff/vtDhQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnk\n"
|
||||
"bWOACKsGkoHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46\n"
|
||||
"ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aSEcr1wPrY\n"
|
||||
"g1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80knCDgKs4qllo3UCk\n"
|
||||
"GJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJhJ65bvspmZDogNOfJA==\n"
|
||||
"-----END CERTIFICATE-----",.len=2020},
|
||||
|
||||
/* D-TRUST EV Root CA 2 2023 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBIMQswCQYD\n"
|
||||
"VQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJv\n"
|
||||
"b3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUwOTA5MTAzMlowSDELMAkGA1UE\n"
|
||||
"BhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290\n"
|
||||
"IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtyp\n"
|
||||
"U0w3uX9jFxPvp1sjW2l1sJkKF8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/k\n"
|
||||
"PbOx1sWy/YgJ25yE7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR\n"
|
||||
"8CUkNRFeEMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6\n"
|
||||
"lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIbRlUWaqZL\n"
|
||||
"Kfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiVjTujIcSuWMYAsoS0\n"
|
||||
"I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgcjmgjutDzUNzPZY9zOjLHfP7K\n"
|
||||
"giJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZxTnXonMkmdMV9WdEKWw9t/p51HBjGGjp8\n"
|
||||
"2A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0Juyf\n"
|
||||
"Br/CBTdkdXgpaP3F9ev+R/nkhbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8\n"
|
||||
"/M3OsD6Onov4/knFNXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\n"
|
||||
"qvyREBuHkV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG\n"
|
||||
"OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8yXzIwMjMu\n"
|
||||
"Y3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14QvBukEdHjqOSMo1w\n"
|
||||
"j/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4pZt+UPJ26oUFKidBK7GB0aL2\n"
|
||||
"QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q3C+jisosketSjl8MmxfPy3MHGcRqwnNU\n"
|
||||
"73xDUmPBEcrCRbH0O1P1aa4846XerOhUt7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHy\n"
|
||||
"TS9URZ0V4U/M5d40VxDJI3IXcI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3do\n"
|
||||
"tfyc1dZnaVuodNv8ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFa\n"
|
||||
"anuU5nCT2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs\n"
|
||||
"7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNPgofXNJhu\n"
|
||||
"S5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAstNl7F6cTVg8uGF5cs\n"
|
||||
"bBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phhXBxvWHZks/wCuPWdCg==\n"
|
||||
"-----END CERTIFICATE-----",.len=2020},
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user