Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 40 additions & 21 deletions src/runtime/bake/bake_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,21 @@ impl UserOptions {
}

if let Some(js_options) = get_optional_value(config, global, b"bundlerOptions")? {
if !js_options.is_object() {
return Err(global.throw_invalid_arguments(format_args!(
"Expected 'bundlerOptions' to be an object"
)));
}
if let Some(server_options) = get_optional_value(js_options, global, b"server")? {
bundler_options.server = BuildConfigSubset::from_js(global, server_options)?;
bundler_options.server =
BuildConfigSubset::from_js(global, server_options, "server")?;
}
if let Some(client_options) = get_optional_value(js_options, global, b"client")? {
bundler_options.client = BuildConfigSubset::from_js(global, client_options)?;
bundler_options.client =
BuildConfigSubset::from_js(global, client_options, "client")?;
}
if let Some(ssr_options) = get_optional_value(js_options, global, b"ssr")? {
bundler_options.ssr = BuildConfigSubset::from_js(global, ssr_options)?;
bundler_options.ssr = BuildConfigSubset::from_js(global, ssr_options, "ssr")?;
}
}

Expand Down Expand Up @@ -408,9 +415,20 @@ pub struct BuildConfigSubset {
}

impl BuildConfigSubset {
pub fn from_js(global: &JSGlobalObject, js_options: JSValue) -> JsResult<BuildConfigSubset> {
pub fn from_js(
global: &JSGlobalObject,
js_options: JSValue,
property_name: &str,
) -> JsResult<BuildConfigSubset> {
let mut options = BuildConfigSubset::default();

if !js_options.is_object() {
return Err(global.throw_invalid_arguments(format_args!(
"Expected 'bundlerOptions.{}' to be an object",
property_name
)));
}

'brk: {
let Some(val) = get_optional_value(js_options, global, b"sourcemap")? else {
break 'brk;
Expand All @@ -428,25 +446,26 @@ impl BuildConfigSubset {
));
}

'brk: {
let Some(minify_options) = get_optional_value(js_options, global, b"minify")? else {
break 'brk;
};
if minify_options.is_boolean() && minify_options.as_boolean() {
options.minify_syntax = Some(minify_options.as_boolean());
options.minify_identifiers = Some(minify_options.as_boolean());
options.minify_whitespace = Some(minify_options.as_boolean());
break 'brk;
}

if let Some(value) = get_boolean_loose(minify_options, global, b"whitespace")? {
options.minify_whitespace = Some(value);
}
if let Some(value) = get_boolean_loose(minify_options, global, b"syntax")? {
if let Some(minify_options) = get_optional_value(js_options, global, b"minify")? {
if minify_options.is_boolean() {
let value = minify_options.as_boolean();
options.minify_syntax = Some(value);
}
if let Some(value) = get_boolean_loose(minify_options, global, b"identifiers")? {
options.minify_identifiers = Some(value);
options.minify_whitespace = Some(value);
} else if minify_options.is_object() {
if let Some(value) = get_boolean_loose(minify_options, global, b"whitespace")? {
options.minify_whitespace = Some(value);
}
if let Some(value) = get_boolean_loose(minify_options, global, b"syntax")? {
options.minify_syntax = Some(value);
}
if let Some(value) = get_boolean_loose(minify_options, global, b"identifiers")? {
options.minify_identifiers = Some(value);
}
} else {
return Err(global.throw_invalid_arguments(format_args!(
"Expected minify to be a boolean or an object"
)));
}
}

Expand Down
44 changes: 44 additions & 0 deletions test/js/bun/http/bun-serve-args.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -670,3 +670,47 @@ describe("Bun.serve unix socket validation", () => {
}
});
});

describe("app.bundlerOptions validation", () => {
test.each([
["bundlerOptions is not an object", { bundlerOptions: 123 }, "Expected 'bundlerOptions' to be an object"],
[
"bundlerOptions.server is not an object",
{ bundlerOptions: { server: 123 } },
"Expected 'bundlerOptions.server' to be an object",
],
[
"bundlerOptions.client is not an object",
{ bundlerOptions: { client: "abc" } },
"Expected 'bundlerOptions.client' to be an object",
],
[
"bundlerOptions.ssr is not an object",
{ bundlerOptions: { ssr: true } },
"Expected 'bundlerOptions.ssr' to be an object",
],
[
"minify is not a boolean or object",
{ bundlerOptions: { ssr: { minify: 10 } } },
"Expected minify to be a boolean or an object",
],
])("throws when %s", (_, app, message) => {
expect(() => {
// @ts-expect-error - Testing invalid runtime input
serve({ port: 0, app });
}).toThrow(
expect.objectContaining({
name: "TypeError",
code: "ERR_INVALID_ARG_TYPE",
message,
}),
);
});

test("minify: false does not crash", () => {
expect(() => {
// @ts-expect-error - Testing runtime input
serve({ port: 0, app: { bundlerOptions: { ssr: { minify: false } } } });
}).toThrow("'app' is missing 'framework'");
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
});
Loading