@atproto/lex-client 0.0.5 → 0.0.7
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 +26 -0
- package/dist/agent.d.ts +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +3 -0
- package/dist/agent.js.map +1 -1
- package/dist/client.d.ts +34 -32
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +17 -21
- package/dist/client.js.map +1 -1
- package/dist/{xrpc-error.d.ts → errors.d.ts} +22 -27
- package/dist/errors.d.ts.map +1 -0
- package/dist/{xrpc-error.js → errors.js} +38 -33
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/createRecord.defs.js +5 -7
- package/dist/lexicons/com/atproto/repo/createRecord.defs.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/deleteRecord.defs.js +5 -7
- package/dist/lexicons/com/atproto/repo/deleteRecord.defs.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/getRecord.defs.js +3 -5
- package/dist/lexicons/com/atproto/repo/getRecord.defs.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/listRecords.defs.js +2 -3
- package/dist/lexicons/com/atproto/repo/listRecords.defs.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/putRecord.defs.js +5 -7
- package/dist/lexicons/com/atproto/repo/putRecord.defs.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js +3 -4
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js.map +1 -1
- package/dist/lexicons/index.d.ts +2 -0
- package/dist/lexicons/index.d.ts.map +1 -0
- package/dist/lexicons/index.js +9 -0
- package/dist/lexicons/index.js.map +1 -0
- package/dist/response.d.ts +38 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/{xrpc-response.js → response.js} +24 -20
- package/dist/response.js.map +1 -0
- package/dist/types.d.ts +0 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -4
- package/dist/types.js.map +1 -1
- package/dist/xrpc.d.ts +23 -17
- package/dist/xrpc.d.ts.map +1 -1
- package/dist/xrpc.js +15 -17
- package/dist/xrpc.js.map +1 -1
- package/package.json +10 -10
- package/src/agent.ts +6 -2
- package/src/client.ts +72 -66
- package/src/{xrpc-error.ts → errors.ts} +59 -48
- package/src/index.ts +2 -0
- package/src/lexicons/com/atproto/repo/createRecord.defs.ts +22 -28
- package/src/lexicons/com/atproto/repo/deleteRecord.defs.ts +18 -24
- package/src/lexicons/com/atproto/repo/getRecord.defs.ts +5 -10
- package/src/lexicons/com/atproto/repo/listRecords.defs.ts +6 -9
- package/src/lexicons/com/atproto/repo/putRecord.defs.ts +23 -29
- package/src/lexicons/com/atproto/repo/uploadBlob.defs.ts +4 -7
- package/src/lexicons/index.ts +5 -0
- package/src/{xrpc-response.ts → response.ts} +45 -30
- package/src/types.ts +0 -6
- package/src/xrpc.ts +56 -57
- package/tsconfig.tests.json +4 -7
- package/dist/lexicons.d.ts +0 -2
- package/dist/lexicons.d.ts.map +0 -1
- package/dist/lexicons.js +0 -6
- package/dist/lexicons.js.map +0 -1
- package/dist/xrpc-error.d.ts.map +0 -1
- package/dist/xrpc-error.js.map +0 -1
- package/dist/xrpc-response.d.ts +0 -35
- package/dist/xrpc-response.d.ts.map +0 -1
- package/dist/xrpc-response.js.map +0 -1
- package/src/lexicons.ts +0 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.com = void 0;
|
|
7
|
+
const tslib_1 = require("tslib");
|
|
8
|
+
exports.com = tslib_1.__importStar(require("./com.js"));
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lexicons/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,wDAA+B","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nexport * as com from './com.js'\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { InferMethodOutputBody, InferMethodOutputEncoding, Procedure, Query, ResultSuccess } from '@atproto/lex-schema';
|
|
2
|
+
import { Payload } from './util.js';
|
|
3
|
+
export type LexRpcResponseBody<M extends Procedure | Query> = InferMethodOutputBody<M, Uint8Array>;
|
|
4
|
+
export type LexRpcResponsePayload<M extends Procedure | Query> = InferMethodOutputEncoding<M> extends infer E extends string ? Payload<LexRpcResponseBody<M>, E> : null;
|
|
5
|
+
/**
|
|
6
|
+
* Small container for XRPC response data.
|
|
7
|
+
*
|
|
8
|
+
* @implements {ResultSuccess<LexRpcResponse<M>>} for convenience in result handling contexts.
|
|
9
|
+
*/
|
|
10
|
+
export declare class LexRpcResponse<const M extends Procedure | Query> implements ResultSuccess<LexRpcResponse<M>> {
|
|
11
|
+
readonly method: M;
|
|
12
|
+
readonly status: number;
|
|
13
|
+
readonly headers: Headers;
|
|
14
|
+
readonly payload: LexRpcResponsePayload<M>;
|
|
15
|
+
/** @see {@link ResultSuccess.success} */
|
|
16
|
+
readonly success: true;
|
|
17
|
+
/** @see {@link ResultSuccess.value} */
|
|
18
|
+
get value(): this;
|
|
19
|
+
constructor(method: M, status: number, headers: Headers, payload: LexRpcResponsePayload<M>);
|
|
20
|
+
/**
|
|
21
|
+
* Whether the response payload was parsed as {@link LexValue} (`true`) or is
|
|
22
|
+
* in binary form {@link Uint8Array} (`false`).
|
|
23
|
+
*/
|
|
24
|
+
get isParsed(): boolean;
|
|
25
|
+
get encoding(): InferMethodOutputEncoding<M>;
|
|
26
|
+
get body(): LexRpcResponseBody<M>;
|
|
27
|
+
/**
|
|
28
|
+
* @throws {LexRpcResponseError} in case of (valid) XRPC error responses. Use
|
|
29
|
+
* {@link LexRpcResponseError.matchesSchema} to narrow the error type based on
|
|
30
|
+
* the method's declared error schema.
|
|
31
|
+
* @throws {LexRpcUpstreamError} when the response is not a valid XRPC
|
|
32
|
+
* response, or if the response does not conform to the method's schema.
|
|
33
|
+
*/
|
|
34
|
+
static fromFetchResponse<const M extends Procedure | Query>(method: M, response: Response, options?: {
|
|
35
|
+
validateResponse?: boolean;
|
|
36
|
+
}): Promise<LexRpcResponse<M>>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=response.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,EACT,KAAK,EACL,aAAa,EACd,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IACxD,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAEtC,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IAC3D,yBAAyB,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,GACvD,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GACjC,IAAI,CAAA;AAEV;;;;GAIG;AACH,qBAAa,cAAc,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,CAC3D,YAAW,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAWzC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAZ5C,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAG,IAAI,CAAS;IAEhC,uCAAuC;IACvC,IAAI,KAAK,IAAI,IAAI,CAEhB;gBAGU,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAG5C;;;OAGG;IACH,IAAI,QAAQ,YAEX;IAED,IAAI,QAAQ,IACuB,yBAAyB,CAAC,CAAC,CAAC,CAC9D;IAED,IAAI,IAAI,IACuB,kBAAkB,CAAC,CAAC,CAAC,CACnD;IAED;;;;;;OAMG;WACU,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,EAC9D,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,GACvC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;CA4F9B"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.LexRpcResponse = void 0;
|
|
4
4
|
const lex_json_1 = require("@atproto/lex-json");
|
|
5
|
-
const
|
|
5
|
+
const errors_js_1 = require("./errors.js");
|
|
6
6
|
/**
|
|
7
7
|
* Small container for XRPC response data.
|
|
8
8
|
*
|
|
9
|
-
* @implements {ResultSuccess<
|
|
9
|
+
* @implements {ResultSuccess<LexRpcResponse<M>>} for convenience in result handling contexts.
|
|
10
10
|
*/
|
|
11
|
-
class
|
|
11
|
+
class LexRpcResponse {
|
|
12
12
|
method;
|
|
13
13
|
status;
|
|
14
14
|
headers;
|
|
@@ -39,8 +39,11 @@ class XrpcResponse {
|
|
|
39
39
|
return this.payload?.body;
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
-
* @throws {
|
|
43
|
-
* to the
|
|
42
|
+
* @throws {LexRpcResponseError} in case of (valid) XRPC error responses. Use
|
|
43
|
+
* {@link LexRpcResponseError.matchesSchema} to narrow the error type based on
|
|
44
|
+
* the method's declared error schema.
|
|
45
|
+
* @throws {LexRpcUpstreamError} when the response is not a valid XRPC
|
|
46
|
+
* response, or if the response does not conform to the method's schema.
|
|
44
47
|
*/
|
|
45
48
|
static async fromFetchResponse(method, response, options) {
|
|
46
49
|
// @NOTE The body MUST either be read or canceled to avoid resource leaks.
|
|
@@ -50,14 +53,15 @@ class XrpcResponse {
|
|
|
50
53
|
if (response.status < 200 || response.status >= 300) {
|
|
51
54
|
// Always parse json for error responses
|
|
52
55
|
const payload = await readPayload(response, { parse: true });
|
|
53
|
-
if (response.status >= 400 && (0,
|
|
54
|
-
throw new
|
|
56
|
+
if (response.status >= 400 && (0, errors_js_1.isLexRpcErrorPayload)(payload)) {
|
|
57
|
+
throw new errors_js_1.LexRpcResponseError(method, response.status, response.headers, payload);
|
|
55
58
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if (response.status >= 500) {
|
|
60
|
+
throw new errors_js_1.LexRpcUpstreamError('UpstreamFailure', `Upstream server encountered an error`, response, payload);
|
|
61
|
+
}
|
|
62
|
+
throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', response.status >= 400
|
|
63
|
+
? `Upstream server returned an invalid response payload`
|
|
64
|
+
: `Upstream server returned an invalid status code`, response, payload);
|
|
61
65
|
}
|
|
62
66
|
// Only parse json if the schema expects it
|
|
63
67
|
const payload = await readPayload(response, {
|
|
@@ -67,13 +71,13 @@ class XrpcResponse {
|
|
|
67
71
|
if (method.output.encoding == null) {
|
|
68
72
|
// Schema expects no payload
|
|
69
73
|
if (payload) {
|
|
70
|
-
throw new
|
|
74
|
+
throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', `Expected response with no body, got ${payload.encoding}`, response, payload);
|
|
71
75
|
}
|
|
72
76
|
}
|
|
73
77
|
else {
|
|
74
78
|
// Schema expects a payload
|
|
75
79
|
if (!payload || !method.output.matchesEncoding(payload.encoding)) {
|
|
76
|
-
throw new
|
|
80
|
+
throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', payload
|
|
77
81
|
? `Expected ${method.output.encoding} response, got ${payload.encoding}`
|
|
78
82
|
: `Expected non-empty response with content-type ${method.output.encoding}`, response, payload);
|
|
79
83
|
}
|
|
@@ -83,14 +87,14 @@ class XrpcResponse {
|
|
|
83
87
|
allowTransform: false,
|
|
84
88
|
});
|
|
85
89
|
if (!result.success) {
|
|
86
|
-
throw new
|
|
90
|
+
throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', `Response validation failed: ${result.reason.message}`, response, payload, { cause: result.reason });
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
|
-
return new
|
|
94
|
+
return new LexRpcResponse(method, response.status, response.headers, payload);
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
|
-
exports.
|
|
97
|
+
exports.LexRpcResponse = LexRpcResponse;
|
|
94
98
|
function shouldParse(method) {
|
|
95
99
|
return method.output.encoding === 'application/json';
|
|
96
100
|
}
|
|
@@ -132,9 +136,9 @@ async function readPayload(response, options) {
|
|
|
132
136
|
return { encoding, body: (0, lex_json_1.lexParse)(text) };
|
|
133
137
|
}
|
|
134
138
|
catch (cause) {
|
|
135
|
-
throw new
|
|
139
|
+
throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', 'Invalid JSON response body', response, null, { cause });
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
return { encoding, body: new Uint8Array(await response.arrayBuffer()) };
|
|
139
143
|
}
|
|
140
|
-
//# sourceMappingURL=
|
|
144
|
+
//# sourceMappingURL=response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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","sourcesContent":["import { lexParse } from '@atproto/lex-json'\nimport {\n InferMethodOutputBody,\n InferMethodOutputEncoding,\n Procedure,\n Query,\n ResultSuccess,\n} from '@atproto/lex-schema'\nimport {\n LexRpcResponseError,\n LexRpcUpstreamError,\n isLexRpcErrorPayload,\n} from './errors.js'\nimport { Payload } from './util.js'\n\nexport type LexRpcResponseBody<M extends Procedure | Query> =\n InferMethodOutputBody<M, Uint8Array>\n\nexport type LexRpcResponsePayload<M extends Procedure | Query> =\n InferMethodOutputEncoding<M> extends infer E extends string\n ? Payload<LexRpcResponseBody<M>, E>\n : null\n\n/**\n * Small container for XRPC response data.\n *\n * @implements {ResultSuccess<LexRpcResponse<M>>} for convenience in result handling contexts.\n */\nexport class LexRpcResponse<const M extends Procedure | Query>\n implements ResultSuccess<LexRpcResponse<M>>\n{\n /** @see {@link ResultSuccess.success} */\n readonly success = true as const\n\n /** @see {@link ResultSuccess.value} */\n get value(): this {\n return this\n }\n\n constructor(\n readonly method: M,\n readonly status: number,\n readonly headers: Headers,\n readonly payload: LexRpcResponsePayload<M>,\n ) {}\n\n /**\n * Whether the response payload was parsed as {@link LexValue} (`true`) or is\n * in binary form {@link Uint8Array} (`false`).\n */\n get isParsed() {\n return this.encoding === 'application/json' && shouldParse(this.method)\n }\n\n get encoding() {\n return this.payload?.encoding as InferMethodOutputEncoding<M>\n }\n\n get body() {\n return this.payload?.body as LexRpcResponseBody<M>\n }\n\n /**\n * @throws {LexRpcResponseError} in case of (valid) XRPC error responses. Use\n * {@link LexRpcResponseError.matchesSchema} to narrow the error type based on\n * the method's declared error schema.\n * @throws {LexRpcUpstreamError} when the response is not a valid XRPC\n * response, or if the response does not conform to the method's schema.\n */\n static async fromFetchResponse<const M extends Procedure | Query>(\n method: M,\n response: Response,\n options?: { validateResponse?: boolean },\n ): Promise<LexRpcResponse<M>> {\n // @NOTE The body MUST either be read or canceled to avoid resource leaks.\n // Since nothing should cause an exception before \"readPayload\" is\n // called, we can safely not use a try/finally here.\n\n // @NOTE redirect is set to 'follow', so we shouldn't get 3xx responses here\n if (response.status < 200 || response.status >= 300) {\n // Always parse json for error responses\n const payload = await readPayload(response, { parse: true })\n\n if (response.status >= 400 && isLexRpcErrorPayload(payload)) {\n throw new LexRpcResponseError(\n method,\n response.status,\n response.headers,\n payload,\n )\n }\n\n if (response.status >= 500) {\n throw new LexRpcUpstreamError(\n 'UpstreamFailure',\n `Upstream server encountered an error`,\n response,\n payload,\n )\n }\n\n throw new LexRpcUpstreamError(\n 'InvalidResponse',\n response.status >= 400\n ? `Upstream server returned an invalid response payload`\n : `Upstream server returned an invalid status code`,\n response,\n payload,\n )\n }\n\n // Only parse json if the schema expects it\n const payload = await readPayload(response, {\n parse: shouldParse(method),\n })\n\n // Response is successful (2xx). Validate payload (data and encoding) against schema.\n if (method.output.encoding == null) {\n // Schema expects no payload\n if (payload) {\n throw new LexRpcUpstreamError(\n 'InvalidResponse',\n `Expected response with no body, got ${payload.encoding}`,\n response,\n payload,\n )\n }\n } else {\n // Schema expects a payload\n if (!payload || !method.output.matchesEncoding(payload.encoding)) {\n throw new LexRpcUpstreamError(\n 'InvalidResponse',\n payload\n ? `Expected ${method.output.encoding} response, got ${payload.encoding}`\n : `Expected non-empty response with content-type ${method.output.encoding}`,\n response,\n payload,\n )\n }\n\n // Assert valid response body.\n if (method.output.schema && options?.validateResponse !== false) {\n const result = method.output.schema.safeParse(payload.body, {\n allowTransform: false,\n })\n\n if (!result.success) {\n throw new LexRpcUpstreamError(\n 'InvalidResponse',\n `Response validation failed: ${result.reason.message}`,\n response,\n payload,\n { cause: result.reason },\n )\n }\n }\n }\n\n return new LexRpcResponse<M>(\n method,\n response.status,\n response.headers,\n payload as LexRpcResponsePayload<M>,\n )\n }\n}\n\nfunction shouldParse(method: Procedure | Query) {\n return method.output.encoding === 'application/json'\n}\n\n/**\n * @note this function always consumes the response body\n */\nasync function readPayload(\n response: Response,\n options?: { parse?: boolean },\n): Promise<Payload | null> {\n // @TODO Should we limit the maximum response size here (this could also be\n // done by the FetchHandler)?\n\n const encoding = response.headers\n .get('content-type')\n ?.split(';')[0]\n .trim()\n .toLowerCase()\n\n // Response content-type is undefined\n if (!encoding) {\n // If the body is empty, return null (= no payload)\n const body = await response.arrayBuffer()\n if (body.byteLength === 0) return null\n\n // If we got data despite no content-type, treat it as binary\n return {\n encoding: 'application/octet-stream',\n body: new Uint8Array(body),\n }\n }\n\n if (options?.parse && encoding === 'application/json') {\n // @NOTE It might be worth returning the raw bytes here (Uint8Array) and\n // perform the lex parsing using cborg/json, allowing to do\n // bytes->LexValue in one step instead of bytes->text->JSON->LexValue.\n // This would require adding encode/decode utilities to lex-json (similar\n // to @ipld/dag-json)\n const text = await response.text()\n\n try {\n // @NOTE Using `lexParse(text)` (instead of `jsonToLex(json)`) here as\n // using a reviver function during JSON.parse should be faster than\n // parsing to JSON then converting to Lex (?)\n\n // @TODO verify statement above\n return { encoding, body: lexParse(text) }\n } catch (cause) {\n throw new LexRpcUpstreamError(\n 'InvalidResponse',\n 'Invalid JSON response body',\n response,\n null,\n { cause },\n )\n }\n }\n\n return { encoding, body: new Uint8Array(await response.arrayBuffer()) }\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -28,8 +28,4 @@ export type CallOptions = {
|
|
|
28
28
|
validateResponse?: boolean;
|
|
29
29
|
};
|
|
30
30
|
export type BinaryBodyInit = Uint8Array | ArrayBuffer | Blob | ReadableStream<Uint8Array> | AsyncIterable<Uint8Array> | string;
|
|
31
|
-
export type Namespace<T> = T | {
|
|
32
|
-
main: T;
|
|
33
|
-
};
|
|
34
|
-
export declare function getMain<T extends object>(ns: Namespace<T>): T;
|
|
35
31
|
//# sourceMappingURL=types.d.ts.map
|
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,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAE9D,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,CAAA;AAExC,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,aAAa,CAAA;AACpE,MAAM,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,oBAAoB,EAAE,CAAA;AAE5D,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IAEzB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,WAAW,GACX,IAAI,GACJ,cAAc,CAAC,UAAU,CAAC,GAC1B,aAAa,CAAC,UAAU,CAAC,GACzB,MAAM,CAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAE9D,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,CAAA;AAExC,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,GAAG,aAAa,CAAA;AACpE,MAAM,MAAM,OAAO,GAAG,GAAG,SAAS,IAAI,oBAAoB,EAAE,CAAA;AAE5D,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IAEzB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,cAAc,GACtB,UAAU,GACV,WAAW,GACX,IAAI,GACJ,cAAc,CAAC,UAAU,CAAC,GAC1B,aAAa,CAAC,UAAU,CAAC,GACzB,MAAM,CAAA"}
|
package/dist/types.js
CHANGED
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { DidString, UnknownString } from '@atproto/lex-schema'\n\nexport type { DidString, UnknownString }\n\nexport type DidServiceIdentifier = 'atproto_labeler' | UnknownString\nexport type Service = `${DidString}#${DidServiceIdentifier}`\n\nexport type CallOptions = {\n labelers?: Iterable<DidString>\n signal?: AbortSignal\n headers?: HeadersInit\n service?: Service\n\n /**\n * Whether to validate the request against the method's input schema. Enabling\n * this can help catch errors early but may have a performance cost. This\n * would typically only be set to `true` in development or debugging\n * scenarios.\n *\n * @default false\n */\n validateRequest?: boolean\n\n /**\n * Whether to validate the response against the method's output schema.\n * Disabling this can improve performance but may lead to runtime errors if\n * the response does not conform to the expected schema. Only set this to\n * `false` if you are certain that the upstream service will always return\n * valid responses.\n *\n * @default true\n */\n validateResponse?: boolean\n}\n\nexport type BinaryBodyInit =\n | Uint8Array\n | ArrayBuffer\n | Blob\n | ReadableStream<Uint8Array>\n | AsyncIterable<Uint8Array>\n | string\n"]}
|
package/dist/xrpc.d.ts
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { InferMethodInput, InferMethodParams, Params, Procedure, Query, Restricted } from '@atproto/lex-schema';
|
|
1
|
+
import { InferMethodInput, InferMethodParams, Main, Params, Procedure, Query, Restricted } from '@atproto/lex-schema';
|
|
2
2
|
import { Agent } from './agent.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
export * from './xrpc-response.js';
|
|
8
|
-
type XrpcParamsOptions<P extends Params> = NonNullable<unknown> extends P ? {
|
|
3
|
+
import { LexRpcResponseError, LexRpcUnexpectedError, LexRpcUpstreamError } from './errors.js';
|
|
4
|
+
import { LexRpcResponse } from './response.js';
|
|
5
|
+
import { BinaryBodyInit, CallOptions } from './types.js';
|
|
6
|
+
type LexRpcParamsOptions<P extends Params> = NonNullable<unknown> extends P ? {
|
|
9
7
|
params?: P;
|
|
10
8
|
} : {
|
|
11
9
|
params: P;
|
|
12
10
|
};
|
|
13
|
-
type
|
|
14
|
-
type
|
|
11
|
+
type LexRpcRequestPayload<M extends Procedure | Query> = InferMethodInput<M, BinaryBodyInit>;
|
|
12
|
+
type LexRpcInputOptions<In> = In extends {
|
|
15
13
|
body: infer B;
|
|
16
14
|
encoding: infer E;
|
|
17
15
|
} ? {
|
|
@@ -21,14 +19,22 @@ type XrpcInputOptions<In> = In extends {
|
|
|
21
19
|
body?: undefined;
|
|
22
20
|
encoding?: undefined;
|
|
23
21
|
};
|
|
24
|
-
export type
|
|
25
|
-
export type
|
|
26
|
-
export type
|
|
22
|
+
export type LexRpcOptions<M extends Procedure | Query = Procedure | Query> = CallOptions & LexRpcInputOptions<LexRpcRequestPayload<M>> & LexRpcParamsOptions<InferMethodParams<M>>;
|
|
23
|
+
export type LexRpcFailure<M extends Procedure | Query> = LexRpcResponseError<M> | LexRpcUpstreamError | LexRpcUnexpectedError;
|
|
24
|
+
export type LexRpcResult<M extends Procedure | Query> = LexRpcResponse<M> | LexRpcFailure<M>;
|
|
27
25
|
/**
|
|
28
|
-
* @
|
|
26
|
+
* Utility method to type cast the error thrown by {@link xrpc} to an
|
|
27
|
+
* {@link LexRpcFailure} matching the provided method. Only use this function
|
|
28
|
+
* inside a catch block right after calling {@link xrpc}, and use the same
|
|
29
|
+
* method type parameter as used in the {@link xrpc} call.
|
|
29
30
|
*/
|
|
30
|
-
export declare function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
export declare function asLexRpcFailure<M extends Procedure | Query = Procedure | Query>(err: unknown): LexRpcFailure<M>;
|
|
32
|
+
/**
|
|
33
|
+
* @throws LexRpcFailure<M>
|
|
34
|
+
*/
|
|
35
|
+
export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends LexRpcOptions<M> ? Main<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<LexRpcResponse<M>>;
|
|
36
|
+
export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: LexRpcOptions<M>): Promise<LexRpcResponse<M>>;
|
|
37
|
+
export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends LexRpcOptions<M> ? Main<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<LexRpcResult<M>>;
|
|
38
|
+
export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: LexRpcOptions<M>): Promise<LexRpcResult<M>>;
|
|
39
|
+
export {};
|
|
34
40
|
//# sourceMappingURL=xrpc.d.ts.map
|
package/dist/xrpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xrpc.d.ts","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,MAAM,EAGN,SAAS,EACT,KAAK,EACL,UAAU,
|
|
1
|
+
{"version":3,"file":"xrpc.d.ts","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,IAAI,EACJ,MAAM,EAGN,SAAS,EACT,KAAK,EACL,UAAU,EAGX,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAUxD,KAAK,mBAAmB,CAAC,CAAC,SAAS,MAAM,IACvC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,CAAC,CAAA;CAAE,CAAA;AAEjE,KAAK,oBAAoB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IAAI,gBAAgB,CACvE,CAAC,EACD,cAAc,CACf,CAAA;AAED,KAAK,kBAAkB,CAAC,EAAE,IAAI,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;CAAE,GAEzE;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,CAAA;CAAE,GACzB;IAAE,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,CAAA;AAE9C,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,IACvE,WAAW,GACT,kBAAkB,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,GAC3C,mBAAmB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;AAE7C,MAAM,MAAM,aAAa,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IAEjD,mBAAmB,CAAC,CAAC,CAAC,GAEtB,mBAAmB,GAEnB,qBAAqB,CAAA;AAEzB,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IAChD,cAAc,CAAC,CAAC,CAAC,GACjB,aAAa,CAAC,CAAC,CAAC,CAAA;AAEpB;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,EAC/C,GAAG,EAAE,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,CAIhC;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,GAAG,SAAS,EAC1D,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,GAC7C,IAAI,CAAC,CAAC,CAAC,GACP,UAAU,CAAC,iDAAiD,CAAC,GAChE,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;AAC7B,wBAAsB,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,GAAG,SAAS,EAC1D,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,EACX,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;AAa7B,wBAAsB,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,GAAG,SAAS,EAC9D,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,aAAa,CAAC,CAAC,CAAC,GAC7C,IAAI,CAAC,CAAC,CAAC,GACP,UAAU,CAAC,iDAAiD,CAAC,GAChE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA;AAC3B,wBAAsB,QAAQ,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,GAAG,SAAS,EAC9D,KAAK,EAAE,KAAK,EACZ,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,EACX,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAA"}
|
package/dist/xrpc.js
CHANGED
|
@@ -1,47 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.asLexRpcFailure = asLexRpcFailure;
|
|
3
4
|
exports.xrpc = xrpc;
|
|
4
5
|
exports.xrpcSafe = xrpcSafe;
|
|
5
|
-
const tslib_1 = require("tslib");
|
|
6
6
|
const lex_data_1 = require("@atproto/lex-data");
|
|
7
7
|
const lex_json_1 = require("@atproto/lex-json");
|
|
8
|
-
const
|
|
8
|
+
const lex_schema_1 = require("@atproto/lex-schema");
|
|
9
|
+
const errors_js_1 = require("./errors.js");
|
|
10
|
+
const response_js_1 = require("./response.js");
|
|
9
11
|
const util_js_1 = require("./util.js");
|
|
10
|
-
const xrpc_error_js_1 = require("./xrpc-error.js");
|
|
11
|
-
const xrpc_response_js_1 = require("./xrpc-response.js");
|
|
12
|
-
tslib_1.__exportStar(require("./xrpc-error.js"), exports);
|
|
13
|
-
tslib_1.__exportStar(require("./xrpc-response.js"), exports);
|
|
14
12
|
/**
|
|
15
13
|
* Utility method to type cast the error thrown by {@link xrpc} to an
|
|
16
|
-
* {@link
|
|
14
|
+
* {@link LexRpcFailure} matching the provided method. Only use this function
|
|
17
15
|
* inside a catch block right after calling {@link xrpc}, and use the same
|
|
18
16
|
* method type parameter as used in the {@link xrpc} call.
|
|
19
17
|
*/
|
|
20
|
-
function
|
|
21
|
-
if (err instanceof
|
|
18
|
+
function asLexRpcFailure(err) {
|
|
19
|
+
if (err instanceof errors_js_1.LexRpcResponseError)
|
|
22
20
|
return err;
|
|
23
|
-
if (err instanceof
|
|
21
|
+
if (err instanceof errors_js_1.LexRpcUpstreamError)
|
|
24
22
|
return err;
|
|
25
|
-
return
|
|
23
|
+
return errors_js_1.LexRpcUnexpectedError.from(err);
|
|
26
24
|
}
|
|
27
25
|
async function xrpc(agent, ns, options = {}) {
|
|
28
26
|
try {
|
|
29
|
-
return await
|
|
27
|
+
return await lexRpcRequest(agent, ns, options);
|
|
30
28
|
}
|
|
31
29
|
catch (err) {
|
|
32
|
-
throw
|
|
30
|
+
throw asLexRpcFailure(err);
|
|
33
31
|
}
|
|
34
32
|
}
|
|
35
33
|
async function xrpcSafe(agent, ns, options = {}) {
|
|
36
|
-
return
|
|
34
|
+
return lexRpcRequest(agent, ns, options).catch((asLexRpcFailure));
|
|
37
35
|
}
|
|
38
|
-
async function
|
|
39
|
-
const method = (0,
|
|
36
|
+
async function lexRpcRequest(agent, ns, options = {}) {
|
|
37
|
+
const method = (0, lex_schema_1.getMain)(ns);
|
|
40
38
|
options.signal?.throwIfAborted();
|
|
41
39
|
const url = xrpcRequestUrl(method, options);
|
|
42
40
|
const request = xrpcRequestInit(method, options);
|
|
43
41
|
const response = await agent.fetchHandler(url, request);
|
|
44
|
-
return
|
|
42
|
+
return response_js_1.LexRpcResponse.fromFetchResponse(method, response, options);
|
|
45
43
|
}
|
|
46
44
|
function xrpcRequestUrl(method, options) {
|
|
47
45
|
const path = `/xrpc/${method.nsid}`;
|
package/dist/xrpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xrpc.js","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexValue, isLexScalar, isPlainObject } from '@atproto/lex-data'\nimport { lexStringify } from '@atproto/lex-json'\nimport {\n InferMethodInput,\n InferMethodParams,\n Params,\n ParamsSchema,\n Payload as LexPayload,\n Procedure,\n Query,\n Restricted,\n Subscription,\n} from '@atproto/lex-schema'\nimport { Agent } from './agent.js'\nimport { BinaryBodyInit, CallOptions, Namespace, getMain } from './types.js'\nimport {\n Payload,\n buildAtprotoHeaders,\n isAsyncIterable,\n isBlobLike,\n toReadableStream,\n} from './util.js'\nimport {\n XrpcInvalidResponseError,\n XrpcResponseError,\n XrpcUnexpectedError,\n} from './xrpc-error.js'\nimport { XrpcResponse } from './xrpc-response.js'\n\nexport * from './xrpc-error.js'\nexport * from './xrpc-response.js'\n\n// If all params are optional, allow omitting the params object\ntype XrpcParamsOptions<P extends Params> =\n NonNullable<unknown> extends P ? { params?: P } : { params: P }\n\ntype XrpcRequestPayload<M extends Procedure | Query> = InferMethodInput<\n M,\n BinaryBodyInit\n>\n\ntype XrpcInputOptions<In> = In extends { body: infer B; encoding: infer E }\n ? // encoding will be inferred from the schema at runtime if not provided\n { body: B; encoding?: E }\n : { body?: undefined; encoding?: undefined }\n\nexport type XrpcOptions<M extends Procedure | Query = Procedure | Query> =\n CallOptions &\n XrpcInputOptions<XrpcRequestPayload<M>> &\n XrpcParamsOptions<InferMethodParams<M>>\n\nexport type XrpcFailure<M extends Procedure | Query> =\n // The server returned a valid XRPC error response\n | XrpcResponseError<M>\n // The response was not a valid XRPC response, or it does not match the schema\n | XrpcInvalidResponseError\n // Something went wrong (network error, etc.)\n | XrpcUnexpectedError\n\nexport type XrpcResult<M extends Procedure | Query> =\n | XrpcResponse<M>\n | XrpcFailure<M>\n\n/**\n * Utility method to type cast the error thrown by {@link xrpc} to an\n * {@link XrpcFailure} matching the provided method. Only use this function\n * inside a catch block right after calling {@link xrpc}, and use the same\n * method type parameter as used in the {@link xrpc} call.\n */\nfunction asXrpcFailure<M extends Procedure | Query>(\n err: unknown,\n): XrpcFailure<M> {\n if (err instanceof XrpcResponseError) return err\n if (err instanceof XrpcInvalidResponseError) return err\n return XrpcUnexpectedError.from(err)\n}\n\n/**\n * @throws XrpcFailure<M>\n */\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: NonNullable<unknown> extends XrpcOptions<M>\n ? Namespace<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: Namespace<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: Namespace<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResponse<M>> {\n try {\n return await xrpcRequest<M>(agent, ns, options)\n } catch (err) {\n throw asXrpcFailure<M>(err)\n }\n}\n\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: NonNullable<unknown> extends XrpcOptions<M>\n ? Namespace<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: Namespace<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: Namespace<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResult<M>> {\n return xrpcRequest<M>(agent, ns, options).catch(asXrpcFailure<M>)\n}\n\nasync function xrpcRequest<const M extends Query | Procedure>(\n agent: Agent,\n ns: Namespace<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResponse<M>> {\n const method = getMain(ns)\n options.signal?.throwIfAborted()\n const url = xrpcRequestUrl(method, options)\n const request = xrpcRequestInit(method, options)\n const response = await agent.fetchHandler(url, request)\n return XrpcResponse.fromFetchResponse<M>(method, response, options)\n}\n\nfunction xrpcRequestUrl<M extends Procedure | Query | Subscription>(\n method: M,\n options: CallOptions & { params?: Params },\n) {\n const path = `/xrpc/${method.nsid}`\n\n const queryString = options.params\n ? xrpcRequestParams(method.parameters, options.params, options)\n : undefined\n\n return queryString ? `${path}?${queryString}` : path\n}\n\nfunction xrpcRequestParams(\n schema: ParamsSchema | undefined,\n params: Params | undefined,\n options: CallOptions,\n): undefined | string {\n const urlSearchParams = schema?.toURLSearchParams(\n options.validateRequest ? schema.parse(params) : (params as any),\n )\n return urlSearchParams?.size ? urlSearchParams.toString() : undefined\n}\n\nfunction xrpcRequestInit<T extends Procedure | Query>(\n schema: T,\n options: CallOptions & {\n body?: LexValue | BinaryBodyInit\n encoding?: string\n },\n): RequestInit & { duplex?: 'half' } {\n const headers = buildAtprotoHeaders(options)\n\n // Tell the server what type of response we're expecting\n if (schema.output.encoding) {\n headers.set('accept', schema.output.encoding)\n }\n\n // Caller should not set content-type header\n if (headers.has('content-type')) {\n const contentType = headers.get('content-type')\n throw new TypeError(`Unexpected content-type header (${contentType})`)\n }\n\n // Requests with body\n if ('input' in schema) {\n const encodingHint = options.encoding\n const input = xrpcProcedureInput(schema, options, encodingHint)\n\n if (input) {\n headers.set('content-type', input.encoding)\n } else if (encodingHint != null) {\n throw new TypeError(`Unexpected encoding hint (${encodingHint})`)\n }\n\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'POST',\n headers,\n body: input?.body,\n }\n }\n\n // Requests without body\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'GET',\n headers,\n }\n}\n\nfunction xrpcProcedureInput(\n method: Procedure,\n options: CallOptions & { body?: LexValue | BinaryBodyInit },\n encodingHint?: string,\n): null | Payload<BodyInit> {\n const { input } = method\n const { body } = options\n\n if (options.validateRequest) {\n input.schema?.check(body)\n }\n\n // Special handling for endpoints expecting application/json input\n if (input.encoding === 'application/json') {\n // @NOTE **NOT** using isLexValue here to avoid deep checks in order to\n // distinguish between LexValue and BinaryBodyInit.\n if (!isLexScalar(body) && !isPlainObject(body) && !Array.isArray(body)) {\n throw new TypeError(`Expected LexValue body, got ${typeof body}`)\n }\n\n return buildPayload(input, lexStringify(body), encodingHint)\n }\n\n // Other encodings will be sent unaltered (ie. as binary data)\n switch (typeof body) {\n case 'undefined':\n case 'string':\n return buildPayload(input, body, encodingHint)\n case 'object': {\n if (body === null) break\n if (\n ArrayBuffer.isView(body) ||\n body instanceof ArrayBuffer ||\n body instanceof ReadableStream\n ) {\n return buildPayload(input, body, encodingHint)\n } else if (isAsyncIterable(body)) {\n return buildPayload(input, toReadableStream(body), encodingHint)\n } else if (isBlobLike(body)) {\n return buildPayload(input, body, encodingHint || body.type)\n }\n }\n }\n\n throw new TypeError(\n `Invalid ${typeof body} body for ${input.encoding} encoding`,\n )\n}\n\nfunction buildPayload(\n schema: LexPayload,\n body: undefined | BodyInit,\n encodingHint?: string,\n): null | Payload<BodyInit> {\n if (schema.encoding === undefined) {\n if (body !== undefined) {\n throw new TypeError(\n `Cannot send a ${typeof body} body with undefined encoding`,\n )\n }\n\n return null\n }\n\n if (body === undefined) {\n // This error would be returned by the server, but we can catch it earlier\n // to avoid un-necessary requests. Note that a content-length of 0 does not\n // necessary mean that the body is \"empty\" (e.g. an empty txt file).\n throw new TypeError(`A request body is expected but none was provided`)\n }\n\n const encoding = buildEncoding(schema, encodingHint)\n return { encoding, body }\n}\n\nfunction buildEncoding(schema: LexPayload, encodingHint?: string): string {\n // Should never happen (required for type safety)\n if (!schema.encoding) {\n throw new TypeError('Unexpected payload')\n }\n\n if (encodingHint?.length) {\n if (!schema.matchesEncoding(encodingHint)) {\n throw new TypeError(\n `Cannot send a body with content-type \"${encodingHint}\" for \"${schema.encoding}\" encoding`,\n )\n }\n return encodingHint\n }\n\n // Fallback\n\n if (schema.encoding === '*/*') {\n return 'application/octet-stream'\n }\n\n if (schema.encoding.startsWith('text/')) {\n return schema.encoding.includes('*')\n ? 'text/plain; charset=utf-8'\n : `${schema.encoding}; charset=utf-8`\n }\n\n if (!schema.encoding.includes('*')) {\n return schema.encoding\n }\n\n throw new TypeError(\n `Unable to determine payload encoding. Please provide a 'content-type' header matching ${schema.encoding}.`,\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"xrpc.js","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexValue, isLexScalar, isPlainObject } from '@atproto/lex-data'\nimport { lexStringify } from '@atproto/lex-json'\nimport {\n InferMethodInput,\n InferMethodParams,\n Main,\n Params,\n ParamsSchema,\n Payload as LexPayload,\n Procedure,\n Query,\n Restricted,\n Subscription,\n getMain,\n} from '@atproto/lex-schema'\nimport { Agent } from './agent.js'\nimport {\n LexRpcResponseError,\n LexRpcUnexpectedError,\n LexRpcUpstreamError,\n} from './errors.js'\nimport { LexRpcResponse } from './response.js'\nimport { BinaryBodyInit, CallOptions } from './types.js'\nimport {\n Payload,\n buildAtprotoHeaders,\n isAsyncIterable,\n isBlobLike,\n toReadableStream,\n} from './util.js'\n\n// If all params are optional, allow omitting the params object\ntype LexRpcParamsOptions<P extends Params> =\n NonNullable<unknown> extends P ? { params?: P } : { params: P }\n\ntype LexRpcRequestPayload<M extends Procedure | Query> = InferMethodInput<\n M,\n BinaryBodyInit\n>\n\ntype LexRpcInputOptions<In> = In extends { body: infer B; encoding: infer E }\n ? // encoding will be inferred from the schema at runtime if not provided\n { body: B; encoding?: E }\n : { body?: undefined; encoding?: undefined }\n\nexport type LexRpcOptions<M extends Procedure | Query = Procedure | Query> =\n CallOptions &\n LexRpcInputOptions<LexRpcRequestPayload<M>> &\n LexRpcParamsOptions<InferMethodParams<M>>\n\nexport type LexRpcFailure<M extends Procedure | Query> =\n // The server returned a valid XRPC error response\n | LexRpcResponseError<M>\n // The response was not a valid XRPC response, or it does not match the schema\n | LexRpcUpstreamError\n // Something went wrong (network error, etc.)\n | LexRpcUnexpectedError\n\nexport type LexRpcResult<M extends Procedure | Query> =\n | LexRpcResponse<M>\n | LexRpcFailure<M>\n\n/**\n * Utility method to type cast the error thrown by {@link xrpc} to an\n * {@link LexRpcFailure} matching the provided method. Only use this function\n * inside a catch block right after calling {@link xrpc}, and use the same\n * method type parameter as used in the {@link xrpc} call.\n */\nexport function asLexRpcFailure<\n M extends Procedure | Query = Procedure | Query,\n>(err: unknown): LexRpcFailure<M> {\n if (err instanceof LexRpcResponseError) return err\n if (err instanceof LexRpcUpstreamError) return err\n return LexRpcUnexpectedError.from(err)\n}\n\n/**\n * @throws LexRpcFailure<M>\n */\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: NonNullable<unknown> extends LexRpcOptions<M>\n ? Main<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<LexRpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: LexRpcOptions<M>,\n): Promise<LexRpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: LexRpcOptions<M> = {} as LexRpcOptions<M>,\n): Promise<LexRpcResponse<M>> {\n try {\n return await lexRpcRequest<M>(agent, ns, options)\n } catch (err) {\n throw asLexRpcFailure<M>(err)\n }\n}\n\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: NonNullable<unknown> extends LexRpcOptions<M>\n ? Main<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<LexRpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: LexRpcOptions<M>,\n): Promise<LexRpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: LexRpcOptions<M> = {} as LexRpcOptions<M>,\n): Promise<LexRpcResult<M>> {\n return lexRpcRequest<M>(agent, ns, options).catch(asLexRpcFailure<M>)\n}\n\nasync function lexRpcRequest<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: LexRpcOptions<M> = {} as LexRpcOptions<M>,\n): Promise<LexRpcResponse<M>> {\n const method = getMain(ns)\n options.signal?.throwIfAborted()\n const url = xrpcRequestUrl(method, options)\n const request = xrpcRequestInit(method, options)\n const response = await agent.fetchHandler(url, request)\n return LexRpcResponse.fromFetchResponse<M>(method, response, options)\n}\n\nfunction xrpcRequestUrl<M extends Procedure | Query | Subscription>(\n method: M,\n options: CallOptions & { params?: Params },\n) {\n const path = `/xrpc/${method.nsid}`\n\n const queryString = options.params\n ? xrpcRequestParams(method.parameters, options.params, options)\n : undefined\n\n return queryString ? `${path}?${queryString}` : path\n}\n\nfunction xrpcRequestParams(\n schema: ParamsSchema | undefined,\n params: Params | undefined,\n options: CallOptions,\n): undefined | string {\n const urlSearchParams = schema?.toURLSearchParams(\n options.validateRequest ? schema.parse(params) : (params as any),\n )\n return urlSearchParams?.size ? urlSearchParams.toString() : undefined\n}\n\nfunction xrpcRequestInit<T extends Procedure | Query>(\n schema: T,\n options: CallOptions & {\n body?: LexValue | BinaryBodyInit\n encoding?: string\n },\n): RequestInit & { duplex?: 'half' } {\n const headers = buildAtprotoHeaders(options)\n\n // Tell the server what type of response we're expecting\n if (schema.output.encoding) {\n headers.set('accept', schema.output.encoding)\n }\n\n // Caller should not set content-type header\n if (headers.has('content-type')) {\n const contentType = headers.get('content-type')\n throw new TypeError(`Unexpected content-type header (${contentType})`)\n }\n\n // Requests with body\n if ('input' in schema) {\n const encodingHint = options.encoding\n const input = xrpcProcedureInput(schema, options, encodingHint)\n\n if (input) {\n headers.set('content-type', input.encoding)\n } else if (encodingHint != null) {\n throw new TypeError(`Unexpected encoding hint (${encodingHint})`)\n }\n\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'POST',\n headers,\n body: input?.body,\n }\n }\n\n // Requests without body\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'GET',\n headers,\n }\n}\n\nfunction xrpcProcedureInput(\n method: Procedure,\n options: CallOptions & { body?: LexValue | BinaryBodyInit },\n encodingHint?: string,\n): null | Payload<BodyInit> {\n const { input } = method\n const { body } = options\n\n if (options.validateRequest) {\n input.schema?.check(body)\n }\n\n // Special handling for endpoints expecting application/json input\n if (input.encoding === 'application/json') {\n // @NOTE **NOT** using isLexValue here to avoid deep checks in order to\n // distinguish between LexValue and BinaryBodyInit.\n if (!isLexScalar(body) && !isPlainObject(body) && !Array.isArray(body)) {\n throw new TypeError(`Expected LexValue body, got ${typeof body}`)\n }\n\n return buildPayload(input, lexStringify(body), encodingHint)\n }\n\n // Other encodings will be sent unaltered (ie. as binary data)\n switch (typeof body) {\n case 'undefined':\n case 'string':\n return buildPayload(input, body, encodingHint)\n case 'object': {\n if (body === null) break\n if (\n ArrayBuffer.isView(body) ||\n body instanceof ArrayBuffer ||\n body instanceof ReadableStream\n ) {\n return buildPayload(input, body, encodingHint)\n } else if (isAsyncIterable(body)) {\n return buildPayload(input, toReadableStream(body), encodingHint)\n } else if (isBlobLike(body)) {\n return buildPayload(input, body, encodingHint || body.type)\n }\n }\n }\n\n throw new TypeError(\n `Invalid ${typeof body} body for ${input.encoding} encoding`,\n )\n}\n\nfunction buildPayload(\n schema: LexPayload,\n body: undefined | BodyInit,\n encodingHint?: string,\n): null | Payload<BodyInit> {\n if (schema.encoding === undefined) {\n if (body !== undefined) {\n throw new TypeError(\n `Cannot send a ${typeof body} body with undefined encoding`,\n )\n }\n\n return null\n }\n\n if (body === undefined) {\n // This error would be returned by the server, but we can catch it earlier\n // to avoid un-necessary requests. Note that a content-length of 0 does not\n // necessary mean that the body is \"empty\" (e.g. an empty txt file).\n throw new TypeError(`A request body is expected but none was provided`)\n }\n\n const encoding = buildEncoding(schema, encodingHint)\n return { encoding, body }\n}\n\nfunction buildEncoding(schema: LexPayload, encodingHint?: string): string {\n // Should never happen (required for type safety)\n if (!schema.encoding) {\n throw new TypeError('Unexpected payload')\n }\n\n if (encodingHint?.length) {\n if (!schema.matchesEncoding(encodingHint)) {\n throw new TypeError(\n `Cannot send a body with content-type \"${encodingHint}\" for \"${schema.encoding}\" encoding`,\n )\n }\n return encodingHint\n }\n\n // Fallback\n\n if (schema.encoding === '*/*') {\n return 'application/octet-stream'\n }\n\n if (schema.encoding.startsWith('text/')) {\n return schema.encoding.includes('*')\n ? 'text/plain; charset=utf-8'\n : `${schema.encoding}; charset=utf-8`\n }\n\n if (!schema.encoding.includes('*')) {\n return schema.encoding\n }\n\n throw new TypeError(\n `Unable to determine payload encoding. Please provide a 'content-type' header matching ${schema.encoding}.`,\n )\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/lex-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "HTTP client for interacting with Lexicon based APIs",
|
|
6
6
|
"keywords": [
|
|
@@ -29,26 +29,26 @@
|
|
|
29
29
|
"types": "./dist/index.d.ts",
|
|
30
30
|
"exports": {
|
|
31
31
|
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
32
33
|
"browser": "./dist/index.js",
|
|
33
34
|
"import": "./dist/index.js",
|
|
34
|
-
"require": "./dist/index.js"
|
|
35
|
-
"types": "./dist/index.d.ts"
|
|
35
|
+
"require": "./dist/index.js"
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"tslib": "^2.8.1",
|
|
40
|
-
"@atproto/lex-data": "0.0.
|
|
41
|
-
"@atproto/lex-json": "0.0.
|
|
42
|
-
"@atproto/lex-schema": "0.0.
|
|
40
|
+
"@atproto/lex-data": "0.0.6",
|
|
41
|
+
"@atproto/lex-json": "0.0.6",
|
|
42
|
+
"@atproto/lex-schema": "0.0.7"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"
|
|
46
|
-
"@atproto/lex-cbor": "0.0.
|
|
47
|
-
"@atproto/lex-builder": "0.0.
|
|
45
|
+
"vitest": "^4.0.16",
|
|
46
|
+
"@atproto/lex-cbor": "0.0.6",
|
|
47
|
+
"@atproto/lex-builder": "0.0.9"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"prebuild": "node ./scripts/lex-build.mjs",
|
|
51
51
|
"build": "tsc --build tsconfig.build.json",
|
|
52
|
-
"test": "
|
|
52
|
+
"test": "vitest run"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/src/agent.ts
CHANGED
|
@@ -39,8 +39,12 @@ export type AgentConfig = {
|
|
|
39
39
|
|
|
40
40
|
export type AgentOptions = AgentConfig | string | URL
|
|
41
41
|
|
|
42
|
-
export function buildAgent(options: AgentOptions): Agent {
|
|
43
|
-
|
|
42
|
+
export function buildAgent(options: Agent | AgentOptions): Agent {
|
|
43
|
+
if (typeof options === 'object' && 'fetchHandler' in options) {
|
|
44
|
+
return options
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const config: Agent | AgentConfig =
|
|
44
48
|
typeof options === 'string' || options instanceof URL
|
|
45
49
|
? { did: undefined, service: options }
|
|
46
50
|
: options
|