limen-auth 0.0.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.
- package/LICENSE +21 -0
- package/README.md +72 -0
- package/dist/bearer-Cqmrmjjf.mjs +84 -0
- package/dist/bearer-Cqmrmjjf.mjs.map +1 -0
- package/dist/client-Er91De-z.mjs +705 -0
- package/dist/client-Er91De-z.mjs.map +1 -0
- package/dist/constants-CsR2pQ_9.mjs +15 -0
- package/dist/constants-CsR2pQ_9.mjs.map +1 -0
- package/dist/define-plugin-C7WOGU4b.mjs +24 -0
- package/dist/define-plugin-C7WOGU4b.mjs.map +1 -0
- package/dist/define-plugin-Dv0xXIaH.d.mts +450 -0
- package/dist/define-plugin-Dv0xXIaH.d.mts.map +1 -0
- package/dist/errors-4YJYt6f0.mjs +37 -0
- package/dist/errors-4YJYt6f0.mjs.map +1 -0
- package/dist/helpers-Cs3VtXdv.mjs +54 -0
- package/dist/helpers-Cs3VtXdv.mjs.map +1 -0
- package/dist/helpers-CvmKjWi2.d.mts +10 -0
- package/dist/helpers-CvmKjWi2.d.mts.map +1 -0
- package/dist/index-B8SpHkSd.d.mts +48 -0
- package/dist/index-B8SpHkSd.d.mts.map +1 -0
- package/dist/index-C6atwjEq.d.mts +65 -0
- package/dist/index-C6atwjEq.d.mts.map +1 -0
- package/dist/index-C9EuA9UZ.d.mts +32 -0
- package/dist/index-C9EuA9UZ.d.mts.map +1 -0
- package/dist/index-Cgr2wHmM.d.mts +87 -0
- package/dist/index-Cgr2wHmM.d.mts.map +1 -0
- package/dist/index-DV6YcNSu.d.mts +81 -0
- package/dist/index-DV6YcNSu.d.mts.map +1 -0
- package/dist/index-dEksIImj.d.mts +28 -0
- package/dist/index-dEksIImj.d.mts.map +1 -0
- package/dist/index.d.mts +30 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +12 -0
- package/dist/index.mjs.map +1 -0
- package/dist/plugins/bearer/index.d.mts +2 -0
- package/dist/plugins/bearer/index.mjs +2 -0
- package/dist/plugins/credential/index.d.mts +2 -0
- package/dist/plugins/credential/index.mjs +50 -0
- package/dist/plugins/credential/index.mjs.map +1 -0
- package/dist/plugins/index.d.mts +7 -0
- package/dist/plugins/index.mjs +7 -0
- package/dist/plugins/magic-link/index.d.mts +2 -0
- package/dist/plugins/magic-link/index.mjs +21 -0
- package/dist/plugins/magic-link/index.mjs.map +1 -0
- package/dist/plugins/oauth/index.d.mts +2 -0
- package/dist/plugins/oauth/index.mjs +56 -0
- package/dist/plugins/oauth/index.mjs.map +1 -0
- package/dist/plugins/session-jwt/index.d.mts +2 -0
- package/dist/plugins/session-jwt/index.mjs +2 -0
- package/dist/plugins/two-factor/index.d.mts +2 -0
- package/dist/plugins/two-factor/index.mjs +52 -0
- package/dist/plugins/two-factor/index.mjs.map +1 -0
- package/dist/react/index.d.mts +24 -0
- package/dist/react/index.d.mts.map +1 -0
- package/dist/react/index.mjs +31 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/route-DGxvFqWl.mjs +19 -0
- package/dist/route-DGxvFqWl.mjs.map +1 -0
- package/dist/session-jwt-DgLdMQxP.mjs +129 -0
- package/dist/session-jwt-DgLdMQxP.mjs.map +1 -0
- package/dist/solid/index.d.mts +25 -0
- package/dist/solid/index.d.mts.map +1 -0
- package/dist/solid/index.mjs +28 -0
- package/dist/solid/index.mjs.map +1 -0
- package/dist/svelte/index.d.mts +25 -0
- package/dist/svelte/index.d.mts.map +1 -0
- package/dist/svelte/index.mjs +18 -0
- package/dist/svelte/index.mjs.map +1 -0
- package/dist/vue/index.d.mts +36 -0
- package/dist/vue/index.d.mts.map +1 -0
- package/dist/vue/index.mjs +36 -0
- package/dist/vue/index.mjs.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { n as defineRoutes, t as defineClientPlugin } from "../../define-plugin-C7WOGU4b.mjs";
|
|
2
|
+
import { t as route } from "../../route-DGxvFqWl.mjs";
|
|
3
|
+
//#region src/plugins/magic-link/index.ts
|
|
4
|
+
function magicLinkPlugin() {
|
|
5
|
+
return defineClientPlugin({
|
|
6
|
+
id: "magic-link",
|
|
7
|
+
basePath: "/magic-link",
|
|
8
|
+
routes: defineRoutes(route()({
|
|
9
|
+
method: "POST",
|
|
10
|
+
path: "/signin"
|
|
11
|
+
}), route()({
|
|
12
|
+
method: "GET",
|
|
13
|
+
path: "/verify",
|
|
14
|
+
parseSession: true
|
|
15
|
+
}))
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { magicLinkPlugin };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/magic-link/index.ts"],"sourcesContent":["import { defineClientPlugin, defineRoutes } from \"../../define-plugin\";\nimport { route } from \"../../route\";\nimport type { Session } from \"../../types\";\nimport type { RequestMagicLinkInput, VerifyMagicLinkInput } from \"./types\";\n\nexport function magicLinkPlugin<TFields = unknown>() {\n const routes = defineRoutes(\n route<RequestMagicLinkInput, { message: string }>()({\n method: \"POST\",\n path: \"/signin\",\n }),\n route<VerifyMagicLinkInput, Session<TFields>>()({\n method: \"GET\",\n path: \"/verify\",\n parseSession: true,\n }),\n );\n\n return defineClientPlugin({\n id: \"magic-link\",\n basePath: \"/magic-link\",\n routes,\n });\n}\n\nexport type { RequestMagicLinkInput, VerifyMagicLinkInput } from \"./types\";\n"],"mappings":";;;AAKA,SAAgB,kBAAqC;CAanD,OAAO,mBAAmB;EACxB,IAAI;EACJ,UAAU;EACV,QAfa,aACb,MAAkD,CAAC,CAAC;GAClD,QAAQ;GACR,MAAM;EACR,CAAC,GACD,MAA8C,CAAC,CAAC;GAC9C,QAAQ;GACR,MAAM;GACN,cAAc;EAChB,CAAC,CAMI;CACP,CAAC;AACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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";
|
|
2
|
+
export { type LinkOAuthInput, type OAuthAccount, type OAuthAuthorizeQuery, type OAuthAuthorizeResult, type OAuthTokens, type SignInOAuthInput, oauthClientPlugin };
|
|
@@ -0,0 +1,56 @@
|
|
|
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";
|
|
4
|
+
//#region src/plugins/oauth/index.ts
|
|
5
|
+
const fetchThenRedirect = async (ctx, input, http) => {
|
|
6
|
+
const { disableRedirect, ...rest } = input;
|
|
7
|
+
const { url } = await http(rest);
|
|
8
|
+
return {
|
|
9
|
+
url,
|
|
10
|
+
redirect: disableRedirect === true ? false : ctx.redirect(url)
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
function oauthClientPlugin() {
|
|
14
|
+
return defineClientPlugin({
|
|
15
|
+
id: "oauth",
|
|
16
|
+
basePath: "/oauth",
|
|
17
|
+
routes: defineRoutes(route()({
|
|
18
|
+
method: "GET",
|
|
19
|
+
path: "/:provider/authorize",
|
|
20
|
+
as: "signIn.social",
|
|
21
|
+
params: ["provider"],
|
|
22
|
+
handler: fetchThenRedirect
|
|
23
|
+
}), route()({
|
|
24
|
+
method: "GET",
|
|
25
|
+
path: "/:provider/link",
|
|
26
|
+
as: "social.link",
|
|
27
|
+
params: ["provider"],
|
|
28
|
+
handler: fetchThenRedirect
|
|
29
|
+
}), route()({
|
|
30
|
+
method: "DELETE",
|
|
31
|
+
path: "/:provider/unlink",
|
|
32
|
+
as: "social.unlink",
|
|
33
|
+
params: ["provider"]
|
|
34
|
+
}), route()({
|
|
35
|
+
method: "GET",
|
|
36
|
+
path: "/accounts",
|
|
37
|
+
as: "social.accounts"
|
|
38
|
+
}), route()({
|
|
39
|
+
method: "GET",
|
|
40
|
+
path: "/:provider/tokens",
|
|
41
|
+
as: "social.tokens",
|
|
42
|
+
params: ["provider"],
|
|
43
|
+
parse: camelizeKeys
|
|
44
|
+
}), route()({
|
|
45
|
+
method: "POST",
|
|
46
|
+
path: "/:provider/tokens/refresh",
|
|
47
|
+
as: "social.refreshTokens",
|
|
48
|
+
params: ["provider"],
|
|
49
|
+
parse: camelizeKeys
|
|
50
|
+
}))
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { oauthClientPlugin };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/oauth/index.ts"],"sourcesContent":["import { defineClientPlugin, defineRoutes } from \"../../define-plugin\";\nimport { camelizeKeys } from \"../../helpers\";\nimport { route, type RouteHandler } from \"../../route\";\nimport type { LinkOAuthInput, OAuthAccount, OAuthAuthorizeResult, OAuthTokens, SignInOAuthInput } from \"./types\";\n\nconst fetchThenRedirect: RouteHandler<SignInOAuthInput, OAuthAuthorizeResult> = async (ctx, input, http) => {\n const { disableRedirect, ...rest } = input;\n const { url } = await http<{ url: string }>(rest);\n return { url, redirect: disableRedirect === true ? false : ctx.redirect(url) };\n};\n\nexport function oauthClientPlugin() {\n const routes = defineRoutes(\n route<SignInOAuthInput, OAuthAuthorizeResult>()({\n method: \"GET\",\n path: \"/:provider/authorize\",\n as: \"signIn.social\",\n params: [\"provider\"],\n handler: fetchThenRedirect,\n }),\n route<LinkOAuthInput, OAuthAuthorizeResult>()({\n method: \"GET\",\n path: \"/:provider/link\",\n as: \"social.link\",\n params: [\"provider\"],\n handler: fetchThenRedirect,\n }),\n route<{ provider: string }, void>()({\n method: \"DELETE\",\n path: \"/:provider/unlink\",\n as: \"social.unlink\",\n params: [\"provider\"],\n }),\n route<void, OAuthAccount[]>()({\n method: \"GET\",\n path: \"/accounts\",\n as: \"social.accounts\",\n }),\n route<{ provider: string }, OAuthTokens>()({\n method: \"GET\",\n path: \"/:provider/tokens\",\n as: \"social.tokens\",\n params: [\"provider\"],\n parse: camelizeKeys,\n }),\n route<{ provider: string }, OAuthTokens>()({\n method: \"POST\",\n path: \"/:provider/tokens/refresh\",\n as: \"social.refreshTokens\",\n params: [\"provider\"],\n parse: camelizeKeys,\n }),\n );\n\n return defineClientPlugin({\n id: \"oauth\",\n basePath: \"/oauth\",\n routes,\n });\n}\n\nexport type {\n LinkOAuthInput,\n OAuthAccount,\n OAuthAuthorizeQuery,\n OAuthAuthorizeResult,\n OAuthTokens,\n SignInOAuthInput,\n} from \"./types\";\n"],"mappings":";;;;AAKA,MAAM,oBAA0E,OAAO,KAAK,OAAO,SAAS;CAC1G,MAAM,EAAE,iBAAiB,GAAG,SAAS;CACrC,MAAM,EAAE,QAAQ,MAAM,KAAsB,IAAI;CAChD,OAAO;EAAE;EAAK,UAAU,oBAAoB,OAAO,QAAQ,IAAI,SAAS,GAAG;CAAE;AAC/E;AAEA,SAAgB,oBAAoB;CA2ClC,OAAO,mBAAmB;EACxB,IAAI;EACJ,UAAU;EACV,QA7Ca,aACb,MAA8C,CAAC,CAAC;GAC9C,QAAQ;GACR,MAAM;GACN,IAAI;GACJ,QAAQ,CAAC,UAAU;GACnB,SAAS;EACX,CAAC,GACD,MAA4C,CAAC,CAAC;GAC5C,QAAQ;GACR,MAAM;GACN,IAAI;GACJ,QAAQ,CAAC,UAAU;GACnB,SAAS;EACX,CAAC,GACD,MAAkC,CAAC,CAAC;GAClC,QAAQ;GACR,MAAM;GACN,IAAI;GACJ,QAAQ,CAAC,UAAU;EACrB,CAAC,GACD,MAA4B,CAAC,CAAC;GAC5B,QAAQ;GACR,MAAM;GACN,IAAI;EACN,CAAC,GACD,MAAyC,CAAC,CAAC;GACzC,QAAQ;GACR,MAAM;GACN,IAAI;GACJ,QAAQ,CAAC,UAAU;GACnB,OAAO;EACT,CAAC,GACD,MAAyC,CAAC,CAAC;GACzC,QAAQ;GACR,MAAM;GACN,IAAI;GACJ,QAAQ,CAAC,UAAU;GACnB,OAAO;EACT,CAAC,CAMI;CACP,CAAC;AACH"}
|
|
@@ -0,0 +1,2 @@
|
|
|
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";
|
|
2
|
+
export { type DisableTwoFactorInput, type FinalizeSetupInput, type InitiateSetupInput, type SendOTPInput, type TwoFactorConfig, type TwoFactorMethod, type TwoFactorSetupURI, type VerifyInput, twoFactorPlugin };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { n as defineRoutes, t as defineClientPlugin } from "../../define-plugin-C7WOGU4b.mjs";
|
|
2
|
+
import { t as route } from "../../route-DGxvFqWl.mjs";
|
|
3
|
+
//#region src/plugins/two-factor/index.ts
|
|
4
|
+
function twoFactorPlugin(config) {
|
|
5
|
+
return defineClientPlugin({
|
|
6
|
+
id: "two-factor",
|
|
7
|
+
basePath: "/two-factor",
|
|
8
|
+
routes: defineRoutes(route()({
|
|
9
|
+
method: "POST",
|
|
10
|
+
path: "/initiate-setup"
|
|
11
|
+
}), route()({
|
|
12
|
+
method: "POST",
|
|
13
|
+
path: "/finalize-setup",
|
|
14
|
+
parseSession: true
|
|
15
|
+
}), route()({
|
|
16
|
+
method: "POST",
|
|
17
|
+
path: "/disable",
|
|
18
|
+
parseSession: true
|
|
19
|
+
}), route()({
|
|
20
|
+
method: "POST",
|
|
21
|
+
path: "/verify",
|
|
22
|
+
parseSession: true
|
|
23
|
+
}), route()({
|
|
24
|
+
method: "GET",
|
|
25
|
+
path: "/totp/uri",
|
|
26
|
+
as: "twoFactor.getTotpUri"
|
|
27
|
+
}), route()({
|
|
28
|
+
method: "GET",
|
|
29
|
+
path: "/backup-codes",
|
|
30
|
+
as: "twoFactor.getBackupCodes"
|
|
31
|
+
}), route()({
|
|
32
|
+
method: "PUT",
|
|
33
|
+
path: "/backup-codes",
|
|
34
|
+
as: "twoFactor.regenerateBackupCodes"
|
|
35
|
+
}), route()({
|
|
36
|
+
method: "POST",
|
|
37
|
+
path: "/otp/send",
|
|
38
|
+
as: "twoFactor.sendOTP"
|
|
39
|
+
})),
|
|
40
|
+
hooks: { afterResponse: [{
|
|
41
|
+
match: "/signin/credential",
|
|
42
|
+
run: (ctx) => {
|
|
43
|
+
if (ctx.body["two_factor_required"] === true) config.onTwoFactorRedirect();
|
|
44
|
+
return ctx;
|
|
45
|
+
}
|
|
46
|
+
}] }
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { twoFactorPlugin };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/two-factor/index.ts"],"sourcesContent":["import { defineClientPlugin, defineRoutes } from \"../../define-plugin\";\nimport { route } from \"../../route\";\nimport type { Session } from \"../../types\";\nimport type {\n DisableTwoFactorInput,\n FinalizeSetupInput,\n InitiateSetupInput,\n SendOTPInput,\n TwoFactorConfig,\n TwoFactorSetupURI,\n VerifyInput,\n} from \"./types\";\n\nexport function twoFactorPlugin<TFields = unknown>(config: TwoFactorConfig) {\n const routes = defineRoutes(\n route<InitiateSetupInput, TwoFactorSetupURI>()({\n method: \"POST\",\n path: \"/initiate-setup\",\n }),\n route<FinalizeSetupInput, Session<TFields>>()({\n method: \"POST\",\n path: \"/finalize-setup\",\n parseSession: true,\n }),\n route<DisableTwoFactorInput, Session<TFields>>()({\n method: \"POST\",\n path: \"/disable\",\n parseSession: true,\n }),\n route<VerifyInput, Session<TFields>>()({\n method: \"POST\",\n path: \"/verify\",\n parseSession: true,\n }),\n route<void, TwoFactorSetupURI>()({\n method: \"GET\",\n path: \"/totp/uri\",\n as: \"twoFactor.getTotpUri\",\n }),\n route<void, string[]>()({\n method: \"GET\",\n path: \"/backup-codes\",\n as: \"twoFactor.getBackupCodes\",\n }),\n route<void, string[]>()({\n method: \"PUT\",\n path: \"/backup-codes\",\n as: \"twoFactor.regenerateBackupCodes\",\n }),\n route<SendOTPInput, { message: string }>()({\n method: \"POST\",\n path: \"/otp/send\",\n as: \"twoFactor.sendOTP\",\n }),\n );\n\n return defineClientPlugin({\n id: \"two-factor\",\n basePath: \"/two-factor\",\n routes,\n hooks: {\n afterResponse: [\n {\n match: \"/signin/credential\",\n run: (ctx) => {\n const body = ctx.body as Record<string, unknown>;\n if (body[\"two_factor_required\"] === true) {\n config.onTwoFactorRedirect();\n }\n return ctx;\n },\n },\n ],\n },\n });\n}\n\nexport type {\n DisableTwoFactorInput,\n FinalizeSetupInput,\n InitiateSetupInput,\n SendOTPInput,\n TwoFactorConfig,\n TwoFactorMethod,\n TwoFactorSetupURI,\n VerifyInput,\n} from \"./types\";\n"],"mappings":";;;AAaA,SAAgB,gBAAmC,QAAyB;CA2C1E,OAAO,mBAAmB;EACxB,IAAI;EACJ,UAAU;EACV,QA7Ca,aACb,MAA6C,CAAC,CAAC;GAC7C,QAAQ;GACR,MAAM;EACR,CAAC,GACD,MAA4C,CAAC,CAAC;GAC5C,QAAQ;GACR,MAAM;GACN,cAAc;EAChB,CAAC,GACD,MAA+C,CAAC,CAAC;GAC/C,QAAQ;GACR,MAAM;GACN,cAAc;EAChB,CAAC,GACD,MAAqC,CAAC,CAAC;GACrC,QAAQ;GACR,MAAM;GACN,cAAc;EAChB,CAAC,GACD,MAA+B,CAAC,CAAC;GAC/B,QAAQ;GACR,MAAM;GACN,IAAI;EACN,CAAC,GACD,MAAsB,CAAC,CAAC;GACtB,QAAQ;GACR,MAAM;GACN,IAAI;EACN,CAAC,GACD,MAAsB,CAAC,CAAC;GACtB,QAAQ;GACR,MAAM;GACN,IAAI;EACN,CAAC,GACD,MAAyC,CAAC,CAAC;GACzC,QAAQ;GACR,MAAM;GACN,IAAI;EACN,CAAC,CAMI;EACL,OAAO,EACL,eAAe,CACb;GACE,OAAO;GACP,MAAM,QAAQ;IAEZ,IADa,IAAI,KACR,2BAA2B,MAClC,OAAO,oBAAoB;IAE7B,OAAO;GACT;EACF,CACF,EACF;CACF,CAAC;AACH"}
|
|
@@ -0,0 +1,24 @@
|
|
|
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";
|
|
3
|
+
|
|
4
|
+
//#region src/react/react-store.d.ts
|
|
5
|
+
declare function useStore<SomeStore extends Store>(store: SomeStore): StoreValue<SomeStore>;
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/react/index.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* An {@link AuthClient} augmented with React hooks.
|
|
10
|
+
*/
|
|
11
|
+
type ReactAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<AuthClient<Plugins, TFields> & {
|
|
12
|
+
/**
|
|
13
|
+
* Reactively read the session store. Re-renders the component whenever
|
|
14
|
+
* `{ data, isPending, error }` changes.
|
|
15
|
+
*/
|
|
16
|
+
useSession: () => SessionState<TFields>;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Create a Limen auth client with React hooks attached.
|
|
20
|
+
*/
|
|
21
|
+
declare function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(opts: CreateAuthClientOptions<Plugins, TFields>): ReactAuthClient<Plugins, TFields>;
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react/react-store.ts","../../src/react/index.ts"],"mappings":";;;;iBAGgB,QAAA,mBAA2B,KAAA,EAAO,KAAA,EAAO,SAAA,GAAY,UAAA,CAAW,SAAA;;;AAAhF;;;AAAA,KCOY,eAAA,0BAAyC,eAAA,yBAAwC,QAAA,CAC3F,UAAA,CAAW,OAAA,EAAS,OAAA;EDRmC;;;;ECarD,UAAA,QAAkB,YAAA,CAAa,OAAA;AAAA;;;;iBAOnB,gBAAA,gCAAgD,eAAA,qCAC9D,IAAA,EAAM,uBAAA,CAAwB,OAAA,EAAS,OAAA,IACtC,eAAA,CAAgB,OAAA,EAAS,OAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
|
19
|
+
//#region src/react/index.ts
|
|
20
|
+
/**
|
|
21
|
+
* Create a Limen auth client with React hooks attached.
|
|
22
|
+
*/
|
|
23
|
+
function createAuthClient(opts) {
|
|
24
|
+
const client = createAuthClient$1(opts);
|
|
25
|
+
const useSession = () => useStore(client.$session);
|
|
26
|
+
return Object.assign(client, { useSession });
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { createAuthClient, useStore };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["createCoreClient"],"sources":["../../src/react/react-store.ts","../../src/react/index.ts"],"sourcesContent":["import type { Store, StoreValue } from \"nanostores\";\nimport { useCallback, useRef, useSyncExternalStore } from \"react\";\n\nexport function useStore<SomeStore extends Store>(store: SomeStore): StoreValue<SomeStore> {\n type Value = StoreValue<SomeStore>;\n\n const snapshotRef = useRef<Value | undefined>(store.get());\n\n const subscribe = useCallback(\n (onChange: () => void) => {\n const emitValue = (value: Value): void => {\n if (snapshotRef.current === value) {\n return;\n }\n snapshotRef.current = value;\n onChange();\n };\n // Resync before listening: the value may have changed between render and\n // this effect, and `listen` does not fire for the current value.\n emitValue(store.value);\n return store.listen(emitValue);\n },\n [store],\n );\n\n const get = (): Value => snapshotRef.current as Value;\n\n return useSyncExternalStore(subscribe, get, get);\n}\n","import { createAuthClient as createCoreClient } from \"../client\";\nimport type { AnyClientPlugin } from \"../define-plugin\";\nimport type { SessionState } from \"../session-store\";\nimport type { Prettify } from \"../type-utils\";\nimport type { AuthClient, CreateAuthClientOptions } from \"../types\";\nimport { useStore } from \"./react-store\";\n\n/**\n * An {@link AuthClient} augmented with React hooks.\n */\nexport type ReactAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<\n AuthClient<Plugins, TFields> & {\n /**\n * Reactively read the session store. Re-renders the component whenever\n * `{ data, isPending, error }` changes.\n */\n useSession: () => SessionState<TFields>;\n }\n>;\n\n/**\n * Create a Limen auth client with React hooks attached.\n */\nexport function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(\n opts: CreateAuthClientOptions<Plugins, TFields>,\n): ReactAuthClient<Plugins, TFields> {\n const client = createCoreClient<Plugins, TFields>(opts);\n const useSession = (): SessionState<TFields> => useStore(client.$session);\n\n return Object.assign(client, { useSession }) as ReactAuthClient<Plugins, TFields>;\n}\n\nexport type { SessionState, SessionStore } from \"../session-store\";\nexport type { AuthClient, CreateAuthClientOptions, Session, User } from \"../types\";\nexport { useStore } from \"./react-store\";\n"],"mappings":";;;AAGA,SAAgB,SAAkC,OAAyC;CAGzF,MAAM,cAAc,OAA0B,MAAM,IAAI,CAAC;CAEzD,MAAM,YAAY,aACf,aAAyB;EACxB,MAAM,aAAa,UAAuB;GACxC,IAAI,YAAY,YAAY,OAC1B;GAEF,YAAY,UAAU;GACtB,SAAS;EACX;EAGA,UAAU,MAAM,KAAK;EACrB,OAAO,MAAM,OAAO,SAAS;CAC/B,GACA,CAAC,KAAK,CACR;CAEA,MAAM,YAAmB,YAAY;CAErC,OAAO,qBAAqB,WAAW,KAAK,GAAG;AACjD;;;;;;ACLA,SAAgB,iBACd,MACmC;CACnC,MAAM,SAASA,mBAAmC,IAAI;CACtD,MAAM,mBAA0C,SAAS,OAAO,QAAQ;CAExE,OAAO,OAAO,OAAO,QAAQ,EAAE,WAAW,CAAC;AAC7C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/route.ts
|
|
2
|
+
/**
|
|
3
|
+
* Define an HTTP-backed client method for a plugin. The input/output types
|
|
4
|
+
* become the generated method's argument and resolved value.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* route<VerifyInput, Session<TFields>>()({
|
|
8
|
+
* method: "POST",
|
|
9
|
+
* path: "/verify",
|
|
10
|
+
* parseSession: true,
|
|
11
|
+
* })
|
|
12
|
+
*/
|
|
13
|
+
function route() {
|
|
14
|
+
return (def) => def;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
export { route as t };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=route-DGxvFqWl.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-DGxvFqWl.mjs","names":[],"sources":["../src/route.ts"],"sourcesContent":["import type { RouteContext } from \"./context\";\nimport type { LimenError } from \"./errors\";\nimport type { HTTPMethod } from \"./types\";\n\ndeclare const INPUT: unique symbol;\ndeclare const OUTPUT: unique symbol;\n\n/**\n * Runs the route's default HTTP request and parser without session effects.\n * Pass an input override when a handler needs to omit client-only fields.\n */\nexport type HttpRunner<I> = <R = unknown>(input?: I) => Promise<R>;\n\n/**\n * Custom route behavior for flows that need more than the default request\n * pipeline.\n */\nexport type RouteHandler<I, O, TFields = unknown> = (\n ctx: RouteContext<TFields>,\n input: I,\n http: HttpRunner<I>,\n) => Promise<O>;\n\n/**\n * Per-call options accepted as the final argument of every generated route\n * method.\n */\nexport type RouteCallOptions<O = unknown> = {\n /** Invoked with the resolved value after the call succeeds. */\n onSuccess?: (data: O) => void;\n /** Invoked with the error just before it is re-thrown. */\n onError?: (error: LimenError) => void;\n};\n\n/**\n * Declarative client route definition. The public client chain is derived from\n * `path` unless `as` is provided.\n */\nexport type RouteDef<I, O> = {\n method: HTTPMethod;\n path: `/${string}`;\n\n /** Dotted client chain override, e.g. `\"twoFactor.getTotpUri\"`. */\n as?: string;\n\n /** Merged under the caller's input before serialization. */\n defaults?: Partial<I>;\n /** SDK input → wire body/query. Defaults to shallow camelCase → snake_case. */\n serialize?: (input: I) => unknown;\n /** Raw response → typed output. Ignored when `parseSession` is set. */\n parse?: (raw: unknown) => O;\n /**\n * Parse the response as a session and store it when it contains a `user`.\n * Set `skipStore` to return the parsed session without writing it.\n */\n parseSession?: boolean;\n /** Resolve `path` from the client base path instead of the plugin base path. */\n absolute?: boolean;\n\n /** Input keys used as `:param` path values. */\n params?: readonly (keyof I & string)[];\n\n /** For `parseSession` routes, skip the session-store write. */\n skipStore?: boolean;\n /** Clear the session store on success. */\n clearSession?: boolean;\n /** Revalidate the session after success. */\n refetchSession?: boolean;\n\n /** Set `false` to keep the route out of the public client API. */\n expose?: boolean;\n\n /** Override the default route call behavior. */\n handler?: RouteHandler<I, O>;\n};\n\n/**\n * A route definition carrying its input and output types for inference.\n */\nexport type RouteDescriptor<I, O, D extends RouteDef<I, O> = RouteDef<I, O>> = D & {\n readonly [INPUT]: I;\n readonly [OUTPUT]: O;\n};\n\n/**\n * Loose route-descriptor constraint for route tuples and plugin definitions.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- accepts any route descriptor\nexport type AnyRouteDescriptor = RouteDescriptor<any, any, any>;\n\n/**\n * Route definition with erased input/output types but typed fields.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- erases route I/O only\nexport type AnyRoute = RouteDef<any, any>;\n\nexport type InputOf<R> = R extends { readonly [INPUT]: infer I } ? I : never;\nexport type OutputOf<R> = R extends { readonly [OUTPUT]: infer O } ? O : never;\n\n/**\n * Define an HTTP-backed client method for a plugin. The input/output types\n * become the generated method's argument and resolved value.\n *\n * @example\n * route<VerifyInput, Session<TFields>>()({\n * method: \"POST\",\n * path: \"/verify\",\n * parseSession: true,\n * })\n */\nexport function route<I = void, O = unknown>() {\n return <const D extends RouteDef<I, O>>(def: D): RouteDescriptor<I, O, D> => def as RouteDescriptor<I, O, D>;\n}\n"],"mappings":";;;;;;;;;;;;AA8GA,SAAgB,QAA+B;CAC7C,QAAwC,QAAqC;AAC/E"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { a as SET_REFRESH_TOKEN_HEADER, i as SET_AUTH_TOKEN_HEADER } from "./constants-CsR2pQ_9.mjs";
|
|
2
|
+
import { t as LimenError } from "./errors-4YJYt6f0.mjs";
|
|
3
|
+
import { n as defineRoutes, t as defineClientPlugin } from "./define-plugin-C7WOGU4b.mjs";
|
|
4
|
+
import { t as route } from "./route-DGxvFqWl.mjs";
|
|
5
|
+
import { i as resolveDefaultStorage } from "./bearer-Cqmrmjjf.mjs";
|
|
6
|
+
//#region src/plugins/session-jwt/jwt.ts
|
|
7
|
+
/**
|
|
8
|
+
* Read the `exp` (seconds since epoch) from a JWT without verifying its
|
|
9
|
+
* signature — the server is the source of truth; the client only needs expiry
|
|
10
|
+
* to decide when to refresh. Returns `null` for anything malformed.
|
|
11
|
+
*/
|
|
12
|
+
function decodeJwtExp(token) {
|
|
13
|
+
const payload = token.split(".")[1];
|
|
14
|
+
if (!payload) return null;
|
|
15
|
+
try {
|
|
16
|
+
const b64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
17
|
+
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
18
|
+
const claims = JSON.parse(atob(padded));
|
|
19
|
+
return typeof claims.exp === "number" ? claims.exp : null;
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function isExpiring(token, skewMs) {
|
|
25
|
+
const exp = decodeJwtExp(token);
|
|
26
|
+
if (exp === null) return true;
|
|
27
|
+
return exp * 1e3 - skewMs <= Date.now();
|
|
28
|
+
}
|
|
29
|
+
function tokensFromHeaders(headers) {
|
|
30
|
+
const accessToken = headers.get(SET_AUTH_TOKEN_HEADER);
|
|
31
|
+
if (!accessToken) return null;
|
|
32
|
+
const tokens = { accessToken };
|
|
33
|
+
const refreshToken = headers.get(SET_REFRESH_TOKEN_HEADER);
|
|
34
|
+
if (refreshToken) tokens.refreshToken = refreshToken;
|
|
35
|
+
return tokens;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region src/plugins/session-jwt/index.ts
|
|
39
|
+
function sessionJwtPlugin(config = {}) {
|
|
40
|
+
const store = config.storage ?? resolveDefaultStorage(config.storageKey ?? "limen.tokens");
|
|
41
|
+
const skewMs = (config.expirySkewSeconds ?? 30) * 1e3;
|
|
42
|
+
const refreshRoute = route()({
|
|
43
|
+
method: "POST",
|
|
44
|
+
path: "/refresh",
|
|
45
|
+
parseSession: true,
|
|
46
|
+
expose: false
|
|
47
|
+
});
|
|
48
|
+
let ctx;
|
|
49
|
+
let run;
|
|
50
|
+
let inFlight = null;
|
|
51
|
+
const runRefresh = async () => {
|
|
52
|
+
const current = store.get();
|
|
53
|
+
if (!current?.refreshToken) throw new LimenError("No refresh token found", 401, "unauthorized");
|
|
54
|
+
try {
|
|
55
|
+
await run(refreshRoute, { refreshToken: current.refreshToken });
|
|
56
|
+
const tokens = store.get();
|
|
57
|
+
if (!tokens?.accessToken) throw new LimenError("Refresh did not return a valid access token", 500, "unknown");
|
|
58
|
+
return tokens;
|
|
59
|
+
} catch (err) {
|
|
60
|
+
store.clear();
|
|
61
|
+
ctx.setSession(null);
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const refresh = () => {
|
|
66
|
+
if (!inFlight) inFlight = runRefresh().finally(() => {
|
|
67
|
+
inFlight = null;
|
|
68
|
+
});
|
|
69
|
+
return inFlight;
|
|
70
|
+
};
|
|
71
|
+
const getAccessToken = async () => {
|
|
72
|
+
const current = store.get();
|
|
73
|
+
if (!current?.accessToken) return null;
|
|
74
|
+
if (!isExpiring(current.accessToken, skewMs)) return current.accessToken;
|
|
75
|
+
if (!current.refreshToken) return null;
|
|
76
|
+
return (await refresh()).accessToken;
|
|
77
|
+
};
|
|
78
|
+
const applyAuthHeader = async (req) => {
|
|
79
|
+
if (req.headers.has("Authorization")) return;
|
|
80
|
+
const token = await getAccessToken().catch(() => null);
|
|
81
|
+
if (token) req.headers.set("Authorization", `Bearer ${token}`);
|
|
82
|
+
};
|
|
83
|
+
return defineClientPlugin({
|
|
84
|
+
id: "session-jwt",
|
|
85
|
+
routes: defineRoutes(refreshRoute),
|
|
86
|
+
actions: (pluginCtx, pluginRun) => {
|
|
87
|
+
ctx = pluginCtx;
|
|
88
|
+
run = pluginRun;
|
|
89
|
+
return { sessionJwt: {
|
|
90
|
+
/**
|
|
91
|
+
* Get the current access token. If the token is expiring, refresh it.
|
|
92
|
+
* @returns The current access token or null if no token is found.
|
|
93
|
+
*/
|
|
94
|
+
getAccessToken,
|
|
95
|
+
refresh,
|
|
96
|
+
getTokens: () => store.get(),
|
|
97
|
+
clear: () => store.clear()
|
|
98
|
+
} };
|
|
99
|
+
},
|
|
100
|
+
hooks: {
|
|
101
|
+
beforeRequest: [{
|
|
102
|
+
match: (route) => route.path !== "/refresh",
|
|
103
|
+
run: async (req) => {
|
|
104
|
+
await applyAuthHeader(req);
|
|
105
|
+
return req;
|
|
106
|
+
}
|
|
107
|
+
}],
|
|
108
|
+
afterResponse: [{
|
|
109
|
+
allowOnFailure: true,
|
|
110
|
+
run: (res) => {
|
|
111
|
+
const tokens = tokensFromHeaders(res.headers);
|
|
112
|
+
if (tokens) store.set(tokens);
|
|
113
|
+
return res;
|
|
114
|
+
}
|
|
115
|
+
}, {
|
|
116
|
+
match: ["/signout", "/revoke-sessions"],
|
|
117
|
+
allowOnFailure: true,
|
|
118
|
+
run: (res) => {
|
|
119
|
+
store.clear();
|
|
120
|
+
return res;
|
|
121
|
+
}
|
|
122
|
+
}]
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { sessionJwtPlugin as t };
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=session-jwt-DgLdMQxP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-jwt-DgLdMQxP.mjs","names":[],"sources":["../src/plugins/session-jwt/jwt.ts","../src/plugins/session-jwt/index.ts"],"sourcesContent":["import { SET_AUTH_TOKEN_HEADER, SET_REFRESH_TOKEN_HEADER } from \"../../constants\";\nimport type { SessionJwtTokens } from \"./types\";\n\n/**\n * Read the `exp` (seconds since epoch) from a JWT without verifying its\n * signature — the server is the source of truth; the client only needs expiry\n * to decide when to refresh. Returns `null` for anything malformed.\n */\nexport function decodeJwtExp(token: string): number | null {\n const payload = token.split(\".\")[1];\n if (!payload) {\n return null;\n }\n try {\n const b64 = payload.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padded = b64 + \"=\".repeat((4 - (b64.length % 4)) % 4);\n const claims = JSON.parse(atob(padded)) as { exp?: unknown };\n return typeof claims.exp === \"number\" ? claims.exp : null;\n } catch {\n return null;\n }\n}\n\nexport function isExpiring(token: string, skewMs: number): boolean {\n const exp = decodeJwtExp(token);\n if (exp === null) {\n return true;\n }\n return exp * 1000 - skewMs <= Date.now();\n}\n\nexport function tokensFromHeaders(headers: Headers): SessionJwtTokens | null {\n const accessToken = headers.get(SET_AUTH_TOKEN_HEADER);\n if (!accessToken) {\n return null;\n }\n\n const tokens: SessionJwtTokens = { accessToken };\n const refreshToken = headers.get(SET_REFRESH_TOKEN_HEADER);\n if (refreshToken) {\n tokens.refreshToken = refreshToken;\n }\n return tokens;\n}\n","import { DEFAULT_TOKEN_STORAGE_KEY } from \"../../constants\";\nimport type { AnyRouteContext } from \"../../context\";\nimport { defineClientPlugin, defineRoutes, type RunRoute } from \"../../define-plugin\";\nimport { LimenError } from \"../../errors\";\nimport { route } from \"../../route\";\nimport type { Session } from \"../../types\";\nimport { resolveDefaultStorage } from \"../bearer\";\nimport { DEFAULT_EXPIRY_SKEW_SECONDS } from \"./constants\";\nimport { isExpiring, tokensFromHeaders } from \"./jwt\";\nimport type { RefreshInput, SessionJwtPluginConfig, SessionJwtTokens } from \"./types\";\n\nexport function sessionJwtPlugin<TFields = unknown>(config: SessionJwtPluginConfig = {}) {\n const store = config.storage ?? resolveDefaultStorage(config.storageKey ?? DEFAULT_TOKEN_STORAGE_KEY);\n const skewMs = (config.expirySkewSeconds ?? DEFAULT_EXPIRY_SKEW_SECONDS) * 1000;\n\n const refreshRoute = route<RefreshInput, Session<TFields>>()({\n method: \"POST\",\n path: \"/refresh\",\n parseSession: true,\n expose: false,\n });\n\n let ctx!: AnyRouteContext;\n let run!: RunRoute;\n let inFlight: Promise<SessionJwtTokens> | null = null;\n\n const runRefresh = async (): Promise<SessionJwtTokens> => {\n const current = store.get();\n if (!current?.refreshToken) {\n throw new LimenError(\"No refresh token found\", 401, \"unauthorized\");\n }\n try {\n await run(refreshRoute, { refreshToken: current.refreshToken });\n const tokens = store.get();\n if (!tokens?.accessToken) {\n throw new LimenError(\"Refresh did not return a valid access token\", 500, \"unknown\");\n }\n return tokens;\n } catch (err) {\n store.clear();\n ctx.setSession(null);\n throw err;\n }\n };\n\n const refresh = (): Promise<SessionJwtTokens> => {\n if (!inFlight) {\n inFlight = runRefresh().finally(() => {\n inFlight = null;\n });\n }\n return inFlight;\n };\n\n const getAccessToken = async (): Promise<string | null> => {\n const current = store.get();\n if (!current?.accessToken) {\n return null;\n }\n\n if (!isExpiring(current.accessToken, skewMs)) {\n return current.accessToken;\n }\n\n if (!current.refreshToken) {\n return null;\n }\n return (await refresh()).accessToken;\n };\n\n const applyAuthHeader = async (req: { headers: Headers }): Promise<void> => {\n if (req.headers.has(\"Authorization\")) {\n return;\n }\n const token = await getAccessToken().catch(() => null);\n if (token) {\n req.headers.set(\"Authorization\", `Bearer ${token}`);\n }\n };\n\n return defineClientPlugin({\n id: \"session-jwt\",\n routes: defineRoutes(refreshRoute),\n actions: (pluginCtx, pluginRun) => {\n ctx = pluginCtx;\n run = pluginRun;\n return {\n sessionJwt: {\n /**\n * Get the current access token. If the token is expiring, refresh it.\n * @returns The current access token or null if no token is found.\n */\n getAccessToken,\n refresh,\n getTokens: () => store.get(),\n clear: () => store.clear(),\n },\n };\n },\n hooks: {\n beforeRequest: [\n {\n match: (route) => route.path !== \"/refresh\",\n run: async (req) => {\n await applyAuthHeader(req);\n return req;\n },\n },\n ],\n afterResponse: [\n {\n allowOnFailure: true,\n run: (res) => {\n const tokens = tokensFromHeaders(res.headers);\n if (tokens) {\n store.set(tokens);\n }\n return res;\n },\n },\n {\n match: [\"/signout\", \"/revoke-sessions\"],\n allowOnFailure: true,\n run: (res) => {\n store.clear();\n return res;\n },\n },\n ],\n },\n });\n}\n\nexport type { SessionJwtPluginConfig, SessionJwtTokens } from \"./types\";\n"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
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";
|
|
3
|
+
import { Accessor } from "solid-js";
|
|
4
|
+
|
|
5
|
+
//#region src/solid/solid-store.d.ts
|
|
6
|
+
declare function useStore<SomeStore extends Store, Value extends StoreValue<SomeStore>>(store: SomeStore): Accessor<Value>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/solid/index.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* An {@link AuthClient} augmented with Solid primitives.
|
|
11
|
+
*/
|
|
12
|
+
type SolidAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<AuthClient<Plugins, TFields> & {
|
|
13
|
+
/**
|
|
14
|
+
* Reactively read the session store as a Solid accessor. Updates whenever
|
|
15
|
+
* `{ data, isPending, error }` changes.
|
|
16
|
+
*/
|
|
17
|
+
useSession: () => Accessor<SessionState<TFields>>;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a Limen auth client with Solid primitives attached.
|
|
21
|
+
*/
|
|
22
|
+
declare function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(opts: CreateAuthClientOptions<Plugins, TFields>): SolidAuthClient<Plugins, TFields>;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { type AuthClient, type CreateAuthClientOptions, type Session, type SessionState, type SessionStore, SolidAuthClient, type User, createAuthClient, useStore };
|
|
25
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/solid/solid-store.ts","../../src/solid/index.ts"],"mappings":";;;;;iBAKgB,QAAA,mBAA2B,KAAA,gBAAqB,UAAA,CAAW,SAAA,GACzE,KAAA,EAAO,SAAA,GACN,QAAA,CAAS,KAAA;;;AAFZ;;;AAAA,KCMY,eAAA,0BAAyC,eAAA,yBAAwC,QAAA,CAC3F,UAAA,CAAW,OAAA,EAAS,OAAA;EDPqD;;;;ECYvE,UAAA,QAAkB,QAAA,CAAS,YAAA,CAAa,OAAA;AAAA;;;;iBAO5B,gBAAA,gCAAgD,eAAA,qCAC9D,IAAA,EAAM,uBAAA,CAAwB,OAAA,EAAS,OAAA,IACtC,eAAA,CAAgB,OAAA,EAAS,OAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { t as createAuthClient$1 } from "../client-Er91De-z.mjs";
|
|
2
|
+
import { onCleanup } from "solid-js";
|
|
3
|
+
import { createStore, reconcile } from "solid-js/store";
|
|
4
|
+
//#region src/solid/solid-store.ts
|
|
5
|
+
function useStore(store) {
|
|
6
|
+
const unbindActivation = store.listen(() => {});
|
|
7
|
+
const [state, setState] = createStore({ value: store.get() });
|
|
8
|
+
const unsubscribe = store.subscribe((value) => {
|
|
9
|
+
setState("value", reconcile(value));
|
|
10
|
+
});
|
|
11
|
+
onCleanup(() => unsubscribe());
|
|
12
|
+
unbindActivation();
|
|
13
|
+
return () => state.value;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/solid/index.ts
|
|
17
|
+
/**
|
|
18
|
+
* Create a Limen auth client with Solid primitives attached.
|
|
19
|
+
*/
|
|
20
|
+
function createAuthClient(opts) {
|
|
21
|
+
const client = createAuthClient$1(opts);
|
|
22
|
+
const useSession = () => useStore(client.$session);
|
|
23
|
+
return Object.assign(client, { useSession });
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { createAuthClient, useStore };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["createCoreClient"],"sources":["../../src/solid/solid-store.ts","../../src/solid/index.ts"],"sourcesContent":["import type { Store, StoreValue } from \"nanostores\";\nimport type { Accessor } from \"solid-js\";\nimport { onCleanup } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\n\nexport function useStore<SomeStore extends Store, Value extends StoreValue<SomeStore>>(\n store: SomeStore,\n): Accessor<Value> {\n // Activate the store so `get()` is populated, then hand off to the real\n // subscriber and unbind — avoids a dangling activation (https://github.com/nanostores/solid/issues/19).\n const unbindActivation = store.listen(() => {});\n\n const [state, setState] = createStore({ value: store.get() as Value });\n\n // `reconcile` diffs each update so only changed paths re-trigger (fine-grained).\n const unsubscribe = store.subscribe((value) => {\n setState(\"value\", reconcile(value as Value));\n });\n\n onCleanup(() => unsubscribe());\n unbindActivation();\n\n return () => state.value;\n}\n","import type { Accessor } from \"solid-js\";\nimport { createAuthClient as createCoreClient } from \"../client\";\nimport type { AnyClientPlugin } from \"../define-plugin\";\nimport type { SessionState } from \"../session-store\";\nimport type { Prettify } from \"../type-utils\";\nimport type { AuthClient, CreateAuthClientOptions } from \"../types\";\nimport { useStore } from \"./solid-store\";\n\n/**\n * An {@link AuthClient} augmented with Solid primitives.\n */\nexport type SolidAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<\n AuthClient<Plugins, TFields> & {\n /**\n * Reactively read the session store as a Solid accessor. Updates whenever\n * `{ data, isPending, error }` changes.\n */\n useSession: () => Accessor<SessionState<TFields>>;\n }\n>;\n\n/**\n * Create a Limen auth client with Solid primitives attached.\n */\nexport function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(\n opts: CreateAuthClientOptions<Plugins, TFields>,\n): SolidAuthClient<Plugins, TFields> {\n const client = createCoreClient<Plugins, TFields>(opts);\n const useSession = (): Accessor<SessionState<TFields>> => useStore(client.$session);\n\n return Object.assign(client, { useSession }) as SolidAuthClient<Plugins, TFields>;\n}\n\nexport type { SessionState, SessionStore } from \"../session-store\";\nexport type { AuthClient, CreateAuthClientOptions, Session, User } from \"../types\";\nexport { useStore } from \"./solid-store\";\n"],"mappings":";;;;AAKA,SAAgB,SACd,OACiB;CAGjB,MAAM,mBAAmB,MAAM,aAAa,CAAC,CAAC;CAE9C,MAAM,CAAC,OAAO,YAAY,YAAY,EAAE,OAAO,MAAM,IAAI,EAAW,CAAC;CAGrE,MAAM,cAAc,MAAM,WAAW,UAAU;EAC7C,SAAS,SAAS,UAAU,KAAc,CAAC;CAC7C,CAAC;CAED,gBAAgB,YAAY,CAAC;CAC7B,iBAAiB;CAEjB,aAAa,MAAM;AACrB;;;;;;ACCA,SAAgB,iBACd,MACmC;CACnC,MAAM,SAASA,mBAAmC,IAAI;CACtD,MAAM,mBAAoD,SAAS,OAAO,QAAQ;CAElF,OAAO,OAAO,OAAO,QAAQ,EAAE,WAAW,CAAC;AAC7C"}
|
|
@@ -0,0 +1,25 @@
|
|
|
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 { Readable } from "svelte/store";
|
|
3
|
+
|
|
4
|
+
//#region src/svelte/index.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* An {@link AuthClient} augmented with Svelte stores.
|
|
7
|
+
*/
|
|
8
|
+
type SvelteAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<AuthClient<Plugins, TFields> & {
|
|
9
|
+
/**
|
|
10
|
+
* The reactive session as a Svelte readable store. Use it with `$`:
|
|
11
|
+
* `$session.data`, `$session.isPending`, `$session.error`.
|
|
12
|
+
*/
|
|
13
|
+
useSession: () => Readable<SessionState<TFields>>;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Create a Limen auth client with Svelte stores attached.
|
|
17
|
+
*
|
|
18
|
+
* nanostores stores already satisfy Svelte's store contract (`subscribe(run)`
|
|
19
|
+
* fires immediately and returns an unsubscribe), so `useSession` returns the
|
|
20
|
+
* reactive `$session` store directly — no wrapper.
|
|
21
|
+
*/
|
|
22
|
+
declare function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(opts: CreateAuthClientOptions<Plugins, TFields>): SvelteAuthClient<Plugins, TFields>;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { type AuthClient, type CreateAuthClientOptions, type Session, type SessionState, type SessionStore, SvelteAuthClient, type User, createAuthClient };
|
|
25
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/svelte/index.ts"],"mappings":";;;;;;;KAUY,gBAAA,0BAA0C,eAAA,yBAAwC,QAAA,CAC5F,UAAA,CAAW,OAAA,EAAS,OAAA;EAAA;;;;EAKlB,UAAA,QAAkB,QAAA,CAAS,YAAA,CAAa,OAAA;AAAA;;;;;;;;iBAW5B,gBAAA,gCAAgD,eAAA,qCAC9D,IAAA,EAAM,uBAAA,CAAwB,OAAA,EAAS,OAAA,IACtC,gBAAA,CAAiB,OAAA,EAAS,OAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { t as createAuthClient$1 } from "../client-Er91De-z.mjs";
|
|
2
|
+
//#region src/svelte/index.ts
|
|
3
|
+
/**
|
|
4
|
+
* Create a Limen auth client with Svelte stores attached.
|
|
5
|
+
*
|
|
6
|
+
* nanostores stores already satisfy Svelte's store contract (`subscribe(run)`
|
|
7
|
+
* fires immediately and returns an unsubscribe), so `useSession` returns the
|
|
8
|
+
* reactive `$session` store directly — no wrapper.
|
|
9
|
+
*/
|
|
10
|
+
function createAuthClient(opts) {
|
|
11
|
+
const client = createAuthClient$1(opts);
|
|
12
|
+
const useSession = () => client.$session;
|
|
13
|
+
return Object.assign(client, { useSession });
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { createAuthClient };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["createCoreClient"],"sources":["../../src/svelte/index.ts"],"sourcesContent":["import type { Readable } from \"svelte/store\";\nimport { createAuthClient as createCoreClient } from \"../client\";\nimport type { AnyClientPlugin } from \"../define-plugin\";\nimport type { SessionState } from \"../session-store\";\nimport type { Prettify } from \"../type-utils\";\nimport type { AuthClient, CreateAuthClientOptions } from \"../types\";\n\n/**\n * An {@link AuthClient} augmented with Svelte stores.\n */\nexport type SvelteAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<\n AuthClient<Plugins, TFields> & {\n /**\n * The reactive session as a Svelte readable store. Use it with `$`:\n * `$session.data`, `$session.isPending`, `$session.error`.\n */\n useSession: () => Readable<SessionState<TFields>>;\n }\n>;\n\n/**\n * Create a Limen auth client with Svelte stores attached.\n *\n * nanostores stores already satisfy Svelte's store contract (`subscribe(run)`\n * fires immediately and returns an unsubscribe), so `useSession` returns the\n * reactive `$session` store directly — no wrapper.\n */\nexport function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(\n opts: CreateAuthClientOptions<Plugins, TFields>,\n): SvelteAuthClient<Plugins, TFields> {\n const client = createCoreClient<Plugins, TFields>(opts);\n const useSession = (): Readable<SessionState<TFields>> =>\n client.$session as unknown as Readable<SessionState<TFields>>;\n\n return Object.assign(client, { useSession }) as SvelteAuthClient<Plugins, TFields>;\n}\n\nexport type { SessionState, SessionStore } from \"../session-store\";\nexport type { AuthClient, CreateAuthClientOptions, Session, User } from \"../types\";\n"],"mappings":";;;;;;;;;AA2BA,SAAgB,iBACd,MACoC;CACpC,MAAM,SAASA,mBAAmC,IAAI;CACtD,MAAM,mBACJ,OAAO;CAET,OAAO,OAAO,OAAO,QAAQ,EAAE,WAAW,CAAC;AAC7C"}
|
|
@@ -0,0 +1,36 @@
|
|
|
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";
|
|
3
|
+
import { DeepReadonly, ShallowRef, UnwrapNestedRefs } from "vue";
|
|
4
|
+
|
|
5
|
+
//#region src/vue/vue-store.d.ts
|
|
6
|
+
/** What {@link useStore} returns: a readonly reactive ref of the store value. */
|
|
7
|
+
type ReactiveValue<Value> = DeepReadonly<UnwrapNestedRefs<ShallowRef<Value>>>;
|
|
8
|
+
/**
|
|
9
|
+
* Subscribe a Vue component to a nanostores store.
|
|
10
|
+
*
|
|
11
|
+
* Modeled on `@nanostores/vue`'s `useStore`: a `shallowRef` mirrors the store
|
|
12
|
+
* value, `subscribe` keeps it in sync (firing once immediately), and the
|
|
13
|
+
* listener is torn down on scope dispose. On the server (no `window`) it reads
|
|
14
|
+
* once without subscribing, so a store seeded with `initialSession` renders
|
|
15
|
+
* without leaving a subscription behind.
|
|
16
|
+
*/
|
|
17
|
+
declare function useStore<SomeStore extends Store>(store: SomeStore): ReactiveValue<StoreValue<SomeStore>>;
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/vue/index.d.ts
|
|
20
|
+
/**
|
|
21
|
+
* An {@link AuthClient} augmented with Vue composables.
|
|
22
|
+
*/
|
|
23
|
+
type VueAuthClient<Plugins extends readonly AnyClientPlugin[], TFields = unknown> = Prettify<AuthClient<Plugins, TFields> & {
|
|
24
|
+
/**
|
|
25
|
+
* Reactively read the session store as a readonly ref. Updates whenever
|
|
26
|
+
* `{ data, isPending, error }` changes.
|
|
27
|
+
*/
|
|
28
|
+
useSession: () => ReactiveValue<SessionState<TFields>>;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Create a Limen auth client with Vue composables attached.
|
|
32
|
+
*/
|
|
33
|
+
declare function createAuthClient<const Plugins extends readonly AnyClientPlugin[] = readonly [], TFields = unknown>(opts: CreateAuthClientOptions<Plugins, TFields>): VueAuthClient<Plugins, TFields>;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { type AuthClient, type CreateAuthClientOptions, type ReactiveValue, type Session, type SessionState, type SessionStore, type User, VueAuthClient, createAuthClient, useStore };
|
|
36
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/vue/vue-store.ts","../../src/vue/index.ts"],"mappings":";;;;;;KAKY,aAAA,UAAuB,YAAA,CAAa,gBAAA,CAAiB,UAAA,CAAW,KAAA;;AAA5E;;;;;;;;iBAWgB,QAAA,mBAA2B,KAAA,EAAO,KAAA,EAAO,SAAA,GAAY,aAAA,CAAc,UAAA,CAAW,SAAA;;;AAX9F;;;AAAA,KCMY,aAAA,0BAAuC,eAAA,yBAAwC,QAAA,CACzF,UAAA,CAAW,OAAA,EAAS,OAAA;EDP2C;;;;ECY7D,UAAA,QAAkB,aAAA,CAAc,YAAA,CAAa,OAAA;AAAA;;;;iBAOjC,gBAAA,gCAAgD,eAAA,qCAC9D,IAAA,EAAM,uBAAA,CAAwB,OAAA,EAAS,OAAA,IACtC,aAAA,CAAc,OAAA,EAAS,OAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { t as createAuthClient$1 } from "../client-Er91De-z.mjs";
|
|
2
|
+
import { getCurrentScope, onScopeDispose, readonly, shallowRef } from "vue";
|
|
3
|
+
//#region src/vue/vue-store.ts
|
|
4
|
+
/**
|
|
5
|
+
* Subscribe a Vue component to a nanostores store.
|
|
6
|
+
*
|
|
7
|
+
* Modeled on `@nanostores/vue`'s `useStore`: a `shallowRef` mirrors the store
|
|
8
|
+
* value, `subscribe` keeps it in sync (firing once immediately), and the
|
|
9
|
+
* listener is torn down on scope dispose. On the server (no `window`) it reads
|
|
10
|
+
* once without subscribing, so a store seeded with `initialSession` renders
|
|
11
|
+
* without leaving a subscription behind.
|
|
12
|
+
*/
|
|
13
|
+
function useStore(store) {
|
|
14
|
+
const state = shallowRef(store.get());
|
|
15
|
+
if (typeof window !== "undefined") {
|
|
16
|
+
const unsubscribe = store.subscribe((value) => {
|
|
17
|
+
state.value = value;
|
|
18
|
+
});
|
|
19
|
+
if (getCurrentScope()) onScopeDispose(unsubscribe);
|
|
20
|
+
}
|
|
21
|
+
return readonly(state);
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/vue/index.ts
|
|
25
|
+
/**
|
|
26
|
+
* Create a Limen auth client with Vue composables attached.
|
|
27
|
+
*/
|
|
28
|
+
function createAuthClient(opts) {
|
|
29
|
+
const client = createAuthClient$1(opts);
|
|
30
|
+
const useSession = () => useStore(client.$session);
|
|
31
|
+
return Object.assign(client, { useSession });
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { createAuthClient, useStore };
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=index.mjs.map
|