@atproto/xrpc 0.5.0 → 0.6.0-rc.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/CHANGELOG.md +35 -0
- package/README.md +56 -31
- package/dist/client.d.ts +12 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +21 -80
- package/dist/client.js.map +1 -1
- package/dist/fetch-handler.d.ts +33 -0
- package/dist/fetch-handler.d.ts.map +1 -0
- package/dist/fetch-handler.js +21 -0
- package/dist/fetch-handler.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +16 -12
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +61 -12
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +8 -5
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +290 -77
- package/dist/util.js.map +1 -1
- package/dist/xrpc-client.d.ts +10 -0
- package/dist/xrpc-client.d.ts.map +1 -0
- package/dist/xrpc-client.js +79 -0
- package/dist/xrpc-client.js.map +1 -0
- package/package.json +3 -3
- package/src/client.ts +34 -121
- package/src/fetch-handler.ts +68 -0
- package/src/index.ts +5 -1
- package/src/types.ts +77 -24
- package/src/util.ts +353 -84
- package/src/xrpc-client.ts +108 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @atproto/xrpc
|
|
2
2
|
|
|
3
|
+
## 0.6.0-rc.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`2ded0156b`](https://github.com/bluesky-social/atproto/commit/2ded0156b9adf33b9cce66583a375bff922d383b) Thanks [@matthieusieben](https://github.com/matthieusieben)! - **New Features**:
|
|
8
|
+
|
|
9
|
+
1. Improved Separation of Concerns: We've restructured the XRPC HTTP call
|
|
10
|
+
dispatcher into a distinct class. This means cleaner code organization and
|
|
11
|
+
better clarity on responsibilities.
|
|
12
|
+
2. Enhanced Evolutivity: With this refactor, the XRPC client is now more
|
|
13
|
+
adaptable to various use cases. You can easily extend and customize the
|
|
14
|
+
dispatcher perform session management, retries, and more.
|
|
15
|
+
|
|
16
|
+
**Compatibility**:
|
|
17
|
+
|
|
18
|
+
Most of the changes introduced in this version are backward-compatible. However,
|
|
19
|
+
there are a couple of breaking changes you should be aware of:
|
|
20
|
+
|
|
21
|
+
- Customizing `fetchHandler`: The ability to customize the fetchHandler on the
|
|
22
|
+
XRPC Client and AtpAgent classes has been modified. Please review your code if
|
|
23
|
+
you rely on custom fetch handlers.
|
|
24
|
+
- Managing Sessions: Previously, you had the ability to manage sessions directly
|
|
25
|
+
through AtpAgent instances. Now, session management must be handled through a
|
|
26
|
+
dedicated `SessionManager` instance. If you were making authenticated
|
|
27
|
+
requests, you'll need to update your code to use explicit session management.
|
|
28
|
+
- The `fetch()` method, as well as WhatWG compliant `Request` and `Headers`
|
|
29
|
+
constructors, must be globally available in your environment.
|
|
30
|
+
|
|
31
|
+
- [#2483](https://github.com/bluesky-social/atproto/pull/2483) [`2ded0156b`](https://github.com/bluesky-social/atproto/commit/2ded0156b9adf33b9cce66583a375bff922d383b) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add the ability to use `fetch()` compatible `BodyInit` body when making XRPC calls.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- Updated dependencies [[`2ded0156b`](https://github.com/bluesky-social/atproto/commit/2ded0156b9adf33b9cce66583a375bff922d383b), [`2ded0156b`](https://github.com/bluesky-social/atproto/commit/2ded0156b9adf33b9cce66583a375bff922d383b)]:
|
|
36
|
+
- @atproto/lexicon@0.4.1-rc.0
|
|
37
|
+
|
|
3
38
|
## 0.5.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -9,9 +9,9 @@ TypeScript client library for talking to [atproto](https://atproto.com) services
|
|
|
9
9
|
|
|
10
10
|
```typescript
|
|
11
11
|
import { LexiconDoc } from '@atproto/lexicon'
|
|
12
|
-
import
|
|
12
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
13
13
|
|
|
14
|
-
const pingLexicon
|
|
14
|
+
const pingLexicon = {
|
|
15
15
|
lexicon: 1,
|
|
16
16
|
id: 'io.example.ping',
|
|
17
17
|
defs: {
|
|
@@ -32,44 +32,69 @@ const pingLexicon: LexiconDoc = {
|
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
},
|
|
35
|
-
}
|
|
36
|
-
|
|
35
|
+
} satisfies LexiconDoc
|
|
36
|
+
|
|
37
|
+
const xrpc = new XrpcClient('https://ping.example.com', [
|
|
38
|
+
// Any number of lexicon here
|
|
39
|
+
pingLexicon,
|
|
40
|
+
])
|
|
37
41
|
|
|
38
|
-
const res1 = await xrpc.call('
|
|
42
|
+
const res1 = await xrpc.call('io.example.ping', {
|
|
39
43
|
message: 'hello world',
|
|
40
44
|
})
|
|
41
45
|
res1.encoding // => 'application/json'
|
|
42
46
|
res1.body // => {message: 'hello world'}
|
|
43
|
-
|
|
44
|
-
.service('https://example.com')
|
|
45
|
-
.call('io.example.ping', { message: 'hello world' })
|
|
46
|
-
res2.encoding // => 'application/json'
|
|
47
|
-
res2.body // => {message: 'hello world'}
|
|
47
|
+
```
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
49
|
+
### With a custom fetch handler
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import { XrpcClient } from '@atproto/xrpc'
|
|
53
|
+
|
|
54
|
+
const session = {
|
|
55
|
+
serviceUrl: 'https://ping.example.com',
|
|
56
|
+
token: '<my-token>',
|
|
57
|
+
async refreshToken() {
|
|
58
|
+
const { token } = await fetch('https://auth.example.com/refresh', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
61
|
+
}).then((res) => res.json())
|
|
62
|
+
|
|
63
|
+
this.token = token
|
|
64
|
+
|
|
65
|
+
return token
|
|
64
66
|
},
|
|
65
67
|
}
|
|
66
|
-
xrpc.addLexicon(writeJsonLexicon)
|
|
67
68
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
)
|
|
69
|
+
const sessionBasedFetch: FetchHandler = async (
|
|
70
|
+
url: string,
|
|
71
|
+
init: RequestInit,
|
|
72
|
+
) => {
|
|
73
|
+
const headers = new Headers(init.headers)
|
|
74
|
+
|
|
75
|
+
headers.set('Authorization', `Bearer ${session.token}`)
|
|
76
|
+
|
|
77
|
+
const response = await fetch(new URL(url, session.serviceUrl), {
|
|
78
|
+
...init,
|
|
79
|
+
headers,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
if (response.status === 401) {
|
|
83
|
+
// Refresh token, then try again.
|
|
84
|
+
const newToken = await session.refreshToken()
|
|
85
|
+
headers.set('Authorization', `Bearer ${newToken}`)
|
|
86
|
+
return fetch(new URL(url, session.serviceUrl), { ...init, headers })
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return response
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const xrpc = new XrpcClient(sessionBasedFetch, [
|
|
93
|
+
// Any number of lexicon here
|
|
94
|
+
pingLexicon,
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
//
|
|
73
98
|
```
|
|
74
99
|
|
|
75
100
|
## License
|
package/dist/client.d.ts
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { LexiconDoc, Lexicons } from '@atproto/lexicon';
|
|
2
|
-
import {
|
|
2
|
+
import { CallOptions, Gettable, QueryParams } from './types';
|
|
3
|
+
import { XrpcClient } from './xrpc-client';
|
|
4
|
+
/** @deprecated Use {@link XrpcClient} instead */
|
|
3
5
|
export declare class Client {
|
|
4
|
-
|
|
6
|
+
/** @deprecated */
|
|
7
|
+
get fetch(): never;
|
|
8
|
+
/** @deprecated */
|
|
9
|
+
set fetch(_: never);
|
|
5
10
|
lex: Lexicons;
|
|
6
|
-
call(serviceUri: string | URL, methodNsid: string, params?: QueryParams, data?:
|
|
11
|
+
call(serviceUri: string | URL, methodNsid: string, params?: QueryParams, data?: BodyInit | null, opts?: CallOptions): Promise<import("./types").XRPCResponse>;
|
|
7
12
|
service(serviceUri: string | URL): ServiceClient;
|
|
8
13
|
addLexicon(doc: LexiconDoc): void;
|
|
9
14
|
addLexicons(docs: LexiconDoc[]): void;
|
|
10
15
|
removeLexicon(uri: string): void;
|
|
11
16
|
}
|
|
12
|
-
|
|
17
|
+
/** @deprecated Use {@link XrpcClient} instead */
|
|
18
|
+
export declare class ServiceClient extends XrpcClient {
|
|
13
19
|
baseClient: Client;
|
|
14
20
|
uri: URL;
|
|
15
|
-
headers:
|
|
21
|
+
protected headers: Map<string, Gettable<string | null>>;
|
|
16
22
|
constructor(baseClient: Client, serviceUri: string | URL);
|
|
17
|
-
setHeader(key: string, value: string): void;
|
|
23
|
+
setHeader(key: string, value: Gettable<null | string>): void;
|
|
18
24
|
unsetHeader(key: string): void;
|
|
19
|
-
call(methodNsid: string, params?: QueryParams, data?: unknown, opts?: CallOptions): Promise<XRPCResponse>;
|
|
20
25
|
}
|
|
21
|
-
export declare function defaultFetchHandler(httpUri: string, httpMethod: string, httpHeaders: Headers, httpReqBody: unknown): Promise<FetchHandlerResponse>;
|
|
22
26
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAG1C,iDAAiD;AACjD,qBAAa,MAAM;IACjB,kBAAkB;IAClB,IAAI,KAAK,IAAI,KAAK,CAIjB;IAED,kBAAkB;IAClB,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,EAIjB;IAED,GAAG,WAAiB;IAKd,IAAI,CACR,UAAU,EAAE,MAAM,GAAG,GAAG,EACxB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,EACtB,IAAI,CAAC,EAAE,WAAW;IAKpB,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG;IAOhC,UAAU,CAAC,GAAG,EAAE,UAAU;IAI1B,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE;IAM9B,aAAa,CAAC,GAAG,EAAE,MAAM;CAG1B;AAED,iDAAiD;AACjD,qBAAa,aAAc,SAAQ,UAAU;IAKlC,UAAU,EAAE,MAAM;IAJ3B,GAAG,EAAE,GAAG,CAAA;IACR,SAAS,CAAC,OAAO,uCAA6C;gBAGrD,UAAU,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,GAAG,GAAG;IAS1B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,GAAG,IAAI;IAI5D,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG/B"}
|
package/dist/client.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.ServiceClient = exports.Client = void 0;
|
|
4
4
|
const lexicon_1 = require("@atproto/lexicon");
|
|
5
|
+
const xrpc_client_1 = require("./xrpc-client");
|
|
5
6
|
const util_1 = require("./util");
|
|
6
|
-
|
|
7
|
+
/** @deprecated Use {@link XrpcClient} instead */
|
|
7
8
|
class Client {
|
|
8
9
|
constructor() {
|
|
9
|
-
Object.defineProperty(this, "fetch", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
configurable: true,
|
|
12
|
-
writable: true,
|
|
13
|
-
value: defaultFetchHandler
|
|
14
|
-
});
|
|
15
10
|
Object.defineProperty(this, "lex", {
|
|
16
11
|
enumerable: true,
|
|
17
12
|
configurable: true,
|
|
@@ -19,6 +14,14 @@ class Client {
|
|
|
19
14
|
value: new lexicon_1.Lexicons()
|
|
20
15
|
});
|
|
21
16
|
}
|
|
17
|
+
/** @deprecated */
|
|
18
|
+
get fetch() {
|
|
19
|
+
throw new Error('Client.fetch is no longer supported. Use an XrpcClient instead.');
|
|
20
|
+
}
|
|
21
|
+
/** @deprecated */
|
|
22
|
+
set fetch(_) {
|
|
23
|
+
throw new Error('Client.fetch is no longer supported. Use an XrpcClient instead.');
|
|
24
|
+
}
|
|
22
25
|
// method calls
|
|
23
26
|
//
|
|
24
27
|
async call(serviceUri, methodNsid, params, data, opts) {
|
|
@@ -42,13 +45,18 @@ class Client {
|
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
exports.Client = Client;
|
|
45
|
-
|
|
48
|
+
/** @deprecated Use {@link XrpcClient} instead */
|
|
49
|
+
class ServiceClient extends xrpc_client_1.XrpcClient {
|
|
46
50
|
constructor(baseClient, serviceUri) {
|
|
51
|
+
super(async (input, init) => {
|
|
52
|
+
const headers = (0, util_1.combineHeaders)(init.headers, this.headers);
|
|
53
|
+
return fetch(new URL(input, this.uri), { ...init, headers });
|
|
54
|
+
}, baseClient.lex);
|
|
47
55
|
Object.defineProperty(this, "baseClient", {
|
|
48
56
|
enumerable: true,
|
|
49
57
|
configurable: true,
|
|
50
58
|
writable: true,
|
|
51
|
-
value:
|
|
59
|
+
value: baseClient
|
|
52
60
|
});
|
|
53
61
|
Object.defineProperty(this, "uri", {
|
|
54
62
|
enumerable: true,
|
|
@@ -60,83 +68,16 @@ class ServiceClient {
|
|
|
60
68
|
enumerable: true,
|
|
61
69
|
configurable: true,
|
|
62
70
|
writable: true,
|
|
63
|
-
value:
|
|
71
|
+
value: new Map()
|
|
64
72
|
});
|
|
65
|
-
this.baseClient = baseClient;
|
|
66
73
|
this.uri = typeof serviceUri === 'string' ? new URL(serviceUri) : serviceUri;
|
|
67
74
|
}
|
|
68
75
|
setHeader(key, value) {
|
|
69
|
-
this.headers
|
|
76
|
+
this.headers.set(key.toLowerCase(), value);
|
|
70
77
|
}
|
|
71
78
|
unsetHeader(key) {
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
async call(methodNsid, params, data, opts) {
|
|
75
|
-
const def = this.baseClient.lex.getDefOrThrow(methodNsid);
|
|
76
|
-
if (!def || (def.type !== 'query' && def.type !== 'procedure')) {
|
|
77
|
-
throw new Error(`Invalid lexicon: ${methodNsid}. Must be a query or procedure.`);
|
|
78
|
-
}
|
|
79
|
-
const httpMethod = (0, util_1.getMethodSchemaHTTPMethod)(def);
|
|
80
|
-
const httpUri = (0, util_1.constructMethodCallUri)(methodNsid, def, this.uri, params);
|
|
81
|
-
const httpHeaders = (0, util_1.constructMethodCallHeaders)(def, data, {
|
|
82
|
-
headers: {
|
|
83
|
-
...this.headers,
|
|
84
|
-
...opts?.headers,
|
|
85
|
-
},
|
|
86
|
-
encoding: opts?.encoding,
|
|
87
|
-
});
|
|
88
|
-
const res = await this.baseClient.fetch(httpUri, httpMethod, httpHeaders, data);
|
|
89
|
-
const resCode = (0, util_1.httpResponseCodeToEnum)(res.status);
|
|
90
|
-
if (resCode === types_1.ResponseType.Success) {
|
|
91
|
-
try {
|
|
92
|
-
this.baseClient.lex.assertValidXrpcOutput(methodNsid, res.body);
|
|
93
|
-
}
|
|
94
|
-
catch (e) {
|
|
95
|
-
if (e instanceof lexicon_1.ValidationError) {
|
|
96
|
-
throw new types_1.XRPCInvalidResponseError(methodNsid, e, res.body);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
throw e;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return new types_1.XRPCResponse(res.body, res.headers);
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
if (res.body && isErrorResponseBody(res.body)) {
|
|
106
|
-
throw new types_1.XRPCError(resCode, res.body.error, res.body.message, res.headers);
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
throw new types_1.XRPCError(resCode);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
79
|
+
this.headers.delete(key.toLowerCase());
|
|
112
80
|
}
|
|
113
81
|
}
|
|
114
82
|
exports.ServiceClient = ServiceClient;
|
|
115
|
-
async function defaultFetchHandler(httpUri, httpMethod, httpHeaders, httpReqBody) {
|
|
116
|
-
try {
|
|
117
|
-
// The duplex field is now required for streaming bodies, but not yet reflected
|
|
118
|
-
// anywhere in docs or types. See whatwg/fetch#1438, nodejs/node#46221.
|
|
119
|
-
const headers = (0, util_1.normalizeHeaders)(httpHeaders);
|
|
120
|
-
const reqInit = {
|
|
121
|
-
method: httpMethod,
|
|
122
|
-
headers,
|
|
123
|
-
body: (0, util_1.encodeMethodCallBody)(headers, httpReqBody),
|
|
124
|
-
duplex: 'half',
|
|
125
|
-
};
|
|
126
|
-
const res = await fetch(httpUri, reqInit);
|
|
127
|
-
const resBody = await res.arrayBuffer();
|
|
128
|
-
return {
|
|
129
|
-
status: res.status,
|
|
130
|
-
headers: Object.fromEntries(res.headers.entries()),
|
|
131
|
-
body: (0, util_1.httpResponseBodyParse)(res.headers.get('content-type'), resBody),
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
catch (e) {
|
|
135
|
-
throw new types_1.XRPCError(types_1.ResponseType.Unknown, String(e));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
exports.defaultFetchHandler = defaultFetchHandler;
|
|
139
|
-
function isErrorResponseBody(v) {
|
|
140
|
-
return types_1.errorResponseBody.safeParse(v).success;
|
|
141
|
-
}
|
|
142
83
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,8CAAuD;AAEvD,+CAA0C;AAC1C,iCAAuC;AAEvC,iDAAiD;AACjD,MAAa,MAAM;IAAnB;QAeE;;;;mBAAM,IAAI,kBAAQ,EAAE;WAAA;IAmCtB,CAAC;IAjDC,kBAAkB;IAClB,IAAI,KAAK;QACP,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAA;IACH,CAAC;IAED,kBAAkB;IAClB,IAAI,KAAK,CAAC,CAAQ;QAChB,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAA;IACH,CAAC;IAID,eAAe;IACf,EAAE;IAEF,KAAK,CAAC,IAAI,CACR,UAAwB,EACxB,UAAkB,EAClB,MAAoB,EACpB,IAAsB,EACtB,IAAkB;QAElB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;IACtE,CAAC;IAED,OAAO,CAAC,UAAwB;QAC9B,OAAO,IAAI,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAC5C,CAAC;IAED,UAAU;IACV,IAAI;IAEJ,UAAU,CAAC,GAAe;QACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACnB,CAAC;IAED,WAAW,CAAC,IAAkB;QAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC;CACF;AAlDD,wBAkDC;AAED,iDAAiD;AACjD,MAAa,aAAc,SAAQ,wBAAU;IAI3C,YACS,UAAkB,EACzB,UAAwB;QAExB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC1B,MAAM,OAAO,GAAG,IAAA,qBAAc,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;YAC1D,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;QAC9D,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAA;QANlB;;;;mBAAO,UAAU;WAAQ;QAJ3B;;;;;WAAQ;QACE;;;;mBAAU,IAAI,GAAG,EAAmC;WAAA;QAU5D,IAAI,CAAC,GAAG,GAAG,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAA;IAC9E,CAAC;IAED,SAAS,CAAC,GAAW,EAAE,KAA8B;QACnD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAA;IAC5C,CAAC;IAED,WAAW,CAAC,GAAW;QACrB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAA;IACxC,CAAC;CACF;AAtBD,sCAsBC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Gettable } from './types';
|
|
2
|
+
export type FetchHandler = (this: void,
|
|
3
|
+
/**
|
|
4
|
+
* The URL (pathname + query parameters) to make the request to, without the
|
|
5
|
+
* origin. The origin (protocol, hostname, and port) must be added by this
|
|
6
|
+
* {@link FetchHandler}, typically based on authentication or other factors.
|
|
7
|
+
*/
|
|
8
|
+
url: string, init: RequestInit) => Promise<Response>;
|
|
9
|
+
export type FetchHandlerOptions = BuildFetchHandlerOptions | string | URL;
|
|
10
|
+
export type BuildFetchHandlerOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* The service URL to make requests to. This can be a string, URL, or a
|
|
13
|
+
* function that returns a string or URL. This is useful for dynamic URLs,
|
|
14
|
+
* such as a service URL that changes based on authentication.
|
|
15
|
+
*/
|
|
16
|
+
service: Gettable<string | URL>;
|
|
17
|
+
/**
|
|
18
|
+
* Headers to be added to every request. If a function is provided, it will be
|
|
19
|
+
* called on each request to get the headers. This is useful for dynamic
|
|
20
|
+
* headers, such as authentication tokens that may expire.
|
|
21
|
+
*/
|
|
22
|
+
headers?: {
|
|
23
|
+
[_ in string]?: Gettable<null | string>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Bring your own fetch implementation. Typically useful for testing, logging,
|
|
27
|
+
* mocking, or adding retries, session management, signatures, proof of
|
|
28
|
+
* possession (DPoP), etc. Defaults to the global `fetch` function.
|
|
29
|
+
*/
|
|
30
|
+
fetch?: typeof globalThis.fetch;
|
|
31
|
+
};
|
|
32
|
+
export declare function buildFetchHandler(options: FetchHandlerOptions): FetchHandler;
|
|
33
|
+
//# sourceMappingURL=fetch-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-handler.d.ts","sourceRoot":"","sources":["../src/fetch-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGlC,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,IAAI;AACV;;;;GAIG;AACH,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,KACd,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtB,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,MAAM,GAAG,GAAG,CAAA;AAEzE,MAAM,MAAM,wBAAwB,GAAG;IACrC;;;;OAIG;IACH,OAAO,EAAE,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;IAE/B;;;;OAIG;IACH,OAAO,CAAC,EAAE;SACP,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC;KACxC,CAAA;IAED;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;CAChC,CAAA;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CA0B5E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFetchHandler = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
function buildFetchHandler(options) {
|
|
6
|
+
const { service, headers: defaultHeaders = undefined, fetch = globalThis.fetch, } = typeof options === 'string' || options instanceof URL
|
|
7
|
+
? { service: options }
|
|
8
|
+
: options;
|
|
9
|
+
if (typeof fetch !== 'function') {
|
|
10
|
+
throw new TypeError('XrpcDispatcher requires fetch() to be available in your environment.');
|
|
11
|
+
}
|
|
12
|
+
const defaultHeadersEntries = defaultHeaders != null ? Object.entries(defaultHeaders) : undefined;
|
|
13
|
+
return async function (url, init) {
|
|
14
|
+
const base = typeof service === 'function' ? service() : service;
|
|
15
|
+
const fullUrl = new URL(url, base);
|
|
16
|
+
const headers = (0, util_1.combineHeaders)(init.headers, defaultHeadersEntries);
|
|
17
|
+
return fetch(fullUrl, { ...init, headers });
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
exports.buildFetchHandler = buildFetchHandler;
|
|
21
|
+
//# sourceMappingURL=fetch-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-handler.js","sourceRoot":"","sources":["../src/fetch-handler.ts"],"names":[],"mappings":";;;AACA,iCAAuC;AAwCvC,SAAgB,iBAAiB,CAAC,OAA4B;IAC5D,MAAM,EACJ,OAAO,EACP,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,KAAK,GAAG,UAAU,CAAC,KAAK,GACzB,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,YAAY,GAAG;QACvD,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE;QACtB,CAAC,CAAC,OAAO,CAAA;IAEX,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CACjB,sEAAsE,CACvE,CAAA;IACH,CAAC;IAED,MAAM,qBAAqB,GACzB,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAErE,OAAO,KAAK,WAAW,GAAG,EAAE,IAAI;QAC9B,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QAChE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;QAElC,MAAM,OAAO,GAAG,IAAA,qBAAc,EAAC,IAAI,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAA;QAEnE,OAAO,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;IAC7C,CAAC,CAAA;AACH,CAAC;AA1BD,8CA0BC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
export * from './types';
|
|
2
1
|
export * from './client';
|
|
2
|
+
export * from './fetch-handler';
|
|
3
|
+
export * from './types';
|
|
4
|
+
export * from './util';
|
|
5
|
+
export * from './xrpc-client';
|
|
3
6
|
import { Client } from './client';
|
|
7
|
+
/** @deprecated create a local {@link XrpcClient} instance instead */
|
|
4
8
|
declare const defaultInst: Client;
|
|
5
9
|
export default defaultInst;
|
|
6
10
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,qEAAqE;AACrE,QAAA,MAAM,WAAW,QAAe,CAAA;AAChC,eAAe,WAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -14,9 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./types"), exports);
|
|
18
17
|
__exportStar(require("./client"), exports);
|
|
18
|
+
__exportStar(require("./fetch-handler"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
__exportStar(require("./util"), exports);
|
|
21
|
+
__exportStar(require("./xrpc-client"), exports);
|
|
19
22
|
const client_1 = require("./client");
|
|
23
|
+
/** @deprecated create a local {@link XrpcClient} instance instead */
|
|
20
24
|
const defaultInst = new client_1.Client();
|
|
21
25
|
exports.default = defaultInst;
|
|
22
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAuB;AACvB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAwB;AACxB,kDAA+B;AAC/B,0CAAuB;AACvB,yCAAsB;AACtB,gDAA6B;AAE7B,qCAAiC;AACjC,qEAAqE;AACrE,MAAM,WAAW,GAAG,IAAI,eAAM,EAAE,CAAA;AAChC,kBAAe,WAAW,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { ValidationError } from '@atproto/lexicon';
|
|
3
3
|
export type QueryParams = Record<string, any>;
|
|
4
|
-
export type
|
|
4
|
+
export type HeadersMap = Record<string, string>;
|
|
5
|
+
/** @deprecated not to be confused with the WHATWG Headers constructor */
|
|
6
|
+
export type Headers = HeadersMap;
|
|
7
|
+
export type Gettable<T> = T | (() => T);
|
|
5
8
|
export interface CallOptions {
|
|
6
9
|
encoding?: string;
|
|
7
|
-
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
headers?: HeadersMap;
|
|
8
12
|
}
|
|
9
|
-
export interface FetchHandlerResponse {
|
|
10
|
-
status: number;
|
|
11
|
-
headers: Headers;
|
|
12
|
-
body: ArrayBuffer | undefined;
|
|
13
|
-
}
|
|
14
|
-
export type FetchHandler = (httpUri: string, httpMethod: string, httpHeaders: Headers, httpReqBody: any) => Promise<FetchHandlerResponse>;
|
|
15
13
|
export declare const errorResponseBody: z.ZodObject<{
|
|
16
14
|
error: z.ZodOptional<z.ZodString>;
|
|
17
15
|
message: z.ZodOptional<z.ZodString>;
|
|
@@ -39,7 +37,9 @@ export declare enum ResponseType {
|
|
|
39
37
|
NotEnoughResources = 503,
|
|
40
38
|
UpstreamTimeout = 504
|
|
41
39
|
}
|
|
40
|
+
export declare function httpResponseCodeToEnum(status: number): ResponseType;
|
|
42
41
|
export declare const ResponseTypeNames: {
|
|
42
|
+
1: string;
|
|
43
43
|
2: string;
|
|
44
44
|
200: string;
|
|
45
45
|
400: string;
|
|
@@ -54,7 +54,9 @@ export declare const ResponseTypeNames: {
|
|
|
54
54
|
503: string;
|
|
55
55
|
504: string;
|
|
56
56
|
};
|
|
57
|
+
export declare function httpResponseCodeToName(status: number): string;
|
|
57
58
|
export declare const ResponseTypeStrings: {
|
|
59
|
+
1: string;
|
|
58
60
|
2: string;
|
|
59
61
|
200: string;
|
|
60
62
|
400: string;
|
|
@@ -69,6 +71,7 @@ export declare const ResponseTypeStrings: {
|
|
|
69
71
|
503: string;
|
|
70
72
|
504: string;
|
|
71
73
|
};
|
|
74
|
+
export declare function httpResponseCodeToString(status: number): string;
|
|
72
75
|
export declare class XRPCResponse {
|
|
73
76
|
data: any;
|
|
74
77
|
headers: Headers;
|
|
@@ -76,11 +79,12 @@ export declare class XRPCResponse {
|
|
|
76
79
|
constructor(data: any, headers: Headers);
|
|
77
80
|
}
|
|
78
81
|
export declare class XRPCError extends Error {
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
error: string;
|
|
83
|
+
headers?: HeadersMap | undefined;
|
|
81
84
|
success: boolean;
|
|
82
|
-
|
|
83
|
-
constructor(
|
|
85
|
+
status: ResponseType;
|
|
86
|
+
constructor(statusCode: number, error?: string, message?: string, headers?: HeadersMap | undefined, options?: ErrorOptions);
|
|
87
|
+
static from(cause: unknown, fallbackStatus?: ResponseType): XRPCError;
|
|
84
88
|
}
|
|
85
89
|
export declare class XRPCInvalidResponseError extends XRPCError {
|
|
86
90
|
lexiconNsid: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAElD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAC7C,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAElD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAC7C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE/C,yEAAyE;AACzE,MAAM,MAAM,OAAO,GAAG,UAAU,CAAA;AAEhC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;AAEvC,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,UAAU,CAAA;CACrB;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;EAG5B,CAAA;AACF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEjE,oBAAY,YAAY;IACtB,OAAO,IAAI;IACX,eAAe,IAAI;IACnB,OAAO,MAAM;IACb,cAAc,MAAM;IACpB,YAAY,MAAM;IAClB,SAAS,MAAM;IACf,gBAAgB,MAAM;IACtB,eAAe,MAAM;IACrB,iBAAiB,MAAM;IACvB,mBAAmB,MAAM;IACzB,oBAAoB,MAAM;IAC1B,eAAe,MAAM;IACrB,kBAAkB,MAAM;IACxB,eAAe,MAAM;CACtB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAcnE;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;CAe7B,CAAA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;CAe/B,CAAA;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,qBAAa,YAAY;IAId,IAAI,EAAE,GAAG;IACT,OAAO,EAAE,OAAO;IAJzB,OAAO,UAAO;gBAGL,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,OAAO;CAE1B;AAED,qBAAa,SAAU,SAAQ,KAAK;IAOzB,KAAK,EAAE,MAAM;IAEb,OAAO,CAAC;IARjB,OAAO,UAAQ;IAER,MAAM,EAAE,YAAY,CAAA;gBAGzB,UAAU,EAAE,MAAM,EACX,KAAK,GAAE,MAA2C,EACzD,OAAO,CAAC,EAAE,MAAM,EACT,OAAO,CAAC,wBAAS,EACxB,OAAO,CAAC,EAAE,YAAY;IAaxB,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,YAAY,GAAG,SAAS;CAsBtE;AAED,qBAAa,wBAAyB,SAAQ,SAAS;IAE5C,WAAW,EAAE,MAAM;IACnB,eAAe,EAAE,eAAe;IAChC,YAAY,EAAE,OAAO;gBAFrB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,eAAe,EAChC,YAAY,EAAE,OAAO;CAU/B"}
|