diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bunfig.zig | 93 | ||||
-rw-r--r-- | src/install/install.zig | 12 | ||||
-rw-r--r-- | src/install/npm.zig | 56 |
3 files changed, 112 insertions, 49 deletions
diff --git a/src/bunfig.zig b/src/bunfig.zig index bb52e3053..63a6c389d 100644 --- a/src/bunfig.zig +++ b/src/bunfig.zig @@ -55,59 +55,68 @@ pub const Bunfig = struct { return error.@"Invalid Bunfig"; } - fn parseRegistry(this: *Parser, expr: js_ast.Expr) !Api.NpmRegistry { + fn parseRegistryURLString(this: *Parser, str: *js_ast.E.String) !Api.NpmRegistry { + const url = URL.parse(str.data); + var registry = std.mem.zeroes(Api.NpmRegistry); + + // Token + if (url.username.len == 0 and url.password.len > 0) { + registry.token = url.password; + registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{}/{s}/", .{ url.displayProtocol(), url.displayHost(), std.mem.trim(u8, url.pathname, "/") }); + } else if (url.username.len > 0 and url.password.len > 0) { + registry.username = url.username; + registry.password = url.password; + + registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{}/{s}/", .{ url.displayProtocol(), url.displayHost(), std.mem.trim(u8, url.pathname, "/") }); + } else { + // Do not include a trailing slash. There might be parameters at the end. + registry.url = url.href; + } + + return registry; + } + + fn parseRegistryObject(this: *Parser, obj: *js_ast.E.Object) !Api.NpmRegistry { var registry = std.mem.zeroes(Api.NpmRegistry); + if (obj.get("url")) |url| { + try this.expect(url, .e_string); + const href = url.data.e_string.data; + // Do not include a trailing slash. There might be parameters at the end. + registry.url = href; + } + + if (obj.get("username")) |username| { + try this.expect(username, .e_string); + registry.username = username.data.e_string.data; + } + + if (obj.get("password")) |password| { + try this.expect(password, .e_string); + registry.password = password.data.e_string.data; + } + + if (obj.get("token")) |token| { + try this.expect(token, .e_string); + registry.token = token.data.e_string.data; + } + + return registry; + } + + fn parseRegistry(this: *Parser, expr: js_ast.Expr) !Api.NpmRegistry { switch (expr.data) { .e_string => |str| { - const url = URL.parse(str.data); - // Token - if (url.username.len == 0 and url.password.len > 0) { - registry.token = url.password; - registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{s}/{s}/", .{ url.displayProtocol(), url.displayHostname(), std.mem.trim(u8, url.pathname, "/") }); - } else if (url.username.len > 0 and url.password.len > 0) { - registry.username = url.username; - registry.password = url.password; - registry.url = try std.fmt.allocPrint(this.allocator, "{s}://{s}/{s}/", .{ url.displayProtocol(), url.displayHostname(), std.mem.trim(u8, url.pathname, "/") }); - } else { - if (strings.hasSuffixComptime(url.href, "/")) { - registry.url = url.href; - } else { - registry.url = try std.fmt.allocPrint(this.allocator, "{s}/", .{url.href}); - } - } + return this.parseRegistryURLString(str); }, .e_object => |obj| { - if (obj.get("url")) |url| { - try this.expect(url, .e_string); - if (strings.hasSuffixComptime(url.data.e_string.data, "/")) { - registry.url = url.data.e_string.data; - } else { - registry.url = try std.fmt.allocPrint(this.allocator, "{s}/", .{url.data.e_string.data}); - } - } - - if (obj.get("username")) |username| { - try this.expect(username, .e_string); - registry.username = username.data.e_string.data; - } - - if (obj.get("password")) |password| { - try this.expect(password, .e_string); - registry.password = password.data.e_string.data; - } - - if (obj.get("token")) |token| { - try this.expect(token, .e_string); - registry.token = token.data.e_string.data; - } + return this.parseRegistryObject(obj); }, else => { try this.addError(expr.loc, "Expected registry to be a URL string or an object"); + return std.mem.zeroes(Api.NpmRegistry); }, } - - return registry; } fn loadLogLevel(this: *Parser, expr: js_ast.Expr) !void { diff --git a/src/install/install.zig b/src/install/install.zig index c7a2816a5..3757a6980 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -273,8 +273,8 @@ const NetworkTask = struct { if (tmp.tag == .Dead) { const msg = .{ - .fmt = "Failed to join registry \"{s}\" and package \"{s}\" URLs", - .args = .{ scope.url.href, name }, + .fmt = "Failed to join registry {} and package {} URLs", + .args = .{ strings.QuotedFormatter{ .text = scope.url.href }, strings.QuotedFormatter{ .text = name } }, }; if (warn_on_error) @@ -3806,10 +3806,10 @@ pub const PackageManager = struct { switch (response.status_code) { 404 => { if (comptime log_level != .silent) { - const fmt = "\n<r><red>error<r>: package <b>\"{s}\"<r> not found <d>{s}{s} 404<r>\n"; + const fmt = "\n<r><red>error<r>: package <b>\"{s}\"<r> not found <d>{}{s} 404<r>\n"; const args = .{ name.slice(), - task.http.url.displayHostname(), + task.http.url.displayHost(), task.http.url.pathname, }; @@ -3823,10 +3823,10 @@ pub const PackageManager = struct { }, 401 => { if (comptime log_level != .silent) { - const fmt = "\n<r><red>error<r>: unauthorized <b>\"{s}\"<r> <d>{s}{s} 401<r>\n"; + const fmt = "\n<r><red>error<r>: unauthorized <b>\"{s}\"<r> <d>{}{s} 401<r>\n"; const args = .{ name.slice(), - task.http.url.displayHostname(), + task.http.url.displayHost(), task.http.url.pathname, }; diff --git a/src/install/npm.zig b/src/install/npm.zig index fec545b0c..24e631836 100644 --- a/src/install/npm.zig +++ b/src/install/npm.zig @@ -81,6 +81,7 @@ pub const Registry = struct { var url = URL.parse(registry.url); var auth: string = ""; + var needs_normalize = false; if (registry.token.len == 0) { outer: { @@ -90,10 +91,12 @@ pub const Registry = struct { url.pathname = pathname; url.path = pathname; } - + var needs_to_check_slash = true; while (strings.lastIndexOfChar(pathname, ':')) |colon| { var segment = pathname[colon + 1 ..]; pathname = pathname[0..colon]; + needs_to_check_slash = false; + needs_normalize = true; if (pathname.len > 1 and pathname[pathname.len - 1] == '/') { pathname = pathname[0 .. pathname.len - 1]; } @@ -124,6 +127,47 @@ pub const Registry = struct { continue; } } + + // In this case, there is only one. + if (needs_to_check_slash) { + if (strings.lastIndexOfChar(pathname, '/')) |last_slash| { + var remain = pathname[last_slash + 1 ..]; + if (strings.indexOfChar(remain, '=')) |eql_i| { + const segment = remain[0..eql_i]; + var value = remain[eql_i + 1 ..]; + + // https://github.com/yarnpkg/yarn/blob/6db39cf0ff684ce4e7de29669046afb8103fce3d/src/registries/npm-registry.js#L364 + // Bearer Token + if (strings.eqlComptime(segment, "_authToken")) { + registry.token = value; + pathname = pathname[0 .. last_slash + 1]; + needs_normalize = true; + break :outer; + } + + if (strings.eqlComptime(segment, "_auth")) { + auth = value; + pathname = pathname[0 .. last_slash + 1]; + needs_normalize = true; + break :outer; + } + + if (strings.eqlComptime(segment, "username")) { + registry.username = value; + pathname = pathname[0 .. last_slash + 1]; + needs_normalize = true; + break :outer; + } + + if (strings.eqlComptime(segment, "_password")) { + registry.password = value; + pathname = pathname[0 .. last_slash + 1]; + needs_normalize = true; + break :outer; + } + } + } + } } registry.username = env.getAuto(registry.username); @@ -144,6 +188,16 @@ pub const Registry = struct { registry.token = env.getAuto(registry.token); + if (needs_normalize) { + url = URL.parse( + try std.fmt.allocPrint(allocator, "{s}://{}/{s}/", .{ + url.displayProtocol(), + url.displayHost(), + strings.trim(url.pathname, "/"), + }), + ); + } + return Scope{ .name = name, .url = url, .token = registry.token, .auth = auth }; } }; |