A personal media tracker built on the AT Protocol opnshelf.xyz
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Sanitize onboarding import errors and harden import handling

- Add shared onboarding error helpers for web and mobile
- Map backend import failures to safe user-facing messages
- Handle account deletion completion once and add coverage
- Ensure show metadata is upserted before seasons

+1068 -136
+24 -18
apps/mobile/app/onboarding.tsx
··· 45 45 validateAvatarAsset, 46 46 } from "@/lib/avatar-upload"; 47 47 import { 48 + buildImportErrorList, 49 + getSafeOnboardingErrorMessage, 50 + } from "@/lib/onboarding-errors"; 51 + import { 48 52 type ImportProgressUpdate, 49 53 parseCsvText, 50 54 runImportInChunks, ··· 338 342 setFollowImportStatus("success"); 339 343 } catch (error) { 340 344 setFollowImportStatus("error"); 341 - const message = 342 - error instanceof Error 343 - ? error.message 344 - : "Could not import Bluesky following"; 345 + const message = getSafeOnboardingErrorMessage( 346 + error, 347 + "Could not import Bluesky following", 348 + ); 345 349 showToast(message, "error"); 346 350 } 347 351 }; ··· 431 435 message: `Preview ready for @${fetched.profile.username}`, 432 436 })); 433 437 } catch (error) { 434 - const message = 435 - error instanceof Error 436 - ? error.message 437 - : "Unable to fetch Trakt history right now"; 438 + const message = getSafeOnboardingErrorMessage( 439 + error, 440 + "Could not fetch Trakt history right now.", 441 + ); 438 442 setImportProgress((previous) => ({ 439 443 ...previous, 440 444 phase: "error", ··· 467 471 })); 468 472 showToast(`Background import started for @${started.profile.username}`); 469 473 } catch (error) { 470 - const message = 471 - error instanceof Error 472 - ? error.message 473 - : "Unable to import Trakt history right now"; 474 + const message = getSafeOnboardingErrorMessage( 475 + error, 476 + "Could not start the Trakt import right now.", 477 + ); 474 478 setImportProgress((previous) => ({ 475 479 ...previous, 476 480 phase: "error", ··· 546 550 imported: imported.imported, 547 551 skipped: imported.skipped, 548 552 failed: imported.failed + parsed.errors.length, 549 - errors: [ 550 - ...parsed.errors.map((entry) => entry.message), 551 - ...imported.errors, 552 - ], 553 + errors: buildImportErrorList( 554 + parsed.errors.map((entry) => entry.message), 555 + imported.errors, 556 + ), 553 557 }); 554 558 555 559 setImportProgress((previous) => ({ ··· 561 565 562 566 setStep(5); 563 567 } catch (error) { 564 - const message = 565 - error instanceof Error ? error.message : "Unable to parse CSV file"; 568 + const message = getSafeOnboardingErrorMessage( 569 + error, 570 + "Could not import your history right now.", 571 + ); 566 572 setImportProgress((previous) => ({ 567 573 ...previous, 568 574 phase: "error",
+85
apps/mobile/lib/onboarding-errors.ts
··· 1 + const SAFE_ONBOARDING_MESSAGES = new Set([ 2 + "This watch was already imported.", 3 + "We couldn't fetch details for this title right now.", 4 + "We couldn't save this watch right now. Please try again.", 5 + "We couldn't import this item.", 6 + "Trakt user not found", 7 + "Trakt profile is private or unavailable. Try CSV import instead.", 8 + "Trakt rate limit reached. We will retry in the background shortly.", 9 + "Trakt is temporarily unavailable. Please retry later or use CSV import.", 10 + ]); 11 + 12 + const MAX_VISIBLE_IMPORT_ERRORS = 10; 13 + 14 + export function getSafeOnboardingErrorMessage( 15 + error: unknown, 16 + fallback: string, 17 + ): string { 18 + const message = getNestedStringMessage(error); 19 + if (message && SAFE_ONBOARDING_MESSAGES.has(message)) { 20 + return message; 21 + } 22 + 23 + return fallback; 24 + } 25 + 26 + export function getSafeImportErrorMessage(message: string): string { 27 + return SAFE_ONBOARDING_MESSAGES.has(message) 28 + ? message 29 + : "We couldn't import this item."; 30 + } 31 + 32 + export function buildImportErrorList( 33 + localMessages: string[], 34 + serverMessages: string[], 35 + ): string[] { 36 + const uniqueMessages = Array.from( 37 + new Set([ 38 + ...localMessages, 39 + ...serverMessages.map((message) => getSafeImportErrorMessage(message)), 40 + ]), 41 + ); 42 + 43 + if (uniqueMessages.length <= MAX_VISIBLE_IMPORT_ERRORS) { 44 + return uniqueMessages; 45 + } 46 + 47 + const remainingCount = uniqueMessages.length - MAX_VISIBLE_IMPORT_ERRORS; 48 + return [ 49 + ...uniqueMessages.slice(0, MAX_VISIBLE_IMPORT_ERRORS), 50 + `...and ${remainingCount} more`, 51 + ]; 52 + } 53 + 54 + function getNestedStringMessage(error: unknown): string | null { 55 + if (typeof error === "string" && error.trim() !== "") { 56 + return error; 57 + } 58 + 59 + if (!error || typeof error !== "object") { 60 + return null; 61 + } 62 + 63 + if ("message" in error) { 64 + const { message } = error as { message?: unknown }; 65 + if (typeof message === "string" && message.trim() !== "") { 66 + return message; 67 + } 68 + } 69 + 70 + if ("body" in error) { 71 + const nested = getNestedStringMessage((error as { body?: unknown }).body); 72 + if (nested) { 73 + return nested; 74 + } 75 + } 76 + 77 + if ("error" in error) { 78 + const nested = getNestedStringMessage((error as { error?: unknown }).error); 79 + if (nested) { 80 + return nested; 81 + } 82 + } 83 + 84 + return null; 85 + }
+52
apps/web/src/lib/onboarding-errors.test.ts
··· 1 + import { describe, expect, it } from "vitest"; 2 + import { 3 + buildImportErrorList, 4 + getSafeImportErrorMessage, 5 + getSafeOnboardingErrorMessage, 6 + } from "./onboarding-errors"; 7 + 8 + describe("onboarding error helpers", () => { 9 + it("falls back for raw backend errors", () => { 10 + expect( 11 + getSafeOnboardingErrorMessage( 12 + new Error("Unique constraint failed on the fields: (`rkey`)"), 13 + "Could not import your history right now.", 14 + ), 15 + ).toBe("Could not import your history right now."); 16 + }); 17 + 18 + it("preserves allowlisted safe backend messages", () => { 19 + expect( 20 + getSafeOnboardingErrorMessage( 21 + { body: { message: "Trakt user not found" } }, 22 + "Could not fetch Trakt history right now.", 23 + ), 24 + ).toBe("Trakt user not found"); 25 + }); 26 + 27 + it("sanitizes server import errors, deduplicates them, and caps the visible list", () => { 28 + const errors = buildImportErrorList( 29 + ["Row 2: invalid watched_at"], 30 + [ 31 + "Unique constraint failed on the fields: (`rkey`)", 32 + "We couldn't fetch details for this title right now.", 33 + "We couldn't fetch details for this title right now.", 34 + ...Array.from({ length: 10 }, (_, index) => `raw error ${index + 1}`), 35 + ], 36 + ); 37 + 38 + expect(errors).toEqual([ 39 + "Row 2: invalid watched_at", 40 + "We couldn't import this item.", 41 + "We couldn't fetch details for this title right now.", 42 + ]); 43 + }); 44 + 45 + it("keeps sanitized import messages unchanged", () => { 46 + expect( 47 + getSafeImportErrorMessage( 48 + "We couldn't fetch details for this title right now.", 49 + ), 50 + ).toBe("We couldn't fetch details for this title right now."); 51 + }); 52 + });
+85
apps/web/src/lib/onboarding-errors.ts
··· 1 + const SAFE_ONBOARDING_MESSAGES = new Set([ 2 + "This watch was already imported.", 3 + "We couldn't fetch details for this title right now.", 4 + "We couldn't save this watch right now. Please try again.", 5 + "We couldn't import this item.", 6 + "Trakt user not found", 7 + "Trakt profile is private or unavailable. Try CSV import instead.", 8 + "Trakt rate limit reached. We will retry in the background shortly.", 9 + "Trakt is temporarily unavailable. Please retry later or use CSV import.", 10 + ]); 11 + 12 + const MAX_VISIBLE_IMPORT_ERRORS = 10; 13 + 14 + export function getSafeOnboardingErrorMessage( 15 + error: unknown, 16 + fallback: string, 17 + ): string { 18 + const message = getNestedStringMessage(error); 19 + if (message && SAFE_ONBOARDING_MESSAGES.has(message)) { 20 + return message; 21 + } 22 + 23 + return fallback; 24 + } 25 + 26 + export function getSafeImportErrorMessage(message: string): string { 27 + return SAFE_ONBOARDING_MESSAGES.has(message) 28 + ? message 29 + : "We couldn't import this item."; 30 + } 31 + 32 + export function buildImportErrorList( 33 + localMessages: string[], 34 + serverMessages: string[], 35 + ): string[] { 36 + const uniqueMessages = Array.from( 37 + new Set([ 38 + ...localMessages, 39 + ...serverMessages.map((message) => getSafeImportErrorMessage(message)), 40 + ]), 41 + ); 42 + 43 + if (uniqueMessages.length <= MAX_VISIBLE_IMPORT_ERRORS) { 44 + return uniqueMessages; 45 + } 46 + 47 + const remainingCount = uniqueMessages.length - MAX_VISIBLE_IMPORT_ERRORS; 48 + return [ 49 + ...uniqueMessages.slice(0, MAX_VISIBLE_IMPORT_ERRORS), 50 + `...and ${remainingCount} more`, 51 + ]; 52 + } 53 + 54 + function getNestedStringMessage(error: unknown): string | null { 55 + if (typeof error === "string" && error.trim() !== "") { 56 + return error; 57 + } 58 + 59 + if (!error || typeof error !== "object") { 60 + return null; 61 + } 62 + 63 + if ("message" in error) { 64 + const { message } = error as { message?: unknown }; 65 + if (typeof message === "string" && message.trim() !== "") { 66 + return message; 67 + } 68 + } 69 + 70 + if ("body" in error) { 71 + const nested = getNestedStringMessage((error as { body?: unknown }).body); 72 + if (nested) { 73 + return nested; 74 + } 75 + } 76 + 77 + if ("error" in error) { 78 + const nested = getNestedStringMessage((error as { error?: unknown }).error); 79 + if (nested) { 80 + return nested; 81 + } 82 + } 83 + 84 + return null; 85 + }
+11 -8
apps/web/src/routes/-onboarding.test.tsx
··· 285 285 expect(mockFetchTrakt).toHaveBeenCalledWith({ 286 286 body: { username: "alice" }, 287 287 }); 288 - expect(container?.textContent).toContain( 289 - "2 importable items found from 4 Trakt history rows.", 290 - ); 291 - expect(container?.textContent).toContain("Import 2 items"); 288 + expect(container?.textContent).toContain("Trakt profile"); 289 + expect(container?.textContent).toContain("Last played items"); 290 + expect(container?.textContent).toContain("Start import"); 292 291 expect(container?.textContent).not.toContain("Continue"); 293 292 294 293 const confirmImportButton = Array.from( 295 294 container?.querySelectorAll("button") ?? [], 296 - ).find((button) => button.textContent?.includes("Import 2 items")); 295 + ).find((button) => button.textContent?.includes("Start import")); 297 296 298 297 await act(async () => { 299 298 confirmImportButton?.dispatchEvent( ··· 308 307 queryKey: usersControllerGetMyCurrentTraktImportOptions().queryKey, 309 308 }); 310 309 expect(container?.textContent).toContain("Background import"); 311 - expect(container?.textContent).toContain("Queued"); 310 + expect(container?.textContent).toContain( 311 + "We'll keep importing the full Trakt history", 312 + ); 312 313 expect(container?.textContent).toContain("Continue"); 313 314 314 315 act(() => { ··· 317 318 } 318 319 }); 319 320 320 - expect(container?.textContent).not.toContain("Import 2 items"); 321 - expect(container?.textContent).not.toContain("Queued"); 321 + expect(container?.textContent).not.toContain("Start import"); 322 + expect(container?.textContent).not.toContain( 323 + "We'll keep importing the full Trakt history", 324 + ); 322 325 expect(container?.textContent).toContain("Fetch preview"); 323 326 expect(container?.textContent).toContain("Skip import"); 324 327 });
+355
apps/web/src/routes/-profile.$handle.settings.test.tsx
··· 1 + // @vitest-environment jsdom 2 + 3 + import { act } from "react"; 4 + import { createRoot, type Root } from "react-dom/client"; 5 + import { afterEach, describe, expect, it, vi } from "vitest"; 6 + import { SettingsPage } from "./profile.$handle.settings"; 7 + 8 + const mockNavigate = vi.fn(); 9 + const mockUseQuery = vi.fn(); 10 + const mockUseMutation = vi.fn(); 11 + const mockUseQueryClient = vi.fn(); 12 + const mockPublishSignedOutAuthState = vi.fn(); 13 + const mockToastSuccess = vi.fn(); 14 + const mockToastError = vi.fn(); 15 + const mockCapture = vi.fn(); 16 + const mockReset = vi.fn(); 17 + 18 + vi.mock("@tanstack/react-router", () => ({ 19 + createFileRoute: () => () => ({}), 20 + redirect: vi.fn(), 21 + useRouter: () => ({ 22 + navigate: mockNavigate, 23 + }), 24 + })); 25 + 26 + vi.mock("@tanstack/react-query", async (importOriginal) => { 27 + const actual = await importOriginal<typeof import("@tanstack/react-query")>(); 28 + 29 + return { 30 + ...actual, 31 + useQuery: (...args: unknown[]) => mockUseQuery(...args), 32 + useMutation: (...args: unknown[]) => mockUseMutation(...args), 33 + useQueryClient: () => mockUseQueryClient(), 34 + }; 35 + }); 36 + 37 + vi.mock("@posthog/react", () => ({ 38 + usePostHog: () => ({ 39 + capture: mockCapture, 40 + reset: mockReset, 41 + }), 42 + })); 43 + 44 + vi.mock("sonner", () => ({ 45 + toast: { 46 + success: (...args: unknown[]) => mockToastSuccess(...args), 47 + error: (...args: unknown[]) => mockToastError(...args), 48 + }, 49 + })); 50 + 51 + vi.mock("@/components/theme-provider", () => ({ 52 + useTheme: () => ({ seedColor: "#336699" }), 53 + })); 54 + 55 + vi.mock("@/components/AuthLoadingState", () => ({ 56 + AuthLoadingState: ({ className }: { className?: string }) => ( 57 + <div className={className}>Loading...</div> 58 + ), 59 + })); 60 + 61 + vi.mock("@/components/ui/dialog", () => ({ 62 + Dialog: ({ 63 + children, 64 + open, 65 + }: { 66 + children: React.ReactNode; 67 + open?: boolean; 68 + }) => (open ? <div>{children}</div> : null), 69 + DialogContent: ({ children }: { children: React.ReactNode }) => ( 70 + <div>{children}</div> 71 + ), 72 + DialogDescription: ({ children }: { children: React.ReactNode }) => ( 73 + <div>{children}</div> 74 + ), 75 + DialogFooter: ({ children }: { children: React.ReactNode }) => ( 76 + <div>{children}</div> 77 + ), 78 + DialogHeader: ({ children }: { children: React.ReactNode }) => ( 79 + <div>{children}</div> 80 + ), 81 + DialogTitle: ({ children }: { children: React.ReactNode }) => ( 82 + <div>{children}</div> 83 + ), 84 + })); 85 + 86 + vi.mock("@/components/ui/m3-button", () => ({ 87 + M3Button: ({ 88 + children, 89 + ...props 90 + }: { 91 + children: React.ReactNode; 92 + [key: string]: unknown; 93 + }) => <button {...props}>{children}</button>, 94 + })); 95 + 96 + vi.mock("@/components/ui/m3-card", () => ({ 97 + M3Card: ({ children }: { children: React.ReactNode }) => ( 98 + <div>{children}</div> 99 + ), 100 + M3CardContent: ({ children }: { children: React.ReactNode }) => ( 101 + <div>{children}</div> 102 + ), 103 + M3CardDescription: ({ children }: { children: React.ReactNode }) => ( 104 + <div>{children}</div> 105 + ), 106 + M3CardHeader: ({ children }: { children: React.ReactNode }) => ( 107 + <div>{children}</div> 108 + ), 109 + M3CardTitle: ({ children }: { children: React.ReactNode }) => ( 110 + <div>{children}</div> 111 + ), 112 + })); 113 + 114 + vi.mock("@/components/ui/select", () => ({ 115 + Select: ({ children }: { children: React.ReactNode }) => ( 116 + <div>{children}</div> 117 + ), 118 + SelectContent: ({ children }: { children: React.ReactNode }) => ( 119 + <div>{children}</div> 120 + ), 121 + SelectItem: ({ 122 + children, 123 + value, 124 + }: { 125 + children: React.ReactNode; 126 + value: string; 127 + }) => <option value={value}>{children}</option>, 128 + SelectTrigger: ({ children }: { children: React.ReactNode }) => ( 129 + <div>{children}</div> 130 + ), 131 + SelectValue: ({ placeholder }: { placeholder?: string }) => ( 132 + <span>{placeholder}</span> 133 + ), 134 + })); 135 + 136 + vi.mock("@/components/ui/label", () => ({ 137 + Label: ({ 138 + children, 139 + ...props 140 + }: { 141 + children: React.ReactNode; 142 + [key: string]: unknown; 143 + }) => <span {...props}>{children}</span>, 144 + })); 145 + 146 + vi.mock("@/components/ui/skeleton", () => ({ 147 + Skeleton: ({ className }: { className?: string }) => ( 148 + <div className={className} /> 149 + ), 150 + })); 151 + 152 + vi.mock("@/components/ui/switch", () => ({ 153 + Switch: ({ 154 + checked, 155 + onCheckedChange, 156 + disabled, 157 + }: { 158 + checked: boolean; 159 + onCheckedChange: (checked: boolean) => void; 160 + disabled?: boolean; 161 + }) => ( 162 + <input 163 + type="checkbox" 164 + checked={checked} 165 + onChange={(event) => onCheckedChange(event.target.checked)} 166 + disabled={disabled} 167 + /> 168 + ), 169 + })); 170 + 171 + vi.mock("@/lib/auth-cache", () => ({ 172 + publishSignedOutAuthState: (...args: unknown[]) => 173 + mockPublishSignedOutAuthState(...args), 174 + })); 175 + 176 + vi.mock("@/lib/avatar-upload", () => ({ 177 + AVATAR_UPLOAD_HELP_TEXT: "Upload help", 178 + getAvatarUploadErrorMessage: vi.fn(), 179 + validateAvatarFile: vi.fn(), 180 + })); 181 + 182 + vi.mock("@/lib/profile-routes", () => ({ 183 + getProfileRoute: vi.fn(), 184 + isOwnerProfile: vi.fn(() => true), 185 + })); 186 + 187 + vi.mock("@/lib/ssr-auth-headers", () => ({ 188 + getSsrAuthHeaders: vi.fn(), 189 + })); 190 + 191 + vi.mock("@/lib/timezones", () => ({ 192 + TIMEZONE_GROUPS: [], 193 + })); 194 + 195 + declare global { 196 + var IS_REACT_ACT_ENVIRONMENT: boolean; 197 + } 198 + 199 + globalThis.IS_REACT_ACT_ENVIRONMENT = true; 200 + 201 + describe("SettingsPage account deletion", () => { 202 + let container: HTMLDivElement | null = null; 203 + let root: Root | null = null; 204 + 205 + afterEach(() => { 206 + vi.clearAllMocks(); 207 + 208 + if (root) { 209 + act(() => { 210 + root?.unmount(); 211 + }); 212 + } 213 + 214 + container?.remove(); 215 + container = null; 216 + root = null; 217 + document.body.innerHTML = ""; 218 + window.localStorage.clear(); 219 + }); 220 + 221 + it("shows the account deleted toast only once for completed background deletions", async () => { 222 + const user = { 223 + did: "did:plc:alice", 224 + handle: "alice", 225 + displayName: "Alice", 226 + avatar: null, 227 + needsOnboarding: false, 228 + }; 229 + const settings = { 230 + timezone: "UTC", 231 + timeFormat: "24h" as const, 232 + }; 233 + const queryClient = { 234 + invalidateQueries: vi.fn(), 235 + setQueryData: vi.fn(), 236 + }; 237 + 238 + mockUseQueryClient.mockReturnValue(queryClient); 239 + mockPublishSignedOutAuthState.mockResolvedValue(undefined); 240 + 241 + mockUseQuery.mockImplementation( 242 + (options: { enabled?: boolean; queryKey?: Array<{ _id?: string }> }) => { 243 + const queryId = options.queryKey?.[0]?._id; 244 + 245 + if (queryId === "authControllerMe") { 246 + return { data: user, isLoading: false }; 247 + } 248 + 249 + if (queryId === "usersControllerGetMySettings") { 250 + return { data: settings, isLoading: false }; 251 + } 252 + 253 + if (queryId === "usersControllerGetMyAccountDeletion") { 254 + if (!options.enabled) { 255 + return { data: undefined, error: null, isLoading: false }; 256 + } 257 + 258 + return { 259 + data: { 260 + id: "job-1", 261 + status: "completed" as const, 262 + totalRecords: 10, 263 + deletedRecords: 10, 264 + currentStep: "completed", 265 + createdAt: "2026-03-27T12:00:00.000Z", 266 + }, 267 + error: null, 268 + isLoading: false, 269 + }; 270 + } 271 + 272 + return { data: undefined, error: null, isLoading: false }; 273 + }, 274 + ); 275 + 276 + mockUseMutation.mockImplementation( 277 + (options: { 278 + mutationKey?: unknown[]; 279 + onSuccess?: (data?: unknown) => Promise<void> | void; 280 + }) => { 281 + const mutationKey = JSON.stringify(options.mutationKey ?? []); 282 + 283 + if (mutationKey === JSON.stringify(["users", "account", "delete"])) { 284 + return { 285 + isPending: false, 286 + mutate: () => { 287 + void options.onSuccess?.({ 288 + id: "job-1", 289 + status: "queued", 290 + totalRecords: 10, 291 + deletedRecords: 0, 292 + currentStep: "movies", 293 + createdAt: "2026-03-27T12:00:00.000Z", 294 + }); 295 + }, 296 + }; 297 + } 298 + 299 + return { 300 + isPending: false, 301 + mutate: vi.fn(), 302 + }; 303 + }, 304 + ); 305 + 306 + container = document.createElement("div"); 307 + document.body.appendChild(container); 308 + root = createRoot(container); 309 + 310 + await act(async () => { 311 + root?.render(<SettingsPage />); 312 + }); 313 + 314 + const openDeleteDialogButton = Array.from( 315 + document.querySelectorAll("button"), 316 + ).find((button) => button.textContent?.includes("Delete Account")); 317 + 318 + expect(openDeleteDialogButton).toBeDefined(); 319 + 320 + await act(async () => { 321 + openDeleteDialogButton?.dispatchEvent( 322 + new MouseEvent("click", { bubbles: true, cancelable: true }), 323 + ); 324 + }); 325 + 326 + const deleteButtons = Array.from( 327 + document.querySelectorAll("button"), 328 + ).filter((button) => button.textContent?.includes("Delete Account")); 329 + const confirmDeleteButton = deleteButtons.at(-1); 330 + 331 + expect(confirmDeleteButton).toBeDefined(); 332 + 333 + await act(async () => { 334 + confirmDeleteButton?.dispatchEvent( 335 + new MouseEvent("click", { bubbles: true, cancelable: true }), 336 + ); 337 + }); 338 + 339 + await act(async () => { 340 + await Promise.resolve(); 341 + }); 342 + 343 + expect(mockToastSuccess).toHaveBeenCalledTimes(1); 344 + expect(mockToastSuccess).toHaveBeenCalledWith("Account deleted"); 345 + expect(mockPublishSignedOutAuthState).toHaveBeenCalledTimes(1); 346 + expect(mockPublishSignedOutAuthState).toHaveBeenCalledWith(queryClient); 347 + expect(mockNavigate).toHaveBeenCalledTimes(1); 348 + expect(mockNavigate).toHaveBeenCalledWith({ to: "/" }); 349 + expect(mockCapture).toHaveBeenCalledTimes(1); 350 + expect(mockCapture).toHaveBeenCalledWith("account_deleted", { 351 + deleted_pds_data: true, 352 + }); 353 + expect(mockReset).toHaveBeenCalledTimes(1); 354 + }); 355 + });
+24 -15
apps/web/src/routes/onboarding.tsx
··· 36 36 getAvatarUploadErrorMessage, 37 37 validateAvatarFile, 38 38 } from "@/lib/avatar-upload"; 39 + import { 40 + buildImportErrorList, 41 + getSafeOnboardingErrorMessage, 42 + } from "@/lib/onboarding-errors"; 39 43 import { parseCsvFile, runImportInChunks } from "@/lib/onboarding-import"; 40 44 41 45 export const Route = createFileRoute("/onboarding")({ ··· 305 309 setFollowImportStatus("success"); 306 310 } catch (error) { 307 311 setFollowImportStatus("error"); 308 - const message = 309 - error instanceof Error 310 - ? error.message 311 - : "Could not import Bluesky following"; 312 + const message = getSafeOnboardingErrorMessage( 313 + error, 314 + "Could not import Bluesky following", 315 + ); 312 316 toast.error(message); 313 317 } 314 318 }; ··· 393 397 message: `Preview ready for @${fetched.profile.username}`, 394 398 })); 395 399 } catch (error) { 396 - const message = 397 - error instanceof Error 398 - ? error.message 399 - : "Unable to fetch Trakt history right now"; 400 + const message = getSafeOnboardingErrorMessage( 401 + error, 402 + "Could not fetch Trakt history right now.", 403 + ); 400 404 setImportProgress((prev) => ({ 401 405 ...prev, 402 406 phase: "error", ··· 433 437 `Background import started for @${started.profile.username}`, 434 438 ); 435 439 } catch (error) { 436 - const message = 437 - error instanceof Error 438 - ? error.message 439 - : "Unable to import Trakt history right now"; 440 + const message = getSafeOnboardingErrorMessage( 441 + error, 442 + "Could not start the Trakt import right now.", 443 + ); 440 444 setImportProgress((prev) => ({ 441 445 ...prev, 442 446 phase: "error", ··· 496 500 imported: imported.imported, 497 501 skipped: imported.skipped, 498 502 failed: imported.failed + errors.length, 499 - errors: [...errors.map((entry) => entry.message), ...imported.errors], 503 + errors: buildImportErrorList( 504 + errors.map((entry) => entry.message), 505 + imported.errors, 506 + ), 500 507 }); 501 508 setImportProgress((prev) => ({ 502 509 ...prev, ··· 506 513 })); 507 514 setStep(5); 508 515 } catch (error) { 509 - const message = 510 - error instanceof Error ? error.message : "Unable to parse CSV file"; 516 + const message = getSafeOnboardingErrorMessage( 517 + error, 518 + "Could not import your history right now.", 519 + ); 511 520 setImportProgress((prev) => ({ 512 521 ...prev, 513 522 phase: "error",
+12 -4
apps/web/src/routes/profile.$handle.settings.tsx
··· 128 128 return fallback; 129 129 } 130 130 131 - function SettingsPage() { 131 + export function SettingsPage() { 132 132 const router = useRouter(); 133 133 const queryClient = useQueryClient(); 134 134 const { seedColor } = useTheme(); ··· 137 137 const displayNameId = useId(); 138 138 const posthog = usePostHog(); 139 139 const avatarInputRef = useRef<HTMLInputElement | null>(null); 140 + const deletionCompletionHandledRef = useRef(false); 140 141 141 142 const { data: user, isLoading: isAuthLoading } = useQuery({ 142 143 ...authControllerMeOptions(), ··· 214 215 }); 215 216 216 217 const handleDeletionComplete = useCallback(async () => { 218 + if (deletionCompletionHandledRef.current) { 219 + return; 220 + } 221 + deletionCompletionHandledRef.current = true; 222 + 217 223 if (user?.did) { 218 224 clearDismissedTraktImportJobIds(user.did); 219 225 } ··· 768 774 : undefined 769 775 } 770 776 onRetry={() => { 777 + deletionCompletionHandledRef.current = false; 771 778 setDeletionJobId(null); 772 779 setDeletePDSData(true); 773 780 }} ··· 875 882 <M3Button 876 883 variant="filled" 877 884 className="bg-(--md-sys-color-error) text-(--md-sys-color-on-error) hover:brightness-110 active:brightness-95" 878 - onClick={() => 885 + onClick={() => { 886 + deletionCompletionHandledRef.current = false; 879 887 deleteAccountMutation.mutate({ 880 888 body: { deletePDSData }, 881 - }) 882 - } 889 + }); 890 + }} 883 891 disabled={deleteAccountMutation.isPending} 884 892 > 885 893 {deleteAccountMutation.isPending && (
+1
backend/src/auth/auth.service.spec.ts
··· 124 124 }, 125 125 stateStore: expect.any(Object), 126 126 sessionStore: expect.any(Object), 127 + requestLock: expect.any(Function), 127 128 allowHttp: true, 128 129 }); 129 130 });
+2
backend/src/auth/auth.service.ts
··· 1 1 import { Agent } from "@atproto/api"; 2 + import { requestLocalLock } from "@atproto/oauth-client-node"; 2 3 import { 3 4 NodeOAuthClient, 4 5 type OAuthClientMetadataInput, ··· 116 117 clientMetadata, 117 118 stateStore, 118 119 sessionStore, 120 + requestLock: requestLocalLock, 119 121 // Allow HTTP for localhost development 120 122 allowHttp: oauthClientConfig.allowHttp, 121 123 });
+89
backend/src/shows/shows.service.spec.ts
··· 261 261 }); 262 262 }); 263 263 264 + describe("syncShowMetadata", () => { 265 + it("should upsert the show before upserting seasons", async () => { 266 + mockPrismaService.season.findFirst.mockResolvedValue(null); 267 + mockColorExtractionService.extractColorsFromPoster.mockResolvedValue( 268 + null, 269 + ); 270 + mockPrismaService.show.upsert.mockResolvedValue({ 271 + showId: "123", 272 + title: "Test Show", 273 + }); 274 + mockPrismaService.season.upsert.mockResolvedValue({ 275 + id: "season-1", 276 + }); 277 + mockPrismaService.episode.upsert.mockResolvedValue({ 278 + id: "episode-1", 279 + }); 280 + 281 + mockFetch 282 + .mockResolvedValueOnce({ 283 + ok: true, 284 + json: () => 285 + Promise.resolve({ 286 + id: 123, 287 + name: "Test Show", 288 + overview: "A test show", 289 + first_air_date: "2024-01-01", 290 + seasons: [ 291 + { 292 + id: 10, 293 + season_number: 1, 294 + name: "Season 1", 295 + poster_path: "/season.jpg", 296 + air_date: "2024-01-01", 297 + episode_count: 1, 298 + }, 299 + ], 300 + }), 301 + }) 302 + .mockResolvedValueOnce({ 303 + ok: true, 304 + json: () => Promise.resolve({ results: [] }), 305 + }) 306 + .mockResolvedValueOnce({ 307 + ok: true, 308 + json: () => 309 + Promise.resolve({ 310 + id: 10, 311 + name: "Season 1", 312 + season_number: 1, 313 + episodes: [ 314 + { 315 + id: 100, 316 + name: "Episode 1", 317 + episode_number: 1, 318 + still_path: "/episode.jpg", 319 + air_date: "2024-01-02", 320 + overview: "Episode overview", 321 + }, 322 + ], 323 + }), 324 + }) 325 + .mockResolvedValueOnce({ 326 + ok: true, 327 + json: () => Promise.resolve({ results: [] }), 328 + }); 329 + 330 + await service.syncShowMetadata("123"); 331 + 332 + expect(mockPrismaService.show.upsert).toHaveBeenCalledWith( 333 + expect.objectContaining({ 334 + where: { showId: "123" }, 335 + }), 336 + ); 337 + expect(mockPrismaService.season.upsert).toHaveBeenCalledWith( 338 + expect.objectContaining({ 339 + create: expect.objectContaining({ 340 + showId: "123", 341 + seasonNumber: 1, 342 + }), 343 + }), 344 + ); 345 + expect( 346 + mockPrismaService.show.upsert.mock.invocationCallOrder[0], 347 + ).toBeLessThan( 348 + mockPrismaService.season.upsert.mock.invocationCallOrder[0], 349 + ); 350 + }); 351 + }); 352 + 264 353 describe("getEpisodeContext", () => { 265 354 it("should move to the next aired episode across seasons", async () => { 266 355 mockPrismaService.episode.count.mockResolvedValue(0);
+1
backend/src/shows/shows.service.ts
··· 210 210 } 211 211 212 212 const show = await this.showsTmdb.getShowDetails(showId); 213 + await this.upsertShow(show); 213 214 const tmdbSeasons = (show.seasons ?? []).filter( 214 215 (s) => s.season_number !== 0, 215 216 );
+14
backend/src/users/dto/import-history.dto.ts
··· 100 100 | "write_failed" 101 101 | "duplicate_in_request"; 102 102 103 + @ApiPropertyOptional({ 104 + enum: [ 105 + "duplicate_record", 106 + "metadata_unavailable", 107 + "upstream_write_failed", 108 + "unknown", 109 + ], 110 + }) 111 + reason?: 112 + | "duplicate_record" 113 + | "metadata_unavailable" 114 + | "upstream_write_failed" 115 + | "unknown"; 116 + 103 117 @ApiProperty() 104 118 message: string; 105 119 }
+149
backend/src/users/import-history.service.spec.ts
··· 465 465 }), 466 466 ); 467 467 }); 468 + 469 + it("treats duplicate tracked movie races as skipped without exposing prisma errors", async () => { 470 + prisma.trackedMovie.findFirst = jest.fn().mockResolvedValue(null); 471 + (moviesService.markWatched as jest.Mock).mockResolvedValue({ 472 + uri: "at://did:plc:abc/xyz.opnshelf.movie/1", 473 + cid: "cid-1", 474 + rkey: "1", 475 + }); 476 + (moviesService.indexTrackedMovie as jest.Mock).mockRejectedValue( 477 + new Error("Unique constraint failed on the fields: (`rkey`)"), 478 + ); 479 + 480 + const warnSpy = jest.spyOn( 481 + (service as unknown as { logger: { warn: (message: string) => void } }) 482 + .logger, 483 + "warn", 484 + ); 485 + 486 + const result = await service.importNormalizedItems( 487 + "did:plc:abc", 488 + { did: "did:plc:abc" }, 489 + [ 490 + { 491 + type: "movie", 492 + movieTmdbId: 329865, 493 + watchedAt: "2026-03-22T12:00:00.000Z", 494 + action: "watch", 495 + }, 496 + ], 497 + ); 498 + 499 + expect(result).toEqual({ 500 + imported: 0, 501 + skipped: 1, 502 + failed: 0, 503 + errors: [], 504 + }); 505 + expect(warnSpy).toHaveBeenCalledWith( 506 + expect.stringContaining("Unique constraint failed on the fields"), 507 + ); 508 + }); 509 + 510 + it("treats duplicate tracked episode races as skipped without exposing prisma errors", async () => { 511 + prisma.trackedEpisode.findFirst = jest.fn().mockResolvedValue(null); 512 + (showsService.markEpisodeWatched as jest.Mock).mockResolvedValue({ 513 + uri: "at://did:plc:abc/xyz.opnshelf.episode/1", 514 + cid: "cid-1", 515 + rkey: "1", 516 + }); 517 + (showsService.indexTrackedEpisode as jest.Mock).mockRejectedValue( 518 + new Error("Unique constraint failed on the fields: (`rkey`)"), 519 + ); 520 + 521 + const result = await service.importNormalizedItems( 522 + "did:plc:abc", 523 + { did: "did:plc:abc" }, 524 + [ 525 + { 526 + type: "episode", 527 + showTmdbId: 1399, 528 + seasonNumber: 1, 529 + episodeNumber: 1, 530 + watchedAt: "2026-03-22T12:00:00.000Z", 531 + action: "watch", 532 + }, 533 + ], 534 + ); 535 + 536 + expect(result).toEqual({ 537 + imported: 0, 538 + skipped: 1, 539 + failed: 0, 540 + errors: [], 541 + }); 542 + }); 543 + 544 + it("returns sanitized unknown write failures", async () => { 545 + prisma.trackedMovie.findFirst = jest.fn().mockResolvedValue(null); 546 + (moviesService.markWatched as jest.Mock).mockResolvedValue({ 547 + uri: "at://did:plc:abc/xyz.opnshelf.movie/1", 548 + cid: "cid-1", 549 + rkey: "1", 550 + }); 551 + (moviesService.indexTrackedMovie as jest.Mock).mockRejectedValue( 552 + new Error("database exploded in production"), 553 + ); 554 + 555 + const result = await service.importNormalizedItems( 556 + "did:plc:abc", 557 + { did: "did:plc:abc" }, 558 + [ 559 + { 560 + type: "movie", 561 + movieTmdbId: 329865, 562 + watchedAt: "2026-03-22T12:00:00.000Z", 563 + action: "watch", 564 + }, 565 + ], 566 + ); 567 + 568 + expect(result).toEqual({ 569 + imported: 0, 570 + skipped: 0, 571 + failed: 1, 572 + errors: [ 573 + { 574 + index: 1, 575 + code: "write_failed", 576 + reason: "unknown", 577 + message: "We couldn't import this item.", 578 + }, 579 + ], 580 + }); 581 + expect(JSON.stringify(result.errors)).not.toContain("database exploded"); 582 + }); 583 + 584 + it("returns sanitized metadata failures", async () => { 585 + prisma.trackedMovie.findFirst = jest.fn().mockResolvedValue(null); 586 + (moviesService.markWatched as jest.Mock).mockResolvedValue({ 587 + uri: "at://did:plc:abc/xyz.opnshelf.movie/1", 588 + cid: "cid-1", 589 + rkey: "1", 590 + }); 591 + (moviesService.indexTrackedMovie as jest.Mock).mockRejectedValue( 592 + new Error("TMDB movie details request failed"), 593 + ); 594 + 595 + const result = await service.importNormalizedItems( 596 + "did:plc:abc", 597 + { did: "did:plc:abc" }, 598 + [ 599 + { 600 + type: "movie", 601 + movieTmdbId: 329865, 602 + watchedAt: "2026-03-22T12:00:00.000Z", 603 + action: "watch", 604 + }, 605 + ], 606 + ); 607 + 608 + expect(result.errors).toEqual([ 609 + { 610 + index: 1, 611 + code: "write_failed", 612 + reason: "metadata_unavailable", 613 + message: "We couldn't fetch details for this title right now.", 614 + }, 615 + ]); 616 + }); 468 617 });
+79 -7
backend/src/users/import-history.service.ts
··· 85 85 | "completed" 86 86 | "failed"; 87 87 88 + type ImportWriteFailureReason = 89 + | "duplicate_record" 90 + | "metadata_unavailable" 91 + | "upstream_write_failed" 92 + | "unknown"; 93 + 94 + type ClassifiedImportWriteError = { 95 + reason: ImportWriteFailureReason; 96 + message: string; 97 + rawMessage: string; 98 + }; 99 + 88 100 type BackgroundJobRecord = Awaited< 89 101 ReturnType<PrismaService["backgroundJob"]["findFirst"]> 90 102 >; ··· 385 397 } 386 398 387 399 failed += 1; 388 - const itemContext = this.describeImportItem(item); 389 400 errors.push({ 390 401 index: index + 1, 391 402 code: "invalid_item", 392 - message: `${itemContext}: missing required fields`, 403 + message: "This item is missing required fields.", 393 404 }); 394 405 } catch (error) { 395 - failed += 1; 396 406 const itemContext = this.describeImportItem(item); 397 - const rawMessage = 398 - this.getErrorMessage(error) || "Failed to import watch item"; 407 + const classified = this.classifyImportWriteError(error); 399 408 this.logger.warn( 400 - `Failed to import item at index ${index + 1}: ${rawMessage}`, 409 + `Failed to import item at index ${index + 1} (${itemContext}): ${classified.rawMessage}`, 401 410 ); 411 + if (classified.reason === "duplicate_record") { 412 + skipped += 1; 413 + continue; 414 + } 415 + failed += 1; 402 416 errors.push({ 403 417 index: index + 1, 404 418 code: "write_failed", 405 - message: `${itemContext}: ${rawMessage}`, 419 + reason: classified.reason, 420 + message: classified.message, 406 421 }); 407 422 } 408 423 } ··· 1094 1109 private getRetryAfterSeconds(retryAfterSeconds?: number): number { 1095 1110 const boundedRetry = retryAfterSeconds ?? TRAKT_RETRY_FALLBACK_SECONDS; 1096 1111 return Math.max(1, Math.min(boundedRetry, TRAKT_RETRY_MAX_SECONDS)); 1112 + } 1113 + 1114 + private classifyImportWriteError(error: unknown): ClassifiedImportWriteError { 1115 + const rawMessage = 1116 + this.getErrorMessage(error) || "Failed to import watch item"; 1117 + const normalizedMessage = rawMessage.toLowerCase(); 1118 + 1119 + if ( 1120 + normalizedMessage.includes("unique constraint failed") || 1121 + normalizedMessage.includes("duplicate key") || 1122 + normalizedMessage.includes("duplicate") || 1123 + normalizedMessage.includes("trackedmovie_rkey_key") || 1124 + normalizedMessage.includes("trackedepisode_rkey_key") || 1125 + normalizedMessage.includes("`rkey`") 1126 + ) { 1127 + return { 1128 + reason: "duplicate_record", 1129 + message: "This watch was already imported.", 1130 + rawMessage, 1131 + }; 1132 + } 1133 + 1134 + if ( 1135 + normalizedMessage.includes("tmdb") || 1136 + normalizedMessage.includes("show details") || 1137 + normalizedMessage.includes("movie details") || 1138 + normalizedMessage.includes("metadata") || 1139 + normalizedMessage.includes("season details") || 1140 + normalizedMessage.includes("episode details") 1141 + ) { 1142 + return { 1143 + reason: "metadata_unavailable", 1144 + message: "We couldn't fetch details for this title right now.", 1145 + rawMessage, 1146 + }; 1147 + } 1148 + 1149 + if ( 1150 + normalizedMessage.includes("atproto") || 1151 + normalizedMessage.includes("pds") || 1152 + normalizedMessage.includes("putrecord") || 1153 + normalizedMessage.includes("repo.putrecord") || 1154 + normalizedMessage.includes("repo#putrecord") || 1155 + normalizedMessage.includes("upstream") 1156 + ) { 1157 + return { 1158 + reason: "upstream_write_failed", 1159 + message: "We couldn't save this watch right now. Please try again.", 1160 + rawMessage, 1161 + }; 1162 + } 1163 + 1164 + return { 1165 + reason: "unknown", 1166 + message: "We couldn't import this item.", 1167 + rawMessage, 1168 + }; 1097 1169 } 1098 1170 1099 1171 private getErrorMessage(error: unknown): string {
+1 -1
package.json
··· 21 21 ], 22 22 "devDependencies": { 23 23 "husky": "^9.1.7", 24 - "turbo": "^2.8.14" 24 + "turbo": "^2.8.20" 25 25 }, 26 26 "packageManager": "pnpm@10.30.2+sha512.36cdc707e7b7940a988c9c1ecf88d084f8514b5c3f085f53a2e244c2921d3b2545bc20dd4ebe1fc245feec463bb298aecea7a63ed1f7680b877dc6379d8d0cb4" 27 27 }
+20 -20
packages/api/src/generated/@tanstack/react-query.gen.ts
··· 3 3 import { type DefaultError, type InfiniteData, infiniteQueryOptions, queryOptions, type UseMutationOptions } from '@tanstack/react-query'; 4 4 5 5 import { client } from '../client.gen'; 6 - import { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar, usersControllerGetMyAccountDeletion } from '../sdk.gen'; 7 - import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusResponse, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerMeData, AuthControllerMeResponse, AuthControllerSignupData, AuthControllerSuggestionsData, ListsControllerAddItemToListData, ListsControllerCreateListData, ListsControllerCreateListResponse, ListsControllerDeleteListData, ListsControllerGetListData, ListsControllerGetListResponse, ListsControllerGetListsForItemData, ListsControllerGetListsForItemResponse, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetUserListsData, ListsControllerGetUserListsResponse, ListsControllerRemoveItemFromListData, ListsControllerUpdateListData, ListsControllerUpdateListResponse, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieResponse, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesResponse, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedResponse, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedResponse, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerSearchAllData, SearchControllerSearchAllResponse, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowResponse, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedResponse, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerUnfollowData, SocialControllerUnfollowResponse, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingResponse, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerGetAvatarData, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMySettingsData, UsersControllerGetMySettingsResponse, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileResponse, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryResponse, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportResponse, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsResponse, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionResponse } from '../types.gen'; 6 + import { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyAccountDeletion, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar } from '../sdk.gen'; 7 + import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusResponse, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerMeData, AuthControllerMeResponse, AuthControllerSignupData, AuthControllerSuggestionsData, ListsControllerAddItemToListData, ListsControllerCreateListData, ListsControllerCreateListResponse, ListsControllerDeleteListData, ListsControllerGetListData, ListsControllerGetListResponse, ListsControllerGetListsForItemData, ListsControllerGetListsForItemResponse, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetUserListsData, ListsControllerGetUserListsResponse, ListsControllerRemoveItemFromListData, ListsControllerUpdateListData, ListsControllerUpdateListResponse, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieResponse, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesResponse, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedResponse, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedResponse, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerSearchAllData, SearchControllerSearchAllResponse, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowResponse, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedResponse, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerUnfollowData, SocialControllerUnfollowResponse, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingResponse, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerGetAvatarData, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionResponse, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMySettingsData, UsersControllerGetMySettingsResponse, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileResponse, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryResponse, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportResponse, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsResponse, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse } from '../types.gen'; 8 8 9 9 export type QueryKey<TOptions extends Options> = [ 10 10 Pick<TOptions, 'baseUrl' | 'body' | 'headers' | 'path' | 'query'> & { ··· 927 927 return mutationOptions; 928 928 }; 929 929 930 + export const usersControllerGetMyAccountDeletionQueryKey = (options?: Options<UsersControllerGetMyAccountDeletionData>) => createQueryKey('usersControllerGetMyAccountDeletion', options); 931 + 932 + /** 933 + * Get current account deletion job status 934 + */ 935 + export const usersControllerGetMyAccountDeletionOptions = (options?: Options<UsersControllerGetMyAccountDeletionData>) => queryOptions<UsersControllerGetMyAccountDeletionResponse, DefaultError, UsersControllerGetMyAccountDeletionResponse, ReturnType<typeof usersControllerGetMyAccountDeletionQueryKey>>({ 936 + queryFn: async ({ queryKey, signal }) => { 937 + const { data } = await usersControllerGetMyAccountDeletion({ 938 + ...options, 939 + ...queryKey[0], 940 + signal, 941 + throwOnError: true 942 + }); 943 + return data; 944 + }, 945 + queryKey: usersControllerGetMyAccountDeletionQueryKey(options) 946 + }); 947 + 930 948 /** 931 949 * Complete onboarding for the current user 932 950 */ ··· 994 1012 return data; 995 1013 }, 996 1014 queryKey: usersControllerGetMyCurrentTraktImportQueryKey(options) 997 - }); 998 - 999 - export const usersControllerGetMyAccountDeletionQueryKey = (options?: Options<UsersControllerGetMyAccountDeletionData>) => createQueryKey('usersControllerGetMyAccountDeletion', options); 1000 - 1001 - /** 1002 - * Get current account deletion job status 1003 - */ 1004 - export const usersControllerGetMyAccountDeletionOptions = (options?: Options<UsersControllerGetMyAccountDeletionData>) => queryOptions<UsersControllerGetMyAccountDeletionResponse, DefaultError, UsersControllerGetMyAccountDeletionResponse, ReturnType<typeof usersControllerGetMyAccountDeletionQueryKey>>({ 1005 - queryFn: async ({ queryKey, signal }) => { 1006 - const { data } = await usersControllerGetMyAccountDeletion({ 1007 - ...options, 1008 - ...queryKey[0], 1009 - signal, 1010 - throwOnError: true 1011 - }); 1012 - return data; 1013 - }, 1014 - queryKey: usersControllerGetMyAccountDeletionQueryKey(options) 1015 1015 }); 1016 1016 1017 1017 /**
+2 -2
packages/api/src/generated/index.ts
··· 1 1 // This file is auto-generated by @hey-api/openapi-ts 2 2 3 - export { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerGetMyAccountDeletion, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar } from './sdk.gen'; 4 - export type { AddToListDto, AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponse, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponse, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, BlueskyProfileStatusDto, ClientOptions, CompleteOnboardingResponseDto, CreateListDto, AccountDeletionJobDto, DeleteUserAccountDto, EpisodeContextDto, EpisodeHistoryItemDto, EpisodeReferenceDto, FetchTraktPublicHistoryDto, FetchTraktPublicHistoryResponseDto, FollowedActivityFeedDto, FollowedActivityItemDto, FollowedWatcherActorDto, FollowedWatcherDto, FollowedWatchersDto, ImportBlueskyFollowsResponseDto, ImportErrorDto, ImportHistoryDto, ImportHistoryResponseDto, ImportSkipDto, ListDto, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponse, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponse, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponse, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponse, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponse, ListsControllerUpdateListResponses, ListsForItemDto, ListSummaryDto, ListWithItemsDto, LocalEpisodeDto, LocalSeasonDto, MarkedEpisodesResponseDto, MarkEpisodeWatchedDto, MarkSeasonWatchedDto, MarkShowWatchedDto, MediaInListDto, MovieColorsDto, MovieDto, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponse, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponse, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponse, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponse, MoviesControllerUnmarkWatchedResponses, NormalizedImportItemDto, PaginatedEpisodesResponseDto, PaginatedMoviesResponseDto, PaginatedSocialUsersDto, PaginatedUpNextResponseDto, PublicUserProfileDto, ReleaseCalendarItemDto, ReleaseCalendarResponseDto, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponse, SearchControllerSearchAllResponses, SearchResultsDto, SearchShowsResultsDto, ShelfActivityBucketDto, ShelfActivitySummaryDto, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShelfControllerGetUserShelfResponses, ShelfResponseDto, ShowDto, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponse, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponse, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, ShowsControllerUnmarkWatchedResponses, SocialActorDto, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponse, SocialControllerUnfollowResponses, SocialUserCardDto, StartTraktImportDto, StartTraktImportResponseDto, TmdbCastDto, TmdbCreditsDto, TmdbCrewDto, TmdbEpisodeDto, TmdbGenreDto, TmdbMovieDetailDto, TmdbMovieResultDto, TmdbNetworkDto, TmdbSeasonDetailDto, TmdbSeasonSummaryDto, TmdbShowDetailDto, TmdbShowResultDto, TmdbTrailerDto, TrackedEpisodeDto, TrackedMovieDto, TrackedShowSummaryDto, TraktHistoryPreviewItemDto, TraktImportJobDto, TraktPublicProfileDto, UnifiedDiscoverResponseDto, UnifiedSearchResponseDto, UnifiedSearchResultDto, UpdateListDto, UpdateUserProfileDto, UpdateUserSettingsDto, UpNextEpisodeDto, UpNextShowDto, UserDto, UserProfileDto, UserRelationshipDto, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponse, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionResponse, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponse, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponse, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponse, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponse, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponse, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse, UsersControllerUploadMyAvatarResponses, UserSettingsDto, WatchHistoryItemDto } from './types.gen'; 3 + export { authControllerBlueskyProfileStatus, authControllerCallback, authControllerGetClientMetadata, authControllerLogin, authControllerLogout, authControllerMe, authControllerSignup, authControllerSuggestions, listsControllerAddItemToList, listsControllerCreateList, listsControllerDeleteList, listsControllerGetList, listsControllerGetListsForItem, listsControllerGetPublicUserList, listsControllerGetPublicUserLists, listsControllerGetUserLists, listsControllerRemoveItemFromList, listsControllerUpdateList, moviesControllerDeleteWatchHistoryEntry, moviesControllerDiscoverMovies, moviesControllerGetMovie, moviesControllerGetMovieDetails, moviesControllerGetMovieWatchHistory, moviesControllerGetUserMovies, moviesControllerGetUserMoviesPaginated, moviesControllerMarkWatched, moviesControllerSearchMovies, moviesControllerUnmarkWatched, type Options, searchControllerDiscoverAll, searchControllerSearchAll, shelfControllerGetUserActivitySummary, shelfControllerGetUserShelf, showsControllerDeleteEpisodeWatchHistoryEntry, showsControllerDiscoverShows, showsControllerGetEpisodeDetails, showsControllerGetLocalEpisodes, showsControllerGetLocalSeasons, showsControllerGetSeasonDetails, showsControllerGetShow, showsControllerGetShowDetails, showsControllerGetShowWatchHistory, showsControllerGetUserEpisodesPaginated, showsControllerGetUserReleaseCalendar, showsControllerGetUserShows, showsControllerGetUserUpNext, showsControllerMarkSeasonWatched, showsControllerMarkShowWatched, showsControllerMarkWatched, showsControllerSearchShows, showsControllerUnmarkWatched, socialControllerFollow, socialControllerGetFeed, socialControllerGetFollowers, socialControllerGetFollowing, socialControllerGetRelationship, socialControllerGetWatchers, socialControllerSearchPeople, socialControllerUnfollow, usersControllerCompleteOnboarding, usersControllerDeleteMyAccount, usersControllerDeleteMyAvatar, usersControllerFetchMyTraktPublicHistory, usersControllerGetAvatar, usersControllerGetMyAccountDeletion, usersControllerGetMyCurrentTraktImport, usersControllerGetMySettings, usersControllerGetPublicProfile, usersControllerImportMyBlueskyFollows, usersControllerImportMyHistory, usersControllerStartMyTraktImport, usersControllerUpdateMyProfile, usersControllerUpdateMySettings, usersControllerUploadMyAvatar } from './sdk.gen'; 4 + export type { AccountDeletionJobDto, AddToListDto, AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponse, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponse, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, BlueskyProfileStatusDto, ClientOptions, CompleteOnboardingResponseDto, CreateListDto, DeleteUserAccountDto, EpisodeContextDto, EpisodeHistoryItemDto, EpisodeReferenceDto, FetchTraktPublicHistoryDto, FetchTraktPublicHistoryResponseDto, FollowedActivityFeedDto, FollowedActivityItemDto, FollowedWatcherActorDto, FollowedWatcherDto, FollowedWatchersDto, ImportBlueskyFollowsResponseDto, ImportErrorDto, ImportHistoryDto, ImportHistoryResponseDto, ImportSkipDto, ListDto, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponse, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponse, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponse, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponse, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponse, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponse, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponse, ListsControllerUpdateListResponses, ListsForItemDto, ListSummaryDto, ListWithItemsDto, LocalEpisodeDto, LocalSeasonDto, MarkedEpisodesResponseDto, MarkEpisodeWatchedDto, MarkSeasonWatchedDto, MarkShowWatchedDto, MediaInListDto, MovieColorsDto, MovieDto, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponse, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponse, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponse, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponse, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponse, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponse, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponse, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponse, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponse, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponse, MoviesControllerUnmarkWatchedResponses, NormalizedImportItemDto, PaginatedEpisodesResponseDto, PaginatedMoviesResponseDto, PaginatedSocialUsersDto, PaginatedUpNextResponseDto, PublicUserProfileDto, ReleaseCalendarItemDto, ReleaseCalendarResponseDto, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponse, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponse, SearchControllerSearchAllResponses, SearchResultsDto, SearchShowsResultsDto, ShelfActivityBucketDto, ShelfActivitySummaryDto, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponse, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponse, ShelfControllerGetUserShelfResponses, ShelfResponseDto, ShowDto, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponse, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponse, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponse, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponse, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponse, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponse, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponse, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponse, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponse, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponse, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponse, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponse, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponse, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponse, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponse, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponse, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponse, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponse, ShowsControllerUnmarkWatchedResponses, SocialActorDto, SocialControllerFollowData, SocialControllerFollowResponse, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponse, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponse, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponse, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponse, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponse, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponse, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponse, SocialControllerUnfollowResponses, SocialUserCardDto, StartTraktImportDto, StartTraktImportResponseDto, TmdbCastDto, TmdbCreditsDto, TmdbCrewDto, TmdbEpisodeDto, TmdbGenreDto, TmdbMovieDetailDto, TmdbMovieResultDto, TmdbNetworkDto, TmdbSeasonDetailDto, TmdbSeasonSummaryDto, TmdbShowDetailDto, TmdbShowResultDto, TmdbTrailerDto, TrackedEpisodeDto, TrackedMovieDto, TrackedShowSummaryDto, TraktHistoryPreviewItemDto, TraktImportJobDto, TraktPublicProfileDto, UnifiedDiscoverResponseDto, UnifiedSearchResponseDto, UnifiedSearchResultDto, UpdateListDto, UpdateUserProfileDto, UpdateUserSettingsDto, UpNextEpisodeDto, UpNextShowDto, UserDto, UserProfileDto, UserRelationshipDto, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponse, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponse, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponse, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponse, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionErrors, UsersControllerGetMyAccountDeletionResponse, UsersControllerGetMyAccountDeletionResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponse, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponse, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponse, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponse, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponse, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponse, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponse, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponse, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponse, UsersControllerUploadMyAvatarResponses, UserSettingsDto, WatchHistoryItemDto } from './types.gen';
+1 -1
packages/api/src/generated/sdk.gen.ts
··· 2 2 3 3 import { type Client, formDataBodySerializer, type Options as Options2, type TDataShape } from './client'; 4 4 import { client } from './client.gen'; 5 - import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponses, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponses, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponses, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponses, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponses, SocialControllerFollowData, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponses, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponses, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionErrors, UsersControllerGetMyAccountDeletionResponses } from './types.gen'; 5 + import type { AuthControllerBlueskyProfileStatusData, AuthControllerBlueskyProfileStatusErrors, AuthControllerBlueskyProfileStatusResponses, AuthControllerCallbackData, AuthControllerGetClientMetadataData, AuthControllerGetClientMetadataResponses, AuthControllerLoginData, AuthControllerLogoutData, AuthControllerLogoutResponses, AuthControllerMeData, AuthControllerMeErrors, AuthControllerMeResponses, AuthControllerSignupData, AuthControllerSuggestionsData, AuthControllerSuggestionsResponses, ListsControllerAddItemToListData, ListsControllerAddItemToListErrors, ListsControllerAddItemToListResponses, ListsControllerCreateListData, ListsControllerCreateListErrors, ListsControllerCreateListResponses, ListsControllerDeleteListData, ListsControllerDeleteListErrors, ListsControllerDeleteListResponses, ListsControllerGetListData, ListsControllerGetListErrors, ListsControllerGetListResponses, ListsControllerGetListsForItemData, ListsControllerGetListsForItemErrors, ListsControllerGetListsForItemResponses, ListsControllerGetPublicUserListData, ListsControllerGetPublicUserListErrors, ListsControllerGetPublicUserListResponses, ListsControllerGetPublicUserListsData, ListsControllerGetPublicUserListsResponses, ListsControllerGetUserListsData, ListsControllerGetUserListsErrors, ListsControllerGetUserListsResponses, ListsControllerRemoveItemFromListData, ListsControllerRemoveItemFromListErrors, ListsControllerRemoveItemFromListResponses, ListsControllerUpdateListData, ListsControllerUpdateListErrors, ListsControllerUpdateListResponses, MoviesControllerDeleteWatchHistoryEntryData, MoviesControllerDeleteWatchHistoryEntryErrors, MoviesControllerDeleteWatchHistoryEntryResponses, MoviesControllerDiscoverMoviesData, MoviesControllerDiscoverMoviesResponses, MoviesControllerGetMovieData, MoviesControllerGetMovieDetailsData, MoviesControllerGetMovieDetailsResponses, MoviesControllerGetMovieResponses, MoviesControllerGetMovieWatchHistoryData, MoviesControllerGetMovieWatchHistoryErrors, MoviesControllerGetMovieWatchHistoryResponses, MoviesControllerGetUserMoviesData, MoviesControllerGetUserMoviesPaginatedData, MoviesControllerGetUserMoviesPaginatedResponses, MoviesControllerGetUserMoviesResponses, MoviesControllerMarkWatchedData, MoviesControllerMarkWatchedErrors, MoviesControllerMarkWatchedResponses, MoviesControllerSearchMoviesData, MoviesControllerSearchMoviesResponses, MoviesControllerUnmarkWatchedData, MoviesControllerUnmarkWatchedErrors, MoviesControllerUnmarkWatchedResponses, SearchControllerDiscoverAllData, SearchControllerDiscoverAllResponses, SearchControllerSearchAllData, SearchControllerSearchAllResponses, ShelfControllerGetUserActivitySummaryData, ShelfControllerGetUserActivitySummaryResponses, ShelfControllerGetUserShelfData, ShelfControllerGetUserShelfResponses, ShowsControllerDeleteEpisodeWatchHistoryEntryData, ShowsControllerDeleteEpisodeWatchHistoryEntryErrors, ShowsControllerDeleteEpisodeWatchHistoryEntryResponses, ShowsControllerDiscoverShowsData, ShowsControllerDiscoverShowsResponses, ShowsControllerGetEpisodeDetailsData, ShowsControllerGetEpisodeDetailsResponses, ShowsControllerGetLocalEpisodesData, ShowsControllerGetLocalEpisodesResponses, ShowsControllerGetLocalSeasonsData, ShowsControllerGetLocalSeasonsResponses, ShowsControllerGetSeasonDetailsData, ShowsControllerGetSeasonDetailsResponses, ShowsControllerGetShowData, ShowsControllerGetShowDetailsData, ShowsControllerGetShowDetailsResponses, ShowsControllerGetShowResponses, ShowsControllerGetShowWatchHistoryData, ShowsControllerGetShowWatchHistoryErrors, ShowsControllerGetShowWatchHistoryResponses, ShowsControllerGetUserEpisodesPaginatedData, ShowsControllerGetUserEpisodesPaginatedResponses, ShowsControllerGetUserReleaseCalendarData, ShowsControllerGetUserReleaseCalendarResponses, ShowsControllerGetUserShowsData, ShowsControllerGetUserShowsResponses, ShowsControllerGetUserUpNextData, ShowsControllerGetUserUpNextResponses, ShowsControllerMarkSeasonWatchedData, ShowsControllerMarkSeasonWatchedErrors, ShowsControllerMarkSeasonWatchedResponses, ShowsControllerMarkShowWatchedData, ShowsControllerMarkShowWatchedErrors, ShowsControllerMarkShowWatchedResponses, ShowsControllerMarkWatchedData, ShowsControllerMarkWatchedErrors, ShowsControllerMarkWatchedResponses, ShowsControllerSearchShowsData, ShowsControllerSearchShowsResponses, ShowsControllerUnmarkWatchedData, ShowsControllerUnmarkWatchedResponses, SocialControllerFollowData, SocialControllerFollowResponses, SocialControllerGetFeedData, SocialControllerGetFeedResponses, SocialControllerGetFollowersData, SocialControllerGetFollowersResponses, SocialControllerGetFollowingData, SocialControllerGetFollowingResponses, SocialControllerGetRelationshipData, SocialControllerGetRelationshipResponses, SocialControllerGetWatchersData, SocialControllerGetWatchersResponses, SocialControllerSearchPeopleData, SocialControllerSearchPeopleResponses, SocialControllerUnfollowData, SocialControllerUnfollowResponses, UsersControllerCompleteOnboardingData, UsersControllerCompleteOnboardingErrors, UsersControllerCompleteOnboardingResponses, UsersControllerDeleteMyAccountData, UsersControllerDeleteMyAccountErrors, UsersControllerDeleteMyAccountResponses, UsersControllerDeleteMyAvatarData, UsersControllerDeleteMyAvatarResponses, UsersControllerFetchMyTraktPublicHistoryData, UsersControllerFetchMyTraktPublicHistoryErrors, UsersControllerFetchMyTraktPublicHistoryResponses, UsersControllerGetAvatarData, UsersControllerGetAvatarResponses, UsersControllerGetMyAccountDeletionData, UsersControllerGetMyAccountDeletionErrors, UsersControllerGetMyAccountDeletionResponses, UsersControllerGetMyCurrentTraktImportData, UsersControllerGetMyCurrentTraktImportErrors, UsersControllerGetMyCurrentTraktImportResponses, UsersControllerGetMySettingsData, UsersControllerGetMySettingsErrors, UsersControllerGetMySettingsResponses, UsersControllerGetPublicProfileData, UsersControllerGetPublicProfileErrors, UsersControllerGetPublicProfileResponses, UsersControllerImportMyBlueskyFollowsData, UsersControllerImportMyBlueskyFollowsErrors, UsersControllerImportMyBlueskyFollowsResponses, UsersControllerImportMyHistoryData, UsersControllerImportMyHistoryErrors, UsersControllerImportMyHistoryResponses, UsersControllerStartMyTraktImportData, UsersControllerStartMyTraktImportErrors, UsersControllerStartMyTraktImportResponses, UsersControllerUpdateMyProfileData, UsersControllerUpdateMyProfileErrors, UsersControllerUpdateMyProfileResponses, UsersControllerUpdateMySettingsData, UsersControllerUpdateMySettingsErrors, UsersControllerUpdateMySettingsResponses, UsersControllerUploadMyAvatarData, UsersControllerUploadMyAvatarResponses } from './types.gen'; 6 6 7 7 export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & { 8 8 /**
+2 -1
packages/api/src/generated/types.gen.ts
··· 720 720 */ 721 721 index: number; 722 722 code: 'invalid_item' | 'already_exists' | 'write_failed' | 'duplicate_in_request'; 723 + reason?: 'duplicate_record' | 'metadata_unavailable' | 'upstream_write_failed' | 'unknown'; 723 724 message: string; 724 725 }; 725 726 ··· 1966 1967 /** 1967 1968 * Current or most recent account deletion job, or null when none exists 1968 1969 */ 1969 - 200: AccountDeletionJobDto | null; 1970 + 200: AccountDeletionJobDto; 1970 1971 }; 1971 1972 1972 1973 export type UsersControllerGetMyAccountDeletionResponse = UsersControllerGetMyAccountDeletionResponses[keyof UsersControllerGetMyAccountDeletionResponses];
+59 -59
pnpm-lock.yaml
··· 12 12 specifier: ^9.1.7 13 13 version: 9.1.7 14 14 turbo: 15 - specifier: ^2.8.14 16 - version: 2.8.14 15 + specifier: ^2.8.20 16 + version: 2.8.20 17 17 18 18 apps/mobile: 19 19 dependencies: ··· 3877 3877 3878 3878 '@tsconfig/node16@1.0.4': 3879 3879 resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} 3880 + 3881 + '@turbo/darwin-64@2.8.20': 3882 + resolution: {integrity: sha512-FQ9EX1xMU5nbwjxXxM3yU88AQQ6Sqc6S44exPRroMcx9XZHqqppl5ymJF0Ig/z3nvQNwDmz1Gsnvxubo+nXWjQ==} 3883 + cpu: [x64] 3884 + os: [darwin] 3885 + 3886 + '@turbo/darwin-arm64@2.8.20': 3887 + resolution: {integrity: sha512-Gpyh9ATFGThD6/s9L95YWY54cizg/VRWl2B67h0yofG8BpHf67DFAh9nuJVKG7bY0+SBJDAo5cMur+wOl9YOYw==} 3888 + cpu: [arm64] 3889 + os: [darwin] 3890 + 3891 + '@turbo/linux-64@2.8.20': 3892 + resolution: {integrity: sha512-p2QxWUYyYUgUFG0b0kR+pPi8t7c9uaVlRtjTTI1AbCvVqkpjUfCcReBn6DgG/Hu8xrWdKLuyQFaLYFzQskZbcA==} 3893 + cpu: [x64] 3894 + os: [linux] 3895 + 3896 + '@turbo/linux-arm64@2.8.20': 3897 + resolution: {integrity: sha512-Gn5yjlZGLRZWarLWqdQzv0wMqyBNIdq1QLi48F1oY5Lo9kiohuf7BPQWtWxeNVS2NgJ1+nb/DzK1JduYC4AWOA==} 3898 + cpu: [arm64] 3899 + os: [linux] 3900 + 3901 + '@turbo/windows-64@2.8.20': 3902 + resolution: {integrity: sha512-vyaDpYk/8T6Qz5V/X+ihKvKFEZFUoC0oxYpC1sZanK6gaESJlmV3cMRT3Qhcg4D2VxvtC2Jjs9IRkrZGL+exLw==} 3903 + cpu: [x64] 3904 + os: [win32] 3905 + 3906 + '@turbo/windows-arm64@2.8.20': 3907 + resolution: {integrity: sha512-voicVULvUV5yaGXo0Iue13BcHGYW3u0VgqSbfQwBaHbpj1zLjYV4KIe+7fYIo6DO8FVUJzxFps3ODCQG/Wy2Qw==} 3908 + cpu: [arm64] 3909 + os: [win32] 3880 3910 3881 3911 '@tybys/wasm-util@0.10.1': 3882 3912 resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} ··· 8414 8444 tunnel-agent@0.6.0: 8415 8445 resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} 8416 8446 8417 - turbo-darwin-64@2.8.14: 8418 - resolution: {integrity: sha512-9sFi7n2lLfEsGWi5OEoA/eTtQU2BPKtzSYKqufMtDeRmqMT9vKjbv9gJCRkllSVE9BOXA0qXC3diyX8V8rKIKw==} 8419 - cpu: [x64] 8420 - os: [darwin] 8421 - 8422 - turbo-darwin-arm64@2.8.14: 8423 - resolution: {integrity: sha512-aS4yJuy6A1PCLws+PJpZP0qCURG8Y5iVx13z/WAbKyeDTY6W6PiGgcEllSaeLGxyn++382ztN/EZH85n2zZ6VQ==} 8424 - cpu: [arm64] 8425 - os: [darwin] 8426 - 8427 - turbo-linux-64@2.8.14: 8428 - resolution: {integrity: sha512-XC6wPUDJkakjhNLaS0NrHDMiujRVjH+naEAwvKLArgqRaFkNxjmyNDRM4eu3soMMFmjym6NTxYaF74rvET+Orw==} 8429 - cpu: [x64] 8430 - os: [linux] 8431 - 8432 - turbo-linux-arm64@2.8.14: 8433 - resolution: {integrity: sha512-ChfE7isyVNjZrVSPDwcfqcHLG/FuIBbOFxnt1FM8vSuBGzHAs8AlTdwFNIxlEMJfZ8Ad9mdMxdmsCUPIWiQ6cg==} 8434 - cpu: [arm64] 8435 - os: [linux] 8436 - 8437 - turbo-windows-64@2.8.14: 8438 - resolution: {integrity: sha512-FTbIeQL1ycLFW2t9uQNMy+bRSzi3Xhwun/e7ZhFBdM+U0VZxxrtfYEBM9CHOejlfqomk6Jh7aRz0sJoqYn39Hg==} 8439 - cpu: [x64] 8440 - os: [win32] 8441 - 8442 - turbo-windows-arm64@2.8.14: 8443 - resolution: {integrity: sha512-KgZX12cTyhY030qS7ieT8zRkhZZE2VWJasDFVUSVVn17nR7IShpv68/7j5UqJNeRLIGF1XPK0phsP5V5yw3how==} 8444 - cpu: [arm64] 8445 - os: [win32] 8446 - 8447 - turbo@2.8.14: 8448 - resolution: {integrity: sha512-UCTxeMNYT1cKaHiIFdLCQ7ulI+jw5i5uOnJOrRXsgUD7G3+OjlUjwVd7JfeVt2McWSVGjYA3EVW/v1FSsJ5DtA==} 8447 + turbo@2.8.20: 8448 + resolution: {integrity: sha512-Rb4qk5YT8RUwwdXtkLpkVhNEe/lor6+WV7S5tTlLpxSz6MjV5Qi8jGNn4gS6NAvrYGA/rNrE6YUQM85sCZUDbQ==} 8449 8449 hasBin: true 8450 8450 8451 8451 tw-animate-css@1.4.0: ··· 13484 13484 '@tsconfig/node14@1.0.3': {} 13485 13485 13486 13486 '@tsconfig/node16@1.0.4': {} 13487 + 13488 + '@turbo/darwin-64@2.8.20': 13489 + optional: true 13490 + 13491 + '@turbo/darwin-arm64@2.8.20': 13492 + optional: true 13493 + 13494 + '@turbo/linux-64@2.8.20': 13495 + optional: true 13496 + 13497 + '@turbo/linux-arm64@2.8.20': 13498 + optional: true 13499 + 13500 + '@turbo/windows-64@2.8.20': 13501 + optional: true 13502 + 13503 + '@turbo/windows-arm64@2.8.20': 13504 + optional: true 13487 13505 13488 13506 '@tybys/wasm-util@0.10.1': 13489 13507 dependencies: ··· 18643 18661 safe-buffer: 5.2.1 18644 18662 optional: true 18645 18663 18646 - turbo-darwin-64@2.8.14: 18647 - optional: true 18648 - 18649 - turbo-darwin-arm64@2.8.14: 18650 - optional: true 18651 - 18652 - turbo-linux-64@2.8.14: 18653 - optional: true 18654 - 18655 - turbo-linux-arm64@2.8.14: 18656 - optional: true 18657 - 18658 - turbo-windows-64@2.8.14: 18659 - optional: true 18660 - 18661 - turbo-windows-arm64@2.8.14: 18662 - optional: true 18663 - 18664 - turbo@2.8.14: 18664 + turbo@2.8.20: 18665 18665 optionalDependencies: 18666 - turbo-darwin-64: 2.8.14 18667 - turbo-darwin-arm64: 2.8.14 18668 - turbo-linux-64: 2.8.14 18669 - turbo-linux-arm64: 2.8.14 18670 - turbo-windows-64: 2.8.14 18671 - turbo-windows-arm64: 2.8.14 18666 + '@turbo/darwin-64': 2.8.20 18667 + '@turbo/darwin-arm64': 2.8.20 18668 + '@turbo/linux-64': 2.8.20 18669 + '@turbo/linux-arm64': 2.8.20 18670 + '@turbo/windows-64': 2.8.20 18671 + '@turbo/windows-arm64': 2.8.20 18672 18672 18673 18673 tw-animate-css@1.4.0: {} 18674 18674