diff --git a/src/bake/bake.zig b/src/bake/bake.zig index cd621eb3de4..50e71cad258 100644 --- a/src/bake/bake.zig +++ b/src/bake/bake.zig @@ -68,13 +68,25 @@ pub const UserOptions = struct { } if (try config.getOptional(global, "bundlerOptions", JSValue)) |js_options| { + if (!js_options.isObject()) { + return global.throwInvalidArguments("'" ++ api_name ++ ".bundlerOptions' must be an object", .{}); + } if (try js_options.getOptional(global, "server", JSValue)) |server_options| { + if (!server_options.isObject()) { + return global.throwInvalidArguments("'" ++ api_name ++ ".bundlerOptions.server' must be an object", .{}); + } bundler_options.server = try BuildConfigSubset.fromJS(global, server_options); } if (try js_options.getOptional(global, "client", JSValue)) |client_options| { + if (!client_options.isObject()) { + return global.throwInvalidArguments("'" ++ api_name ++ ".bundlerOptions.client' must be an object", .{}); + } bundler_options.client = try BuildConfigSubset.fromJS(global, client_options); } if (try js_options.getOptional(global, "ssr", JSValue)) |ssr_options| { + if (!ssr_options.isObject()) { + return global.throwInvalidArguments("'" ++ api_name ++ ".bundlerOptions.ssr' must be an object", .{}); + } bundler_options.ssr = try BuildConfigSubset.fromJS(global, ssr_options); } } @@ -215,13 +227,19 @@ const BuildConfigSubset = struct { } if (try js_options.getOptional(global, "minify", JSValue)) |minify_options| brk: { - if (minify_options.isBoolean() and minify_options.asBoolean()) { - options.minify_syntax = minify_options.asBoolean(); - options.minify_identifiers = minify_options.asBoolean(); - options.minify_whitespace = minify_options.asBoolean(); + if (minify_options.isBoolean()) { + if (minify_options.asBoolean()) { + options.minify_syntax = true; + options.minify_identifiers = true; + options.minify_whitespace = true; + } break :brk; } + if (!minify_options.isObject()) { + return bun.jsc.Node.validators.throwErrInvalidArgType(global, "minify", .{}, "boolean | object", minify_options); + } + if (try minify_options.getBooleanLoose(global, "whitespace")) |value| { options.minify_whitespace = value; } diff --git a/test/js/bun/http/bun-serve-args.test.ts b/test/js/bun/http/bun-serve-args.test.ts index 54a44c192d3..b7f32606789 100644 --- a/test/js/bun/http/bun-serve-args.test.ts +++ b/test/js/bun/http/bun-serve-args.test.ts @@ -670,3 +670,23 @@ describe("Bun.serve unix socket validation", () => { } }); }); + +describe("app.bundlerOptions validation", () => { + test("non-object bundlerOptions throws", () => { + expect(() => serve({ port: 0, app: { bundlerOptions: 551 } } as any)).toThrow( + "'app.bundlerOptions' must be an object", + ); + }); + + test.each(["server", "client", "ssr"] as const)("non-object bundlerOptions.%s throws", key => { + expect(() => serve({ port: 0, app: { bundlerOptions: { [key]: 551 } } } as any)).toThrow( + `'app.bundlerOptions.${key}' must be an object`, + ); + }); + + test("non-object non-boolean minify throws", () => { + expect(() => serve({ port: 0, app: { bundlerOptions: { server: { minify: 551 } } } } as any)).toThrow( + 'The "minify" property must be of type boolean | object', + ); + }); +});