@atcute/client 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -13
- package/dist/client.d.ts +181 -0
- package/dist/client.js +180 -0
- package/dist/client.js.map +1 -0
- package/dist/credential-manager.d.ts +47 -38
- package/dist/credential-manager.js +50 -41
- package/dist/credential-manager.js.map +1 -1
- package/dist/fetch-handler.d.ts +2 -2
- package/dist/fetch-handler.js +1 -1
- package/dist/fetch-handler.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lexicons.d.ts +82 -0
- package/dist/rpc.d.ts +44 -8
- package/dist/rpc.js +13 -1
- package/dist/rpc.js.map +1 -1
- package/lib/client.ts +406 -0
- package/lib/credential-manager.ts +119 -93
- package/lib/fetch-handler.ts +3 -3
- package/lib/index.ts +3 -2
- package/lib/lexicons.ts +81 -0
- package/lib/rpc.ts +44 -8
- package/package.json +2 -2
|
@@ -1,65 +1,71 @@
|
|
|
1
1
|
import type { At, ComAtprotoServerCreateSession } from './lexicons.js';
|
|
2
2
|
|
|
3
|
+
import { Client, ClientResponseError, isXRPCErrorPayload, ok } from './client.js';
|
|
3
4
|
import { simpleFetchHandler, type FetchHandlerObject } from './fetch-handler.js';
|
|
4
|
-
import { XRPC, XRPCError } from './rpc.js';
|
|
5
5
|
|
|
6
6
|
import { getPdsEndpoint, type DidDocument } from './utils/did.js';
|
|
7
7
|
import { decodeJwt } from './utils/jwt.js';
|
|
8
8
|
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* represents the decoded access token, for convenience
|
|
11
|
+
* @deprecated
|
|
12
|
+
*/
|
|
10
13
|
export interface AtpAccessJwt {
|
|
11
|
-
/**
|
|
14
|
+
/** access token scope */
|
|
12
15
|
scope:
|
|
13
16
|
| 'com.atproto.access'
|
|
14
17
|
| 'com.atproto.appPass'
|
|
15
18
|
| 'com.atproto.appPassPrivileged'
|
|
16
19
|
| 'com.atproto.signupQueued'
|
|
17
20
|
| 'com.atproto.takendown';
|
|
18
|
-
/**
|
|
21
|
+
/** account DID */
|
|
19
22
|
sub: At.Did;
|
|
20
|
-
/**
|
|
23
|
+
/** expiration time in Unix seconds */
|
|
21
24
|
exp: number;
|
|
22
|
-
/**
|
|
25
|
+
/** token issued time in Unix seconds */
|
|
23
26
|
iat: number;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* represents the the decoded refresh token, for convenience
|
|
31
|
+
* @deprecated
|
|
32
|
+
*/
|
|
27
33
|
export interface AtpRefreshJwt {
|
|
28
|
-
/**
|
|
34
|
+
/** refresh token scope */
|
|
29
35
|
scope: 'com.atproto.refresh';
|
|
30
|
-
/**
|
|
36
|
+
/** unique identifier for this session */
|
|
31
37
|
jti: string;
|
|
32
|
-
/**
|
|
38
|
+
/** account DID */
|
|
33
39
|
sub: At.Did;
|
|
34
|
-
/**
|
|
40
|
+
/** intended audience of this refresh token, in DID */
|
|
35
41
|
aud: At.Did;
|
|
36
|
-
/**
|
|
42
|
+
/** token expiration time in seconds */
|
|
37
43
|
exp: number;
|
|
38
|
-
/**
|
|
44
|
+
/** token issued time in seconds */
|
|
39
45
|
iat: number;
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
/**
|
|
48
|
+
/** session data, can be persisted and reused */
|
|
43
49
|
export interface AtpSessionData {
|
|
44
|
-
/**
|
|
50
|
+
/** refresh token */
|
|
45
51
|
refreshJwt: string;
|
|
46
|
-
/**
|
|
52
|
+
/** access token */
|
|
47
53
|
accessJwt: string;
|
|
48
|
-
/**
|
|
54
|
+
/** account handle */
|
|
49
55
|
handle: string;
|
|
50
|
-
/**
|
|
56
|
+
/** account DID */
|
|
51
57
|
did: At.Did;
|
|
52
58
|
/** PDS endpoint found in the DID document, this will be used as the service URI if provided */
|
|
53
59
|
pdsUri?: string;
|
|
54
|
-
/**
|
|
60
|
+
/** email address of the account, might not be available if on app password */
|
|
55
61
|
email?: string;
|
|
56
|
-
/**
|
|
62
|
+
/** whether the email address has been confirmed or not */
|
|
57
63
|
emailConfirmed?: boolean;
|
|
58
|
-
/**
|
|
64
|
+
/** whether the account has email-based two-factor authentication enabled */
|
|
59
65
|
emailAuthFactor?: boolean;
|
|
60
|
-
/**
|
|
66
|
+
/** whether the account is active (not deactivated, taken down, or suspended) */
|
|
61
67
|
active: boolean;
|
|
62
|
-
/**
|
|
68
|
+
/** possible reason for why the account is inactive */
|
|
63
69
|
inactiveStatus?: string;
|
|
64
70
|
}
|
|
65
71
|
|
|
@@ -67,29 +73,36 @@ export interface CredentialManagerOptions {
|
|
|
67
73
|
/** PDS server URL */
|
|
68
74
|
service: string;
|
|
69
75
|
|
|
70
|
-
/**
|
|
71
|
-
fetch?: typeof
|
|
76
|
+
/** custom fetch function */
|
|
77
|
+
fetch?: typeof fetch;
|
|
72
78
|
|
|
73
|
-
/**
|
|
79
|
+
/** function called when the session expires and can't be refreshed */
|
|
74
80
|
onExpired?: (session: AtpSessionData) => void;
|
|
75
|
-
/**
|
|
81
|
+
/** function called after a successful session refresh */
|
|
76
82
|
onRefresh?: (session: AtpSessionData) => void;
|
|
77
|
-
/**
|
|
83
|
+
/** function called whenever the session object is updated (login, resume, refresh) */
|
|
78
84
|
onSessionUpdate?: (session: AtpSessionData) => void;
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
export class CredentialManager implements FetchHandlerObject {
|
|
88
|
+
/** service URL to make authentication requests with */
|
|
82
89
|
readonly serviceUrl: string;
|
|
90
|
+
/** fetch implementation */
|
|
83
91
|
fetch: typeof fetch;
|
|
84
92
|
|
|
85
|
-
|
|
93
|
+
/** internal client instance for making authentication requests */
|
|
94
|
+
#server: Client;
|
|
95
|
+
/** holds a promise for the current refresh operation, used for debouncing */
|
|
86
96
|
#refreshSessionPromise: Promise<void> | undefined;
|
|
87
97
|
|
|
98
|
+
/** callback for session expiration */
|
|
88
99
|
#onExpired: CredentialManagerOptions['onExpired'];
|
|
100
|
+
/** callback for successful session refresh */
|
|
89
101
|
#onRefresh: CredentialManagerOptions['onRefresh'];
|
|
102
|
+
/** callback for session updates */
|
|
90
103
|
#onSessionUpdate: CredentialManagerOptions['onSessionUpdate'];
|
|
91
104
|
|
|
92
|
-
/**
|
|
105
|
+
/** current active session, undefined if not authenticated */
|
|
93
106
|
session?: AtpSessionData;
|
|
94
107
|
|
|
95
108
|
constructor({
|
|
@@ -102,13 +115,14 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
102
115
|
this.serviceUrl = service;
|
|
103
116
|
this.fetch = _fetch;
|
|
104
117
|
|
|
105
|
-
this.#server = new
|
|
118
|
+
this.#server = new Client({ handler: simpleFetchHandler({ service, fetch: _fetch }) });
|
|
106
119
|
|
|
107
120
|
this.#onRefresh = onRefresh;
|
|
108
121
|
this.#onExpired = onExpired;
|
|
109
122
|
this.#onSessionUpdate = onSessionUpdate;
|
|
110
123
|
}
|
|
111
124
|
|
|
125
|
+
/** service URL to make actual API requests with */
|
|
112
126
|
get dispatchUrl() {
|
|
113
127
|
return this.session?.pdsUri ?? this.serviceUrl;
|
|
114
128
|
}
|
|
@@ -138,13 +152,14 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
138
152
|
return initialResponse;
|
|
139
153
|
}
|
|
140
154
|
|
|
141
|
-
//
|
|
142
|
-
// - refreshSession
|
|
143
|
-
// -
|
|
155
|
+
// return initial response if:
|
|
156
|
+
// - the above refreshSession failed and cleared the session
|
|
157
|
+
// - provided request body was a stream, which can't be resent once consumed
|
|
144
158
|
if (!this.session || init.body instanceof ReadableStream) {
|
|
145
159
|
return initialResponse;
|
|
146
160
|
}
|
|
147
161
|
|
|
162
|
+
// set the new token and retry the request
|
|
148
163
|
headers.set('authorization', `Bearer ${this.session.accessJwt}`);
|
|
149
164
|
|
|
150
165
|
return await (0, this.fetch)(url, { ...init, headers });
|
|
@@ -158,30 +173,29 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
158
173
|
|
|
159
174
|
async #refreshSessionInner(): Promise<void> {
|
|
160
175
|
const currentSession = this.session;
|
|
161
|
-
|
|
162
176
|
if (!currentSession) {
|
|
163
177
|
return;
|
|
164
178
|
}
|
|
165
179
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (kind === 'ExpiredToken' || kind === 'InvalidToken') {
|
|
180
|
-
this.session = undefined;
|
|
181
|
-
this.#onExpired?.(currentSession);
|
|
182
|
-
}
|
|
180
|
+
const response = await this.#server.post('com.atproto.server.refreshSession', {
|
|
181
|
+
headers: {
|
|
182
|
+
authorization: `Bearer ${currentSession.refreshJwt}`,
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
if (!response.ok) {
|
|
187
|
+
const error = response.data.error;
|
|
188
|
+
|
|
189
|
+
if (error === 'ExpiredToken' || error === 'InvalidToken') {
|
|
190
|
+
this.session = undefined;
|
|
191
|
+
this.#onExpired?.(currentSession);
|
|
183
192
|
}
|
|
193
|
+
|
|
194
|
+
throw new ClientResponseError(response);
|
|
184
195
|
}
|
|
196
|
+
|
|
197
|
+
this.#updateSession({ ...currentSession, ...response.data });
|
|
198
|
+
this.#onRefresh?.(this.session!);
|
|
185
199
|
}
|
|
186
200
|
|
|
187
201
|
#updateSession(raw: ComAtprotoServerCreateSession.Output): AtpSessionData {
|
|
@@ -192,7 +206,7 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
192
206
|
pdsUri = getPdsEndpoint(didDoc);
|
|
193
207
|
}
|
|
194
208
|
|
|
195
|
-
const newSession = {
|
|
209
|
+
const newSession: AtpSessionData = {
|
|
196
210
|
accessJwt: raw.accessJwt,
|
|
197
211
|
refreshJwt: raw.refreshJwt,
|
|
198
212
|
handle: raw.handle,
|
|
@@ -200,7 +214,7 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
200
214
|
pdsUri: pdsUri,
|
|
201
215
|
email: raw.email,
|
|
202
216
|
emailConfirmed: raw.emailConfirmed,
|
|
203
|
-
emailAuthFactor: raw.
|
|
217
|
+
emailAuthFactor: raw.emailAuthFactor,
|
|
204
218
|
active: raw.active ?? true,
|
|
205
219
|
inactiveStatus: raw.status,
|
|
206
220
|
};
|
|
@@ -212,16 +226,16 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
212
226
|
}
|
|
213
227
|
|
|
214
228
|
/**
|
|
215
|
-
*
|
|
216
|
-
* @param session
|
|
229
|
+
* resume from a persisted session
|
|
230
|
+
* @param session session data, taken from `AtpAuth#session` after login
|
|
217
231
|
*/
|
|
218
232
|
async resume(session: AtpSessionData): Promise<AtpSessionData> {
|
|
219
|
-
const now = Date.now() /
|
|
233
|
+
const now = Date.now() / 1_000 + 60 * 5;
|
|
220
234
|
|
|
221
235
|
const refreshToken = decodeJwt(session.refreshJwt) as AtpRefreshJwt;
|
|
222
236
|
|
|
223
237
|
if (now >= refreshToken.exp) {
|
|
224
|
-
throw new
|
|
238
|
+
throw new ClientResponseError({ status: 401, data: { error: 'InvalidToken' } });
|
|
225
239
|
}
|
|
226
240
|
|
|
227
241
|
const accessToken = decodeJwt(session.accessJwt) as AtpAccessJwt;
|
|
@@ -230,62 +244,69 @@ export class CredentialManager implements FetchHandlerObject {
|
|
|
230
244
|
if (now >= accessToken.exp) {
|
|
231
245
|
await this.#refreshSession();
|
|
232
246
|
} else {
|
|
233
|
-
const promise =
|
|
234
|
-
|
|
235
|
-
|
|
247
|
+
const promise = ok(
|
|
248
|
+
this.#server.get('com.atproto.server.getSession', {
|
|
249
|
+
headers: {
|
|
250
|
+
authorization: `Bearer ${session.accessJwt}`,
|
|
251
|
+
},
|
|
252
|
+
}),
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
promise.then(
|
|
256
|
+
(next) => {
|
|
257
|
+
const existing = this.session;
|
|
258
|
+
if (!existing || existing.did !== next.did) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
this.#updateSession({ ...existing, ...next });
|
|
236
263
|
},
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const next = response.data;
|
|
242
|
-
|
|
243
|
-
if (!existing) {
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
this.#updateSession({ ...existing, ...next });
|
|
248
|
-
});
|
|
264
|
+
(_err) => {
|
|
265
|
+
// ignore error
|
|
266
|
+
},
|
|
267
|
+
);
|
|
249
268
|
}
|
|
250
269
|
|
|
251
270
|
if (!this.session) {
|
|
252
|
-
throw new
|
|
271
|
+
throw new ClientResponseError({ status: 401, data: { error: 'InvalidToken' } });
|
|
253
272
|
}
|
|
254
273
|
|
|
255
274
|
return this.session;
|
|
256
275
|
}
|
|
257
276
|
|
|
258
277
|
/**
|
|
259
|
-
*
|
|
260
|
-
* @param options
|
|
261
|
-
* @returns
|
|
278
|
+
* sign in to an account
|
|
279
|
+
* @param options credential options
|
|
280
|
+
* @returns session data
|
|
262
281
|
*/
|
|
263
282
|
async login(options: AuthLoginOptions): Promise<AtpSessionData> {
|
|
264
283
|
// Reset the session
|
|
265
284
|
this.session = undefined;
|
|
266
285
|
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
286
|
+
const session = await ok(
|
|
287
|
+
this.#server.post('com.atproto.server.createSession', {
|
|
288
|
+
input: {
|
|
289
|
+
identifier: options.identifier,
|
|
290
|
+
password: options.password,
|
|
291
|
+
authFactorToken: options.code,
|
|
292
|
+
allowTakendown: options.allowTakendown,
|
|
293
|
+
},
|
|
294
|
+
}),
|
|
295
|
+
);
|
|
275
296
|
|
|
276
|
-
return this.#updateSession(
|
|
297
|
+
return this.#updateSession(session);
|
|
277
298
|
}
|
|
278
299
|
}
|
|
279
300
|
|
|
280
|
-
/**
|
|
301
|
+
/** credentials */
|
|
281
302
|
export interface AuthLoginOptions {
|
|
282
|
-
/**
|
|
303
|
+
/** what account to login as, this could be domain handle, DID, or email address */
|
|
283
304
|
identifier: string;
|
|
284
|
-
/**
|
|
305
|
+
/** account password */
|
|
285
306
|
password: string;
|
|
286
|
-
/**
|
|
307
|
+
/** two-factor authentication code, if email TOTP is enabled */
|
|
287
308
|
code?: string;
|
|
288
|
-
/**
|
|
309
|
+
/** allow signing in even if the account has been taken down */
|
|
289
310
|
allowTakendown?: boolean;
|
|
290
311
|
}
|
|
291
312
|
|
|
@@ -298,6 +319,9 @@ const isExpiredTokenResponse = async (response: Response): Promise<boolean> => {
|
|
|
298
319
|
return false;
|
|
299
320
|
}
|
|
300
321
|
|
|
322
|
+
// this is nasty as it relies heavily on what the PDS returns, but avoiding
|
|
323
|
+
// cloning and reading the request as much as possible is better.
|
|
324
|
+
|
|
301
325
|
// {"error":"ExpiredToken","message":"Token has expired"}
|
|
302
326
|
// {"error":"ExpiredToken","message":"Token is expired"}
|
|
303
327
|
if (extractContentLength(response.headers) > 54 * 1.5) {
|
|
@@ -305,8 +329,10 @@ const isExpiredTokenResponse = async (response: Response): Promise<boolean> => {
|
|
|
305
329
|
}
|
|
306
330
|
|
|
307
331
|
try {
|
|
308
|
-
const
|
|
309
|
-
|
|
332
|
+
const data = await response.clone().json();
|
|
333
|
+
if (isXRPCErrorPayload(data)) {
|
|
334
|
+
return data.error === 'ExpiredToken';
|
|
335
|
+
}
|
|
310
336
|
} catch {}
|
|
311
337
|
|
|
312
338
|
return false;
|
package/lib/fetch-handler.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** fetch handler function */
|
|
2
2
|
export type FetchHandler = (pathname: string, init: RequestInit) => Promise<Response>;
|
|
3
3
|
|
|
4
|
-
/**
|
|
4
|
+
/** fetch handler in an object */
|
|
5
5
|
export interface FetchHandlerObject {
|
|
6
6
|
handle(this: FetchHandlerObject, pathname: string, init: RequestInit): Promise<Response>;
|
|
7
7
|
}
|
|
@@ -25,6 +25,6 @@ export const simpleFetchHandler = ({
|
|
|
25
25
|
}: SimpleFetchHandlerOptions): FetchHandler => {
|
|
26
26
|
return async (pathname, init) => {
|
|
27
27
|
const url = new URL(pathname, service);
|
|
28
|
-
return _fetch(url, init);
|
|
28
|
+
return await _fetch(url, init);
|
|
29
29
|
};
|
|
30
30
|
};
|
package/lib/index.ts
CHANGED
package/lib/lexicons.ts
CHANGED
|
@@ -316,6 +316,17 @@ export declare namespace ComAtprotoAdminUpdateAccountPassword {
|
|
|
316
316
|
type Output = undefined;
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
/** Administrative action to update an account's signing key in their Did document. */
|
|
320
|
+
export declare namespace ComAtprotoAdminUpdateAccountSigningKey {
|
|
321
|
+
interface Params {}
|
|
322
|
+
interface Input {
|
|
323
|
+
did: At.Did;
|
|
324
|
+
/** Did-key formatted public key */
|
|
325
|
+
signingKey: At.Did;
|
|
326
|
+
}
|
|
327
|
+
type Output = undefined;
|
|
328
|
+
}
|
|
329
|
+
|
|
319
330
|
/** Update the service-specific admin status of a subject (account, record, or blob). */
|
|
320
331
|
export declare namespace ComAtprotoAdminUpdateSubjectStatus {
|
|
321
332
|
interface Params {}
|
|
@@ -1336,6 +1347,10 @@ export declare namespace ComAtprotoServerUpdateEmail {
|
|
|
1336
1347
|
}
|
|
1337
1348
|
}
|
|
1338
1349
|
|
|
1350
|
+
export declare namespace ComAtprotoSyncDefs {
|
|
1351
|
+
type HostStatus = 'active' | 'banned' | 'idle' | 'offline' | 'throttled' | (string & {});
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1339
1354
|
/** Get a blob associated with a given account. Returns the full blob as originally uploaded. Does not require auth; implemented by PDS. */
|
|
1340
1355
|
export declare namespace ComAtprotoSyncGetBlob {
|
|
1341
1356
|
interface Params {
|
|
@@ -1404,6 +1419,26 @@ export declare namespace ComAtprotoSyncGetHead {
|
|
|
1404
1419
|
}
|
|
1405
1420
|
}
|
|
1406
1421
|
|
|
1422
|
+
/** Returns information about a specified upstream host, as consumed by the server. Implemented by relays. */
|
|
1423
|
+
export declare namespace ComAtprotoSyncGetHostStatus {
|
|
1424
|
+
interface Params {
|
|
1425
|
+
/** Hostname of the host (eg, PDS or relay) being queried. */
|
|
1426
|
+
hostname: string;
|
|
1427
|
+
}
|
|
1428
|
+
type Input = undefined;
|
|
1429
|
+
interface Output {
|
|
1430
|
+
hostname: string;
|
|
1431
|
+
/** Number of accounts on the server which are associated with the upstream host. Note that the upstream may actually have more accounts. */
|
|
1432
|
+
accountCount?: number;
|
|
1433
|
+
/** Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor). */
|
|
1434
|
+
seq?: number;
|
|
1435
|
+
status?: ComAtprotoSyncDefs.HostStatus;
|
|
1436
|
+
}
|
|
1437
|
+
interface Errors {
|
|
1438
|
+
HostNotFound: {};
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1407
1442
|
/** Get the current commit CID & revision of the specified repo. Does not require auth. */
|
|
1408
1443
|
export declare namespace ComAtprotoSyncGetLatestCommit {
|
|
1409
1444
|
interface Params {
|
|
@@ -1516,6 +1551,34 @@ export declare namespace ComAtprotoSyncListBlobs {
|
|
|
1516
1551
|
}
|
|
1517
1552
|
}
|
|
1518
1553
|
|
|
1554
|
+
/** Enumerates upstream hosts (eg, PDS or relay instances) that this service consumes from. Implemented by relays. */
|
|
1555
|
+
export declare namespace ComAtprotoSyncListHosts {
|
|
1556
|
+
interface Params {
|
|
1557
|
+
cursor?: string;
|
|
1558
|
+
/**
|
|
1559
|
+
* Minimum: 1 \
|
|
1560
|
+
* Maximum: 1000
|
|
1561
|
+
* @default 200
|
|
1562
|
+
*/
|
|
1563
|
+
limit?: number;
|
|
1564
|
+
}
|
|
1565
|
+
type Input = undefined;
|
|
1566
|
+
interface Output {
|
|
1567
|
+
/** Sort order is not formally specified. Recommended order is by time host was first seen by the server, with oldest first. */
|
|
1568
|
+
hosts: Host[];
|
|
1569
|
+
cursor?: string;
|
|
1570
|
+
}
|
|
1571
|
+
interface Host {
|
|
1572
|
+
[Brand.Type]?: 'com.atproto.sync.listHosts#host';
|
|
1573
|
+
/** hostname of server; not a URL (no scheme) */
|
|
1574
|
+
hostname: string;
|
|
1575
|
+
accountCount?: number;
|
|
1576
|
+
/** Recent repo stream event sequence number. May be delayed from actual stream processing (eg, persisted cursor not in-memory cursor). */
|
|
1577
|
+
seq?: number;
|
|
1578
|
+
status?: ComAtprotoSyncDefs.HostStatus;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1519
1582
|
/** Enumerates all the DID, rev, and commit CID for all repos hosted by this service. Does not require auth; implemented by PDS and Relay. */
|
|
1520
1583
|
export declare namespace ComAtprotoSyncListRepos {
|
|
1521
1584
|
interface Params {
|
|
@@ -1593,6 +1656,9 @@ export declare namespace ComAtprotoSyncRequestCrawl {
|
|
|
1593
1656
|
hostname: string;
|
|
1594
1657
|
}
|
|
1595
1658
|
type Output = undefined;
|
|
1659
|
+
interface Errors {
|
|
1660
|
+
HostBanned: {};
|
|
1661
|
+
}
|
|
1596
1662
|
}
|
|
1597
1663
|
|
|
1598
1664
|
export declare namespace ComAtprotoSyncSubscribeRepos {
|
|
@@ -1887,6 +1953,12 @@ export declare interface Queries {
|
|
|
1887
1953
|
output: ComAtprotoSyncGetHead.Output;
|
|
1888
1954
|
response: { json: ComAtprotoSyncGetHead.Output };
|
|
1889
1955
|
};
|
|
1956
|
+
'com.atproto.sync.getHostStatus': {
|
|
1957
|
+
params: ComAtprotoSyncGetHostStatus.Params;
|
|
1958
|
+
/** @deprecated */
|
|
1959
|
+
output: ComAtprotoSyncGetHostStatus.Output;
|
|
1960
|
+
response: { json: ComAtprotoSyncGetHostStatus.Output };
|
|
1961
|
+
};
|
|
1890
1962
|
'com.atproto.sync.getLatestCommit': {
|
|
1891
1963
|
params: ComAtprotoSyncGetLatestCommit.Params;
|
|
1892
1964
|
/** @deprecated */
|
|
@@ -1917,6 +1989,12 @@ export declare interface Queries {
|
|
|
1917
1989
|
output: ComAtprotoSyncListBlobs.Output;
|
|
1918
1990
|
response: { json: ComAtprotoSyncListBlobs.Output };
|
|
1919
1991
|
};
|
|
1992
|
+
'com.atproto.sync.listHosts': {
|
|
1993
|
+
params: ComAtprotoSyncListHosts.Params;
|
|
1994
|
+
/** @deprecated */
|
|
1995
|
+
output: ComAtprotoSyncListHosts.Output;
|
|
1996
|
+
response: { json: ComAtprotoSyncListHosts.Output };
|
|
1997
|
+
};
|
|
1920
1998
|
'com.atproto.sync.listRepos': {
|
|
1921
1999
|
params: ComAtprotoSyncListRepos.Params;
|
|
1922
2000
|
/** @deprecated */
|
|
@@ -1970,6 +2048,9 @@ export declare interface Procedures {
|
|
|
1970
2048
|
'com.atproto.admin.updateAccountPassword': {
|
|
1971
2049
|
input: ComAtprotoAdminUpdateAccountPassword.Input;
|
|
1972
2050
|
};
|
|
2051
|
+
'com.atproto.admin.updateAccountSigningKey': {
|
|
2052
|
+
input: ComAtprotoAdminUpdateAccountSigningKey.Input;
|
|
2053
|
+
};
|
|
1973
2054
|
'com.atproto.admin.updateSubjectStatus': {
|
|
1974
2055
|
input: ComAtprotoAdminUpdateSubjectStatus.Input;
|
|
1975
2056
|
/** @deprecated */
|
package/lib/rpc.ts
CHANGED
|
@@ -3,15 +3,24 @@ import type { At, Procedures, Queries } from './lexicons.js';
|
|
|
3
3
|
import { buildFetchHandler, type FetchHandler, type FetchHandlerObject } from './fetch-handler.js';
|
|
4
4
|
import { mergeHeaders } from './utils/http.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated
|
|
8
|
+
*/
|
|
6
9
|
export type HeadersObject = Record<string, string>;
|
|
7
10
|
|
|
8
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Response from XRPC service
|
|
13
|
+
* @deprecated
|
|
14
|
+
*/
|
|
9
15
|
export interface XRPCResponse<T = any> {
|
|
10
16
|
data: T;
|
|
11
17
|
headers: HeadersObject;
|
|
12
18
|
}
|
|
13
19
|
|
|
14
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Options for constructing an XRPC error
|
|
22
|
+
* @deprecated
|
|
23
|
+
*/
|
|
15
24
|
export interface XRPCErrorOptions {
|
|
16
25
|
kind?: string;
|
|
17
26
|
description?: string;
|
|
@@ -19,7 +28,10 @@ export interface XRPCErrorOptions {
|
|
|
19
28
|
cause?: unknown;
|
|
20
29
|
}
|
|
21
30
|
|
|
22
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Error coming from the XRPC service
|
|
33
|
+
* @deprecated
|
|
34
|
+
*/
|
|
23
35
|
export class XRPCError extends Error {
|
|
24
36
|
override name = 'XRPCError';
|
|
25
37
|
|
|
@@ -50,19 +62,28 @@ export class XRPCError extends Error {
|
|
|
50
62
|
}
|
|
51
63
|
}
|
|
52
64
|
|
|
53
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Service proxy options
|
|
67
|
+
* @deprecated
|
|
68
|
+
*/
|
|
54
69
|
export interface XRPCProxyOptions {
|
|
55
70
|
type: 'atproto_pds' | 'atproto_labeler' | 'bsky_fg' | 'bsky_notif' | ({} & string);
|
|
56
71
|
service: At.Did;
|
|
57
72
|
}
|
|
58
73
|
|
|
59
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Options for constructing an XRPC
|
|
76
|
+
* @deprecated
|
|
77
|
+
*/
|
|
60
78
|
export interface XRPCOptions {
|
|
61
79
|
handler: FetchHandler | FetchHandlerObject;
|
|
62
80
|
proxy?: XRPCProxyOptions;
|
|
63
81
|
}
|
|
64
82
|
|
|
65
|
-
/**
|
|
83
|
+
/**
|
|
84
|
+
* XRPC request options
|
|
85
|
+
* @deprecated
|
|
86
|
+
*/
|
|
66
87
|
export interface XRPCRequestOptions {
|
|
67
88
|
type: 'get' | 'post';
|
|
68
89
|
nsid: string;
|
|
@@ -72,7 +93,10 @@ export interface XRPCRequestOptions {
|
|
|
72
93
|
signal?: AbortSignal;
|
|
73
94
|
}
|
|
74
95
|
|
|
75
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* XRPC response
|
|
98
|
+
* @deprecated
|
|
99
|
+
*/
|
|
76
100
|
export interface XRPCResponse<T = any> {
|
|
77
101
|
data: T;
|
|
78
102
|
headers: HeadersObject;
|
|
@@ -86,13 +110,19 @@ interface BaseRPCOptions {
|
|
|
86
110
|
signal?: AbortSignal;
|
|
87
111
|
}
|
|
88
112
|
|
|
89
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* Options for the query/procedure request
|
|
115
|
+
* @deprecated
|
|
116
|
+
*/
|
|
90
117
|
export type RPCOptions<T> = BaseRPCOptions &
|
|
91
118
|
(T extends { params: any } ? { params: T['params'] } : {}) &
|
|
92
119
|
(T extends { input: any } ? { data: T['input'] } : {});
|
|
93
120
|
|
|
94
121
|
type OutputOf<T> = T extends { output: any } ? T['output'] : never;
|
|
95
122
|
|
|
123
|
+
/**
|
|
124
|
+
* @deprecated
|
|
125
|
+
*/
|
|
96
126
|
export class XRPC {
|
|
97
127
|
handle: FetchHandler;
|
|
98
128
|
proxy: XRPCProxyOptions | undefined;
|
|
@@ -253,10 +283,16 @@ interface ErrorResponseBody {
|
|
|
253
283
|
message?: string;
|
|
254
284
|
}
|
|
255
285
|
|
|
286
|
+
/**
|
|
287
|
+
* @deprecated
|
|
288
|
+
*/
|
|
256
289
|
export const clone = (rpc: XRPC): XRPC => {
|
|
257
290
|
return new XRPC({ handler: rpc.handle, proxy: rpc.proxy });
|
|
258
291
|
};
|
|
259
292
|
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated
|
|
295
|
+
*/
|
|
260
296
|
export const withProxy = (rpc: XRPC, options: XRPCProxyOptions) => {
|
|
261
297
|
return new XRPC({ handler: rpc.handle, proxy: options });
|
|
262
298
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@atcute/client",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"description": "lightweight and cute API client for AT Protocol",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@vitest/coverage-v8": "^3.0.4",
|
|
26
26
|
"vitest": "^3.0.4",
|
|
27
27
|
"@atcute/internal-dev-env": "^1.0.1",
|
|
28
|
-
"@atcute/lex-cli": "^1.1.
|
|
28
|
+
"@atcute/lex-cli": "^1.1.2"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "tsc --project tsconfig.build.json",
|