Skip to content

Commit

Permalink
Merge branch 'main' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
source-c authored Oct 10, 2024
2 parents 1e8794b + 05f68d7 commit 4a7090e
Show file tree
Hide file tree
Showing 12 changed files with 306 additions and 145 deletions.
2 changes: 1 addition & 1 deletion cmake/tools/SetupWebKit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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 0a0a3838e5fab36b579df26620237bb62ed6d950)
set(WEBKIT_VERSION 019ff6e1e879ff4533f2a857cab5028b6b95ab53)
endif()

if(WEBKIT_LOCAL)
Expand Down
24 changes: 24 additions & 0 deletions docs/runtime/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ If `exports` is not defined, Bun falls back to `"module"` (ESM imports only) the
}
```

### Custom conditions

The `--conditions` flag allows you to specify a list of conditions to use when resolving packages from package.json `"exports"`.

This flag is supported in both `bun build` and Bun's runtime.

```sh
# Use it with bun build:
$ bun build --conditions="react-server" --target=bun ./app/foo/route.js

# Use it with bun's runtime:
$ bun --conditions="react-server" ./app/foo/route.js
```

You can also use `conditions` programmatically with `Bun.build`:

```js
await Bun.build({
conditions: ["react-server"],
target: "bun",
entryPoints: ["./app/foo/route.js"],
});
```

## Path re-mapping

In the spirit of treating TypeScript as a first-class citizen, the Bun runtime will re-map import paths according to the [`compilerOptions.paths`](https://www.typescriptlang.org/tsconfig#paths) field in `tsconfig.json`. This is a major divergence from Node.js, which doesn't support any form of import path re-mapping.
Expand Down
2 changes: 1 addition & 1 deletion packages/bun-types/bun.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3961,7 +3961,7 @@ declare module "bun" {
*
* In a future version of Bun, this will be used in error messages.
*/
name?: string;
name: string;

/**
* The target JavaScript environment the plugin should be applied to.
Expand Down
178 changes: 51 additions & 127 deletions src/bun.js/bindings/napi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1300,66 +1300,73 @@ napi_define_properties(napi_env env, napi_value object, size_t property_count,
return napi_ok;
}

static void throwErrorWithCode(JSC::JSGlobalObject* globalObject, const char* msg_utf8, const char* code_utf8, const WTF::Function<JSObject*(JSC::JSGlobalObject*, const WTF::String&)>& createError)
static JSC::ErrorInstance* createErrorWithCode(JSC::JSGlobalObject* globalObject, const WTF::String& code, const WTF::String& message, JSC::ErrorType type)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
// no napi functions permit a null message, they must check before calling this function and
// return the right error code
ASSERT(!message.isNull());

auto message = msg_utf8 ? WTF::String::fromUTF8(msg_utf8) : String();
auto code = msg_utf8 ? WTF::String::fromUTF8(code_utf8) : String();
auto& vm = globalObject->vm();

auto* error = createError(globalObject, message);
if (!code.isEmpty()) {
// we don't call JSC::createError() as it asserts the message is not an empty string ""
auto* error = JSC::ErrorInstance::create(globalObject->vm(), globalObject->errorStructure(type), message, JSValue(), nullptr, RuntimeType::TypeNothing, type);
if (!code.isNull()) {
error->putDirect(vm, WebCore::builtinNames(vm).codePublicName(), JSC::jsString(vm, code), 0);
}

scope.throwException(globalObject, Exception::create(vm, error));
return error;
}

static JSValue createErrorForNapi(napi_env env, napi_value code, napi_value msg, const WTF::Function<JSObject*(JSC::JSGlobalObject*, const WTF::String&)>& constructor)
// used to implement napi_throw_*_error
static napi_status throwErrorWithCStrings(napi_env env, const char* code_utf8, const char* msg_utf8, JSC::ErrorType type)
{
auto* globalObject = toJS(env);
JSC::VM& vm = globalObject->vm();
auto catchScope = DECLARE_CATCH_SCOPE(vm);

JSValue codeValue = toJS(code);
WTF::String message;
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

if (msg) {
JSValue messageValue = toJS(msg);
message = messageValue.toWTFString(globalObject);
if (catchScope.exception()) {
catchScope.clearException();
return {};
}
if (!msg_utf8) {
return napi_invalid_arg;
}

auto* error = constructor(globalObject, message);
WTF::String code = code_utf8 ? WTF::String::fromUTF8(code_utf8) : WTF::String();
WTF::String message = WTF::String::fromUTF8(msg_utf8);

if (codeValue && error) {
error->putDirect(vm, WebCore::builtinNames(vm).codePublicName(), codeValue, 0);
}
auto* error = createErrorWithCode(globalObject, code, message, type);
scope.throwException(globalObject, error);
return napi_ok;
}

if (catchScope.exception()) {
catchScope.clearException();
return {};
// code must be a string or nullptr (no code)
// msg must be a string
// never calls toString, never throws
static napi_status createErrorWithNapiValues(napi_env env, napi_value code, napi_value message, JSC::ErrorType type, napi_value* result)
{
if (!result || !message) {
return napi_invalid_arg;
}
JSValue js_code = toJS(code);
JSValue js_message = toJS(message);
if (!js_message.isString() || !(js_code.isEmpty() || js_code.isString())) {
return napi_string_expected;
}

return error;
auto* globalObject = toJS(env);

auto wtf_code = js_code.isEmpty() ? WTF::String() : js_code.getString(globalObject);
auto wtf_message = js_message.getString(globalObject);

*result = toNapi(
createErrorWithCode(globalObject, wtf_code, wtf_message, type),
globalObject);
return napi_ok;
}

extern "C" napi_status napi_throw_error(napi_env env,
const char* code,
const char* msg)
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);

throwErrorWithCode(globalObject, msg, code, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
return JSC::createError(globalObject, message);
});

return napi_ok;
return throwErrorWithCStrings(env, code, msg, JSC::ErrorType::Error);
}

extern "C" napi_status napi_create_reference(napi_env env, napi_value value,
Expand Down Expand Up @@ -1650,110 +1657,44 @@ extern "C" napi_status node_api_create_syntax_error(napi_env env,
napi_value* result)
{
NAPI_PREMABLE
if (UNLIKELY(!result)) {
return napi_invalid_arg;
}

auto err = createErrorForNapi(env, code, msg, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
return JSC::createSyntaxError(globalObject, message);
});

if (UNLIKELY(!err)) {
return napi_generic_failure;
}

*result = toNapi(err, toJS(env));
return napi_ok;
return createErrorWithNapiValues(env, code, msg, JSC::ErrorType::SyntaxError, result);
}

extern "C" napi_status node_api_throw_syntax_error(napi_env env,
const char* code,
const char* msg)
{
NAPI_PREMABLE

auto globalObject = toJS(env);

throwErrorWithCode(globalObject, msg, code, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
return JSC::createSyntaxError(globalObject, message);
});

return napi_ok;
return throwErrorWithCStrings(env, code, msg, JSC::ErrorType::SyntaxError);
}

extern "C" napi_status napi_throw_type_error(napi_env env, const char* code,
const char* msg)
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);

throwErrorWithCode(globalObject, msg, code, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
return JSC::createTypeError(globalObject, message);
});

return napi_ok;
return throwErrorWithCStrings(env, code, msg, JSC::ErrorType::TypeError);
}

extern "C" napi_status napi_create_type_error(napi_env env, napi_value code,
napi_value msg,
napi_value* result)
{
if (UNLIKELY(!result || !env)) {
return napi_invalid_arg;
}

auto err = createErrorForNapi(env, code, msg, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
if (message.isEmpty()) {
return JSC::createTypeError(globalObject);
}

return JSC::createTypeError(globalObject, message);
});

if (UNLIKELY(!err)) {
return napi_generic_failure;
}

*result = toNapi(err, toJS(env));
return napi_ok;
NAPI_PREMABLE
return createErrorWithNapiValues(env, code, msg, JSC::ErrorType::TypeError, result);
}

extern "C" napi_status napi_create_error(napi_env env, napi_value code,
napi_value msg,
napi_value* result)
{
NAPI_PREMABLE

if (UNLIKELY(!result)) {
return napi_invalid_arg;
}

auto err = createErrorForNapi(env, code, msg, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
if (message.isEmpty()) {
return JSC::createError(globalObject, String("Error"_s));
}

return JSC::createError(globalObject, message);
});

if (UNLIKELY(!err)) {
return napi_generic_failure;
}

*result = toNapi(err, toJS(env));
return napi_ok;
return createErrorWithNapiValues(env, code, msg, JSC::ErrorType::Error, result);
}
extern "C" napi_status napi_throw_range_error(napi_env env, const char* code,
const char* msg)
{
NAPI_PREMABLE
Zig::GlobalObject* globalObject = toJS(env);

throwErrorWithCode(globalObject, msg, code, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
return JSC::createRangeError(globalObject, message);
});

return napi_ok;
return throwErrorWithCStrings(env, code, msg, JSC::ErrorType::RangeError);
}

extern "C" napi_status napi_object_freeze(napi_env env, napi_value object_value)
Expand Down Expand Up @@ -1818,24 +1759,7 @@ extern "C" napi_status napi_create_range_error(napi_env env, napi_value code,
napi_value* result)
{
NAPI_PREMABLE

if (UNLIKELY(!result)) {
return napi_invalid_arg;
}

auto err = createErrorForNapi(env, code, msg, [](JSC::JSGlobalObject* globalObject, const WTF::String& message) {
if (message.isEmpty()) {
return JSC::createRangeError(globalObject, String("Range error"_s));
}

return JSC::createRangeError(globalObject, message);
});

if (UNLIKELY(!err)) {
return napi_generic_failure;
}
*result = toNapi(err, toJS(env));
return napi_ok;
return createErrorWithNapiValues(env, code, msg, JSC::ErrorType::RangeError, result);
}

extern "C" napi_status napi_get_new_target(napi_env env,
Expand Down
Binary file modified test/bun.lockb
Binary file not shown.
40 changes: 40 additions & 0 deletions test/integration/sass/__snapshots__/sass.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Bun Snapshot v1, https://goo.gl/fbAQLP

exports[`sass source maps 1`] = `
{
"css":
".ruleGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.5rem;
border-width: 1px;
}"
,
"loadedUrls": [],
}
`;

exports[`sass source maps 2`] = `
{
"css":
".ruleGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.5rem;
border-width: 1px;
}"
,
"loadedUrls": [],
"sourceMap": {
"mappings": "AAAA;EACI;EACA;EACA;EACA;EACA",
"names": [],
"sourceRoot": "",
"sources": [
"data:;charset=utf-8,.ruleGroup%20%7B%0A%20%20%20%20display:%20flex;%0A%20%20%20%20flex-direction:%20column;%0A%20%20%20%20gap:%200.5rem;%0A%20%20%20%20padding:%200.5rem;%0A%20%20%20%20border-width:%201px;%0A%20%20%7D%0A%20%20",
],
"version": 3,
},
}
`;
15 changes: 15 additions & 0 deletions test/integration/sass/sass.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { compileString } from "sass";

test("sass source maps", () => {
const scssString = `.ruleGroup {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.5rem;
border-width: 1px;
}
`;

expect(compileString(scssString, { sourceMap: false })).toMatchSnapshot();
expect(compileString(scssString, { sourceMap: true })).toMatchSnapshot();
});
Loading

0 comments on commit 4a7090e

Please sign in to comment.