╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────────╮ │src/test/undo.zig│ ╰─────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │82 defer user_repo.deinit(io, allocator); │ │83 try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, &.{ │ │84 .{ .id = std.fmt.bytesToHex(repo_id, .lower), .author = author, .event = .{ .repo = repo_event } }, │ │85 - .{ .id = std.fmt.bytesToHex(evt.Grant.idOf(&repo_id, &writer), .lower), .author = author, .event = .{ .grant = .{ .target_id = &repo_id, .user_id = &writer, .role = .write } } }, │ │85 + .{ .id = std.fmt.bytesToHex(evt.Grant.idOf(&repo_id, &writer), .lower), .author = author, .event = .{ .grant = .{ .target_id = std.fmt.bytesToHex(repo_id, .lower), .user_id = writer_hex, .role = .write } } },│ │86 }); │ │87 const path = try evt.repoPath(aa, users_dir, &owner, &repo_id); │ │88 { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │129 try std.testing.expectEqualStrings("undo", data.items[0].action); │ │130 } │ │131 // keep the old session/page moment, but transfer ownership to the writer. │ │132 - repo_event.user_id = &writer; │ │132 + repo_event.user_id = writer_hex; │ │133 try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, &.{.{ .id = std.fmt.bytesToHex(repo_id, .lower), .author = author, .event = .{ .repo = repo_event } }});│ │134 session.next_page = null; │ │135 Undo.handleRequest(allocator, &session, ui.RoutablePage.repoUndoRoute("alice:demo", 1).?.repo_undo); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │137 try std.testing.expectEqual(null, session.next_page); │ │138 │ │139 // public-write repos still require login for history and undo. │ │140 - repo_event.user_id = &owner; │ │140 + repo_event.user_id = std.fmt.bytesToHex(owner, .lower); │ │141 repo_event.write_access = .public; │ │142 try evt.consume(.{ .server = .{ .users_dir = users_dir } }, .user, .xit, evt.user_repo_opts, io, allocator, &user_repo, evt.events_ref, &.{.{ .id = std.fmt.bytesToHex(repo_id, .lower), .author = author, .event = .{ .repo = repo_event } }});│ │143 var anonymous = try ui.Session.init(&arena, &admin, .{}); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/try.zig│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │250 .author = author, │ │251 .event = .{ │ │252 .repo = .{ │ │253 - .user_id = &user_ids[r.user_index], │ │253 + .user_id = std.fmt.bytesToHex(user_ids[r.user_index], .lower),│ │254 .name = r.name, │ │255 .description = r.description, │ │256 .read_access = r.read_access, │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │264 .id = std.fmt.bytesToHex(evt.Grant.idOf(&repo_event_ids[i], &admin_user_id), .lower), │ │265 .timestamp = seedTimestamp(now, i, repo_data.len, 90 * std.time.s_per_day, 70 * std.time.s_per_day), │ │266 .author = author, │ │267 - .event = .{ .grant = .{ .target_id = &repo_event_ids[i], .user_id = &admin_user_id, .role = .owner } }, │ │267 + .event = .{ .grant = .{ .target_id = std.fmt.bytesToHex(repo_event_ids[i], .lower), .user_id = std.fmt.bytesToHex(admin_user_id, .lower), .role = .owner } },│ │268 }; │ │269 } │ │270 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─╮ │src/ui.zig│ ╰──────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │2191 .author = .{ .name = user.event.name, .email = user.event.email },│ │2192 .user_id = user_id, │ │2193 .role = role, │ │2194 - .repo_user_id = repo.repo.event.user_id[0..evt.event_id_size].*, │ │2194 + .repo_user_id = try evt.parseEventId(&repo.repo.event.user_id), │ │2195 } }; │ │2196 } │ │2197 │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Fork.zig│ ╰───────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │41 const forker_id = (try evt.User.readIdByName(evt.AdminDB, evt.admin_repo_opts.hash, haxy_moment, identity.owner)) orelse return error.NotFound;│ │42 const fork_record = (try evt.readForkById(io, gpa, arena, users_dir, &forker_id, &id)) orelse return error.NotFound; │ │43 if (fork_record.removed) return error.NotFound; │ │44 - if (fork_record.event.repo_id.len != evt.event_id_size) return error.NotFound; │ │45 - var target_id: [evt.event_id_size]u8 = undefined; │ │46 - @memcpy(&target_id, fork_record.event.repo_id); │ │47 - const owner_id = fork_record.event.repo_user_id[0..evt.event_id_size]; │ │44 + const target_id = try evt.parseEventId(&fork_record.event.repo_id); │ │45 + const owner_id = try evt.parseEventId(&fork_record.event.repo_user_id); │ │46 │ │49 - const target = (try evt.readRepoById(io, gpa, arena, users_dir, owner_id, &target_id, session.userId())) orelse return error.NotFound; │ │47 + const target = (try evt.readRepoById(io, gpa, arena, users_dir, &owner_id, &target_id, session.userId())) orelse return error.NotFound; │ │48 // a draft is as readable as the repo it targets │ │49 const target_role = target.role orelse return error.NotFound; │ │50 const target_record = target.repo; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │51 // patches that are off take their drafts with them │ │52 if (target_record.event.patch_role == null) return error.NotFound; │ │55 - const owner = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, haxy_moment, arena, owner_id)) orelse return error.NotFound; │ │53 + const owner = (try evt.User.readById(evt.AdminDB, evt.admin_repo_opts.hash, haxy_moment, arena, &owner_id)) orelse return error.NotFound;│ │54 if (!std.mem.eql(u8, target_record.event.name, identity.name)) return error.NotFound; │ │55 │ │56 const aa = arena.allocator(); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │78 @memcpy(&commits_base_oid, revision.record.event.base_oid); │ │79 } │ │80 │ │83 - const target_path = try evt.repoPath(aa, users_dir, owner_id, &target_id); │ │81 + const target_path = try evt.repoPath(aa, users_dir, &owner_id, &target_id); │ │82 const target_source = ui.RepoSource{ .path = target_path, .repo_kind = .xit }; │ │83 var target_repo_maybe: ?rp.Repo(.xit, repo_opts) = if (!target_record.removed) │ │84 rp.Repo(.xit, repo_opts).open(io, arena.child_allocator, target_source.localInitOpts()) catch null│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Repo.zig│ ╰───────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │229 // knows all three; the server paths resolve them from the admin db.│ │230 var source: ?ui.RepoSource = null; │ │231 var repo_id_maybe: ?[evt.event_id_size]u8 = null; │ │232 + // local mode has no owner │ │233 + var owner_id: [evt.event_id_size]u8 = @splat(0); │ │234 var repo: evt.Repo.Record = undefined; │ │235 // local mode owns its repo │ │236 var role: evt.Repo.Role = .owner; │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯