mirror of
https://github.com/oven-sh/bun
synced 2026-02-03 23:48:52 +00:00
Compare commits
305 Commits
riskymh/sq
...
kai/http
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
171e4ff096 | ||
|
|
80ad7f8e27 | ||
|
|
a19a43b1a7 | ||
|
|
3a504af1e8 | ||
|
|
6566262efa | ||
|
|
1570d4f0a7 | ||
|
|
b6b6efc839 | ||
|
|
d502df353c | ||
|
|
7161326baa | ||
|
|
903d6d058c | ||
|
|
96b305389f | ||
|
|
2a74f0d8f4 | ||
|
|
6e99733320 | ||
|
|
8c79d7c5ae | ||
|
|
acd22a2e52 | ||
|
|
94ab3007a4 | ||
|
|
4645c309ca | ||
|
|
852830eb54 | ||
|
|
4840217156 | ||
|
|
35f64d393a | ||
|
|
78fb3ce64d | ||
|
|
368ddfdd14 | ||
|
|
f9ebabe898 | ||
|
|
60eb2c4ecb | ||
|
|
fd2904a118 | ||
|
|
174ecc8768 | ||
|
|
dd94ebc13a | ||
|
|
5cd9663daa | ||
|
|
379f2a2a2b | ||
|
|
6972a8e3a3 | ||
|
|
8a177f6c85 | ||
|
|
5053d0eaaf | ||
|
|
6ec2b98336 | ||
|
|
bae0921ef7 | ||
|
|
7eab65df99 | ||
|
|
37e2a57913 | ||
|
|
a41d773aaa | ||
|
|
4955b5181d | ||
|
|
ef69f62367 | ||
|
|
4ef7a43939 | ||
|
|
7dc2e8e98e | ||
|
|
63636f19f1 | ||
|
|
23314188ca | ||
|
|
d429e35cdf | ||
|
|
99d85be529 | ||
|
|
2d0cadc949 | ||
|
|
821f42dd8e | ||
|
|
0d4bd61ae0 | ||
|
|
483302d09d | ||
|
|
5aa2913bce | ||
|
|
1803f73b15 | ||
|
|
9141337c7d | ||
|
|
70dbf582a6 | ||
|
|
1a6a34700f | ||
|
|
6e140b4b13 | ||
|
|
e3c6648cd2 | ||
|
|
79858a6223 | ||
|
|
616e4cd50f | ||
|
|
ac07af11de | ||
|
|
078318f33c | ||
|
|
a620db7025 | ||
|
|
99cbdfb004 | ||
|
|
887173c3c3 | ||
|
|
184506ae86 | ||
|
|
25c95f3bdc | ||
|
|
1bf13aa671 | ||
|
|
671d876cf3 | ||
|
|
50856459e6 | ||
|
|
8db2844e80 | ||
|
|
2d74c0162a | ||
|
|
7882418c5f | ||
|
|
01fb872095 | ||
|
|
12a2f412fc | ||
|
|
ee6bdc1588 | ||
|
|
11979f69eb | ||
|
|
65b8b220d2 | ||
|
|
c9e4153826 | ||
|
|
b2eeb3f36c | ||
|
|
febf6593a6 | ||
|
|
cd8a1fb17c | ||
|
|
e7790894d9 | ||
|
|
e38a110dbc | ||
|
|
da35204c3c | ||
|
|
cef38030df | ||
|
|
2fb121e2ed | ||
|
|
7ad46cb118 | ||
|
|
4f58ff7933 | ||
|
|
838c3bbb8b | ||
|
|
fe49ac1a3d | ||
|
|
fbe4d57bae | ||
|
|
f4937678e4 | ||
|
|
b124ba056c | ||
|
|
0237baee92 | ||
|
|
cc481465b5 | ||
|
|
7a033e49c5 | ||
|
|
59551ebc79 | ||
|
|
ad766f2402 | ||
|
|
efabdcbe1f | ||
|
|
174a0f70df | ||
|
|
deeebf0538 | ||
|
|
63bc08e3ca | ||
|
|
d767c15d0a | ||
|
|
d09daca867 | ||
|
|
b3edef5989 | ||
|
|
06d7628965 | ||
|
|
baca1f4634 | ||
|
|
8bb6dd3cee | ||
|
|
215da32660 | ||
|
|
5c6e20aeb4 | ||
|
|
1060558456 | ||
|
|
8a47057dd5 | ||
|
|
17540d3dac | ||
|
|
a4a19bb4f3 | ||
|
|
a2d028462b | ||
|
|
ec4b9d198b | ||
|
|
fd9a5ea668 | ||
|
|
e8249d885c | ||
|
|
ac8fb0e1f5 | ||
|
|
39fdabc364 | ||
|
|
144a9c2f6d | ||
|
|
caff4e6008 | ||
|
|
1322adbb16 | ||
|
|
11e5a6a2c7 | ||
|
|
a130816004 | ||
|
|
f4e0684603 | ||
|
|
a82007a54d | ||
|
|
2db9ab4c72 | ||
|
|
2f48282cbd | ||
|
|
1574df835e | ||
|
|
04973a1520 | ||
|
|
4e3c9bc1d1 | ||
|
|
d4c1114f9d | ||
|
|
b829590356 | ||
|
|
04f985523b | ||
|
|
32e6049be0 | ||
|
|
94274b7198 | ||
|
|
46246bb526 | ||
|
|
09ab840114 | ||
|
|
211824bb3e | ||
|
|
b7e5a38975 | ||
|
|
cbeffe1b48 | ||
|
|
a8c8fa15b9 | ||
|
|
032f99285c | ||
|
|
db5b915559 | ||
|
|
445fe2ac4a | ||
|
|
82c26f0a58 | ||
|
|
943dc53a3b | ||
|
|
61edc58362 | ||
|
|
7a35567b45 | ||
|
|
47f9bb84e8 | ||
|
|
b02156e793 | ||
|
|
6aa62fe4bf | ||
|
|
2206c14314 | ||
|
|
5167ed20f9 | ||
|
|
0bb0bf7c08 | ||
|
|
4978fb8baf | ||
|
|
c2a9cf5bbd | ||
|
|
d474b54ad1 | ||
|
|
9503f7b0b9 | ||
|
|
01d932d7e4 | ||
|
|
5c8da4436c | ||
|
|
d862966631 | ||
|
|
f6c3b92f73 | ||
|
|
363bdf5c6c | ||
|
|
04703bd3cc | ||
|
|
8c4d3ff801 | ||
|
|
fb6f7e43d8 | ||
|
|
78f4b20600 | ||
|
|
bda1ad192d | ||
|
|
8f7143882e | ||
|
|
8f888be7d5 | ||
|
|
84ad89cc95 | ||
|
|
18440d4b11 | ||
|
|
14eea902a4 | ||
|
|
7f0b117496 | ||
|
|
94e5071947 | ||
|
|
8c32eb8354 | ||
|
|
3b956757d9 | ||
|
|
fbc4aa480b | ||
|
|
dc5fae461d | ||
|
|
a3ea521c98 | ||
|
|
27c90786ca | ||
|
|
226275c26d | ||
|
|
b082572dcb | ||
|
|
5092f47023 | ||
|
|
67b71fae98 | ||
|
|
275a34b014 | ||
|
|
aef6a173ee | ||
|
|
1b271fd45e | ||
|
|
6e45e3bf1e | ||
|
|
1e6fdc9f15 | ||
|
|
9b515d74aa | ||
|
|
7c6d9cac50 | ||
|
|
bab4b9fb51 | ||
|
|
e839daee80 | ||
|
|
19887570b2 | ||
|
|
57c74f2a73 | ||
|
|
a008da9428 | ||
|
|
967dacd25d | ||
|
|
f6afdabc23 | ||
|
|
e02ab8e250 | ||
|
|
2c73ef16cf | ||
|
|
db5f743ee3 | ||
|
|
0d77e6b2c2 | ||
|
|
b28c6ae51c | ||
|
|
ac7af3fa33 | ||
|
|
6e039accf5 | ||
|
|
0bf13af151 | ||
|
|
4783ee6e35 | ||
|
|
9cc44f04ef | ||
|
|
425b9a4796 | ||
|
|
9213840c78 | ||
|
|
74a2460532 | ||
|
|
d5aec7e32d | ||
|
|
6ab42b18f6 | ||
|
|
8508744b5d | ||
|
|
b2d664d688 | ||
|
|
b514421884 | ||
|
|
1a599485f1 | ||
|
|
bd045cf652 | ||
|
|
e8c8a4b351 | ||
|
|
e766dcd3f3 | ||
|
|
60b24f79f4 | ||
|
|
249b8dbda5 | ||
|
|
ffa564fd61 | ||
|
|
b42f4594f6 | ||
|
|
d36ed1c306 | ||
|
|
b4ee149905 | ||
|
|
4443e80587 | ||
|
|
c1fec71110 | ||
|
|
4bb91a1ff7 | ||
|
|
5b7b03e699 | ||
|
|
14a6da6f41 | ||
|
|
4751f6cda4 | ||
|
|
5a1c82f898 | ||
|
|
29111d4c11 | ||
|
|
01f2e4c39f | ||
|
|
38c32d1e67 | ||
|
|
764ec60d42 | ||
|
|
5546c4b7ed | ||
|
|
9a8e8dfd4d | ||
|
|
352422c6ce | ||
|
|
a5bfd3510c | ||
|
|
67f7ff2eb6 | ||
|
|
a7516d93bc | ||
|
|
a113fbaf2a | ||
|
|
30653c9d7d | ||
|
|
00d64e5fc9 | ||
|
|
ca36296072 | ||
|
|
715ddd8dff | ||
|
|
a005a602af | ||
|
|
7d5a86c6a8 | ||
|
|
0f0ae42700 | ||
|
|
f4512628e8 | ||
|
|
5dae7425bc | ||
|
|
6f15bc2796 | ||
|
|
236b18bc1e | ||
|
|
8e22382215 | ||
|
|
55ac3affdc | ||
|
|
b80948bdd9 | ||
|
|
f832809d81 | ||
|
|
89973c4a78 | ||
|
|
f5ef0219c5 | ||
|
|
9f32a601ec | ||
|
|
51c7e5b497 | ||
|
|
dc9178b5fc | ||
|
|
9aac020de4 | ||
|
|
ae91704ba0 | ||
|
|
2fed66a038 | ||
|
|
7290e6dae8 | ||
|
|
2cec01fa0f | ||
|
|
b4a1aed131 | ||
|
|
d5ecd8b5e8 | ||
|
|
083a79cd8e | ||
|
|
dd0d8ac272 | ||
|
|
70ce87503a | ||
|
|
029e5bdb7c | ||
|
|
6a744fced6 | ||
|
|
efd0862b61 | ||
|
|
81c007ccbe | ||
|
|
f4b4c4115a | ||
|
|
3446bce092 | ||
|
|
240e795224 | ||
|
|
ca1567e6f3 | ||
|
|
c24ffec53f | ||
|
|
da35833267 | ||
|
|
dae59b687a | ||
|
|
7afbae8e7c | ||
|
|
b7e06a979a | ||
|
|
9593dcde98 | ||
|
|
00e017c274 | ||
|
|
8212e3afc6 | ||
|
|
da3e7160a1 | ||
|
|
2de2cb607b | ||
|
|
3852109ea0 | ||
|
|
8ca6dba524 | ||
|
|
d9a1dc78f9 | ||
|
|
1f93522b88 | ||
|
|
4a53dee5c1 | ||
|
|
44f1870b17 | ||
|
|
7b295c0d18 | ||
|
|
432e92fd27 | ||
|
|
68ad269ef0 | ||
|
|
deb44aa80b | ||
|
|
a660692743 |
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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
|
||||
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@@ -70,7 +70,7 @@ jobs:
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: "1.2.0"
|
||||
bun-version: "1.2.3"
|
||||
- name: Install Dependencies
|
||||
run: bun install
|
||||
- name: Sign Release
|
||||
@@ -98,7 +98,7 @@ jobs:
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: "1.2.0"
|
||||
bun-version: "1.2.3"
|
||||
- name: Install Dependencies
|
||||
run: bun install
|
||||
- name: Release
|
||||
@@ -127,7 +127,7 @@ jobs:
|
||||
if: ${{ env.BUN_VERSION != 'canary' }}
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: "1.2.0"
|
||||
bun-version: "1.2.3"
|
||||
- name: Setup Bun
|
||||
if: ${{ env.BUN_VERSION == 'canary' }}
|
||||
uses: ./.github/actions/setup-bun
|
||||
@@ -167,12 +167,16 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
- name: Checkout (DefinitelyTyped)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: DefinitelyTyped/DefinitelyTyped
|
||||
- name: Checkout (bun)
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: bun
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
uses: ./bun/.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: "1.2.0"
|
||||
- id: bun-version
|
||||
@@ -227,7 +231,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Docker emulator
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- id: buildx
|
||||
name: Setup Docker buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
@@ -235,7 +239,7 @@ jobs:
|
||||
platforms: linux/amd64,linux/arm64
|
||||
- id: metadata
|
||||
name: Setup Docker metadata
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: oven/bun
|
||||
flavor: |
|
||||
@@ -252,7 +256,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Push to Docker
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./dockerhub/${{ matrix.dir || matrix.variant }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
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
.gitignore
vendored
2
.gitignore
vendored
@@ -181,3 +181,5 @@ tmp
|
||||
.buildkite/ci.yml
|
||||
*.sock
|
||||
scratch*.{js,ts,tsx,cjs,mjs}
|
||||
|
||||
*.bun-build
|
||||
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,
|
||||
|
||||
@@ -67,7 +67,7 @@ $ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 18 all
|
||||
```
|
||||
|
||||
```bash#Arch
|
||||
$ sudo pacman -S llvm clang lld
|
||||
$ sudo pacman -S llvm clang18 lld
|
||||
```
|
||||
|
||||
```bash#Fedora
|
||||
|
||||
4
Makefile
4
Makefile
@@ -1154,7 +1154,7 @@ jsc-copy-headers:
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StubInfoSummary.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StubInfoSummary.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/CommonSlowPaths.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/CommonSlowPaths.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/DirectArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/DirectArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/GenericArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/GenericArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/GenericArgumentsImpl.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/GenericArgumentsImpl.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/SamplingProfiler.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/SamplingProfiler.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/ScopedArguments.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ScopedArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h $(WEBKIT_RELEASE_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSLexicalEnvironment.h
|
||||
@@ -1205,7 +1205,7 @@ jsc-copy-headers-debug:
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/bytecode/StubInfoSummary.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/StubInfoSummary.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/CommonSlowPaths.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/CommonSlowPaths.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/DirectArguments.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/DirectArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/GenericArguments.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/GenericArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/GenericArgumentsImpl.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/GenericArgumentsImpl.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/SamplingProfiler.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/SamplingProfiler.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/ScopedArguments.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/ScopedArguments.h
|
||||
cp $(WEBKIT_DIR)/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h $(WEBKIT_DEBUG_DIR)/JavaScriptCore/PrivateHeaders/JavaScriptCore/JSLexicalEnvironment.h
|
||||
|
||||
@@ -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();
|
||||
@@ -25,9 +25,10 @@ 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," ++
|
||||
"Bun requires Zig version " ++ recommended_zig_version ++ " (found " ++
|
||||
builtin.zig_version_string ++ "). This is " ++
|
||||
"automatically configured via Bun's CMake setup. You likely meant to run " ++
|
||||
"`bun setup`. If you are trying to upgrade the Zig compiler, " ++
|
||||
"run `./scripts/download-zig.sh master` or comment this message out.",
|
||||
);
|
||||
}
|
||||
|
||||
66
bun.lock
66
bun.lock
@@ -45,21 +45,21 @@
|
||||
"packages": {
|
||||
"@biomejs/biome": ["@biomejs/biome@1.8.3", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.8.3", "@biomejs/cli-darwin-x64": "1.8.3", "@biomejs/cli-linux-arm64": "1.8.3", "@biomejs/cli-linux-arm64-musl": "1.8.3", "@biomejs/cli-linux-x64": "1.8.3", "@biomejs/cli-linux-x64-musl": "1.8.3", "@biomejs/cli-win32-arm64": "1.8.3", "@biomejs/cli-win32-x64": "1.8.3" }, "bin": { "biome": "bin/biome" } }, "sha512-/uUV3MV+vyAczO+vKrPdOW0Iaet7UnJMU4bNMinggGJTAnBPjCoLEYcyYtYHNnUNYlv4xZMH6hVIQCAozq8d5w=="],
|
||||
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.8.3", "", { "os":"darwin", "cpu":"arm64" }, "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A=="],
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.8.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-9DYOjclFpKrH/m1Oz75SSExR8VKvNSSsLnVIqdnKexj6NwmiMlKk94Wa1kZEdv6MCOHGHgyyoV57Cw8WzL5n3A=="],
|
||||
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.8.3", "", { "os":"darwin", "cpu":"x64" }, "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw=="],
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.8.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-UeW44L/AtbmOF7KXLCoM+9PSgPo0IDcyEUfIoOXYeANaNXXf9mLUwV1GeF2OWjyic5zj6CnAJ9uzk2LT3v/wAw=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.8.3", "", { "os":"linux", "cpu":"arm64" }, "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw=="],
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.8.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-fed2ji8s+I/m8upWpTJGanqiJ0rnlHOK3DdxsyVLZQ8ClY6qLuPc9uehCREBifRJLl/iJyQpHIRufLDeotsPtw=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.8.3", "", { "os":"linux", "cpu":"arm64" }, "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ=="],
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.8.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-9yjUfOFN7wrYsXt/T/gEWfvVxKlnh3yBpnScw98IF+oOeCYb5/b/+K7YNqKROV2i1DlMjg9g/EcN9wvj+NkMuQ=="],
|
||||
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.8.3", "", { "os":"linux", "cpu":"x64" }, "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw=="],
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.8.3", "", { "os": "linux", "cpu": "x64" }, "sha512-I8G2QmuE1teISyT8ie1HXsjFRz9L1m5n83U1O6m30Kw+kPMPSKjag6QGUn+sXT8V+XWIZxFFBoTDEDZW2KPDDw=="],
|
||||
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.8.3", "", { "os":"linux", "cpu":"x64" }, "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA=="],
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.8.3", "", { "os": "linux", "cpu": "x64" }, "sha512-UHrGJX7PrKMKzPGoEsooKC9jXJMa28TUSMjcIlbDnIO4EAavCoVmNQaIuUSH0Ls2mpGMwUIf+aZJv657zfWWjA=="],
|
||||
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.8.3", "", { "os":"win32", "cpu":"arm64" }, "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ=="],
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.8.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-J+Hu9WvrBevfy06eU1Na0lpc7uR9tibm9maHynLIoAjLZpQU3IW+OKHUtyL8p6/3pT2Ju5t5emReeIS2SAxhkQ=="],
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.8.3", "", { "os":"win32", "cpu":"x64" }, "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg=="],
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.8.3", "", { "os": "win32", "cpu": "x64" }, "sha512-/PJ59vA1pnQeKahemaQf4Nyj7IKUvGQSc3Ze1uIGi+Wvr1xF7rGobSrAAG01T/gUDG21vkDsZYM03NAmPiVkqg=="],
|
||||
|
||||
"@definitelytyped/dts-critic": ["@definitelytyped/dts-critic@0.0.191", "", { "dependencies": { "@definitelytyped/header-parser": "0.0.190", "command-exists": "^1.2.9", "semver": "^7.5.4", "tmp": "^0.2.1", "typescript": "^5.2.2", "yargs": "^17.7.2" } }, "sha512-j5HK3pQYiQwSXRLJzyhXJ6KxdzLl4gXXhz3ysCtLnRQkj+zsEfloDkEZ3x2bZMWS0OsKLXmR91JeQ2/c9DFEjg=="],
|
||||
|
||||
@@ -75,51 +75,51 @@
|
||||
|
||||
"@es-joy/jsdoccomment": ["@es-joy/jsdoccomment@0.39.4", "", { "dependencies": { "comment-parser": "1.3.1", "esquery": "^1.5.0", "jsdoc-type-pratt-parser": "~4.0.0" } }, "sha512-Jvw915fjqQct445+yron7Dufix9A+m9j1fCJYlCo1FWlRvTxa3pjJelxdSTdaLWcTwRU6vbL+NYjO4YuNIS5Qg=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os":"aix", "cpu":"ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os":"android", "cpu":"arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="],
|
||||
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os":"android", "cpu":"arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="],
|
||||
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os":"android", "cpu":"x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="],
|
||||
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os":"darwin", "cpu":"arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="],
|
||||
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os":"darwin", "cpu":"x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="],
|
||||
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os":"freebsd", "cpu":"arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="],
|
||||
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os":"freebsd", "cpu":"x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="],
|
||||
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os":"linux", "cpu":"arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="],
|
||||
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os":"linux", "cpu":"arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="],
|
||||
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os":"linux", "cpu":"ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="],
|
||||
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os":"linux", "cpu":"none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="],
|
||||
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os":"linux", "cpu":"none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="],
|
||||
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os":"linux", "cpu":"ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="],
|
||||
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os":"linux", "cpu":"none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="],
|
||||
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os":"linux", "cpu":"s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="],
|
||||
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os":"linux", "cpu":"x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="],
|
||||
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os":"none", "cpu":"x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="],
|
||||
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os":"openbsd", "cpu":"x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="],
|
||||
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os":"sunos", "cpu":"x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="],
|
||||
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os":"win32", "cpu":"arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="],
|
||||
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os":"win32", "cpu":"ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="],
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os":"win32", "cpu":"x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.4.0", "", { "dependencies": { "eslint-visitor-keys": "^3.3.0" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA=="],
|
||||
|
||||
@@ -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=="],
|
||||
|
||||
|
||||
84
ci/README.md
84
ci/README.md
@@ -1,84 +0,0 @@
|
||||
# CI
|
||||
|
||||
This directory contains scripts for building CI images for Bun.
|
||||
|
||||
## Building
|
||||
|
||||
### `macOS`
|
||||
|
||||
On macOS, images are built using [`tart`](https://tart.run/), a tool that abstracts over the [`Virtualization.Framework`](https://developer.apple.com/documentation/virtualization) APIs, to run macOS VMs.
|
||||
|
||||
To install the dependencies required, run:
|
||||
|
||||
```sh
|
||||
$ cd ci
|
||||
$ bun run bootstrap
|
||||
```
|
||||
|
||||
To build a vanilla macOS VM, run:
|
||||
|
||||
```sh
|
||||
$ bun run build:darwin-aarch64-vanilla
|
||||
```
|
||||
|
||||
This builds a vanilla macOS VM with the current macOS release on your machine. It runs scripts to disable things like spotlight and siri, but it does not install any software.
|
||||
|
||||
> Note: The image size is 50GB, so make sure you have enough disk space.
|
||||
|
||||
If you want to build a specific macOS release, you can run:
|
||||
|
||||
```sh
|
||||
$ bun run build:darwin-aarch64-vanilla-15
|
||||
```
|
||||
|
||||
> Note: You cannot build a newer release of macOS on an older macOS machine.
|
||||
|
||||
To build a macOS VM with software installed to build and test Bun, run:
|
||||
|
||||
```sh
|
||||
$ bun run build:darwin-aarch64
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
### `macOS`
|
||||
|
||||
## How To
|
||||
|
||||
### Support a new macOS release
|
||||
|
||||
1. Visit [`ipsw.me`](https://ipsw.me/VirtualMac2,1) and find the IPSW of the macOS release you want to build.
|
||||
|
||||
2. Add an entry to [`ci/darwin/variables.pkr.hcl`](/ci/darwin/variables.pkr.hcl) with the following format:
|
||||
|
||||
```hcl
|
||||
sonoma = {
|
||||
distro = "sonoma"
|
||||
release = "15"
|
||||
ipsw = "https://updates.cdn-apple.com/..."
|
||||
}
|
||||
```
|
||||
|
||||
3. Add matching scripts to [`ci/package.json`](/ci/package.json) to build the image, then test it:
|
||||
|
||||
```sh
|
||||
$ bun run build:darwin-aarch64-vanilla-15
|
||||
```
|
||||
|
||||
> Note: If you need to troubleshoot the build, you can remove the `headless = true` property from [`ci/darwin/image-vanilla.pkr.hcl`](/ci/darwin/image-vanilla.pkr.hcl) and the VM's screen will be displayed.
|
||||
|
||||
4. Test and build the non-vanilla image:
|
||||
|
||||
```sh
|
||||
$ bun run build:darwin-aarch64-15
|
||||
```
|
||||
|
||||
This will use the vanilla image and run the [`scripts/bootstrap.sh`](/scripts/bootstrap.sh) script to install the required software to build and test Bun.
|
||||
|
||||
5. Publish the images:
|
||||
|
||||
```sh
|
||||
$ bun run login
|
||||
$ bun run publish:darwin-aarch64-vanilla-15
|
||||
$ bun run publish:darwin-aarch64-15
|
||||
```
|
||||
@@ -1,22 +0,0 @@
|
||||
FROM alpine:edge AS build
|
||||
ARG GIT_SHA
|
||||
ENV GIT_SHA=${GIT_SHA}
|
||||
WORKDIR /app/bun
|
||||
ENV HOME=/root
|
||||
|
||||
COPY . .
|
||||
RUN touch $HOME/.bashrc
|
||||
RUN ./scripts/bootstrap.sh
|
||||
RUN . $HOME/.bashrc && bun run build:release
|
||||
|
||||
RUN apk add file
|
||||
RUN file ./build/release/bun
|
||||
RUN ldd ./build/release/bun
|
||||
RUN ./build/release/bun
|
||||
|
||||
RUN cp -R /app/bun/build/* /output
|
||||
|
||||
FROM scratch AS artifact
|
||||
COPY --from=build /output /
|
||||
|
||||
# docker build -f ./ci/alpine/build.Dockerfile --progress=plain --build-arg GIT_SHA="$(git rev-parse HEAD)" --target=artifact --output type=local,dest=./build-alpine .
|
||||
@@ -1,20 +0,0 @@
|
||||
FROM alpine:edge
|
||||
ENV HOME=/root
|
||||
WORKDIR /root
|
||||
COPY ./build-alpine/release/bun .
|
||||
COPY ./test ./test
|
||||
COPY ./scripts ./scripts
|
||||
COPY ./package.json ./package.json
|
||||
COPY ./packages ./packages
|
||||
|
||||
RUN apk update
|
||||
RUN apk add nodejs lsb-release-minimal git python3 npm make g++
|
||||
RUN apk add file
|
||||
|
||||
RUN file /root/bun
|
||||
RUN ldd /root/bun
|
||||
RUN /root/bun
|
||||
|
||||
RUN ./scripts/runner.node.mjs --exec-path /root/bun
|
||||
|
||||
# docker build -f ./ci/alpine/test.Dockerfile --progress=plain .
|
||||
@@ -1,46 +0,0 @@
|
||||
# Generates a vanilla macOS VM with optimized settings for virtualized environments.
|
||||
# See login.sh and optimize.sh for details.
|
||||
|
||||
data "external-raw" "boot-script" {
|
||||
program = ["sh", "-c", templatefile("scripts/boot-image.sh", var)]
|
||||
}
|
||||
|
||||
source "tart-cli" "bun-darwin-aarch64-vanilla" {
|
||||
vm_name = "bun-darwin-aarch64-vanilla-${local.release.distro}-${local.release.release}"
|
||||
from_ipsw = local.release.ipsw
|
||||
cpu_count = local.cpu_count
|
||||
memory_gb = local.memory_gb
|
||||
disk_size_gb = local.disk_size_gb
|
||||
ssh_username = local.username
|
||||
ssh_password = local.password
|
||||
ssh_timeout = "120s"
|
||||
create_grace_time = "30s"
|
||||
boot_command = split("\n", data.external-raw.boot-script.result)
|
||||
headless = true # Disable if you need to debug why the boot_command is not working
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.tart-cli.bun-darwin-aarch64-vanilla"]
|
||||
|
||||
provisioner "file" {
|
||||
content = file("scripts/setup-login.sh")
|
||||
destination = "/tmp/setup-login.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
inline = ["echo \"${local.password}\" | sudo -S sh -c 'sh /tmp/setup-login.sh \"${local.username}\" \"${local.password}\"'"]
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
content = file("scripts/optimize-machine.sh")
|
||||
destination = "/tmp/optimize-machine.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
inline = ["sudo sh /tmp/optimize-machine.sh"]
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
inline = ["sudo rm -rf /tmp/*"]
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
# Generates a macOS VM with software installed to build and test Bun.
|
||||
|
||||
source "tart-cli" "bun-darwin-aarch64" {
|
||||
vm_name = "bun-darwin-aarch64-${local.release.distro}-${local.release.release}"
|
||||
vm_base_name = "bun-darwin-aarch64-vanilla-${local.release.distro}-${local.release.release}"
|
||||
cpu_count = local.cpu_count
|
||||
memory_gb = local.memory_gb
|
||||
disk_size_gb = local.disk_size_gb
|
||||
ssh_username = local.username
|
||||
ssh_password = local.password
|
||||
ssh_timeout = "120s"
|
||||
headless = true
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.tart-cli.bun-darwin-aarch64"]
|
||||
|
||||
provisioner "file" {
|
||||
content = file("../../scripts/bootstrap.sh")
|
||||
destination = "/tmp/bootstrap.sh"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
inline = ["CI=true sh /tmp/bootstrap.sh"]
|
||||
}
|
||||
|
||||
provisioner "file" {
|
||||
source = "darwin/plists/"
|
||||
destination = "/tmp/"
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
inline = [
|
||||
"sudo ls /tmp/",
|
||||
"sudo mv /tmp/*.plist /Library/LaunchDaemons/",
|
||||
"sudo chown root:wheel /Library/LaunchDaemons/*.plist",
|
||||
"sudo chmod 644 /Library/LaunchDaemons/*.plist",
|
||||
]
|
||||
}
|
||||
|
||||
provisioner "shell" {
|
||||
inline = ["sudo rm -rf /tmp/*"]
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.buildkite.buildkite-agent</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/buildkite-agent</string>
|
||||
<string>start</string>
|
||||
</array>
|
||||
|
||||
<key>KeepAlive</key>
|
||||
<dict>
|
||||
<key>SuccessfulExit</key>
|
||||
<false />
|
||||
</dict>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true />
|
||||
|
||||
<key>StandardOutPath</key>
|
||||
<string>/var/buildkite-agent/logs/buildkite-agent.log</string>
|
||||
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/buildkite-agent/logs/buildkite-agent.log</string>
|
||||
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>BUILDKITE_AGENT_CONFIG</key>
|
||||
<string>/etc/buildkite-agent/buildkite-agent.cfg</string>
|
||||
</dict>
|
||||
|
||||
<key>LimitLoadToSessionType</key>
|
||||
<array>
|
||||
<string>Aqua</string>
|
||||
<string>LoginWindow</string>
|
||||
<string>Background</string>
|
||||
<string>StandardIO</string>
|
||||
<string>System</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.tailscale.tailscaled</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/tailscale</string>
|
||||
<string>up</string>
|
||||
<string>--ssh</string>
|
||||
<string>--authkey</string>
|
||||
<string>${TAILSCALE_AUTHKEY}</string>
|
||||
</array>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true />
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.tailscale.tailscaled</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/local/bin/tailscaled</string>
|
||||
</array>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true />
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,124 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script generates the boot commands for the macOS installer GUI.
|
||||
# It is run on your local machine, not inside the VM.
|
||||
|
||||
# Sources:
|
||||
# - https://github.com/cirruslabs/macos-image-templates/blob/master/templates/vanilla-sequoia.pkr.hcl
|
||||
|
||||
if ! [ "${release}" ] || ! [ "${username}" ] || ! [ "${password}" ]; then
|
||||
echo "Script must be run with variables: release, username, and password" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Hello, hola, bonjour, etc.
|
||||
echo "<wait120s><spacebar>"
|
||||
|
||||
# Select Your Country and Region
|
||||
echo "<wait30s>italiano<esc>english<enter>"
|
||||
echo "<wait30s>united states<leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Written and Spoken Languages
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Accessibility
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Data & Privacy
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Migration Assistant
|
||||
echo "<wait30s><tab><tab><tab><spacebar>"
|
||||
|
||||
# Sign In with Your Apple ID
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Are you sure you want to skip signing in with an Apple ID?
|
||||
echo "<wait30s><tab><spacebar>"
|
||||
|
||||
# Terms and Conditions
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# I have read and agree to the macOS Software License Agreement
|
||||
echo "<wait30s><tab><spacebar>"
|
||||
|
||||
# Create a Computer Account
|
||||
echo "<wait30s>${username}<tab><tab>${password}<tab>${password}<tab><tab><tab><spacebar>"
|
||||
|
||||
# Enable Location Services
|
||||
echo "<wait60s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Are you sure you don't want to use Location Services?
|
||||
echo "<wait30s><tab><spacebar>"
|
||||
|
||||
# Select Your Time Zone
|
||||
echo "<wait30s><tab>UTC<enter><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Analytics
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Screen Time
|
||||
echo "<wait30s><tab><spacebar>"
|
||||
|
||||
# Siri
|
||||
echo "<wait30s><tab><spacebar><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Choose Your Look
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
if [ "${release}" = "13" ] || [ "${release}" = "14" ]; then
|
||||
# Enable Voice Over
|
||||
echo "<wait30s><leftAltOn><f5><leftAltOff><wait5s>v"
|
||||
else
|
||||
# Welcome to Mac
|
||||
echo "<wait30s><spacebar>"
|
||||
|
||||
# Enable Keyboard navigation
|
||||
echo "<wait30s><leftAltOn><spacebar><leftAltOff>Terminal<enter>"
|
||||
echo "<wait30s>defaults write NSGlobalDomain AppleKeyboardUIMode -int 3<enter>"
|
||||
echo "<wait30s><leftAltOn>q<leftAltOff>"
|
||||
fi
|
||||
|
||||
# Now that the installation is done, open "System Settings"
|
||||
echo "<wait30s><leftAltOn><spacebar><leftAltOff>System Settings<enter>"
|
||||
|
||||
# Navigate to "Sharing"
|
||||
echo "<wait30s><leftAltOn>f<leftAltOff>sharing<enter>"
|
||||
|
||||
if [ "${release}" = "13" ]; then
|
||||
# Navigate to "Screen Sharing" and enable it
|
||||
echo "<wait30s><tab><down><spacebar>"
|
||||
|
||||
# Navigate to "Remote Login" and enable it
|
||||
echo "<wait30s><tab><tab><tab><tab><tab><tab><spacebar>"
|
||||
|
||||
# Open "Remote Login" details
|
||||
echo "<wait30s><tab><spacebar>"
|
||||
|
||||
# Enable "Full Disk Access"
|
||||
echo "<wait30s><tab><spacebar>"
|
||||
|
||||
# Click "Done"
|
||||
echo "<wait30s><leftShiftOn><tab><leftShiftOff><leftShiftOn><tab><leftShiftOff><spacebar>"
|
||||
|
||||
# Disable Voice Over
|
||||
echo "<leftAltOn><f5><leftAltOff>"
|
||||
elif [ "${release}" = "14" ]; then
|
||||
# Navigate to "Screen Sharing" and enable it
|
||||
echo "<wait30s><tab><tab><tab><tab><tab><spacebar>"
|
||||
|
||||
# Navigate to "Remote Login" and enable it
|
||||
echo "<wait30s><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><spacebar>"
|
||||
|
||||
# Disable Voice Over
|
||||
echo "<wait30s><leftAltOn><f5><leftAltOff>"
|
||||
elif [ "${release}" = "15" ]; then
|
||||
# Navigate to "Screen Sharing" and enable it
|
||||
echo "<wait30s><tab><tab><tab><tab><tab><spacebar>"
|
||||
|
||||
# Navigate to "Remote Login" and enable it
|
||||
echo "<wait30s><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><tab><spacebar>"
|
||||
fi
|
||||
|
||||
# Quit System Settings
|
||||
echo "<wait30s><leftAltOn>q<leftAltOff>"
|
||||
@@ -1,122 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script optimizes macOS for virtualized environments.
|
||||
# It disables things like spotlight, screen saver, and sleep.
|
||||
|
||||
# Sources:
|
||||
# - https://github.com/sickcodes/osx-optimizer
|
||||
# - https://github.com/koding88/MacBook-Optimization-Script
|
||||
# - https://www.macstadium.com/blog/simple-optimizations-for-macos-and-ios-build-agents
|
||||
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "This script must be run using sudo." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
execute() {
|
||||
echo "$ $@" >&2
|
||||
if ! "$@"; then
|
||||
echo "Command failed: $@" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
disable_software_update() {
|
||||
execute softwareupdate --schedule off
|
||||
execute defaults write com.apple.SoftwareUpdate AutomaticDownload -bool false
|
||||
execute defaults write com.apple.SoftwareUpdate AutomaticCheckEnabled -bool false
|
||||
execute defaults write com.apple.SoftwareUpdate ConfigDataInstall -int 0
|
||||
execute defaults write com.apple.SoftwareUpdate CriticalUpdateInstall -int 0
|
||||
execute defaults write com.apple.SoftwareUpdate ScheduleFrequency -int 0
|
||||
execute defaults write com.apple.SoftwareUpdate AutomaticDownload -int 0
|
||||
execute defaults write com.apple.commerce AutoUpdate -bool false
|
||||
execute defaults write com.apple.commerce AutoUpdateRestartRequired -bool false
|
||||
}
|
||||
|
||||
disable_spotlight() {
|
||||
execute mdutil -i off -a
|
||||
execute mdutil -E /
|
||||
}
|
||||
|
||||
disable_siri() {
|
||||
execute launchctl unload -w /System/Library/LaunchAgents/com.apple.Siri.agent.plist
|
||||
execute defaults write com.apple.Siri StatusMenuVisible -bool false
|
||||
execute defaults write com.apple.Siri UserHasDeclinedEnable -bool true
|
||||
execute defaults write com.apple.assistant.support "Assistant Enabled" 0
|
||||
}
|
||||
|
||||
disable_sleep() {
|
||||
execute systemsetup -setsleep Never
|
||||
execute systemsetup -setcomputersleep Never
|
||||
execute systemsetup -setdisplaysleep Never
|
||||
execute systemsetup -setharddisksleep Never
|
||||
}
|
||||
|
||||
disable_screen_saver() {
|
||||
execute defaults write com.apple.screensaver loginWindowIdleTime 0
|
||||
execute defaults write com.apple.screensaver idleTime 0
|
||||
}
|
||||
|
||||
disable_screen_lock() {
|
||||
execute defaults write com.apple.loginwindow DisableScreenLock -bool true
|
||||
}
|
||||
|
||||
disable_wallpaper() {
|
||||
execute defaults write com.apple.loginwindow DesktopPicture ""
|
||||
}
|
||||
|
||||
disable_application_state() {
|
||||
execute defaults write com.apple.loginwindow TALLogoutSavesState -bool false
|
||||
}
|
||||
|
||||
disable_accessibility() {
|
||||
execute defaults write com.apple.Accessibility DifferentiateWithoutColor -int 1
|
||||
execute defaults write com.apple.Accessibility ReduceMotionEnabled -int 1
|
||||
execute defaults write com.apple.universalaccess reduceMotion -int 1
|
||||
execute defaults write com.apple.universalaccess reduceTransparency -int 1
|
||||
}
|
||||
|
||||
disable_dashboard() {
|
||||
execute defaults write com.apple.dashboard mcx-disabled -boolean YES
|
||||
execute killall Dock
|
||||
}
|
||||
|
||||
disable_animations() {
|
||||
execute defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool false
|
||||
execute defaults write -g QLPanelAnimationDuration -float 0
|
||||
execute defaults write com.apple.finder DisableAllAnimations -bool true
|
||||
}
|
||||
|
||||
disable_time_machine() {
|
||||
execute tmutil disable
|
||||
}
|
||||
|
||||
enable_performance_mode() {
|
||||
# https://support.apple.com/en-us/101992
|
||||
if ! [ $(nvram boot-args 2>/dev/null | grep -q serverperfmode) ]; then
|
||||
execute nvram boot-args="serverperfmode=1 $(nvram boot-args 2>/dev/null | cut -f 2-)"
|
||||
fi
|
||||
}
|
||||
|
||||
add_terminal_to_desktop() {
|
||||
execute ln -sf /System/Applications/Utilities/Terminal.app ~/Desktop/Terminal
|
||||
}
|
||||
|
||||
main() {
|
||||
disable_software_update
|
||||
disable_spotlight
|
||||
disable_siri
|
||||
disable_sleep
|
||||
disable_screen_saver
|
||||
disable_screen_lock
|
||||
disable_wallpaper
|
||||
disable_application_state
|
||||
disable_accessibility
|
||||
disable_dashboard
|
||||
disable_animations
|
||||
disable_time_machine
|
||||
enable_performance_mode
|
||||
add_terminal_to_desktop
|
||||
}
|
||||
|
||||
main
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script generates a /etc/kcpassword file to enable auto-login on macOS.
|
||||
# Yes, this stores your password in plain text. Do NOT do this on your local machine.
|
||||
|
||||
# Sources:
|
||||
# - https://github.com/xfreebird/kcpassword/blob/master/kcpassword
|
||||
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
echo "This script must be run using sudo." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
execute() {
|
||||
echo "$ $@" >&2
|
||||
if ! "$@"; then
|
||||
echo "Command failed: $@" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
kcpassword() {
|
||||
passwd="$1"
|
||||
key="7d 89 52 23 d2 bc dd ea a3 b9 1f"
|
||||
passwd_hex=$(printf "%s" "$passwd" | xxd -p | tr -d '\n')
|
||||
|
||||
key_len=33
|
||||
passwd_len=${#passwd_hex}
|
||||
remainder=$((passwd_len % key_len))
|
||||
if [ $remainder -ne 0 ]; then
|
||||
padding=$((key_len - remainder))
|
||||
passwd_hex="${passwd_hex}$(printf '%0*x' $((padding / 2)) 0)"
|
||||
fi
|
||||
|
||||
result=""
|
||||
i=0
|
||||
while [ $i -lt ${#passwd_hex} ]; do
|
||||
for byte in $key; do
|
||||
[ $i -ge ${#passwd_hex} ] && break
|
||||
p="${passwd_hex:$i:2}"
|
||||
r=$(printf '%02x' $((0x$p ^ 0x$byte)))
|
||||
result="${result}${r}"
|
||||
i=$((i + 2))
|
||||
done
|
||||
done
|
||||
|
||||
echo "$result"
|
||||
}
|
||||
|
||||
login() {
|
||||
username="$1"
|
||||
password="$2"
|
||||
|
||||
enable_passwordless_sudo() {
|
||||
execute mkdir -p /etc/sudoers.d/
|
||||
echo "${username} ALL=(ALL) NOPASSWD: ALL" | EDITOR=tee execute visudo "/etc/sudoers.d/${username}-nopasswd"
|
||||
}
|
||||
|
||||
enable_auto_login() {
|
||||
echo "00000000: 1ced 3f4a bcbc ba2c caca 4e82" | execute xxd -r - /etc/kcpassword
|
||||
execute defaults write /Library/Preferences/com.apple.loginwindow autoLoginUser "${username}"
|
||||
}
|
||||
|
||||
disable_screen_lock() {
|
||||
execute sysadminctl -screenLock off -password "${password}"
|
||||
}
|
||||
|
||||
enable_passwordless_sudo
|
||||
enable_auto_login
|
||||
disable_screen_lock
|
||||
}
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: $0 <username> <password>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
login "$@"
|
||||
@@ -1,78 +0,0 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
tart = {
|
||||
version = ">= 1.12.0"
|
||||
source = "github.com/cirruslabs/tart"
|
||||
}
|
||||
external = {
|
||||
version = ">= 0.0.2"
|
||||
source = "github.com/joomcode/external"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "release" {
|
||||
type = number
|
||||
default = 13
|
||||
}
|
||||
|
||||
variable "username" {
|
||||
type = string
|
||||
default = "admin"
|
||||
}
|
||||
|
||||
variable "password" {
|
||||
type = string
|
||||
default = "admin"
|
||||
}
|
||||
|
||||
variable "cpu_count" {
|
||||
type = number
|
||||
default = 2
|
||||
}
|
||||
|
||||
variable "memory_gb" {
|
||||
type = number
|
||||
default = 4
|
||||
}
|
||||
|
||||
variable "disk_size_gb" {
|
||||
type = number
|
||||
default = 50
|
||||
}
|
||||
|
||||
locals {
|
||||
sequoia = {
|
||||
tier = 1
|
||||
distro = "sequoia"
|
||||
release = "15"
|
||||
ipsw = "https://updates.cdn-apple.com/2024FallFCS/fullrestores/062-78489/BDA44327-C79E-4608-A7E0-455A7E91911F/UniversalMac_15.0_24A335_Restore.ipsw"
|
||||
}
|
||||
|
||||
sonoma = {
|
||||
tier = 2
|
||||
distro = "sonoma"
|
||||
release = "14"
|
||||
ipsw = "https://updates.cdn-apple.com/2023FallFCS/fullrestores/042-54934/0E101AD6-3117-4B63-9BF1-143B6DB9270A/UniversalMac_14.0_23A344_Restore.ipsw"
|
||||
}
|
||||
|
||||
ventura = {
|
||||
tier = 2
|
||||
distro = "ventura"
|
||||
release = "13"
|
||||
ipsw = "https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-92188/2C38BCD1-2BFF-4A10-B358-94E8E28BE805/UniversalMac_13.0_22A380_Restore.ipsw"
|
||||
}
|
||||
|
||||
releases = {
|
||||
15 = local.sequoia
|
||||
14 = local.sonoma
|
||||
13 = local.ventura
|
||||
}
|
||||
|
||||
release = local.releases[var.release]
|
||||
username = var.username
|
||||
password = var.password
|
||||
cpu_count = var.cpu_count
|
||||
memory_gb = var.memory_gb
|
||||
disk_size_gb = var.disk_size_gb
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
ARG IMAGE=debian:11
|
||||
FROM $IMAGE
|
||||
COPY ./scripts/bootstrap.sh /tmp/bootstrap.sh
|
||||
ENV CI=true
|
||||
RUN sh /tmp/bootstrap.sh && rm -rf /tmp/*
|
||||
WORKDIR /workspace/bun
|
||||
COPY bunfig.toml bunfig.toml
|
||||
COPY package.json package.json
|
||||
COPY CMakeLists.txt CMakeLists.txt
|
||||
COPY cmake/ cmake/
|
||||
COPY scripts/ scripts/
|
||||
COPY patches/ patches/
|
||||
COPY *.zig ./
|
||||
COPY src/ src/
|
||||
COPY packages/ packages/
|
||||
COPY test/ test/
|
||||
RUN bun i
|
||||
RUN bun run build:ci
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script sets the hostname of the current machine.
|
||||
|
||||
execute() {
|
||||
echo "$ $@" >&2
|
||||
if ! "$@"; then
|
||||
echo "Command failed: $@" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <hostname>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$(which hostnamectl)" ]; then
|
||||
execute hostnamectl set-hostname "$1"
|
||||
else
|
||||
echo "Error: hostnamectl is not installed." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script starts tailscale on the current machine.
|
||||
|
||||
execute() {
|
||||
echo "$ $@" >&2
|
||||
if ! "$@"; then
|
||||
echo "Command failed: $@" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Usage: $0 <auth-key>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
execute tailscale up --reset --ssh --accept-risk=lose-ssh --auth-key="$1"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bootstrap": "brew install gh jq cirruslabs/cli/tart cirruslabs/cli/sshpass hashicorp/tap/packer && packer init darwin",
|
||||
"login": "token=$(gh auth token); username=$(gh api user --jq .login); echo \"Login as $username...\"; echo \"$token\" | tart login ghcr.io --username \"$username\" --password-stdin; echo \"$token\" | docker login ghcr.io --username \"$username\" --password-stdin",
|
||||
"fetch:image-name": "echo ghcr.io/oven-sh/bun-vm",
|
||||
"fetch:darwin-version": "echo 1",
|
||||
"fetch:macos-version": "sw_vers -productVersion | cut -d. -f1",
|
||||
"fetch:script-version": "cat ../scripts/bootstrap.sh | grep 'v=' | sed 's/v=\"//;s/\"//' | head -n 1",
|
||||
"build:darwin-aarch64-vanilla": "packer build '-only=*.bun-darwin-aarch64-vanilla' -var release=$(bun fetch:macos-version) darwin/",
|
||||
"build:darwin-aarch64-vanilla-15": "packer build '-only=*.bun-darwin-aarch64-vanilla' -var release=15 darwin/",
|
||||
"build:darwin-aarch64-vanilla-14": "packer build '-only=*.bun-darwin-aarch64-vanilla' -var release=14 darwin/",
|
||||
"build:darwin-aarch64-vanilla-13": "packer build '-only=*.bun-darwin-aarch64-vanilla' -var release=13 darwin/",
|
||||
"build:darwin-aarch64": "packer build '-only=*.bun-darwin-aarch64' -var release=$(bun fetch:macos-version) darwin/",
|
||||
"build:darwin-aarch64-15": "packer build '-only=*.bun-darwin-aarch64' -var release=15 darwin/",
|
||||
"build:darwin-aarch64-14": "packer build '-only=*.bun-darwin-aarch64' -var release=14 darwin/",
|
||||
"build:darwin-aarch64-13": "packer build '-only=*.bun-darwin-aarch64' -var release=13 darwin/",
|
||||
"publish:darwin-aarch64-vanilla": "image=$(tart list --format json | jq -r \".[] | select(.Name | test(\\\"^bun-darwin-aarch64-vanilla-.*-$(bun fetch:macos-version)$\\\")) | .Name\" | head -n 1 | sed 's/bun-//'); tart push \"bun-$image\" \"ghcr.io/oven-sh/bun-vm:$image-v$(bun fetch:darwin-version)\"",
|
||||
"publish:darwin-aarch64-vanilla-15": "tart push bun-darwin-aarch64-vanilla-sequoia-15 \"$(bun fetch:image-name):darwin-aarch64-vanilla-sequoia-15-v$(bun fetch:darwin-version)\"",
|
||||
"publish:darwin-aarch64-vanilla-14": "tart push bun-darwin-aarch64-vanilla-sonoma-14 \"$(bun fetch:image-name):darwin-aarch64-vanilla-sonoma-14-v$(bun fetch:darwin-version)\"",
|
||||
"publish:darwin-aarch64-vanilla-13": "tart push bun-darwin-aarch64-vanilla-ventura-13 \"$(bun fetch:image-name):darwin-aarch64-vanilla-ventura-13-v$(bun fetch:darwin-version)\"",
|
||||
"publish:darwin-aarch64": "image=$(tart list --format json | jq -r \".[] | select(.Name | test(\\\"^bun-darwin-aarch64-.*-$(bun fetch:macos-version)$\\\")) | .Name\" | head -n 1 | sed 's/bun-//'); tart push \"bun-$image\" \"ghcr.io/oven-sh/bun-vm:$image-v$(bun fetch:script-version)\"",
|
||||
"publish:darwin-aarch64-15": "tart push bun-darwin-aarch64-sequoia-15 \"$(bun fetch:image-name):darwin-aarch64-sequoia-15-v$(bun fetch:script-version)\"",
|
||||
"publish:darwin-aarch64-14": "tart push bun-darwin-aarch64-sonoma-14 \"$(bun fetch:image-name):darwin-aarch64-sonoma-14-v$(bun fetch:script-version)\"",
|
||||
"publish:darwin-aarch64-13": "tart push bun-darwin-aarch64-ventura-13 \"$(bun fetch:image-name):darwin-aarch64-ventura-13-v$(bun fetch:script-version)\""
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -432,6 +432,7 @@ set(BUN_OBJECT_LUT_SOURCES
|
||||
${CWD}/src/bun.js/bindings/BunProcess.cpp
|
||||
${CWD}/src/bun.js/bindings/ProcessBindingBuffer.cpp
|
||||
${CWD}/src/bun.js/bindings/ProcessBindingConstants.cpp
|
||||
${CWD}/src/bun.js/bindings/ProcessBindingFs.cpp
|
||||
${CWD}/src/bun.js/bindings/ProcessBindingNatives.cpp
|
||||
${CWD}/src/bun.js/modules/NodeModuleModule.cpp
|
||||
${CODEGEN_PATH}/ZigGeneratedClasses.lut.txt
|
||||
@@ -444,6 +445,7 @@ set(BUN_OBJECT_LUT_OUTPUTS
|
||||
${CODEGEN_PATH}/BunProcess.lut.h
|
||||
${CODEGEN_PATH}/ProcessBindingBuffer.lut.h
|
||||
${CODEGEN_PATH}/ProcessBindingConstants.lut.h
|
||||
${CODEGEN_PATH}/ProcessBindingFs.lut.h
|
||||
${CODEGEN_PATH}/ProcessBindingNatives.lut.h
|
||||
${CODEGEN_PATH}/NodeModuleModule.lut.h
|
||||
${CODEGEN_PATH}/ZigGeneratedClasses.lut.h
|
||||
@@ -620,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
|
||||
@@ -757,6 +760,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
|
||||
|
||||
@@ -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 57004f91903936881b3301594d9d67708f1ff64c)
|
||||
set(WEBKIT_VERSION 0d7d28b5907f628331d4a944c3436856447fbf64)
|
||||
endif()
|
||||
|
||||
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
|
||||
|
||||
@@ -20,7 +20,7 @@ else()
|
||||
unsupported(CMAKE_SYSTEM_NAME)
|
||||
endif()
|
||||
|
||||
set(ZIG_COMMIT "02c57c7ee3b8fde7528c74dd06490834d2d6fae9")
|
||||
set(ZIG_COMMIT "bb9d6ab2c0bbbf20cc24dad03e88f3b3ffdb7de7")
|
||||
optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:bullseye-slim AS build
|
||||
FROM debian:bookworm-slim AS build
|
||||
|
||||
# https://github.com/oven-sh/bun/releases
|
||||
ARG BUN_VERSION=latest
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:bullseye-slim AS build
|
||||
FROM debian:bookworm-slim AS build
|
||||
|
||||
# https://github.com/oven-sh/bun/releases
|
||||
ARG BUN_VERSION=latest
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM debian:bullseye-slim AS build
|
||||
FROM debian:bookworm-slim AS build
|
||||
|
||||
# https://github.com/oven-sh/bun/releases
|
||||
ARG BUN_VERSION=latest
|
||||
|
||||
@@ -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
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
{% callout %}
|
||||
**⚠️ Warning** — `bun:ffi` is **experimental**, with known bugs and limitations, and should not be relied on in production. The most stable way to interact with native code from Bun is to write a [Node-API module](/docs/api/node-api).
|
||||
{% /callout %}
|
||||
|
||||
Use the built-in `bun:ffi` module to efficiently call native libraries from JavaScript. It works with languages that support the C ABI (Zig, Rust, C/C++, C#, Nim, Kotlin, etc).
|
||||
|
||||
## dlopen usage (`bun:ffi`)
|
||||
@@ -298,7 +302,11 @@ setTimeout(() => {
|
||||
When you're done with a JSCallback, you should call `close()` to free the memory.
|
||||
|
||||
### Experimental thread-safe callbacks
|
||||
`JSCallback` has experimental support for thread-safe callbacks. This will be needed if you pass a callback function into a different thread from it's instantiation context. You can enable it with the optional `threadsafe` option flag.
|
||||
|
||||
`JSCallback` has experimental support for thread-safe callbacks. This will be needed if you pass a callback function into a different thread from its instantiation context. You can enable it with the optional `threadsafe` parameter.
|
||||
|
||||
Currently, thread-safe callbacks work best when run from another thread that is running JavaScript code, i.e. a [`Worker`](/docs/api/workers). A future version of Bun will enable them to be called from any thread (such as new threads spawned by your native library that Bun is not aware of).
|
||||
|
||||
```ts
|
||||
const searchIterator = new JSCallback(
|
||||
(ptr, length) => /hello/.test(new CString(ptr, length)),
|
||||
@@ -309,7 +317,6 @@ const searchIterator = new JSCallback(
|
||||
},
|
||||
);
|
||||
```
|
||||
Be aware that there are still cases where this does not 100% work.
|
||||
|
||||
{% callout %}
|
||||
|
||||
|
||||
@@ -418,7 +418,7 @@ export interface Post {
|
||||
|
||||
### Routing performance
|
||||
|
||||
`Bun.serve()`'s router builds on top uWebSocket's [tree-based approach](https://github.com/oven-sh/bun/blob/0d1a00fa0f7830f8ecd99c027fce8096c9d459b6/packages/bun-uws/src/HttpRouter.h#L57-L64) to add [SIMD-accelerated route parameter decoding](https://github.com/oven-sh/bun/blob/jarred/optional-fetch/src/bun.js/bindings/decodeURIComponentSIMD.cpp#L21-L271) and [JavaScriptCore structure caching](https://github.com/oven-sh/bun/blob/jarred/optional-fetch/src/bun.js/bindings/ServerRouteList.cpp#L100-L101) to push the performance limits of what modern hardware allows.
|
||||
`Bun.serve()`'s router builds on top uWebSocket's [tree-based approach](https://github.com/oven-sh/bun/blob/0d1a00fa0f7830f8ecd99c027fce8096c9d459b6/packages/bun-uws/src/HttpRouter.h#L57-L64) to add [SIMD-accelerated route parameter decoding](https://github.com/oven-sh/bun/blob/main/src/bun.js/bindings/decodeURIComponentSIMD.cpp#L21-L271) and [JavaScriptCore structure caching](https://github.com/oven-sh/bun/blob/main/src/bun.js/bindings/ServerRouteList.cpp#L100-L101) to push the performance limits of what modern hardware allows.
|
||||
|
||||
### `fetch` request handler
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ await sql`INSERT INTO users ${sql(users)}`;
|
||||
|
||||
### Picking columns to insert
|
||||
|
||||
You can use `sql(object, Array<string>)` to pick which columns to insert. Each of the columns must be defined on the object.
|
||||
You can use `sql(object, ...string)` to pick which columns to insert. Each of the columns must be defined on the object.
|
||||
|
||||
```ts
|
||||
const user = {
|
||||
@@ -96,7 +96,7 @@ const user = {
|
||||
age: 25,
|
||||
};
|
||||
|
||||
await sql`INSERT INTO users ${sql(user, ["name", "email"])}`;
|
||||
await sql`INSERT INTO users ${sql(user, "name", "email")}`;
|
||||
// Only inserts name and email columns, ignoring other fields
|
||||
```
|
||||
|
||||
@@ -165,6 +165,31 @@ await sql`
|
||||
`;
|
||||
```
|
||||
|
||||
### Dynamic columns in updates
|
||||
|
||||
You can use `sql(object, ...string)` to pick which columns to update. Each of the columns must be defined on the object. If the columns are not informed all keys will be used to update the row.
|
||||
|
||||
```ts
|
||||
await sql`UPDATE users SET ${sql(user, "name", "email")} WHERE id = ${user.id}`;
|
||||
// uses all keys from the object to update the row
|
||||
await sql`UPDATE users SET ${sql(user)} WHERE id = ${user.id}`;
|
||||
```
|
||||
|
||||
### Dynamic values and `where in`
|
||||
|
||||
Value lists can also be created dynamically, making where in queries simple too. Optionally you can pass a array of objects and inform what key to use to create the list.
|
||||
|
||||
```ts
|
||||
await sql`SELECT * FROM users WHERE id IN ${sql([1, 2, 3])}`;
|
||||
|
||||
const users = [
|
||||
{ id: 1, name: "Alice" },
|
||||
{ id: 2, name: "Bob" },
|
||||
{ id: 3, name: "Charlie" },
|
||||
];
|
||||
await sql`SELECT * FROM users WHERE id IN ${sql(users, "id")}`;
|
||||
```
|
||||
|
||||
## `sql``.simple()`
|
||||
|
||||
The PostgreSQL wire protocol supports two types of queries: "simple" and "extended". Simple queries can contain multiple statements but don't support parameters, while extended queries (the default) support parameters but only allow one statement.
|
||||
@@ -183,6 +208,14 @@ Simple queries are often useful for database migrations and setup scripts.
|
||||
|
||||
Note that simple queries cannot use parameters (`${value}`). If you need parameters, you must split your query into separate statements.
|
||||
|
||||
### Queries in files
|
||||
|
||||
You can use the `sql.file` method to read a query from a file and execute it, if the file includes $1, $2, etc you can pass parameters to the query. If no parameters are used it can execute multiple commands per file.
|
||||
|
||||
```ts
|
||||
const result = await sql.file("query.sql", [1, 2, 3]);
|
||||
```
|
||||
|
||||
### Unsafe Queries
|
||||
|
||||
You can use the `sql.unsafe` function to execute raw SQL strings. Use this with caution, as it will not escape user input. Executing more than one command per query is allowed if no parameters are used.
|
||||
@@ -288,6 +321,21 @@ const db = new SQL({
|
||||
});
|
||||
```
|
||||
|
||||
## Dynamic passwords
|
||||
|
||||
When clients need to use alternative authentication schemes such as access tokens or connections to databases with rotating passwords, provide either a synchronous or asynchronous function that will resolve the dynamic password value at connection time.
|
||||
|
||||
```ts
|
||||
import { SQL } from "bun";
|
||||
|
||||
const sql = new SQL(url, {
|
||||
// Other connection config
|
||||
...
|
||||
// Password function for the database user
|
||||
password: async () => await signer.getAuthToken(),
|
||||
});
|
||||
```
|
||||
|
||||
## Transactions
|
||||
|
||||
To start a new transaction, use `sql.begin`. This method reserves a dedicated connection for the duration of the transaction and provides a scoped `sql` instance to use within the callback function. Once the callback completes, `sql.begin` resolves with the return value of the callback.
|
||||
|
||||
@@ -228,3 +228,17 @@ const worker = new Worker("./i-am-smol.ts", {
|
||||
{% details summary="What does `smol` mode actually do?" %}
|
||||
Setting `smol: true` sets `JSC::HeapSize` to be `Small` instead of the default `Large`.
|
||||
{% /details %}
|
||||
|
||||
## `Bun.isMainThread`
|
||||
|
||||
You can check if you're in the main thread by checking `Bun.isMainThread`.
|
||||
|
||||
```ts
|
||||
if (Bun.isMainThread) {
|
||||
console.log("I'm the main thread");
|
||||
} else {
|
||||
console.log("I'm in a worker");
|
||||
}
|
||||
```
|
||||
|
||||
This is useful for conditionally running code based on whether you're in the main thread or not.
|
||||
|
||||
@@ -75,14 +75,16 @@ bun build --compile --target=bun-darwin-x64 ./path/to/my/app.ts --outfile myapp
|
||||
|
||||
The order of the `--target` flag does not matter, as long as they're delimited by a `-`.
|
||||
|
||||
| --target | Operating System | Architecture | Modern | Baseline |
|
||||
| --------------------- | ---------------- | ------------ | ------ | -------- |
|
||||
| bun-linux-x64 | Linux | x64 | ✅ | ✅ |
|
||||
| bun-linux-arm64 | Linux | arm64 | ✅ | N/A |
|
||||
| bun-windows-x64 | Windows | x64 | ✅ | ✅ |
|
||||
| ~~bun-windows-arm64~~ | Windows | arm64 | ❌ | ❌ |
|
||||
| bun-darwin-x64 | macOS | x64 | ✅ | ✅ |
|
||||
| bun-darwin-arm64 | macOS | arm64 | ✅ | N/A |
|
||||
| --target | Operating System | Architecture | Modern | Baseline | Libc |
|
||||
| --------------------- | ---------------- | ------------ | ------ | -------- | ----- |
|
||||
| bun-linux-x64 | Linux | x64 | ✅ | ✅ | glibc |
|
||||
| bun-linux-arm64 | Linux | arm64 | ✅ | N/A | glibc |
|
||||
| bun-windows-x64 | Windows | x64 | ✅ | ✅ | - |
|
||||
| ~~bun-windows-arm64~~ | Windows | arm64 | ❌ | ❌ | - |
|
||||
| bun-darwin-x64 | macOS | x64 | ✅ | ✅ | - |
|
||||
| bun-darwin-arm64 | macOS | arm64 | ✅ | N/A | - |
|
||||
| bun-linux-x64-musl | Linux | x64 | ✅ | ✅ | musl |
|
||||
| bun-linux-arm64-musl | Linux | arm64 | ✅ | N/A | musl |
|
||||
|
||||
On x64 platforms, Bun uses SIMD optimizations which require a modern CPU supporting AVX2 instructions. The `-baseline` build of Bun is for older CPUs that don't support these optimizations. Normally, when you install Bun we automatically detect which version to use but this can be harder to do when cross-compiling since you might not know the target CPU. You usually don't need to worry about it on Darwin x64, but it is relevant for Windows x64 and Linux x64. If you or your users see `"Illegal instruction"` errors, you might need to use the baseline version.
|
||||
|
||||
@@ -294,6 +296,55 @@ These flags currently cannot be used when cross-compiling because they depend on
|
||||
|
||||
{% /callout %}
|
||||
|
||||
## Code signing on macOS
|
||||
|
||||
To codesign a standalone executable on macOS (which fixes Gatekeeper warnings), use the `codesign` command.
|
||||
|
||||
```sh
|
||||
$ codesign --deep --force -vvvv --sign "XXXXXXXXXX" ./myapp
|
||||
```
|
||||
|
||||
We recommend including an `entitlements.plist` file with JIT permissions.
|
||||
|
||||
```xml#entitlements.plist
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
To codesign with JIT support, pass the `--entitlements` flag to `codesign`.
|
||||
|
||||
```sh
|
||||
$ codesign --deep --force -vvvv --sign "XXXXXXXXXX" --entitlements entitlements.plist ./myapp
|
||||
```
|
||||
|
||||
After codesigning, verify the executable:
|
||||
|
||||
```sh
|
||||
$ codesign -vvv --verify ./myapp
|
||||
./myapp: valid on disk
|
||||
./myapp: satisfies its Designated Requirement
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
|
||||
Codesign support requires Bun v1.2.4 or newer.
|
||||
|
||||
{% /callout %}
|
||||
|
||||
## Unsupported CLI arguments
|
||||
|
||||
Currently, the `--compile` flag can only accept a single entrypoint at a time and does not support the following flags:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -12,9 +12,12 @@ Options for the `pack` command:
|
||||
|
||||
- `--dry-run`: Perform all tasks except writing the tarball to disk.
|
||||
- `--destination`: Specify the directory where the tarball will be saved.
|
||||
- `--filename`: Specify an exact file name for the tarball to be saved at.
|
||||
- `--ignore-scripts`: Skip running pre/postpack and prepare scripts.
|
||||
- `--gzip-level`: Set a custom compression level for gzip, ranging from 0 to 9 (default is 9).
|
||||
|
||||
> Note `--filename` and `--destination` cannot be used at the same time
|
||||
|
||||
## bin
|
||||
|
||||
To print the path to the `bin` directory for the local project:
|
||||
|
||||
56
docs/guides/runtime/codesign-macos-executable.md
Normal file
56
docs/guides/runtime/codesign-macos-executable.md
Normal file
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: Codesign a single-file JavaScript executable on macOS
|
||||
description: Fix the "can't be opened because it is from an unidentified developer" Gatekeeper warning when running your JavaScript executable.
|
||||
---
|
||||
|
||||
Compile your executable using the `--compile` flag.
|
||||
|
||||
```sh
|
||||
$ bun build --compile ./path/to/entry.ts --outfile myapp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
List your available signing identities. One of these will be your signing identity that you pass to the `codesign` command. This command requires macOS.
|
||||
|
||||
```sh
|
||||
$ security find-identity -v -p codesigning
|
||||
1. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX "Developer ID Application: Your Name (ZZZZZZZZZZ)"
|
||||
1 valid identities found
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Optional, but recommended: create an `entitlements.plist` file with the necessary permissions for the JavaScript engine to work correctly.
|
||||
|
||||
```xml#entitlements.plist
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-executable-page-protection</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Sign your executable using the `codesign` command and verify it works.
|
||||
|
||||
```bash
|
||||
$ codesign --entitlements entitlements.plist -vvvv --deep --sign "XXXXXXXXXX" ./myapp --force
|
||||
$ codesign -vvv --verify ./myapp
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
For more information on macOS codesigning, refer to [Apple's Code Signing documentation](https://developer.apple.com/documentation/security/code_signing_services). For details about creating single-file executables with Bun, see [Standalone Executables](/docs/bundler/executables). This guide requires Bun v1.2.4 or newer.
|
||||
@@ -28,10 +28,21 @@ BAR=world
|
||||
|
||||
Variables can also be set via the command line.
|
||||
|
||||
```sh
|
||||
{% codetabs %}
|
||||
|
||||
```sh#Linux/macOS
|
||||
$ FOO=helloworld bun run dev
|
||||
```
|
||||
|
||||
```sh#Windows
|
||||
# Using CMD
|
||||
$ set FOO=helloworld && bun run dev
|
||||
|
||||
# Using PowerShell
|
||||
$ $env:FOO="helloworld"; bun run dev
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
---
|
||||
|
||||
See [Docs > Runtime > Environment variables](https://bun.sh/docs/runtime/env) for more information on using environment variables with Bun.
|
||||
|
||||
@@ -8,7 +8,7 @@ VSCode extension support is currently buggy. We recommend the [Web Debugger](htt
|
||||
|
||||
{% /note %}
|
||||
|
||||
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-vscode/types/jsc.d.ts) so you can debug your code with an interactive debugger.
|
||||
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-inspector-protocol/src/protocol/jsc/index.d.ts) so you can debug your code with an interactive debugger.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -63,6 +63,20 @@ $ bun install --filter "pkg-*" --filter "!pkg-c"
|
||||
$ bun install --filter "./packages/pkg-*" --filter "!pkg-c" # or --filter "!./packages/pkg-c"
|
||||
```
|
||||
|
||||
When publishing, `workspace:` versions are replaced by the package's `package.json` version,
|
||||
|
||||
```
|
||||
"workspace:*" -> "1.0.1"
|
||||
"workspace:^" -> "^1.0.1"
|
||||
"workspace:~" -> "~1.0.1"
|
||||
```
|
||||
|
||||
Setting a specific version takes precedence over the package's `package.json` version,
|
||||
|
||||
```
|
||||
"workspace:1.0.2" -> "1.0.2" // Even if current version is 1.0.1
|
||||
```
|
||||
|
||||
Workspaces have a couple major benefits.
|
||||
|
||||
- **Code can be split into logical parts.** If one package relies on another, you can simply add it as a dependency in `package.json`. If package `b` depends on `a`, `bun install` will install your local `packages/a` directory into `node_modules` instead of downloading it from the npm registry.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: Debugging
|
||||
---
|
||||
|
||||
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-types/jsc.d.ts), so you can debug your code with an interactive debugger. For demonstration purposes, consider the following simple web server.
|
||||
Bun speaks the [WebKit Inspector Protocol](https://github.com/oven-sh/bun/blob/main/packages/bun-inspector-protocol/src/protocol/jsc/index.d.ts), so you can debug your code with an interactive debugger. For demonstration purposes, consider the following simple web server.
|
||||
|
||||
## Debugging JavaScript and TypeScript
|
||||
|
||||
|
||||
@@ -15,10 +15,40 @@ BAR=world
|
||||
|
||||
Variables can also be set via the command line.
|
||||
|
||||
```sh
|
||||
{% codetabs %}
|
||||
|
||||
```sh#Linux/macOS
|
||||
$ FOO=helloworld bun run dev
|
||||
```
|
||||
|
||||
```sh#Windows
|
||||
# Using CMD
|
||||
$ set FOO=helloworld && bun run dev
|
||||
|
||||
# Using PowerShell
|
||||
$ $env:FOO="helloworld"; bun run dev
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
{% details summary="Cross-platform solution with Windows" %}
|
||||
|
||||
For a cross-platform solution, you can use [bun shell](https://bun.sh/docs/runtime/shell). For example, the `bun exec` command.
|
||||
|
||||
```sh
|
||||
$ bun exec 'FOO=helloworld bun run dev'
|
||||
```
|
||||
|
||||
On Windows, `package.json` scripts called with `bun run` will automatically use the **bun shell**, making the following also cross-platform.
|
||||
|
||||
```json#package.json
|
||||
"scripts": {
|
||||
"dev": "NODE_ENV=development bun --watch app.ts",
|
||||
},
|
||||
```
|
||||
|
||||
{% /details %}
|
||||
|
||||
Or programmatically by assigning a property to `process.env`.
|
||||
|
||||
```ts
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ await $`cat < ${response} | wc -c`; // 1256
|
||||
- **Safety**: Bun Shell escapes all strings by default, preventing shell injection attacks.
|
||||
- **JavaScript interop**: Use `Response`, `ArrayBuffer`, `Blob`, `Bun.file(path)` and other JavaScript objects as stdin, stdout, and stderr.
|
||||
- **Shell scripting**: Bun Shell can be used to run shell scripts (`.bun.sh` files).
|
||||
- **Custom interpreter**: Bun Shell is written in Zig, along with it's lexer, parser, and interpreter. Bun Shell is a small programming language.
|
||||
- **Custom interpreter**: Bun Shell is written in Zig, along with its lexer, parser, and interpreter. Bun Shell is a small programming language.
|
||||
|
||||
## Getting started
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "bun",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.5",
|
||||
"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
|
||||
86
packages/bun-plugin-svelte/README.md
Normal file
86
packages/bun-plugin-svelte/README.md
Normal file
@@ -0,0 +1,86 @@
|
||||
<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.
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<html>
|
||||
<head>
|
||||
<script type="module" src="./index.ts"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```ts
|
||||
// index.ts
|
||||
|
||||
import { mount, unmount } from "svelte";
|
||||
import App from "./App.svelte";
|
||||
|
||||
// mount the application entrypoint to the DOM
|
||||
const root = document.getElementById("root")!;
|
||||
const app = mount(App, { target: root });
|
||||
```
|
||||
|
||||
```svelte
|
||||
<!-- App.svelte -->
|
||||
|
||||
<script lang="ts">
|
||||
// out-of-the-box typescript support
|
||||
let name: string = "Bun";
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Cookin up apps with {name}</h1>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
## Bundler Usage
|
||||
|
||||
```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", // use "bun" or "node" to use Svelte components server-side
|
||||
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.
|
||||
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=="],
|
||||
}
|
||||
}
|
||||
32
packages/bun-plugin-svelte/package.json
Normal file
32
packages/bun-plugin-svelte/package.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "bun-plugin-svelte",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"module": "src/index.ts",
|
||||
"index": "src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "oxlint .",
|
||||
"check:types": "tsc --noEmit",
|
||||
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir ./dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "canary",
|
||||
"svelte": "^5.20.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
"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);
|
||||
});
|
||||
});
|
||||
98
packages/bun-plugin-svelte/src/index.ts
Normal file
98
packages/bun-plugin-svelte/src/index.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import type { BunPlugin, BuildConfig, OnLoadResult } from "bun";
|
||||
import { basename } from "node:path";
|
||||
import { compile, compileModule } from "svelte/compiler";
|
||||
import { getBaseCompileOptions, validateOptions, type SvelteOptions, hash } from "./options";
|
||||
|
||||
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) {
|
||||
const { config = kEmptyObject as Partial<BuildConfig> } = builder;
|
||||
const baseCompileOptions = getBaseCompileOptions(options ?? (kEmptyObject as Partial<SvelteOptions>), config);
|
||||
|
||||
builder
|
||||
.onLoad({ filter: /\.svelte(?:\.[tj]s)?$/ }, async args => {
|
||||
const { path } = args;
|
||||
|
||||
var isModule = false;
|
||||
|
||||
switch (path.substring(path.length - 2)) {
|
||||
case "js":
|
||||
case "ts":
|
||||
isModule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const sourceText = await Bun.file(path).text();
|
||||
|
||||
const side =
|
||||
args && "side" in args // "side" only passed when run from dev server
|
||||
? (args as { side: "client" | "server" }).side
|
||||
: "server";
|
||||
const hmr = Boolean((args as { hmr?: boolean })["hmr"] ?? process.env.NODE_ENV !== "production");
|
||||
const generate = baseCompileOptions.generate ?? side;
|
||||
|
||||
const compileFn = isModule ? compileModule : compile;
|
||||
const result = compileFn(sourceText, {
|
||||
...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: "js",
|
||||
} satisfies OnLoadResult;
|
||||
// TODO: allow plugins to return multiple results.
|
||||
// TODO: support layered sourcemaps
|
||||
})
|
||||
.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",
|
||||
}),
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
91
packages/bun-plugin-svelte/src/options.ts
Normal file
91
packages/bun-plugin-svelte/src/options.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import type { BuildConfig } from "bun";
|
||||
import type { CompileOptions } 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 { forceSide, development = false } = pluginOptions;
|
||||
const { minify = false, target } = config;
|
||||
|
||||
const shouldMinify = Boolean(minify);
|
||||
const {
|
||||
whitespace: minifyWhitespace,
|
||||
syntax: _minifySyntax,
|
||||
identifiers: _minifyIdentifiers,
|
||||
} = typeof minify === "object"
|
||||
? minify
|
||||
: {
|
||||
whitespace: shouldMinify,
|
||||
syntax: shouldMinify,
|
||||
identifiers: shouldMinify,
|
||||
};
|
||||
|
||||
if (forceSide == null && typeof target === "string") {
|
||||
switch (target) {
|
||||
case "browser":
|
||||
forceSide = "client";
|
||||
break;
|
||||
case "node":
|
||||
case "bun":
|
||||
forceSide = "server";
|
||||
break;
|
||||
default:
|
||||
// warn? throw?
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
css: "external",
|
||||
generate: forceSide,
|
||||
preserveWhitespace: !minifyWhitespace,
|
||||
preserveComments: !shouldMinify,
|
||||
dev: development,
|
||||
cssHash({ css }) {
|
||||
// same prime number seed used by svelte/compiler.
|
||||
// TODO: ensure this provides enough entropy
|
||||
return `svelte-${hash(css)}`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
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>
|
||||
88
packages/bun-plugin-svelte/test/index.test.ts
Normal file
88
packages/bun-plugin-svelte/test/index.test.ts
Normal file
@@ -0,0 +1,88 @@
|
||||
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";
|
||||
|
||||
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("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;
|
||||
}
|
||||
|
||||
365
packages/bun-types/bun.d.ts
vendored
365
packages/bun-types/bun.d.ts
vendored
@@ -1,3 +1,74 @@
|
||||
declare class _ShellError extends Error implements ShellOutput {
|
||||
readonly stdout: Buffer;
|
||||
readonly stderr: Buffer;
|
||||
readonly exitCode: number;
|
||||
|
||||
/**
|
||||
* Read from stdout as a string
|
||||
*
|
||||
* @param encoding - The encoding to use when decoding the output
|
||||
* @returns Stdout as a string with the given encoding
|
||||
* @example
|
||||
*
|
||||
* ## Read as UTF-8 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.text()); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
* ## Read as base64 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo ${atob("hello")}`;
|
||||
* console.log(output.text("base64")); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
text(encoding?: BufferEncoding): string;
|
||||
|
||||
/**
|
||||
* Read from stdout as a JSON object
|
||||
*
|
||||
* @returns Stdout as a JSON object
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo '{"hello": 123}'`;
|
||||
* console.log(output.json()); // { hello: 123 }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
json(): any;
|
||||
|
||||
/**
|
||||
* Read from stdout as an ArrayBuffer
|
||||
*
|
||||
* @returns Stdout as an ArrayBuffer
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
|
||||
* ```
|
||||
*/
|
||||
arrayBuffer(): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Read from stdout as a Blob
|
||||
*
|
||||
* @returns Stdout as a blob
|
||||
* @example
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.blob()); // Blob { size: 6, type: "" }
|
||||
* ```
|
||||
*/
|
||||
blob(): Blob;
|
||||
|
||||
bytes(): Uint8Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bun.js runtime APIs
|
||||
*
|
||||
@@ -16,9 +87,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;
|
||||
/**
|
||||
@@ -110,77 +185,6 @@ declare module "bun" {
|
||||
| SpawnOptions.Writable
|
||||
| ReadableStream;
|
||||
|
||||
class ShellError extends Error implements ShellOutput {
|
||||
readonly stdout: Buffer;
|
||||
readonly stderr: Buffer;
|
||||
readonly exitCode: number;
|
||||
|
||||
/**
|
||||
* Read from stdout as a string
|
||||
*
|
||||
* @param encoding - The encoding to use when decoding the output
|
||||
* @returns Stdout as a string with the given encoding
|
||||
* @example
|
||||
*
|
||||
* ## Read as UTF-8 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.text()); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
* ## Read as base64 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo ${atob("hello")}`;
|
||||
* console.log(output.text("base64")); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
text(encoding?: BufferEncoding): string;
|
||||
|
||||
/**
|
||||
* Read from stdout as a JSON object
|
||||
*
|
||||
* @returns Stdout as a JSON object
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo '{"hello": 123}'`;
|
||||
* console.log(output.json()); // { hello: 123 }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
json(): any;
|
||||
|
||||
/**
|
||||
* Read from stdout as an ArrayBuffer
|
||||
*
|
||||
* @returns Stdout as an ArrayBuffer
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
|
||||
* ```
|
||||
*/
|
||||
arrayBuffer(): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Read from stdout as a Blob
|
||||
*
|
||||
* @returns Stdout as a blob
|
||||
* @example
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.blob()); // Blob { size: 6, type: "" }
|
||||
* ```
|
||||
*/
|
||||
blob(): Blob;
|
||||
|
||||
bytes(): Uint8Array;
|
||||
}
|
||||
|
||||
class ShellPromise extends Promise<ShellOutput> {
|
||||
get stdin(): WritableStream;
|
||||
/**
|
||||
@@ -300,9 +304,13 @@ declare module "bun" {
|
||||
new (): Shell;
|
||||
}
|
||||
|
||||
type ShellError = _ShellError;
|
||||
|
||||
export interface Shell {
|
||||
(strings: TemplateStringsArray, ...expressions: ShellExpression[]): ShellPromise;
|
||||
|
||||
readonly ShellError: typeof _ShellError;
|
||||
|
||||
/**
|
||||
* Perform bash-like brace expansion on the given pattern.
|
||||
* @param pattern - Brace pattern to expand
|
||||
@@ -1984,9 +1992,9 @@ declare module "bun" {
|
||||
/** Database user for authentication (alias for username) */
|
||||
user?: string;
|
||||
/** Database password for authentication */
|
||||
password?: string;
|
||||
password?: string | (() => Promise<string>);
|
||||
/** Database password for authentication (alias for password) */
|
||||
pass?: string;
|
||||
pass?: string | (() => Promise<string>);
|
||||
/** Name of the database to connect to */
|
||||
database?: string;
|
||||
/** Name of the database to connect to (alias for database) */
|
||||
@@ -2263,6 +2271,13 @@ declare module "bun" {
|
||||
* const result = await sql.unsafe(`select ${danger} from users where id = ${dragons}`)
|
||||
*/
|
||||
unsafe(string: string, values?: any[]): SQLQuery;
|
||||
/**
|
||||
* Reads a file and uses the contents as a query.
|
||||
* Optional parameters can be used if the file includes $1, $2, etc
|
||||
* @example
|
||||
* const result = await sql.file("query.sql", [1, 2, 3]);
|
||||
*/
|
||||
file(filename: string, values?: any[]): SQLQuery;
|
||||
|
||||
/** Current client options */
|
||||
options: SQLOptions;
|
||||
@@ -2588,9 +2603,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"`.
|
||||
@@ -2634,7 +2655,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
|
||||
*
|
||||
@@ -2663,6 +2702,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
|
||||
| {
|
||||
@@ -3933,13 +3980,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)
|
||||
@@ -3947,6 +3995,7 @@ declare module "bun" {
|
||||
unix: string;
|
||||
tls?: TLSOptions | TLSOptions[];
|
||||
}
|
||||
|
||||
interface ErrorLike extends Error {
|
||||
code?: string;
|
||||
errno?: number;
|
||||
@@ -4026,11 +4075,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[];
|
||||
}
|
||||
|
||||
@@ -4487,18 +4654,18 @@ declare module "bun" {
|
||||
*/
|
||||
function serve<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }>(
|
||||
options: (
|
||||
| (Omit<ServeOptions, "fetch"> & {
|
||||
| (DistributedOmit<Serve, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (Omit<ServeOptions, "routes"> & {
|
||||
| (DistributedOmit<Serve, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| WebSocketServeOptions<T>
|
||||
) & {
|
||||
/**
|
||||
* @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;
|
||||
},
|
||||
@@ -4911,7 +5078,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;
|
||||
};
|
||||
|
||||
@@ -5529,12 +5696,18 @@ declare module "bun" {
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @returns `this` for method chaining
|
||||
*/
|
||||
onStart(callback: OnStartCallback): void;
|
||||
onStart(callback: OnStartCallback): this;
|
||||
onBeforeParse(
|
||||
constraints: PluginConstraints,
|
||||
callback: { napiModule: unknown; symbol: string; external?: unknown | undefined },
|
||||
): void;
|
||||
callback: {
|
||||
napiModule: unknown;
|
||||
symbol: string;
|
||||
external?: unknown | undefined;
|
||||
},
|
||||
): this;
|
||||
/**
|
||||
* Register a callback to load imports with a specific import specifier
|
||||
* @param constraints The constraints to apply the plugin to
|
||||
@@ -5549,8 +5722,10 @@ declare module "bun" {
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @returns `this` for method chaining
|
||||
*/
|
||||
onLoad(constraints: PluginConstraints, callback: OnLoadCallback): void;
|
||||
onLoad(constraints: PluginConstraints, callback: OnLoadCallback): this;
|
||||
/**
|
||||
* Register a callback to resolve imports matching a filter and/or namespace
|
||||
* @param constraints The constraints to apply the plugin to
|
||||
@@ -5565,8 +5740,10 @@ declare module "bun" {
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @returns `this` for method chaining
|
||||
*/
|
||||
onResolve(constraints: PluginConstraints, callback: OnResolveCallback): void;
|
||||
onResolve(constraints: PluginConstraints, callback: OnResolveCallback): this;
|
||||
/**
|
||||
* The config object passed to `Bun.build` as is. Can be mutated.
|
||||
*/
|
||||
@@ -5597,8 +5774,10 @@ declare module "bun" {
|
||||
* const { foo } = require("hello:world");
|
||||
* console.log(foo); // "bar"
|
||||
* ```
|
||||
*
|
||||
* @returns `this` for method chaining
|
||||
*/
|
||||
module(specifier: string, callback: () => OnLoadResult | Promise<OnLoadResult>): void;
|
||||
module(specifier: string, callback: () => OnLoadResult | Promise<OnLoadResult>): this;
|
||||
}
|
||||
|
||||
interface BunPlugin {
|
||||
@@ -5617,13 +5796,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(
|
||||
/**
|
||||
|
||||
24
packages/bun-types/devserver.d.ts
vendored
Normal file
24
packages/bun-types/devserver.d.ts
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
interface ImportMeta {
|
||||
/**
|
||||
* Hot module replacement
|
||||
*
|
||||
* https://bun.sh/docs/bundler/fullstack
|
||||
*/
|
||||
hot: {
|
||||
/**
|
||||
* import.meta.hot.data maintains state between module instances during hot replacement, enabling data transfer from previous to new versions.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import.meta.hot.data = {
|
||||
* bun: 'is cool',
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
data: any;
|
||||
};
|
||||
}
|
||||
}
|
||||
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;
|
||||
};
|
||||
|
||||
550
packages/bun-types/globals.d.ts
vendored
550
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,7 +71,7 @@ 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;
|
||||
@@ -160,7 +82,7 @@ declare global {
|
||||
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 +90,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 +138,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 +157,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 +206,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 +394,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 +565,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 +583,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 +631,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 +665,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 +683,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 +775,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 +877,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 +892,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 +1274,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 +1765,6 @@ declare global {
|
||||
*/
|
||||
bytes(): Promise<Uint8Array>;
|
||||
}
|
||||
var Blob: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Blob: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof Blob;
|
||||
|
||||
var Response: typeof globalThis extends {
|
||||
onerror: any;
|
||||
Response: infer T;
|
||||
}
|
||||
? T
|
||||
: typeof import("./fetch").Response;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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[];
|
||||
}
|
||||
var Blob: typeof Blob;
|
||||
}
|
||||
|
||||
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),
|
||||
);
|
||||
|
||||
18
packages/bun-types/test.d.ts
vendored
18
packages/bun-types/test.d.ts
vendored
@@ -401,6 +401,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 +1076,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
|
||||
|
||||
@@ -408,7 +408,7 @@ static int bsd_socket_set_membership6(LIBUS_SOCKET_DESCRIPTOR fd, const struct s
|
||||
mreq.ipv6mr_interface = iface->sin6_scope_id;
|
||||
}
|
||||
int option = drop ? IPV6_LEAVE_GROUP : IPV6_JOIN_GROUP;
|
||||
return setsockopt(fd, IPPROTO_IP, option, &mreq, sizeof(mreq));
|
||||
return setsockopt(fd, IPPROTO_IPV6, option, &mreq, sizeof(mreq));
|
||||
}
|
||||
|
||||
int bsd_socket_set_membership(LIBUS_SOCKET_DESCRIPTOR fd, const struct sockaddr_storage *addr, const struct sockaddr_storage *iface, int drop) {
|
||||
|
||||
@@ -326,33 +326,18 @@ int us_internal_ssl_socket_is_closed(struct us_internal_ssl_socket_t *s) {
|
||||
return us_socket_is_closed(0, &s->s);
|
||||
}
|
||||
|
||||
struct us_internal_ssl_socket_t *
|
||||
us_internal_ssl_socket_close(struct us_internal_ssl_socket_t *s, int code,
|
||||
void *reason) {
|
||||
|
||||
// check if we are already closed
|
||||
if (us_internal_ssl_socket_is_closed(s)) return s;
|
||||
|
||||
if (s->handshake_state != HANDSHAKE_COMPLETED) {
|
||||
// if we have some pending handshake we cancel it and try to check the
|
||||
// latest handshake error this way we will always call on_handshake with the
|
||||
// latest error before closing this should always call
|
||||
// secureConnection/secure before close if we remove this here, we will need
|
||||
// to do this check on every on_close event on sockets, fetch etc and will
|
||||
// increase complexity on a lot of places
|
||||
us_internal_trigger_handshake_callback(s, 0);
|
||||
void us_internal_trigger_handshake_callback_econnreset(struct us_internal_ssl_socket_t *s) {
|
||||
struct us_internal_ssl_socket_context_t *context =
|
||||
(struct us_internal_ssl_socket_context_t *)us_socket_context(0, &s->s);
|
||||
|
||||
// always set the handshake state to completed
|
||||
s->handshake_state = HANDSHAKE_COMPLETED;
|
||||
if (context->on_handshake != NULL) {
|
||||
struct us_bun_verify_error_t verify_error = (struct us_bun_verify_error_t){ .error = -46, .code = "ECONNRESET", .reason = "Client network socket disconnected before secure TLS connection was established"};
|
||||
context->on_handshake(s, 0, verify_error, context->handshake_data);
|
||||
}
|
||||
|
||||
// if we are in the middle of a close_notify we need to finish it (code != 0 forces a fast shutdown)
|
||||
int can_close = us_internal_handle_shutdown(s, code != 0);
|
||||
|
||||
// only close the socket if we are not in the middle of a handshake
|
||||
if(can_close) {
|
||||
return (struct us_internal_ssl_socket_t *)us_socket_close(0, (struct us_socket_t *)s, code, reason);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void us_internal_trigger_handshake_callback(struct us_internal_ssl_socket_t *s,
|
||||
int success) {
|
||||
struct us_internal_ssl_socket_context_t *context =
|
||||
@@ -366,6 +351,32 @@ void us_internal_trigger_handshake_callback(struct us_internal_ssl_socket_t *s,
|
||||
context->on_handshake(s, success, verify_error, context->handshake_data);
|
||||
}
|
||||
}
|
||||
struct us_internal_ssl_socket_t *
|
||||
us_internal_ssl_socket_close(struct us_internal_ssl_socket_t *s, int code,
|
||||
void *reason) {
|
||||
|
||||
// check if we are already closed
|
||||
if (us_internal_ssl_socket_is_closed(s)) return s;
|
||||
us_internal_update_handshake(s);
|
||||
|
||||
if (s->handshake_state != HANDSHAKE_COMPLETED) {
|
||||
// if we have some pending handshake we cancel it and try to check the
|
||||
// latest handshake error this way we will always call on_handshake with the
|
||||
// ECONNRESET error if we remove this here, we will need
|
||||
// to do this check on every on_close event on sockets, fetch etc and will
|
||||
// increase complexity on a lot of places
|
||||
us_internal_trigger_handshake_callback_econnreset(s);
|
||||
}
|
||||
|
||||
// if we are in the middle of a close_notify we need to finish it (code != 0 forces a fast shutdown)
|
||||
int can_close = us_internal_handle_shutdown(s, code != 0);
|
||||
|
||||
// only close the socket if we are not in the middle of a handshake
|
||||
if(can_close) {
|
||||
return (struct us_internal_ssl_socket_t *)us_socket_close(0, (struct us_socket_t *)s, code, reason);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
int us_internal_ssl_renegotiate(struct us_internal_ssl_socket_t *s) {
|
||||
// handle renegotation here since we are using ssl_renegotiate_explicit
|
||||
|
||||
@@ -1767,9 +1778,9 @@ int us_internal_ssl_socket_write(struct us_internal_ssl_socket_t *s,
|
||||
loop_ssl_data->ssl_socket = &s->s;
|
||||
loop_ssl_data->msg_more = msg_more;
|
||||
loop_ssl_data->last_write_was_msg_more = 0;
|
||||
|
||||
int written = SSL_write(s->ssl, data, length);
|
||||
loop_ssl_data->msg_more = 0;
|
||||
|
||||
if (loop_ssl_data->last_write_was_msg_more && !msg_more) {
|
||||
us_socket_flush(0, &s->s);
|
||||
}
|
||||
|
||||
@@ -381,38 +381,6 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"W8mw0FfB+j564ZfJ\n"
|
||||
"-----END CERTIFICATE-----",.len=2041},
|
||||
|
||||
/* SwissSign Silver CA - G2 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gx\n"
|
||||
"FTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAt\n"
|
||||
"IEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTAT\n"
|
||||
"BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcy\n"
|
||||
"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dO\n"
|
||||
"cbpLj6VzHVxumK4DV644N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGi\n"
|
||||
"TSf5YXu6t+WiE7brYT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi\n"
|
||||
"0R86TieFnbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH\n"
|
||||
"6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyC\n"
|
||||
"bTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jM\n"
|
||||
"qDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/\n"
|
||||
"+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBsROopN4WSaGa8gzj+ezku01DwH/te\n"
|
||||
"YLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIj\n"
|
||||
"QAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calI\n"
|
||||
"Lv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n"
|
||||
"HQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c\n"
|
||||
"wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0cDovL3Jl\n"
|
||||
"cG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P4JUw\n"
|
||||
"4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F\n"
|
||||
"kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcS\n"
|
||||
"H9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkD\n"
|
||||
"lm4fS/Bx/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakM\n"
|
||||
"DHiqYMZWjwFaDGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHk\n"
|
||||
"Flt4dR2Xem1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR\n"
|
||||
"dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29\n"
|
||||
"MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI\n"
|
||||
"4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s\n"
|
||||
"5Aq7KkzrCWA5zspi2C5u\n"
|
||||
"-----END CERTIFICATE-----",.len=2045},
|
||||
|
||||
/* SecureTrust CA */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYD\n"
|
||||
@@ -3625,4 +3593,66 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr\n"
|
||||
"62Nuk22rGwlgMU4=\n"
|
||||
"-----END CERTIFICATE-----",.len=800},
|
||||
|
||||
/* D-TRUST BR Root CA 2 2023 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBIMQswCQYD\n"
|
||||
"VQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJv\n"
|
||||
"b3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUwOTA4NTYzMFowSDELMAkGA1UE\n"
|
||||
"BhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290\n"
|
||||
"IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYk\n"
|
||||
"P7in5Mg6CjoWzckjYaCTcfKri3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrd\n"
|
||||
"TIzZXcFhfUvnKLNEgXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8\n"
|
||||
"T1soegj8k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT\n"
|
||||
"Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl2ecjbwb9\n"
|
||||
"Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+UcSTq3nD88ZP+npNa\n"
|
||||
"5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP/Wxc6PWOJ4d/GUohR5AdeY0c\n"
|
||||
"W/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bSuREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbM\n"
|
||||
"l6zWK11kJNXuHA7e+whadSr2Y23OC0K+0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAml\n"
|
||||
"Y0cL4UEyNEHZmrHZqLAbWt4NDfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2k\n"
|
||||
"WVki3PaKRT08EtY+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\n"
|
||||
"Z5Dw1t61GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG\n"
|
||||
"OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8yXzIwMjMu\n"
|
||||
"Y3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tIFoE9c+CeJyrrd6kT\n"
|
||||
"pGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67nriv6uvw8l5VAk1/DLQOj7aRv\n"
|
||||
"U9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTRVFxDWy6u71cqqLRvpO8NVhTaIasgdp4D\n"
|
||||
"/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrcLmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8J\n"
|
||||
"kiZmkdijYQ6qgYF/6FKC0ULn4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4n\n"
|
||||
"wSPFyysCu7Ff/vtDhQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnk\n"
|
||||
"bWOACKsGkoHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46\n"
|
||||
"ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aSEcr1wPrY\n"
|
||||
"g1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80knCDgKs4qllo3UCk\n"
|
||||
"GJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJhJ65bvspmZDogNOfJA==\n"
|
||||
"-----END CERTIFICATE-----",.len=2020},
|
||||
|
||||
/* D-TRUST EV Root CA 2 2023 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBIMQswCQYD\n"
|
||||
"VQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJv\n"
|
||||
"b3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUwOTA5MTAzMlowSDELMAkGA1UE\n"
|
||||
"BhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290\n"
|
||||
"IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtyp\n"
|
||||
"U0w3uX9jFxPvp1sjW2l1sJkKF8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/k\n"
|
||||
"PbOx1sWy/YgJ25yE7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR\n"
|
||||
"8CUkNRFeEMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6\n"
|
||||
"lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIbRlUWaqZL\n"
|
||||
"Kfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiVjTujIcSuWMYAsoS0\n"
|
||||
"I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgcjmgjutDzUNzPZY9zOjLHfP7K\n"
|
||||
"giJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZxTnXonMkmdMV9WdEKWw9t/p51HBjGGjp8\n"
|
||||
"2A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0Juyf\n"
|
||||
"Br/CBTdkdXgpaP3F9ev+R/nkhbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8\n"
|
||||
"/M3OsD6Onov4/knFNXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\n"
|
||||
"qvyREBuHkV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG\n"
|
||||
"OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8yXzIwMjMu\n"
|
||||
"Y3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14QvBukEdHjqOSMo1w\n"
|
||||
"j/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4pZt+UPJ26oUFKidBK7GB0aL2\n"
|
||||
"QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q3C+jisosketSjl8MmxfPy3MHGcRqwnNU\n"
|
||||
"73xDUmPBEcrCRbH0O1P1aa4846XerOhUt7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHy\n"
|
||||
"TS9URZ0V4U/M5d40VxDJI3IXcI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3do\n"
|
||||
"tfyc1dZnaVuodNv8ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFa\n"
|
||||
"anuU5nCT2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs\n"
|
||||
"7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNPgofXNJhu\n"
|
||||
"S5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAstNl7F6cTVg8uGF5cs\n"
|
||||
"bBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phhXBxvWHZks/wCuPWdCg==\n"
|
||||
"-----END CERTIFICATE-----",.len=2020},
|
||||
};
|
||||
|
||||
@@ -270,7 +270,6 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
|
||||
|
||||
/* Fetch ready polls */
|
||||
#ifdef LIBUS_USE_EPOLL
|
||||
|
||||
loop->num_ready_polls = bun_epoll_pwait2(loop->fd, loop->ready_polls, 1024, timeout);
|
||||
#else
|
||||
do {
|
||||
|
||||
@@ -457,6 +457,7 @@ struct us_socket_t* us_socket_open(int ssl, struct us_socket_t * s, int is_clien
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
int us_socket_raw_write(int ssl, struct us_socket_t *s, const char *data, int length, int msg_more) {
|
||||
#ifndef LIBUS_NO_SSL
|
||||
if (ssl) {
|
||||
|
||||
@@ -68,11 +68,11 @@ namespace uWS {
|
||||
int ssl_prefer_low_memory_usage = 0;
|
||||
|
||||
const char **key = nullptr;
|
||||
unsigned int key_count = 0;
|
||||
unsigned int key_count = 0;
|
||||
const char **cert = nullptr;
|
||||
unsigned int cert_count = 0;
|
||||
unsigned int cert_count = 0;
|
||||
const char **ca = nullptr;
|
||||
unsigned int ca_count = 0;
|
||||
unsigned int ca_count = 0;
|
||||
unsigned int secure_options = 0;
|
||||
int reject_unauthorized = 0;
|
||||
int request_cert = 0;
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
|
||||
|
||||
/* Server name */
|
||||
TemplatedApp &&addServerName(std::string hostname_pattern, SocketContextOptions options = {}, bool *success = nullptr) {
|
||||
TemplatedApp &&addServerName(const std::string &hostname_pattern, SocketContextOptions options = {}, bool *success = nullptr) {
|
||||
|
||||
/* Do nothing if not even on SSL */
|
||||
if constexpr (SSL) {
|
||||
@@ -121,8 +121,8 @@ public:
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&removeServerName(std::string hostname_pattern) {
|
||||
|
||||
TemplatedApp &&removeServerName(const std::string &hostname_pattern) {
|
||||
|
||||
/* This will do for now, would be better if us_socket_context_remove_server_name returned the user data */
|
||||
auto *domainRouter = us_socket_context_find_server_name_userdata(SSL, (struct us_socket_context_t *) httpContext, hostname_pattern.c_str());
|
||||
if (domainRouter) {
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&missingServerName(MoveOnlyFunction<void(const char *hostname)> handler) {
|
||||
TemplatedApp &&missingServerName(MoveOnlyFunction<void(const char *hostname)> &&handler) {
|
||||
|
||||
if (!constructorFailed()) {
|
||||
httpContext->getSocketContextData()->missingServerNameHandler = std::move(handler);
|
||||
@@ -189,6 +189,10 @@ public:
|
||||
* This function should probably be optimized a lot in future releases,
|
||||
* it could be O(1) with a hash map of fullnames and their counts. */
|
||||
unsigned int numSubscribers(std::string_view topic) {
|
||||
if (!topicTree) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Topic *t = topicTree->lookupTopic(topic);
|
||||
if (t) {
|
||||
return (unsigned int) t->size();
|
||||
@@ -294,7 +298,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename UserData>
|
||||
TemplatedApp &&ws(std::string pattern, WebSocketBehavior<UserData> &&behavior) {
|
||||
TemplatedApp &&ws(std::string_view pattern, WebSocketBehavior<UserData> &&behavior) {
|
||||
/* Don't compile if alignment rules cannot be satisfied */
|
||||
static_assert(alignof(UserData) <= LIBUS_EXT_ALIGNMENT,
|
||||
"µWebSockets cannot satisfy UserData alignment requirements. You need to recompile µSockets with LIBUS_EXT_ALIGNMENT adjusted accordingly.");
|
||||
@@ -473,7 +477,7 @@ public:
|
||||
}
|
||||
|
||||
/* Browse to a server name, changing the router to this domain */
|
||||
TemplatedApp &&domain(std::string serverName) {
|
||||
TemplatedApp &&domain(const std::string &serverName) {
|
||||
HttpContextData<SSL> *httpContextData = httpContext->getSocketContextData();
|
||||
|
||||
void *domainRouter = us_socket_context_find_server_name_userdata(SSL, (struct us_socket_context_t *) httpContext, serverName.c_str());
|
||||
@@ -482,46 +486,46 @@ public:
|
||||
} else {
|
||||
httpContextData->currentRouter = &httpContextData->router;
|
||||
}
|
||||
|
||||
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&get(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&get(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("GET", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&post(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&post(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("POST", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&options(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&options(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("OPTIONS", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&del(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&del(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("DELETE", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&patch(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&patch(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("PATCH", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&put(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&put(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("PUT", pattern, std::move(handler));
|
||||
}
|
||||
@@ -535,21 +539,21 @@ public:
|
||||
}
|
||||
|
||||
|
||||
TemplatedApp &&head(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&head(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("HEAD", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&connect(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&connect(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("CONNECT", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&trace(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&trace(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("TRACE", pattern, std::move(handler));
|
||||
}
|
||||
@@ -557,7 +561,7 @@ public:
|
||||
}
|
||||
|
||||
/* This one catches any method */
|
||||
TemplatedApp &&any(std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
TemplatedApp &&any(std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler) {
|
||||
if (httpContext) {
|
||||
httpContext->onHttp("*", pattern, std::move(handler));
|
||||
}
|
||||
@@ -565,8 +569,8 @@ public:
|
||||
}
|
||||
|
||||
/* Host, port, callback */
|
||||
TemplatedApp &&listen(std::string host, int port, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (!host.length()) {
|
||||
TemplatedApp &&listen(const std::string &host, int port, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (host.empty()) {
|
||||
return listen(port, std::move(handler));
|
||||
}
|
||||
handler(httpContext ? httpContext->listen(host.c_str(), port, 0) : nullptr);
|
||||
@@ -574,8 +578,8 @@ public:
|
||||
}
|
||||
|
||||
/* Host, port, options, callback */
|
||||
TemplatedApp &&listen(std::string host, int port, int options, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (!host.length()) {
|
||||
TemplatedApp &&listen(const std::string &host, int port, int options, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (host.empty()) {
|
||||
return listen(port, options, std::move(handler));
|
||||
}
|
||||
handler(httpContext ? httpContext->listen(host.c_str(), port, options) : nullptr);
|
||||
@@ -595,17 +599,21 @@ public:
|
||||
}
|
||||
|
||||
/* options, callback, path to unix domain socket */
|
||||
TemplatedApp &&listen(int options, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler, std::string path) {
|
||||
TemplatedApp &&listen(int options, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler, std::string_view path) {
|
||||
handler(httpContext ? httpContext->listen_unix(path.data(), path.length(), options) : nullptr);
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
/* callback, path to unix domain socket */
|
||||
TemplatedApp &&listen(MoveOnlyFunction<void(us_listen_socket_t *)> &&handler, std::string path, int options) {
|
||||
TemplatedApp &&listen(MoveOnlyFunction<void(us_listen_socket_t *)> &&handler, std::string_view path, int options) {
|
||||
handler(httpContext ? httpContext->listen_unix(path.data(), path.length(), options) : nullptr);
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
void setOnClose(HttpContextData<SSL>::OnSocketClosedCallback onClose) {
|
||||
httpContext->getSocketContextData()->onSocketClosed = onClose;
|
||||
}
|
||||
|
||||
TemplatedApp &&run() {
|
||||
uWS::run();
|
||||
return std::move(*this);
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "libusockets.h"
|
||||
#include "bun-usockets/src/internal/internal.h"
|
||||
|
||||
|
||||
|
||||
#include "LoopData.h"
|
||||
#include "AsyncSocketData.h"
|
||||
@@ -54,28 +57,6 @@ struct AsyncSocket {
|
||||
template <typename, typename> friend struct TopicTree;
|
||||
template <bool> friend struct HttpResponse;
|
||||
|
||||
private:
|
||||
/* Helper, do not use directly (todo: move to uSockets or de-crazify) */
|
||||
void throttle_helper(int toggle) {
|
||||
/* These should be exposed by uSockets */
|
||||
static thread_local int us_events[2] = {0, 0};
|
||||
|
||||
struct us_poll_t *p = (struct us_poll_t *) this;
|
||||
struct us_loop_t *loop = us_socket_context_loop(SSL, us_socket_context(SSL, (us_socket_t *) this));
|
||||
|
||||
if (toggle) {
|
||||
/* Pause */
|
||||
int events = us_poll_events(p);
|
||||
if (events) {
|
||||
us_events[getBufferedAmount() ? 1 : 0] = events;
|
||||
}
|
||||
us_poll_change(p, loop, 0);
|
||||
} else {
|
||||
/* Resume */
|
||||
int events = us_events[getBufferedAmount() ? 1 : 0];
|
||||
us_poll_change(p, loop, events);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/* Returns SSL pointer or FD as pointer */
|
||||
@@ -105,13 +86,13 @@ public:
|
||||
|
||||
/* Experimental pause */
|
||||
us_socket_t *pause() {
|
||||
throttle_helper(1);
|
||||
us_socket_pause(SSL, (us_socket_t *) this);
|
||||
return (us_socket_t *) this;
|
||||
}
|
||||
|
||||
/* Experimental resume */
|
||||
us_socket_t *resume() {
|
||||
throttle_helper(0);
|
||||
us_socket_resume(SSL, (us_socket_t *) this);
|
||||
return (us_socket_t *) this;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ struct BackPressure {
|
||||
/* Always erase a minimum of 1/32th the current backpressure */
|
||||
if (pendingRemoval > (buffer.length() >> 5)) {
|
||||
buffer.erase(0, pendingRemoval);
|
||||
buffer.shrink_to_fit();
|
||||
pendingRemoval = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@ namespace uWS {
|
||||
/* Reads hex number until CR or out of data to consume. Updates state. Returns bytes consumed. */
|
||||
inline void consumeHexNumber(std::string_view &data, uint64_t &state) {
|
||||
/* Consume everything higher than 32 */
|
||||
while (data.length() && data.data()[0] > 32) {
|
||||
while (data.length() && data[0] > 32) {
|
||||
|
||||
unsigned char digit = (unsigned char)data.data()[0];
|
||||
unsigned char digit = (unsigned char)data[0];
|
||||
if (digit >= 'a') {
|
||||
digit = (unsigned char) (digit - ('a' - ':'));
|
||||
} else if (digit >= 'A') {
|
||||
@@ -67,7 +67,7 @@ namespace uWS {
|
||||
data.remove_prefix(1);
|
||||
}
|
||||
/* Consume everything not /n */
|
||||
while (data.length() && data.data()[0] != '\n') {
|
||||
while (data.length() && data[0] != '\n') {
|
||||
data.remove_prefix(1);
|
||||
}
|
||||
/* Now we stand on \n so consume it and enable size */
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace uWS {
|
||||
//webSocketContext = WebSocketContext<0, false, int>::create();
|
||||
}
|
||||
|
||||
ClientApp &&connect(std::string url, std::string protocol = "") {
|
||||
ClientApp &&connect(std::string_view url, std::string_view protocol = "") {
|
||||
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ namespace uWS {
|
||||
}
|
||||
|
||||
/* Host, port, callback */
|
||||
H3App &&listen(std::string host, int port, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (!host.length()) {
|
||||
H3App &&listen(const std::string &host, int port, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (host.empty()) {
|
||||
return listen(port, std::move(handler));
|
||||
}
|
||||
handler(http3Context ? (us_listen_socket_t *) http3Context->listen(host.c_str(), port) : nullptr);
|
||||
@@ -42,8 +42,8 @@ namespace uWS {
|
||||
}
|
||||
|
||||
/* Host, port, options, callback */
|
||||
H3App &&listen(std::string host, int port, int options, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (!host.length()) {
|
||||
H3App &&listen(const std::string &host, int port, int options, MoveOnlyFunction<void(us_listen_socket_t *)> &&handler) {
|
||||
if (host.empty()) {
|
||||
return listen(port, options, std::move(handler));
|
||||
}
|
||||
handler(http3Context ? (us_listen_socket_t *) http3Context->listen(host.c_str(), port) : nullptr);
|
||||
@@ -62,63 +62,63 @@ namespace uWS {
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&get(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&get(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("GET", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&post(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&post(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("POST", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&options(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&options(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("OPTIONS", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&del(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&del(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("DELETE", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&patch(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&patch(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("PATCH", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&put(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&put(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("PUT", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&head(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&head(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("HEAD", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&connect(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&connect(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("CONNECT", pattern, std::move(handler));
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
H3App &&trace(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&trace(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("TRACE", pattern, std::move(handler));
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace uWS {
|
||||
}
|
||||
|
||||
/* This one catches any method */
|
||||
H3App &&any(std::string pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
H3App &&any(std::string_view pattern, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&handler) {
|
||||
if (http3Context) {
|
||||
http3Context->onHttp("*", pattern, std::move(handler));
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace uWS {
|
||||
us_quic_socket_context_on_stream_data(context, [](us_quic_stream_t *s, char *data, int length) {
|
||||
|
||||
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext(s);
|
||||
|
||||
|
||||
/* We never emit FIN here */
|
||||
if (responseData->onData) {
|
||||
responseData->onData({data, (size_t) length}, false);
|
||||
@@ -26,7 +26,7 @@ namespace uWS {
|
||||
us_quic_socket_context_on_stream_end(context, [](us_quic_stream_t *s) {
|
||||
|
||||
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext(s);
|
||||
|
||||
|
||||
/* Emit FIN to app */
|
||||
if (responseData->onData) {
|
||||
responseData->onData({nullptr, 0}, true);
|
||||
@@ -77,7 +77,7 @@ namespace uWS {
|
||||
|
||||
std::string_view upperCasedMethod = req->getHeader(":method");
|
||||
std::string_view path = req->getHeader(":path");
|
||||
|
||||
|
||||
contextData->router.getUserData() = {(Http3Response *) s, (Http3Request *) nullptr};
|
||||
contextData->router.route(upperCasedMethod, path);
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace uWS {
|
||||
//lsquic_stream_has_unacked_data
|
||||
|
||||
Http3ResponseData *responseData = (Http3ResponseData *) us_quic_stream_ext(s);
|
||||
|
||||
|
||||
if (responseData->onAborted) {
|
||||
responseData->onAborted();
|
||||
}
|
||||
@@ -130,9 +130,9 @@ namespace uWS {
|
||||
}
|
||||
|
||||
// generic for get, post, any, etc
|
||||
void onHttp(std::string method, std::string path, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&cb) {
|
||||
void onHttp(std::string_view method, std::string_view path, MoveOnlyFunction<void(Http3Response *, Http3Request *)> &&cb) {
|
||||
// modifies the router we own as part of Http3ContextData, used in callbacks set in init
|
||||
|
||||
|
||||
Http3ContextData *contextData = (Http3ContextData *) us_quic_socket_context_ext((us_quic_socket_context_t *) this);
|
||||
|
||||
/* Todo: This is ugly, fix */
|
||||
@@ -141,7 +141,7 @@ namespace uWS {
|
||||
methods = contextData->router.upperCasedMethods; //bug! needs to be upper cased!
|
||||
// router.upperCasedMethods;
|
||||
} else {
|
||||
methods = {method};
|
||||
methods = {std::string(method)};
|
||||
}
|
||||
|
||||
contextData->router.add(methods, path, [handler = std::move(cb)](HttpRouter<Http3ContextData::RouterData> *router) mutable {
|
||||
|
||||
@@ -66,14 +66,14 @@ private:
|
||||
|
||||
/* Init the HttpContext by registering libusockets event handlers */
|
||||
HttpContext<SSL> *init() {
|
||||
|
||||
|
||||
if(SSL) {
|
||||
// if we are SSL we need to handle the handshake properly
|
||||
us_socket_context_on_handshake(SSL, getSocketContext(), [](us_socket_t *s, int success, struct us_bun_verify_error_t verify_error, void* custom_data) {
|
||||
// if we are closing or already closed, we don't need to do anything
|
||||
if (!us_socket_is_closed(SSL, s) && !us_socket_is_shut_down(SSL, s)) {
|
||||
if (!us_socket_is_closed(SSL, s) && !us_socket_is_shut_down(SSL, s)) {
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
|
||||
|
||||
|
||||
if(httpContextData->rejectUnauthorized) {
|
||||
if(!success || verify_error.error != 0) {
|
||||
// we failed to handshake, close the socket
|
||||
@@ -92,7 +92,7 @@ private:
|
||||
}
|
||||
}, nullptr);
|
||||
}
|
||||
|
||||
|
||||
/* Handle socket connections */
|
||||
us_socket_context_on_open(SSL, getSocketContext(), [](us_socket_t *s, int /*is_client*/, char */*ip*/, int /*ip_length*/) {
|
||||
/* Init socket ext */
|
||||
@@ -115,9 +115,8 @@ private:
|
||||
us_socket_context_on_close(SSL, getSocketContext(), [](us_socket_t *s, int /*code*/, void */*reason*/) {
|
||||
((AsyncSocket<SSL> *)s)->uncorkWithoutSending();
|
||||
|
||||
|
||||
/* Get socket ext */
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_socket_ext(SSL, s);
|
||||
auto *httpResponseData = reinterpret_cast<HttpResponseData<SSL> *>(us_socket_ext(SSL, s));
|
||||
|
||||
/* Call filter */
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
|
||||
@@ -129,7 +128,10 @@ private:
|
||||
if (httpResponseData->onAborted) {
|
||||
httpResponseData->onAborted((HttpResponse<SSL> *)s, httpResponseData->userData);
|
||||
}
|
||||
|
||||
|
||||
if (httpResponseData->socketData && httpContextData->onSocketClosed) {
|
||||
httpContextData->onSocketClosed(httpResponseData->socketData, SSL, s);
|
||||
}
|
||||
|
||||
/* Destruct socket ext */
|
||||
httpResponseData->~HttpResponseData<SSL>();
|
||||
@@ -171,7 +173,7 @@ private:
|
||||
proxyParser = &httpResponseData->proxyParser;
|
||||
#endif
|
||||
|
||||
/* The return value is entirely up to us to interpret. The HttpParser only care for whether the returned value is DIFFERENT or not from passed user */
|
||||
/* The return value is entirely up to us to interpret. The HttpParser cares only for whether the returned value is DIFFERENT from passed user */
|
||||
auto [err, returnedSocket] = httpResponseData->consumePostPadded(data, (unsigned int) length, s, proxyParser, [httpContextData](void *s, HttpRequest *httpRequest) -> void * {
|
||||
/* For every request we reset the timeout and hang until user makes action */
|
||||
/* Warning: if we are in shutdown state, resetting the timer is a security issue! */
|
||||
@@ -182,7 +184,7 @@ private:
|
||||
httpResponseData->offset = 0;
|
||||
|
||||
/* Are we not ready for another request yet? Terminate the connection.
|
||||
* Important for denying async pipelining until, if ever, we want to suppot it.
|
||||
* Important for denying async pipelining until, if ever, we want to support it.
|
||||
* Otherwise requests can get mixed up on the same connection. We still support sync pipelining. */
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) {
|
||||
us_socket_close(SSL, (us_socket_t *) s, 0, nullptr);
|
||||
@@ -221,7 +223,7 @@ private:
|
||||
}
|
||||
|
||||
/* Was the socket closed? */
|
||||
if (us_socket_is_closed(SSL, (struct us_socket_t *) s)) {
|
||||
if (us_socket_is_closed(SSL, (us_socket_t *) s)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -377,7 +379,7 @@ private:
|
||||
return s;
|
||||
}
|
||||
|
||||
/* We need to drain any remaining buffered data if success == true*/
|
||||
/* We need to drain any remaining buffered data if success == true*/
|
||||
}
|
||||
|
||||
/* Drain any socket buffer, this might empty our backpressure and thus finish the request */
|
||||
@@ -416,7 +418,7 @@ private:
|
||||
|
||||
/* Force close rather than gracefully shutdown and risk confusing the client with a complete download */
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
// Node.js by default sclose the connection but they emit the timeout event before that
|
||||
// Node.js by default closes the connection but they emit the timeout event before that
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getAsyncSocketData();
|
||||
|
||||
if (httpResponseData->onTimeout) {
|
||||
@@ -441,7 +443,7 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
// for servers this is only valid when request cert is enabled
|
||||
|
||||
|
||||
/* Init socket context data */
|
||||
auto* httpContextData = new ((HttpContextData<SSL> *) us_socket_context_ext(SSL, (us_socket_context_t *) httpContext)) HttpContextData<SSL>();
|
||||
if(options.request_cert && options.reject_unauthorized) {
|
||||
@@ -465,16 +467,10 @@ public:
|
||||
}
|
||||
|
||||
/* Register an HTTP route handler acording to URL pattern */
|
||||
void onHttp(std::string method, std::string pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler, bool upgrade = false) {
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextData();
|
||||
void onHttp(std::string_view method, std::string_view pattern, MoveOnlyFunction<void(HttpResponse<SSL> *, HttpRequest *)> &&handler, bool upgrade = false) {
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextData();
|
||||
|
||||
/* Todo: This is ugly, fix */
|
||||
std::vector<std::string> methods;
|
||||
if (method == "*") {
|
||||
methods = {"*"};
|
||||
} else {
|
||||
methods = {method};
|
||||
}
|
||||
std::vector<std::string> methods{std::string(method)};
|
||||
|
||||
uint32_t priority = method == "*" ? httpContextData->currentRouter->LOW_PRIORITY : (upgrade ? httpContextData->currentRouter->HIGH_PRIORITY : httpContextData->currentRouter->MEDIUM_PRIORITY);
|
||||
|
||||
@@ -495,7 +491,6 @@ public:
|
||||
i++;
|
||||
}
|
||||
parameterOffsets[std::string(pattern.data() + start, i - start)] = offset;
|
||||
//std::cout << "<" << std::string(pattern.data() + start, i - start) << "> is offset " << offset;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
@@ -529,7 +524,7 @@ public:
|
||||
// we dont depend on libuv ref for keeping it alive
|
||||
if (socket) {
|
||||
us_socket_unref(&socket->s);
|
||||
}
|
||||
}
|
||||
return socket;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace uWS {
|
||||
template<bool> struct HttpResponse;
|
||||
struct HttpRequest;
|
||||
|
||||
|
||||
template <bool SSL>
|
||||
struct alignas(16) HttpContextData {
|
||||
template <bool> friend struct HttpContext;
|
||||
@@ -34,6 +35,7 @@ struct alignas(16) HttpContextData {
|
||||
template <bool> friend struct TemplatedApp;
|
||||
private:
|
||||
std::vector<MoveOnlyFunction<void(HttpResponse<SSL> *, int)>> filterHandlers;
|
||||
using OnSocketClosedCallback = void (*)(void* userData, int is_ssl, struct us_socket_t *rawSocket);
|
||||
|
||||
MoveOnlyFunction<void(const char *hostname)> missingServerNameHandler;
|
||||
|
||||
@@ -51,6 +53,9 @@ private:
|
||||
bool isParsingHttp = false;
|
||||
bool rejectUnauthorized = false;
|
||||
|
||||
/* Used to simulate Node.js socket events. */
|
||||
OnSocketClosedCallback onSocketClosed = nullptr;
|
||||
|
||||
// TODO: SNI
|
||||
void clearRoutes() {
|
||||
this->router = HttpRouter<RouterData>{};
|
||||
|
||||
@@ -141,13 +141,13 @@ namespace uWS
|
||||
|
||||
std::string_view getFullUrl()
|
||||
{
|
||||
return std::string_view(headers->value.data(), headers->value.length());
|
||||
return headers->value;
|
||||
}
|
||||
|
||||
/* Hack: this should be getMethod */
|
||||
std::string_view getCaseSensitiveMethod()
|
||||
{
|
||||
return std::string_view(headers->key.data(), headers->key.length());
|
||||
return headers->key;
|
||||
}
|
||||
|
||||
std::string_view getMethod()
|
||||
@@ -158,7 +158,7 @@ namespace uWS
|
||||
((char *)headers->key.data())[i] |= 32;
|
||||
}
|
||||
|
||||
return std::string_view(headers->key.data(), headers->key.length());
|
||||
return headers->key;
|
||||
}
|
||||
|
||||
/* Returns the raw querystring as a whole, still encoded */
|
||||
@@ -167,7 +167,7 @@ namespace uWS
|
||||
if (querySeparator < headers->value.length())
|
||||
{
|
||||
/* Strip the initial ? */
|
||||
return std::string_view(headers->value.data() + querySeparator + 1, headers->value.length() - querySeparator - 1);
|
||||
return headers->value.substr(querySeparator + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -179,9 +179,7 @@ namespace uWS
|
||||
std::string_view getQuery(std::string_view key)
|
||||
{
|
||||
/* Raw querystring including initial '?' sign */
|
||||
std::string_view queryString = std::string_view(headers->value.data() + querySeparator, headers->value.length() - querySeparator);
|
||||
|
||||
return getDecodedQueryValue(key, queryString);
|
||||
return getDecodedQueryValue(key, headers->value.substr(querySeparator));
|
||||
}
|
||||
|
||||
void setParameters(std::pair<int, std::string_view *> parameters)
|
||||
@@ -241,7 +239,7 @@ namespace uWS
|
||||
}
|
||||
return unsignedIntegerValue;
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t hasLess(uint64_t x, uint64_t n) {
|
||||
return (((x)-~0ULL/255*(n))&~(x)&~0ULL/255*128);
|
||||
}
|
||||
@@ -285,7 +283,7 @@ namespace uWS
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline void *consumeFieldName(char *p) {
|
||||
/* Best case fast path (particularly useful with clang) */
|
||||
while (true) {
|
||||
@@ -325,14 +323,14 @@ namespace uWS
|
||||
|
||||
uint64_t http;
|
||||
__builtin_memcpy(&http, data, sizeof(uint64_t));
|
||||
|
||||
|
||||
uint32_t first_four_bytes = http & static_cast<uint32_t>(0xFFFFFFFF);
|
||||
// check if any of the first four bytes are > non-ascii
|
||||
if ((first_four_bytes & 0x80808080) != 0) [[unlikely]] {
|
||||
return 0;
|
||||
}
|
||||
first_four_bytes |= 0x20202020; // Lowercase the first four bytes
|
||||
|
||||
|
||||
static constexpr char http_lowercase_bytes[4] = {'h', 't', 't', 'p'};
|
||||
static constexpr uint32_t http_lowercase_bytes_int = __builtin_bit_cast(uint32_t, http_lowercase_bytes);
|
||||
if (first_four_bytes == http_lowercase_bytes_int) [[likely]] {
|
||||
@@ -345,7 +343,7 @@ namespace uWS
|
||||
|
||||
static constexpr char S_colon_slash_slash[4] = {'S', ':', '/', '/'};
|
||||
static constexpr uint32_t S_colon_slash_slash_int = __builtin_bit_cast(uint32_t, S_colon_slash_slash);
|
||||
|
||||
|
||||
// Extract the last four bytes from the uint64_t
|
||||
const uint32_t last_four_bytes = (http >> 32) & static_cast<uint32_t>(0xFFFFFFFF);
|
||||
return (last_four_bytes == s_colon_slash_slash_int) || (last_four_bytes == S_colon_slash_slash_int);
|
||||
@@ -363,7 +361,7 @@ namespace uWS
|
||||
if (&data[1] == end) [[unlikely]] {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (data[0] == 32 && (__builtin_expect(data[1] == '/', 1) || isHTTPorHTTPSPrefixForProxies(data + 1, end) == 1)) [[likely]] {
|
||||
header.key = {start, (size_t) (data - start)};
|
||||
data++;
|
||||
@@ -538,7 +536,7 @@ namespace uWS
|
||||
while (headers->value.length() && headers->value.front() < 33) {
|
||||
headers->value.remove_prefix(1);
|
||||
}
|
||||
|
||||
|
||||
headers++;
|
||||
|
||||
/* We definitely have at least one header (or request line), so check if we are done */
|
||||
@@ -569,7 +567,7 @@ namespace uWS
|
||||
* From here we return either [consumed, user] for "keep going",
|
||||
* or [consumed, nullptr] for "break; I am closed or upgraded to websocket"
|
||||
* or [whatever, fullptr] for "break and close me, I am a parser error!" */
|
||||
template <int CONSUME_MINIMALLY>
|
||||
template <bool ConsumeMinimally>
|
||||
std::pair<unsigned int, void *> fenceAndConsumePostPadded(char *data, unsigned int length, void *user, void *reserved, HttpRequest *req, MoveOnlyFunction<void *(void *, HttpRequest *)> &requestHandler, MoveOnlyFunction<void *(void *, std::string_view, bool)> &dataHandler) {
|
||||
|
||||
/* How much data we CONSUMED (to throw away) */
|
||||
@@ -600,7 +598,7 @@ namespace uWS
|
||||
for (HttpRequest::Header *h = req->headers; (++h)->key.length(); ) {
|
||||
req->bf.add(h->key);
|
||||
}
|
||||
|
||||
|
||||
/* Break if no host header (but we can have empty string which is different from nullptr) */
|
||||
if (!req->getHeader("host").data()) {
|
||||
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
|
||||
@@ -613,11 +611,12 @@ namespace uWS
|
||||
* ought to be handled as an error. */
|
||||
std::string_view transferEncodingString = req->getHeader("transfer-encoding");
|
||||
std::string_view contentLengthString = req->getHeader("content-length");
|
||||
|
||||
auto transferEncodingStringLen = transferEncodingString.length();
|
||||
auto contentLengthStringLen = contentLengthString.length();
|
||||
if (transferEncodingStringLen && contentLengthStringLen) {
|
||||
/* Returning fullptr is the same as calling the errorHandler */
|
||||
/* We could be smart and set an error in the context along with this, to indicate what
|
||||
/* We could be smart and set an error in the context along with this, to indicate what
|
||||
* http error response we might want to return */
|
||||
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
|
||||
}
|
||||
@@ -625,7 +624,7 @@ namespace uWS
|
||||
/* Parse query */
|
||||
const char *querySeparatorPtr = (const char *) memchr(req->headers->value.data(), '?', req->headers->value.length());
|
||||
req->querySeparator = (unsigned int) ((querySeparatorPtr ? querySeparatorPtr : req->headers->value.data() + req->headers->value.length()) - req->headers->value.data());
|
||||
|
||||
|
||||
// lets check if content len is valid before calling requestHandler
|
||||
if(contentLengthStringLen) {
|
||||
remainingStreamingBytes = toUnsignedInteger(contentLengthString);
|
||||
@@ -635,6 +634,14 @@ namespace uWS
|
||||
}
|
||||
}
|
||||
|
||||
// lets check if content len is valid before calling requestHandler
|
||||
if(contentLengthStringLen) {
|
||||
remainingStreamingBytes = toUnsignedInteger(contentLengthString);
|
||||
if (remainingStreamingBytes == UINT64_MAX) {
|
||||
/* Parser error */
|
||||
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
|
||||
}
|
||||
}
|
||||
/* If returned socket is not what we put in we need
|
||||
* to break here as we either have upgraded to
|
||||
* WebSockets or otherwise closed the socket. */
|
||||
@@ -656,7 +663,7 @@ namespace uWS
|
||||
if (transferEncodingStringLen) {
|
||||
|
||||
/* If a proxy sent us the transfer-encoding header that 100% means it must be chunked or else the proxy is
|
||||
* not RFC 9112 compliant. Therefore it is always better to assume this is the case, since that entirely eliminates
|
||||
* not RFC 9112 compliant. Therefore it is always better to assume this is the case, since that entirely eliminates
|
||||
* all forms of transfer-encoding obfuscation tricks. We just rely on the header. */
|
||||
|
||||
/* RFC 9112 6.3
|
||||
@@ -669,7 +676,7 @@ namespace uWS
|
||||
|
||||
remainingStreamingBytes = STATE_IS_CHUNKED;
|
||||
/* If consume minimally, we do not want to consume anything but we want to mark this as being chunked */
|
||||
if (!CONSUME_MINIMALLY) {
|
||||
if constexpr (!ConsumeMinimally) {
|
||||
/* Go ahead and parse it (todo: better heuristics for emitting FIN to the app level) */
|
||||
std::string_view dataToConsume(data, length);
|
||||
for (auto chunk : uWS::ChunkIterator(&dataToConsume, &remainingStreamingBytes)) {
|
||||
@@ -685,8 +692,7 @@ namespace uWS
|
||||
consumedTotal += consumed;
|
||||
}
|
||||
} else if (contentLengthStringLen) {
|
||||
|
||||
if (!CONSUME_MINIMALLY) {
|
||||
if constexpr (!ConsumeMinimally) {
|
||||
unsigned int emittable = (unsigned int) std::min<uint64_t>(remainingStreamingBytes, length);
|
||||
dataHandler(user, std::string_view(data, emittable), emittable == remainingStreamingBytes);
|
||||
remainingStreamingBytes -= emittable;
|
||||
@@ -701,7 +707,7 @@ namespace uWS
|
||||
}
|
||||
|
||||
/* Consume minimally should break as easrly as possible */
|
||||
if (CONSUME_MINIMALLY) {
|
||||
if constexpr (ConsumeMinimally) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,12 @@ public:
|
||||
|
||||
/* Called only once per request */
|
||||
void writeMark() {
|
||||
if (getHttpResponseData()->state & HttpResponseData<SSL>::HTTP_WROTE_DATE_HEADER) {
|
||||
return;
|
||||
}
|
||||
/* Date is always written */
|
||||
writeHeader("Date", std::string_view(((LoopData *) us_loop_ext(us_socket_context_loop(SSL, (us_socket_context(SSL, (us_socket_t *) this)))))->date, 29));
|
||||
getHttpResponseData()->state |= HttpResponseData<SSL>::HTTP_WROTE_DATE_HEADER;
|
||||
}
|
||||
|
||||
/* Returns true on success, indicating that it might be feasible to write more data.
|
||||
@@ -113,7 +117,8 @@ public:
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE;
|
||||
}
|
||||
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED) {
|
||||
/* if write was called and there was previously no Content-Length header set */
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED && !(httpResponseData->state & HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER)) {
|
||||
|
||||
/* We do not have tryWrite-like functionalities, so ignore optional in this path */
|
||||
|
||||
@@ -145,6 +150,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->uncork();
|
||||
}
|
||||
|
||||
/* tryEnd can never fail when in chunked mode, since we do not have tryWrite (yet), only write */
|
||||
@@ -152,7 +159,7 @@ public:
|
||||
return true;
|
||||
} else {
|
||||
/* Write content-length on first call */
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_END_CALLED)) {
|
||||
if (!(httpResponseData->state & (HttpResponseData<SSL>::HTTP_END_CALLED))) {
|
||||
/* Write mark, this propagates to WebSockets too */
|
||||
writeMark();
|
||||
|
||||
@@ -162,7 +169,8 @@ public:
|
||||
Super::write("Content-Length: ", 16);
|
||||
writeUnsigned64(totalSize);
|
||||
Super::write("\r\n\r\n", 4);
|
||||
} else {
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER;
|
||||
} else if (!(httpResponseData->state & (HttpResponseData<SSL>::HTTP_WRITE_CALLED))) {
|
||||
Super::write("\r\n", 2);
|
||||
}
|
||||
|
||||
@@ -207,6 +215,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->uncork();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +241,7 @@ public:
|
||||
/* Manually upgrade to WebSocket. Typically called in upgrade handler. Immediately calls open handler.
|
||||
* NOTE: Will invalidate 'this' as socket might change location in memory. Throw away after use. */
|
||||
template <typename UserData>
|
||||
void upgrade(UserData &&userData, std::string_view secWebSocketKey, std::string_view secWebSocketProtocol,
|
||||
us_socket_t *upgrade(UserData &&userData, std::string_view secWebSocketKey, std::string_view secWebSocketProtocol,
|
||||
std::string_view secWebSocketExtensions,
|
||||
struct us_socket_context_t *webSocketContext) {
|
||||
|
||||
@@ -313,8 +323,8 @@ public:
|
||||
bool wasCorked = Super::isCorked();
|
||||
|
||||
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */
|
||||
WebSocket<SSL, true, UserData> *webSocket = (WebSocket<SSL, true, UserData> *) us_socket_context_adopt_socket(SSL,
|
||||
(us_socket_context_t *) webSocketContext, (us_socket_t *) this, sizeof(WebSocketData) + sizeof(UserData));
|
||||
us_socket_t *usSocket = us_socket_context_adopt_socket(SSL, (us_socket_context_t *) webSocketContext, (us_socket_t *) this, sizeof(WebSocketData) + sizeof(UserData));
|
||||
WebSocket<SSL, true, UserData> *webSocket = (WebSocket<SSL, true, UserData> *) usSocket;
|
||||
|
||||
/* For whatever reason we were corked, update cork to the new socket */
|
||||
if (wasCorked) {
|
||||
@@ -344,6 +354,8 @@ public:
|
||||
if (webSocketContextData->openHandler) {
|
||||
webSocketContextData->openHandler(webSocket);
|
||||
}
|
||||
|
||||
return usSocket;
|
||||
}
|
||||
|
||||
/* Immediately terminate this Http response */
|
||||
@@ -427,7 +439,7 @@ public:
|
||||
|
||||
/* End the response with an optional data chunk. Always starts a timeout. */
|
||||
void end(std::string_view data = {}, bool closeConnection = false) {
|
||||
internalEnd(data, data.length(), false, true, closeConnection);
|
||||
internalEnd(data, data.length(), false, !(this->getHttpResponseData()->state & HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER), closeConnection);
|
||||
}
|
||||
|
||||
/* Try and end the response. Returns [true, true] on success.
|
||||
@@ -441,12 +453,12 @@ public:
|
||||
bool sendTerminatingChunk(bool closeConnection = false) {
|
||||
writeStatus(HTTP_200_OK);
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
if (!(httpResponseData->state & (HttpResponseData<SSL>::HTTP_WRITE_CALLED | HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER))) {
|
||||
/* Write mark on first call to write */
|
||||
writeMark();
|
||||
|
||||
writeHeader("Transfer-Encoding", "chunked");
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
}
|
||||
|
||||
/* This will be sent always when state is HTTP_WRITE_CALLED inside internalEnd, so no need to write the terminating 0 chunk here */
|
||||
@@ -456,33 +468,46 @@ public:
|
||||
}
|
||||
|
||||
/* Write parts of the response in chunking fashion. Starts timeout if failed. */
|
||||
bool write(std::string_view data) {
|
||||
bool write(std::string_view data, size_t *writtenPtr = nullptr) {
|
||||
writeStatus(HTTP_200_OK);
|
||||
|
||||
/* Do not allow sending 0 chunks, they mark end of response */
|
||||
if (!data.length()) {
|
||||
if (data.empty()) {
|
||||
if (writtenPtr) {
|
||||
*writtenPtr = 0;
|
||||
}
|
||||
/* If you called us, then according to you it was fine to call us so it's fine to still call us */
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
/* Write mark on first call to write */
|
||||
writeMark();
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER)) {
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
/* Write mark on first call to write */
|
||||
writeMark();
|
||||
|
||||
writeHeader("Transfer-Encoding", "chunked");
|
||||
writeHeader("Transfer-Encoding", "chunked");
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
}
|
||||
|
||||
Super::write("\r\n", 2);
|
||||
writeUnsignedHex((unsigned int) data.length());
|
||||
Super::write("\r\n", 2);
|
||||
} else if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
writeMark();
|
||||
Super::write("\r\n", 2);
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
}
|
||||
|
||||
Super::write("\r\n", 2);
|
||||
writeUnsignedHex((unsigned int) data.length());
|
||||
Super::write("\r\n", 2);
|
||||
|
||||
auto [written, failed] = Super::write(data.data(), (int) data.length());
|
||||
/* Reset timeout on each sended chunk */
|
||||
this->resetTimeout();
|
||||
|
||||
if (writtenPtr) {
|
||||
*writtenPtr = written;
|
||||
}
|
||||
|
||||
/* If we did not fail the write, accept more */
|
||||
return !failed;
|
||||
}
|
||||
@@ -515,7 +540,7 @@ public:
|
||||
Super::cork();
|
||||
handler();
|
||||
|
||||
/* The only way we could possibly have changed the corked socket during handler call, would be if
|
||||
/* The only way we could possibly have changed the corked socket during handler call, would be if
|
||||
* the HTTP socket was upgraded to WebSocket and caused a realloc. Because of this we cannot use "this"
|
||||
* from here downwards. The corking is done with corkUnchecked() in upgrade. It steals cork. */
|
||||
auto *newCorkedSocket = loopData->getCorkedSocket();
|
||||
@@ -582,7 +607,7 @@ public:
|
||||
/* Attach handler for aborted HTTP request */
|
||||
HttpResponse *onAborted(void* userData, HttpResponseData<SSL>::OnAbortedCallback handler) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
|
||||
httpResponseData->userData = userData;
|
||||
httpResponseData->onAborted = handler;
|
||||
return this;
|
||||
@@ -590,7 +615,7 @@ public:
|
||||
|
||||
HttpResponse *onTimeout(void* userData, HttpResponseData<SSL>::OnTimeoutCallback handler) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
|
||||
httpResponseData->userData = userData;
|
||||
httpResponseData->onTimeout = handler;
|
||||
return this;
|
||||
@@ -620,7 +645,7 @@ public:
|
||||
return this;
|
||||
}
|
||||
/* Attach a read handler for data sent. Will be called with FIN set true if last segment. */
|
||||
void onData(void* userData, HttpResponseData<SSL>::OnDataCallback handler) {
|
||||
void onData(void* userData, HttpResponseData<SSL>::OnDataCallback handler) {
|
||||
HttpResponseData<SSL> *data = getHttpResponseData();
|
||||
data->userData = userData;
|
||||
data->inStream = handler;
|
||||
@@ -629,6 +654,17 @@ public:
|
||||
data->received_bytes_per_timeout = 0;
|
||||
}
|
||||
|
||||
void* getSocketData() {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
return httpResponseData->socketData;
|
||||
}
|
||||
|
||||
void setSocketData(void* socketData) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
httpResponseData->socketData = socketData;
|
||||
}
|
||||
|
||||
void setWriteOffset(uint64_t offset) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user