@robelest/convex-auth 0.0.4-preview.27 → 0.0.4-preview.28

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 (88) hide show
  1. package/README.md +3 -5
  2. package/dist/bin.js +6488 -1571
  3. package/dist/browser/index.js +10 -7
  4. package/dist/browser/locks.js +3 -5
  5. package/dist/browser/navigation.js +7 -10
  6. package/dist/browser/runtime.js +35 -33
  7. package/dist/client/core/types.js +17 -0
  8. package/dist/client/factors/device.js +26 -19
  9. package/dist/client/index.js +151 -163
  10. package/dist/client/runtime/proxy.js +6 -6
  11. package/dist/client/services/adapters.js +3 -7
  12. package/dist/client/services/http.js +2 -5
  13. package/dist/client/services/resolve.js +5 -11
  14. package/dist/client/services/runtime.js +2 -5
  15. package/dist/component/_generated/component.d.ts +46 -0
  16. package/dist/component/index.d.ts +3 -3
  17. package/dist/component/model.d.ts +25 -25
  18. package/dist/component/public/identity/sessions.js +38 -1
  19. package/dist/component/public/identity/tokens.js +81 -3
  20. package/dist/component/public/identity/verifiers.js +9 -3
  21. package/dist/component/public.js +3 -3
  22. package/dist/component/schema.d.ts +320 -320
  23. package/dist/core/index.d.ts +380 -0
  24. package/dist/core/index.js +83 -0
  25. package/dist/otel.d.ts +13 -17
  26. package/dist/otel.js +39 -49
  27. package/dist/providers/email.d.ts +2 -2
  28. package/dist/providers/password.js +8 -16
  29. package/dist/providers/phone.js +2 -9
  30. package/dist/server/auth-context.d.ts +204 -0
  31. package/dist/server/auth-context.js +76 -0
  32. package/dist/server/auth.d.ts +25 -187
  33. package/dist/server/auth.js +5 -96
  34. package/dist/server/componentContext.d.ts +12 -0
  35. package/dist/server/componentContext.js +1 -0
  36. package/dist/server/config.js +1 -12
  37. package/dist/server/constants.js +6 -0
  38. package/dist/server/contract.d.ts +1 -1
  39. package/dist/server/core.js +5 -14
  40. package/dist/server/crypto.js +26 -18
  41. package/dist/server/db.js +6 -1
  42. package/dist/server/device.js +88 -78
  43. package/dist/server/http.d.ts +4 -3
  44. package/dist/server/http.js +74 -86
  45. package/dist/server/index.d.ts +2 -1
  46. package/dist/server/limits.js +22 -15
  47. package/dist/server/mounts.d.ts +103 -103
  48. package/dist/server/mutations/account.js +6 -4
  49. package/dist/server/mutations/invalidate.js +3 -6
  50. package/dist/server/mutations/oauth.js +86 -88
  51. package/dist/server/mutations/refresh.js +45 -87
  52. package/dist/server/mutations/register.js +19 -19
  53. package/dist/server/mutations/retrieve.js +17 -15
  54. package/dist/server/mutations/signature.js +9 -13
  55. package/dist/server/mutations/signin.js +7 -3
  56. package/dist/server/mutations/signout.js +10 -15
  57. package/dist/server/mutations/store.js +22 -12
  58. package/dist/server/mutations/verifier.js +11 -6
  59. package/dist/server/mutations/verify.js +55 -46
  60. package/dist/server/oauth/runtime.js +27 -25
  61. package/dist/server/passkey.js +299 -250
  62. package/dist/server/prefetch.js +283 -281
  63. package/dist/server/refresh.js +7 -60
  64. package/dist/server/runtime.d.ts +82 -206
  65. package/dist/server/runtime.js +63 -56
  66. package/dist/server/services/config.js +5 -3
  67. package/dist/server/services/logger.js +2 -4
  68. package/dist/server/services/providers.js +2 -4
  69. package/dist/server/services/refresh.js +2 -4
  70. package/dist/server/services/resolve.js +15 -14
  71. package/dist/server/services/signin.js +2 -4
  72. package/dist/server/sessions.js +32 -33
  73. package/dist/server/signin.js +177 -142
  74. package/dist/server/sso/domain.d.ts +20 -68
  75. package/dist/server/sso/domain.js +444 -413
  76. package/dist/server/sso/http.js +53 -59
  77. package/dist/server/sso/oidc.js +94 -80
  78. package/dist/server/tokens.js +13 -3
  79. package/dist/server/totp.js +153 -116
  80. package/dist/server/types.d.ts +2 -2
  81. package/dist/server/users.js +18 -23
  82. package/dist/server/utils/cache.js +51 -0
  83. package/dist/server/utils/dispatch.js +36 -0
  84. package/dist/server/utils/retry.js +24 -0
  85. package/dist/server/utils/span.js +32 -0
  86. package/dist/shared/errors.js +9 -3
  87. package/dist/shared/log.js +20 -22
  88. package/package.json +41 -33
@@ -1,11 +1,10 @@
1
1
  import { ClientAdapterFactoriesLive, ClientAdaptersLive } from "../client/services/adapters.js";
2
2
  import { ClientHttpLive } from "../client/services/http.js";
3
- import { ClientRuntimeLive } from "../client/services/runtime.js";
4
3
  import { resolveClientServices } from "../client/services/resolve.js";
4
+ import { ClientRuntimeLive } from "../client/services/runtime.js";
5
5
  import { client as client$1 } from "../client/index.js";
6
6
  import { createBrowserRuntime } from "./runtime.js";
7
7
  import { createPasskeyClient } from "./passkey.js";
8
- import { Layer } from "effect";
9
8
  import { ConvexHttpClient } from "convex/browser";
10
9
 
11
10
  //#region src/browser/index.ts
@@ -42,11 +41,15 @@ import { ConvexHttpClient } from "convex/browser";
42
41
  */
43
42
  function client(options) {
44
43
  const url = options.proxyPath === void 0 ? options.url ?? inferConvexUrl(options.convex) : void 0;
45
- const runtime = mergeBrowserRuntime(options.runtime);
46
- const services = resolveClientServices(Layer.mergeAll(ClientRuntimeLive(runtime), ClientAdaptersLive(options.adapters ?? {}), ClientAdapterFactoriesLive({
47
- ...options.adapterFactories,
48
- passkey: options.adapterFactories?.passkey ?? ((deps) => createPasskeyClient(deps))
49
- }), ClientHttpLive(options.proxyPath !== void 0 ? null : options.httpClient ?? (url ? new ConvexHttpClient(url) : null))));
44
+ const services = resolveClientServices({
45
+ runtime: ClientRuntimeLive(mergeBrowserRuntime(options.runtime)),
46
+ adapters: ClientAdaptersLive(options.adapters ?? {}),
47
+ adapterFactories: ClientAdapterFactoriesLive({
48
+ ...options.adapterFactories,
49
+ passkey: options.adapterFactories?.passkey ?? ((deps) => createPasskeyClient(deps))
50
+ }),
51
+ http: ClientHttpLive(options.proxyPath !== void 0 ? null : options.httpClient ?? (url ? new ConvexHttpClient(url) : null))
52
+ });
50
53
  return client$1({
51
54
  ...options,
52
55
  storage: options.storage === void 0 && options.proxyPath !== void 0 ? null : options.storage,
@@ -1,13 +1,11 @@
1
1
  import { localMutex } from "../client/runtime/mutex.js";
2
- import { Effect, Layer, ServiceMap } from "effect";
3
2
 
4
3
  //#region src/browser/locks.ts
5
- var BrowserLocks = class extends ServiceMap.Service()("BrowserLocks") {};
6
- const BrowserLocksLive = Layer.succeed(BrowserLocks)({ withKey: (key, callback) => Effect.promise(async () => {
4
+ const BrowserLocksLive = { withKey: async (key, callback) => {
7
5
  const lockManager = typeof navigator === "undefined" ? void 0 : navigator.locks;
8
6
  return lockManager !== void 0 ? await lockManager.request(key, callback) : await localMutex(key, callback);
9
- }) });
7
+ } };
10
8
 
11
9
  //#endregion
12
- export { BrowserLocks, BrowserLocksLive };
10
+ export { BrowserLocksLive };
13
11
  //# sourceMappingURL=locks.js.map
@@ -1,17 +1,14 @@
1
- import { Effect, Layer, ServiceMap } from "effect";
2
-
3
1
  //#region src/browser/navigation.ts
4
- var BrowserNavigation = class extends ServiceMap.Service()("BrowserNavigation") {};
5
- const BrowserNavigationLive = Layer.succeed(BrowserNavigation)({
2
+ const BrowserNavigationLive = {
6
3
  get: () => typeof window === "undefined" ? null : new URL(window.location.href),
7
- replace: (url) => Effect.sync(() => {
4
+ replace: (url) => {
8
5
  if (typeof window !== "undefined") window.history.replaceState({}, "", url);
9
- }),
10
- redirect: (url) => Effect.sync(() => {
6
+ },
7
+ redirect: (url) => {
11
8
  if (typeof window !== "undefined") window.location.href = url.toString();
12
- })
13
- });
9
+ }
10
+ };
14
11
 
15
12
  //#endregion
16
- export { BrowserNavigation, BrowserNavigationLive };
13
+ export { BrowserNavigationLive };
17
14
  //# sourceMappingURL=navigation.js.map
@@ -1,27 +1,24 @@
1
- import { BrowserLocks, BrowserLocksLive } from "./locks.js";
2
- import { BrowserNavigation, BrowserNavigationLive } from "./navigation.js";
3
- import { Effect, Fiber, Stream } from "effect";
4
- import * as BrowserHttpClient from "@effect/platform-browser/BrowserHttpClient";
5
- import * as BrowserKeyValueStore from "@effect/platform-browser/BrowserKeyValueStore";
6
- import * as BrowserStream from "@effect/platform-browser/BrowserStream";
7
- import * as KeyValueStore from "effect/unstable/persistence/KeyValueStore";
1
+ import { BrowserLocksLive } from "./locks.js";
2
+ import { BrowserNavigationLive } from "./navigation.js";
8
3
 
9
4
  //#region src/browser/runtime.ts
10
5
  const browserStorage = {
11
6
  async getItem(key) {
12
- return Effect.runPromise(Effect.gen(function* () {
13
- return yield* (yield* KeyValueStore.KeyValueStore).get(key);
14
- }).pipe(Effect.provide(BrowserKeyValueStore.layerLocalStorage)));
7
+ try {
8
+ return localStorage.getItem(key);
9
+ } catch {
10
+ return null;
11
+ }
15
12
  },
16
13
  async setItem(key, value) {
17
- return Effect.runPromise(Effect.gen(function* () {
18
- yield* (yield* KeyValueStore.KeyValueStore).set(key, value);
19
- }).pipe(Effect.provide(BrowserKeyValueStore.layerLocalStorage)));
14
+ try {
15
+ localStorage.setItem(key, value);
16
+ } catch {}
20
17
  },
21
18
  async removeItem(key) {
22
- return Effect.runPromise(Effect.gen(function* () {
23
- yield* (yield* KeyValueStore.KeyValueStore).remove(key);
24
- }).pipe(Effect.provide(BrowserKeyValueStore.layerLocalStorage)));
19
+ try {
20
+ localStorage.removeItem(key);
21
+ } catch {}
25
22
  }
26
23
  };
27
24
  /** @internal */
@@ -51,33 +48,38 @@ function createBrowserRuntime() {
51
48
  environment: typeof window === "undefined" ? "server" : "client",
52
49
  storage: typeof window === "undefined" ? null : browserStorage,
53
50
  location: {
54
- get: () => Effect.runSync(BrowserNavigation.useSync((navigation) => navigation.get()).pipe(Effect.provide(BrowserNavigationLive))),
55
- replace: (url) => Effect.runPromise(BrowserNavigation.use((navigation) => navigation.replace(url)).pipe(Effect.provide(BrowserNavigationLive))),
56
- redirect: (url) => Effect.runPromise(BrowserNavigation.use((navigation) => navigation.redirect(url)).pipe(Effect.provide(BrowserNavigationLive)))
51
+ get: () => BrowserNavigationLive.get(),
52
+ replace: (url) => {
53
+ BrowserNavigationLive.replace(url);
54
+ return Promise.resolve();
55
+ },
56
+ redirect: (url) => {
57
+ BrowserNavigationLive.redirect(url);
58
+ return Promise.resolve();
59
+ }
57
60
  },
58
- mutex: { withKey: (key, callback) => Effect.runPromise(BrowserLocks.use((locks) => locks.withKey(key, callback)).pipe(Effect.provide(BrowserLocksLive))) },
61
+ mutex: { withKey: (key, callback) => BrowserLocksLive.withKey(key, callback) },
59
62
  proxy: { fetch: async (body, proxyPath) => {
60
- return Effect.runPromise(Effect.gen(function* () {
61
- const fetch = yield* BrowserHttpClient.Fetch;
62
- return yield* Effect.promise(() => fetch(new URL(proxyPath, window.location.origin), {
63
- method: "POST",
64
- headers: { "Content-Type": "application/json" },
65
- credentials: "include",
66
- body: JSON.stringify(body)
67
- }));
68
- }).pipe(Effect.provide(BrowserHttpClient.layerFetch)));
63
+ return fetch(new URL(proxyPath, window.location.origin), {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ credentials: "include",
67
+ body: JSON.stringify(body)
68
+ });
69
69
  } },
70
70
  sync: { subscribe: (key, callback) => {
71
71
  if (typeof window === "undefined") return null;
72
72
  const registry = getStorageListenerRegistry();
73
73
  const existingSubscription = registry[key];
74
74
  if (existingSubscription !== void 0) existingSubscription();
75
- const fiber = Effect.runFork(BrowserStream.fromEventListenerWindow("storage").pipe(Stream.runForEach((event) => event.key !== key ? Effect.void : Effect.promise(async () => {
76
- await callback(event.newValue ?? null);
77
- }))));
75
+ const controller = new AbortController();
76
+ window.addEventListener("storage", (event) => {
77
+ if (event.key !== key) return;
78
+ callback(event.newValue ?? null);
79
+ }, { signal: controller.signal });
78
80
  const unsubscribe = () => {
79
81
  if (registry[key] === unsubscribe) delete registry[key];
80
- Effect.runFork(Fiber.interrupt(fiber));
82
+ controller.abort();
81
83
  };
82
84
  registry[key] = unsubscribe;
83
85
  return unsubscribe;
@@ -0,0 +1,17 @@
1
+ //#region src/client/core/types.ts
2
+ function createDeferred() {
3
+ let resolve;
4
+ let reject;
5
+ return {
6
+ promise: new Promise((res, rej) => {
7
+ resolve = res;
8
+ reject = rej;
9
+ }),
10
+ resolve,
11
+ reject
12
+ };
13
+ }
14
+
15
+ //#endregion
16
+ export { createDeferred };
17
+ //# sourceMappingURL=types.js.map
@@ -1,5 +1,4 @@
1
1
  import { ConvexError } from "convex/values";
2
- import { Effect } from "effect";
3
2
 
4
3
  //#region src/client/factors/device.ts
5
4
  function isSignedInResult(result) {
@@ -8,8 +7,8 @@ function isSignedInResult(result) {
8
7
  /** @internal */
9
8
  function createDeviceClient(deps) {
10
9
  const { proxy, convex, requireApiRefs, proxyFetch, setTokenAndMaybeWait } = deps;
11
- const requestDeviceSignIn = (params) => Effect.tryPromise({
12
- try: async () => proxy ? await proxyFetch({
10
+ const requestDeviceSignIn = async (params) => {
11
+ return proxy ? await proxyFetch({
13
12
  action: "auth:signIn",
14
13
  args: {
15
14
  provider: "device",
@@ -18,9 +17,8 @@ function createDeviceClient(deps) {
18
17
  }) : await convex.action(requireApiRefs().signIn, {
19
18
  provider: "device",
20
19
  params
21
- }),
22
- catch: (error) => error
23
- });
20
+ });
21
+ };
24
22
  return {
25
23
  poll: async (opts) => {
26
24
  const { code } = opts;
@@ -32,15 +30,20 @@ function createDeviceClient(deps) {
32
30
  flow: "poll",
33
31
  deviceCode: code.deviceCode
34
32
  };
35
- const pollResult = await Effect.runPromise(requestDeviceSignIn(params).pipe(Effect.catchIf((error) => error instanceof ConvexError, (error) => {
36
- const code$1 = error.data?.code;
37
- if (code$1 === "DEVICE_AUTHORIZATION_PENDING") return Effect.succeed(null);
38
- if (code$1 === "DEVICE_SLOW_DOWN") return Effect.promise(async () => {
39
- await new Promise((resolve) => setTimeout(resolve, intervalMs));
40
- return null;
41
- });
42
- return Effect.fail(error);
43
- })));
33
+ let pollResult;
34
+ try {
35
+ pollResult = await requestDeviceSignIn(params);
36
+ } catch (error) {
37
+ if (error instanceof ConvexError) {
38
+ const errorCode = error.data?.code;
39
+ if (errorCode === "DEVICE_AUTHORIZATION_PENDING") continue;
40
+ if (errorCode === "DEVICE_SLOW_DOWN") {
41
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
42
+ continue;
43
+ }
44
+ }
45
+ throw error;
46
+ }
44
47
  if (pollResult === null) continue;
45
48
  if (isSignedInResult(pollResult) && pollResult.tokens) {
46
49
  if (proxy) await setTokenAndMaybeWait({
@@ -74,10 +77,14 @@ function createDeviceClient(deps) {
74
77
  flow: "verify",
75
78
  userCode: opts.code
76
79
  };
77
- await Effect.runPromise(requestDeviceSignIn(params).pipe(Effect.asVoid, Effect.mapError((error) => new ConvexError({
78
- code: "DEVICE_AUTHORIZATION_FAILED",
79
- message: error instanceof Error ? error.message : "Invalid or expired code."
80
- }))));
80
+ try {
81
+ await requestDeviceSignIn(params);
82
+ } catch (error) {
83
+ throw new ConvexError({
84
+ code: "DEVICE_AUTHORIZATION_FAILED",
85
+ message: error instanceof Error ? error.message : "Invalid or expired code."
86
+ });
87
+ }
81
88
  }
82
89
  };
83
90
  }