@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.
Files changed (77) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/agent.d.ts +1 -1
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +3 -0
  5. package/dist/agent.js.map +1 -1
  6. package/dist/client.d.ts +34 -32
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +17 -21
  9. package/dist/client.js.map +1 -1
  10. package/dist/{xrpc-error.d.ts → errors.d.ts} +22 -27
  11. package/dist/errors.d.ts.map +1 -0
  12. package/dist/{xrpc-error.js → errors.js} +38 -33
  13. package/dist/errors.js.map +1 -0
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts.map +1 -1
  19. package/dist/lexicons/com/atproto/repo/createRecord.defs.js +5 -7
  20. package/dist/lexicons/com/atproto/repo/createRecord.defs.js.map +1 -1
  21. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts.map +1 -1
  22. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.js +5 -7
  23. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.js.map +1 -1
  24. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts.map +1 -1
  25. package/dist/lexicons/com/atproto/repo/getRecord.defs.js +3 -5
  26. package/dist/lexicons/com/atproto/repo/getRecord.defs.js.map +1 -1
  27. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts.map +1 -1
  28. package/dist/lexicons/com/atproto/repo/listRecords.defs.js +2 -3
  29. package/dist/lexicons/com/atproto/repo/listRecords.defs.js.map +1 -1
  30. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts.map +1 -1
  31. package/dist/lexicons/com/atproto/repo/putRecord.defs.js +5 -7
  32. package/dist/lexicons/com/atproto/repo/putRecord.defs.js.map +1 -1
  33. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts.map +1 -1
  34. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js +3 -4
  35. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js.map +1 -1
  36. package/dist/lexicons/index.d.ts +2 -0
  37. package/dist/lexicons/index.d.ts.map +1 -0
  38. package/dist/lexicons/index.js +9 -0
  39. package/dist/lexicons/index.js.map +1 -0
  40. package/dist/response.d.ts +38 -0
  41. package/dist/response.d.ts.map +1 -0
  42. package/dist/{xrpc-response.js → response.js} +24 -20
  43. package/dist/response.js.map +1 -0
  44. package/dist/types.d.ts +0 -4
  45. package/dist/types.d.ts.map +1 -1
  46. package/dist/types.js +0 -4
  47. package/dist/types.js.map +1 -1
  48. package/dist/xrpc.d.ts +23 -17
  49. package/dist/xrpc.d.ts.map +1 -1
  50. package/dist/xrpc.js +15 -17
  51. package/dist/xrpc.js.map +1 -1
  52. package/package.json +10 -10
  53. package/src/agent.ts +6 -2
  54. package/src/client.ts +72 -66
  55. package/src/{xrpc-error.ts → errors.ts} +59 -48
  56. package/src/index.ts +2 -0
  57. package/src/lexicons/com/atproto/repo/createRecord.defs.ts +22 -28
  58. package/src/lexicons/com/atproto/repo/deleteRecord.defs.ts +18 -24
  59. package/src/lexicons/com/atproto/repo/getRecord.defs.ts +5 -10
  60. package/src/lexicons/com/atproto/repo/listRecords.defs.ts +6 -9
  61. package/src/lexicons/com/atproto/repo/putRecord.defs.ts +23 -29
  62. package/src/lexicons/com/atproto/repo/uploadBlob.defs.ts +4 -7
  63. package/src/lexicons/index.ts +5 -0
  64. package/src/{xrpc-response.ts → response.ts} +45 -30
  65. package/src/types.ts +0 -6
  66. package/src/xrpc.ts +56 -57
  67. package/tsconfig.tests.json +4 -7
  68. package/dist/lexicons.d.ts +0 -2
  69. package/dist/lexicons.d.ts.map +0 -1
  70. package/dist/lexicons.js +0 -6
  71. package/dist/lexicons.js.map +0 -1
  72. package/dist/xrpc-error.d.ts.map +0 -1
  73. package/dist/xrpc-error.js.map +0 -1
  74. package/dist/xrpc-response.d.ts +0 -35
  75. package/dist/xrpc-response.d.ts.map +0 -1
  76. package/dist/xrpc-response.js.map +0 -1
  77. 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.XrpcResponse = void 0;
3
+ exports.LexRpcResponse = void 0;
4
4
  const lex_json_1 = require("@atproto/lex-json");
5
- const xrpc_error_js_1 = require("./xrpc-error.js");
5
+ const errors_js_1 = require("./errors.js");
6
6
  /**
7
7
  * Small container for XRPC response data.
8
8
  *
9
- * @implements {ResultSuccess<XrpcResponse<M>>} for convenience in result handling contexts.
9
+ * @implements {ResultSuccess<LexRpcResponse<M>>} for convenience in result handling contexts.
10
10
  */
11
- class XrpcResponse {
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 {XrpcInvalidResponseError} when the response is invalid according
43
- * to the method schema.
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, xrpc_error_js_1.isXrpcErrorPayload)(payload)) {
54
- throw new xrpc_error_js_1.XrpcResponseError(method, response.status, response.headers, payload);
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
- throw new xrpc_error_js_1.XrpcInvalidResponseError(response.status >= 500
57
- ? `Upstream server encountered an error`
58
- : response.status >= 400
59
- ? `Upstream server returned an invalid response payload`
60
- : `Upstream server returned an invalid status code`, response, payload);
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 xrpc_error_js_1.XrpcInvalidResponseError(`Expected response with no body, got ${payload.encoding}`, response, payload);
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 xrpc_error_js_1.XrpcInvalidResponseError(payload
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 xrpc_error_js_1.XrpcInvalidResponseError(`Response validation failed: ${result.reason.message}`, response, payload, { cause: result.reason });
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 XrpcResponse(method, response.status, response.headers, payload);
94
+ return new LexRpcResponse(method, response.status, response.headers, payload);
91
95
  }
92
96
  }
93
- exports.XrpcResponse = XrpcResponse;
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 xrpc_error_js_1.XrpcInvalidResponseError('Invalid JSON response body', response, null, { cause });
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=xrpc-response.js.map
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
@@ -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;AAEV,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAA;AAE1C,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAE7D"}
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
@@ -1,7 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getMain = getMain;
4
- function getMain(ns) {
5
- return 'main' in ns ? ns.main : ns;
6
- }
7
3
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;AA6CA,0BAEC;AAFD,SAAgB,OAAO,CAAmB,EAAgB;IACxD,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AACpC,CAAC","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\nexport type Namespace<T> = T | { main: T }\n\nexport function getMain<T extends object>(ns: Namespace<T>): T {\n return 'main' in ns ? ns.main : ns\n}\n"]}
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 { BinaryBodyInit, CallOptions, Namespace } from './types.js';
4
- import { XrpcInvalidResponseError, XrpcResponseError, XrpcUnexpectedError } from './xrpc-error.js';
5
- import { XrpcResponse } from './xrpc-response.js';
6
- export * from './xrpc-error.js';
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 XrpcRequestPayload<M extends Procedure | Query> = InferMethodInput<M, BinaryBodyInit>;
14
- type XrpcInputOptions<In> = In extends {
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 XrpcOptions<M extends Procedure | Query = Procedure | Query> = CallOptions & XrpcInputOptions<XrpcRequestPayload<M>> & XrpcParamsOptions<InferMethodParams<M>>;
25
- export type XrpcFailure<M extends Procedure | Query> = XrpcResponseError<M> | XrpcInvalidResponseError | XrpcUnexpectedError;
26
- export type XrpcResult<M extends Procedure | Query> = XrpcResponse<M> | XrpcFailure<M>;
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
- * @throws XrpcFailure<M>
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 xrpc<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends XrpcOptions<M> ? Namespace<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<XrpcResponse<M>>;
31
- export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: Namespace<M>, options: XrpcOptions<M>): Promise<XrpcResponse<M>>;
32
- export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends XrpcOptions<M> ? Namespace<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<XrpcResult<M>>;
33
- export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: Namespace<M>, options: XrpcOptions<M>): Promise<XrpcResult<M>>;
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
@@ -1 +1 @@
1
- {"version":3,"file":"xrpc.d.ts","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xrpc.d.ts","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"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"}
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 types_js_1 = require("./types.js");
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 XrpcFailure} matching the provided method. Only use this function
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 asXrpcFailure(err) {
21
- if (err instanceof xrpc_error_js_1.XrpcResponseError)
18
+ function asLexRpcFailure(err) {
19
+ if (err instanceof errors_js_1.LexRpcResponseError)
22
20
  return err;
23
- if (err instanceof xrpc_error_js_1.XrpcInvalidResponseError)
21
+ if (err instanceof errors_js_1.LexRpcUpstreamError)
24
22
  return err;
25
- return xrpc_error_js_1.XrpcUnexpectedError.from(err);
23
+ return errors_js_1.LexRpcUnexpectedError.from(err);
26
24
  }
27
25
  async function xrpc(agent, ns, options = {}) {
28
26
  try {
29
- return await xrpcRequest(agent, ns, options);
27
+ return await lexRpcRequest(agent, ns, options);
30
28
  }
31
29
  catch (err) {
32
- throw asXrpcFailure(err);
30
+ throw asLexRpcFailure(err);
33
31
  }
34
32
  }
35
33
  async function xrpcSafe(agent, ns, options = {}) {
36
- return xrpcRequest(agent, ns, options).catch((asXrpcFailure));
34
+ return lexRpcRequest(agent, ns, options).catch((asLexRpcFailure));
37
35
  }
38
- async function xrpcRequest(agent, ns, options = {}) {
39
- const method = (0, types_js_1.getMain)(ns);
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 xrpc_response_js_1.XrpcResponse.fromFetchResponse(method, response, options);
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.5",
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.4",
41
- "@atproto/lex-json": "0.0.4",
42
- "@atproto/lex-schema": "0.0.5"
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
- "jest": "^28.1.2",
46
- "@atproto/lex-cbor": "0.0.4",
47
- "@atproto/lex-builder": "0.0.7"
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": "jest"
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
- const config: AgentConfig =
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