@atproto/lex-client 0.0.9 → 0.0.10

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 (42) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/client.d.ts +56 -39
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/client.js +2 -6
  6. package/dist/client.js.map +1 -1
  7. package/dist/errors.d.ts +15 -15
  8. package/dist/errors.d.ts.map +1 -1
  9. package/dist/errors.js +17 -17
  10. package/dist/errors.js.map +1 -1
  11. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts +20 -10
  12. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts.map +1 -1
  13. package/dist/lexicons/com/atproto/repo/defs.defs.d.ts +1 -1
  14. package/dist/lexicons/com/atproto/repo/defs.defs.d.ts.map +1 -1
  15. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts +14 -6
  16. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts.map +1 -1
  17. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts +12 -4
  18. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts.map +1 -1
  19. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts +11 -11
  20. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts.map +1 -1
  21. package/dist/lexicons/com/atproto/repo/listRecords.defs.js +2 -1
  22. package/dist/lexicons/com/atproto/repo/listRecords.defs.js.map +1 -1
  23. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts +18 -10
  24. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts.map +1 -1
  25. package/dist/response.d.ts +12 -12
  26. package/dist/response.d.ts.map +1 -1
  27. package/dist/response.js +17 -19
  28. package/dist/response.js.map +1 -1
  29. package/dist/util.d.ts +1 -1
  30. package/dist/util.d.ts.map +1 -1
  31. package/dist/util.js.map +1 -1
  32. package/dist/xrpc.d.ts +17 -16
  33. package/dist/xrpc.d.ts.map +1 -1
  34. package/dist/xrpc.js +12 -16
  35. package/dist/xrpc.js.map +1 -1
  36. package/package.json +6 -6
  37. package/src/client.ts +33 -32
  38. package/src/errors.ts +26 -28
  39. package/src/lexicons/com/atproto/repo/listRecords.defs.ts +4 -1
  40. package/src/response.ts +28 -30
  41. package/src/util.ts +1 -1
  42. package/src/xrpc.ts +58 -68
@@ -1 +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"]}
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 XrpcResponseError,\n XrpcUpstreamError,\n isXrpcErrorPayload,\n} from './errors.js'\nimport { XrpcPayload } from './util.js'\n\nexport type XrpcResponseBody<M extends Procedure | Query> =\n InferMethodOutputBody<M, Uint8Array>\n\nexport type XrpcResponsePayload<M extends Procedure | Query> =\n InferMethodOutputEncoding<M> extends infer E extends string\n ? XrpcPayload<XrpcResponseBody<M>, E>\n : null\n\n/**\n * Small container for XRPC response data.\n *\n * @implements {ResultSuccess<XrpcResponse<M>>} for convenience in result handling contexts.\n */\nexport class XrpcResponse<const M extends Procedure | Query>\n implements ResultSuccess<XrpcResponse<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: XrpcResponsePayload<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 XrpcResponseBody<M>\n }\n\n /**\n * @throws {XrpcResponseError} in case of (valid) XRPC error responses. Use\n * {@link XrpcResponseError.matchesSchema} to narrow the error type based on\n * the method's declared error schema.\n * @throws {XrpcUpstreamError} 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<XrpcResponse<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 && isXrpcErrorPayload(payload)) {\n throw new XrpcResponseError(\n method,\n response.status,\n response.headers,\n payload,\n )\n }\n\n if (response.status >= 500) {\n throw new XrpcUpstreamError(\n 'UpstreamFailure',\n `Upstream server encountered an error`,\n response,\n payload,\n )\n }\n\n throw new XrpcUpstreamError(\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 XrpcUpstreamError(\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 XrpcUpstreamError(\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\n if (!result.success) {\n throw new XrpcUpstreamError(\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 XrpcResponse<M>(\n method,\n response.status,\n response.headers,\n payload as XrpcResponsePayload<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<XrpcPayload | 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 XrpcUpstreamError(\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/util.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { DidString } from '@atproto/lex-schema';
2
- export type Payload<B = unknown, E extends string = string> = {
2
+ export type XrpcPayload<B = unknown, E extends string = string> = {
3
3
  body: B;
4
4
  encoding: E;
5
5
  };
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAC5D,IAAI,EAAE,CAAC,CAAA;IACP,QAAQ,EAAE,CAAC,CAAA;CACZ,CAAA;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAexD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,CAAC,GACP,KAAK,IAAI,OAAO,SAAS,CAAC,GACzB,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,GAC1B,OAAO,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAIjC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,GAAG,SAAS,IAAI,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;CAC/B,GAAG,OAAO,CAiBV;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAC9B,cAAc,CAAC,UAAU,CAAC,CAwB5B"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAE/C,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;IAChE,IAAI,EAAE,CAAC,CAAA;IACP,QAAQ,EAAE,CAAC,CAAA;CACZ,CAAA;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAexD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAC/B,KAAK,EAAE,CAAC,GACP,KAAK,IAAI,OAAO,SAAS,CAAC,GACzB,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,GAC1B,OAAO,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAIjC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAC3C,OAAO,CAAC,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,GAAG,SAAS,IAAI,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAA;CAC/B,GAAG,OAAO,CAiBV;AAED,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,aAAa,CAAC,UAAU,CAAC,GAC9B,cAAc,CAAC,UAAU,CAAC,CAwB5B"}
package/dist/util.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAOA,gCAeC;AAED,0CAQC;AAED,kDAqBC;AAED,4CA0BC;AA5ED,SAAgB,UAAU,CAAC,KAAc;IACvC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,CAAA;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,IAAI,CAAA;IAEpE,yEAAyE;IACzE,qCAAqC;IACrC,4GAA4G;IAE5G,MAAM,GAAG,GAAI,KAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC9C,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACrC,OAAO,QAAQ,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,CAAA;IAChE,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAgB,eAAe,CAC7B,KAAQ;IAIR,OAAO,CACL,KAAK,IAAI,IAAI,IAAI,OAAQ,KAAa,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,UAAU,CAC5E,CAAA;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAInC;IACC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAE7C,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CACT,yBAAyB,EACzB,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC;aAClE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CACd,CAAA;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAgB,gBAAgB,CAC9B,IAA+B;IAE/B,qDAAqD;IACrD,IAAI,MAAM,IAAI,cAAc,IAAI,OAAO,cAAc,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,QAA+C,CAAA;IACnD,OAAO,IAAI,cAAc,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,CAAC;gBACH,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAA;gBACzC,MAAM,MAAM,GAAG,MAAM,QAAS,CAAC,IAAI,EAAE,CAAA;gBACrC,IAAI,MAAM,CAAC,IAAI;oBAAE,UAAU,CAAC,KAAK,EAAE,CAAA;;oBAC9B,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBACrB,QAAQ,GAAG,SAAS,CAAA;YACtB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,MAAM;YACV,MAAM,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAA;YAC1B,QAAQ,GAAG,SAAS,CAAA;QACtB,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { DidString } from '@atproto/lex-schema'\n\nexport type Payload<B = unknown, E extends string = string> = {\n body: B\n encoding: E\n}\n\nexport function isBlobLike(value: unknown): value is Blob {\n if (value == null) return false\n if (typeof value !== 'object') return false\n if (typeof Blob === 'function' && value instanceof Blob) return true\n\n // Support for Blobs provided by libraries that don't use the native Blob\n // (e.g. fetch-blob from node-fetch).\n // https://github.com/node-fetch/fetch-blob/blob/a1a182e5978811407bef4ea1632b517567dda01f/index.js#L233-L244\n\n const tag = (value as any)[Symbol.toStringTag]\n if (tag === 'Blob' || tag === 'File') {\n return 'stream' in value && typeof value.stream === 'function'\n }\n\n return false\n}\n\nexport function isAsyncIterable<T>(\n value: T,\n): value is unknown extends T\n ? T & AsyncIterable<unknown>\n : Extract<T, AsyncIterable<any>> {\n return (\n value != null && typeof (value as any)[Symbol.asyncIterator] === 'function'\n )\n}\n\nexport function buildAtprotoHeaders(options: {\n headers?: HeadersInit\n service?: `${DidString}#${string}`\n labelers?: Iterable<DidString>\n}): Headers {\n const headers = new Headers(options?.headers)\n\n if (options.service && !headers.has('atproto-proxy')) {\n headers.set('atproto-proxy', options.service)\n }\n\n if (options.labelers) {\n headers.set(\n 'atproto-accept-labelers',\n [...options.labelers, headers.get('atproto-accept-labelers')?.trim()]\n .filter(Boolean)\n .join(', '),\n )\n }\n\n return headers\n}\n\nexport function toReadableStream(\n data: AsyncIterable<Uint8Array>,\n): ReadableStream<Uint8Array> {\n // Use the native ReadableStream.from() if available.\n if ('from' in ReadableStream && typeof ReadableStream.from === 'function') {\n return ReadableStream.from(data)\n }\n\n let iterator: AsyncIterator<Uint8Array> | undefined\n return new ReadableStream({\n async pull(controller) {\n try {\n iterator ??= data[Symbol.asyncIterator]()\n const result = await iterator!.next()\n if (result.done) controller.close()\n else controller.enqueue(result.value)\n } catch (err) {\n controller.error(err)\n iterator = undefined\n }\n },\n async cancel() {\n await iterator?.return?.()\n iterator = undefined\n },\n })\n}\n"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;AAOA,gCAeC;AAED,0CAQC;AAED,kDAqBC;AAED,4CA0BC;AA5ED,SAAgB,UAAU,CAAC,KAAc;IACvC,IAAI,KAAK,IAAI,IAAI;QAAE,OAAO,KAAK,CAAA;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,IAAI,CAAA;IAEpE,yEAAyE;IACzE,qCAAqC;IACrC,4GAA4G;IAE5G,MAAM,GAAG,GAAI,KAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC9C,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;QACrC,OAAO,QAAQ,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,UAAU,CAAA;IAChE,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAgB,eAAe,CAC7B,KAAQ;IAIR,OAAO,CACL,KAAK,IAAI,IAAI,IAAI,OAAQ,KAAa,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,UAAU,CAC5E,CAAA;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,OAInC;IACC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAE7C,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CACT,yBAAyB,EACzB,CAAC,GAAG,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC;aAClE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CACd,CAAA;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAgB,gBAAgB,CAC9B,IAA+B;IAE/B,qDAAqD;IACrD,IAAI,MAAM,IAAI,cAAc,IAAI,OAAO,cAAc,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC1E,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,QAA+C,CAAA;IACnD,OAAO,IAAI,cAAc,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,UAAU;YACnB,IAAI,CAAC;gBACH,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAA;gBACzC,MAAM,MAAM,GAAG,MAAM,QAAS,CAAC,IAAI,EAAE,CAAA;gBACrC,IAAI,MAAM,CAAC,IAAI;oBAAE,UAAU,CAAC,KAAK,EAAE,CAAA;;oBAC9B,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACvC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBACrB,QAAQ,GAAG,SAAS,CAAA;YACtB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,MAAM;YACV,MAAM,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAA;YAC1B,QAAQ,GAAG,SAAS,CAAA;QACtB,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { DidString } from '@atproto/lex-schema'\n\nexport type XrpcPayload<B = unknown, E extends string = string> = {\n body: B\n encoding: E\n}\n\nexport function isBlobLike(value: unknown): value is Blob {\n if (value == null) return false\n if (typeof value !== 'object') return false\n if (typeof Blob === 'function' && value instanceof Blob) return true\n\n // Support for Blobs provided by libraries that don't use the native Blob\n // (e.g. fetch-blob from node-fetch).\n // https://github.com/node-fetch/fetch-blob/blob/a1a182e5978811407bef4ea1632b517567dda01f/index.js#L233-L244\n\n const tag = (value as any)[Symbol.toStringTag]\n if (tag === 'Blob' || tag === 'File') {\n return 'stream' in value && typeof value.stream === 'function'\n }\n\n return false\n}\n\nexport function isAsyncIterable<T>(\n value: T,\n): value is unknown extends T\n ? T & AsyncIterable<unknown>\n : Extract<T, AsyncIterable<any>> {\n return (\n value != null && typeof (value as any)[Symbol.asyncIterator] === 'function'\n )\n}\n\nexport function buildAtprotoHeaders(options: {\n headers?: HeadersInit\n service?: `${DidString}#${string}`\n labelers?: Iterable<DidString>\n}): Headers {\n const headers = new Headers(options?.headers)\n\n if (options.service && !headers.has('atproto-proxy')) {\n headers.set('atproto-proxy', options.service)\n }\n\n if (options.labelers) {\n headers.set(\n 'atproto-accept-labelers',\n [...options.labelers, headers.get('atproto-accept-labelers')?.trim()]\n .filter(Boolean)\n .join(', '),\n )\n }\n\n return headers\n}\n\nexport function toReadableStream(\n data: AsyncIterable<Uint8Array>,\n): ReadableStream<Uint8Array> {\n // Use the native ReadableStream.from() if available.\n if ('from' in ReadableStream && typeof ReadableStream.from === 'function') {\n return ReadableStream.from(data)\n }\n\n let iterator: AsyncIterator<Uint8Array> | undefined\n return new ReadableStream({\n async pull(controller) {\n try {\n iterator ??= data[Symbol.asyncIterator]()\n const result = await iterator!.next()\n if (result.done) controller.close()\n else controller.enqueue(result.value)\n } catch (err) {\n controller.error(err)\n iterator = undefined\n }\n },\n async cancel() {\n await iterator?.return?.()\n iterator = undefined\n },\n })\n}\n"]}
package/dist/xrpc.d.ts CHANGED
@@ -1,15 +1,16 @@
1
- import { InferMethodInput, InferMethodParams, Main, Params, Procedure, Query, Restricted } from '@atproto/lex-schema';
1
+ import { InferInput, InferPayload, Main, Params, Procedure, Query, Restricted, Subscription } from '@atproto/lex-schema';
2
2
  import { Agent } from './agent.js';
3
- import { LexRpcResponseError, LexRpcUnexpectedError, LexRpcUpstreamError } from './errors.js';
4
- import { LexRpcResponse } from './response.js';
3
+ import { XrpcResponseError, XrpcUnexpectedError, XrpcUpstreamError } from './errors.js';
4
+ import { XrpcResponse } from './response.js';
5
5
  import { BinaryBodyInit, CallOptions } from './types.js';
6
- type LexRpcParamsOptions<P extends Params> = NonNullable<unknown> extends P ? {
6
+ type XrpcParamsOptions<P extends Params> = NonNullable<unknown> extends P ? {
7
7
  params?: P;
8
8
  } : {
9
9
  params: P;
10
10
  };
11
- type LexRpcRequestPayload<M extends Procedure | Query> = InferMethodInput<M, BinaryBodyInit>;
12
- type LexRpcInputOptions<In> = In extends {
11
+ export type XrpcRequestParams<M extends Procedure | Query | Subscription> = InferInput<M['parameters']>;
12
+ type XrpcRequestPayload<M extends Procedure | Query> = M extends Procedure ? InferPayload<M['input'], BinaryBodyInit> : undefined;
13
+ type XrpcInputOptions<In> = In extends {
13
14
  body: infer B;
14
15
  encoding: infer E;
15
16
  } ? {
@@ -19,22 +20,22 @@ type LexRpcInputOptions<In> = In extends {
19
20
  body?: undefined;
20
21
  encoding?: undefined;
21
22
  };
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>;
23
+ export type XrpcOptions<M extends Procedure | Query = Procedure | Query> = CallOptions & XrpcInputOptions<XrpcRequestPayload<M>> & XrpcParamsOptions<XrpcRequestParams<M>>;
24
+ export type XrpcFailure<M extends Procedure | Query> = XrpcResponseError<M> | XrpcUpstreamError | XrpcUnexpectedError;
25
+ export type XrpcResult<M extends Procedure | Query> = XrpcResponse<M> | XrpcFailure<M>;
25
26
  /**
26
27
  * 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
+ * {@link XrpcFailure} matching the provided method. Only use this function
28
29
  * inside a catch block right after calling {@link xrpc}, and use the same
29
30
  * method type parameter as used in the {@link xrpc} call.
30
31
  */
31
- export declare function asLexRpcFailure<M extends Procedure | Query = Procedure | Query>(err: unknown): LexRpcFailure<M>;
32
+ export declare function asXrpcFailure<M extends Procedure | Query = Procedure | Query>(err: unknown): XrpcFailure<M>;
32
33
  /**
33
- * @throws LexRpcFailure<M>
34
+ * @throws XrpcFailure<M>
34
35
  */
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>>;
36
+ export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends XrpcOptions<M> ? Main<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<XrpcResponse<M>>;
37
+ export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: XrpcOptions<M>): Promise<XrpcResponse<M>>;
38
+ export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends XrpcOptions<M> ? Main<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<XrpcResult<M>>;
39
+ export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: XrpcOptions<M>): Promise<XrpcResult<M>>;
39
40
  export {};
40
41
  //# 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,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.asLexRpcFailure = asLexRpcFailure;
3
+ exports.asXrpcFailure = asXrpcFailure;
4
4
  exports.xrpc = xrpc;
5
5
  exports.xrpcSafe = xrpcSafe;
6
6
  const lex_data_1 = require("@atproto/lex-data");
@@ -11,27 +11,27 @@ const response_js_1 = require("./response.js");
11
11
  const util_js_1 = require("./util.js");
12
12
  /**
13
13
  * Utility method to type cast the error thrown by {@link xrpc} to an
14
- * {@link LexRpcFailure} matching the provided method. Only use this function
14
+ * {@link XrpcFailure} matching the provided method. Only use this function
15
15
  * inside a catch block right after calling {@link xrpc}, and use the same
16
16
  * method type parameter as used in the {@link xrpc} call.
17
17
  */
18
- function asLexRpcFailure(err) {
19
- if (err instanceof errors_js_1.LexRpcResponseError)
18
+ function asXrpcFailure(err) {
19
+ if (err instanceof errors_js_1.XrpcResponseError)
20
20
  return err;
21
- if (err instanceof errors_js_1.LexRpcUpstreamError)
21
+ if (err instanceof errors_js_1.XrpcUpstreamError)
22
22
  return err;
23
- return errors_js_1.LexRpcUnexpectedError.from(err);
23
+ return errors_js_1.XrpcUnexpectedError.from(err);
24
24
  }
25
25
  async function xrpc(agent, ns, options = {}) {
26
26
  try {
27
27
  return await lexRpcRequest(agent, ns, options);
28
28
  }
29
29
  catch (err) {
30
- throw asLexRpcFailure(err);
30
+ throw asXrpcFailure(err);
31
31
  }
32
32
  }
33
33
  async function xrpcSafe(agent, ns, options = {}) {
34
- return lexRpcRequest(agent, ns, options).catch((asLexRpcFailure));
34
+ return lexRpcRequest(agent, ns, options).catch((asXrpcFailure));
35
35
  }
36
36
  async function lexRpcRequest(agent, ns, options = {}) {
37
37
  const method = (0, lex_schema_1.getMain)(ns);
@@ -39,19 +39,15 @@ async function lexRpcRequest(agent, ns, options = {}) {
39
39
  const url = xrpcRequestUrl(method, options);
40
40
  const request = xrpcRequestInit(method, options);
41
41
  const response = await agent.fetchHandler(url, request);
42
- return response_js_1.LexRpcResponse.fromFetchResponse(method, response, options);
42
+ return response_js_1.XrpcResponse.fromFetchResponse(method, response, options);
43
43
  }
44
44
  function xrpcRequestUrl(method, options) {
45
45
  const path = `/xrpc/${method.nsid}`;
46
- const queryString = options.params
47
- ? xrpcRequestParams(method.parameters, options.params, options)
48
- : undefined;
46
+ const queryString = method.parameters
47
+ ?.toURLSearchParams(options.params ?? {})
48
+ .toString();
49
49
  return queryString ? `${path}?${queryString}` : path;
50
50
  }
51
- function xrpcRequestParams(schema, params, options) {
52
- const urlSearchParams = schema?.toURLSearchParams(options.validateRequest ? schema.parse(params) : params);
53
- return urlSearchParams?.size ? urlSearchParams.toString() : undefined;
54
- }
55
51
  function xrpcRequestInit(schema, options) {
56
52
  const headers = (0, util_js_1.buildAtprotoHeaders)(options);
57
53
  // Tell the server what type of response we're expecting
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 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"]}
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 InferInput,\n InferPayload,\n Main,\n Params,\n Payload,\n Procedure,\n Query,\n Restricted,\n Subscription,\n getMain,\n} from '@atproto/lex-schema'\nimport { Agent } from './agent.js'\nimport {\n XrpcResponseError,\n XrpcUnexpectedError,\n XrpcUpstreamError,\n} from './errors.js'\nimport { XrpcResponse } from './response.js'\nimport { BinaryBodyInit, CallOptions } from './types.js'\nimport {\n XrpcPayload,\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 XrpcParamsOptions<P extends Params> =\n NonNullable<unknown> extends P ? { params?: P } : { params: P }\n\nexport type XrpcRequestParams<M extends Procedure | Query | Subscription> =\n InferInput<M['parameters']>\n\ntype XrpcRequestPayload<M extends Procedure | Query> = M extends Procedure\n ? InferPayload<M['input'], BinaryBodyInit>\n : undefined\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<XrpcRequestParams<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 | XrpcUpstreamError\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 */\nexport function asXrpcFailure<M extends Procedure | Query = Procedure | Query>(\n err: unknown,\n): XrpcFailure<M> {\n if (err instanceof XrpcResponseError) return err\n if (err instanceof XrpcUpstreamError) 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 ? Main<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: Main<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResponse<M>> {\n try {\n return await lexRpcRequest<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 ? Main<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: Main<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResult<M>> {\n return lexRpcRequest<M>(agent, ns, options).catch(asXrpcFailure<M>)\n}\n\nasync function lexRpcRequest<const M extends Query | Procedure>(\n agent: Agent,\n ns: Main<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 = method.parameters\n ?.toURLSearchParams(options.params ?? {})\n .toString()\n\n return queryString ? `${path}?${queryString}` : path\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 | XrpcPayload<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: Payload,\n body: undefined | BodyInit,\n encodingHint?: string,\n): null | XrpcPayload<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: Payload, 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.9",
3
+ "version": "0.0.10",
4
4
  "license": "MIT",
5
5
  "description": "HTTP client for interacting with Lexicon based APIs",
6
6
  "keywords": [
@@ -37,14 +37,14 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "tslib": "^2.8.1",
40
- "@atproto/lex-data": "0.0.8",
41
- "@atproto/lex-json": "0.0.8",
42
- "@atproto/lex-schema": "0.0.9"
40
+ "@atproto/lex-data": "0.0.9",
41
+ "@atproto/lex-json": "0.0.9",
42
+ "@atproto/lex-schema": "0.0.10"
43
43
  },
44
44
  "devDependencies": {
45
45
  "vitest": "^4.0.16",
46
- "@atproto/lex-cbor": "0.0.8",
47
- "@atproto/lex-builder": "0.0.11"
46
+ "@atproto/lex-cbor": "0.0.9",
47
+ "@atproto/lex-builder": "0.0.12"
48
48
  },
49
49
  "scripts": {
50
50
  "prebuild": "node ./scripts/lex-build.mjs",
package/src/client.ts CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  Infer,
7
7
  InferMethodInputBody,
8
8
  InferMethodOutputBody,
9
- InferMethodParams,
10
9
  InferRecordKey,
11
10
  LexiconRecordKey,
12
11
  Main,
@@ -16,15 +15,21 @@ import {
16
15
  Query,
17
16
  RecordSchema,
18
17
  Restricted,
19
- Schema,
18
+ UnknownObject,
20
19
  getMain,
21
20
  } from '@atproto/lex-schema'
22
21
  import { Agent, AgentOptions, buildAgent } from './agent.js'
23
22
  import { com } from './lexicons/index.js'
24
- import { LexRpcResponse, LexRpcResponseBody } from './response.js'
23
+ import { XrpcResponse, XrpcResponseBody } from './response.js'
25
24
  import { BinaryBodyInit, CallOptions, Service } from './types.js'
26
25
  import { buildAtprotoHeaders } from './util.js'
27
- import { LexRpcFailure, LexRpcOptions, xrpc, xrpcSafe } from './xrpc.js'
26
+ import {
27
+ XrpcFailure,
28
+ XrpcOptions,
29
+ XrpcRequestParams,
30
+ xrpc,
31
+ xrpcSafe,
32
+ } from './xrpc.js'
28
33
 
29
34
  export type {
30
35
  AtIdentifierString,
@@ -32,7 +37,6 @@ export type {
32
37
  DidString,
33
38
  InferMethodInputBody,
34
39
  InferMethodOutputBody,
35
- InferMethodParams,
36
40
  InferRecordKey,
37
41
  LexMap,
38
42
  LexValue,
@@ -43,7 +47,6 @@ export type {
43
47
  Query,
44
48
  RecordSchema,
45
49
  Restricted,
46
- Schema,
47
50
  }
48
51
 
49
52
  export type ClientOptions = {
@@ -133,8 +136,8 @@ export type ListOutput<T extends RecordSchema> = InferMethodOutputBody<
133
136
  > & {
134
137
  records: ListRecord<Infer<T>>[]
135
138
  // @NOTE Because the schema uses "type": "unknown" instead of an open union,
136
- // we have to use LexMap instead of TypedObject here.
137
- invalid: LexMap[]
139
+ // we have to use UnknownObject instead of Unknown$TypedObject here.
140
+ invalid: UnknownObject[]
138
141
  }
139
142
  export type ListRecord<Value extends LexMap> =
140
143
  com.atproto.repo.listRecords.Record & {
@@ -211,37 +214,37 @@ export class Client implements Agent {
211
214
  }
212
215
 
213
216
  /**
214
- * @throws {LexRpcFailure<M>} when the request fails or the response is an error
217
+ * @throws {XrpcFailure<M>} when the request fails or the response is an error
215
218
  */
216
219
  async xrpc<const M extends Query | Procedure>(
217
- ns: NonNullable<unknown> extends LexRpcOptions<M>
220
+ ns: NonNullable<unknown> extends XrpcOptions<M>
218
221
  ? Main<M>
219
222
  : Restricted<'This XRPC method requires an "options" argument'>,
220
- ): Promise<LexRpcResponse<M>>
223
+ ): Promise<XrpcResponse<M>>
221
224
  async xrpc<const M extends Query | Procedure>(
222
225
  ns: Main<M>,
223
- options: LexRpcOptions<M>,
224
- ): Promise<LexRpcResponse<M>>
226
+ options: XrpcOptions<M>,
227
+ ): Promise<XrpcResponse<M>>
225
228
  async xrpc<const M extends Query | Procedure>(
226
229
  ns: Main<M>,
227
- options: LexRpcOptions<M> = {} as LexRpcOptions<M>,
228
- ): Promise<LexRpcResponse<M>> {
230
+ options: XrpcOptions<M> = {} as XrpcOptions<M>,
231
+ ): Promise<XrpcResponse<M>> {
229
232
  return xrpc(this, ns, options)
230
233
  }
231
234
 
232
235
  async xrpcSafe<const M extends Query | Procedure>(
233
- ns: NonNullable<unknown> extends LexRpcOptions<M>
236
+ ns: NonNullable<unknown> extends XrpcOptions<M>
234
237
  ? Main<M>
235
238
  : Restricted<'This XRPC method requires an "options" argument'>,
236
- ): Promise<LexRpcResponse<M> | LexRpcFailure<M>>
239
+ ): Promise<XrpcResponse<M> | XrpcFailure<M>>
237
240
  async xrpcSafe<const M extends Query | Procedure>(
238
241
  ns: Main<M>,
239
- options: LexRpcOptions<M>,
240
- ): Promise<LexRpcResponse<M> | LexRpcFailure<M>>
242
+ options: XrpcOptions<M>,
243
+ ): Promise<XrpcResponse<M> | XrpcFailure<M>>
241
244
  async xrpcSafe<const M extends Query | Procedure>(
242
245
  ns: Main<M>,
243
- options: LexRpcOptions<M> = {} as LexRpcOptions<M>,
244
- ): Promise<LexRpcResponse<M> | LexRpcFailure<M>> {
246
+ options: XrpcOptions<M> = {} as XrpcOptions<M>,
247
+ ): Promise<XrpcResponse<M> | XrpcFailure<M>> {
245
248
  return xrpcSafe(this, ns, options)
246
249
  }
247
250
 
@@ -348,10 +351,10 @@ export class Client implements Agent {
348
351
  }
349
352
 
350
353
  public async call<const T extends Query>(
351
- ns: NonNullable<unknown> extends InferMethodParams<T>
354
+ ns: NonNullable<unknown> extends XrpcRequestParams<T>
352
355
  ? Main<T>
353
356
  : Restricted<'This query type requires a "params" argument'>,
354
- ): Promise<LexRpcResponseBody<T>>
357
+ ): Promise<XrpcResponseBody<T>>
355
358
  public async call<const T extends Action>(
356
359
  ns: void extends InferActionInput<T>
357
360
  ? Main<T>
@@ -364,16 +367,16 @@ export class Client implements Agent {
364
367
  : T extends Procedure
365
368
  ? InferMethodInputBody<T, Uint8Array>
366
369
  : T extends Query
367
- ? InferMethodParams<T>
370
+ ? XrpcRequestParams<T>
368
371
  : never,
369
372
  options?: CallOptions,
370
373
  ): Promise<
371
374
  T extends Action
372
375
  ? InferActionOutput<T>
373
376
  : T extends Procedure
374
- ? LexRpcResponseBody<T>
377
+ ? XrpcResponseBody<T>
375
378
  : T extends Query
376
- ? LexRpcResponseBody<T>
379
+ ? XrpcResponseBody<T>
377
380
  : never
378
381
  >
379
382
  public async call(
@@ -415,8 +418,7 @@ export class Client implements Agent {
415
418
  options: CreateOptions<T> = {} as CreateOptions<T>,
416
419
  ): Promise<CreateOutput> {
417
420
  const schema: T = getMain(ns)
418
- const record = schema.build(input)
419
- if (options.validateRequest) schema.assert(record)
421
+ const record = schema.build(input) as { $type: NsidString } & LexMap
420
422
  const rkey = options.rkey ?? getDefaultRecordKey(schema)
421
423
  if (rkey !== undefined) schema.keySchema.assert(rkey)
422
424
  const response = await this.createRecord(record, rkey, options)
@@ -462,7 +464,7 @@ export class Client implements Agent {
462
464
  options.rkey ?? getLiteralRecordKey(schema),
463
465
  )
464
466
  const response = await this.getRecord(schema.$type, rkey, options)
465
- const value = schema.parse(response.body.value) as Infer<T>
467
+ const value = schema.validate(response.body.value)
466
468
  return { ...response.body, value }
467
469
  }
468
470
 
@@ -483,8 +485,7 @@ export class Client implements Agent {
483
485
  options: PutOptions<T> = {} as PutOptions<T>,
484
486
  ): Promise<PutOutput> {
485
487
  const schema: T = getMain(ns)
486
- const record = schema.build(input)
487
- if (options.validateRequest) schema.assert(record)
488
+ const record = schema.build(input) as { $type: NsidString } & LexMap
488
489
  const rkey = options.rkey ?? getLiteralRecordKey(schema)
489
490
  const response = await this.putRecord(record, rkey, options)
490
491
  return response.body
@@ -501,7 +502,7 @@ export class Client implements Agent {
501
502
  const invalid: LexMap[] = []
502
503
 
503
504
  for (const record of body.records) {
504
- const parsed = (schema as Schema<Infer<T>>).safeParse(record.value)
505
+ const parsed = schema.safeValidate(record.value)
505
506
  if (parsed.success) {
506
507
  records.push({ ...record, value: parsed.value })
507
508
  } else {