@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.
- package/CHANGELOG.md +32 -0
- package/dist/agent.d.ts +72 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +46 -1
- package/dist/agent.js.map +1 -1
- package/dist/client.d.ts +442 -46
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +145 -1
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +202 -48
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +208 -65
- package/dist/errors.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts +20 -20
- package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts +12 -12
- package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts +6 -6
- package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts +6 -6
- package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts +22 -22
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts +2 -2
- package/dist/response.d.ts +17 -6
- package/dist/response.d.ts.map +1 -1
- package/dist/response.js +45 -32
- package/dist/response.js.map +1 -1
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts +40 -5
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +22 -0
- package/dist/util.js.map +1 -1
- package/dist/www-authenticate.d.ts +35 -0
- package/dist/www-authenticate.d.ts.map +1 -0
- package/dist/www-authenticate.js +57 -0
- package/dist/www-authenticate.js.map +1 -0
- package/dist/xrpc.d.ts +82 -10
- package/dist/xrpc.d.ts.map +1 -1
- package/dist/xrpc.js +15 -28
- package/dist/xrpc.js.map +1 -1
- package/package.json +7 -7
- package/src/agent.ts +101 -1
- package/src/client.ts +428 -15
- package/src/errors.ts +308 -120
- package/src/response.ts +68 -63
- package/src/types.ts +52 -0
- package/src/util.ts +50 -5
- package/src/www-authenticate.test.ts +227 -0
- package/src/www-authenticate.ts +101 -0
- package/src/xrpc.ts +100 -53
package/dist/errors.js.map
CHANGED
|
@@ -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
|
-
|
|
7
|
+
repo: l.StringSchema<{
|
|
8
8
|
readonly format: "at-identifier";
|
|
9
9
|
}>;
|
|
10
|
-
|
|
10
|
+
collection: l.StringSchema<{
|
|
11
11
|
readonly format: "nsid";
|
|
12
12
|
}>;
|
|
13
|
-
|
|
13
|
+
rkey: l.OptionalSchema<l.StringSchema<{
|
|
14
14
|
readonly format: "record-key";
|
|
15
15
|
readonly maxLength: 512;
|
|
16
16
|
}>>;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
23
|
+
uri: l.StringSchema<{
|
|
24
24
|
readonly format: "at-uri";
|
|
25
25
|
}>;
|
|
26
|
-
|
|
26
|
+
cid: l.StringSchema<{
|
|
27
27
|
readonly format: "cid";
|
|
28
28
|
}>;
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
39
|
+
repo: l.StringSchema<{
|
|
40
40
|
readonly format: "at-identifier";
|
|
41
41
|
}>;
|
|
42
|
-
|
|
42
|
+
collection: l.StringSchema<{
|
|
43
43
|
readonly format: "nsid";
|
|
44
44
|
}>;
|
|
45
|
-
|
|
45
|
+
rkey: l.OptionalSchema<l.StringSchema<{
|
|
46
46
|
readonly format: "record-key";
|
|
47
47
|
readonly maxLength: 512;
|
|
48
48
|
}>>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
55
|
+
uri: l.StringSchema<{
|
|
56
56
|
readonly format: "at-uri";
|
|
57
57
|
}>;
|
|
58
|
-
|
|
58
|
+
cid: l.StringSchema<{
|
|
59
59
|
readonly format: "cid";
|
|
60
60
|
}>;
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
7
|
+
repo: l.StringSchema<{
|
|
8
8
|
readonly format: "at-identifier";
|
|
9
9
|
}>;
|
|
10
|
-
|
|
10
|
+
collection: l.StringSchema<{
|
|
11
11
|
readonly format: "nsid";
|
|
12
12
|
}>;
|
|
13
|
-
|
|
13
|
+
rkey: l.StringSchema<{
|
|
14
14
|
readonly format: "record-key";
|
|
15
15
|
}>;
|
|
16
|
-
|
|
16
|
+
swapRecord: l.OptionalSchema<l.StringSchema<{
|
|
17
17
|
readonly format: "cid";
|
|
18
18
|
}>>;
|
|
19
|
-
|
|
19
|
+
swapCommit: l.OptionalSchema<l.StringSchema<{
|
|
20
20
|
readonly format: "cid";
|
|
21
21
|
}>>;
|
|
22
22
|
}>>, l.Payload<"application/json", l.ObjectSchema<{
|
|
23
|
-
|
|
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
|
-
|
|
32
|
+
repo: l.StringSchema<{
|
|
33
33
|
readonly format: "at-identifier";
|
|
34
34
|
}>;
|
|
35
|
-
|
|
35
|
+
collection: l.StringSchema<{
|
|
36
36
|
readonly format: "nsid";
|
|
37
37
|
}>;
|
|
38
|
-
|
|
38
|
+
rkey: l.StringSchema<{
|
|
39
39
|
readonly format: "record-key";
|
|
40
40
|
}>;
|
|
41
|
-
|
|
41
|
+
swapRecord: l.OptionalSchema<l.StringSchema<{
|
|
42
42
|
readonly format: "cid";
|
|
43
43
|
}>>;
|
|
44
|
-
|
|
44
|
+
swapCommit: l.OptionalSchema<l.StringSchema<{
|
|
45
45
|
readonly format: "cid";
|
|
46
46
|
}>>;
|
|
47
47
|
}>>, $output: l.Payload<"application/json", l.ObjectSchema<{
|
|
48
|
-
|
|
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
|
-
|
|
19
|
+
uri: l.StringSchema<{
|
|
20
20
|
readonly format: "at-uri";
|
|
21
21
|
}>;
|
|
22
|
-
|
|
22
|
+
cid: l.OptionalSchema<l.StringSchema<{
|
|
23
23
|
readonly format: "cid";
|
|
24
24
|
}>>;
|
|
25
|
-
|
|
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
|
-
|
|
45
|
+
uri: l.StringSchema<{
|
|
46
46
|
readonly format: "at-uri";
|
|
47
47
|
}>;
|
|
48
|
-
|
|
48
|
+
cid: l.OptionalSchema<l.StringSchema<{
|
|
49
49
|
readonly format: "cid";
|
|
50
50
|
}>>;
|
|
51
|
-
|
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
35
|
-
|
|
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
|
-
|
|
7
|
+
repo: l.StringSchema<{
|
|
8
8
|
readonly format: "at-identifier";
|
|
9
9
|
}>;
|
|
10
|
-
|
|
10
|
+
collection: l.StringSchema<{
|
|
11
11
|
readonly format: "nsid";
|
|
12
12
|
}>;
|
|
13
|
-
|
|
13
|
+
rkey: l.StringSchema<{
|
|
14
14
|
readonly format: "record-key";
|
|
15
15
|
readonly maxLength: 512;
|
|
16
16
|
}>;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
22
|
+
swapCommit: l.OptionalSchema<l.StringSchema<{
|
|
23
23
|
readonly format: "cid";
|
|
24
24
|
}>>;
|
|
25
25
|
}>>, l.Payload<"application/json", l.ObjectSchema<{
|
|
26
|
-
|
|
26
|
+
uri: l.StringSchema<{
|
|
27
27
|
readonly format: "at-uri";
|
|
28
28
|
}>;
|
|
29
|
-
|
|
29
|
+
cid: l.StringSchema<{
|
|
30
30
|
readonly format: "cid";
|
|
31
31
|
}>;
|
|
32
|
-
|
|
33
|
-
|
|
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
|
-
|
|
42
|
+
repo: l.StringSchema<{
|
|
43
43
|
readonly format: "at-identifier";
|
|
44
44
|
}>;
|
|
45
|
-
|
|
45
|
+
collection: l.StringSchema<{
|
|
46
46
|
readonly format: "nsid";
|
|
47
47
|
}>;
|
|
48
|
-
|
|
48
|
+
rkey: l.StringSchema<{
|
|
49
49
|
readonly format: "record-key";
|
|
50
50
|
readonly maxLength: 512;
|
|
51
51
|
}>;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
57
|
+
swapCommit: l.OptionalSchema<l.StringSchema<{
|
|
58
58
|
readonly format: "cid";
|
|
59
59
|
}>>;
|
|
60
60
|
}>>, $output: l.Payload<"application/json", l.ObjectSchema<{
|
|
61
|
-
|
|
61
|
+
uri: l.StringSchema<{
|
|
62
62
|
readonly format: "at-uri";
|
|
63
63
|
}>;
|
|
64
|
-
|
|
64
|
+
cid: l.StringSchema<{
|
|
65
65
|
readonly format: "cid";
|
|
66
66
|
}>;
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
|
|
17
|
+
blob: l.BlobSchema<{
|
|
18
18
|
allowLegacy: false;
|
|
19
19
|
}>;
|
|
20
20
|
}>>;
|
package/dist/response.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export type XrpcResponseBody
|
|
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<
|
|
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
|
*/
|
package/dist/response.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AACA,OAAO,EACL,
|
|
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 ===
|
|
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
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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:
|
|
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(
|
|
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(
|
|
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}
|
|
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(
|
|
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
|
|
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
|
|
133
|
+
return undefined;
|
|
116
134
|
// If we got data despite no content-type, treat it as binary
|
|
117
135
|
return {
|
|
118
|
-
encoding:
|
|
136
|
+
encoding: CONTENT_TYPE_BINARY,
|
|
119
137
|
body: new Uint8Array(body),
|
|
120
138
|
};
|
|
121
139
|
}
|
|
122
|
-
if (options?.parse && encoding ===
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
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
|
}
|