@atproto/lex-client 0.0.10 → 0.0.12

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 (48) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/agent.d.ts +72 -0
  3. package/dist/agent.d.ts.map +1 -1
  4. package/dist/agent.js +46 -1
  5. package/dist/agent.js.map +1 -1
  6. package/dist/client.d.ts +442 -46
  7. package/dist/client.d.ts.map +1 -1
  8. package/dist/client.js +145 -1
  9. package/dist/client.js.map +1 -1
  10. package/dist/errors.d.ts +202 -48
  11. package/dist/errors.d.ts.map +1 -1
  12. package/dist/errors.js +208 -65
  13. package/dist/errors.js.map +1 -1
  14. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts +20 -20
  15. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts +12 -12
  16. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts +6 -6
  17. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts +6 -6
  18. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts +22 -22
  19. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts +2 -2
  20. package/dist/response.d.ts +17 -6
  21. package/dist/response.d.ts.map +1 -1
  22. package/dist/response.js +45 -32
  23. package/dist/response.js.map +1 -1
  24. package/dist/types.d.ts +51 -0
  25. package/dist/types.d.ts.map +1 -1
  26. package/dist/types.js.map +1 -1
  27. package/dist/util.d.ts +40 -5
  28. package/dist/util.d.ts.map +1 -1
  29. package/dist/util.js +22 -0
  30. package/dist/util.js.map +1 -1
  31. package/dist/www-authenticate.d.ts +35 -0
  32. package/dist/www-authenticate.d.ts.map +1 -0
  33. package/dist/www-authenticate.js +57 -0
  34. package/dist/www-authenticate.js.map +1 -0
  35. package/dist/xrpc.d.ts +82 -10
  36. package/dist/xrpc.d.ts.map +1 -1
  37. package/dist/xrpc.js +15 -28
  38. package/dist/xrpc.js.map +1 -1
  39. package/package.json +7 -7
  40. package/src/agent.ts +101 -1
  41. package/src/client.ts +428 -15
  42. package/src/errors.ts +308 -120
  43. package/src/response.ts +68 -63
  44. package/src/types.ts +52 -0
  45. package/src/util.ts +50 -5
  46. package/src/www-authenticate.test.ts +227 -0
  47. package/src/www-authenticate.ts +101 -0
  48. package/src/xrpc.ts +100 -53
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexError, LexErrorCode, LexErrorData } from '@atproto/lex-data'\nimport { l } from '@atproto/lex-schema'\nimport { XrpcPayload } from './util.js'\n\nexport { LexError }\nexport type { LexErrorCode, LexErrorData }\n\nexport type XrpcErrorPayload<N extends LexErrorCode = LexErrorCode> =\n XrpcPayload<LexErrorData<N>, 'application/json'>\n\nexport class XrpcError<\n N extends LexErrorCode = LexErrorCode,\n> extends LexError<N> {\n name = 'XrpcError'\n\n constructor(\n error: N,\n message: string = `${error} Lexicon RPC error`,\n options?: ErrorOptions,\n ) {\n super(error, message, options)\n }\n}\n\n/**\n * All unsuccessful responses should follow a standard error response\n * schema. The Content-Type should be application/json, and the payload\n * should be a JSON object with the following fields:\n *\n * - `error` (string, required): type name of the error (generic ASCII\n * constant, no whitespace)\n * - `message` (string, optional): description of the error, appropriate for\n * display to humans\n *\n * This function checks whether a given payload matches this schema.\n */\nexport function isXrpcErrorPayload(\n payload: XrpcPayload | null,\n): payload is XrpcErrorPayload {\n return (\n payload !== null &&\n payload.encoding === 'application/json' &&\n l.lexErrorData.matches(payload.body)\n )\n}\n\n/**\n * Interface representing a failed XRPC request result.\n */\ntype LexRpcFailureResult<N extends LexErrorCode, E> = l.ResultFailure<E> & {\n readonly error: N\n shouldRetry(): boolean\n matchesSchema(): boolean\n}\n\n/**\n * Class used to represent an HTTP request that resulted in an XRPC method error\n * That is, a non-2xx response with a valid XRPC error payload.\n */\nexport class XrpcResponseError<\n M extends l.Procedure | l.Query = l.Procedure | l.Query,\n N extends LexErrorCode = LexErrorCode,\n >\n extends XrpcError<N>\n implements LexRpcFailureResult<N, XrpcResponseError<M, N>>\n{\n name = 'XrpcResponseError'\n\n constructor(\n readonly method: M,\n readonly status: number,\n readonly headers: Headers,\n readonly payload: XrpcErrorPayload<N>,\n options?: ErrorOptions,\n ) {\n const { error, message } = payload.body\n super(error, message, options)\n }\n\n readonly success = false\n\n get reason(): this {\n return this as this\n }\n\n get body(): LexErrorData {\n return this.payload.body\n }\n\n matchesSchema(): this is M extends {\n errors: readonly (infer E extends string)[]\n }\n ? XrpcResponseError<M, E>\n : never {\n return this.method.errors?.includes(this.error) ?? false\n }\n\n shouldRetry(): boolean {\n // Do not retry client errors\n if (this.status < 500) return false\n\n return true\n }\n\n toJSON() {\n return this.payload.body\n }\n\n toResponse(): Response {\n const { status, headers } = this\n return Response.json(this.toJSON(), { status, headers })\n }\n}\n\n/**\n * This class represents an invalid XRPC response from the server.\n */\nexport class XrpcUpstreamError<\n N extends 'InvalidResponse' | 'UpstreamFailure' =\n | 'InvalidResponse'\n | 'UpstreamFailure',\n >\n extends XrpcError<N>\n implements LexRpcFailureResult<N, XrpcUpstreamError<N>>\n{\n name = 'XrpcUpstreamError' as const\n\n // For debugging purposes, we keep the response details here\n readonly response: {\n status: number\n headers: Headers\n payload: XrpcPayload | null\n }\n\n constructor(\n error: N,\n message: string,\n response: { status: number; headers: Headers },\n payload: XrpcPayload | null,\n options?: ErrorOptions,\n ) {\n super(error, message, { cause: options?.cause })\n this.response = {\n status: response.status,\n headers: response.headers,\n payload,\n }\n }\n\n readonly success = false as const\n\n get reason(): this {\n return this\n }\n\n matchesSchema(): false {\n return false\n }\n\n shouldRetry(): boolean {\n // Do not retry client errors\n return this.response.status >= 500\n }\n\n toResponse(): Response {\n return Response.json(this.toJSON(), { status: 502 })\n }\n}\n\nexport class XrpcUnexpectedError\n extends XrpcError<'InternalServerError'>\n implements LexRpcFailureResult<'InternalServerError', unknown>\n{\n name = 'XrpcUnexpectedError' as const\n\n protected constructor(message: string, options: Required<ErrorOptions>) {\n super('InternalServerError', message, options)\n }\n\n readonly success = false\n\n get reason() {\n return this.cause\n }\n\n matchesSchema(): false {\n return false\n }\n\n shouldRetry(): boolean {\n return true\n }\n\n toResponse(): Response {\n return Response.json(this.toJSON(), { status: 500 })\n }\n\n static from(\n cause: unknown,\n message: string = cause instanceof LexError\n ? cause.message\n : 'XRPC request failed',\n ): XrpcUnexpectedError {\n if (cause instanceof XrpcUnexpectedError) return cause\n return new XrpcUnexpectedError(message, { cause })\n }\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexError, LexErrorCode, LexErrorData } from '@atproto/lex-data'\nimport {\n InferMethodError,\n Procedure,\n Query,\n ResultFailure,\n lexErrorDataSchema,\n} from '@atproto/lex-schema'\nimport { XrpcResponsePayload } from './util.js'\nimport {\n WWWAuthenticate,\n parseWWWAuthenticateHeader,\n} from './www-authenticate.js'\n\n/**\n * HTTP status codes that indicate a transient error that may succeed on retry.\n *\n * Includes:\n * - 408 Request Timeout\n * - 425 Too Early\n * - 429 Too Many Requests (rate limited)\n * - 500 Internal Server Error\n * - 502 Bad Gateway\n * - 503 Service Unavailable\n * - 504 Gateway Timeout\n * - 522 Connection Timed Out (Cloudflare)\n * - 524 A Timeout Occurred (Cloudflare)\n */\nexport const RETRYABLE_HTTP_STATUS_CODES: ReadonlySet<number> = new Set([\n 408, 425, 429, 500, 502, 503, 504, 522, 524,\n])\n\nexport { LexError }\nexport type { LexErrorCode, LexErrorData }\n\n/**\n * The payload structure for XRPC error responses.\n *\n * All XRPC errors return JSON with an `error` code and optional `message`.\n *\n * @typeParam N - The specific error code type\n */\nexport type XrpcErrorPayload<N extends LexErrorCode = LexErrorCode> = {\n body: LexErrorData<N>\n encoding: 'application/json'\n}\n\n/**\n * All unsuccessful responses should follow a standard error response\n * schema. The Content-Type should be application/json, and the payload\n * should be a JSON object with the following fields:\n *\n * - `error` (string, required): type name of the error (generic ASCII\n * constant, no whitespace)\n * - `message` (string, optional): description of the error, appropriate for\n * display to humans\n *\n * This function checks whether a given payload matches this schema.\n */\nexport function isXrpcErrorPayload(\n payload: XrpcResponsePayload | null | undefined,\n): payload is XrpcErrorPayload {\n return (\n payload != null &&\n payload.encoding === 'application/json' &&\n lexErrorDataSchema.matches(payload.body)\n )\n}\n\n/**\n * Abstract base class for all XRPC errors.\n *\n * Extends {@link LexError} and implements {@link ResultFailure} for use with\n * safe/result-based error handling patterns.\n *\n * @typeParam M - The XRPC method type (Procedure or Query)\n * @typeParam N - The error code type\n * @typeParam TReason - The reason type for ResultFailure\n *\n * @see {@link XrpcResponseError} - For valid XRPC error responses\n * @see {@link XrpcUpstreamError} - For invalid/unexpected responses\n * @see {@link XrpcInternalError} - For network/internal errors\n */\nexport abstract class XrpcError<\n M extends Procedure | Query = Procedure | Query,\n N extends LexErrorCode = LexErrorCode,\n TReason = unknown,\n >\n extends LexError<N>\n implements ResultFailure<TReason>\n{\n name = 'XrpcError'\n\n constructor(\n readonly method: M,\n error: N,\n message: string = `${error} Lexicon RPC error`,\n options?: ErrorOptions,\n ) {\n super(error, message, options)\n }\n\n /**\n * @see {@link ResultFailure.success}\n */\n readonly success = false as const\n\n /**\n * @see {@link ResultFailure.reason}\n */\n abstract readonly reason: TReason\n\n /**\n * Indicates whether the error is transient and can be retried.\n */\n abstract shouldRetry(): boolean\n\n matchesSchema(): this is XrpcError<M, InferMethodError<M>> {\n return this.method.errors?.includes(this.error) ?? false\n }\n}\n\n/**\n * Error class for valid XRPC error responses from the server.\n *\n * This represents a properly formatted XRPC error where the server returned\n * a non-2xx status with a valid JSON error payload containing `error` and\n * optional `message` fields.\n *\n * Use {@link matchesSchema} to check if the error matches the method's declared\n * error types for type-safe error handling.\n *\n * @typeParam M - The XRPC method type\n * @typeParam N - The error code type (inferred from method or generic)\n *\n * @example Handling specific errors\n * ```typescript\n * try {\n * await client.xrpc(someMethod, options)\n * } catch (err) {\n * if (err instanceof XrpcResponseError && err.error === 'RecordNotFound') {\n * // Handle not found case\n * }\n * }\n * ```\n */\nexport class XrpcResponseError<\n M extends Procedure | Query = Procedure | Query,\n N extends LexErrorCode = InferMethodError<M> | LexErrorCode,\n> extends XrpcError<M, N, XrpcResponseError<M, N>> {\n name = 'XrpcResponseError'\n\n constructor(\n method: M,\n readonly response: Response,\n readonly payload: XrpcErrorPayload<N>,\n options?: ErrorOptions,\n ) {\n const { error, message } = payload.body\n super(method, error, message, options)\n }\n\n override get reason(): this {\n return this\n }\n\n override shouldRetry(): boolean {\n return RETRYABLE_HTTP_STATUS_CODES.has(this.response.status)\n }\n\n override toJSON() {\n return this.payload.body\n }\n\n override toResponse(): Response {\n // Re-expose schema-valid errors as-is to downstream clients\n if (this.matchesSchema()) {\n const status = this.response.status >= 500 ? 502 : this.response.status\n return Response.json(this.toJSON(), { status })\n }\n\n return this.response.status >= 500\n ? // The upstream server had an error, return a generic upstream failure\n Response.json({ error: 'UpstreamFailure' }, { status: 502 })\n : // If the error is on our side, return a generic internal server error\n Response.json({ error: 'InternalServerError' }, { status: 500 })\n }\n\n get body(): LexErrorData {\n return this.payload.body\n }\n}\n\nexport type { WWWAuthenticate }\n\n/**\n * Error class for 401 Unauthorized XRPC responses.\n *\n * Extends {@link XrpcResponseError} with access to parsed WWW-Authenticate header\n * information, useful for implementing authentication flows.\n *\n * Authentication errors are never retryable as they require user intervention\n * (e.g., re-authentication, token refresh).\n *\n * @typeParam M - The XRPC method type\n * @typeParam N - The error code type\n *\n * @example Handling authentication errors\n * ```typescript\n * try {\n * await client.xrpc(someMethod, options)\n * } catch (err) {\n * if (err instanceof XrpcAuthenticationError) {\n * const { DPoP } = err.wwwAuthenticate\n * if (DPoP?.error === 'use_dpop_nonce') {\n * // Handle DPoP nonce requirement\n * }\n * }\n * }\n * ```\n */\nexport class XrpcAuthenticationError<\n M extends Procedure | Query = Procedure | Query,\n N extends LexErrorCode = LexErrorCode,\n> extends XrpcResponseError<M, N> {\n name = 'XrpcAuthenticationError'\n\n override shouldRetry(): boolean {\n return false\n }\n\n #wwwAuthenticateCached?: WWWAuthenticate\n /**\n * Parsed WWW-Authenticate header from the response.\n * Contains authentication scheme parameters (e.g., Bearer realm, DPoP nonce).\n */\n get wwwAuthenticate(): WWWAuthenticate {\n return (this.#wwwAuthenticateCached ??=\n parseWWWAuthenticateHeader(\n this.response.headers.get('www-authenticate'),\n ) ?? {})\n }\n}\n\n/**\n * Error class for invalid or unprocessable XRPC responses from upstream servers.\n *\n * This occurs when the server returns a response that doesn't conform to the\n * XRPC protocol, such as:\n * - Missing or invalid Content-Type header\n * - Response body that doesn't match the method's output schema\n * - Non-JSON error responses\n * - Responses from non-XRPC endpoints\n *\n * The error code is always 'UpstreamFailure' and maps to HTTP 502 Bad Gateway\n * when converted to a response.\n *\n * @typeParam M - The XRPC method type\n */\nexport class XrpcUpstreamError<\n M extends Procedure | Query = Procedure | Query,\n> extends XrpcError<M, 'UpstreamFailure', XrpcUpstreamError<M>> {\n name = 'XrpcUpstreamError'\n\n constructor(\n method: M,\n readonly response: Response,\n readonly payload: XrpcResponsePayload | null = null,\n message: string = `Unexpected upstream XRPC response`,\n options?: ErrorOptions,\n ) {\n super(method, 'UpstreamFailure', message, options)\n }\n\n override get reason(): this {\n return this\n }\n\n override shouldRetry(): boolean {\n return RETRYABLE_HTTP_STATUS_CODES.has(this.response.status)\n }\n\n override toResponse(): Response {\n return Response.json(this.toJSON(), { status: 502 })\n }\n}\n\n/**\n * Error class for internal/client-side errors during XRPC requests.\n *\n * This represents errors that occur before or during the request that are not\n * server responses, such as:\n * - Network errors (connection refused, DNS failure)\n * - Request timeouts\n * - Request aborted via AbortSignal\n * - Invalid request construction\n *\n * The error code is always 'InternalServerError' and these errors are\n * optimistically considered retryable.\n *\n * @typeParam M - The XRPC method type\n */\nexport class XrpcInternalError<\n M extends Procedure | Query = Procedure | Query,\n> extends XrpcError<M, 'InternalServerError', XrpcInternalError<M>> {\n name = 'XrpcInternalError'\n\n constructor(method: M, message?: string, options?: ErrorOptions) {\n super(\n method,\n 'InternalServerError',\n message ?? 'Unable to fulfill XRPC request',\n options,\n )\n }\n\n override get reason(): this {\n return this\n }\n\n override shouldRetry(): true {\n // Ideally, we would inspect the reason to determine if it's retryable\n // (by detecting network errors, timeouts, etc.). Since these cases are\n // highly platform-dependent, we optimistically assume all internal\n // errors are retryable.\n return true\n }\n\n override toResponse(): Response {\n // Do not expose internal error details to downstream clients\n return Response.json({ error: this.error }, { status: 500 })\n }\n}\n\n/**\n * Union type of all possible XRPC failure types.\n *\n * Used as the return type for safe/non-throwing XRPC methods. Check the\n * `success` property to distinguish between success and failure:\n *\n * @typeParam M - The XRPC method type\n *\n * @example\n * ```typescript\n * const result = await client.xrpcSafe(someMethod, options)\n * if (result.success) {\n * console.log(result.body) // XrpcResponse\n * } else {\n * // result is XrpcFailure (XrpcResponseError | XrpcUpstreamError | XrpcInternalError)\n * console.error(result.error, result.message)\n * }\n * ```\n */\nexport type XrpcFailure<M extends Procedure | Query = 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 | XrpcUpstreamError<M>\n // Something went wrong (network error, etc.)\n | XrpcInternalError<M>\n\n/**\n * Converts an unknown error into an appropriate {@link XrpcFailure} type.\n *\n * If the error is already an XrpcFailure for the given method, returns it as-is.\n * Otherwise, wraps it in an {@link XrpcInternalError}.\n *\n * @param method - The XRPC method that was called\n * @param cause - The error to convert\n * @returns An XrpcFailure instance\n *\n * @example\n * ```typescript\n * try {\n * const response = await fetch(...)\n * // ... process response\n * } catch (err) {\n * return asXrpcFailure(method, err)\n * }\n * ```\n */\nexport function asXrpcFailure<M extends Procedure | Query>(\n method: M,\n cause: unknown,\n): XrpcFailure<M> {\n if (\n cause instanceof XrpcResponseError ||\n cause instanceof XrpcUpstreamError ||\n cause instanceof XrpcInternalError\n ) {\n if (cause.method === method) return cause\n }\n\n return new XrpcInternalError(method, undefined, { cause })\n}\n"]}
@@ -4,30 +4,30 @@ declare const $nsid = "com.atproto.repo.createRecord";
4
4
  export { $nsid };
5
5
  /** Create a single new repository record. Requires auth, implemented by PDS. */
6
6
  declare const main: l.Procedure<"com.atproto.repo.createRecord", l.ParamsSchema<{}>, l.Payload<"application/json", l.ObjectSchema<{
7
- readonly repo: l.StringSchema<{
7
+ repo: l.StringSchema<{
8
8
  readonly format: "at-identifier";
9
9
  }>;
10
- readonly collection: l.StringSchema<{
10
+ collection: l.StringSchema<{
11
11
  readonly format: "nsid";
12
12
  }>;
13
- readonly rkey: l.OptionalSchema<l.StringSchema<{
13
+ rkey: l.OptionalSchema<l.StringSchema<{
14
14
  readonly format: "record-key";
15
15
  readonly maxLength: 512;
16
16
  }>>;
17
- readonly validate: l.OptionalSchema<l.BooleanSchema>;
18
- readonly record: l.UnknownObjectSchema;
19
- readonly swapCommit: l.OptionalSchema<l.StringSchema<{
17
+ validate: l.OptionalSchema<l.BooleanSchema>;
18
+ record: l.UnknownObjectSchema;
19
+ swapCommit: l.OptionalSchema<l.StringSchema<{
20
20
  readonly format: "cid";
21
21
  }>>;
22
22
  }>>, l.Payload<"application/json", l.ObjectSchema<{
23
- readonly uri: l.StringSchema<{
23
+ uri: l.StringSchema<{
24
24
  readonly format: "at-uri";
25
25
  }>;
26
- readonly cid: l.StringSchema<{
26
+ cid: l.StringSchema<{
27
27
  readonly format: "cid";
28
28
  }>;
29
- readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
30
- readonly validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
29
+ commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
30
+ validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
31
31
  }>>, readonly ["InvalidSwap"]>;
32
32
  export { main };
33
33
  export type Params = l.InferMethodParams<typeof main>;
@@ -36,29 +36,29 @@ export type InputBody = l.InferMethodInputBody<typeof main>;
36
36
  export type Output = l.InferMethodOutput<typeof main>;
37
37
  export type OutputBody = l.InferMethodOutputBody<typeof main>;
38
38
  export declare const $lxm: "com.atproto.repo.createRecord", $params: l.ParamsSchema<{}>, $input: l.Payload<"application/json", l.ObjectSchema<{
39
- readonly repo: l.StringSchema<{
39
+ repo: l.StringSchema<{
40
40
  readonly format: "at-identifier";
41
41
  }>;
42
- readonly collection: l.StringSchema<{
42
+ collection: l.StringSchema<{
43
43
  readonly format: "nsid";
44
44
  }>;
45
- readonly rkey: l.OptionalSchema<l.StringSchema<{
45
+ rkey: l.OptionalSchema<l.StringSchema<{
46
46
  readonly format: "record-key";
47
47
  readonly maxLength: 512;
48
48
  }>>;
49
- readonly validate: l.OptionalSchema<l.BooleanSchema>;
50
- readonly record: l.UnknownObjectSchema;
51
- readonly swapCommit: l.OptionalSchema<l.StringSchema<{
49
+ validate: l.OptionalSchema<l.BooleanSchema>;
50
+ record: l.UnknownObjectSchema;
51
+ swapCommit: l.OptionalSchema<l.StringSchema<{
52
52
  readonly format: "cid";
53
53
  }>>;
54
54
  }>>, $output: l.Payload<"application/json", l.ObjectSchema<{
55
- readonly uri: l.StringSchema<{
55
+ uri: l.StringSchema<{
56
56
  readonly format: "at-uri";
57
57
  }>;
58
- readonly cid: l.StringSchema<{
58
+ cid: l.StringSchema<{
59
59
  readonly format: "cid";
60
60
  }>;
61
- readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
62
- readonly validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
61
+ commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
62
+ validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
63
63
  }>>;
64
64
  //# sourceMappingURL=createRecord.defs.d.ts.map
@@ -4,23 +4,23 @@ declare const $nsid = "com.atproto.repo.deleteRecord";
4
4
  export { $nsid };
5
5
  /** Delete a repository record, or ensure it doesn't exist. Requires auth, implemented by PDS. */
6
6
  declare const main: l.Procedure<"com.atproto.repo.deleteRecord", l.ParamsSchema<{}>, l.Payload<"application/json", l.ObjectSchema<{
7
- readonly repo: l.StringSchema<{
7
+ repo: l.StringSchema<{
8
8
  readonly format: "at-identifier";
9
9
  }>;
10
- readonly collection: l.StringSchema<{
10
+ collection: l.StringSchema<{
11
11
  readonly format: "nsid";
12
12
  }>;
13
- readonly rkey: l.StringSchema<{
13
+ rkey: l.StringSchema<{
14
14
  readonly format: "record-key";
15
15
  }>;
16
- readonly swapRecord: l.OptionalSchema<l.StringSchema<{
16
+ swapRecord: l.OptionalSchema<l.StringSchema<{
17
17
  readonly format: "cid";
18
18
  }>>;
19
- readonly swapCommit: l.OptionalSchema<l.StringSchema<{
19
+ swapCommit: l.OptionalSchema<l.StringSchema<{
20
20
  readonly format: "cid";
21
21
  }>>;
22
22
  }>>, l.Payload<"application/json", l.ObjectSchema<{
23
- readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
23
+ commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
24
24
  }>>, readonly ["InvalidSwap"]>;
25
25
  export { main };
26
26
  export type Params = l.InferMethodParams<typeof main>;
@@ -29,22 +29,22 @@ export type InputBody = l.InferMethodInputBody<typeof main>;
29
29
  export type Output = l.InferMethodOutput<typeof main>;
30
30
  export type OutputBody = l.InferMethodOutputBody<typeof main>;
31
31
  export declare const $lxm: "com.atproto.repo.deleteRecord", $params: l.ParamsSchema<{}>, $input: l.Payload<"application/json", l.ObjectSchema<{
32
- readonly repo: l.StringSchema<{
32
+ repo: l.StringSchema<{
33
33
  readonly format: "at-identifier";
34
34
  }>;
35
- readonly collection: l.StringSchema<{
35
+ collection: l.StringSchema<{
36
36
  readonly format: "nsid";
37
37
  }>;
38
- readonly rkey: l.StringSchema<{
38
+ rkey: l.StringSchema<{
39
39
  readonly format: "record-key";
40
40
  }>;
41
- readonly swapRecord: l.OptionalSchema<l.StringSchema<{
41
+ swapRecord: l.OptionalSchema<l.StringSchema<{
42
42
  readonly format: "cid";
43
43
  }>>;
44
- readonly swapCommit: l.OptionalSchema<l.StringSchema<{
44
+ swapCommit: l.OptionalSchema<l.StringSchema<{
45
45
  readonly format: "cid";
46
46
  }>>;
47
47
  }>>, $output: l.Payload<"application/json", l.ObjectSchema<{
48
- readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
48
+ commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
49
49
  }>>;
50
50
  //# sourceMappingURL=deleteRecord.defs.d.ts.map
@@ -16,13 +16,13 @@ declare const main: l.Query<"com.atproto.repo.getRecord", l.ParamsSchema<{
16
16
  readonly format: "cid";
17
17
  }>>;
18
18
  }>, l.Payload<"application/json", l.ObjectSchema<{
19
- readonly uri: l.StringSchema<{
19
+ uri: l.StringSchema<{
20
20
  readonly format: "at-uri";
21
21
  }>;
22
- readonly cid: l.OptionalSchema<l.StringSchema<{
22
+ cid: l.OptionalSchema<l.StringSchema<{
23
23
  readonly format: "cid";
24
24
  }>>;
25
- readonly value: l.UnknownObjectSchema;
25
+ value: l.UnknownObjectSchema;
26
26
  }>>, readonly ["RecordNotFound"]>;
27
27
  export { main };
28
28
  export type Params = l.InferMethodParams<typeof main>;
@@ -42,12 +42,12 @@ export declare const $lxm: "com.atproto.repo.getRecord", $params: l.ParamsSchema
42
42
  readonly format: "cid";
43
43
  }>>;
44
44
  }>, $output: l.Payload<"application/json", l.ObjectSchema<{
45
- readonly uri: l.StringSchema<{
45
+ uri: l.StringSchema<{
46
46
  readonly format: "at-uri";
47
47
  }>;
48
- readonly cid: l.OptionalSchema<l.StringSchema<{
48
+ cid: l.OptionalSchema<l.StringSchema<{
49
49
  readonly format: "cid";
50
50
  }>>;
51
- readonly value: l.UnknownObjectSchema;
51
+ value: l.UnknownObjectSchema;
52
52
  }>>;
53
53
  //# sourceMappingURL=getRecord.defs.d.ts.map
@@ -10,11 +10,11 @@ declare const main: l.Query<"com.atproto.repo.listRecords", l.ParamsSchema<{
10
10
  readonly format: "nsid";
11
11
  }>;
12
12
  readonly limit: l.OptionalSchema<l.WithDefaultSchema<l.IntegerSchema>>;
13
- readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
13
+ readonly cursor: l.OptionalSchema<l.StringSchema<l.StringSchemaOptions>>;
14
14
  readonly reverse: l.OptionalSchema<l.BooleanSchema>;
15
15
  }>, l.Payload<"application/json", l.ObjectSchema<{
16
- readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
17
- readonly records: l.ArraySchema<l.RefSchema<l.Validator<Record$0, Record$0>>>;
16
+ cursor: l.OptionalSchema<l.StringSchema<{}>>;
17
+ records: l.ArraySchema<l.RefSchema<l.Validator<Record$0, Record$0>>>;
18
18
  }>>, undefined>;
19
19
  export { main };
20
20
  export type Params = l.InferMethodParams<typeof main>;
@@ -28,11 +28,11 @@ export declare const $lxm: "com.atproto.repo.listRecords", $params: l.ParamsSche
28
28
  readonly format: "nsid";
29
29
  }>;
30
30
  readonly limit: l.OptionalSchema<l.WithDefaultSchema<l.IntegerSchema>>;
31
- readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
31
+ readonly cursor: l.OptionalSchema<l.StringSchema<l.StringSchemaOptions>>;
32
32
  readonly reverse: l.OptionalSchema<l.BooleanSchema>;
33
33
  }>, $output: l.Payload<"application/json", l.ObjectSchema<{
34
- readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
35
- readonly records: l.ArraySchema<l.RefSchema<l.Validator<Record$0, Record$0>>>;
34
+ cursor: l.OptionalSchema<l.StringSchema<{}>>;
35
+ records: l.ArraySchema<l.RefSchema<l.Validator<Record$0, Record$0>>>;
36
36
  }>>;
37
37
  type Record$0 = {
38
38
  $type?: 'com.atproto.repo.listRecords#record';
@@ -4,33 +4,33 @@ declare const $nsid = "com.atproto.repo.putRecord";
4
4
  export { $nsid };
5
5
  /** Write a repository record, creating or updating it as needed. Requires auth, implemented by PDS. */
6
6
  declare const main: l.Procedure<"com.atproto.repo.putRecord", l.ParamsSchema<{}>, l.Payload<"application/json", l.ObjectSchema<{
7
- readonly repo: l.StringSchema<{
7
+ repo: l.StringSchema<{
8
8
  readonly format: "at-identifier";
9
9
  }>;
10
- readonly collection: l.StringSchema<{
10
+ collection: l.StringSchema<{
11
11
  readonly format: "nsid";
12
12
  }>;
13
- readonly rkey: l.StringSchema<{
13
+ rkey: l.StringSchema<{
14
14
  readonly format: "record-key";
15
15
  readonly maxLength: 512;
16
16
  }>;
17
- readonly validate: l.OptionalSchema<l.BooleanSchema>;
18
- readonly record: l.UnknownObjectSchema;
19
- readonly swapRecord: l.OptionalSchema<l.NullableSchema<l.StringSchema<{
17
+ validate: l.OptionalSchema<l.BooleanSchema>;
18
+ record: l.UnknownObjectSchema;
19
+ swapRecord: l.OptionalSchema<l.NullableSchema<l.StringSchema<{
20
20
  readonly format: "cid";
21
21
  }>>>;
22
- readonly swapCommit: l.OptionalSchema<l.StringSchema<{
22
+ swapCommit: l.OptionalSchema<l.StringSchema<{
23
23
  readonly format: "cid";
24
24
  }>>;
25
25
  }>>, l.Payload<"application/json", l.ObjectSchema<{
26
- readonly uri: l.StringSchema<{
26
+ uri: l.StringSchema<{
27
27
  readonly format: "at-uri";
28
28
  }>;
29
- readonly cid: l.StringSchema<{
29
+ cid: l.StringSchema<{
30
30
  readonly format: "cid";
31
31
  }>;
32
- readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
33
- readonly validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
32
+ commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
33
+ validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
34
34
  }>>, readonly ["InvalidSwap"]>;
35
35
  export { main };
36
36
  export type Params = l.InferMethodParams<typeof main>;
@@ -39,32 +39,32 @@ export type InputBody = l.InferMethodInputBody<typeof main>;
39
39
  export type Output = l.InferMethodOutput<typeof main>;
40
40
  export type OutputBody = l.InferMethodOutputBody<typeof main>;
41
41
  export declare const $lxm: "com.atproto.repo.putRecord", $params: l.ParamsSchema<{}>, $input: l.Payload<"application/json", l.ObjectSchema<{
42
- readonly repo: l.StringSchema<{
42
+ repo: l.StringSchema<{
43
43
  readonly format: "at-identifier";
44
44
  }>;
45
- readonly collection: l.StringSchema<{
45
+ collection: l.StringSchema<{
46
46
  readonly format: "nsid";
47
47
  }>;
48
- readonly rkey: l.StringSchema<{
48
+ rkey: l.StringSchema<{
49
49
  readonly format: "record-key";
50
50
  readonly maxLength: 512;
51
51
  }>;
52
- readonly validate: l.OptionalSchema<l.BooleanSchema>;
53
- readonly record: l.UnknownObjectSchema;
54
- readonly swapRecord: l.OptionalSchema<l.NullableSchema<l.StringSchema<{
52
+ validate: l.OptionalSchema<l.BooleanSchema>;
53
+ record: l.UnknownObjectSchema;
54
+ swapRecord: l.OptionalSchema<l.NullableSchema<l.StringSchema<{
55
55
  readonly format: "cid";
56
56
  }>>>;
57
- readonly swapCommit: l.OptionalSchema<l.StringSchema<{
57
+ swapCommit: l.OptionalSchema<l.StringSchema<{
58
58
  readonly format: "cid";
59
59
  }>>;
60
60
  }>>, $output: l.Payload<"application/json", l.ObjectSchema<{
61
- readonly uri: l.StringSchema<{
61
+ uri: l.StringSchema<{
62
62
  readonly format: "at-uri";
63
63
  }>;
64
- readonly cid: l.StringSchema<{
64
+ cid: l.StringSchema<{
65
65
  readonly format: "cid";
66
66
  }>;
67
- readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
68
- readonly validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
67
+ commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
68
+ validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
69
69
  }>>;
70
70
  //# sourceMappingURL=putRecord.defs.d.ts.map
@@ -3,7 +3,7 @@ declare const $nsid = "com.atproto.repo.uploadBlob";
3
3
  export { $nsid };
4
4
  /** Upload a new blob, to be referenced from a repository record. The blob will be deleted if it is not referenced within a time window (eg, minutes). Blob restrictions (mimetype, size, etc) are enforced when the reference is created. Requires auth, implemented by PDS. */
5
5
  declare const main: l.Procedure<"com.atproto.repo.uploadBlob", l.ParamsSchema<{}>, l.Payload<"*/*", undefined>, l.Payload<"application/json", l.ObjectSchema<{
6
- readonly blob: l.BlobSchema<{
6
+ blob: l.BlobSchema<{
7
7
  allowLegacy: false;
8
8
  }>;
9
9
  }>>, undefined>;
@@ -14,7 +14,7 @@ export type InputBody = l.InferMethodInputBody<typeof main>;
14
14
  export type Output = l.InferMethodOutput<typeof main>;
15
15
  export type OutputBody = l.InferMethodOutputBody<typeof main>;
16
16
  export declare const $lxm: "com.atproto.repo.uploadBlob", $params: l.ParamsSchema<{}>, $input: l.Payload<"*/*", undefined>, $output: l.Payload<"application/json", l.ObjectSchema<{
17
- readonly blob: l.BlobSchema<{
17
+ blob: l.BlobSchema<{
18
18
  allowLegacy: false;
19
19
  }>;
20
20
  }>>;
@@ -1,13 +1,12 @@
1
- import { InferMethodOutputBody, InferMethodOutputEncoding, Procedure, Query, ResultSuccess } from '@atproto/lex-schema';
2
- import { XrpcPayload } from './util.js';
3
- export type XrpcResponseBody<M extends Procedure | Query> = InferMethodOutputBody<M, Uint8Array>;
4
- export type XrpcResponsePayload<M extends Procedure | Query> = InferMethodOutputEncoding<M> extends infer E extends string ? XrpcPayload<XrpcResponseBody<M>, E> : null;
1
+ import { InferMethodOutputEncoding, Procedure, Query, ResultSuccess } from '@atproto/lex-schema';
2
+ import { XrpcResponseBody, XrpcResponsePayload } from './util.js';
3
+ export type { XrpcResponseBody, XrpcResponsePayload };
5
4
  /**
6
5
  * Small container for XRPC response data.
7
6
  *
8
7
  * @implements {ResultSuccess<XrpcResponse<M>>} for convenience in result handling contexts.
9
8
  */
10
- export declare class XrpcResponse<const M extends Procedure | Query> implements ResultSuccess<XrpcResponse<M>> {
9
+ export declare class XrpcResponse<M extends Procedure | Query> implements ResultSuccess<XrpcResponse<M>> {
11
10
  readonly method: M;
12
11
  readonly status: number;
13
12
  readonly headers: Headers;
@@ -22,12 +21,24 @@ export declare class XrpcResponse<const M extends Procedure | Query> implements
22
21
  * in binary form {@link Uint8Array} (`false`).
23
22
  */
24
23
  get isParsed(): boolean;
24
+ /**
25
+ * The Content-Type encoding of the response (e.g., 'application/json').
26
+ * Returns `undefined` if the response has no body.
27
+ */
25
28
  get encoding(): InferMethodOutputEncoding<M>;
29
+ /**
30
+ * The parsed response body.
31
+ *
32
+ * For 'application/json' responses, this is the parsed and validated LexValue.
33
+ * For binary responses, this is a Uint8Array.
34
+ * Returns `undefined` if the response has no body.
35
+ */
26
36
  get body(): XrpcResponseBody<M>;
27
37
  /**
28
38
  * @throws {XrpcResponseError} in case of (valid) XRPC error responses. Use
29
39
  * {@link XrpcResponseError.matchesSchema} to narrow the error type based on
30
- * the method's declared error schema.
40
+ * the method's declared error schema. This can be narrowed further as a
41
+ * {@link XrpcAuthenticationError} if the error is an authentication error.
31
42
  * @throws {XrpcUpstreamError} when the response is not a valid XRPC
32
43
  * response, or if the response does not conform to the method's schema.
33
44
  */
@@ -1 +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,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IACtD,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAEtC,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IACzD,yBAAyB,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,GACvD,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GACnC,IAAI,CAAA;AAEV;;;;GAIG;AACH,qBAAa,YAAY,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,CACzD,YAAW,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAWvC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAZ1C,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,mBAAmB,CAAC,CAAC,CAAC;IAG1C;;;OAGG;IACH,IAAI,QAAQ,YAEX;IAED,IAAI,QAAQ,IACuB,yBAAyB,CAAC,CAAC,CAAC,CAC9D;IAED,IAAI,IAAI,IACuB,gBAAgB,CAAC,CAAC,CAAC,CACjD;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,YAAY,CAAC,CAAC,CAAC,CAAC;CA0F5B"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AACA,OAAO,EACL,yBAAyB,EACzB,SAAS,EACT,KAAK,EACL,aAAa,EACd,MAAM,qBAAqB,CAAA;AAO5B,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAKjE,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,CAAA;AAErD;;;;GAIG;AACH,qBAAa,YAAY,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,CACnD,YAAW,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAWvC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAZ1C,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,mBAAmB,CAAC,CAAC,CAAC;IAG1C;;;OAGG;IACH,IAAI,QAAQ,YAEX;IAED;;;OAGG;IACH,IAAI,QAAQ,IACuB,yBAAyB,CAAC,CAAC,CAAC,CAC9D;IAED;;;;;;OAMG;IACH,IAAI,IAAI,IACuB,gBAAgB,CAAC,CAAC,CAAC,CACjD;IAED;;;;;;;OAOG;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,YAAY,CAAC,CAAC,CAAC,CAAC;CAoG5B"}
package/dist/response.js CHANGED
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.XrpcResponse = void 0;
4
4
  const lex_json_1 = require("@atproto/lex-json");
5
5
  const errors_js_1 = require("./errors.js");
6
+ const CONTENT_TYPE_BINARY = 'application/octet-stream';
7
+ const CONTENT_TYPE_JSON = 'application/json';
6
8
  /**
7
9
  * Small container for XRPC response data.
8
10
  *
@@ -30,18 +32,30 @@ class XrpcResponse {
30
32
  * in binary form {@link Uint8Array} (`false`).
31
33
  */
32
34
  get isParsed() {
33
- return this.encoding === 'application/json' && shouldParse(this.method);
35
+ return this.method.output.encoding === CONTENT_TYPE_JSON;
34
36
  }
37
+ /**
38
+ * The Content-Type encoding of the response (e.g., 'application/json').
39
+ * Returns `undefined` if the response has no body.
40
+ */
35
41
  get encoding() {
36
42
  return this.payload?.encoding;
37
43
  }
44
+ /**
45
+ * The parsed response body.
46
+ *
47
+ * For 'application/json' responses, this is the parsed and validated LexValue.
48
+ * For binary responses, this is a Uint8Array.
49
+ * Returns `undefined` if the response has no body.
50
+ */
38
51
  get body() {
39
52
  return this.payload?.body;
40
53
  }
41
54
  /**
42
55
  * @throws {XrpcResponseError} in case of (valid) XRPC error responses. Use
43
56
  * {@link XrpcResponseError.matchesSchema} to narrow the error type based on
44
- * the method's declared error schema.
57
+ * the method's declared error schema. This can be narrowed further as a
58
+ * {@link XrpcAuthenticationError} if the error is an authentication error.
45
59
  * @throws {XrpcUpstreamError} when the response is not a valid XRPC
46
60
  * response, or if the response does not conform to the method's schema.
47
61
  */
@@ -52,40 +66,47 @@ class XrpcResponse {
52
66
  // @NOTE redirect is set to 'follow', so we shouldn't get 3xx responses here
53
67
  if (response.status < 200 || response.status >= 300) {
54
68
  // Always parse json for error responses
55
- const payload = await readPayload(response, { parse: true });
69
+ const payload = await readPayload(response, { parse: true }).catch((cause) => {
70
+ throw new errors_js_1.XrpcUpstreamError(method, response, null, 'Unable to parse response payload', { cause });
71
+ });
72
+ // Properly formatted XRPC error response ?
56
73
  if (response.status >= 400 && (0, errors_js_1.isXrpcErrorPayload)(payload)) {
57
- throw new errors_js_1.XrpcResponseError(method, response.status, response.headers, payload);
74
+ throw response.status === 401
75
+ ? new errors_js_1.XrpcAuthenticationError(method, response, payload)
76
+ : new errors_js_1.XrpcResponseError(method, response, payload);
58
77
  }
59
- if (response.status >= 500) {
60
- throw new errors_js_1.XrpcUpstreamError('UpstreamFailure', `Upstream server encountered an error`, response, payload);
61
- }
62
- throw new errors_js_1.XrpcUpstreamError('InvalidResponse', response.status >= 400
63
- ? `Upstream server returned an invalid response payload`
64
- : `Upstream server returned an invalid status code`, response, payload);
78
+ // Invalid XRPC response (we probably did not hit an XRPC implementation)
79
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, response.status >= 500
80
+ ? 'Upstream server encountered an error'
81
+ : response.status >= 400
82
+ ? 'Invalid response payload'
83
+ : 'Invalid response status code');
65
84
  }
66
85
  // Only parse json if the schema expects it
67
86
  const payload = await readPayload(response, {
68
- parse: shouldParse(method),
87
+ parse: method.output.encoding === CONTENT_TYPE_JSON,
88
+ }).catch((cause) => {
89
+ throw new errors_js_1.XrpcUpstreamError(method, response, null, 'Unable to parse response payload', { cause });
69
90
  });
70
91
  // Response is successful (2xx). Validate payload (data and encoding) against schema.
71
92
  if (method.output.encoding == null) {
72
93
  // Schema expects no payload
73
94
  if (payload) {
74
- throw new errors_js_1.XrpcUpstreamError('InvalidResponse', `Expected response with no body, got ${payload.encoding}`, response, payload);
95
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, `Expected response with no body, got ${payload.encoding}`);
75
96
  }
76
97
  }
77
98
  else {
78
99
  // Schema expects a payload
79
100
  if (!payload || !method.output.matchesEncoding(payload.encoding)) {
80
- throw new errors_js_1.XrpcUpstreamError('InvalidResponse', payload
101
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, payload
81
102
  ? `Expected ${method.output.encoding} response, got ${payload.encoding}`
82
- : `Expected non-empty response with content-type ${method.output.encoding}`, response, payload);
103
+ : `Expected non-empty response with content-type ${method.output.encoding}`);
83
104
  }
84
105
  // Assert valid response body.
85
106
  if (method.output.schema && options?.validateResponse !== false) {
86
107
  const result = method.output.schema.safeParse(payload.body);
87
108
  if (!result.success) {
88
- throw new errors_js_1.XrpcUpstreamError('InvalidResponse', `Response validation failed: ${result.reason.message}`, response, payload, { cause: result.reason });
109
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, `Response validation failed: ${result.reason.message}`, { cause: result.reason });
89
110
  }
90
111
  }
91
112
  }
@@ -93,9 +114,6 @@ class XrpcResponse {
93
114
  }
94
115
  }
95
116
  exports.XrpcResponse = XrpcResponse;
96
- function shouldParse(method) {
97
- return method.output.encoding === 'application/json';
98
- }
99
117
  /**
100
118
  * @note this function always consumes the response body
101
119
  */
@@ -109,33 +127,28 @@ async function readPayload(response, options) {
109
127
  .toLowerCase();
110
128
  // Response content-type is undefined
111
129
  if (!encoding) {
112
- // If the body is empty, return null (= no payload)
130
+ // If the body is empty, return undefined (= no payload)
113
131
  const body = await response.arrayBuffer();
114
132
  if (body.byteLength === 0)
115
- return null;
133
+ return undefined;
116
134
  // If we got data despite no content-type, treat it as binary
117
135
  return {
118
- encoding: 'application/octet-stream',
136
+ encoding: CONTENT_TYPE_BINARY,
119
137
  body: new Uint8Array(body),
120
138
  };
121
139
  }
122
- if (options?.parse && encoding === 'application/json') {
140
+ if (options?.parse && encoding === CONTENT_TYPE_JSON) {
123
141
  // @NOTE It might be worth returning the raw bytes here (Uint8Array) and
124
142
  // perform the lex parsing using cborg/json, allowing to do
125
143
  // bytes->LexValue in one step instead of bytes->text->JSON->LexValue.
126
144
  // This would require adding encode/decode utilities to lex-json (similar
127
145
  // to @ipld/dag-json)
128
146
  const text = await response.text();
129
- try {
130
- // @NOTE Using `lexParse(text)` (instead of `jsonToLex(json)`) here as
131
- // using a reviver function during JSON.parse should be faster than
132
- // parsing to JSON then converting to Lex (?)
133
- // @TODO verify statement above
134
- return { encoding, body: (0, lex_json_1.lexParse)(text) };
135
- }
136
- catch (cause) {
137
- throw new errors_js_1.XrpcUpstreamError('InvalidResponse', 'Invalid JSON response body', response, null, { cause });
138
- }
147
+ // @NOTE Using `lexParse(text)` (instead of `jsonToLex(json)`) here as
148
+ // using a reviver function during JSON.parse should be faster than
149
+ // parsing to JSON then converting to Lex (?)
150
+ // @TODO verify statement above
151
+ return { encoding, body: (0, lex_json_1.lexParse)(text) };
139
152
  }
140
153
  return { encoding, body: new Uint8Array(await response.arrayBuffer()) };
141
154
  }