limen-auth 0.0.0 → 0.0.2-beta.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 (118) hide show
  1. package/README.md +18 -41
  2. package/dist/broadcast-channel.mjs +51 -0
  3. package/dist/build-tree.mjs +73 -0
  4. package/dist/client.d.mts +7 -0
  5. package/dist/client.mjs +71 -0
  6. package/dist/{constants-CsR2pQ_9.mjs → constants.mjs} +1 -3
  7. package/dist/context.d.mts +32 -0
  8. package/dist/define-plugin.d.mts +40 -0
  9. package/dist/{define-plugin-C7WOGU4b.mjs → define-plugin.mjs} +1 -3
  10. package/dist/envelope.mjs +39 -0
  11. package/dist/errors.d.mts +18 -0
  12. package/dist/{errors-4YJYt6f0.mjs → errors.mjs} +2 -5
  13. package/dist/fetcher.d.mts +17 -0
  14. package/dist/fetcher.mjs +112 -0
  15. package/dist/{helpers-CvmKjWi2.d.mts → helpers.d.mts} +1 -2
  16. package/dist/{helpers-Cs3VtXdv.mjs → helpers.mjs} +1 -3
  17. package/dist/hooks.d.mts +1 -0
  18. package/dist/hooks.mjs +34 -0
  19. package/dist/index.d.mts +14 -30
  20. package/dist/index.mjs +9 -11
  21. package/dist/infer.d.mts +42 -0
  22. package/dist/json-deep-equal.mjs +27 -0
  23. package/dist/normalize.d.mts +12 -0
  24. package/dist/normalize.mjs +19 -0
  25. package/dist/package.mjs +4 -0
  26. package/dist/path.mjs +41 -0
  27. package/dist/pipeline.mjs +65 -0
  28. package/dist/plugin.d.mts +71 -0
  29. package/dist/plugins/bearer/index.d.mts +13 -1
  30. package/dist/plugins/bearer/index.mjs +43 -1
  31. package/dist/plugins/bearer/storage.d.mts +8 -0
  32. package/dist/plugins/bearer/storage.mjs +41 -0
  33. package/dist/{index-B8SpHkSd.d.mts → plugins/bearer/types.d.mts} +1 -18
  34. package/dist/plugins/credential/index.d.mts +54 -1
  35. package/dist/plugins/credential/index.mjs +2 -4
  36. package/dist/plugins/credential/types.d.mts +35 -0
  37. package/dist/plugins/index.d.mts +13 -6
  38. package/dist/plugins/index.mjs +3 -2
  39. package/dist/plugins/magic-link/index.d.mts +17 -1
  40. package/dist/plugins/magic-link/index.mjs +2 -4
  41. package/dist/plugins/magic-link/types.d.mts +13 -0
  42. package/dist/plugins/oauth/index.d.mts +47 -1
  43. package/dist/plugins/oauth/index.mjs +3 -5
  44. package/dist/plugins/oauth/types.d.mts +35 -0
  45. package/dist/plugins/session-jwt/index.d.mts +24 -1
  46. package/dist/plugins/session-jwt/index.mjs +95 -1
  47. package/dist/plugins/session-jwt/jwt.mjs +34 -0
  48. package/dist/plugins/session-jwt/types.d.mts +11 -0
  49. package/dist/plugins/two-factor/index.d.mts +41 -1
  50. package/dist/plugins/two-factor/index.mjs +2 -4
  51. package/dist/plugins/two-factor/types.d.mts +26 -0
  52. package/dist/react/index.d.mts +6 -7
  53. package/dist/react/index.mjs +2 -20
  54. package/dist/react/react-store.d.mts +6 -0
  55. package/dist/react/react-store.mjs +18 -0
  56. package/dist/route.d.mts +80 -0
  57. package/dist/{route-DGxvFqWl.mjs → route.mjs} +1 -3
  58. package/dist/routes.d.mts +53 -0
  59. package/dist/routes.mjs +58 -0
  60. package/dist/serialize.d.mts +11 -0
  61. package/dist/serialize.mjs +23 -0
  62. package/dist/session-store.d.mts +29 -0
  63. package/dist/session-store.mjs +79 -0
  64. package/dist/session-sync.mjs +47 -0
  65. package/dist/solid/index.d.mts +6 -7
  66. package/dist/solid/index.mjs +2 -17
  67. package/dist/solid/solid-store.d.mts +7 -0
  68. package/dist/solid/solid-store.mjs +15 -0
  69. package/dist/svelte/index.d.mts +5 -3
  70. package/dist/svelte/index.mjs +1 -3
  71. package/dist/type-utils.d.mts +15 -0
  72. package/dist/types.d.mts +97 -0
  73. package/dist/version.d.mts +4 -0
  74. package/dist/version.mjs +5 -0
  75. package/dist/vue/index.d.mts +6 -19
  76. package/dist/vue/index.mjs +2 -25
  77. package/dist/vue/vue-store.d.mts +18 -0
  78. package/dist/vue/vue-store.mjs +23 -0
  79. package/package.json +4 -3
  80. package/dist/bearer-Cqmrmjjf.mjs +0 -84
  81. package/dist/bearer-Cqmrmjjf.mjs.map +0 -1
  82. package/dist/client-Er91De-z.mjs +0 -705
  83. package/dist/client-Er91De-z.mjs.map +0 -1
  84. package/dist/constants-CsR2pQ_9.mjs.map +0 -1
  85. package/dist/define-plugin-C7WOGU4b.mjs.map +0 -1
  86. package/dist/define-plugin-Dv0xXIaH.d.mts +0 -450
  87. package/dist/define-plugin-Dv0xXIaH.d.mts.map +0 -1
  88. package/dist/errors-4YJYt6f0.mjs.map +0 -1
  89. package/dist/helpers-Cs3VtXdv.mjs.map +0 -1
  90. package/dist/helpers-CvmKjWi2.d.mts.map +0 -1
  91. package/dist/index-B8SpHkSd.d.mts.map +0 -1
  92. package/dist/index-C6atwjEq.d.mts +0 -65
  93. package/dist/index-C6atwjEq.d.mts.map +0 -1
  94. package/dist/index-C9EuA9UZ.d.mts +0 -32
  95. package/dist/index-C9EuA9UZ.d.mts.map +0 -1
  96. package/dist/index-Cgr2wHmM.d.mts +0 -87
  97. package/dist/index-Cgr2wHmM.d.mts.map +0 -1
  98. package/dist/index-DV6YcNSu.d.mts +0 -81
  99. package/dist/index-DV6YcNSu.d.mts.map +0 -1
  100. package/dist/index-dEksIImj.d.mts +0 -28
  101. package/dist/index-dEksIImj.d.mts.map +0 -1
  102. package/dist/index.d.mts.map +0 -1
  103. package/dist/index.mjs.map +0 -1
  104. package/dist/plugins/credential/index.mjs.map +0 -1
  105. package/dist/plugins/magic-link/index.mjs.map +0 -1
  106. package/dist/plugins/oauth/index.mjs.map +0 -1
  107. package/dist/plugins/two-factor/index.mjs.map +0 -1
  108. package/dist/react/index.d.mts.map +0 -1
  109. package/dist/react/index.mjs.map +0 -1
  110. package/dist/route-DGxvFqWl.mjs.map +0 -1
  111. package/dist/session-jwt-DgLdMQxP.mjs +0 -129
  112. package/dist/session-jwt-DgLdMQxP.mjs.map +0 -1
  113. package/dist/solid/index.d.mts.map +0 -1
  114. package/dist/solid/index.mjs.map +0 -1
  115. package/dist/svelte/index.d.mts.map +0 -1
  116. package/dist/svelte/index.mjs.map +0 -1
  117. package/dist/vue/index.d.mts.map +0 -1
  118. package/dist/vue/index.mjs.map +0 -1
@@ -1,7 +1,8 @@
1
- import { i as resolveDefaultStorage, n as localStorageBearerStorage, r as memoryBearerStorage, t as bearerPlugin } from "../bearer-Cqmrmjjf.mjs";
1
+ import { localStorageBearerStorage, memoryBearerStorage, resolveDefaultStorage } from "./bearer/storage.mjs";
2
+ import { bearerPlugin } from "./bearer/index.mjs";
2
3
  import { credentialPasswordPlugin } from "./credential/index.mjs";
3
4
  import { magicLinkPlugin } from "./magic-link/index.mjs";
4
5
  import { oauthClientPlugin } from "./oauth/index.mjs";
5
- import { t as sessionJwtPlugin } from "../session-jwt-DgLdMQxP.mjs";
6
+ import { sessionJwtPlugin } from "./session-jwt/index.mjs";
6
7
  import { twoFactorPlugin } from "./two-factor/index.mjs";
7
8
  export { bearerPlugin, credentialPasswordPlugin, localStorageBearerStorage, magicLinkPlugin, memoryBearerStorage, oauthClientPlugin, resolveDefaultStorage, sessionJwtPlugin, twoFactorPlugin };
@@ -1,2 +1,18 @@
1
- import { n as RequestMagicLinkInput, r as VerifyMagicLinkInput, t as magicLinkPlugin } from "../../index-dEksIImj.mjs";
1
+ import { RouteDescriptor } from "../../route.mjs";
2
+ import { Session } from "../../types.mjs";
3
+ import { ClientPlugin } from "../../define-plugin.mjs";
4
+ import { RequestMagicLinkInput, VerifyMagicLinkInput } from "./types.mjs";
5
+
6
+ //#region src/plugins/magic-link/index.d.ts
7
+ declare function magicLinkPlugin<TFields = unknown>(): ClientPlugin<"magic-link", "/magic-link", [RouteDescriptor<RequestMagicLinkInput, {
8
+ message: string;
9
+ }, {
10
+ readonly method: "POST";
11
+ readonly path: "/signin";
12
+ }>, RouteDescriptor<VerifyMagicLinkInput, Session<TFields>, {
13
+ readonly method: "GET";
14
+ readonly path: "/verify";
15
+ readonly parseSession: true;
16
+ }>], Record<never, never>>;
17
+ //#endregion
2
18
  export { type RequestMagicLinkInput, type VerifyMagicLinkInput, magicLinkPlugin };
@@ -1,5 +1,5 @@
1
- import { n as defineRoutes, t as defineClientPlugin } from "../../define-plugin-C7WOGU4b.mjs";
2
- import { t as route } from "../../route-DGxvFqWl.mjs";
1
+ import { defineClientPlugin, defineRoutes } from "../../define-plugin.mjs";
2
+ import { route } from "../../route.mjs";
3
3
  //#region src/plugins/magic-link/index.ts
4
4
  function magicLinkPlugin() {
5
5
  return defineClientPlugin({
@@ -17,5 +17,3 @@ function magicLinkPlugin() {
17
17
  }
18
18
  //#endregion
19
19
  export { magicLinkPlugin };
20
-
21
- //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,13 @@
1
+ //#region src/plugins/magic-link/types.d.ts
2
+ type RequestMagicLinkInput = {
3
+ email: string;
4
+ redirectUri?: string;
5
+ newUserRedirectUri?: string;
6
+ errorRedirectUri?: string;
7
+ meta?: Record<string, unknown>;
8
+ };
9
+ type VerifyMagicLinkInput = {
10
+ token: string;
11
+ };
12
+ //#endregion
13
+ export { RequestMagicLinkInput, VerifyMagicLinkInput };
@@ -1,2 +1,48 @@
1
- import { a as OAuthAuthorizeResult, i as OAuthAuthorizeQuery, n as LinkOAuthInput, o as OAuthTokens, r as OAuthAccount, s as SignInOAuthInput, t as oauthClientPlugin } from "../../index-DV6YcNSu.mjs";
1
+ import { RouteDescriptor, RouteHandler } from "../../route.mjs";
2
+ import { ClientPlugin } from "../../define-plugin.mjs";
3
+ import { camelizeKeys } from "../../helpers.mjs";
4
+ import { LinkOAuthInput, OAuthAccount, OAuthAuthorizeQuery, OAuthAuthorizeResult, OAuthTokens, SignInOAuthInput } from "./types.mjs";
5
+
6
+ //#region src/plugins/oauth/index.d.ts
7
+ declare function oauthClientPlugin(): ClientPlugin<"oauth", "/oauth", [RouteDescriptor<SignInOAuthInput, OAuthAuthorizeResult, {
8
+ readonly method: "GET";
9
+ readonly path: "/:provider/authorize";
10
+ readonly as: "signIn.social";
11
+ readonly params: readonly ["provider"];
12
+ readonly handler: RouteHandler<SignInOAuthInput, OAuthAuthorizeResult>;
13
+ }>, RouteDescriptor<SignInOAuthInput, OAuthAuthorizeResult, {
14
+ readonly method: "GET";
15
+ readonly path: "/:provider/link";
16
+ readonly as: "social.link";
17
+ readonly params: readonly ["provider"];
18
+ readonly handler: RouteHandler<SignInOAuthInput, OAuthAuthorizeResult>;
19
+ }>, RouteDescriptor<{
20
+ provider: string;
21
+ }, void, {
22
+ readonly method: "DELETE";
23
+ readonly path: "/:provider/unlink";
24
+ readonly as: "social.unlink";
25
+ readonly params: readonly ["provider"];
26
+ }>, RouteDescriptor<void, OAuthAccount[], {
27
+ readonly method: "GET";
28
+ readonly path: "/accounts";
29
+ readonly as: "social.accounts";
30
+ }>, RouteDescriptor<{
31
+ provider: string;
32
+ }, OAuthTokens, {
33
+ readonly method: "GET";
34
+ readonly path: "/:provider/tokens";
35
+ readonly as: "social.tokens";
36
+ readonly params: readonly ["provider"];
37
+ readonly parse: typeof camelizeKeys;
38
+ }>, RouteDescriptor<{
39
+ provider: string;
40
+ }, OAuthTokens, {
41
+ readonly method: "POST";
42
+ readonly path: "/:provider/tokens/refresh";
43
+ readonly as: "social.refreshTokens";
44
+ readonly params: readonly ["provider"];
45
+ readonly parse: typeof camelizeKeys;
46
+ }>], Record<never, never>>;
47
+ //#endregion
2
48
  export { type LinkOAuthInput, type OAuthAccount, type OAuthAuthorizeQuery, type OAuthAuthorizeResult, type OAuthTokens, type SignInOAuthInput, oauthClientPlugin };
@@ -1,6 +1,6 @@
1
- import { r as camelizeKeys } from "../../helpers-Cs3VtXdv.mjs";
2
- import { n as defineRoutes, t as defineClientPlugin } from "../../define-plugin-C7WOGU4b.mjs";
3
- import { t as route } from "../../route-DGxvFqWl.mjs";
1
+ import { camelizeKeys } from "../../helpers.mjs";
2
+ import { defineClientPlugin, defineRoutes } from "../../define-plugin.mjs";
3
+ import { route } from "../../route.mjs";
4
4
  //#region src/plugins/oauth/index.ts
5
5
  const fetchThenRedirect = async (ctx, input, http) => {
6
6
  const { disableRedirect, ...rest } = input;
@@ -52,5 +52,3 @@ function oauthClientPlugin() {
52
52
  }
53
53
  //#endregion
54
54
  export { oauthClientPlugin };
55
-
56
- //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,35 @@
1
+ //#region src/plugins/oauth/types.d.ts
2
+ type OAuthAuthorizeQuery = {
3
+ /** Where the server redirects the browser after a successful callback. */redirectUri?: string; /** Where the server redirects on a failed callback. Falls back to `redirectUri`. */
4
+ errorRedirectUri?: string;
5
+ };
6
+ type SignInOAuthInput = OAuthAuthorizeQuery & {
7
+ /** Provider id, e.g. `"google"` or `"github"`. */provider: string;
8
+ /**
9
+ * When true, skip auto-navigation and only resolve with the authorization
10
+ * URL — the caller is responsible for navigating the browser.
11
+ */
12
+ disableRedirect?: boolean;
13
+ };
14
+ type LinkOAuthInput = SignInOAuthInput;
15
+ type OAuthAuthorizeResult = {
16
+ /** Provider authorization URL. */url: string; /** Whether the SDK navigated to `url`. */
17
+ redirect: boolean;
18
+ };
19
+ type OAuthAccount = {
20
+ provider: string;
21
+ providerAccountId: string;
22
+ scopes: string[];
23
+ accessTokenExpiresAt?: string;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ };
27
+ type OAuthTokens = {
28
+ accessToken: string;
29
+ refreshToken?: string;
30
+ idToken?: string;
31
+ accessTokenExpiresAt?: string;
32
+ scope?: string;
33
+ };
34
+ //#endregion
35
+ export { LinkOAuthInput, OAuthAccount, OAuthAuthorizeQuery, OAuthAuthorizeResult, OAuthTokens, SignInOAuthInput };
@@ -1,2 +1,25 @@
1
- import { n as SessionJwtPluginConfig, r as SessionJwtTokens, t as sessionJwtPlugin } from "../../index-C9EuA9UZ.mjs";
1
+ import { RouteDescriptor } from "../../route.mjs";
2
+ import { Session } from "../../types.mjs";
3
+ import { ClientPlugin } from "../../define-plugin.mjs";
4
+ import { BearerTokens } from "../bearer/types.mjs";
5
+ import { RefreshInput, SessionJwtPluginConfig, SessionJwtTokens } from "./types.mjs";
6
+ //#region src/plugins/session-jwt/index.d.ts
7
+ declare function sessionJwtPlugin<TFields = unknown>(config?: SessionJwtPluginConfig): ClientPlugin<"session-jwt", "", [RouteDescriptor<RefreshInput, Session<TFields>, {
8
+ readonly method: "POST";
9
+ readonly path: "/refresh";
10
+ readonly parseSession: true;
11
+ readonly expose: false;
12
+ }>], {
13
+ sessionJwt: {
14
+ /**
15
+ * Get the current access token. If the token is expiring, refresh it.
16
+ * @returns The current access token or null if no token is found.
17
+ */
18
+ getAccessToken: () => Promise<string | null>;
19
+ refresh: () => Promise<SessionJwtTokens>;
20
+ getTokens: () => BearerTokens | null;
21
+ clear: () => void;
22
+ };
23
+ }>;
24
+ //#endregion
2
25
  export { type SessionJwtPluginConfig, type SessionJwtTokens, sessionJwtPlugin };
@@ -1,2 +1,96 @@
1
- import { t as sessionJwtPlugin } from "../../session-jwt-DgLdMQxP.mjs";
1
+ import "../../constants.mjs";
2
+ import { LimenError } from "../../errors.mjs";
3
+ import { defineClientPlugin, defineRoutes } from "../../define-plugin.mjs";
4
+ import { route } from "../../route.mjs";
5
+ import { resolveDefaultStorage } from "../bearer/storage.mjs";
6
+ import { isExpiring, tokensFromHeaders } from "./jwt.mjs";
7
+ //#region src/plugins/session-jwt/index.ts
8
+ function sessionJwtPlugin(config = {}) {
9
+ const store = config.storage ?? resolveDefaultStorage(config.storageKey ?? "limen.tokens");
10
+ const skewMs = (config.expirySkewSeconds ?? 30) * 1e3;
11
+ const refreshRoute = route()({
12
+ method: "POST",
13
+ path: "/refresh",
14
+ parseSession: true,
15
+ expose: false
16
+ });
17
+ let ctx;
18
+ let run;
19
+ let inFlight = null;
20
+ const runRefresh = async () => {
21
+ const current = store.get();
22
+ if (!current?.refreshToken) throw new LimenError("No refresh token found", 401, "unauthorized");
23
+ try {
24
+ await run(refreshRoute, { refreshToken: current.refreshToken });
25
+ const tokens = store.get();
26
+ if (!tokens?.accessToken) throw new LimenError("Refresh did not return a valid access token", 500, "unknown");
27
+ return tokens;
28
+ } catch (err) {
29
+ store.clear();
30
+ ctx.setSession(null);
31
+ throw err;
32
+ }
33
+ };
34
+ const refresh = () => {
35
+ if (!inFlight) inFlight = runRefresh().finally(() => {
36
+ inFlight = null;
37
+ });
38
+ return inFlight;
39
+ };
40
+ const getAccessToken = async () => {
41
+ const current = store.get();
42
+ if (!current?.accessToken) return null;
43
+ if (!isExpiring(current.accessToken, skewMs)) return current.accessToken;
44
+ if (!current.refreshToken) return null;
45
+ return (await refresh()).accessToken;
46
+ };
47
+ const applyAuthHeader = async (req) => {
48
+ if (req.headers.has("Authorization")) return;
49
+ const token = await getAccessToken().catch(() => null);
50
+ if (token) req.headers.set("Authorization", `Bearer ${token}`);
51
+ };
52
+ return defineClientPlugin({
53
+ id: "session-jwt",
54
+ routes: defineRoutes(refreshRoute),
55
+ actions: (pluginCtx, pluginRun) => {
56
+ ctx = pluginCtx;
57
+ run = pluginRun;
58
+ return { sessionJwt: {
59
+ /**
60
+ * Get the current access token. If the token is expiring, refresh it.
61
+ * @returns The current access token or null if no token is found.
62
+ */
63
+ getAccessToken,
64
+ refresh,
65
+ getTokens: () => store.get(),
66
+ clear: () => store.clear()
67
+ } };
68
+ },
69
+ hooks: {
70
+ beforeRequest: [{
71
+ match: (route) => route.path !== "/refresh",
72
+ run: async (req) => {
73
+ await applyAuthHeader(req);
74
+ return req;
75
+ }
76
+ }],
77
+ afterResponse: [{
78
+ allowOnFailure: true,
79
+ run: (res) => {
80
+ const tokens = tokensFromHeaders(res.headers);
81
+ if (tokens) store.set(tokens);
82
+ return res;
83
+ }
84
+ }, {
85
+ match: ["/signout", "/revoke-sessions"],
86
+ allowOnFailure: true,
87
+ run: (res) => {
88
+ store.clear();
89
+ return res;
90
+ }
91
+ }]
92
+ }
93
+ });
94
+ }
95
+ //#endregion
2
96
  export { sessionJwtPlugin };
@@ -0,0 +1,34 @@
1
+ import { SET_AUTH_TOKEN_HEADER, SET_REFRESH_TOKEN_HEADER } from "../../constants.mjs";
2
+ //#region src/plugins/session-jwt/jwt.ts
3
+ /**
4
+ * Read the `exp` (seconds since epoch) from a JWT without verifying its
5
+ * signature — the server is the source of truth; the client only needs expiry
6
+ * to decide when to refresh. Returns `null` for anything malformed.
7
+ */
8
+ function decodeJwtExp(token) {
9
+ const payload = token.split(".")[1];
10
+ if (!payload) return null;
11
+ try {
12
+ const b64 = payload.replace(/-/g, "+").replace(/_/g, "/");
13
+ const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
14
+ const claims = JSON.parse(atob(padded));
15
+ return typeof claims.exp === "number" ? claims.exp : null;
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+ function isExpiring(token, skewMs) {
21
+ const exp = decodeJwtExp(token);
22
+ if (exp === null) return true;
23
+ return exp * 1e3 - skewMs <= Date.now();
24
+ }
25
+ function tokensFromHeaders(headers) {
26
+ const accessToken = headers.get(SET_AUTH_TOKEN_HEADER);
27
+ if (!accessToken) return null;
28
+ const tokens = { accessToken };
29
+ const refreshToken = headers.get(SET_REFRESH_TOKEN_HEADER);
30
+ if (refreshToken) tokens.refreshToken = refreshToken;
31
+ return tokens;
32
+ }
33
+ //#endregion
34
+ export { isExpiring, tokensFromHeaders };
@@ -0,0 +1,11 @@
1
+ import { BearerPluginConfig, BearerTokens } from "../bearer/types.mjs";
2
+ //#region src/plugins/session-jwt/types.d.ts
3
+ type SessionJwtTokens = BearerTokens;
4
+ type SessionJwtPluginConfig = BearerPluginConfig & {
5
+ /** Refresh once the access token is within this many seconds of expiry. Default 30. */expirySkewSeconds?: number;
6
+ };
7
+ type RefreshInput = {
8
+ refreshToken: string;
9
+ };
10
+ //#endregion
11
+ export { RefreshInput, SessionJwtPluginConfig, SessionJwtTokens };
@@ -1,2 +1,42 @@
1
- import { a as SendOTPInput, c as TwoFactorSetupURI, i as InitiateSetupInput, l as VerifyInput, n as DisableTwoFactorInput, o as TwoFactorConfig, r as FinalizeSetupInput, s as TwoFactorMethod, t as twoFactorPlugin } from "../../index-C6atwjEq.mjs";
1
+ import { RouteDescriptor } from "../../route.mjs";
2
+ import { Session } from "../../types.mjs";
3
+ import { ClientPlugin } from "../../define-plugin.mjs";
4
+ import { DisableTwoFactorInput, FinalizeSetupInput, InitiateSetupInput, SendOTPInput, TwoFactorConfig, TwoFactorMethod, TwoFactorSetupURI, VerifyInput } from "./types.mjs";
5
+
6
+ //#region src/plugins/two-factor/index.d.ts
7
+ declare function twoFactorPlugin<TFields = unknown>(config: TwoFactorConfig): ClientPlugin<"two-factor", "/two-factor", [RouteDescriptor<InitiateSetupInput, TwoFactorSetupURI, {
8
+ readonly method: "POST";
9
+ readonly path: "/initiate-setup";
10
+ }>, RouteDescriptor<FinalizeSetupInput, Session<TFields>, {
11
+ readonly method: "POST";
12
+ readonly path: "/finalize-setup";
13
+ readonly parseSession: true;
14
+ }>, RouteDescriptor<DisableTwoFactorInput, Session<TFields>, {
15
+ readonly method: "POST";
16
+ readonly path: "/disable";
17
+ readonly parseSession: true;
18
+ }>, RouteDescriptor<VerifyInput, Session<TFields>, {
19
+ readonly method: "POST";
20
+ readonly path: "/verify";
21
+ readonly parseSession: true;
22
+ }>, RouteDescriptor<void, TwoFactorSetupURI, {
23
+ readonly method: "GET";
24
+ readonly path: "/totp/uri";
25
+ readonly as: "twoFactor.getTotpUri";
26
+ }>, RouteDescriptor<void, string[], {
27
+ readonly method: "GET";
28
+ readonly path: "/backup-codes";
29
+ readonly as: "twoFactor.getBackupCodes";
30
+ }>, RouteDescriptor<void, string[], {
31
+ readonly method: "PUT";
32
+ readonly path: "/backup-codes";
33
+ readonly as: "twoFactor.regenerateBackupCodes";
34
+ }>, RouteDescriptor<SendOTPInput, {
35
+ message: string;
36
+ }, {
37
+ readonly method: "POST";
38
+ readonly path: "/otp/send";
39
+ readonly as: "twoFactor.sendOTP";
40
+ }>], Record<never, never>>;
41
+ //#endregion
2
42
  export { type DisableTwoFactorInput, type FinalizeSetupInput, type InitiateSetupInput, type SendOTPInput, type TwoFactorConfig, type TwoFactorMethod, type TwoFactorSetupURI, type VerifyInput, twoFactorPlugin };
@@ -1,5 +1,5 @@
1
- import { n as defineRoutes, t as defineClientPlugin } from "../../define-plugin-C7WOGU4b.mjs";
2
- import { t as route } from "../../route-DGxvFqWl.mjs";
1
+ import { defineClientPlugin, defineRoutes } from "../../define-plugin.mjs";
2
+ import { route } from "../../route.mjs";
3
3
  //#region src/plugins/two-factor/index.ts
4
4
  function twoFactorPlugin(config) {
5
5
  return defineClientPlugin({
@@ -48,5 +48,3 @@ function twoFactorPlugin(config) {
48
48
  }
49
49
  //#endregion
50
50
  export { twoFactorPlugin };
51
-
52
- //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,26 @@
1
+ //#region src/plugins/two-factor/types.d.ts
2
+ type TwoFactorConfig = {
3
+ /** Called when sign-in requires a two-factor challenge. */onTwoFactorRedirect: () => void;
4
+ };
5
+ type VerifyInput = {
6
+ code: string;
7
+ method?: TwoFactorMethod;
8
+ };
9
+ type InitiateSetupInput = {
10
+ password: string;
11
+ };
12
+ type FinalizeSetupInput = {
13
+ code: string;
14
+ };
15
+ type DisableTwoFactorInput = {
16
+ password: string;
17
+ };
18
+ type SendOTPInput = {
19
+ email: string;
20
+ };
21
+ type TwoFactorSetupURI = {
22
+ uri: string;
23
+ };
24
+ type TwoFactorMethod = "totp" | "otp";
25
+ //#endregion
26
+ export { DisableTwoFactorInput, FinalizeSetupInput, InitiateSetupInput, SendOTPInput, TwoFactorConfig, TwoFactorMethod, TwoFactorSetupURI, VerifyInput };
@@ -1,9 +1,9 @@
1
- import { D as User, E as Session, O as SessionState, V as Prettify, _ as AuthClient, k as SessionStore, t as AnyClientPlugin, y as CreateAuthClientOptions } from "../define-plugin-Dv0xXIaH.mjs";
2
- import { Store, StoreValue } from "nanostores";
1
+ import { Prettify } from "../type-utils.mjs";
2
+ import { SessionState, SessionStore } from "../session-store.mjs";
3
+ import { AuthClient, CreateAuthClientOptions, Session, User } from "../types.mjs";
4
+ import { AnyClientPlugin } from "../define-plugin.mjs";
5
+ import { useStore } from "./react-store.mjs";
3
6
 
4
- //#region src/react/react-store.d.ts
5
- declare function useStore<SomeStore extends Store>(store: SomeStore): StoreValue<SomeStore>;
6
- //#endregion
7
7
  //#region src/react/index.d.ts
8
8
  /**
9
9
  * An {@link AuthClient} augmented with React hooks.
@@ -20,5 +20,4 @@ type ReactAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unkno
20
20
  */
21
21
  declare function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(opts: CreateAuthClientOptions<Plugins, TFields>): ReactAuthClient<Plugins, TFields>;
22
22
  //#endregion
23
- export { type AuthClient, type CreateAuthClientOptions, ReactAuthClient, type Session, type SessionState, type SessionStore, type User, createAuthClient, useStore };
24
- //# sourceMappingURL=index.d.mts.map
23
+ export { type AuthClient, type CreateAuthClientOptions, ReactAuthClient, type Session, type SessionState, type SessionStore, type User, createAuthClient, useStore };
@@ -1,21 +1,5 @@
1
- import { t as createAuthClient$1 } from "../client-Er91De-z.mjs";
2
- import { useCallback, useRef, useSyncExternalStore } from "react";
3
- //#region src/react/react-store.ts
4
- function useStore(store) {
5
- const snapshotRef = useRef(store.get());
6
- const subscribe = useCallback((onChange) => {
7
- const emitValue = (value) => {
8
- if (snapshotRef.current === value) return;
9
- snapshotRef.current = value;
10
- onChange();
11
- };
12
- emitValue(store.value);
13
- return store.listen(emitValue);
14
- }, [store]);
15
- const get = () => snapshotRef.current;
16
- return useSyncExternalStore(subscribe, get, get);
17
- }
18
- //#endregion
1
+ import { createAuthClient as createAuthClient$1 } from "../client.mjs";
2
+ import { useStore } from "./react-store.mjs";
19
3
  //#region src/react/index.ts
20
4
  /**
21
5
  * Create a Limen auth client with React hooks attached.
@@ -27,5 +11,3 @@ function createAuthClient(opts) {
27
11
  }
28
12
  //#endregion
29
13
  export { createAuthClient, useStore };
30
-
31
- //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,6 @@
1
+ import { Store, StoreValue } from "nanostores";
2
+
3
+ //#region src/react/react-store.d.ts
4
+ declare function useStore<SomeStore extends Store>(store: SomeStore): StoreValue<SomeStore>;
5
+ //#endregion
6
+ export { useStore };
@@ -0,0 +1,18 @@
1
+ import { useCallback, useRef, useSyncExternalStore } from "react";
2
+ //#region src/react/react-store.ts
3
+ function useStore(store) {
4
+ const snapshotRef = useRef(store.get());
5
+ const subscribe = useCallback((onChange) => {
6
+ const emitValue = (value) => {
7
+ if (snapshotRef.current === value) return;
8
+ snapshotRef.current = value;
9
+ onChange();
10
+ };
11
+ emitValue(store.value);
12
+ return store.listen(emitValue);
13
+ }, [store]);
14
+ const get = () => snapshotRef.current;
15
+ return useSyncExternalStore(subscribe, get, get);
16
+ }
17
+ //#endregion
18
+ export { useStore };
@@ -0,0 +1,80 @@
1
+ import { LimenError } from "./errors.mjs";
2
+ import { HTTPMethod } from "./types.mjs";
3
+ import { RouteContext } from "./context.mjs";
4
+
5
+ //#region src/route.d.ts
6
+ declare const INPUT: unique symbol;
7
+ declare const OUTPUT: unique symbol;
8
+ /**
9
+ * Runs the route's default HTTP request and parser without session effects.
10
+ * Pass an input override when a handler needs to omit client-only fields.
11
+ */
12
+ type HttpRunner<I> = <R = unknown>(input?: I) => Promise<R>;
13
+ /**
14
+ * Custom route behavior for flows that need more than the default request
15
+ * pipeline.
16
+ */
17
+ type RouteHandler<I, O, TFields = unknown> = (ctx: RouteContext<TFields>, input: I, http: HttpRunner<I>) => Promise<O>;
18
+ /**
19
+ * Per-call options accepted as the final argument of every generated route
20
+ * method.
21
+ */
22
+ type RouteCallOptions<O = unknown> = {
23
+ /** Invoked with the resolved value after the call succeeds. */onSuccess?: (data: O) => void; /** Invoked with the error just before it is re-thrown. */
24
+ onError?: (error: LimenError) => void;
25
+ };
26
+ /**
27
+ * Declarative client route definition. The public client chain is derived from
28
+ * `path` unless `as` is provided.
29
+ */
30
+ type RouteDef<I, O> = {
31
+ method: HTTPMethod;
32
+ path: `/${string}`; /** Dotted client chain override, e.g. `"twoFactor.getTotpUri"`. */
33
+ as?: string; /** Merged under the caller's input before serialization. */
34
+ defaults?: Partial<I>; /** SDK input → wire body/query. Defaults to shallow camelCase → snake_case. */
35
+ serialize?: (input: I) => unknown; /** Raw response → typed output. Ignored when `parseSession` is set. */
36
+ parse?: (raw: unknown) => O;
37
+ /**
38
+ * Parse the response as a session and store it when it contains a `user`.
39
+ * Set `skipStore` to return the parsed session without writing it.
40
+ */
41
+ parseSession?: boolean; /** Resolve `path` from the client base path instead of the plugin base path. */
42
+ absolute?: boolean; /** Input keys used as `:param` path values. */
43
+ params?: readonly (keyof I & string)[]; /** For `parseSession` routes, skip the session-store write. */
44
+ skipStore?: boolean; /** Clear the session store on success. */
45
+ clearSession?: boolean; /** Revalidate the session after success. */
46
+ refetchSession?: boolean; /** Set `false` to keep the route out of the public client API. */
47
+ expose?: boolean; /** Override the default route call behavior. */
48
+ handler?: RouteHandler<I, O>;
49
+ };
50
+ /**
51
+ * A route definition carrying its input and output types for inference.
52
+ */
53
+ type RouteDescriptor<I, O, D extends RouteDef<I, O> = RouteDef<I, O>> = D & {
54
+ readonly [INPUT]: I;
55
+ readonly [OUTPUT]: O;
56
+ };
57
+ /**
58
+ * Loose route-descriptor constraint for route tuples and plugin definitions.
59
+ */
60
+ type AnyRouteDescriptor = RouteDescriptor<any, any, any>;
61
+ type InputOf<R> = R extends {
62
+ readonly [INPUT]: infer I;
63
+ } ? I : never;
64
+ type OutputOf<R> = R extends {
65
+ readonly [OUTPUT]: infer O;
66
+ } ? O : never;
67
+ /**
68
+ * Define an HTTP-backed client method for a plugin. The input/output types
69
+ * become the generated method's argument and resolved value.
70
+ *
71
+ * @example
72
+ * route<VerifyInput, Session<TFields>>()({
73
+ * method: "POST",
74
+ * path: "/verify",
75
+ * parseSession: true,
76
+ * })
77
+ */
78
+ declare function route<I = void, O = unknown>(): <const D extends RouteDef<I, O>>(def: D) => RouteDescriptor<I, O, D>;
79
+ //#endregion
80
+ export { AnyRouteDescriptor, InputOf, OutputOf, RouteCallOptions, RouteDescriptor, RouteHandler, route };
@@ -14,6 +14,4 @@ function route() {
14
14
  return (def) => def;
15
15
  }
16
16
  //#endregion
17
- export { route as t };
18
-
19
- //# sourceMappingURL=route-DGxvFqWl.mjs.map
17
+ export { route };
@@ -0,0 +1,53 @@
1
+ import { RouteDescriptor } from "./route.mjs";
2
+ import { Session } from "./types.mjs";
3
+ import { ClientPlugin, InferPluginContribution } from "./define-plugin.mjs";
4
+
5
+ //#region src/routes.d.ts
6
+ type VerifyEmailInput = {
7
+ token: string;
8
+ };
9
+ type ActiveSession = {
10
+ id: string | number;
11
+ token: string;
12
+ userId: unknown;
13
+ createdAt: string;
14
+ expiresAt: string;
15
+ lastAccess: string;
16
+ metadata?: Record<string, unknown>;
17
+ };
18
+ /**
19
+ * Core routes available on every client.
20
+ */
21
+ declare function coreClientPlugin<TFields = unknown>(): ClientPlugin<"core", "/", [RouteDescriptor<void, ActiveSession[], {
22
+ readonly method: "GET";
23
+ readonly path: "/sessions";
24
+ }>, RouteDescriptor<void, void, {
25
+ readonly method: "POST";
26
+ readonly path: "/signout";
27
+ readonly clearSession: true;
28
+ }>, RouteDescriptor<void, void, {
29
+ readonly method: "POST";
30
+ readonly path: "/revoke-sessions";
31
+ readonly clearSession: true;
32
+ }>, RouteDescriptor<VerifyEmailInput, string, {
33
+ readonly method: "POST";
34
+ readonly path: "/verify-email";
35
+ readonly refetchSession: true;
36
+ }>, RouteDescriptor<void, string, {
37
+ readonly method: "POST";
38
+ readonly path: "/email-verifications";
39
+ readonly as: "requestEmailVerification";
40
+ }>], {
41
+ /**
42
+ * Revalidate session state with `GET /me`, update `$session`, and return the
43
+ * resolved value (`null` when signed out).
44
+ *
45
+ * Prefer subscribing to `$session` for reactive UI state (`data`, `isPending`,
46
+ * `error`). Use `getSession()` when you need an awaited server re-check, such
47
+ * as route guards or SSR revalidation after `initialSession`.
48
+ */
49
+ getSession: () => Promise<Session<TFields> | null>;
50
+ }>;
51
+ type CoreContribution<TFields = unknown> = InferPluginContribution<ReturnType<typeof coreClientPlugin<TFields>>>;
52
+ //#endregion
53
+ export { ActiveSession, CoreContribution, VerifyEmailInput, coreClientPlugin };