Skip to content

Commit 821ae0b

Browse files
committed
fix(sdk-core): remove invalid Agent property assignments and fix test type safety
- Remove non-existent agent.service and agent.api.xrpc.uri property assignments that were causing TypeScript errors (TS2339) - Agent service URL is properly configured through Session's fetch handler - Replace 'any' types in test files with proper types (Partial<Agent>, Partial<Session>) - Use createMockSession() helper for consistent test mocking - All builds, lints, and tests now pass without warnings Fixes: TypeScript compilation errors in Repository.ts:189-190 Fixes: ESLint @typescript-eslint/no-explicit-any warnings in test files
1 parent 39accd9 commit 821ae0b

File tree

10 files changed

+35
-43
lines changed

10 files changed

+35
-43
lines changed

.changeset/fix-agent-service-url.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/sdk-core/src/repository/Repository.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,10 @@ export class Repository {
180180
this.logger = logger;
181181

182182
// Create Agent with OAuth session
183+
// Note: The Agent will use the session's fetch handler which contains
184+
// the service URL configuration from the OAuth session
183185
this.agent = new Agent(session);
184186

185-
// Configure Agent to use the specified server URL (PDS or SDS)
186-
// This ensures queries are routed to the correct server
187-
// We need to set both the service URL and the XRPC URI to ensure all
188-
// requests are routed to the correct server, not the session's default PDS
189-
this.agent.service = new URL(serverUrl);
190-
this.agent.api.xrpc.uri = new URL(serverUrl);
191-
192187
this.lexiconRegistry.addToAgent(this.agent);
193188

194189
// Register hypercert lexicons

packages/sdk-core/tests/core/SDK.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ATProtoSDK, createATProtoSDK } from "../../src/core/SDK.js";
33
import { ValidationError } from "../../src/core/errors.js";
44
import { createTestConfigAsync } from "../utils/fixtures.js";
55
import { InMemorySessionStore, InMemoryStateStore } from "../utils/mocks.js";
6+
import { createMockSession } from "../utils/repository-fixtures.js";
67

78
describe("ATProtoSDK", () => {
89
let config: Awaited<ReturnType<typeof createTestConfigAsync>>;
@@ -109,28 +110,29 @@ describe("ATProtoSDK", () => {
109110
describe("repository", () => {
110111
it("should throw ValidationError when session is null", () => {
111112
const sdk = new ATProtoSDK(config);
113+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
112114
expect(() => sdk.repository(null as any)).toThrow(ValidationError);
113115
});
114116

115117
it("should throw ValidationError when PDS not configured and no server specified", async () => {
116118
const configWithoutServers = await createTestConfigAsync();
117119
delete configWithoutServers.servers;
118120
const sdk = new ATProtoSDK(configWithoutServers);
119-
const mockSession = { did: "did:plc:test", sub: "did:plc:test", fetchHandler: async () => new Response() } as any;
121+
const mockSession = createMockSession();
120122
expect(() => sdk.repository(mockSession)).toThrow(ValidationError);
121123
});
122124

123125
it("should throw ValidationError when SDS not configured and server=sds", async () => {
124126
const configWithOnlyPds = await createTestConfigAsync();
125127
configWithOnlyPds.servers = { pds: "https://pds.example.com" };
126128
const sdk = new ATProtoSDK(configWithOnlyPds);
127-
const mockSession = { did: "did:plc:test", sub: "did:plc:test", fetchHandler: async () => new Response() } as any;
129+
const mockSession = createMockSession();
128130
expect(() => sdk.repository(mockSession, { server: "sds" })).toThrow(ValidationError);
129131
});
130132

131133
it("should create repository with custom serverUrl", () => {
132134
const sdk = new ATProtoSDK(config);
133-
const mockSession = { did: "did:plc:test", sub: "did:plc:test", fetchHandler: async () => new Response() } as any;
135+
const mockSession = createMockSession();
134136
const repo = sdk.repository(mockSession, { serverUrl: "https://custom.server.com" });
135137
expect(repo).toBeDefined();
136138
expect(repo.getServerUrl()).toBe("https://custom.server.com");

packages/sdk-core/tests/repository/BlobOperationsImpl.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
import type { Agent } from "@atproto/api";
23
import { BlobOperationsImpl } from "../../src/repository/BlobOperationsImpl.js";
34
import { NetworkError } from "../../src/core/errors.js";
45

56
describe("BlobOperationsImpl", () => {
6-
let mockAgent: any;
7+
let mockAgent: Partial<Agent>;
78
let blobOps: BlobOperationsImpl;
89
const repoDid = "did:plc:testdid123";
910
const serverUrl = "https://pds.example.com";
@@ -22,7 +23,7 @@ describe("BlobOperationsImpl", () => {
2223
},
2324
};
2425

25-
blobOps = new BlobOperationsImpl(mockAgent, repoDid, serverUrl);
26+
blobOps = new BlobOperationsImpl(mockAgent as Agent, repoDid, serverUrl);
2627
});
2728

2829
describe("upload", () => {

packages/sdk-core/tests/repository/CollaboratorOperationsImpl.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
import type { Session } from "../../src/core/types.js";
23
import { CollaboratorOperationsImpl } from "../../src/repository/CollaboratorOperationsImpl.js";
34
import { NetworkError } from "../../src/core/errors.js";
45

56
describe("CollaboratorOperationsImpl", () => {
6-
let mockSession: any;
7+
let mockSession: Partial<Session>;
78
let collaboratorOps: CollaboratorOperationsImpl;
89
const repoDid = "did:plc:testdid123";
910
const serverUrl = "https://sds.example.com";
@@ -15,7 +16,7 @@ describe("CollaboratorOperationsImpl", () => {
1516
fetchHandler: vi.fn(),
1617
};
1718

18-
collaboratorOps = new CollaboratorOperationsImpl(mockSession, repoDid, serverUrl);
19+
collaboratorOps = new CollaboratorOperationsImpl(mockSession as Session, repoDid, serverUrl);
1920
});
2021

2122
describe("grant", () => {

packages/sdk-core/tests/repository/HypercertOperationsImpl.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
import type { Agent } from "@atproto/api";
23
import { HypercertOperationsImpl } from "../../src/repository/HypercertOperationsImpl.js";
34
import { LexiconRegistry } from "../../src/repository/LexiconRegistry.js";
45
import { NetworkError, ValidationError } from "../../src/core/errors.js";
56
import { HYPERCERT_LEXICONS } from "@hypercerts-org/lexicon";
67

78
describe("HypercertOperationsImpl", () => {
8-
let mockAgent: any;
9+
let mockAgent: Partial<Agent>;
910
let lexiconRegistry: LexiconRegistry;
1011
let hypercertOps: HypercertOperationsImpl;
1112
const repoDid = "did:plc:testdid123";
@@ -31,7 +32,7 @@ describe("HypercertOperationsImpl", () => {
3132
lexiconRegistry.registerMany(HYPERCERT_LEXICONS);
3233
// Mock validate to always return valid - we test LexiconRegistry separately
3334
vi.spyOn(lexiconRegistry, "validate").mockReturnValue({ valid: true });
34-
hypercertOps = new HypercertOperationsImpl(mockAgent, repoDid, serverUrl, lexiconRegistry);
35+
hypercertOps = new HypercertOperationsImpl(mockAgent as Agent, repoDid, serverUrl, lexiconRegistry);
3536
});
3637

3738
describe("create", () => {
@@ -201,7 +202,7 @@ describe("HypercertOperationsImpl", () => {
201202
});
202203

203204
expect(onProgress).toHaveBeenCalled();
204-
const calls = onProgress.mock.calls.map((c: any[]) => c[0].name);
205+
const calls = onProgress.mock.calls.map((c: unknown[]) => (c[0] as { name: string }).name);
205206
expect(calls).toContain("createRights");
206207
expect(calls).toContain("createHypercert");
207208
});

packages/sdk-core/tests/repository/OrganizationOperationsImpl.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
import type { Session } from "../../src/core/types.js";
23
import { OrganizationOperationsImpl } from "../../src/repository/OrganizationOperationsImpl.js";
34
import { NetworkError } from "../../src/core/errors.js";
45

56
describe("OrganizationOperationsImpl", () => {
6-
let mockSession: any;
7+
let mockSession: Partial<Session>;
78
let orgOps: OrganizationOperationsImpl;
89
const repoDid = "did:plc:testdid123";
910
const serverUrl = "https://sds.example.com";
@@ -15,7 +16,7 @@ describe("OrganizationOperationsImpl", () => {
1516
fetchHandler: vi.fn(),
1617
};
1718

18-
orgOps = new OrganizationOperationsImpl(mockSession, repoDid, serverUrl);
19+
orgOps = new OrganizationOperationsImpl(mockSession as Session, repoDid, serverUrl);
1920
});
2021

2122
describe("create", () => {

packages/sdk-core/tests/repository/ProfileOperationsImpl.test.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
import type { Agent } from "@atproto/api";
23
import { ProfileOperationsImpl } from "../../src/repository/ProfileOperationsImpl.js";
34
import { NetworkError } from "../../src/core/errors.js";
45

56
describe("ProfileOperationsImpl", () => {
6-
let mockAgent: any;
7+
let mockAgent: Partial<Agent>;
78
let profileOps: ProfileOperationsImpl;
89
const repoDid = "did:plc:testdid123";
910
const serverUrl = "https://pds.example.com";
@@ -22,7 +23,7 @@ describe("ProfileOperationsImpl", () => {
2223
},
2324
};
2425

25-
profileOps = new ProfileOperationsImpl(mockAgent, repoDid, serverUrl);
26+
profileOps = new ProfileOperationsImpl(mockAgent as Agent, repoDid, serverUrl);
2627
});
2728

2829
describe("get", () => {
@@ -238,17 +239,13 @@ describe("ProfileOperationsImpl", () => {
238239
success: false,
239240
});
240241

241-
await expect(
242-
profileOps.update({ displayName: "New Name" }),
243-
).rejects.toThrow(NetworkError);
242+
await expect(profileOps.update({ displayName: "New Name" })).rejects.toThrow(NetworkError);
244243
});
245244

246245
it("should throw NetworkError when API throws", async () => {
247246
mockAgent.com.atproto.repo.putRecord.mockRejectedValue(new Error("Update failed"));
248247

249-
await expect(
250-
profileOps.update({ displayName: "New Name" }),
251-
).rejects.toThrow(NetworkError);
248+
await expect(profileOps.update({ displayName: "New Name" })).rejects.toThrow(NetworkError);
252249
});
253250
});
254251
});

packages/sdk-core/tests/repository/RecordOperationsImpl.test.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
import type { Agent } from "@atproto/api";
23
import { RecordOperationsImpl } from "../../src/repository/RecordOperationsImpl.js";
34
import { LexiconRegistry } from "../../src/repository/LexiconRegistry.js";
45
import { NetworkError, ValidationError } from "../../src/core/errors.js";
56

67
describe("RecordOperationsImpl", () => {
7-
let mockAgent: any;
8+
let mockAgent: Partial<Agent>;
89
let lexiconRegistry: LexiconRegistry;
910
let recordOps: RecordOperationsImpl;
1011
const repoDid = "did:plc:testdid123";
@@ -25,7 +26,7 @@ describe("RecordOperationsImpl", () => {
2526
};
2627

2728
lexiconRegistry = new LexiconRegistry();
28-
recordOps = new RecordOperationsImpl(mockAgent, repoDid, lexiconRegistry);
29+
recordOps = new RecordOperationsImpl(mockAgent as Agent, repoDid, lexiconRegistry);
2930
});
3031

3132
describe("create", () => {
@@ -314,17 +315,13 @@ describe("RecordOperationsImpl", () => {
314315
success: false,
315316
});
316317

317-
await expect(
318-
recordOps.list({ collection: "app.bsky.feed.post" }),
319-
).rejects.toThrow(NetworkError);
318+
await expect(recordOps.list({ collection: "app.bsky.feed.post" })).rejects.toThrow(NetworkError);
320319
});
321320

322321
it("should throw NetworkError when API throws", async () => {
323322
mockAgent.com.atproto.repo.listRecords.mockRejectedValue(new Error("Network failure"));
324323

325-
await expect(
326-
recordOps.list({ collection: "app.bsky.feed.post" }),
327-
).rejects.toThrow(NetworkError);
324+
await expect(recordOps.list({ collection: "app.bsky.feed.post" })).rejects.toThrow(NetworkError);
328325
});
329326
});
330327

packages/sdk-react/tests/factory/createATProtoReact.test.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@ describe("createATProtoReact", () => {
4747
sdsUrl: "https://sds.example.com",
4848
};
4949

50+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5051
const instance = createATProtoReact({ sdk: mockSDK as any });
5152

5253
expect(instance.sdk).toBe(mockSDK);
5354
});
5455

5556
it("should throw error if neither config nor sdk provided", () => {
57+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5658
expect(() => createATProtoReact({} as any)).toThrow(
57-
"createATProtoReact requires either 'config' or 'sdk' option"
59+
"createATProtoReact requires either 'config' or 'sdk' option",
5860
);
5961
});
6062

@@ -142,7 +144,7 @@ describe("createATProtoReact", () => {
142144
<Provider>
143145
<div data-testid="child">Hello</div>
144146
</Provider>
145-
</QueryClientProvider>
147+
</QueryClientProvider>,
146148
);
147149

148150
expect(screen.getByTestId("child")).toHaveTextContent("Hello");
@@ -159,7 +161,7 @@ describe("createATProtoReact", () => {
159161
<Provider dehydratedState={{ mutations: [], queries: [] }}>
160162
<div>Test</div>
161163
</Provider>
162-
</QueryClientProvider>
164+
</QueryClientProvider>,
163165
);
164166
});
165167
});

0 commit comments

Comments
 (0)