@atcute/oauth-types 0.1.0

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 (158) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +48 -0
  3. package/dist/build-client-metadata.d.ts +168 -0
  4. package/dist/build-client-metadata.d.ts.map +1 -0
  5. package/dist/build-client-metadata.js +53 -0
  6. package/dist/build-client-metadata.js.map +1 -0
  7. package/dist/constants.d.ts +5 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +5 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/index.d.ts +31 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +37 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/schemas/atcute-confidential-client-metadata.d.ts +21 -0
  16. package/dist/schemas/atcute-confidential-client-metadata.d.ts.map +1 -0
  17. package/dist/schemas/atcute-confidential-client-metadata.js +112 -0
  18. package/dist/schemas/atcute-confidential-client-metadata.js.map +1 -0
  19. package/dist/schemas/atproto-authorization-server-metadata.d.ts +55 -0
  20. package/dist/schemas/atproto-authorization-server-metadata.d.ts.map +1 -0
  21. package/dist/schemas/atproto-authorization-server-metadata.js +25 -0
  22. package/dist/schemas/atproto-authorization-server-metadata.js.map +1 -0
  23. package/dist/schemas/atproto-oauth-scope.d.ts +8 -0
  24. package/dist/schemas/atproto-oauth-scope.d.ts.map +1 -0
  25. package/dist/schemas/atproto-oauth-scope.js +12 -0
  26. package/dist/schemas/atproto-oauth-scope.js.map +1 -0
  27. package/dist/schemas/atproto-oauth-token-response.d.ts +19 -0
  28. package/dist/schemas/atproto-oauth-token-response.d.ts.map +1 -0
  29. package/dist/schemas/atproto-oauth-token-response.js +16 -0
  30. package/dist/schemas/atproto-oauth-token-response.js.map +1 -0
  31. package/dist/schemas/atproto-protected-resource-metadata.d.ts +21 -0
  32. package/dist/schemas/atproto-protected-resource-metadata.d.ts.map +1 -0
  33. package/dist/schemas/atproto-protected-resource-metadata.js +18 -0
  34. package/dist/schemas/atproto-protected-resource-metadata.js.map +1 -0
  35. package/dist/schemas/jwk.d.ts +241 -0
  36. package/dist/schemas/jwk.d.ts.map +1 -0
  37. package/dist/schemas/jwk.js +138 -0
  38. package/dist/schemas/jwk.js.map +1 -0
  39. package/dist/schemas/jwks.d.ts +242 -0
  40. package/dist/schemas/jwks.d.ts.map +1 -0
  41. package/dist/schemas/jwks.js +34 -0
  42. package/dist/schemas/jwks.js.map +1 -0
  43. package/dist/schemas/oauth-authorization-details.d.ts +64 -0
  44. package/dist/schemas/oauth-authorization-details.d.ts.map +1 -0
  45. package/dist/schemas/oauth-authorization-details.js +37 -0
  46. package/dist/schemas/oauth-authorization-details.js.map +1 -0
  47. package/dist/schemas/oauth-authorization-server-metadata.d.ts +96 -0
  48. package/dist/schemas/oauth-authorization-server-metadata.d.ts.map +1 -0
  49. package/dist/schemas/oauth-authorization-server-metadata.js +81 -0
  50. package/dist/schemas/oauth-authorization-server-metadata.js.map +1 -0
  51. package/dist/schemas/oauth-client-id-discoverable.d.ts +6 -0
  52. package/dist/schemas/oauth-client-id-discoverable.d.ts.map +1 -0
  53. package/dist/schemas/oauth-client-id-discoverable.js +43 -0
  54. package/dist/schemas/oauth-client-id-discoverable.js.map +1 -0
  55. package/dist/schemas/oauth-client-id.d.ts +5 -0
  56. package/dist/schemas/oauth-client-id.d.ts.map +1 -0
  57. package/dist/schemas/oauth-client-id.js +4 -0
  58. package/dist/schemas/oauth-client-id.js.map +1 -0
  59. package/dist/schemas/oauth-client-metadata.d.ts +164 -0
  60. package/dist/schemas/oauth-client-metadata.d.ts.map +1 -0
  61. package/dist/schemas/oauth-client-metadata.js +74 -0
  62. package/dist/schemas/oauth-client-metadata.js.map +1 -0
  63. package/dist/schemas/oauth-code-challenge-method.d.ts +4 -0
  64. package/dist/schemas/oauth-code-challenge-method.d.ts.map +1 -0
  65. package/dist/schemas/oauth-code-challenge-method.js +3 -0
  66. package/dist/schemas/oauth-code-challenge-method.js.map +1 -0
  67. package/dist/schemas/oauth-endpoint-auth-method.d.ts +4 -0
  68. package/dist/schemas/oauth-endpoint-auth-method.d.ts.map +1 -0
  69. package/dist/schemas/oauth-endpoint-auth-method.js +3 -0
  70. package/dist/schemas/oauth-endpoint-auth-method.js.map +1 -0
  71. package/dist/schemas/oauth-grant-type.d.ts +4 -0
  72. package/dist/schemas/oauth-grant-type.d.ts.map +1 -0
  73. package/dist/schemas/oauth-grant-type.js +4 -0
  74. package/dist/schemas/oauth-grant-type.js.map +1 -0
  75. package/dist/schemas/oauth-issuer-identifier.d.ts +4 -0
  76. package/dist/schemas/oauth-issuer-identifier.d.ts.map +1 -0
  77. package/dist/schemas/oauth-issuer-identifier.js +21 -0
  78. package/dist/schemas/oauth-issuer-identifier.js.map +1 -0
  79. package/dist/schemas/oauth-par-response.d.ts +7 -0
  80. package/dist/schemas/oauth-par-response.d.ts.map +1 -0
  81. package/dist/schemas/oauth-par-response.js +7 -0
  82. package/dist/schemas/oauth-par-response.js.map +1 -0
  83. package/dist/schemas/oauth-prompt.d.ts +13 -0
  84. package/dist/schemas/oauth-prompt.d.ts.map +1 -0
  85. package/dist/schemas/oauth-prompt.js +12 -0
  86. package/dist/schemas/oauth-prompt.js.map +1 -0
  87. package/dist/schemas/oauth-protected-resource-metadata.d.ts +66 -0
  88. package/dist/schemas/oauth-protected-resource-metadata.d.ts.map +1 -0
  89. package/dist/schemas/oauth-protected-resource-metadata.js +71 -0
  90. package/dist/schemas/oauth-protected-resource-metadata.js.map +1 -0
  91. package/dist/schemas/oauth-redirect-uri.d.ts +20 -0
  92. package/dist/schemas/oauth-redirect-uri.d.ts.map +1 -0
  93. package/dist/schemas/oauth-redirect-uri.js +32 -0
  94. package/dist/schemas/oauth-redirect-uri.js.map +1 -0
  95. package/dist/schemas/oauth-response-mode.d.ts +4 -0
  96. package/dist/schemas/oauth-response-mode.d.ts.map +1 -0
  97. package/dist/schemas/oauth-response-mode.js +3 -0
  98. package/dist/schemas/oauth-response-mode.js.map +1 -0
  99. package/dist/schemas/oauth-response-type.d.ts +4 -0
  100. package/dist/schemas/oauth-response-type.d.ts.map +1 -0
  101. package/dist/schemas/oauth-response-type.js +8 -0
  102. package/dist/schemas/oauth-response-type.js.map +1 -0
  103. package/dist/schemas/oauth-scope.d.ts +12 -0
  104. package/dist/schemas/oauth-scope.d.ts.map +1 -0
  105. package/dist/schemas/oauth-scope.js +14 -0
  106. package/dist/schemas/oauth-scope.js.map +1 -0
  107. package/dist/schemas/oauth-token-response.d.ts +22 -0
  108. package/dist/schemas/oauth-token-response.d.ts.map +1 -0
  109. package/dist/schemas/oauth-token-response.js +19 -0
  110. package/dist/schemas/oauth-token-response.js.map +1 -0
  111. package/dist/schemas/oauth-token-type.d.ts +5 -0
  112. package/dist/schemas/oauth-token-type.d.ts.map +1 -0
  113. package/dist/schemas/oauth-token-type.js +13 -0
  114. package/dist/schemas/oauth-token-type.js.map +1 -0
  115. package/dist/schemas/uri.d.ts +18 -0
  116. package/dist/schemas/uri.d.ts.map +1 -0
  117. package/dist/schemas/uri.js +81 -0
  118. package/dist/schemas/uri.js.map +1 -0
  119. package/dist/schemas/utils.d.ts +32 -0
  120. package/dist/schemas/utils.d.ts.map +1 -0
  121. package/dist/schemas/utils.js +94 -0
  122. package/dist/schemas/utils.js.map +1 -0
  123. package/dist/scope.d.ts +84 -0
  124. package/dist/scope.d.ts.map +1 -0
  125. package/dist/scope.js +102 -0
  126. package/dist/scope.js.map +1 -0
  127. package/lib/build-client-metadata.ts +72 -0
  128. package/lib/constants.ts +5 -0
  129. package/lib/index.ts +116 -0
  130. package/lib/schemas/atcute-confidential-client-metadata.ts +139 -0
  131. package/lib/schemas/atproto-authorization-server-metadata.ts +32 -0
  132. package/lib/schemas/atproto-oauth-scope.ts +18 -0
  133. package/lib/schemas/atproto-oauth-token-response.ts +20 -0
  134. package/lib/schemas/atproto-protected-resource-metadata.ts +24 -0
  135. package/lib/schemas/jwk.ts +189 -0
  136. package/lib/schemas/jwks.ts +45 -0
  137. package/lib/schemas/oauth-authorization-details.ts +43 -0
  138. package/lib/schemas/oauth-authorization-server-metadata.ts +101 -0
  139. package/lib/schemas/oauth-client-id-discoverable.ts +53 -0
  140. package/lib/schemas/oauth-client-id.ts +6 -0
  141. package/lib/schemas/oauth-client-metadata.ts +83 -0
  142. package/lib/schemas/oauth-code-challenge-method.ts +5 -0
  143. package/lib/schemas/oauth-endpoint-auth-method.ts +13 -0
  144. package/lib/schemas/oauth-grant-type.ts +13 -0
  145. package/lib/schemas/oauth-issuer-identifier.ts +30 -0
  146. package/lib/schemas/oauth-par-response.ts +10 -0
  147. package/lib/schemas/oauth-prompt.ts +20 -0
  148. package/lib/schemas/oauth-protected-resource-metadata.ts +89 -0
  149. package/lib/schemas/oauth-redirect-uri.ts +42 -0
  150. package/lib/schemas/oauth-response-mode.ts +9 -0
  151. package/lib/schemas/oauth-response-type.ts +17 -0
  152. package/lib/schemas/oauth-scope.ts +18 -0
  153. package/lib/schemas/oauth-token-response.ts +22 -0
  154. package/lib/schemas/oauth-token-type.ts +15 -0
  155. package/lib/schemas/uri.ts +100 -0
  156. package/lib/schemas/utils.ts +113 -0
  157. package/lib/scope.ts +187 -0
  158. package/package.json +38 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-redirect-uri.js","sourceRoot":"","sources":["../../lib/schemas/oauth-redirect-uri.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAElF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IAC3E,IAAI,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,CAAC,GAAG,CACX,sGAAsG,CACtG,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AAAA,CACnB,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC;IAC1E,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACjC,OAAO,yBAAyB,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,OAAO,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAAA,CAC/C,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import * as v from '@badrap/valita';
2
+ export declare const oauthResponseModeSchema: v.UnionType<[v.Type<"query">, v.Type<"fragment">, v.Type<"form_post">]>;
3
+ export type OAuthResponseMode = v.Infer<typeof oauthResponseModeSchema>;
4
+ //# sourceMappingURL=oauth-response-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-response-mode.d.ts","sourceRoot":"","sources":["../../lib/schemas/oauth-response-mode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,eAAO,MAAM,uBAAuB,yEAInC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import * as v from '@badrap/valita';
2
+ export const oauthResponseModeSchema = v.union(v.literal('query'), v.literal('fragment'), v.literal('form_post'));
3
+ //# sourceMappingURL=oauth-response-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-response-mode.js","sourceRoot":"","sources":["../../lib/schemas/oauth-response-mode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC7C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAClB,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EACrB,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CACtB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import * as v from '@badrap/valita';
2
+ export declare const oauthResponseTypeSchema: v.UnionType<[v.Type<"code">, v.Type<"token">, v.Type<"none">, v.Type<"code id_token token">, v.Type<"code id_token">, v.Type<"code token">, v.Type<"id_token token">, v.Type<"id_token">]>;
3
+ export type OAuthResponseType = v.Infer<typeof oauthResponseTypeSchema>;
4
+ //# sourceMappingURL=oauth-response-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-response-type.d.ts","sourceRoot":"","sources":["../../lib/schemas/oauth-response-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,eAAO,MAAM,uBAAuB,4LAYnC,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import * as v from '@badrap/valita';
2
+ export const oauthResponseTypeSchema = v.union(
3
+ // OAuth2 (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-10#section-4.1.1)
4
+ v.literal('code'), // Authorization Code Grant
5
+ v.literal('token'), // Implicit Grant
6
+ // OIDC (https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html)
7
+ v.literal('none'), v.literal('code id_token token'), v.literal('code id_token'), v.literal('code token'), v.literal('id_token token'), v.literal('id_token'));
8
+ //# sourceMappingURL=oauth-response-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-response-type.js","sourceRoot":"","sources":["../../lib/schemas/oauth-response-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK;AAC7C,wFAAwF;AACxF,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,2BAA2B;AAC9C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,iBAAiB;AAErC,4EAA4E;AAC5E,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EACjB,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAChC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,EAC1B,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,EACvB,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAC3B,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CACrB,CAAC"}
@@ -0,0 +1,12 @@
1
+ import * as v from '@badrap/valita';
2
+ export declare const OAUTH_SCOPE_REGEXP: RegExp;
3
+ export declare const isOAuthScope: (input: string) => boolean;
4
+ /**
5
+ * a (single) space separated list of non empty printable ASCII char string
6
+ * (except backslash and double quote).
7
+ *
8
+ * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-1.4.1}
9
+ */
10
+ export declare const oauthScopeSchema: v.Type<string>;
11
+ export type OAuthScope = v.Infer<typeof oauthScopeSchema>;
12
+ //# sourceMappingURL=oauth-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-scope.d.ts","sourceRoot":"","sources":["../../lib/schemas/oauth-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAKpC,eAAO,MAAM,kBAAkB,QAA+D,CAAC;AAE/F,eAAO,MAAM,YAAY,4BAA6D,CAAC;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,gBAAyD,CAAC;AAEvF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import * as v from '@badrap/valita';
2
+ // scope = scope-token *( SP scope-token )
3
+ // scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
4
+ // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-1.4.1
5
+ export const OAUTH_SCOPE_REGEXP = /^[\x21\x23-\x5B\x5D-\x7E]+(?: [\x21\x23-\x5B\x5D-\x7E]+)*$/;
6
+ export const isOAuthScope = (input) => OAUTH_SCOPE_REGEXP.test(input);
7
+ /**
8
+ * a (single) space separated list of non empty printable ASCII char string
9
+ * (except backslash and double quote).
10
+ *
11
+ * @see {@link https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-11#section-1.4.1}
12
+ */
13
+ export const oauthScopeSchema = v.string().assert(isOAuthScope, `invalid OAuth scope`);
14
+ //# sourceMappingURL=oauth-scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-scope.js","sourceRoot":"","sources":["../../lib/schemas/oauth-scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,gDAAgD;AAChD,+CAA+C;AAC/C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG,4DAA4D,CAAC;AAE/F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as v from '@badrap/valita';
2
+ /**
3
+ * @see {@link https://www.rfc-editor.org/rfc/rfc6749.html#section-5.1 | RFC 6749 (OAuth2), Section 5.1}
4
+ */
5
+ export declare const oauthTokenResponseSchema: v.ObjectType<{
6
+ access_token: v.Type<string>;
7
+ token_type: v.Type<"Bearer" | "DPoP">;
8
+ scope: v.Optional<string>;
9
+ refresh_token: v.Optional<string>;
10
+ expires_in: v.Optional<number>;
11
+ id_token: v.Optional<string>;
12
+ authorization_details: v.Optional<{
13
+ type: string;
14
+ locations?: string[] | undefined;
15
+ actions?: string[] | undefined;
16
+ datatypes?: string[] | undefined;
17
+ identifier?: string | undefined;
18
+ privileges?: string[] | undefined;
19
+ }[]>;
20
+ }, undefined>;
21
+ export type OAuthTokenResponse = v.Infer<typeof oauthTokenResponseSchema>;
22
+ //# sourceMappingURL=oauth-token-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-response.d.ts","sourceRoot":"","sources":["../../lib/schemas/oauth-token-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAKpC;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;aAWnC,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import * as v from '@badrap/valita';
2
+ import { oauthAuthorizationDetailsSchema } from './oauth-authorization-details.js';
3
+ import { oauthTokenTypeSchema } from './oauth-token-type.js';
4
+ /**
5
+ * @see {@link https://www.rfc-editor.org/rfc/rfc6749.html#section-5.1 | RFC 6749 (OAuth2), Section 5.1}
6
+ */
7
+ export const oauthTokenResponseSchema = v.object({
8
+ // https://www.rfc-editor.org/rfc/rfc6749.html#section-5.1
9
+ access_token: v.string(),
10
+ token_type: oauthTokenTypeSchema,
11
+ scope: v.string().optional(),
12
+ refresh_token: v.string().optional(),
13
+ expires_in: v.number().optional(),
14
+ // https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
15
+ id_token: v.string().optional(),
16
+ // https://datatracker.ietf.org/doc/html/rfc9396#name-enriched-authorization-deta
17
+ authorization_details: oauthAuthorizationDetailsSchema.optional(),
18
+ });
19
+ //# sourceMappingURL=oauth-token-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-response.js","sourceRoot":"","sources":["../../lib/schemas/oauth-token-response.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChD,0DAA0D;IAC1D,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,UAAU,EAAE,oBAAoB;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,sEAAsE;IACtE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,iFAAiF;IACjF,qBAAqB,EAAE,+BAA+B,CAAC,QAAQ,EAAE;CACjE,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import * as v from '@badrap/valita';
2
+ /** token type (case-insensitive input, normalized output) */
3
+ export declare const oauthTokenTypeSchema: v.Type<"Bearer" | "DPoP">;
4
+ export type OAuthTokenType = v.Infer<typeof oauthTokenTypeSchema>;
5
+ //# sourceMappingURL=oauth-token-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-type.d.ts","sourceRoot":"","sources":["../../lib/schemas/oauth-token-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,2BAS/B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import * as v from '@badrap/valita';
2
+ /** token type (case-insensitive input, normalized output) */
3
+ export const oauthTokenTypeSchema = v.string().chain((input) => {
4
+ const lower = input.toLowerCase();
5
+ if (lower === 'dpop') {
6
+ return v.ok('DPoP');
7
+ }
8
+ if (lower === 'bearer') {
9
+ return v.ok('Bearer');
10
+ }
11
+ return v.err(`must be "DPoP" or "Bearer"`);
12
+ });
13
+ //# sourceMappingURL=oauth-token-type.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-token-type.js","sourceRoot":"","sources":["../../lib/schemas/oauth-token-type.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAEpC,6DAA6D;AAC7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAAA,CAC3C,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import * as v from '@badrap/valita';
2
+ /**
3
+ * valid, but potentially dangerous URL (`data:`, `file:`, `javascript:`, etc.).
4
+ *
5
+ * any value that matches this schema is safe to parse using `new URL()`.
6
+ */
7
+ export declare const urlSchema: v.Type<string>;
8
+ /** loopback URL (http://localhost, http://127.0.0.1, http://[::1]) */
9
+ export declare const loopbackUriSchema: v.Type<string>;
10
+ /** HTTPS URL with additional restrictions */
11
+ export declare const httpsUriSchema: v.Type<string>;
12
+ /** web URL (either loopback http or https) */
13
+ export declare const webUriSchema: v.Type<string>;
14
+ /** web URL with a non-local hostname */
15
+ export declare const nonLocalWebUriSchema: v.Type<string>;
16
+ /** private-use URI scheme (e.g., com.example.app:/callback) */
17
+ export declare const privateUseUriSchema: v.Type<string>;
18
+ //# sourceMappingURL=uri.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.d.ts","sourceRoot":"","sources":["../../lib/schemas/uri.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AAIpC;;;;GAIG;AACH,eAAO,MAAM,SAAS,gBAKpB,CAAC;AAEH,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,gBAW5B,CAAC;AAEH,6CAA6C;AAC7C,eAAO,MAAM,cAAc,gBAqBzB,CAAC;AAEH,8CAA8C;AAC9C,eAAO,MAAM,YAAY,gBAUvB,CAAC;AAEH,wCAAwC;AACxC,eAAO,MAAM,oBAAoB,gBAM/B,CAAC;AAEH,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,gBAsB9B,CAAC"}
@@ -0,0 +1,81 @@
1
+ import * as v from '@badrap/valita';
2
+ import { isHostnameIP, isLocalHostname, isLoopbackHost } from './utils.js';
3
+ /**
4
+ * valid, but potentially dangerous URL (`data:`, `file:`, `javascript:`, etc.).
5
+ *
6
+ * any value that matches this schema is safe to parse using `new URL()`.
7
+ */
8
+ export const urlSchema = v.string().chain((input) => {
9
+ if (input.includes(':') && URL.canParse(input)) {
10
+ return v.ok(input);
11
+ }
12
+ return v.err(`must be a valid url`);
13
+ });
14
+ /** loopback URL (http://localhost, http://127.0.0.1, http://[::1]) */
15
+ export const loopbackUriSchema = urlSchema.chain((input) => {
16
+ if (!input.startsWith('http://')) {
17
+ return v.err(`loopback url must use http: protocol`);
18
+ }
19
+ const url = new URL(input);
20
+ if (!isLoopbackHost(url.hostname)) {
21
+ return v.err(`loopback url must use localhost, 127.0.0.1, or [::1] as hostname`);
22
+ }
23
+ return v.ok(input);
24
+ });
25
+ /** HTTPS URL with additional restrictions */
26
+ export const httpsUriSchema = urlSchema.chain((input) => {
27
+ if (!input.startsWith('https://')) {
28
+ return v.err(`url must use https: protocol`);
29
+ }
30
+ const url = new URL(input);
31
+ if (isLoopbackHost(url.hostname)) {
32
+ return v.err(`https url must not use a loopback host`);
33
+ }
34
+ if (!isHostnameIP(url.hostname)) {
35
+ if (!url.hostname.includes('.')) {
36
+ return v.err(`domain name must contain at least two segments`);
37
+ }
38
+ if (url.hostname.endsWith('.local')) {
39
+ return v.err(`domain name must not end with .local`);
40
+ }
41
+ }
42
+ return v.ok(input);
43
+ });
44
+ /** web URL (either loopback http or https) */
45
+ export const webUriSchema = urlSchema.chain((input, options) => {
46
+ if (input.startsWith('http://')) {
47
+ return loopbackUriSchema.try(input, options);
48
+ }
49
+ if (input.startsWith('https://')) {
50
+ return httpsUriSchema.try(input, options);
51
+ }
52
+ return v.err(`url must use http: or https: protocol`);
53
+ });
54
+ /** web URL with a non-local hostname */
55
+ export const nonLocalWebUriSchema = webUriSchema.chain((input) => {
56
+ const url = new URL(input);
57
+ if (isLocalHostname(url.hostname)) {
58
+ return v.err(`hostname is invalid`);
59
+ }
60
+ return v.ok(input);
61
+ });
62
+ /** private-use URI scheme (e.g., com.example.app:/callback) */
63
+ export const privateUseUriSchema = urlSchema.chain((input) => {
64
+ const dotIdx = input.indexOf('.');
65
+ const colonIdx = input.indexOf(':');
66
+ if (dotIdx === -1 || colonIdx === -1 || dotIdx > colonIdx) {
67
+ return v.err(`private-use uri scheme must contain a dot in the protocol`);
68
+ }
69
+ const url = new URL(input);
70
+ const scheme = url.protocol.slice(0, -1);
71
+ const domain = scheme.split('.').reverse().join('.');
72
+ if (isLocalHostname(domain)) {
73
+ return v.err(`private-use uri scheme must not be a local hostname`);
74
+ }
75
+ // RFC 8252: private-use URIs must use single slash after scheme
76
+ if (url.href.startsWith(`${url.protocol}//`) || url.username || url.password || url.hostname || url.port) {
77
+ return v.err(`private-use uri must be in the form scheme:/<path>`);
78
+ }
79
+ return v.ok(input);
80
+ });
81
+ //# sourceMappingURL=uri.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uri.js","sourceRoot":"","sources":["../../lib/schemas/uri.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * checks if a hostname is a loopback address
3
+ */
4
+ export declare const isLoopbackHost: (hostname: string) => boolean;
5
+ /**
6
+ * checks if a hostname is an IP address (IPv4 or IPv6)
7
+ */
8
+ export declare const isHostnameIP: (hostname: string) => boolean;
9
+ /**
10
+ * checks if a hostname is a local/reserved hostname
11
+ *
12
+ * returns true for single-segment hostnames and reserved TLDs
13
+ */
14
+ export declare const isLocalHostname: (hostname: string) => boolean;
15
+ /**
16
+ * extracts the path from a URL without relying on URL constructor normalization
17
+ *
18
+ * this is needed because the URL constructor normalizes paths (e.g., removes `.` and `..` segments),
19
+ * which can be used to bypass validation checks
20
+ */
21
+ export declare const extractUrlPath: (url: string) => string;
22
+ /**
23
+ * checks if an item is the last occurrence in an array (for duplicate detection)
24
+ */
25
+ export declare const isLastOccurrence: <T>(item: T, index: number, array: readonly T[]) => boolean;
26
+ /**
27
+ * checks if a space-separated string contains a specific value
28
+ *
29
+ * optimized version of `input.split(' ').includes(value)`
30
+ */
31
+ export declare const isSpaceSeparatedValue: (value: string, input: string) => boolean;
32
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../lib/schemas/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,cAAc,+BAE1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,+BAUxB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,+BAQ3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,yBA4B1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,yDAEjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,2CA2BjC,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * checks if a hostname is a loopback address
3
+ */
4
+ export const isLoopbackHost = (hostname) => {
5
+ return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]';
6
+ };
7
+ /**
8
+ * checks if a hostname is an IP address (IPv4 or IPv6)
9
+ */
10
+ export const isHostnameIP = (hostname) => {
11
+ // IPv4
12
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(hostname)) {
13
+ return true;
14
+ }
15
+ // IPv6
16
+ if (hostname.startsWith('[') && hostname.endsWith(']')) {
17
+ return true;
18
+ }
19
+ return false;
20
+ };
21
+ /**
22
+ * checks if a hostname is a local/reserved hostname
23
+ *
24
+ * returns true for single-segment hostnames and reserved TLDs
25
+ */
26
+ export const isLocalHostname = (hostname) => {
27
+ const parts = hostname.split('.');
28
+ if (parts.length < 2) {
29
+ return true;
30
+ }
31
+ const tld = parts.at(-1).toLowerCase();
32
+ return tld === 'test' || tld === 'local' || tld === 'localhost' || tld === 'invalid' || tld === 'example';
33
+ };
34
+ /**
35
+ * extracts the path from a URL without relying on URL constructor normalization
36
+ *
37
+ * this is needed because the URL constructor normalizes paths (e.g., removes `.` and `..` segments),
38
+ * which can be used to bypass validation checks
39
+ */
40
+ export const extractUrlPath = (url) => {
41
+ const endOfProtocol = url.startsWith('https://') ? 8 : url.startsWith('http://') ? 7 : -1;
42
+ if (endOfProtocol === -1) {
43
+ throw new TypeError(`url must use https: or http: protocol`);
44
+ }
45
+ const hashIdx = url.indexOf('#', endOfProtocol);
46
+ const questionIdx = url.indexOf('?', endOfProtocol);
47
+ const queryStrIdx = questionIdx !== -1 && (hashIdx === -1 || questionIdx < hashIdx) ? questionIdx : -1;
48
+ const pathEnd = hashIdx === -1
49
+ ? queryStrIdx === -1
50
+ ? url.length
51
+ : queryStrIdx
52
+ : queryStrIdx === -1
53
+ ? hashIdx
54
+ : Math.min(hashIdx, queryStrIdx);
55
+ const slashIdx = url.indexOf('/', endOfProtocol);
56
+ const pathStart = slashIdx === -1 || slashIdx > pathEnd ? pathEnd : slashIdx;
57
+ if (endOfProtocol === pathStart) {
58
+ throw new TypeError(`url must contain a host`);
59
+ }
60
+ return url.substring(pathStart, pathEnd) || '/';
61
+ };
62
+ /**
63
+ * checks if an item is the last occurrence in an array (for duplicate detection)
64
+ */
65
+ export const isLastOccurrence = (item, index, array) => {
66
+ return array.lastIndexOf(item) === index;
67
+ };
68
+ /**
69
+ * checks if a space-separated string contains a specific value
70
+ *
71
+ * optimized version of `input.split(' ').includes(value)`
72
+ */
73
+ export const isSpaceSeparatedValue = (value, input) => {
74
+ const inputLength = input.length;
75
+ const valueLength = value.length;
76
+ if (inputLength < valueLength) {
77
+ return false;
78
+ }
79
+ let idx = input.indexOf(value);
80
+ let idxEnd;
81
+ while (idx !== -1) {
82
+ idxEnd = idx + valueLength;
83
+ if (
84
+ // at beginning or preceded by space
85
+ (idx === 0 || input.charCodeAt(idx - 1) === 32) &&
86
+ // at end or followed by space
87
+ (idxEnd === inputLength || input.charCodeAt(idxEnd) === 32)) {
88
+ return true;
89
+ }
90
+ idx = input.indexOf(value, idxEnd + 1);
91
+ }
92
+ return false;
93
+ };
94
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/schemas/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import type { AtprotoAudience, Nsid } from '@atcute/lexicons/syntax';
2
+ /** repo record actions */
3
+ export type RepoAction = 'create' | 'update' | 'delete';
4
+ /** account attributes */
5
+ export type AccountAttr = 'email' | 'repo' | 'status';
6
+ /** account actions */
7
+ export type AccountAction = 'read' | 'manage';
8
+ /** identity attributes */
9
+ export type IdentityAttr = 'handle' | '*';
10
+ /** collection parameter - NSID or wildcard */
11
+ export type CollectionParam = Nsid | '*';
12
+ /** lexicon method parameter - NSID or wildcard */
13
+ export type LxmParam = Nsid | '*';
14
+ /** audience parameter - atproto audience or wildcard */
15
+ export type AudParam = AtprotoAudience | '*';
16
+ export interface RepoOptions {
17
+ /** collection NSID(s) or '*' for all */
18
+ collection: CollectionParam[];
19
+ /** allowed actions; if omitted, all operations are permitted */
20
+ action?: RepoAction[];
21
+ }
22
+ /**
23
+ * builds a repo permission scope
24
+ * @param options repo permission options
25
+ * @returns scope string like `repo?collection=app.bsky.feed.post&action=create&action=update`
26
+ */
27
+ export declare const repo: (options: RepoOptions) => string;
28
+ export interface RpcOptions {
29
+ /** lexicon method NSID(s) or '*' for all */
30
+ lxm: LxmParam[];
31
+ /** audience */
32
+ aud: AudParam;
33
+ }
34
+ /**
35
+ * builds an rpc permission scope
36
+ * @param options rpc permission options
37
+ * @returns scope string like `rpc?lxm=app.bsky.feed.getFeed&aud=*`
38
+ */
39
+ export declare const rpc: (options: RpcOptions) => string;
40
+ export interface AccountOptions {
41
+ /** account attribute (email, repo, status) */
42
+ attr: AccountAttr;
43
+ /** action (read or manage); defaults to read */
44
+ action?: AccountAction;
45
+ }
46
+ /**
47
+ * builds an account permission scope
48
+ * @param options account permission options
49
+ * @returns scope string like `account?attr=email` or `account?attr=email&action=manage`
50
+ */
51
+ export declare const account: (options: AccountOptions) => string;
52
+ export interface BlobOptions {
53
+ /** MIME type(s) to accept (e.g., 'image/*', '*\/*') */
54
+ accept: string[];
55
+ }
56
+ /**
57
+ * builds a blob permission scope
58
+ * @param options blob permission options
59
+ * @returns scope string like `blob?accept=image/*`
60
+ */
61
+ export declare const blob: (options: BlobOptions) => string;
62
+ export interface IdentityOptions {
63
+ /** identity attribute ('handle' or '*') */
64
+ attr: IdentityAttr;
65
+ }
66
+ /**
67
+ * builds an identity permission scope
68
+ * @param options identity permission options
69
+ * @returns scope string like `identity?attr=handle`
70
+ */
71
+ export declare const identity: (options: IdentityOptions) => string;
72
+ export interface IncludeOptions {
73
+ /** lexicon NSID */
74
+ nsid: Nsid;
75
+ /** optional audience override */
76
+ aud?: AtprotoAudience;
77
+ }
78
+ /**
79
+ * builds an include scope for lexicon-defined permission sets
80
+ * @param options include scope options
81
+ * @returns scope string like `include?nsid=app.bsky.permissions&aud=did:web:bsky.app%23appview`
82
+ */
83
+ export declare const include: (options: IncludeOptions) => string;
84
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../lib/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAErE,0BAA0B;AAC1B,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,yBAAyB;AACzB,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEtD,sBAAsB;AACtB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE9C,0BAA0B;AAC1B,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,GAAG,CAAC;AAE1C,8CAA8C;AAC9C,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,GAAG,CAAC;AAEzC,kDAAkD;AAClD,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,GAAG,CAAC;AAElC,wDAAwD;AACxD,MAAM,MAAM,QAAQ,GAAG,eAAe,GAAG,GAAG,CAAC;AAE7C,MAAM,WAAW,WAAW;IAC3B,wCAAwC;IACxC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,gEAAgE;IAChE,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,kCAahB,CAAC;AAEF,MAAM,WAAW,UAAU;IAC1B,4CAA4C;IAC5C,GAAG,EAAE,QAAQ,EAAE,CAAC;IAChB,eAAe;IACf,GAAG,EAAE,QAAQ,CAAC;CACd;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,iCAWf,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B,8CAA8C;IAC9C,IAAI,EAAE,WAAW,CAAC;IAClB,gDAAgD;IAChD,MAAM,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO,qCAWnB,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B,uDAAuD;IACvD,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,IAAI,kCAUhB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC/B,2CAA2C;IAC3C,IAAI,EAAE,YAAY,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,sCAKpB,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B,mBAAmB;IACnB,IAAI,EAAE,IAAI,CAAC;IACX,iCAAiC;IACjC,GAAG,CAAC,EAAE,eAAe,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,OAAO,qCAWnB,CAAC"}
package/dist/scope.js ADDED
@@ -0,0 +1,102 @@
1
+ /**
2
+ * builds a repo permission scope
3
+ * @param options repo permission options
4
+ * @returns scope string like `repo?collection=app.bsky.feed.post&action=create&action=update`
5
+ */
6
+ export const repo = (options) => {
7
+ const { collection, action = [] } = options;
8
+ const params = new URLSearchParams();
9
+ for (const c of collection) {
10
+ params.append('collection', c);
11
+ }
12
+ for (const a of action) {
13
+ params.append('action', a);
14
+ }
15
+ return formatScope('repo', params);
16
+ };
17
+ /**
18
+ * builds an rpc permission scope
19
+ * @param options rpc permission options
20
+ * @returns scope string like `rpc?lxm=app.bsky.feed.getFeed&aud=*`
21
+ */
22
+ export const rpc = (options) => {
23
+ const { lxm, aud } = options;
24
+ const params = new URLSearchParams();
25
+ params.set('aud', aud);
26
+ for (const l of lxm) {
27
+ params.append('lxm', l);
28
+ }
29
+ return formatScope('rpc', params);
30
+ };
31
+ /**
32
+ * builds an account permission scope
33
+ * @param options account permission options
34
+ * @returns scope string like `account?attr=email` or `account?attr=email&action=manage`
35
+ */
36
+ export const account = (options) => {
37
+ const { attr, action } = options;
38
+ const params = new URLSearchParams();
39
+ params.set('attr', attr);
40
+ if (action !== undefined) {
41
+ params.set('action', action);
42
+ }
43
+ return formatScope('account', params);
44
+ };
45
+ /**
46
+ * builds a blob permission scope
47
+ * @param options blob permission options
48
+ * @returns scope string like `blob?accept=image/*`
49
+ */
50
+ export const blob = (options) => {
51
+ const { accept } = options;
52
+ const params = new URLSearchParams();
53
+ for (const a of accept) {
54
+ params.append('accept', a);
55
+ }
56
+ return formatScope('blob', params);
57
+ };
58
+ /**
59
+ * builds an identity permission scope
60
+ * @param options identity permission options
61
+ * @returns scope string like `identity?attr=handle`
62
+ */
63
+ export const identity = (options) => {
64
+ const params = new URLSearchParams();
65
+ params.set('attr', options.attr);
66
+ return formatScope('identity', params);
67
+ };
68
+ /**
69
+ * builds an include scope for lexicon-defined permission sets
70
+ * @param options include scope options
71
+ * @returns scope string like `include?nsid=app.bsky.permissions&aud=did:web:bsky.app%23appview`
72
+ */
73
+ export const include = (options) => {
74
+ const { nsid, aud } = options;
75
+ const params = new URLSearchParams();
76
+ params.set('nsid', nsid);
77
+ if (aud !== undefined) {
78
+ params.set('aud', aud);
79
+ }
80
+ return formatScope('include', params);
81
+ };
82
+ // characters that should remain unencoded in scope strings
83
+ const ALLOWED_CHARS = new Set([':', '/', '+', ',', '@', '%']);
84
+ // format a scope string matching atproto oauth-scopes format
85
+ const formatScope = (prefix, params) => {
86
+ if (params.size === 0) {
87
+ return prefix;
88
+ }
89
+ return `${prefix}?${normalizeEncoding(params.toString())}`;
90
+ };
91
+ // normalize URL encoding to match atproto format
92
+ // keeps : / + , @ unencoded, but # must stay as %23
93
+ const normalizeEncoding = (value) => {
94
+ return value.replace(/%[0-9A-F]{2}/gi, (match) => {
95
+ const char = decodeURIComponent(match);
96
+ if (ALLOWED_CHARS.has(char)) {
97
+ return char;
98
+ }
99
+ return match.toUpperCase();
100
+ });
101
+ };
102
+ //# sourceMappingURL=scope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../lib/scope.ts"],"names":[],"mappings":"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"}