diff options
Diffstat (limited to 'src')
31 files changed, 682 insertions, 322 deletions
diff --git a/src/api/schema.d.ts b/src/api/schema.d.ts index 159cf4061..46429c9d0 100644 --- a/src/api/schema.d.ts +++ b/src/api/schema.d.ts @@ -401,6 +401,7 @@ type uint32 = number; development?: boolean; client_css_in_js?: CSSInJSBehavior; display_name?: string; + overrideModules?: StringMap; } export interface FrameworkEntryPoint { @@ -426,6 +427,7 @@ type uint32 = number; development: boolean; entry_points: FrameworkEntryPointMap; client_css_in_js: CSSInJSBehavior; + overrideModules: StringMap; } export interface LoadedRouteConfig { diff --git a/src/api/schema.js b/src/api/schema.js index 1b928aa20..c69b09834 100644 --- a/src/api/schema.js +++ b/src/api/schema.js @@ -1226,6 +1226,10 @@ function decodeFrameworkConfig(bb) { result["display_name"] = bb.readString(); break; + case 8: + result["overrideModules"] = decodeStringMap(bb); + break; + default: throw new Error("Attempted to parse invalid message"); } @@ -1277,6 +1281,12 @@ bb.writeByte(encoded); bb.writeByte(7); bb.writeString(value); } + + var value = message["overrideModules"]; + if (value != null) { + bb.writeByte(8); + encodeStringMap(value, bb); + } bb.writeByte(0); } @@ -1413,6 +1423,7 @@ function decodeLoadedFramework(bb) { result["development"] = !!bb.readByte(); result["entry_points"] = decodeFrameworkEntryPointMap(bb); result["client_css_in_js"] = CSSInJSBehavior[bb.readByte()]; + result["overrideModules"] = decodeStringMap(bb); return result; } @@ -1455,6 +1466,13 @@ bb.writeByte(encoded); throw new Error("Missing required field \"client_css_in_js\""); } + var value = message["overrideModules"]; + if (value != null) { + encodeStringMap(value, bb); + } else { + throw new Error("Missing required field \"overrideModules\""); + } + } function decodeLoadedRouteConfig(bb) { diff --git a/src/api/schema.peechy b/src/api/schema.peechy index a74059dca..fd887db3b 100644 --- a/src/api/schema.peechy +++ b/src/api/schema.peechy @@ -256,6 +256,8 @@ message FrameworkConfig { CSSInJSBehavior client_css_in_js = 6; string display_name = 7; + + StringMap overrideModules = 8; } struct FrameworkEntryPoint { @@ -281,6 +283,7 @@ struct LoadedFramework { bool development; FrameworkEntryPointMap entry_points; CSSInJSBehavior client_css_in_js; + StringMap overrideModules; } struct LoadedRouteConfig { diff --git a/src/api/schema.zig b/src/api/schema.zig index 980346698..13598e487 100644 --- a/src/api/schema.zig +++ b/src/api/schema.zig @@ -1340,6 +1340,9 @@ client_css_in_js: ?CssInJsBehavior = null, /// display_name display_name: ?[]const u8 = null, +/// overrideModules +override_modules: ?StringMap = null, + pub fn decode(reader: anytype) anyerror!FrameworkConfig { var this = std.mem.zeroes(FrameworkConfig); @@ -1369,6 +1372,9 @@ pub fn decode(reader: anytype) anyerror!FrameworkConfig { 7 => { this.display_name = try reader.readValue([]const u8); }, + 8 => { + this.override_modules = try reader.readValue(StringMap); +}, else => { return error.InvalidMessage; }, @@ -1406,6 +1412,10 @@ if (this.display_name) |display_name| { try writer.writeFieldID(7); try writer.writeValue(display_name); } +if (this.override_modules) |override_modules| { + try writer.writeFieldID(8); + try writer.writeValue(override_modules); +} try writer.endMessage(); } @@ -1551,6 +1561,9 @@ entry_points: FrameworkEntryPointMap, /// client_css_in_js client_css_in_js: CssInJsBehavior, +/// overrideModules +override_modules: StringMap, + pub fn decode(reader: anytype) anyerror!LoadedFramework { var this = std.mem.zeroes(LoadedFramework); @@ -1560,6 +1573,7 @@ pub fn decode(reader: anytype) anyerror!LoadedFramework { this.development = try reader.readValue(bool); this.entry_points = try reader.readValue(FrameworkEntryPointMap); this.client_css_in_js = try reader.readValue(CssInJsBehavior); + this.override_modules = try reader.readValue(StringMap); return this; } @@ -1569,6 +1583,7 @@ pub fn encode(this: *const @This(), writer: anytype) anyerror!void { try writer.writeInt(@intCast(u8, @boolToInt(this.development))); try writer.writeValue(this.entry_points); try writer.writeEnum(this.client_css_in_js); + try writer.writeValue(this.override_modules); } }; diff --git a/src/bundler.zig b/src/bundler.zig index 49ece989f..9b5371014 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -486,6 +486,7 @@ pub fn NewBundler(cache_files: bool) type { pub fn init(worker: *Worker, generator: *GenerateNodeModuleBundle) !void { worker.generator = generator; + worker.allocator = generator.allocator; worker.thread = try std.Thread.spawn(.{}, Worker.run, .{worker}); } @@ -754,6 +755,12 @@ pub fn NewBundler(cache_files: bool) type { try this.bundler.configureFramework(true); if (bundler.options.framework) |framework| { + if (framework.override_modules.keys.len > 0) { + bundler.options.framework.?.override_modules_hashes = allocator.alloc(u64, framework.override_modules.keys.len) catch unreachable; + for (framework.override_modules.keys) |key, i| { + bundler.options.framework.?.override_modules_hashes[i] = std.hash.Wyhash.hash(0, key); + } + } if (bundler.options.platform == .bun) { if (framework.server.isEnabled()) { const resolved = try bundler.linker.resolver.resolve( @@ -1074,7 +1081,14 @@ pub fn NewBundler(cache_files: bool) type { }; fn processImportRecord(this: *GenerateNodeModuleBundle, import_record: ImportRecord) !void {} - + var json_ast_symbols = [_]js_ast.Symbol{ + js_ast.Symbol{ .original_name = "$$m" }, + js_ast.Symbol{ .original_name = "exports" }, + js_ast.Symbol{ .original_name = "module" }, + js_ast.Symbol{ .original_name = "CONGRATS_YOU_FOUND_A_BUG" }, + }; + var json_ast_symbols_list = std.mem.span(&json_ast_symbols); + threadlocal var override_file_path_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; pub fn processFile(this: *GenerateNodeModuleBundle, worker: *ThreadPool.Worker, _resolve: _resolver.Result) !void { const resolve = _resolve; if (resolve.is_external) return; @@ -1094,90 +1108,121 @@ pub fn NewBundler(cache_files: bool) type { // If we're in a node_module, build that almost normally if (is_from_node_modules) { - switch (loader) { - .jsx, - .tsx, - .js, - .ts, - => { - var written: usize = undefined; - var code_offset: u32 = 0; - - const entry: CacheEntry = brk: { - if (!strings.eqlComptime(file_path.namespace, "node")) - break :brk try bundler.resolver.caches.fs.readFileShared( - bundler.fs, - file_path.textZ(), - resolve.dirname_fd, - if (resolve.file_fd != 0) resolve.file_fd else null, - shared_buffer, - ); - - var module_name = file_path.text["/bun-vfs/node_modules/".len..]; - - if (module_name[0] == '@') { - var end = strings.indexOfChar(module_name, '/').? + 1; - end += strings.indexOfChar(module_name[end..], '/').?; - - module_name = module_name[0..end]; - } else { - module_name = module_name[0..strings.indexOfChar(module_name, '/').?]; - } - - if (NodeFallbackModules.Map.get(module_name)) |mod| { - break :brk CacheEntry{ .contents = mod.code.* }; - } + var written: usize = undefined; + var code_offset: u32 = 0; + + const module_data = BundledModuleData.get(this, &resolve) orelse { + const fake_path = logger.Source.initPathString(file_path.text, ""); + log.addResolveError( + &fake_path, + logger.Range.None, + this.allocator, + "Bug while resolving: \"{s}\"", + .{file_path.text}, + resolve.import_kind, + ) catch {}; + return error.ResolveError; + }; - break :brk CacheEntry{ - .contents = "", + const module_id = module_data.module_id; + const package = module_data.package; + const package_relative_path = module_data.import_path; + + file_path.pretty = module_data.package_path; + + const entry: CacheEntry = brk: { + if (this.bundler.options.framework.?.override_modules_hashes.len > 0) { + const package_relative_path_hash = std.hash.Wyhash.hash(0, module_data.package_path); + if (std.mem.indexOfScalar( + u64, + this.bundler.options.framework.?.override_modules_hashes, + package_relative_path_hash, + )) |index| { + const relative_path = [_]string{ + this.bundler.options.framework.?.resolved_dir, + this.bundler.options.framework.?.override_modules.values[index], }; - }; + var override_path = this.bundler.fs.absBuf( + &relative_path, + &override_file_path_buf, + ); + override_file_path_buf[override_path.len] = 0; + var override_pathZ = override_file_path_buf[0..override_path.len :0]; + break :brk try bundler.resolver.caches.fs.readFileShared( + bundler.fs, + override_pathZ, + 0, + null, + shared_buffer, + ); + } + } - const module_data = BundledModuleData.get(this, &resolve) orelse { - const source = logger.Source.initPathString(file_path.text, entry.contents); - log.addResolveError( - &source, - logger.Range.None, - this.allocator, - "Bug while resolving: \"{s}\"", - .{file_path.text}, - resolve.import_kind, - ) catch {}; - return error.ResolveError; - }; - const module_id = module_data.module_id; - const package = module_data.package; - const package_relative_path = module_data.import_path; - file_path.pretty = module_data.package_path; - - // Handle empty files - // We can't just ignore them. Sometimes code will try to import it. Often because of TypeScript types. - // So we just say it's an empty object. Empty object mimicks what "browser": false does as well. - // TODO: optimize this so that all the exports for these are done in one line instead of writing repeatedly - if (entry.contents.len == 0 or (entry.contents.len < 33 and strings.trim(entry.contents, " \n\r").len == 0)) { - this.write_lock.lock(); - defer this.write_lock.unlock(); - code_offset = @truncate(u32, try this.tmpfile.getPos()); - var writer = this.tmpfile.writer(); - var buffered = std.io.bufferedWriter(writer); - - var bufwriter = buffered.writer(); - try bufwriter.writeAll("// "); - try bufwriter.writeAll(package_relative_path); - try bufwriter.writeAll("\nexport var $"); - std.fmt.formatInt(module_id, 16, .lower, .{}, bufwriter) catch unreachable; - try bufwriter.writeAll(" = () => ({});\n"); - try buffered.flush(); - this.tmpfile_byte_offset = @truncate(u32, try this.tmpfile.getPos()); - } else { - const source = logger.Source.initRecycledFile( - Fs.File{ - .path = file_path, - .contents = entry.contents, - }, - bundler.allocator, - ) catch return null; + if (!strings.eqlComptime(file_path.namespace, "node")) + break :brk try bundler.resolver.caches.fs.readFileShared( + bundler.fs, + file_path.textZ(), + resolve.dirname_fd, + if (resolve.file_fd != 0) resolve.file_fd else null, + shared_buffer, + ); + + var module_name = file_path.text["/bun-vfs/node_modules/".len..]; + + if (module_name[0] == '@') { + var end = strings.indexOfChar(module_name, '/').? + 1; + end += strings.indexOfChar(module_name[end..], '/').?; + + module_name = module_name[0..end]; + } else { + module_name = module_name[0..strings.indexOfChar(module_name, '/').?]; + } + if (NodeFallbackModules.Map.get(module_name)) |mod| { + break :brk CacheEntry{ .contents = mod.code.* }; + } + + break :brk CacheEntry{ + .contents = "", + }; + }; + + // Handle empty files + // We can't just ignore them. Sometimes code will try to import it. Often because of TypeScript types. + // So we just say it's an empty object. Empty object mimicks what "browser": false does as well. + // TODO: optimize this so that all the exports for these are done in one line instead of writing repeatedly + if (entry.contents.len == 0 or (entry.contents.len < 33 and strings.trim(entry.contents, " \n\r").len == 0)) { + this.write_lock.lock(); + defer this.write_lock.unlock(); + code_offset = @truncate(u32, try this.tmpfile.getPos()); + var writer = this.tmpfile.writer(); + var buffered = std.io.bufferedWriter(writer); + + var bufwriter = buffered.writer(); + try bufwriter.writeAll("// "); + try bufwriter.writeAll(package_relative_path); + try bufwriter.writeAll("(disabled or empty file) \nexport var $"); + std.fmt.formatInt(module_id, 16, .lower, .{}, bufwriter) catch unreachable; + try bufwriter.writeAll(" = () => (var obj = {}, Object.defineProperty(obj, 'default', { value: obj, enumerable: false, configurable: true }, obj);\n"); + try buffered.flush(); + this.tmpfile_byte_offset = @truncate(u32, try this.tmpfile.getPos()); + } else { + var ast: js_ast.Ast = undefined; + + const source = logger.Source.initRecycledFile( + Fs.File{ + .path = file_path, + .contents = entry.contents, + }, + bundler.allocator, + ) catch return null; + + switch (loader) { + .jsx, + .tsx, + .js, + .ts, + => { var jsx = bundler.options.jsx; jsx.parse = loader.isJSX(); @@ -1186,7 +1231,7 @@ pub fn NewBundler(cache_files: bool) type { opts.enable_bundling = true; opts.warn_about_unbundled_modules = false; - var ast: js_ast.Ast = (try bundler.resolver.caches.js.parse( + ast = (try bundler.resolver.caches.js.parse( bundler.allocator, opts, bundler.options.define, @@ -1291,193 +1336,215 @@ pub fn NewBundler(cache_files: bool) type { } } } + }, + .json => { + var expr = json_parser.ParseJSON(&source, worker.data.log, worker.allocator) catch return; + var stmt = js_ast.Stmt.alloc(worker.allocator, js_ast.S.ExportDefault{ + .value = js_ast.StmtOrExpr{ .expr = expr }, + .default_name = js_ast.LocRef{ .loc = logger.Loc{}, .ref = Ref{} }, + }, logger.Loc{ .start = 0 }); + var stmts = worker.allocator.alloc(js_ast.Stmt, 1) catch unreachable; + stmts[0] = stmt; + var parts = worker.allocator.alloc(js_ast.Part, 1) catch unreachable; + parts[0] = js_ast.Part{ .stmts = stmts }; + ast = js_ast.Ast.initTest(parts); + + ast.runtime_imports = runtime.Runtime.Imports{}; + ast.runtime_imports.register = Ref{ .source_index = 0, .inner_index = 0 }; + ast.runtime_imports.__export = Ref{ .source_index = 0, .inner_index = 1 }; + ast.symbols = json_ast_symbols_list; + ast.module_ref = Ref{ .source_index = 0, .inner_index = 2 }; + ast.exports_ref = ast.runtime_imports.__export; + ast.bundle_export_ref = Ref{ .source_index = 0, .inner_index = 3 }; + }, + else => { + return; + }, + } - // const load_from_symbol_ref = ast.runtime_imports.$$r.?; - // const reexport_ref = ast.runtime_imports.__reExport.?; - const register_ref = ast.runtime_imports.register.?; - const E = js_ast.E; - const Expr = js_ast.Expr; - const Stmt = js_ast.Stmt; - - var prepend_part: js_ast.Part = undefined; - var needs_prepend_part = false; - if (ast.parts.len > 1) { - for (ast.parts) |part| { - if (part.tag != .none and part.stmts.len > 0) { - prepend_part = part; - needs_prepend_part = true; - break; - } - } - } - - if (ast.parts.len == 0) { - if (comptime isDebug) { - Output.prettyErrorln("Missing AST for file: {s}", .{file_path.text}); - Output.flush(); - } + // const load_from_symbol_ref = ast.runtime_imports.$$r.?; + // const reexport_ref = ast.runtime_imports.__reExport.?; + const register_ref = ast.runtime_imports.register.?; + const E = js_ast.E; + const Expr = js_ast.Expr; + const Stmt = js_ast.Stmt; + + var prepend_part: js_ast.Part = undefined; + var needs_prepend_part = false; + if (ast.parts.len > 1) { + for (ast.parts) |part| { + if (part.tag != .none and part.stmts.len > 0) { + prepend_part = part; + needs_prepend_part = true; + break; } + } + } - var part = &ast.parts[ast.parts.len - 1]; - var new_stmts: [1]Stmt = undefined; - var register_args: [3]Expr = undefined; - - var package_json_string = E.String{ .utf8 = package.name }; - var module_path_string = E.String{ .utf8 = module_data.import_path }; - var target_identifier = E.Identifier{ .ref = register_ref }; - var cjs_args: [2]js_ast.G.Arg = undefined; - var module_binding = js_ast.B.Identifier{ .ref = ast.module_ref.? }; - var exports_binding = js_ast.B.Identifier{ .ref = ast.exports_ref.? }; - - // if (!ast.uses_module_ref) { - // var symbol = &ast.symbols[ast.module_ref.?.inner_index]; - // symbol.original_name = "_$$"; - // } - - cjs_args[0] = js_ast.G.Arg{ - .binding = js_ast.Binding{ - .loc = logger.Loc.Empty, - .data = .{ .b_identifier = &module_binding }, - }, - }; - cjs_args[1] = js_ast.G.Arg{ - .binding = js_ast.Binding{ - .loc = logger.Loc.Empty, - .data = .{ .b_identifier = &exports_binding }, - }, - }; + if (ast.parts.len == 0) { + if (comptime isDebug) { + Output.prettyErrorln("Missing AST for file: {s}", .{file_path.text}); + Output.flush(); + } + } - var closure = E.Arrow{ - .args = &cjs_args, - .body = .{ - .loc = logger.Loc.Empty, - .stmts = part.stmts, - }, - }; + var part = &ast.parts[ast.parts.len - 1]; + var new_stmts: [1]Stmt = undefined; + var register_args: [3]Expr = undefined; + + var package_json_string = E.String{ .utf8 = package.name }; + var module_path_string = E.String{ .utf8 = module_data.import_path }; + var target_identifier = E.Identifier{ .ref = register_ref }; + var cjs_args: [2]js_ast.G.Arg = undefined; + var module_binding = js_ast.B.Identifier{ .ref = ast.module_ref.? }; + var exports_binding = js_ast.B.Identifier{ .ref = ast.exports_ref.? }; + + // if (!ast.uses_module_ref) { + // var symbol = &ast.symbols[ast.module_ref.?.inner_index]; + // symbol.original_name = "_$$"; + // } + + cjs_args[0] = js_ast.G.Arg{ + .binding = js_ast.Binding{ + .loc = logger.Loc.Empty, + .data = .{ .b_identifier = &module_binding }, + }, + }; + cjs_args[1] = js_ast.G.Arg{ + .binding = js_ast.Binding{ + .loc = logger.Loc.Empty, + .data = .{ .b_identifier = &exports_binding }, + }, + }; - // $$m(12345, "react", "index.js", function(module, exports) { + var closure = E.Arrow{ + .args = &cjs_args, + .body = .{ + .loc = logger.Loc.Empty, + .stmts = part.stmts, + }, + }; - // }) - register_args[0] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &package_json_string } }; - register_args[1] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &module_path_string } }; - register_args[2] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_arrow = &closure } }; + // $$m(12345, "react", "index.js", function(module, exports) { - var call_register = E.Call{ - .target = Expr{ - .data = .{ .e_identifier = &target_identifier }, - .loc = logger.Loc{ .start = 0 }, - }, - .args = ®ister_args, - }; - var register_expr = Expr{ .loc = call_register.target.loc, .data = .{ .e_call = &call_register } }; - var decls: [1]js_ast.G.Decl = undefined; - var bundle_export_binding = js_ast.B.Identifier{ .ref = ast.bundle_export_ref.? }; - var binding = js_ast.Binding{ - .loc = register_expr.loc, - .data = .{ .b_identifier = &bundle_export_binding }, - }; - decls[0] = js_ast.G.Decl{ - .value = register_expr, - .binding = binding, - }; - var export_var = js_ast.S.Local{ - .decls = &decls, - .is_export = true, - }; - new_stmts[0] = Stmt{ .loc = register_expr.loc, .data = .{ .s_local = &export_var } }; - part.stmts = &new_stmts; + // }) + register_args[0] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &package_json_string } }; + register_args[1] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_string = &module_path_string } }; + register_args[2] = Expr{ .loc = .{ .start = 0 }, .data = .{ .e_arrow = &closure } }; - var writer = js_printer.NewFileWriter(this.tmpfile); - var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols}); + var call_register = E.Call{ + .target = Expr{ + .data = .{ .e_identifier = &target_identifier }, + .loc = logger.Loc{ .start = 0 }, + }, + .args = ®ister_args, + }; + var register_expr = Expr{ .loc = call_register.target.loc, .data = .{ .e_call = &call_register } }; + var decls: [1]js_ast.G.Decl = undefined; + var bundle_export_binding = js_ast.B.Identifier{ .ref = ast.bundle_export_ref.? }; + var binding = js_ast.Binding{ + .loc = register_expr.loc, + .data = .{ .b_identifier = &bundle_export_binding }, + }; + decls[0] = js_ast.G.Decl{ + .value = register_expr, + .binding = binding, + }; + var export_var = js_ast.S.Local{ + .decls = &decls, + .is_export = true, + }; + new_stmts[0] = Stmt{ .loc = register_expr.loc, .data = .{ .s_local = &export_var } }; + part.stmts = &new_stmts; - // It should only have one part. - ast.parts = ast.parts[ast.parts.len - 1 ..]; + var writer = js_printer.NewFileWriter(this.tmpfile); + var symbols: [][]js_ast.Symbol = &([_][]js_ast.Symbol{ast.symbols}); - const write_result = - try js_printer.printCommonJSThreaded( - @TypeOf(writer), - writer, - ast, - js_ast.Symbol.Map.initList(symbols), - &source, - false, - js_printer.Options{ - .to_module_ref = Ref.RuntimeRef, - .bundle_export_ref = ast.bundle_export_ref.?, - .source_path = file_path, - .externals = ast.externals, - .indent = 0, - .module_hash = module_id, - .runtime_imports = ast.runtime_imports, - .prepend_part_value = &prepend_part, - .prepend_part_key = if (needs_prepend_part) closure.body.stmts.ptr else null, - }, - Linker, - &bundler.linker, - &this.write_lock, - std.fs.File, - this.tmpfile, - std.fs.File.getPos, - ); + // It should only have one part. + ast.parts = ast.parts[ast.parts.len - 1 ..]; - code_offset = write_result.off; - written = write_result.len; + const write_result = + try js_printer.printCommonJSThreaded( + @TypeOf(writer), + writer, + ast, + js_ast.Symbol.Map.initList(symbols), + &source, + false, + js_printer.Options{ + .to_module_ref = Ref.RuntimeRef, + .bundle_export_ref = ast.bundle_export_ref.?, + .source_path = file_path, + .externals = ast.externals, + .indent = 0, + .module_hash = module_id, + .runtime_imports = ast.runtime_imports, + .prepend_part_value = &prepend_part, + .prepend_part_key = if (needs_prepend_part) closure.body.stmts.ptr else null, + }, + Linker, + &bundler.linker, + &this.write_lock, + std.fs.File, + this.tmpfile, + std.fs.File.getPos, + ); - // Faster to _not_ do the syscall - // But there's some off-by-one error somewhere and more reliable to just do the lseek - this.tmpfile_byte_offset = write_result.end_off; - } + code_offset = write_result.off; + written = write_result.len; - if (comptime isDebug) { - Output.prettyln("{s}@{s}/{s} - {d}:{d} \n", .{ package.name, package.version, package_relative_path, package.hash, module_id }); - Output.flush(); - std.debug.assert(package_relative_path.len > 0); - } + // Faster to _not_ do the syscall + // But there's some off-by-one error somewhere and more reliable to just do the lseek + this.tmpfile_byte_offset = write_result.end_off; - this.list_lock.lock(); - defer this.list_lock.unlock(); + if (comptime isDebug) { + Output.prettyln("{s}@{s}/{s} - {d}:{d} \n", .{ package.name, package.version, package_relative_path, package.hash, module_id }); + Output.flush(); + std.debug.assert(package_relative_path.len > 0); + } - const code_length = this.tmpfile_byte_offset - code_offset; + this.list_lock.lock(); + defer this.list_lock.unlock(); - if (comptime isDebug) { - std.debug.assert(code_length > 0); - std.debug.assert(package.hash != 0); - std.debug.assert(package.version.len > 0); - std.debug.assert(package.name.len > 0); - std.debug.assert(module_id > 0); - } + const code_length = this.tmpfile_byte_offset - code_offset; - var package_get_or_put_entry = try this.package_list_map.getOrPut(package.hash); + if (comptime isDebug) { + std.debug.assert(code_length > 0); + std.debug.assert(package.hash != 0); + std.debug.assert(package.version.len > 0); + std.debug.assert(package.name.len > 0); + std.debug.assert(module_id > 0); + } - if (!package_get_or_put_entry.found_existing) { - package_get_or_put_entry.value_ptr.* = @truncate(u32, this.package_list.items.len); - try this.package_list.append( - Api.JavascriptBundledPackage{ - .name = try this.appendHeaderString(package.name), - .version = try this.appendHeaderString(package.version), - .hash = package.hash, - }, - ); - this.has_jsx = this.has_jsx or strings.eql(package.name, this.bundler.options.jsx.package_name); - } + var package_get_or_put_entry = try this.package_list_map.getOrPut(package.hash); - var path_extname_length = @truncate(u8, std.fs.path.extension(package_relative_path).len); - try this.module_list.append( - Api.JavascriptBundledModule{ - .path = try this.appendHeaderString( - package_relative_path, - ), - .path_extname_length = path_extname_length, - .package_id = package_get_or_put_entry.value_ptr.*, - .id = module_id, - .code = Api.StringPointer{ - .length = @truncate(u32, code_length), - .offset = @truncate(u32, code_offset), - }, + if (!package_get_or_put_entry.found_existing) { + package_get_or_put_entry.value_ptr.* = @truncate(u32, this.package_list.items.len); + try this.package_list.append( + Api.JavascriptBundledPackage{ + .name = try this.appendHeaderString(package.name), + .version = try this.appendHeaderString(package.version), + .hash = package.hash, }, ); - }, - else => {}, + this.has_jsx = this.has_jsx or strings.eql(package.name, this.bundler.options.jsx.package_name); + } + + var path_extname_length = @truncate(u8, std.fs.path.extension(package_relative_path).len); + try this.module_list.append( + Api.JavascriptBundledModule{ + .path = try this.appendHeaderString( + package_relative_path, + ), + .path_extname_length = path_extname_length, + .package_id = package_get_or_put_entry.value_ptr.*, + .id = module_id, + .code = Api.StringPointer{ + .length = @truncate(u32, code_length), + .offset = @truncate(u32, code_offset), + }, + }, + ); } } else { // If it's app code, scan but do not fully parse. @@ -1586,10 +1653,7 @@ pub fn NewBundler(cache_files: bool) type { } } }, - // TODO: - else => { - return; - }, + else => {}, } } } diff --git a/src/deps/iguanaTLS/test/DSTRootCAX3.crt.pem b/src/deps/iguanaTLS/test/DSTRootCAX3.crt.pem new file mode 100644 index 000000000..ea08d57a2 --- /dev/null +++ b/src/deps/iguanaTLS/test/DSTRootCAX3.crt.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
+MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
+DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
+PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
+Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
+rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
+OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
+xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
+7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
+aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
+SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
+ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
+AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
+R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
+JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
+Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
diff --git a/src/deps/iguanaTLS/test/DigiCertGlobalRootCA.crt.pem b/src/deps/iguanaTLS/test/DigiCertGlobalRootCA.crt.pem new file mode 100644 index 000000000..fd4341df2 --- /dev/null +++ b/src/deps/iguanaTLS/test/DigiCertGlobalRootCA.crt.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- diff --git a/src/deps/iguanaTLS/test/DigiCertHighAssuranceEVRootCA.crt.pem b/src/deps/iguanaTLS/test/DigiCertHighAssuranceEVRootCA.crt.pem new file mode 100644 index 000000000..9e6810ab7 --- /dev/null +++ b/src/deps/iguanaTLS/test/DigiCertHighAssuranceEVRootCA.crt.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- diff --git a/src/deps/iguanaTLS/test/badssl.com-client.pem b/src/deps/iguanaTLS/test/badssl.com-client.pem new file mode 100644 index 000000000..16a2d1ad9 --- /dev/null +++ b/src/deps/iguanaTLS/test/badssl.com-client.pem @@ -0,0 +1,61 @@ +Bag Attributes + localKeyID: 41 C3 6C 33 C7 E3 36 DD EA 4A 1F C0 B7 23 B8 E6 9C DC D8 0F +subject=C = US, ST = California, L = San Francisco, O = BadSSL, CN = BadSSL Client Certificate + +issuer=C = US, ST = California, L = San Francisco, O = BadSSL, CN = BadSSL Client Root Certificate Authority + +-----BEGIN CERTIFICATE----- +MIIEqDCCApCgAwIBAgIUK5Ns4y2CzosB/ZoFlaxjZqoBTIIwDQYJKoZIhvcNAQEL +BQAwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDExMC8GA1UEAwwoQmFkU1NM +IENsaWVudCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xOTExMjcwMDE5 +NTdaFw0yMTExMjYwMDE5NTdaMG8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp +Zm9ybmlhMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZCYWRTU0wx +IjAgBgNVBAMMGUJhZFNTTCBDbGllbnQgQ2VydGlmaWNhdGUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDHN18R6x5Oz+u6SOXLoxIscz5GHR6cDcCLgyPa +x2XfXHdJs+h6fTy61WGM+aXEhR2SIwbj5997s34m0MsbvkJrFmn0LHK1fuTLCihE +EmxGdCGZA9xrwxFYAkEjP7D8v7cAWRMipYF/JP7VU7xNUo+QSkZ0sOi9k6bNkABK +L3+yP6PqAzsBoKIN5lN/YRLrppsDmk6nrRDo4R3CD+8JQl9quEoOmL22Pc/qpOjL +1jgOIFSE5y3gwbzDlfCYoAL5V+by1vu0yJShTTK8oo5wvphcFfEHaQ9w5jFg2htd +q99UER3BKuNDuL+zejqGQZCWb0Xsk8S5WBuX8l3Brrg5giqNAgMBAAGjLTArMAkG +A1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgeAMAsGA1UdDwQEAwIF4DANBgkqhkiG +9w0BAQsFAAOCAgEAZBauLzFSOijkDadcippr9C6laHebb0oRS54xAV70E9k5GxfR +/E2EMuQ8X+miRUMXxKquffcDsSxzo2ac0flw94hDx3B6vJIYvsQx9Lzo95Im0DdT +DkHFXhTlv2kjQwFVnEsWYwyGpHMTjanvNkO7sBP9p1bN1qTE3QAeyMZNKWJk5xPl +U298ERar6tl3Z2Cl8mO6yLhrq4ba6iPGw08SENxzuAJW+n8r0rq7EU+bMg5spgT1 +CxExzG8Bb0f98ZXMklpYFogkcuH4OUOFyRodotrotm3iRbuvZNk0Zz7N5n1oLTPl +bGPMwBcqaGXvK62NlaRkwjnbkPM4MYvREM0bbAgZD2GHyANBTso8bdWvhLvmoSjs +FSqJUJp17AZ0x/ELWZd69v2zKW9UdPmw0evyVR19elh/7dmtF6wbewc4N4jxQnTq +IItuhIWKWB9edgJz65uZ9ubQWjXoa+9CuWcV/1KxuKCbLHdZXiboLrKm4S1WmMYW +d0sJm95H9mJzcLyhLF7iX2kK6K9ug1y02YCVXBC9WGZc2x6GMS7lDkXSkJFy3EWh +CmfxkmFGwOgwKt3Jd1pF9ftcSEMhu4WcMgxi9vZr9OdkJLxmk033sVKI/hnkPaHw +g0Y2YBH5v0xmi8sYU7weOcwynkjZARpUltBUQ0pWCF5uJsEB8uE8PPDD3c4= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxzdfEeseTs/rukjly6MSLHM+Rh0enA3Ai4Mj2sdl31x3SbPo +en08utVhjPmlxIUdkiMG4+ffe7N+JtDLG75CaxZp9CxytX7kywooRBJsRnQhmQPc +a8MRWAJBIz+w/L+3AFkTIqWBfyT+1VO8TVKPkEpGdLDovZOmzZAASi9/sj+j6gM7 +AaCiDeZTf2ES66abA5pOp60Q6OEdwg/vCUJfarhKDpi9tj3P6qToy9Y4DiBUhOct +4MG8w5XwmKAC+Vfm8tb7tMiUoU0yvKKOcL6YXBXxB2kPcOYxYNobXavfVBEdwSrj +Q7i/s3o6hkGQlm9F7JPEuVgbl/Jdwa64OYIqjQIDAQABAoIBAFUQf7fW/YoJnk5c +8kKRzyDL1Lt7k6Zu+NiZlqXEnutRQF5oQ8yJzXS5yH25296eOJI+AqMuT28ypZtN +bGzcQOAZIgTxNcnp9Sf9nlPyyekLjY0Y6PXaxX0e+VFj0N8bvbiYUGNq6HCyC15r +8uvRZRvnm04YfEj20zLTWkxTG+OwJ6ZNha1vfq8z7MG5JTsZbP0g7e/LrEb3wI7J +Zu9yHQUzq23HhfhpmLN/0l89YLtOaS8WNq4QvKYgZapw/0G1wWoWW4Y2/UpAxZ9r +cqTBWSpCSCCgyWjiNhPbSJWfe/9J2bcanITLcvCLlPWGAHy1wpo9iBH57y7S+7YS +3yi7lgECgYEA8lwaRIChc38tmtQCNPtai/7uVDdeJe0uv8Jsg04FTF8KMYcD0V1g ++T7rUPA+rTHwv8uAGLdzl4NW5Qryw18rDY+UivnaZkEdEsnlo3fc8MSQF78dDHCX +nwmHfOmBnBoSbLl+W5ByHkJRHOnX+8qKq9ePNFUMf/hZNYuma9BCFBUCgYEA0m2p +VDn12YdhFUUBIH91aD5cQIsBhkHFU4vqW4zBt6TsJpFciWbrBrTeRzeDou59aIsn +zGBrLMykOY+EwwRku9KTVM4U791Z/NFbH89GqyUaicb4or+BXw5rGF8DmzSsDo0f +ixJ9TVD5DmDi3c9ZQ7ljrtdSxPdA8kOoYPFsApkCgYEA08uZSPQAI6aoe/16UEK4 +Rk9qhz47kHlNuVZ27ehoyOzlQ5Lxyy0HacmKaxkILOLPuUxljTQEWAv3DAIdVI7+ +WMN41Fq0eVe9yIWXoNtGwUGFirsA77YVSm5RcN++3GQMZedUfUAl+juKFvJkRS4j +MTkXdGw+mDa3/wsjTGSa2mECgYABO6NCWxSVsbVf6oeXKSgG9FaWCjp4DuqZErjM +0IZSDSVVFIT2SSQXZffncuvSiJMziZ0yFV6LZKeRrsWYXu44K4Oxe4Oj5Cgi0xc1 +mIFRf2YoaIIMchLP+8Wk3ummfyiC7VDB/9m8Gj1bWDX8FrrvKqbq31gcz1YSFVNn +PgLkAQKBgFzG8NdL8os55YcjBcOZMUs5QTKiQSyZM0Abab17k9JaqsU0jQtzeFsY +FTiwh2uh6l4gdO/dGC/P0Vrp7F05NnO7oE4T+ojDzVQMnFpCBeL7x08GfUQkphEG +m0Wqhhi8/24Sy934t5Txgkfoltg8ahkx934WjP6WWRnSAu+cf+vW +-----END RSA PRIVATE KEY----- diff --git a/src/deps/iguanaTLS/test/github.der b/src/deps/iguanaTLS/test/github.der Binary files differnew file mode 100644 index 000000000..dae019650 --- /dev/null +++ b/src/deps/iguanaTLS/test/github.der diff --git a/src/deps/iguanaTLS/test/github.pem b/src/deps/iguanaTLS/test/github.pem new file mode 100644 index 000000000..4b1bc66be --- /dev/null +++ b/src/deps/iguanaTLS/test/github.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
+MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
+ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
+MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
+LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
+RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
+PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
+xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
+Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
+hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
+EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
+FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
+nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
+eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
+hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
+Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
++OkuE6N36B9K
+-----END CERTIFICATE-----
diff --git a/src/deps/picohttp.zig b/src/deps/picohttp.zig index 3340793ca..7c081afc4 100644 --- a/src/deps/picohttp.zig +++ b/src/deps/picohttp.zig @@ -35,6 +35,14 @@ pub const Request = struct { minor_version: usize, headers: []const Header, + pub fn format(self: Request, comptime layout: []const u8, opts: fmt.FormatOptions, writer: anytype) !void { + try fmt.format(writer, "{s} {s}\n", .{ self.method, self.path }); + for (self.headers) |header| { + _ = try writer.write("\t"); + try fmt.format(writer, "{s}\n", .{header}); + } + } + pub fn parse(buf: []const u8, src: []Header) !Request { var method: []const u8 = undefined; var path: []const u8 = undefined; diff --git a/src/http_client.zig b/src/http_client.zig index e01d6aa92..cbc2ddedb 100644 --- a/src/http_client.zig +++ b/src/http_client.zig @@ -35,6 +35,7 @@ header_entries: Headers.Entries, header_buf: string, url: URL, allocator: *std.mem.Allocator, +verbose: bool = true, pub fn init(allocator: *std.mem.Allocator, method: Method, url: URL, header_entries: Headers.Entries, header_buf: string) HTTPClient { return HTTPClient{ @@ -155,7 +156,7 @@ pub fn buildRequest(this: *const HTTPClient, body_len: usize) picohttp.Request { return picohttp.Request{ .method = @tagName(this.method), - .path = this.url.path, + .path = this.url.pathname, .minor_version = 1, .headers = request_headers_buf[0..header_count], }; @@ -203,7 +204,9 @@ pub fn sendHTTP(this: *HTTPClient, body: []const u8, body_out_str: *MutableStrin std.os.closeSocket(client.socket.fd); } var request = buildRequest(this, body.len); - + if (this.verbose) { + Output.prettyErrorln("{s}", .{request}); + } var client_writer = client.writer(SOCKET_FLAGS); { var client_writer_buffered = std.io.bufferedWriter(client_writer); @@ -246,8 +249,10 @@ pub fn sendHTTP(this: *HTTPClient, body: []const u8, body_out_str: *MutableStrin switch (hashHeaderName(header.name)) { content_length_header_hash => { content_length = std.fmt.parseInt(u32, header.value, 10) catch 0; - try body_out_str.inflate(content_length); + // Always write a sentinel + try body_out_str.inflate(content_length + 1); body_out_str.list.expandToCapacity(); + body_out_str.list.items[content_length] = 0; }, content_encoding_hash => { return error.UnsupportedEncoding; @@ -311,6 +316,9 @@ pub fn sendHTTPS(this: *HTTPClient, body_str: []const u8, body_out_str: *Mutable } var request = buildRequest(this, body_str.len); + if (this.verbose) { + Output.prettyErrorln("{s}", .{request}); + } const body = body_str; var client_writer = client.writer(); diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig index 680e8aa06..8b698bdea 100644 --- a/src/javascript/jsc/webcore/response.zig +++ b/src/javascript/jsc/webcore/response.zig @@ -105,16 +105,30 @@ pub const Response = struct { arguments: []const js.JSValueRef, exception: js.ExceptionRef, ) js.JSValueRef { - defer this.body.value = .Empty; var zig_string = ZigString.init(""); + var deallocate = false; + defer { + if (deallocate) { + if (this.body.value == .Unconsumed) { + this.body.ptr_allocator.?.free(this.body.ptr.?[0..this.body.len]); + this.body.ptr_allocator = null; + this.body.ptr = null; + this.body.len = 0; + } + } + + this.body.value = .Empty; + } - var js_string = (js.JSValueCreateJSONString( + var json_value = (js.JSValueMakeFromJSONString( ctx, brk: { switch (this.body.value) { .Unconsumed => { if (this.body.ptr) |_ptr| { zig_string = ZigString.init(_ptr[0..this.body.len]); + deallocate = true; + break :brk zig_string.toJSStringRef(); } @@ -133,8 +147,6 @@ pub const Response = struct { }, } }, - 0, - exception, ) orelse { var out = std.fmt.bufPrint(&temp_error_buffer, "Invalid JSON\n\n \"{s}\"", .{zig_string.slice()[0..std.math.min(zig_string.len, 4000)]}) catch unreachable; error_arg_list[0] = ZigString.init(out).toValueGC(VirtualMachine.vm.global).asRef(); @@ -150,16 +162,10 @@ pub const Response = struct { ), ).asRef(); }); - defer js.JSStringRelease(js_string); return JSPromise.resolvedPromiseValue( VirtualMachine.vm.global, - JSValue.fromRef( - js.JSValueMakeString( - ctx, - js_string, - ), - ), + JSValue.fromRef(json_value), ).asRef(); } pub fn getArrayBuffer( diff --git a/src/js_ast.zig b/src/js_ast.zig index 750100750..3b40a0127 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -1128,6 +1128,18 @@ pub const E = struct { } } + pub fn hash(s: *const String) u64 { + if (s.isBlank()) return 0; + + if (s.isUTF8()) { + // hash utf-8 + return std.hash.Wyhash.hash(0, s.utf8); + } else { + // hash utf-16 + return std.hash.Wyhash.hash(0, @ptrCast([*]u8, s.value.ptr)[0 .. s.value.len * 2]); + } + } + pub fn jsonStringify(s: *const String, options: anytype, writer: anytype) !void { var buf = [_]u8{0} ** 4096; var i: usize = 0; diff --git a/src/js_lexer.zig b/src/js_lexer.zig index 0cbe88ae9..265ccef18 100644 --- a/src/js_lexer.zig +++ b/src/js_lexer.zig @@ -2682,6 +2682,7 @@ pub const CodepointIterator = struct { // TODO: implement this to actually work right // this fn is a stub! pub fn rangeOfIdentifier(source: *const Source, loc: logger.Loc) logger.Range { + if (loc.start == -1) return logger.Range.None; const text = source.contents[loc.toUsize()..]; var r = logger.Range{ .loc = loc, .len = 0 }; if (text.len == 0) { diff --git a/src/js_parser/js_parser.zig b/src/js_parser/js_parser.zig index 274b79c20..a0ce4252f 100644 --- a/src/js_parser/js_parser.zig +++ b/src/js_parser/js_parser.zig @@ -10643,23 +10643,39 @@ pub fn NewParser( .classic => { // Arguments to createElement() const args = p.allocator.alloc(Expr, 2 + children_count) catch unreachable; + // There are at least two args: + // - name of the tag + // - props var i: usize = 1; args[0] = tag; if (e_.properties.len > 0) { + for (e_.properties) |prop, prop_i| { + if (prop.key) |key| { + e_.properties[prop_i].key = p.visitExpr(key); + } + + if (prop.value) |val| { + e_.properties[prop_i].value = p.visitExpr(val); + } + } + if (e_.key) |key| { - var props = List(G.Property).fromOwnedSlice(p.allocator, e_.properties); - props.append(G.Property{ .key = Expr{ .loc = key.loc, .data = keyExprData }, .value = key }) catch unreachable; - args[1] = p.e(E.Object{ .properties = props.toOwnedSlice() }, expr.loc); + var props = p.allocator.alloc(G.Property, e_.properties.len + 1) catch unreachable; + std.mem.copy(G.Property, props, e_.properties); + props[props.len - 1] = G.Property{ .key = Expr{ .loc = key.loc, .data = keyExprData }, .value = key }; + args[1] = p.e(E.Object{ .properties = props }, expr.loc); } else { args[1] = p.e(E.Object{ .properties = e_.properties }, expr.loc); } + i = 2; } else { args[1] = p.e(E.Null{}, expr.loc); + i = 2; } for (e_.children[0..children_count]) |child| { args[i] = p.visitExpr(child); - i += 1; + i += @intCast(usize, @boolToInt(args[i].data != .e_missing)); } // Call createElement() @@ -11227,9 +11243,9 @@ pub fn NewParser( } // maybe won't do this idk - if (Expr.maybeSimplifyNot(&e_.value, p.allocator)) |exp| { - return exp; - } + // if (Expr.maybeSimplifyNot(&e_.value, p.allocator)) |exp| { + // return exp; + // } }, .un_void => { if (p.exprCanBeRemovedIfUnused(&e_.value)) { diff --git a/src/js_printer.zig b/src/js_printer.zig index bf9286a9d..153a29850 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -3243,7 +3243,7 @@ pub fn NewPrinter( } } - pub fn printModuleExportSymbol(p: *Printer) void { + pub inline fn printModuleExportSymbol(p: *Printer) void { p.print("module.exports"); } @@ -3446,7 +3446,7 @@ pub fn NewPrinter( pub fn printBundledRexport(p: *Printer, name: string, import_record_index: u32) void { p.print("Object.defineProperty("); - p.print("module.exports"); + p.printModuleExportSymbol(); p.print(","); p.printQuotedUTF8(name, true); @@ -3456,13 +3456,11 @@ pub fn NewPrinter( } pub fn printBundledExport(p: *Printer, name: string, identifier: string) void { - p.print("Object.defineProperty("); - p.print("module.exports"); - p.print(","); - p.printQuotedUTF8(name, true); - p.print(",{get: () => ("); + p.printModuleExportSymbol(); + p.print("."); + p.printIdentifier(name); + p.print(" = "); p.printIdentifier(identifier); - p.print("), enumerable: true, configurable: true})"); } pub fn printForLoopInit(p: *Printer, initSt: Stmt) void { @@ -3603,7 +3601,10 @@ pub fn NewPrinter( pub fn printDeclStmt(p: *Printer, is_export: bool, comptime keyword: string, decls: []G.Decl) void { if (rewrite_esm_to_cjs and keyword[0] == 'v' and is_export) { // this is a top-level export - if (decls.len == 1 and std.meta.activeTag(decls[0].binding.data) == .b_identifier and decls[0].binding.data.b_identifier.ref.eql(p.options.bundle_export_ref.?)) { + if (decls.len == 1 and + std.meta.activeTag(decls[0].binding.data) == .b_identifier and + decls[0].binding.data.b_identifier.ref.eql(p.options.bundle_export_ref.?)) + { p.print("// "); p.print(p.options.source_path.?.pretty); p.print("\nexport var $"); diff --git a/src/json_parser.zig b/src/json_parser.zig index 8f8f415f3..4bb20f1cc 100644 --- a/src/json_parser.zig +++ b/src/json_parser.zig @@ -142,7 +142,7 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { try p.lexer.next(); var is_single_line = !p.lexer.has_newline_before; var properties = std.ArrayList(G.Property).init(p.allocator); - var duplicates = std.BufSet.init(p.allocator); + var duplicates = std.AutoHashMap(u64, void).init(p.allocator); defer duplicates.deinit(); while (p.lexer.token != .t_close_brace) { @@ -159,13 +159,13 @@ fn JSONLikeParser(opts: js_lexer.JSONOptions) type { } var str = p.lexer.toEString(); - const is_duplicate = duplicates.contains(p.lexer.string_literal_slice); - if (!is_duplicate) { - duplicates.insert(p.lexer.string_literal_slice) catch unreachable; - } + const hash_key = str.hash(); + const duplicate_get_or_put = duplicates.getOrPut(hash_key) catch unreachable; + duplicate_get_or_put.key_ptr.* = hash_key; + var key_range = p.lexer.range(); // Warn about duplicate keys - if (is_duplicate) { + if (duplicate_get_or_put.found_existing) { p.log.addRangeWarningFmt(p.source, key_range, p.allocator, "Duplicate key \"{s}\" in object literal", .{p.lexer.string_literal_slice}) catch unreachable; } diff --git a/src/node-fallbacks/@vercel_fetch.js b/src/node-fallbacks/@vercel_fetch.js index 5ab626670..95314ba9e 100644 --- a/src/node-fallbacks/@vercel_fetch.js +++ b/src/node-fallbacks/@vercel_fetch.js @@ -1,6 +1,8 @@ // This is just a no-op. Intent is to prevent importing a bunch of stuff that isn't relevant. -module.exports = (wrapper = Bun.fetch) => { - return async function vercelFetch(url, opts = {}) { +module.exports = ( + wrapper = "Bun" in globalThis ? Bun.fetch : globalThis.fetch +) => { + async function vercelFetch(url, opts = {}) { // Convert Object bodies to JSON if they are JS objects if ( opts.body && @@ -27,5 +29,8 @@ module.exports = (wrapper = Bun.fetch) => { err.opts = opts; throw err; } - }; + } + + vercelFetch.default = vercelFetch; + return vercelFetch; }; diff --git a/src/node-fallbacks/isomorphic-fetch.js b/src/node-fallbacks/isomorphic-fetch.js index 0bbe50ebf..96cbd72fb 100644 --- a/src/node-fallbacks/isomorphic-fetch.js +++ b/src/node-fallbacks/isomorphic-fetch.js @@ -1 +1 @@ -export default Bun.fetch; +export default "Bun" in globalThis ? Bun.fetch : globalThis.fetch; diff --git a/src/node-fallbacks/node-fetch.js b/src/node-fallbacks/node-fetch.js index 0bbe50ebf..96cbd72fb 100644 --- a/src/node-fallbacks/node-fetch.js +++ b/src/node-fallbacks/node-fetch.js @@ -1 +1 @@ -export default Bun.fetch; +export default "Bun" in globalThis ? Bun.fetch : globalThis.fetch; diff --git a/src/options.zig b/src/options.zig index 30f8dc018..a1c96dc1e 100644 --- a/src/options.zig +++ b/src/options.zig @@ -1611,6 +1611,10 @@ pub const Framework = struct { resolved: bool = false, from_bundle: bool = false, + resolved_dir: string = "", + override_modules: Api.StringMap = Api.StringMap{}, + override_modules_hashes: []u64 = &[_]u64{}, + client_css_in_js: Api.CssInJsBehavior = .auto_onimportcss, pub const fallback_html: string = @embedFile("./fallback.html"); @@ -1633,6 +1637,7 @@ pub const Framework = struct { .from_bundle = true, .client_css_in_js = loaded.client_css_in_js, .display_name = loaded.display_name, + .override_modules = loaded.override_modules, }; if (loaded.entry_points.fallback) |fallback| { @@ -1667,6 +1672,7 @@ pub const Framework = struct { .server = try this.server.toAPI(allocator, toplevel_path, .server), }, .client_css_in_js = this.client_css_in_js, + .override_modules = this.override_modules, }; } @@ -1701,6 +1707,7 @@ pub const Framework = struct { .package = transform.package orelse "", .display_name = transform.display_name orelse "", .development = transform.development orelse true, + .override_modules = transform.override_modules orelse .{ .keys = &.{}, .values = &.{} }, .resolved = false, .client_css_in_js = switch (transform.client_css_in_js orelse .auto_onimportcss) { .facade_onimportcss => .facade_onimportcss, diff --git a/src/query_string_map.zig b/src/query_string_map.zig index ddf90750f..4c451806d 100644 --- a/src/query_string_map.zig +++ b/src/query_string_map.zig @@ -226,7 +226,12 @@ pub const URL = struct { } if (base.len > path_offset and base[path_offset] == '/' and offset > 0) { - url.pathname = base[path_offset..std.math.min(offset, base.len)]; + if (url.search.len > 0) { + url.pathname = base[path_offset..std.math.min(offset + url.search.len, base.len)]; + } else { + url.pathname = base[path_offset..std.math.min(offset, base.len)]; + } + url.origin = base[0..path_offset]; } diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig index 4547be9db..972feb06c 100644 --- a/src/resolver/package_json.zig +++ b/src/resolver/package_json.zig @@ -108,6 +108,29 @@ pub const PackageJSON = struct { } } + fn loadOverrides( + framework: *options.Framework, + json: *const js_ast.E.Object, + allocator: *std.mem.Allocator, + ) void { + var valid_count: usize = 0; + for (json.properties) |prop| { + if (prop.value.?.data != .e_string) continue; + valid_count += 1; + } + + var buffer = allocator.alloc([]const u8, valid_count * 2) catch unreachable; + var keys = buffer[0 .. buffer.len / 2]; + var values = buffer[keys.len..]; + var i: usize = 0; + for (json.properties) |prop| { + if (prop.value.?.data != .e_string) continue; + keys[i] = prop.key.?.data.e_string.string(allocator) catch unreachable; + values[i] = prop.value.?.data.e_string.string(allocator) catch unreachable; + } + framework.override_modules = Api.StringMap{ .keys = keys, .values = values }; + } + fn loadDefineExpression( env: *options.Env, json: *const js_ast.E.Object, @@ -178,6 +201,12 @@ pub const PackageJSON = struct { } } + if (json.asProperty("override")) |override| { + if (override.expr.data == .e_object) { + loadOverrides(framework, override.expr.data.e_object, allocator); + } + } + if (comptime read_define) { if (json.asProperty("define")) |defines| { var skip_fallback = false; diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index 4d8f91881..5cf860a88 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -509,6 +509,8 @@ pub fn NewResolver(cache_files: bool) type { var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; + pair.framework.resolved_dir = pkg.source.path.sourceDir(); + if (pair.framework.client.isEnabled()) { var parts = [_]string{ dir, pair.framework.client.path }; const abs = r.fs.abs(&parts); diff --git a/src/runtime.js b/src/runtime.js index bcfd4c3fb..98cea8b8a 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -37,6 +37,7 @@ export var __toModule = (module) => { ); }; +var tagSymbol = Symbol("CommonJSTransformed"); export var __commonJS = (cb, name) => { var mod = {}; var has_run = false; @@ -59,21 +60,8 @@ export var __commonJS = (cb, name) => { if ( kind === "object" && "default" in mod.exports && - Object.keys(mod.exports).len === 1 - ) { - mod.exports = mod.exports.default; - Object.defineProperty(mod.exports, "default", { - get() { - return mod.exports; - }, - enumerable: true, - configurable: true, - }); - // If it's a namespace export without .default, pretend .default is the same as mod.exports - } else if ( - kind === "object" && - "default" in mod.exports && - Object.keys(mod.exports).len === 1 + !mod.exports[tagSymbol] && + Object.keys(mod.exports).length === 1 ) { mod.exports = mod.exports.default; Object.defineProperty(mod.exports, "default", { @@ -101,6 +89,14 @@ export var __commonJS = (cb, name) => { }); } + if (kind === "object" && !mod.exports[tagSymbol]) { + Object.defineProperty(mod.exports, tagSymbol, { + value: true, + enumerable: false, + configurable: false, + }); + } + return mod.exports; }, }[`require(${name})`]; diff --git a/src/runtime.version b/src/runtime.version index b309f488e..d4f951e04 100644 --- a/src/runtime.version +++ b/src/runtime.version @@ -1 +1 @@ -a36793f60275e5e9
\ No newline at end of file +c525e78958fc519b
\ No newline at end of file diff --git a/src/runtime.zig b/src/runtime.zig index 32c5f752e..7af295957 100644 --- a/src/runtime.zig +++ b/src/runtime.zig @@ -8,25 +8,23 @@ const Schema = @import("./api/schema.zig"); const Api = Schema.Api; -const ErrorCSSPath = "../examples/hello-next/bun-framework-next/bun-error.css"; +const ErrorCSSPath = "packages/bun-framework-next/bun-error.css"; pub const ErrorCSS = struct { pub const ProdSourceContent = @embedFile(ErrorCSSPath); pub fn sourceContent() string { if (comptime isDebug) { - var dirpath = std.fs.path.dirname(@src().file).?; var env = std.process.getEnvMap(default_allocator) catch unreachable; - - const dir = std.mem.replaceOwned( - u8, - default_allocator, - dirpath, - "jarred", - env.get("USER").?, + var out_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; + var dirname = std.fs.selfExeDirPath(&out_buffer) catch unreachable; + var paths = [_]string{ dirname, "../../../", ErrorCSSPath }; + const file = std.fs.cwd().openFile( + resolve_path.joinAbsString(dirname, std.mem.span(&paths), .auto), + .{ + .read = true, + }, ) catch unreachable; - var runtime_path = std.fs.path.join(default_allocator, &[_]string{ dir, ErrorCSSPath }) catch unreachable; - const file = std.fs.openFileAbsolute(runtime_path, .{}) catch unreachable; defer file.close(); return file.readToEndAlloc(default_allocator, (file.stat() catch unreachable).size) catch unreachable; } else { diff --git a/src/runtime/hmr.ts b/src/runtime/hmr.ts index dc72f469d..5c91683a2 100644 --- a/src/runtime/hmr.ts +++ b/src/runtime/hmr.ts @@ -611,7 +611,6 @@ if (typeof window !== "undefined") { this.client.verbose = verbose; this.client.start(); globalThis["__BUN_HMR"] = this.client; - globalThis["__BUN"] = this; } handleBuildFailure(buffer: ByteBuffer, timestamp: number) { @@ -1341,6 +1340,7 @@ if (typeof window !== "undefined") { window.addEventListener("error", HMRClient.onError, { passive: true }); } + globalThis["__BUN"] = HMRClient; } export { __HMRModule, __FastRefreshModule, __HMRClient }; diff --git a/src/string_immutable.zig b/src/string_immutable.zig index a68059aef..923d860cc 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -660,6 +660,21 @@ pub const CodepointIterator = struct { return if (!(it.i > it.bytes.len)) it.bytes[it.i - cp_len .. it.i] else ""; } + pub fn needsUTF8Decoding(slice: string) bool { + var it = CodepointIterator{ .bytes = slice, .i = 0 }; + + while (true) { + const part = it.nextCodepointSlice(); + it.width = @intCast(u3, part.len); + @setRuntimeSafety(false); + switch (it.width) { + 0 => return false, + 1 => continue, + else => return true, + } + } + } + pub fn nextCodepoint(it: *CodepointIterator) CodePoint { const slice = it.nextCodepointSlice(); it.width = @intCast(u3, slice.len); |