@atproto/lex-client 0.0.9 → 0.0.11

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 (53) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/agent.d.ts +5 -0
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +15 -1
  6. package/dist/agent.js.map +1 -1
  7. package/dist/client.d.ts +59 -40
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +2 -6
  10. package/dist/client.js.map +1 -1
  11. package/dist/errors.d.ts +52 -51
  12. package/dist/errors.d.ts.map +1 -1
  13. package/dist/errors.js +90 -71
  14. package/dist/errors.js.map +1 -1
  15. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts +20 -10
  16. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts.map +1 -1
  17. package/dist/lexicons/com/atproto/repo/defs.defs.d.ts +1 -1
  18. package/dist/lexicons/com/atproto/repo/defs.defs.d.ts.map +1 -1
  19. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts +14 -6
  20. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts.map +1 -1
  21. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts +12 -4
  22. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts.map +1 -1
  23. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts +11 -11
  24. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts.map +1 -1
  25. package/dist/lexicons/com/atproto/repo/listRecords.defs.js +2 -1
  26. package/dist/lexicons/com/atproto/repo/listRecords.defs.js.map +1 -1
  27. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts +18 -10
  28. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts.map +1 -1
  29. package/dist/response.d.ts +14 -13
  30. package/dist/response.d.ts.map +1 -1
  31. package/dist/response.js +36 -35
  32. package/dist/response.js.map +1 -1
  33. package/dist/util.d.ts +1 -1
  34. package/dist/util.d.ts.map +1 -1
  35. package/dist/util.js.map +1 -1
  36. package/dist/www-authenticate.d.ts +12 -0
  37. package/dist/www-authenticate.d.ts.map +1 -0
  38. package/dist/www-authenticate.js +57 -0
  39. package/dist/www-authenticate.js.map +1 -0
  40. package/dist/xrpc.d.ts +14 -21
  41. package/dist/xrpc.d.ts.map +1 -1
  42. package/dist/xrpc.js +18 -35
  43. package/dist/xrpc.js.map +1 -1
  44. package/package.json +6 -6
  45. package/src/agent.ts +34 -1
  46. package/src/client.ts +34 -33
  47. package/src/errors.ts +161 -128
  48. package/src/lexicons/com/atproto/repo/listRecords.defs.ts +4 -1
  49. package/src/response.ts +71 -71
  50. package/src/util.ts +1 -1
  51. package/src/www-authenticate.test.ts +227 -0
  52. package/src/www-authenticate.ts +77 -0
  53. package/src/xrpc.ts +53 -95
@@ -9,12 +9,12 @@ declare const main: l.Query<"com.atproto.repo.listRecords", l.ParamsSchema<{
9
9
  readonly collection: l.StringSchema<{
10
10
  readonly format: "nsid";
11
11
  }>;
12
- readonly limit: l.OptionalSchema<number>;
13
- readonly cursor: l.OptionalSchema<string>;
14
- readonly reverse: l.OptionalSchema<boolean>;
12
+ readonly limit: l.OptionalSchema<l.WithDefaultSchema<l.IntegerSchema>>;
13
+ readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
14
+ readonly reverse: l.OptionalSchema<l.BooleanSchema>;
15
15
  }>, l.Payload<"application/json", l.ObjectSchema<{
16
- readonly cursor: l.OptionalSchema<string>;
17
- readonly records: l.ArraySchema<l.RefSchema<Record$0>>;
16
+ readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
17
+ readonly 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>;
@@ -27,12 +27,12 @@ export declare const $lxm: "com.atproto.repo.listRecords", $params: l.ParamsSche
27
27
  readonly collection: l.StringSchema<{
28
28
  readonly format: "nsid";
29
29
  }>;
30
- readonly limit: l.OptionalSchema<number>;
31
- readonly cursor: l.OptionalSchema<string>;
32
- readonly reverse: l.OptionalSchema<boolean>;
30
+ readonly limit: l.OptionalSchema<l.WithDefaultSchema<l.IntegerSchema>>;
31
+ readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
32
+ readonly reverse: l.OptionalSchema<l.BooleanSchema>;
33
33
  }>, $output: l.Payload<"application/json", l.ObjectSchema<{
34
- readonly cursor: l.OptionalSchema<string>;
35
- readonly records: l.ArraySchema<l.RefSchema<Record$0>>;
34
+ readonly cursor: l.OptionalSchema<l.StringSchema<{}>>;
35
+ readonly 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';
@@ -41,6 +41,6 @@ type Record$0 = {
41
41
  value: l.UnknownObject;
42
42
  };
43
43
  export type { Record$0 as Record };
44
- declare const record$0: l.TypedObjectSchema<"com.atproto.repo.listRecords#record", l.Validator<Omit<Record$0, "$type">>>;
44
+ declare const record$0: l.TypedObjectSchema<"com.atproto.repo.listRecords#record", l.Validator<Record$0, Record$0>>;
45
45
  export { record$0 as record };
46
46
  //# sourceMappingURL=listRecords.defs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"listRecords.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/repo/listRecords.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAA;AAEvC,QAAA,MAAM,KAAK,iCAAiC,CAAA;AAE5C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,sGAAsG;AACtG,QAAA,MAAM,IAAI;;;;;;;;;;;;;eAmBP,CAAA;AACH,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,qBAAqB,CAAC,OAAO,IAAI,CAAC,CAAA;AAE7D,eAAO,MAAM,IAAI,gCAA0B,EACzC,OAAO;;;;;;;;;;EAAkB,EACzB,OAAO;;;GAAc,CAAA;AAEvB,KAAK,QAAQ,GAAG;IACd,KAAK,CAAC,EAAE,qCAAqC,CAAA;IAC7C,GAAG,EAAE,CAAC,CAAC,WAAW,CAAA;IAClB,GAAG,EAAE,CAAC,CAAC,SAAS,CAAA;IAChB,KAAK,EAAE,CAAC,CAAC,aAAa,CAAA;CACvB,CAAA;AAED,YAAY,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAA;AAElC,QAAA,MAAM,QAAQ,kGAQb,CAAA;AAED,OAAO,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAA"}
1
+ {"version":3,"file":"listRecords.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/repo/listRecords.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAA;AAEvC,QAAA,MAAM,KAAK,iCAAiC,CAAA;AAE5C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,sGAAsG;AACtG,QAAA,MAAM,IAAI;;;;;;;;;;;;;eAsBP,CAAA;AACH,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,qBAAqB,CAAC,OAAO,IAAI,CAAC,CAAA;AAE7D,eAAO,MAAM,IAAI,gCAA0B,EACzC,OAAO;;;;;;;;;;EAAkB,EACzB,OAAO;;;GAAc,CAAA;AAEvB,KAAK,QAAQ,GAAG;IACd,KAAK,CAAC,EAAE,qCAAqC,CAAA;IAC7C,GAAG,EAAE,CAAC,CAAC,WAAW,CAAA;IAClB,GAAG,EAAE,CAAC,CAAC,SAAS,CAAA;IAChB,KAAK,EAAE,CAAC,CAAC,aAAa,CAAA;CACvB,CAAA;AAED,YAAY,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAA;AAElC,QAAA,MAAM,QAAQ,6FAQb,CAAA;AAED,OAAO,EAAE,QAAQ,IAAI,MAAM,EAAE,CAAA"}
@@ -15,7 +15,8 @@ lex_schema_1.l.query($nsid,
15
15
  repo: /*#__PURE__*/ lex_schema_1.l.string({ format: 'at-identifier' }),
16
16
  collection: /*#__PURE__*/ lex_schema_1.l.string({ format: 'nsid' }),
17
17
  limit: /*#__PURE__*/ lex_schema_1.l.optional(
18
- /*#__PURE__*/ lex_schema_1.l.integer({ minimum: 1, maximum: 100, default: 50 })),
18
+ /*#__PURE__*/ lex_schema_1.l.withDefault(
19
+ /*#__PURE__*/ lex_schema_1.l.integer({ minimum: 1, maximum: 100 }), 50)),
19
20
  cursor: /*#__PURE__*/ lex_schema_1.l.optional(/*#__PURE__*/ lex_schema_1.l.string()),
20
21
  reverse: /*#__PURE__*/ lex_schema_1.l.optional(/*#__PURE__*/ lex_schema_1.l.boolean()),
21
22
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"listRecords.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/repo/listRecords.defs.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,oDAAuC;AAEvC,MAAM,KAAK,GAAG,8BAA8B,CAAA;AAEnC,sBAAK;AAEd,sGAAsG;AACtG,MAAM,IAAI;AACR,aAAa;AACb,cAAC,CAAC,KAAK,CACL,KAAK;AACL,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACzD,UAAU,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACtD,KAAK,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ;IAC7B,aAAa,CAAC,cAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CACnE;IACD,MAAM,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,OAAO,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAC,CAAC,OAAO,EAAE,CAAC;CAC7D,CAAC;AACF,aAAa,CAAC,cAAC,CAAC,WAAW,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,OAAO,EAAE,aAAa,CAAC,cAAC,CAAC,KAAK;IAC5B,aAAa,CAAC,cAAC,CAAC,GAAG,CAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAQ,CAAC,CACvD;CACF,CAAC,CACH,CAAA;AACM,oBAAI;AAMA,QAAA,IAAI,GAAiB,IAAI,CAAC,IAAI,EACzC,QAAA,OAAO,GAAG,IAAI,CAAC,UAAU,EACzB,QAAA,OAAO,GAAG,IAAI,CAAC,MAAM,CAAA;AAWvB,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAC,CAAC,WAAW,CAC1C,KAAK,EACL,QAAQ;AACR,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC;IACrB,GAAG,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACjD,GAAG,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC9C,KAAK,EAAE,aAAa,CAAC,cAAC,CAAC,aAAa,EAAE;CACvC,CAAC,CACH,CAAA;AAEoB,0BAAM","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex-schema'\n\nconst $nsid = 'com.atproto.repo.listRecords'\n\nexport { $nsid }\n\n/** List a range of records in a repository, matching a specific collection. Does not require auth. */\nconst main =\n /*#__PURE__*/\n l.query(\n $nsid,\n /*#__PURE__*/ l.params({\n repo: /*#__PURE__*/ l.string({ format: 'at-identifier' }),\n collection: /*#__PURE__*/ l.string({ format: 'nsid' }),\n limit: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.integer({ minimum: 1, maximum: 100, default: 50 }),\n ),\n cursor: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),\n reverse: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),\n }),\n /*#__PURE__*/ l.jsonPayload({\n cursor: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),\n records: /*#__PURE__*/ l.array(\n /*#__PURE__*/ l.ref<Record$0>((() => record$0) as any),\n ),\n }),\n )\nexport { main }\n\nexport type Params = l.InferMethodParams<typeof main>\nexport type Output = l.InferMethodOutput<typeof main>\nexport type OutputBody = l.InferMethodOutputBody<typeof main>\n\nexport const $lxm = /*#__PURE__*/ main.nsid,\n $params = main.parameters,\n $output = main.output\n\ntype Record$0 = {\n $type?: 'com.atproto.repo.listRecords#record'\n uri: l.AtUriString\n cid: l.CidString\n value: l.UnknownObject\n}\n\nexport type { Record$0 as Record }\n\nconst record$0 = /*#__PURE__*/ l.typedObject<Record$0>(\n $nsid,\n 'record',\n /*#__PURE__*/ l.object({\n uri: /*#__PURE__*/ l.string({ format: 'at-uri' }),\n cid: /*#__PURE__*/ l.string({ format: 'cid' }),\n value: /*#__PURE__*/ l.unknownObject(),\n }),\n)\n\nexport { record$0 as record }\n"]}
1
+ {"version":3,"file":"listRecords.defs.js","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/repo/listRecords.defs.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,oDAAuC;AAEvC,MAAM,KAAK,GAAG,8BAA8B,CAAA;AAEnC,sBAAK;AAEd,sGAAsG;AACtG,MAAM,IAAI;AACR,aAAa;AACb,cAAC,CAAC,KAAK,CACL,KAAK;AACL,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACzD,UAAU,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACtD,KAAK,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ;IAC7B,aAAa,CAAC,cAAC,CAAC,WAAW;IACzB,aAAa,CAAC,cAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EACrD,EAAE,CACH,CACF;IACD,MAAM,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,OAAO,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAC,CAAC,OAAO,EAAE,CAAC;CAC7D,CAAC;AACF,aAAa,CAAC,cAAC,CAAC,WAAW,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC,cAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,cAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,OAAO,EAAE,aAAa,CAAC,cAAC,CAAC,KAAK;IAC5B,aAAa,CAAC,cAAC,CAAC,GAAG,CAAW,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAQ,CAAC,CACvD;CACF,CAAC,CACH,CAAA;AACM,oBAAI;AAMA,QAAA,IAAI,GAAiB,IAAI,CAAC,IAAI,EACzC,QAAA,OAAO,GAAG,IAAI,CAAC,UAAU,EACzB,QAAA,OAAO,GAAG,IAAI,CAAC,MAAM,CAAA;AAWvB,MAAM,QAAQ,GAAG,aAAa,CAAC,cAAC,CAAC,WAAW,CAC1C,KAAK,EACL,QAAQ;AACR,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC;IACrB,GAAG,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IACjD,GAAG,EAAE,aAAa,CAAC,cAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC9C,KAAK,EAAE,aAAa,CAAC,cAAC,CAAC,aAAa,EAAE;CACvC,CAAC,CACH,CAAA;AAEoB,0BAAM","sourcesContent":["/*\n * THIS FILE WAS GENERATED BY \"@atproto/lex\". DO NOT EDIT.\n */\n\nimport { l } from '@atproto/lex-schema'\n\nconst $nsid = 'com.atproto.repo.listRecords'\n\nexport { $nsid }\n\n/** List a range of records in a repository, matching a specific collection. Does not require auth. */\nconst main =\n /*#__PURE__*/\n l.query(\n $nsid,\n /*#__PURE__*/ l.params({\n repo: /*#__PURE__*/ l.string({ format: 'at-identifier' }),\n collection: /*#__PURE__*/ l.string({ format: 'nsid' }),\n limit: /*#__PURE__*/ l.optional(\n /*#__PURE__*/ l.withDefault(\n /*#__PURE__*/ l.integer({ minimum: 1, maximum: 100 }),\n 50,\n ),\n ),\n cursor: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),\n reverse: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),\n }),\n /*#__PURE__*/ l.jsonPayload({\n cursor: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.string()),\n records: /*#__PURE__*/ l.array(\n /*#__PURE__*/ l.ref<Record$0>((() => record$0) as any),\n ),\n }),\n )\nexport { main }\n\nexport type Params = l.InferMethodParams<typeof main>\nexport type Output = l.InferMethodOutput<typeof main>\nexport type OutputBody = l.InferMethodOutputBody<typeof main>\n\nexport const $lxm = /*#__PURE__*/ main.nsid,\n $params = main.parameters,\n $output = main.output\n\ntype Record$0 = {\n $type?: 'com.atproto.repo.listRecords#record'\n uri: l.AtUriString\n cid: l.CidString\n value: l.UnknownObject\n}\n\nexport type { Record$0 as Record }\n\nconst record$0 = /*#__PURE__*/ l.typedObject<Record$0>(\n $nsid,\n 'record',\n /*#__PURE__*/ l.object({\n uri: /*#__PURE__*/ l.string({ format: 'at-uri' }),\n cid: /*#__PURE__*/ l.string({ format: 'cid' }),\n value: /*#__PURE__*/ l.unknownObject(),\n }),\n)\n\nexport { record$0 as record }\n"]}
@@ -14,10 +14,14 @@ declare const main: l.Procedure<"com.atproto.repo.putRecord", l.ParamsSchema<{}>
14
14
  readonly format: "record-key";
15
15
  readonly maxLength: 512;
16
16
  }>;
17
- readonly validate: l.OptionalSchema<boolean>;
17
+ readonly validate: l.OptionalSchema<l.BooleanSchema>;
18
18
  readonly record: l.UnknownObjectSchema;
19
- readonly swapRecord: l.OptionalSchema<string | null>;
20
- readonly swapCommit: l.OptionalSchema<string>;
19
+ readonly swapRecord: l.OptionalSchema<l.NullableSchema<l.StringSchema<{
20
+ readonly format: "cid";
21
+ }>>>;
22
+ readonly swapCommit: l.OptionalSchema<l.StringSchema<{
23
+ readonly format: "cid";
24
+ }>>;
21
25
  }>>, l.Payload<"application/json", l.ObjectSchema<{
22
26
  readonly uri: l.StringSchema<{
23
27
  readonly format: "at-uri";
@@ -25,8 +29,8 @@ declare const main: l.Procedure<"com.atproto.repo.putRecord", l.ParamsSchema<{}>
25
29
  readonly cid: l.StringSchema<{
26
30
  readonly format: "cid";
27
31
  }>;
28
- readonly commit: l.OptionalSchema<RepoDefs.CommitMeta>;
29
- readonly validationStatus: l.OptionalSchema<string>;
32
+ readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
33
+ readonly validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
30
34
  }>>, readonly ["InvalidSwap"]>;
31
35
  export { main };
32
36
  export type Params = l.InferMethodParams<typeof main>;
@@ -45,10 +49,14 @@ export declare const $lxm: "com.atproto.repo.putRecord", $params: l.ParamsSchema
45
49
  readonly format: "record-key";
46
50
  readonly maxLength: 512;
47
51
  }>;
48
- readonly validate: l.OptionalSchema<boolean>;
52
+ readonly validate: l.OptionalSchema<l.BooleanSchema>;
49
53
  readonly record: l.UnknownObjectSchema;
50
- readonly swapRecord: l.OptionalSchema<string | null>;
51
- readonly swapCommit: l.OptionalSchema<string>;
54
+ readonly swapRecord: l.OptionalSchema<l.NullableSchema<l.StringSchema<{
55
+ readonly format: "cid";
56
+ }>>>;
57
+ readonly swapCommit: l.OptionalSchema<l.StringSchema<{
58
+ readonly format: "cid";
59
+ }>>;
52
60
  }>>, $output: l.Payload<"application/json", l.ObjectSchema<{
53
61
  readonly uri: l.StringSchema<{
54
62
  readonly format: "at-uri";
@@ -56,7 +64,7 @@ export declare const $lxm: "com.atproto.repo.putRecord", $params: l.ParamsSchema
56
64
  readonly cid: l.StringSchema<{
57
65
  readonly format: "cid";
58
66
  }>;
59
- readonly commit: l.OptionalSchema<RepoDefs.CommitMeta>;
60
- readonly validationStatus: l.OptionalSchema<string>;
67
+ readonly commit: l.OptionalSchema<l.RefSchema<l.Validator<RepoDefs.CommitMeta, RepoDefs.CommitMeta>>>;
68
+ readonly validationStatus: l.OptionalSchema<l.StringSchema<{}>>;
61
69
  }>>;
62
70
  //# sourceMappingURL=putRecord.defs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"putRecord.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/repo/putRecord.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C,QAAA,MAAM,KAAK,+BAA+B,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,uGAAuG;AACvG,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;8BA6BP,CAAA;AACH,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,CAAA;AACnD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,oBAAoB,CAAC,OAAO,IAAI,CAAC,CAAA;AAC3D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,qBAAqB,CAAC,OAAO,IAAI,CAAC,CAAA;AAE7D,eAAO,MAAM,IAAI,8BAA0B,EACzC,OAAO,oBAAgC,EACvC,MAAM;;;;;;;;;;;;;;;GAA2B,EACjC,OAAO;;;;;;;;;GAA4B,CAAA"}
1
+ {"version":3,"file":"putRecord.defs.d.ts","sourceRoot":"","sources":["../../../../../src/lexicons/com/atproto/repo/putRecord.defs.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAA;AACvC,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE1C,QAAA,MAAM,KAAK,+BAA+B,CAAA;AAE1C,OAAO,EAAE,KAAK,EAAE,CAAA;AAEhB,uGAAuG;AACvG,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BA6BP,CAAA;AACH,OAAO,EAAE,IAAI,EAAE,CAAA;AAEf,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,CAAA;AACnD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,oBAAoB,CAAC,OAAO,IAAI,CAAC,CAAA;AAC3D,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,iBAAiB,CAAC,OAAO,IAAI,CAAC,CAAA;AACrD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,qBAAqB,CAAC,OAAO,IAAI,CAAC,CAAA;AAE7D,eAAO,MAAM,IAAI,8BAA0B,EACzC,OAAO,oBAAgC,EACvC,MAAM;;;;;;;;;;;;;;;;;;;GAA2B,EACjC,OAAO;;;;;;;;;GAA4B,CAAA"}
@@ -1,38 +1,39 @@
1
1
  import { InferMethodOutputBody, InferMethodOutputEncoding, Procedure, Query, ResultSuccess } from '@atproto/lex-schema';
2
- import { Payload } from './util.js';
3
- export type LexRpcResponseBody<M extends Procedure | Query> = InferMethodOutputBody<M, Uint8Array>;
4
- export type LexRpcResponsePayload<M extends Procedure | Query> = InferMethodOutputEncoding<M> extends infer E extends string ? Payload<LexRpcResponseBody<M>, E> : null;
2
+ import { XrpcPayload } from './util.js';
3
+ export type XrpcResponseBody<M extends Procedure | Query> = InferMethodOutputBody<M, Uint8Array>;
4
+ export type XrpcResponsePayload<M extends Procedure | Query> = InferMethodOutputEncoding<M> extends infer E extends string ? XrpcPayload<XrpcResponseBody<M>, E> : null;
5
5
  /**
6
6
  * Small container for XRPC response data.
7
7
  *
8
- * @implements {ResultSuccess<LexRpcResponse<M>>} for convenience in result handling contexts.
8
+ * @implements {ResultSuccess<XrpcResponse<M>>} for convenience in result handling contexts.
9
9
  */
10
- export declare class LexRpcResponse<const M extends Procedure | Query> implements ResultSuccess<LexRpcResponse<M>> {
10
+ export declare class XrpcResponse<M extends Procedure | Query> implements ResultSuccess<XrpcResponse<M>> {
11
11
  readonly method: M;
12
12
  readonly status: number;
13
13
  readonly headers: Headers;
14
- readonly payload: LexRpcResponsePayload<M>;
14
+ readonly payload: XrpcResponsePayload<M>;
15
15
  /** @see {@link ResultSuccess.success} */
16
16
  readonly success: true;
17
17
  /** @see {@link ResultSuccess.value} */
18
18
  get value(): this;
19
- constructor(method: M, status: number, headers: Headers, payload: LexRpcResponsePayload<M>);
19
+ constructor(method: M, status: number, headers: Headers, payload: XrpcResponsePayload<M>);
20
20
  /**
21
21
  * Whether the response payload was parsed as {@link LexValue} (`true`) or is
22
22
  * in binary form {@link Uint8Array} (`false`).
23
23
  */
24
24
  get isParsed(): boolean;
25
25
  get encoding(): InferMethodOutputEncoding<M>;
26
- get body(): LexRpcResponseBody<M>;
26
+ get body(): XrpcResponseBody<M>;
27
27
  /**
28
- * @throws {LexRpcResponseError} in case of (valid) XRPC error responses. Use
29
- * {@link LexRpcResponseError.matchesSchema} to narrow the error type based on
30
- * the method's declared error schema.
31
- * @throws {LexRpcUpstreamError} when the response is not a valid XRPC
28
+ * @throws {XrpcResponseError} in case of (valid) XRPC error responses. Use
29
+ * {@link XrpcResponseError.matchesSchema} to narrow the error type based on
30
+ * the method's declared error schema. This can be narrowed further as a
31
+ * {@link XrpcAuthenticationError} if the error is an authentication error.
32
+ * @throws {XrpcUpstreamError} when the response is not a valid XRPC
32
33
  * response, or if the response does not conform to the method's schema.
33
34
  */
34
35
  static fromFetchResponse<const M extends Procedure | Query>(method: M, response: Response, options?: {
35
36
  validateResponse?: boolean;
36
- }): Promise<LexRpcResponse<M>>;
37
+ }): Promise<XrpcResponse<M>>;
37
38
  }
38
39
  //# sourceMappingURL=response.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,EACT,KAAK,EACL,aAAa,EACd,MAAM,qBAAqB,CAAA;AAM5B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IACxD,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAEtC,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IAC3D,yBAAyB,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,GACvD,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GACjC,IAAI,CAAA;AAEV;;;;GAIG;AACH,qBAAa,cAAc,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,CAC3D,YAAW,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAWzC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAZ5C,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAG,IAAI,CAAS;IAEhC,uCAAuC;IACvC,IAAI,KAAK,IAAI,IAAI,CAEhB;gBAGU,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAG5C;;;OAGG;IACH,IAAI,QAAQ,YAEX;IAED,IAAI,QAAQ,IACuB,yBAAyB,CAAC,CAAC,CAAC,CAC9D;IAED,IAAI,IAAI,IACuB,kBAAkB,CAAC,CAAC,CAAC,CACnD;IAED;;;;;;OAMG;WACU,iBAAiB,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,EAC9D,MAAM,EAAE,CAAC,EACT,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,GACvC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;CA4F9B"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,EACT,KAAK,EACL,aAAa,EACd,MAAM,qBAAqB,CAAA;AAO5B,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IACtD,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAEtC,MAAM,MAAM,mBAAmB,CAAC,CAAC,SAAS,SAAS,GAAG,KAAK,IACzD,yBAAyB,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,GACvD,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GACnC,IAAI,CAAA;AAEV;;;;GAIG;AACH,qBAAa,YAAY,CAAC,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,IAAI,QAAQ,IACuB,yBAAyB,CAAC,CAAC,CAAC,CAC9D;IAED,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
@@ -1,14 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LexRpcResponse = void 0;
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
6
  /**
7
7
  * Small container for XRPC response data.
8
8
  *
9
- * @implements {ResultSuccess<LexRpcResponse<M>>} for convenience in result handling contexts.
9
+ * @implements {ResultSuccess<XrpcResponse<M>>} for convenience in result handling contexts.
10
10
  */
11
- class LexRpcResponse {
11
+ class XrpcResponse {
12
12
  method;
13
13
  status;
14
14
  headers;
@@ -39,10 +39,11 @@ class LexRpcResponse {
39
39
  return this.payload?.body;
40
40
  }
41
41
  /**
42
- * @throws {LexRpcResponseError} in case of (valid) XRPC error responses. Use
43
- * {@link LexRpcResponseError.matchesSchema} to narrow the error type based on
44
- * the method's declared error schema.
45
- * @throws {LexRpcUpstreamError} when the response is not a valid XRPC
42
+ * @throws {XrpcResponseError} in case of (valid) XRPC error responses. Use
43
+ * {@link XrpcResponseError.matchesSchema} to narrow the error type based on
44
+ * the method's declared error schema. This can be narrowed further as a
45
+ * {@link XrpcAuthenticationError} if the error is an authentication error.
46
+ * @throws {XrpcUpstreamError} when the response is not a valid XRPC
46
47
  * response, or if the response does not conform to the method's schema.
47
48
  */
48
49
  static async fromFetchResponse(method, response, options) {
@@ -52,49 +53,54 @@ class LexRpcResponse {
52
53
  // @NOTE redirect is set to 'follow', so we shouldn't get 3xx responses here
53
54
  if (response.status < 200 || response.status >= 300) {
54
55
  // Always parse json for error responses
55
- const payload = await readPayload(response, { parse: true });
56
- if (response.status >= 400 && (0, errors_js_1.isLexRpcErrorPayload)(payload)) {
57
- throw new errors_js_1.LexRpcResponseError(method, response.status, response.headers, payload);
56
+ const payload = await readPayload(response, { parse: true }).catch((cause) => {
57
+ throw new errors_js_1.XrpcUpstreamError(method, response, null, 'Unable to parse response payload', { cause });
58
+ });
59
+ // Properly formatted XRPC error response ?
60
+ if (response.status >= 400 && (0, errors_js_1.isXrpcErrorPayload)(payload)) {
61
+ throw response.status === 401
62
+ ? new errors_js_1.XrpcAuthenticationError(method, response, payload)
63
+ : new errors_js_1.XrpcResponseError(method, response, payload);
58
64
  }
59
- if (response.status >= 500) {
60
- throw new errors_js_1.LexRpcUpstreamError('UpstreamFailure', `Upstream server encountered an error`, response, payload);
61
- }
62
- throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', response.status >= 400
63
- ? `Upstream server returned an invalid response payload`
64
- : `Upstream server returned an invalid status code`, response, payload);
65
+ // Invalid XRPC response (we probably did not hit an XRPC implementation)
66
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, response.status >= 500
67
+ ? 'Upstream server encountered an error'
68
+ : response.status >= 400
69
+ ? 'Invalid response payload'
70
+ : 'Invalid response status code');
65
71
  }
66
72
  // Only parse json if the schema expects it
67
73
  const payload = await readPayload(response, {
68
74
  parse: shouldParse(method),
75
+ }).catch((cause) => {
76
+ throw new errors_js_1.XrpcUpstreamError(method, response, null, 'Unable to parse response payload', { cause });
69
77
  });
70
78
  // Response is successful (2xx). Validate payload (data and encoding) against schema.
71
79
  if (method.output.encoding == null) {
72
80
  // Schema expects no payload
73
81
  if (payload) {
74
- throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', `Expected response with no body, got ${payload.encoding}`, response, payload);
82
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, `Expected response with no body, got ${payload.encoding}`);
75
83
  }
76
84
  }
77
85
  else {
78
86
  // Schema expects a payload
79
87
  if (!payload || !method.output.matchesEncoding(payload.encoding)) {
80
- throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', payload
88
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, payload
81
89
  ? `Expected ${method.output.encoding} response, got ${payload.encoding}`
82
- : `Expected non-empty response with content-type ${method.output.encoding}`, response, payload);
90
+ : `Expected non-empty response with content-type ${method.output.encoding}`);
83
91
  }
84
92
  // Assert valid response body.
85
93
  if (method.output.schema && options?.validateResponse !== false) {
86
- const result = method.output.schema.safeParse(payload.body, {
87
- allowTransform: false,
88
- });
94
+ const result = method.output.schema.safeParse(payload.body);
89
95
  if (!result.success) {
90
- throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', `Response validation failed: ${result.reason.message}`, response, payload, { cause: result.reason });
96
+ throw new errors_js_1.XrpcUpstreamError(method, response, payload, `Response validation failed: ${result.reason.message}`, { cause: result.reason });
91
97
  }
92
98
  }
93
99
  }
94
- return new LexRpcResponse(method, response.status, response.headers, payload);
100
+ return new XrpcResponse(method, response.status, response.headers, payload);
95
101
  }
96
102
  }
97
- exports.LexRpcResponse = LexRpcResponse;
103
+ exports.XrpcResponse = XrpcResponse;
98
104
  function shouldParse(method) {
99
105
  return method.output.encoding === 'application/json';
100
106
  }
@@ -128,16 +134,11 @@ async function readPayload(response, options) {
128
134
  // This would require adding encode/decode utilities to lex-json (similar
129
135
  // to @ipld/dag-json)
130
136
  const text = await response.text();
131
- try {
132
- // @NOTE Using `lexParse(text)` (instead of `jsonToLex(json)`) here as
133
- // using a reviver function during JSON.parse should be faster than
134
- // parsing to JSON then converting to Lex (?)
135
- // @TODO verify statement above
136
- return { encoding, body: (0, lex_json_1.lexParse)(text) };
137
- }
138
- catch (cause) {
139
- throw new errors_js_1.LexRpcUpstreamError('InvalidResponse', 'Invalid JSON response body', response, null, { cause });
140
- }
137
+ // @NOTE Using `lexParse(text)` (instead of `jsonToLex(json)`) here as
138
+ // using a reviver function during JSON.parse should be faster than
139
+ // parsing to JSON then converting to Lex (?)
140
+ // @TODO verify statement above
141
+ return { encoding, body: (0, lex_json_1.lexParse)(text) };
141
142
  }
142
143
  return { encoding, body: new Uint8Array(await response.arrayBuffer()) };
143
144
  }
@@ -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 XrpcAuthenticationError,\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<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. This can be narrowed further as a\n * {@link XrpcAuthenticationError} if the error is an authentication error.\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 }).catch(\n (cause) => {\n throw new XrpcUpstreamError(\n method,\n response,\n null,\n 'Unable to parse response payload',\n { cause },\n )\n },\n )\n\n // Properly formatted XRPC error response ?\n if (response.status >= 400 && isXrpcErrorPayload(payload)) {\n throw response.status === 401\n ? new XrpcAuthenticationError<M>(method, response, payload)\n : new XrpcResponseError<M>(method, response, payload)\n }\n\n // Invalid XRPC response (we probably did not hit an XRPC implementation)\n throw new XrpcUpstreamError(\n method,\n response,\n payload,\n response.status >= 500\n ? 'Upstream server encountered an error'\n : response.status >= 400\n ? 'Invalid response payload'\n : 'Invalid response status code',\n )\n }\n\n // Only parse json if the schema expects it\n const payload = await readPayload(response, {\n parse: shouldParse(method),\n }).catch((cause) => {\n throw new XrpcUpstreamError(\n method,\n response,\n null,\n 'Unable to parse response payload',\n { cause },\n )\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 method,\n response,\n payload,\n `Expected response with no body, got ${payload.encoding}`,\n )\n }\n } else {\n // Schema expects a payload\n if (!payload || !method.output.matchesEncoding(payload.encoding)) {\n throw new XrpcUpstreamError(\n method,\n response,\n payload,\n payload\n ? `Expected ${method.output.encoding} response, got ${payload.encoding}`\n : `Expected non-empty response with content-type ${method.output.encoding}`,\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 method,\n response,\n payload,\n `Response validation failed: ${result.reason.message}`,\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 // @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 }\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"]}
@@ -0,0 +1,12 @@
1
+ type WWWAuthenticateParams = {
2
+ [authParam in string]: string;
3
+ };
4
+ export type WWWAuthenticate = {
5
+ [authScheme in string]: string | WWWAuthenticateParams;
6
+ };
7
+ /**
8
+ * Returns `undefined` if the header is malformed.
9
+ */
10
+ export declare function parseWWWAuthenticateHeader(header?: unknown): undefined | WWWAuthenticate;
11
+ export {};
12
+ //# sourceMappingURL=www-authenticate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"www-authenticate.d.ts","sourceRoot":"","sources":["../src/www-authenticate.ts"],"names":[],"mappings":"AAAA,KAAK,qBAAqB,GAAG;KAAG,SAAS,IAAI,MAAM,GAAG,MAAM;CAAE,CAAA;AAC9D,MAAM,MAAM,eAAe,GAAG;KAC3B,UAAU,IAAI,MAAM,GACjB,MAAM,GACN,qBAAqB;CAC1B,CAAA;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,CAAC,EAAE,OAAO,GACf,SAAS,GAAG,eAAe,CAgE7B"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseWWWAuthenticateHeader = parseWWWAuthenticateHeader;
4
+ /**
5
+ * Returns `undefined` if the header is malformed.
6
+ */
7
+ function parseWWWAuthenticateHeader(header) {
8
+ if (typeof header !== 'string')
9
+ return undefined;
10
+ const wwwAuthenticate = {};
11
+ // Split over commas, not within quoted strings
12
+ const trimmedHeader = header.trim();
13
+ if (!trimmedHeader)
14
+ return wwwAuthenticate;
15
+ const parts = trimmedHeader.split(/,(?=(?:[^"]*"[^"]*")*[^"]*$)/);
16
+ let currentParams = null;
17
+ for (let part of parts) {
18
+ // Check if the part starts with an auth scheme
19
+ const schemeMatch = part.trim().match(/^([^"=\s]+)(\s+.*)?$/);
20
+ if (schemeMatch) {
21
+ const scheme = schemeMatch[1];
22
+ // Duplicate scheme
23
+ if (Object.hasOwn(wwwAuthenticate, scheme))
24
+ return undefined;
25
+ const rest = schemeMatch[2]?.trim();
26
+ if (!rest) {
27
+ // Scheme only (no params or token68)
28
+ currentParams = null;
29
+ wwwAuthenticate[scheme] = Object.create(null);
30
+ continue;
31
+ }
32
+ if (!rest.includes('=')) {
33
+ // Scheme with token68
34
+ currentParams = null;
35
+ wwwAuthenticate[scheme] = rest;
36
+ continue;
37
+ }
38
+ // Scheme with params
39
+ currentParams = Object.create(null);
40
+ wwwAuthenticate[scheme] = currentParams;
41
+ // Fall through to parse params
42
+ part = rest;
43
+ }
44
+ // Invalid header
45
+ if (!currentParams)
46
+ return undefined;
47
+ const param = part.match(/^\s*([^"\s=]+)=(?:("[^"\\]*(?:\\.[^"\\]*)*")|([^\s,"]*))\s*$/);
48
+ // invalid param
49
+ if (!param)
50
+ return undefined;
51
+ const paramName = param[1];
52
+ const paramValue = param[3] ?? param[2].slice(1, -1).replaceAll(/\\(.)/g, '$1');
53
+ currentParams[paramName] = paramValue;
54
+ }
55
+ return wwwAuthenticate;
56
+ }
57
+ //# sourceMappingURL=www-authenticate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"www-authenticate.js","sourceRoot":"","sources":["../src/www-authenticate.ts"],"names":[],"mappings":";;AAUA,gEAkEC;AArED;;GAEG;AACH,SAAgB,0BAA0B,CACxC,MAAgB;IAEhB,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IAEhD,MAAM,eAAe,GAAoB,EAAE,CAAA;IAE3C,+CAA+C;IAC/C,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;IACnC,IAAI,CAAC,aAAa;QAAE,OAAO,eAAe,CAAA;IAE1C,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;IAEjE,IAAI,aAAa,GAAiC,IAAI,CAAA;IAEtD,KAAK,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,+CAA+C;QAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAA;QAC7D,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;YAE7B,mBAAmB;YACnB,IAAI,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC;gBAAE,OAAO,SAAS,CAAA;YAE5D,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAA;YACnC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,qCAAqC;gBACrC,aAAa,GAAG,IAAI,CAAA;gBACpB,eAAe,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBAC7C,SAAQ;YACV,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,sBAAsB;gBACtB,aAAa,GAAG,IAAI,CAAA;gBACpB,eAAe,CAAC,MAAM,CAAC,GAAG,IAAI,CAAA;gBAC9B,SAAQ;YACV,CAAC;YAED,qBAAqB;YAErB,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAA0B,CAAA;YAC5D,eAAe,CAAC,MAAM,CAAC,GAAG,aAAa,CAAA;YAEvC,+BAA+B;YAC/B,IAAI,GAAG,IAAI,CAAA;QACb,CAAC;QAED,iBAAiB;QACjB,IAAI,CAAC,aAAa;YAAE,OAAO,SAAS,CAAA;QAEpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CACtB,8DAA8D,CAC/D,CAAA;QAED,gBAAgB;QAChB,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAA;QAE5B,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1B,MAAM,UAAU,GACd,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAE/D,aAAa,CAAC,SAAS,CAAC,GAAG,UAAU,CAAA;IACvC,CAAC;IAED,OAAO,eAAe,CAAA;AACxB,CAAC","sourcesContent":["type WWWAuthenticateParams = { [authParam in string]: string }\nexport type WWWAuthenticate = {\n [authScheme in string]:\n | string // token68\n | WWWAuthenticateParams\n}\n\n/**\n * Returns `undefined` if the header is malformed.\n */\nexport function parseWWWAuthenticateHeader(\n header?: unknown,\n): undefined | WWWAuthenticate {\n if (typeof header !== 'string') return undefined\n\n const wwwAuthenticate: WWWAuthenticate = {}\n\n // Split over commas, not within quoted strings\n const trimmedHeader = header.trim()\n if (!trimmedHeader) return wwwAuthenticate\n\n const parts = trimmedHeader.split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/)\n\n let currentParams: WWWAuthenticateParams | null = null\n\n for (let part of parts) {\n // Check if the part starts with an auth scheme\n const schemeMatch = part.trim().match(/^([^\"=\\s]+)(\\s+.*)?$/)\n if (schemeMatch) {\n const scheme = schemeMatch[1]\n\n // Duplicate scheme\n if (Object.hasOwn(wwwAuthenticate, scheme)) return undefined\n\n const rest = schemeMatch[2]?.trim()\n if (!rest) {\n // Scheme only (no params or token68)\n currentParams = null\n wwwAuthenticate[scheme] = Object.create(null)\n continue\n }\n\n if (!rest.includes('=')) {\n // Scheme with token68\n currentParams = null\n wwwAuthenticate[scheme] = rest\n continue\n }\n\n // Scheme with params\n\n currentParams = Object.create(null) as WWWAuthenticateParams\n wwwAuthenticate[scheme] = currentParams\n\n // Fall through to parse params\n part = rest\n }\n\n // Invalid header\n if (!currentParams) return undefined\n\n const param = part.match(\n /^\\s*([^\"\\s=]+)=(?:(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")|([^\\s,\"]*))\\s*$/,\n )\n\n // invalid param\n if (!param) return undefined\n\n const paramName = param[1]\n const paramValue =\n param[3] ?? param[2]!.slice(1, -1).replaceAll(/\\\\(.)/g, '$1')\n\n currentParams[paramName] = paramValue\n }\n\n return wwwAuthenticate\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 { XrpcFailure } 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,14 @@ 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>>;
25
24
  /**
26
- * Utility method to type cast the error thrown by {@link xrpc} to an
27
- * {@link LexRpcFailure} matching the provided method. Only use this function
28
- * inside a catch block right after calling {@link xrpc}, and use the same
29
- * method type parameter as used in the {@link xrpc} call.
25
+ * @throws XrpcFailure<M>
30
26
  */
31
- export declare function asLexRpcFailure<M extends Procedure | Query = Procedure | Query>(err: unknown): LexRpcFailure<M>;
32
- /**
33
- * @throws LexRpcFailure<M>
34
- */
35
- export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends LexRpcOptions<M> ? Main<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<LexRpcResponse<M>>;
36
- export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: LexRpcOptions<M>): Promise<LexRpcResponse<M>>;
37
- export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: NonNullable<unknown> extends LexRpcOptions<M> ? Main<M> : Restricted<'This XRPC method requires an "options" argument'>): Promise<LexRpcResult<M>>;
38
- export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: LexRpcOptions<M>): Promise<LexRpcResult<M>>;
27
+ 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>>;
28
+ export declare function xrpc<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: XrpcOptions<M>): Promise<XrpcResponse<M>>;
29
+ export type XrpcResult<M extends Procedure | Query> = XrpcResponse<M> | XrpcFailure<M>;
30
+ 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>>;
31
+ export declare function xrpcSafe<const M extends Query | Procedure>(agent: Agent, ns: Main<M>, options: XrpcOptions<M>): Promise<XrpcResult<M>>;
39
32
  export {};
40
33
  //# 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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"}