@atproto/oauth-client-expo 0.0.1

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 (81) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE.txt +7 -0
  3. package/README.md +140 -0
  4. package/android/.editorconfig +2 -0
  5. package/android/build.gradle +47 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/expo/modules/atprotooauthclient/Crypto.kt +69 -0
  8. package/android/src/main/java/expo/modules/atprotooauthclient/ExpoAtprotoOAuthClientModule.kt +41 -0
  9. package/android/src/main/java/expo/modules/atprotooauthclient/Jose.kt +116 -0
  10. package/android/src/main/java/expo/modules/atprotooauthclient/Records.kt +61 -0
  11. package/dist/ExpoAtprotoOAuthClientModule.d.ts +22 -0
  12. package/dist/ExpoAtprotoOAuthClientModule.d.ts.map +1 -0
  13. package/dist/ExpoAtprotoOAuthClientModule.js +3 -0
  14. package/dist/ExpoAtprotoOAuthClientModule.js.map +1 -0
  15. package/dist/ExpoAtprotoOAuthClientModule.types.d.ts +2 -0
  16. package/dist/ExpoAtprotoOAuthClientModule.types.d.ts.map +1 -0
  17. package/dist/ExpoAtprotoOAuthClientModule.types.js +2 -0
  18. package/dist/ExpoAtprotoOAuthClientModule.types.js.map +1 -0
  19. package/dist/expo-oauth-client-interface.d.ts +6 -0
  20. package/dist/expo-oauth-client-interface.d.ts.map +1 -0
  21. package/dist/expo-oauth-client-interface.js +2 -0
  22. package/dist/expo-oauth-client-interface.js.map +1 -0
  23. package/dist/expo-oauth-client-options.d.ts +9 -0
  24. package/dist/expo-oauth-client-options.d.ts.map +1 -0
  25. package/dist/expo-oauth-client-options.js +2 -0
  26. package/dist/expo-oauth-client-options.js.map +1 -0
  27. package/dist/expo-oauth-client.native.d.ts +13 -0
  28. package/dist/expo-oauth-client.native.d.ts.map +1 -0
  29. package/dist/expo-oauth-client.native.js +130 -0
  30. package/dist/expo-oauth-client.native.js.map +1 -0
  31. package/dist/expo-oauth-client.web.d.ts +9 -0
  32. package/dist/expo-oauth-client.web.d.ts.map +1 -0
  33. package/dist/expo-oauth-client.web.js +24 -0
  34. package/dist/expo-oauth-client.web.js.map +1 -0
  35. package/dist/index.d.ts +4 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +2 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/polyfill.d.ts +5 -0
  40. package/dist/polyfill.d.ts.map +1 -0
  41. package/dist/polyfill.js +5 -0
  42. package/dist/polyfill.js.map +1 -0
  43. package/dist/utils/expo-key.d.ts +11 -0
  44. package/dist/utils/expo-key.d.ts.map +1 -0
  45. package/dist/utils/expo-key.js +29 -0
  46. package/dist/utils/expo-key.js.map +1 -0
  47. package/dist/utils/mmkv-simple-store-ttl.d.ts +24 -0
  48. package/dist/utils/mmkv-simple-store-ttl.d.ts.map +1 -0
  49. package/dist/utils/mmkv-simple-store-ttl.js +62 -0
  50. package/dist/utils/mmkv-simple-store-ttl.js.map +1 -0
  51. package/dist/utils/mmkv-simple-store.d.ts +18 -0
  52. package/dist/utils/mmkv-simple-store.d.ts.map +1 -0
  53. package/dist/utils/mmkv-simple-store.js +31 -0
  54. package/dist/utils/mmkv-simple-store.js.map +1 -0
  55. package/dist/utils/stores.d.ts +24 -0
  56. package/dist/utils/stores.d.ts.map +1 -0
  57. package/dist/utils/stores.js +99 -0
  58. package/dist/utils/stores.js.map +1 -0
  59. package/expo-module.config.json +9 -0
  60. package/ios/Crypto.swift +83 -0
  61. package/ios/ExpoAtprotoOAuthClient.podspec +31 -0
  62. package/ios/ExpoAtprotoOAuthClientModule.swift +45 -0
  63. package/ios/Jose.swift +137 -0
  64. package/ios/Records.swift +58 -0
  65. package/package.json +52 -0
  66. package/src/ExpoAtprotoOAuthClientModule.ts +33 -0
  67. package/src/ExpoAtprotoOAuthClientModule.types.ts +2 -0
  68. package/src/expo-oauth-client-interface.ts +10 -0
  69. package/src/expo-oauth-client-options.ts +27 -0
  70. package/src/expo-oauth-client.d.ts +6 -0
  71. package/src/expo-oauth-client.native.ts +111 -0
  72. package/src/expo-oauth-client.web.ts +42 -0
  73. package/src/index.ts +4 -0
  74. package/src/polyfill.ts +4 -0
  75. package/src/utils/expo-key.ts +50 -0
  76. package/src/utils/mmkv-simple-store-ttl.ts +90 -0
  77. package/src/utils/mmkv-simple-store.ts +48 -0
  78. package/src/utils/stores.ts +115 -0
  79. package/tsconfig.build.json +8 -0
  80. package/tsconfig.build.tsbuildinfo +1 -0
  81. package/tsconfig.json +4 -0
@@ -0,0 +1,130 @@
1
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
2
+ if (value !== null && value !== void 0) {
3
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
4
+ var dispose, inner;
5
+ if (async) {
6
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
7
+ dispose = value[Symbol.asyncDispose];
8
+ }
9
+ if (dispose === void 0) {
10
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
11
+ dispose = value[Symbol.dispose];
12
+ if (async) inner = dispose;
13
+ }
14
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
15
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
16
+ env.stack.push({ value: value, dispose: dispose, async: async });
17
+ }
18
+ else if (async) {
19
+ env.stack.push({ async: true });
20
+ }
21
+ return value;
22
+ };
23
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
24
+ return function (env) {
25
+ function fail(e) {
26
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
27
+ env.hasError = true;
28
+ }
29
+ var r, s = 0;
30
+ function next() {
31
+ while (r = env.stack.pop()) {
32
+ try {
33
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
34
+ if (r.dispose) {
35
+ var result = r.dispose.call(r.value);
36
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
37
+ }
38
+ else s |= 1;
39
+ }
40
+ catch (e) {
41
+ fail(e);
42
+ }
43
+ }
44
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
45
+ if (env.hasError) throw env.error;
46
+ }
47
+ return next();
48
+ };
49
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
50
+ var e = new Error(message);
51
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
+ });
53
+ import './polyfill';
54
+ import { openAuthSessionAsync } from 'expo-web-browser';
55
+ import { OAuthClient, } from '@atproto/oauth-client';
56
+ import { default as NativeModule } from './ExpoAtprotoOAuthClientModule';
57
+ import { ExpoKey } from './utils/expo-key';
58
+ import { AuthorizationServerMetadataCache, DidCache, DpopNonceCache, HandleCache, ProtectedResourceMetadataCache, SessionStore, StateStore, } from './utils/stores';
59
+ export const CUSTOM_URI_SCHEME_REGEX = /^(?:[^.]+(?:\.[^.]+)+):\/(?:[^/].*)?$/;
60
+ const isCustomUriScheme = (uri) => CUSTOM_URI_SCHEME_REGEX.test(uri);
61
+ export class ExpoOAuthClient extends OAuthClient {
62
+ #disposables;
63
+ constructor(options) {
64
+ const env_1 = { stack: [], error: void 0, hasError: false };
65
+ try {
66
+ const stack = __addDisposableResource(env_1, new DisposableStack(), false);
67
+ super({
68
+ ...options,
69
+ responseMode: options.responseMode ?? 'query',
70
+ keyset: undefined,
71
+ runtimeImplementation: {
72
+ createKey: async (algs) => ExpoKey.generate(algs),
73
+ digest: async (bytes, { name }) => NativeModule.digest(bytes, name),
74
+ getRandomValues: async (length) => NativeModule.getRandomValues(length),
75
+ },
76
+ sessionStore: stack.use(new SessionStore()),
77
+ stateStore: stack.use(new StateStore()),
78
+ didCache: stack.use(new DidCache()),
79
+ handleCache: stack.use(new HandleCache()),
80
+ dpopNonceCache: stack.use(new DpopNonceCache()),
81
+ authorizationServerMetadataCache: stack.use(new AuthorizationServerMetadataCache()),
82
+ protectedResourceMetadataCache: stack.use(new ProtectedResourceMetadataCache()),
83
+ });
84
+ stack.defer(() => super[Symbol.dispose]?.());
85
+ this.#disposables = stack.move();
86
+ }
87
+ catch (e_1) {
88
+ env_1.error = e_1;
89
+ env_1.hasError = true;
90
+ }
91
+ finally {
92
+ __disposeResources(env_1);
93
+ }
94
+ }
95
+ async handleCallback() {
96
+ return null;
97
+ }
98
+ async signIn(input, options) {
99
+ const redirectUri = options?.redirect_uri ??
100
+ this.clientMetadata.redirect_uris.find(isCustomUriScheme);
101
+ if (!redirectUri) {
102
+ throw new TypeError('A redirect URI with a custom scheme is required for Expo OAuth.');
103
+ }
104
+ const url = await this.authorize(input, {
105
+ ...options,
106
+ redirect_uri: redirectUri,
107
+ display: options?.display ?? 'touch',
108
+ });
109
+ console.debug('openAuthSessionAsync', { url, redirectUri });
110
+ const result = await openAuthSessionAsync(url.toString(), redirectUri);
111
+ console.debug('AUTH SESSION RESULT', result);
112
+ if (result.type === 'success') {
113
+ const callbackUrl = new URL(result.url);
114
+ const params = this.responseMode === 'fragment'
115
+ ? new URLSearchParams(callbackUrl.hash.slice(1))
116
+ : callbackUrl.searchParams;
117
+ const { session } = await this.callback(params, {
118
+ redirect_uri: redirectUri,
119
+ });
120
+ return session;
121
+ }
122
+ else {
123
+ throw new Error(`Authentication cancelled: ${result.type}`);
124
+ }
125
+ }
126
+ [Symbol.dispose]() {
127
+ this.#disposables.dispose();
128
+ }
129
+ }
130
+ //# sourceMappingURL=expo-oauth-client.native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-oauth-client.native.js","sourceRoot":"","sources":["../src/expo-oauth-client.native.ts"],"names":[],"mappings":"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","sourcesContent":["import './polyfill'\n\nimport { openAuthSessionAsync } from 'expo-web-browser'\nimport {\n AuthorizeOptions,\n OAuthClient,\n OAuthSession,\n} from '@atproto/oauth-client'\nimport { default as NativeModule } from './ExpoAtprotoOAuthClientModule'\nimport { ExpoOAuthClientInterface } from './expo-oauth-client-interface'\nimport { ExpoOAuthClientOptions } from './expo-oauth-client-options'\nimport { ExpoKey } from './utils/expo-key'\nimport {\n AuthorizationServerMetadataCache,\n DidCache,\n DpopNonceCache,\n HandleCache,\n ProtectedResourceMetadataCache,\n SessionStore,\n StateStore,\n} from './utils/stores'\n\nexport const CUSTOM_URI_SCHEME_REGEX = /^(?:[^.]+(?:\\.[^.]+)+):\\/(?:[^/].*)?$/\nconst isCustomUriScheme = (uri: string) => CUSTOM_URI_SCHEME_REGEX.test(uri)\n\nexport class ExpoOAuthClient\n extends OAuthClient\n implements ExpoOAuthClientInterface\n{\n readonly #disposables: DisposableStack\n\n constructor(options: ExpoOAuthClientOptions) {\n using stack = new DisposableStack()\n\n super({\n ...options,\n responseMode: options.responseMode ?? 'query',\n keyset: undefined,\n runtimeImplementation: {\n createKey: async (algs) => ExpoKey.generate(algs),\n digest: async (bytes, { name }) => NativeModule.digest(bytes, name),\n getRandomValues: async (length) => NativeModule.getRandomValues(length),\n },\n sessionStore: stack.use(new SessionStore()),\n stateStore: stack.use(new StateStore()),\n didCache: stack.use(new DidCache()),\n handleCache: stack.use(new HandleCache()),\n dpopNonceCache: stack.use(new DpopNonceCache()),\n authorizationServerMetadataCache: stack.use(\n new AuthorizationServerMetadataCache(),\n ),\n protectedResourceMetadataCache: stack.use(\n new ProtectedResourceMetadataCache(),\n ),\n })\n\n stack.defer(() => super[Symbol.dispose]?.())\n\n this.#disposables = stack.move()\n }\n\n async handleCallback(): Promise<null | OAuthSession> {\n return null\n }\n\n async signIn(\n input: string,\n options?: AuthorizeOptions,\n ): Promise<OAuthSession> {\n const redirectUri =\n options?.redirect_uri ??\n this.clientMetadata.redirect_uris.find(isCustomUriScheme)\n\n if (!redirectUri) {\n throw new TypeError(\n 'A redirect URI with a custom scheme is required for Expo OAuth.',\n )\n }\n\n const url = await this.authorize(input, {\n ...options,\n redirect_uri: redirectUri,\n display: options?.display ?? 'touch',\n })\n\n console.debug('openAuthSessionAsync', { url, redirectUri })\n\n const result = await openAuthSessionAsync(url.toString(), redirectUri)\n\n console.debug('AUTH SESSION RESULT', result)\n\n if (result.type === 'success') {\n const callbackUrl = new URL(result.url)\n const params =\n this.responseMode === 'fragment'\n ? new URLSearchParams(callbackUrl.hash.slice(1))\n : callbackUrl.searchParams\n\n const { session } = await this.callback(params, {\n redirect_uri: redirectUri,\n })\n return session\n } else {\n throw new Error(`Authentication cancelled: ${result.type}`)\n }\n }\n\n [Symbol.dispose]() {\n this.#disposables.dispose()\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import { AuthorizeOptions, BrowserOAuthClient, OAuthSession } from '@atproto/oauth-client-browser';
2
+ import { ExpoOAuthClientInterface } from './expo-oauth-client-interface';
3
+ import { ExpoOAuthClientOptions } from './expo-oauth-client-options';
4
+ export declare class ExpoOAuthClient extends BrowserOAuthClient implements ExpoOAuthClientInterface {
5
+ constructor({ clientMetadata, responseMode, ...options }: ExpoOAuthClientOptions);
6
+ signIn(input: string, options?: AuthorizeOptions): Promise<OAuthSession>;
7
+ handleCallback(): Promise<null | OAuthSession>;
8
+ }
9
+ //# sourceMappingURL=expo-oauth-client.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-oauth-client.web.d.ts","sourceRoot":"","sources":["../src/expo-oauth-client.web.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACb,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEpE,qBAAa,eACX,SAAQ,kBACR,YAAW,wBAAwB;gBAEvB,EACV,cAAc,EACd,YAAyB,EACzB,GAAG,OAAO,EACX,EAAE,sBAAsB;IAIV,MAAM,CACnB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,YAAY,CAAC;IAQlB,cAAc,IAAI,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;CAUrD"}
@@ -0,0 +1,24 @@
1
+ import { BrowserOAuthClient, } from '@atproto/oauth-client-browser';
2
+ export class ExpoOAuthClient extends BrowserOAuthClient {
3
+ constructor({ clientMetadata, responseMode = 'fragment', ...options }) {
4
+ super({ ...options, clientMetadata, responseMode });
5
+ }
6
+ async signIn(input, options) {
7
+ // Force popup mode
8
+ return this.signInPopup(input, {
9
+ ...options,
10
+ display: options?.display ?? 'touch',
11
+ });
12
+ }
13
+ async handleCallback() {
14
+ const params = this.readCallbackParams();
15
+ if (!params)
16
+ return null;
17
+ const url = this.findRedirectUrl();
18
+ if (!url)
19
+ return null;
20
+ const { session } = await this.initCallback(params, url);
21
+ return session;
22
+ }
23
+ }
24
+ //# sourceMappingURL=expo-oauth-client.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-oauth-client.web.js","sourceRoot":"","sources":["../src/expo-oauth-client.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,kBAAkB,GAEnB,MAAM,+BAA+B,CAAA;AAItC,MAAM,OAAO,eACX,SAAQ,kBAAkB;IAG1B,YAAY,EACV,cAAc,EACd,YAAY,GAAG,UAAU,EACzB,GAAG,OAAO,EACa;QACvB,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAA;IACrD,CAAC;IAEQ,KAAK,CAAC,MAAM,CACnB,KAAa,EACb,OAA0B;QAE1B,mBAAmB;QACnB,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE;YAC7B,GAAG,OAAO;YACV,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,OAAO;SACrC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAA;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAExB,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,EAAE,CAAA;QAClC,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QACxD,OAAO,OAAO,CAAA;IAChB,CAAC;CACF","sourcesContent":["import {\n AuthorizeOptions,\n BrowserOAuthClient,\n OAuthSession,\n} from '@atproto/oauth-client-browser'\nimport { ExpoOAuthClientInterface } from './expo-oauth-client-interface'\nimport { ExpoOAuthClientOptions } from './expo-oauth-client-options'\n\nexport class ExpoOAuthClient\n extends BrowserOAuthClient\n implements ExpoOAuthClientInterface\n{\n constructor({\n clientMetadata,\n responseMode = 'fragment',\n ...options\n }: ExpoOAuthClientOptions) {\n super({ ...options, clientMetadata, responseMode })\n }\n\n override async signIn(\n input: string,\n options?: AuthorizeOptions,\n ): Promise<OAuthSession> {\n // Force popup mode\n return this.signInPopup(input, {\n ...options,\n display: options?.display ?? 'touch',\n })\n }\n\n async handleCallback(): Promise<null | OAuthSession> {\n const params = this.readCallbackParams()\n if (!params) return null\n\n const url = this.findRedirectUrl()\n if (!url) return null\n\n const { session } = await this.initCallback(params, url)\n return session\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export type { ExpoOAuthClientInterface } from './expo-oauth-client-interface';
2
+ export type { ExpoOAuthClientOptions } from './expo-oauth-client-options';
3
+ export { ExpoOAuthClient } from './expo-oauth-client';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAC7E,YAAY,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { ExpoOAuthClient } from './expo-oauth-client';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA","sourcesContent":["export type { ExpoOAuthClientInterface } from './expo-oauth-client-interface'\nexport type { ExpoOAuthClientOptions } from './expo-oauth-client-options'\n\nexport { ExpoOAuthClient } from './expo-oauth-client'\n"]}
@@ -0,0 +1,5 @@
1
+ import 'core-js/proposals/explicit-resource-management';
2
+ import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
3
+ import 'event-target-polyfill';
4
+ import 'react-native-url-polyfill/auto';
5
+ //# sourceMappingURL=polyfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyfill.d.ts","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":"AAAA,OAAO,gDAAgD,CAAA;AACvD,OAAO,oDAAoD,CAAA;AAC3D,OAAO,uBAAuB,CAAA;AAC9B,OAAO,gCAAgC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import 'core-js/proposals/explicit-resource-management';
2
+ import 'abortcontroller-polyfill/dist/polyfill-patch-fetch';
3
+ import 'event-target-polyfill';
4
+ import 'react-native-url-polyfill/auto';
5
+ //# sourceMappingURL=polyfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyfill.js","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":"AAAA,OAAO,gDAAgD,CAAA;AACvD,OAAO,oDAAoD,CAAA;AAC3D,OAAO,uBAAuB,CAAA;AAC9B,OAAO,gCAAgC,CAAA","sourcesContent":["import 'core-js/proposals/explicit-resource-management'\nimport 'abortcontroller-polyfill/dist/polyfill-patch-fetch'\nimport 'event-target-polyfill'\nimport 'react-native-url-polyfill/auto'\n"]}
@@ -0,0 +1,11 @@
1
+ import { type Jwk, type JwtHeader, type JwtPayload, Key, type SignedJwt, type VerifyOptions, type VerifyResult } from '@atproto/oauth-client';
2
+ import type { NativeJwk } from '../ExpoAtprotoOAuthClientModule';
3
+ export type ExpoJwk = Jwk & NativeJwk & {
4
+ key_ops: ['sign'];
5
+ };
6
+ export declare class ExpoKey extends Key<ExpoJwk> {
7
+ createJwt(header: JwtHeader, payload: JwtPayload): Promise<SignedJwt>;
8
+ verifyJwt<C extends string = never>(token: SignedJwt, options?: VerifyOptions<C>): Promise<VerifyResult<C>>;
9
+ static generate(algs: string[]): Promise<ExpoKey>;
10
+ }
11
+ //# sourceMappingURL=expo-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-key.d.ts","sourceRoot":"","sources":["../../src/utils/expo-key.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,UAAU,EACf,GAAG,EACH,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAA;AAGhE,MAAM,MAAM,OAAO,GAAG,GAAG,GAAG,SAAS,GAAG;IAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAA;CAAE,CAAA;AAC7D,qBAAa,OAAQ,SAAQ,GAAG,CAAC,OAAO,CAAC;IACjC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAQrE,SAAS,CAAC,CAAC,SAAS,MAAM,GAAG,KAAK,EACtC,KAAK,EAAE,SAAS,EAChB,OAAO,GAAE,aAAa,CAAC,CAAC,CAAM,GAC7B,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;WAId,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAQxD"}
@@ -0,0 +1,29 @@
1
+ import { Key, } from '@atproto/oauth-client';
2
+ import { default as NativeModule } from '../ExpoAtprotoOAuthClientModule';
3
+ export class ExpoKey extends Key {
4
+ async createJwt(header, payload) {
5
+ return NativeModule.createJwt(JSON.stringify(header), JSON.stringify(payload), toNativeJwk(this.jwk));
6
+ }
7
+ async verifyJwt(token, options = {}) {
8
+ return NativeModule.verifyJwt(token, toNativeJwk(this.jwk), options);
9
+ }
10
+ static async generate(algs) {
11
+ if (algs.includes('ES256')) {
12
+ const jwk = await NativeModule.generatePrivateJwk('ES256');
13
+ return new ExpoKey({ ...jwk, key_ops: ['sign'] });
14
+ }
15
+ throw TypeError(`No supported algorithm found in: ${algs.join(', ')}`);
16
+ }
17
+ }
18
+ function toNativeJwk(jwk) {
19
+ return {
20
+ kty: jwk.kty,
21
+ crv: jwk.crv,
22
+ kid: jwk.kid,
23
+ x: jwk.x,
24
+ y: jwk.y,
25
+ d: jwk.d,
26
+ alg: jwk.alg,
27
+ };
28
+ }
29
+ //# sourceMappingURL=expo-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-key.js","sourceRoot":"","sources":["../../src/utils/expo-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,GAAG,GAIJ,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iCAAiC,CAAA;AAGzE,MAAM,OAAO,OAAQ,SAAQ,GAAY;IACvC,KAAK,CAAC,SAAS,CAAC,MAAiB,EAAE,OAAmB;QACpD,OAAO,YAAY,CAAC,SAAS,CAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EACtB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EACvB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CACtB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,SAAS,CACb,KAAgB,EAChB,UAA4B,EAAE;QAE9B,OAAO,YAAY,CAAC,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAc;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAA;YAC1D,OAAO,IAAI,OAAO,CAAC,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;QACnD,CAAC;QAED,MAAM,SAAS,CAAC,oCAAoC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,CAAC,EAAE,GAAG,CAAC,CAAC;QACR,CAAC,EAAE,GAAG,CAAC,CAAC;QACR,CAAC,EAAE,GAAG,CAAC,CAAC;QACR,GAAG,EAAE,GAAG,CAAC,GAAG;KACb,CAAA;AACH,CAAC","sourcesContent":["import {\n type Jwk,\n type JwtHeader,\n type JwtPayload,\n Key,\n type SignedJwt,\n type VerifyOptions,\n type VerifyResult,\n} from '@atproto/oauth-client'\nimport type { NativeJwk } from '../ExpoAtprotoOAuthClientModule'\nimport { default as NativeModule } from '../ExpoAtprotoOAuthClientModule'\n\nexport type ExpoJwk = Jwk & NativeJwk & { key_ops: ['sign'] }\nexport class ExpoKey extends Key<ExpoJwk> {\n async createJwt(header: JwtHeader, payload: JwtPayload): Promise<SignedJwt> {\n return NativeModule.createJwt(\n JSON.stringify(header),\n JSON.stringify(payload),\n toNativeJwk(this.jwk),\n )\n }\n\n async verifyJwt<C extends string = never>(\n token: SignedJwt,\n options: VerifyOptions<C> = {},\n ): Promise<VerifyResult<C>> {\n return NativeModule.verifyJwt(token, toNativeJwk(this.jwk), options)\n }\n\n static async generate(algs: string[]): Promise<ExpoKey> {\n if (algs.includes('ES256')) {\n const jwk = await NativeModule.generatePrivateJwk('ES256')\n return new ExpoKey({ ...jwk, key_ops: ['sign'] })\n }\n\n throw TypeError(`No supported algorithm found in: ${algs.join(', ')}`)\n }\n}\n\nfunction toNativeJwk(jwk: ExpoJwk): NativeJwk {\n return {\n kty: jwk.kty,\n crv: jwk.crv,\n kid: jwk.kid,\n x: jwk.x,\n y: jwk.y,\n d: jwk.d,\n alg: jwk.alg,\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import { Configuration } from 'react-native-mmkv';
2
+ import type { SimpleStore, Value } from '@atproto-labs/simple-store';
3
+ import { MMKVSimpleStore, MMKVSimpleStoreOptions } from './mmkv-simple-store';
4
+ export type MMKVSimpleStoreTTLOptions<V extends Value> = MMKVSimpleStoreOptions<V> & {
5
+ clearInterval?: null | false | number;
6
+ expiresAt: (value: V) => null | number;
7
+ };
8
+ /**
9
+ * A {@link SimpleStore} implementation based on {@link MMKVSimpleStore} that
10
+ * supports expiring entries after a certain time.
11
+ */
12
+ export declare class MMKVSimpleStoreTTL<V extends Value> extends MMKVSimpleStore<V> implements Disposable, SimpleStore<string, V> {
13
+ #private;
14
+ constructor({ clearInterval, expiresAt, encode, decode, ...config }: MMKVSimpleStoreTTLOptions<V> & Configuration);
15
+ [Symbol.dispose](): void;
16
+ set(key: string, value: V): void;
17
+ get(key: string): V | undefined;
18
+ del(key: string): void;
19
+ clear(): void;
20
+ getExpirationTime(key: string): number | undefined;
21
+ isExpired(key: string): boolean;
22
+ clearExpired(): void;
23
+ }
24
+ //# sourceMappingURL=mmkv-simple-store-ttl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmkv-simple-store-ttl.d.ts","sourceRoot":"","sources":["../../src/utils/mmkv-simple-store-ttl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAQ,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AACpE,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAA;AAE7E,MAAM,MAAM,yBAAyB,CAAC,CAAC,SAAS,KAAK,IACnD,sBAAsB,CAAC,CAAC,CAAC,GAAG;IAC1B,aAAa,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,CAAA;IACrC,SAAS,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,CAAA;CACvC,CAAA;AAEH;;;GAGG;AACH,qBAAa,kBAAkB,CAAC,CAAC,SAAS,KAAK,CAC7C,SAAQ,eAAe,CAAC,CAAC,CACzB,YAAW,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;;gBAMjC,EACV,aAAwB,EACxB,SAAS,EACT,MAAM,EACN,MAAM,EAEN,GAAG,MAAM,EACV,EAAE,yBAAyB,CAAC,CAAC,CAAC,GAAG,aAAa;IAY/C,CAAC,MAAM,CAAC,OAAO,CAAC;IAKP,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAQhC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAS/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKtB,KAAK,IAAI,IAAI;IAKtB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIlD,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAK/B,YAAY;CAOb"}
@@ -0,0 +1,62 @@
1
+ import { MMKV } from 'react-native-mmkv';
2
+ import { MMKVSimpleStore } from './mmkv-simple-store';
3
+ /**
4
+ * A {@link SimpleStore} implementation based on {@link MMKVSimpleStore} that
5
+ * supports expiring entries after a certain time.
6
+ */
7
+ export class MMKVSimpleStoreTTL extends MMKVSimpleStore {
8
+ #store;
9
+ #expiresAt;
10
+ #clearTimer;
11
+ constructor({ clearInterval = 60 * 1e3, expiresAt, encode, decode, ...config }) {
12
+ super({ ...config, encode, decode });
13
+ this.#store = new MMKV({ ...config, id: `${config.id}.exp` });
14
+ this.#expiresAt = expiresAt;
15
+ if (clearInterval) {
16
+ this.#clearTimer = setInterval(() => this.clearExpired(), clearInterval);
17
+ }
18
+ this.clearExpired();
19
+ }
20
+ [Symbol.dispose]() {
21
+ clearInterval(this.#clearTimer);
22
+ this.clearExpired();
23
+ }
24
+ set(key, value) {
25
+ super.set(key, value);
26
+ const expirationDate = this.#expiresAt.call(null, value);
27
+ if (expirationDate == null)
28
+ this.#store.delete(key);
29
+ else
30
+ this.#store.set(key, expirationDate);
31
+ }
32
+ get(key) {
33
+ if (this.isExpired(key)) {
34
+ this.del(key);
35
+ return undefined;
36
+ }
37
+ return super.get(key);
38
+ }
39
+ del(key) {
40
+ super.del(key);
41
+ this.#store.delete(key);
42
+ }
43
+ clear() {
44
+ super.clear();
45
+ this.#store.clearAll();
46
+ }
47
+ getExpirationTime(key) {
48
+ return this.#store.getNumber(key) ?? undefined;
49
+ }
50
+ isExpired(key) {
51
+ const expirationTime = this.getExpirationTime(key);
52
+ return expirationTime != null && expirationTime < Date.now();
53
+ }
54
+ clearExpired() {
55
+ for (const key of this.#store.getAllKeys() ?? []) {
56
+ if (this.isExpired(key)) {
57
+ this.del(key);
58
+ }
59
+ }
60
+ }
61
+ }
62
+ //# sourceMappingURL=mmkv-simple-store-ttl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmkv-simple-store-ttl.js","sourceRoot":"","sources":["../../src/utils/mmkv-simple-store-ttl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAEvD,OAAO,EAAE,eAAe,EAA0B,MAAM,qBAAqB,CAAA;AAQ7E;;;GAGG;AACH,MAAM,OAAO,kBACX,SAAQ,eAAkB;IAGjB,MAAM,CAAM;IACZ,UAAU,CAA6B;IACvC,WAAW,CAAiC;IAErD,YAAY,EACV,aAAa,GAAG,EAAE,GAAG,GAAG,EACxB,SAAS,EACT,MAAM,EACN,MAAM,EAEN,GAAG,MAAM,EACoC;QAC7C,KAAK,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;QAEpC,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;QAC7D,IAAI,CAAC,UAAU,GAAG,SAAS,CAAA;QAC3B,IAAI,aAAa,EAAE,CAAC;YAClB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAA;QAC1E,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAA;IACrB,CAAC;IAED,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC/B,IAAI,CAAC,YAAY,EAAE,CAAA;IACrB,CAAC;IAEQ,GAAG,CAAC,GAAW,EAAE,KAAQ;QAChC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAErB,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QACxD,IAAI,cAAc,IAAI,IAAI;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;;YAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IAC3C,CAAC;IAEQ,GAAG,CAAC,GAAW;QACtB,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACb,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAEQ,GAAG,CAAC,GAAW;QACtB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACd,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAEQ,KAAK;QACZ,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAA;IACxB,CAAC;IAED,iBAAiB,CAAC,GAAW;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,SAAS,CAAA;IAChD,CAAC;IAED,SAAS,CAAC,GAAW;QACnB,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAA;QAClD,OAAO,cAAc,IAAI,IAAI,IAAI,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAC9D,CAAC;IAED,YAAY;QACV,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACf,CAAC;QACH,CAAC;IACH,CAAC;CACF","sourcesContent":["import { Configuration, MMKV } from 'react-native-mmkv'\nimport type { SimpleStore, Value } from '@atproto-labs/simple-store'\nimport { MMKVSimpleStore, MMKVSimpleStoreOptions } from './mmkv-simple-store'\n\nexport type MMKVSimpleStoreTTLOptions<V extends Value> =\n MMKVSimpleStoreOptions<V> & {\n clearInterval?: null | false | number\n expiresAt: (value: V) => null | number\n }\n\n/**\n * A {@link SimpleStore} implementation based on {@link MMKVSimpleStore} that\n * supports expiring entries after a certain time.\n */\nexport class MMKVSimpleStoreTTL<V extends Value>\n extends MMKVSimpleStore<V>\n implements Disposable, SimpleStore<string, V>\n{\n readonly #store: MMKV\n readonly #expiresAt: (value: V) => null | number\n readonly #clearTimer?: ReturnType<typeof setInterval>\n\n constructor({\n clearInterval = 60 * 1e3,\n expiresAt,\n encode,\n decode,\n\n ...config\n }: MMKVSimpleStoreTTLOptions<V> & Configuration) {\n super({ ...config, encode, decode })\n\n this.#store = new MMKV({ ...config, id: `${config.id}.exp` })\n this.#expiresAt = expiresAt\n if (clearInterval) {\n this.#clearTimer = setInterval(() => this.clearExpired(), clearInterval)\n }\n\n this.clearExpired()\n }\n\n [Symbol.dispose]() {\n clearInterval(this.#clearTimer)\n this.clearExpired()\n }\n\n override set(key: string, value: V): void {\n super.set(key, value)\n\n const expirationDate = this.#expiresAt.call(null, value)\n if (expirationDate == null) this.#store.delete(key)\n else this.#store.set(key, expirationDate)\n }\n\n override get(key: string): V | undefined {\n if (this.isExpired(key)) {\n this.del(key)\n return undefined\n }\n\n return super.get(key)\n }\n\n override del(key: string): void {\n super.del(key)\n this.#store.delete(key)\n }\n\n override clear(): void {\n super.clear()\n this.#store.clearAll()\n }\n\n getExpirationTime(key: string): number | undefined {\n return this.#store.getNumber(key) ?? undefined\n }\n\n isExpired(key: string): boolean {\n const expirationTime = this.getExpirationTime(key)\n return expirationTime != null && expirationTime < Date.now()\n }\n\n clearExpired() {\n for (const key of this.#store.getAllKeys() ?? []) {\n if (this.isExpired(key)) {\n this.del(key)\n }\n }\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { Configuration } from 'react-native-mmkv';
2
+ import type { SimpleStore, Value } from '@atproto-labs/simple-store';
3
+ export type MMKVSimpleStoreOptions<V extends Value> = {
4
+ decode: (value: string) => V;
5
+ encode: (value: V) => string;
6
+ };
7
+ /**
8
+ * A {@link SimpleStore} implementation using {@link MMKV} for storage.
9
+ */
10
+ export declare class MMKVSimpleStore<V extends Value> implements SimpleStore<string, V> {
11
+ #private;
12
+ constructor({ decode, encode, ...config }: MMKVSimpleStoreOptions<V> & Configuration);
13
+ set(key: string, value: V): void;
14
+ get(key: string): V | undefined;
15
+ del(key: string): void;
16
+ clear(): void;
17
+ }
18
+ //# sourceMappingURL=mmkv-simple-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmkv-simple-store.d.ts","sourceRoot":"","sources":["../../src/utils/mmkv-simple-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAQ,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAEpE,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,KAAK,IAAI;IACpD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,CAAA;IAC5B,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,CAAA;CAC7B,CAAA;AAED;;GAEG;AACH,qBAAa,eAAe,CAAC,CAAC,SAAS,KAAK,CAC1C,YAAW,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;;gBAMrB,EACV,MAAM,EACN,MAAM,EACN,GAAG,MAAM,EACV,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,aAAa;IAM5C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAKhC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAO/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAItB,KAAK;CAGN"}
@@ -0,0 +1,31 @@
1
+ import { MMKV } from 'react-native-mmkv';
2
+ /**
3
+ * A {@link SimpleStore} implementation using {@link MMKV} for storage.
4
+ */
5
+ export class MMKVSimpleStore {
6
+ #store;
7
+ #encode;
8
+ #decode;
9
+ constructor({ decode, encode, ...config }) {
10
+ this.#store = new MMKV(config);
11
+ this.#decode = decode;
12
+ this.#encode = encode;
13
+ }
14
+ set(key, value) {
15
+ const encoded = this.#encode.call(null, value);
16
+ this.#store.set(key, encoded);
17
+ }
18
+ get(key) {
19
+ const value = this.#store.getString(key);
20
+ if (value === undefined)
21
+ return undefined;
22
+ return this.#decode.call(null, value);
23
+ }
24
+ del(key) {
25
+ this.#store.delete(key);
26
+ }
27
+ clear() {
28
+ this.#store.clearAll();
29
+ }
30
+ }
31
+ //# sourceMappingURL=mmkv-simple-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mmkv-simple-store.js","sourceRoot":"","sources":["../../src/utils/mmkv-simple-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,IAAI,EAAE,MAAM,mBAAmB,CAAA;AAQvD;;GAEG;AACH,MAAM,OAAO,eAAe;IAGjB,MAAM,CAAM;IACZ,OAAO,CAAsB;IAC7B,OAAO,CAAsB;IAEtC,YAAY,EACV,MAAM,EACN,MAAM,EACN,GAAG,MAAM,EACiC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAA;QAC9B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAC9C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC/B,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QACxC,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAA;QAEzC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IACvC,CAAC;IAED,GAAG,CAAC,GAAW;QACb,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAA;IACxB,CAAC;CACF","sourcesContent":["import { Configuration, MMKV } from 'react-native-mmkv'\nimport type { SimpleStore, Value } from '@atproto-labs/simple-store'\n\nexport type MMKVSimpleStoreOptions<V extends Value> = {\n decode: (value: string) => V\n encode: (value: V) => string\n}\n\n/**\n * A {@link SimpleStore} implementation using {@link MMKV} for storage.\n */\nexport class MMKVSimpleStore<V extends Value>\n implements SimpleStore<string, V>\n{\n readonly #store: MMKV\n readonly #encode: (value: V) => string\n readonly #decode: (value: string) => V\n\n constructor({\n decode,\n encode,\n ...config\n }: MMKVSimpleStoreOptions<V> & Configuration) {\n this.#store = new MMKV(config)\n this.#decode = decode\n this.#encode = encode\n }\n\n set(key: string, value: V): void {\n const encoded = this.#encode.call(null, value)\n this.#store.set(key, encoded)\n }\n\n get(key: string): V | undefined {\n const value = this.#store.getString(key)\n if (value === undefined) return undefined\n\n return this.#decode.call(null, value)\n }\n\n del(key: string): void {\n this.#store.delete(key)\n }\n\n clear() {\n this.#store.clearAll()\n }\n}\n"]}
@@ -0,0 +1,24 @@
1
+ import type { DidDocument, InternalStateData, OAuthAuthorizationServerMetadata, OAuthProtectedResourceMetadata, ResolvedHandle, Session } from '@atproto/oauth-client';
2
+ import { MMKVSimpleStoreTTL } from './mmkv-simple-store-ttl';
3
+ export declare class AuthorizationServerMetadataCache extends MMKVSimpleStoreTTL<OAuthAuthorizationServerMetadata> {
4
+ constructor();
5
+ }
6
+ export declare class ProtectedResourceMetadataCache extends MMKVSimpleStoreTTL<OAuthProtectedResourceMetadata> {
7
+ constructor();
8
+ }
9
+ export declare class DpopNonceCache extends MMKVSimpleStoreTTL<string> {
10
+ constructor();
11
+ }
12
+ export declare class DidCache extends MMKVSimpleStoreTTL<DidDocument> {
13
+ constructor();
14
+ }
15
+ export declare class HandleCache extends MMKVSimpleStoreTTL<ResolvedHandle> {
16
+ constructor();
17
+ }
18
+ export declare class StateStore extends MMKVSimpleStoreTTL<InternalStateData> {
19
+ constructor();
20
+ }
21
+ export declare class SessionStore extends MMKVSimpleStoreTTL<Session> {
22
+ constructor();
23
+ }
24
+ //# sourceMappingURL=stores.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.d.ts","sourceRoot":"","sources":["../../src/utils/stores.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,iBAAiB,EACjB,gCAAgC,EAChC,8BAA8B,EAC9B,cAAc,EACd,OAAO,EACR,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAI5D,qBAAa,gCAAiC,SAAQ,kBAAkB,CAAC,gCAAgC,CAAC;;CASzG;AAED,qBAAa,8BAA+B,SAAQ,kBAAkB,CAAC,8BAA8B,CAAC;;CASrG;AAED,qBAAa,cAAe,SAAQ,kBAAkB,CAAC,MAAM,CAAC;;CAS7D;AAED,qBAAa,QAAS,SAAQ,kBAAkB,CAAC,WAAW,CAAC;;CAS5D;AAED,qBAAa,WAAY,SAAQ,kBAAkB,CAAC,cAAc,CAAC;;CASlE;AAED,qBAAa,UAAW,SAAQ,kBAAkB,CAAC,iBAAiB,CAAC;;CAcpE;AAED,qBAAa,YAAa,SAAQ,kBAAkB,CAAC,OAAO,CAAC;;CAkB5D"}
@@ -0,0 +1,99 @@
1
+ import { ExpoKey } from './expo-key';
2
+ import { MMKVSimpleStoreTTL } from './mmkv-simple-store-ttl';
3
+ const MMKV_ID = 'expo-atproto-oauth-client';
4
+ export class AuthorizationServerMetadataCache extends MMKVSimpleStoreTTL {
5
+ constructor() {
6
+ super({
7
+ id: `${MMKV_ID}.authorizationServerMetadata`,
8
+ expiresAt: oneMinuteFromNow,
9
+ decode: JSON.parse,
10
+ encode: JSON.stringify,
11
+ });
12
+ }
13
+ }
14
+ export class ProtectedResourceMetadataCache extends MMKVSimpleStoreTTL {
15
+ constructor() {
16
+ super({
17
+ id: `${MMKV_ID}.protectedResourceMetadata`,
18
+ expiresAt: oneMinuteFromNow,
19
+ decode: JSON.parse,
20
+ encode: JSON.stringify,
21
+ });
22
+ }
23
+ }
24
+ export class DpopNonceCache extends MMKVSimpleStoreTTL {
25
+ constructor() {
26
+ super({
27
+ id: `${MMKV_ID}.dpopNonce`,
28
+ expiresAt: tenMinutesFromNow,
29
+ decode: identity,
30
+ encode: identity,
31
+ });
32
+ }
33
+ }
34
+ export class DidCache extends MMKVSimpleStoreTTL {
35
+ constructor() {
36
+ super({
37
+ id: `${MMKV_ID}.did`,
38
+ expiresAt: oneMinuteFromNow,
39
+ decode: JSON.parse,
40
+ encode: JSON.stringify,
41
+ });
42
+ }
43
+ }
44
+ export class HandleCache extends MMKVSimpleStoreTTL {
45
+ constructor() {
46
+ super({
47
+ id: `${MMKV_ID}.handle`,
48
+ expiresAt: oneMinuteFromNow,
49
+ decode: JSON.parse,
50
+ encode: JSON.stringify,
51
+ });
52
+ }
53
+ }
54
+ export class StateStore extends MMKVSimpleStoreTTL {
55
+ constructor() {
56
+ super({
57
+ id: `${MMKV_ID}.state`,
58
+ expiresAt: tenMinutesFromNow,
59
+ decode: (value) => {
60
+ const parsed = JSON.parse(value);
61
+ return { ...parsed, dpopKey: new ExpoKey(parsed.dpopKey) };
62
+ },
63
+ encode: (value) => {
64
+ return JSON.stringify({ ...value, dpopKey: value.dpopKey.jwk });
65
+ },
66
+ });
67
+ }
68
+ }
69
+ export class SessionStore extends MMKVSimpleStoreTTL {
70
+ constructor() {
71
+ super({
72
+ id: `${MMKV_ID}.session`,
73
+ expiresAt: ({ tokenSet }) => {
74
+ if (tokenSet.refresh_token)
75
+ return null;
76
+ if (tokenSet.expires_at)
77
+ return new Date(tokenSet.expires_at).valueOf();
78
+ return null;
79
+ },
80
+ decode: (value) => {
81
+ const parsed = JSON.parse(value);
82
+ return { ...parsed, dpopKey: new ExpoKey(parsed.dpopKey) };
83
+ },
84
+ encode: (value) => {
85
+ return JSON.stringify({ ...value, dpopKey: value.dpopKey.jwk });
86
+ },
87
+ });
88
+ }
89
+ }
90
+ function identity(x) {
91
+ return x;
92
+ }
93
+ function tenMinutesFromNow() {
94
+ return Date.now() + 10 * 60e3;
95
+ }
96
+ function oneMinuteFromNow() {
97
+ return Date.now() + 60e3;
98
+ }
99
+ //# sourceMappingURL=stores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/utils/stores.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DidDocument,\n InternalStateData,\n OAuthAuthorizationServerMetadata,\n OAuthProtectedResourceMetadata,\n ResolvedHandle,\n Session,\n} from '@atproto/oauth-client'\nimport { ExpoKey } from './expo-key'\nimport { MMKVSimpleStoreTTL } from './mmkv-simple-store-ttl'\n\nconst MMKV_ID = 'expo-atproto-oauth-client'\n\nexport class AuthorizationServerMetadataCache extends MMKVSimpleStoreTTL<OAuthAuthorizationServerMetadata> {\n constructor() {\n super({\n id: `${MMKV_ID}.authorizationServerMetadata`,\n expiresAt: oneMinuteFromNow,\n decode: JSON.parse,\n encode: JSON.stringify,\n })\n }\n}\n\nexport class ProtectedResourceMetadataCache extends MMKVSimpleStoreTTL<OAuthProtectedResourceMetadata> {\n constructor() {\n super({\n id: `${MMKV_ID}.protectedResourceMetadata`,\n expiresAt: oneMinuteFromNow,\n decode: JSON.parse,\n encode: JSON.stringify,\n })\n }\n}\n\nexport class DpopNonceCache extends MMKVSimpleStoreTTL<string> {\n constructor() {\n super({\n id: `${MMKV_ID}.dpopNonce`,\n expiresAt: tenMinutesFromNow,\n decode: identity,\n encode: identity,\n })\n }\n}\n\nexport class DidCache extends MMKVSimpleStoreTTL<DidDocument> {\n constructor() {\n super({\n id: `${MMKV_ID}.did`,\n expiresAt: oneMinuteFromNow,\n decode: JSON.parse,\n encode: JSON.stringify,\n })\n }\n}\n\nexport class HandleCache extends MMKVSimpleStoreTTL<ResolvedHandle> {\n constructor() {\n super({\n id: `${MMKV_ID}.handle`,\n expiresAt: oneMinuteFromNow,\n decode: JSON.parse,\n encode: JSON.stringify,\n })\n }\n}\n\nexport class StateStore extends MMKVSimpleStoreTTL<InternalStateData> {\n constructor() {\n super({\n id: `${MMKV_ID}.state`,\n expiresAt: tenMinutesFromNow,\n decode: (value) => {\n const parsed = JSON.parse(value)\n return { ...parsed, dpopKey: new ExpoKey(parsed.dpopKey) }\n },\n encode: (value) => {\n return JSON.stringify({ ...value, dpopKey: value.dpopKey.jwk })\n },\n })\n }\n}\n\nexport class SessionStore extends MMKVSimpleStoreTTL<Session> {\n constructor() {\n super({\n id: `${MMKV_ID}.session`,\n expiresAt: ({ tokenSet }) => {\n if (tokenSet.refresh_token) return null\n if (tokenSet.expires_at) return new Date(tokenSet.expires_at).valueOf()\n return null\n },\n decode: (value) => {\n const parsed = JSON.parse(value)\n return { ...parsed, dpopKey: new ExpoKey(parsed.dpopKey) }\n },\n encode: (value) => {\n return JSON.stringify({ ...value, dpopKey: value.dpopKey.jwk })\n },\n })\n }\n}\n\nfunction identity<T>(x: T): T {\n return x\n}\n\nfunction tenMinutesFromNow() {\n return Date.now() + 10 * 60e3\n}\n\nfunction oneMinuteFromNow() {\n return Date.now() + 60e3\n}\n"]}
@@ -0,0 +1,9 @@
1
+ {
2
+ "platforms": ["apple", "android", "web"],
3
+ "apple": {
4
+ "modules": ["ExpoAtprotoOAuthClientModule"]
5
+ },
6
+ "android": {
7
+ "modules": ["expo.modules.atprotooauthclient.ExpoAtprotoOAuthClientModule"]
8
+ }
9
+ }