@inai-dev/astro 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @inai-dev/astro
2
+
3
+ Astro integration for InAI Auth. Provides middleware, server-side helpers, and Astro components for authentication.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @inai-dev/astro
9
+ ```
10
+
11
+ ## Setup
12
+
13
+ ### 1. Add Integration
14
+
15
+ ```ts
16
+ // astro.config.mjs
17
+ import { defineConfig } from "astro/config";
18
+ import inaiAuth from "@inai-dev/astro";
19
+
20
+ export default defineConfig({
21
+ integrations: [
22
+ inaiAuth({
23
+ publishableKey: import.meta.env.INAI_PUBLISHABLE_KEY,
24
+ }),
25
+ ],
26
+ });
27
+ ```
28
+
29
+ ### 2. Use in Pages
30
+
31
+ ```astro
32
+ ---
33
+ // src/pages/dashboard.astro
34
+ const auth = Astro.locals.auth;
35
+ if (!auth?.userId) return Astro.redirect("/sign-in");
36
+ ---
37
+ <p>Welcome {auth.user.email}</p>
38
+ ```
39
+
40
+ ### 3. API Endpoints
41
+
42
+ ```ts
43
+ // src/pages/api/auth/[...path].ts
44
+ import { handleAuthRoutes } from "@inai-dev/astro/server";
45
+ export const ALL = handleAuthRoutes();
46
+ ```
47
+
48
+ ## Exports
49
+
50
+ - `@inai-dev/astro` — Astro integration function
51
+ - `@inai-dev/astro/middleware` — Auth middleware
52
+ - `@inai-dev/astro/server` — Server-side helpers and API route handlers
53
+
54
+ ## Documentation
55
+
56
+ - [Astro Integration](https://github.com/inai-dev/sdk/blob/main/docs/astro-integration.md)
57
+ - [API Reference](https://github.com/inai-dev/sdk/blob/main/docs/api-reference.md)
58
+
59
+ ## License
60
+
61
+ [MIT](../../LICENSE)
@@ -0,0 +1,12 @@
1
+ import { AstroIntegration } from 'astro';
2
+ export { InAIAstroMiddlewareConfig, inaiAstroMiddleware } from './middleware.js';
3
+ export { auth, currentUser } from './server.js';
4
+ export { AuthObject, OrganizationResource, UserResource } from '@inai-dev/types';
5
+
6
+ interface InAIAstroConfig {
7
+ apiUrl: string;
8
+ publishableKey?: string;
9
+ }
10
+ declare function inaiAuth(config: InAIAstroConfig): AstroIntegration;
11
+
12
+ export { type InAIAstroConfig, inaiAuth };
package/dist/index.js ADDED
@@ -0,0 +1,127 @@
1
+ // src/integration.ts
2
+ function inaiAuth(config) {
3
+ return {
4
+ name: "@inai-dev/astro",
5
+ hooks: {
6
+ "astro:config:setup": ({ updateConfig }) => {
7
+ updateConfig({
8
+ vite: {
9
+ define: {
10
+ "import.meta.env.INAI_API_URL": JSON.stringify(config.apiUrl),
11
+ "import.meta.env.INAI_PUBLISHABLE_KEY": JSON.stringify(
12
+ config.publishableKey ?? ""
13
+ )
14
+ }
15
+ }
16
+ });
17
+ }
18
+ }
19
+ };
20
+ }
21
+
22
+ // src/middleware.ts
23
+ import {
24
+ COOKIE_AUTH_TOKEN,
25
+ getClaimsFromToken,
26
+ isTokenExpired
27
+ } from "@inai-dev/shared";
28
+ function inaiAstroMiddleware(config = {}) {
29
+ const { publicRoutes = [], signInUrl = "/login" } = config;
30
+ return async (context, next) => {
31
+ const { pathname } = context.url;
32
+ const isPublic = publicRoutes.some((route) => {
33
+ if (route.endsWith("*")) {
34
+ return pathname.startsWith(route.slice(0, -1));
35
+ }
36
+ return pathname === route;
37
+ }) || pathname === signInUrl || pathname.startsWith("/_") || pathname.startsWith("/api/");
38
+ if (isPublic) {
39
+ return next();
40
+ }
41
+ const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;
42
+ if (!token || isTokenExpired(token)) {
43
+ return context.redirect(
44
+ `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`
45
+ );
46
+ }
47
+ const claims = getClaimsFromToken(token);
48
+ if (!claims) {
49
+ return context.redirect(signInUrl);
50
+ }
51
+ const roles = claims.roles ?? [];
52
+ const permissions = claims.permissions ?? [];
53
+ const authObject = {
54
+ userId: claims.sub,
55
+ tenantId: claims.tenant_id,
56
+ appId: claims.app_id ?? null,
57
+ envId: claims.env_id ?? null,
58
+ orgId: claims.org_id ?? null,
59
+ orgRole: claims.org_role ?? null,
60
+ sessionId: null,
61
+ getToken: async () => token,
62
+ has: (params) => {
63
+ if (params.role && roles.includes(params.role)) return true;
64
+ if (params.permission && permissions.includes(params.permission))
65
+ return true;
66
+ return false;
67
+ }
68
+ };
69
+ context.locals.auth = authObject;
70
+ return next();
71
+ };
72
+ }
73
+
74
+ // src/server.ts
75
+ import { InAIAuthClient } from "@inai-dev/backend";
76
+ import {
77
+ COOKIE_AUTH_TOKEN as COOKIE_AUTH_TOKEN2,
78
+ getClaimsFromToken as getClaimsFromToken2,
79
+ isTokenExpired as isTokenExpired2
80
+ } from "@inai-dev/shared";
81
+ function auth(context) {
82
+ const existing = context.locals.auth;
83
+ if (existing) return existing;
84
+ const token = context.cookies.get(COOKIE_AUTH_TOKEN2)?.value;
85
+ if (!token || isTokenExpired2(token)) return null;
86
+ const claims = getClaimsFromToken2(token);
87
+ if (!claims) return null;
88
+ const roles = claims.roles ?? [];
89
+ const permissions = claims.permissions ?? [];
90
+ return {
91
+ userId: claims.sub,
92
+ tenantId: claims.tenant_id,
93
+ appId: claims.app_id ?? null,
94
+ envId: claims.env_id ?? null,
95
+ orgId: claims.org_id ?? null,
96
+ orgRole: claims.org_role ?? null,
97
+ sessionId: null,
98
+ getToken: async () => token,
99
+ has: (params) => {
100
+ if (params.role && roles.includes(params.role)) return true;
101
+ if (params.permission && permissions.includes(params.permission))
102
+ return true;
103
+ return false;
104
+ }
105
+ };
106
+ }
107
+ async function currentUser(context, config) {
108
+ const token = context.cookies.get(COOKIE_AUTH_TOKEN2)?.value;
109
+ if (!token || isTokenExpired2(token)) return null;
110
+ const client = new InAIAuthClient({
111
+ apiUrl: config.apiUrl,
112
+ publishableKey: config.publishableKey
113
+ });
114
+ try {
115
+ const { data } = await client.getMe(token);
116
+ return data;
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+ export {
122
+ auth,
123
+ currentUser,
124
+ inaiAstroMiddleware,
125
+ inaiAuth
126
+ };
127
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/integration.ts","../src/middleware.ts","../src/server.ts"],"sourcesContent":["import type { AstroIntegration } from \"astro\";\n\nexport interface InAIAstroConfig {\n apiUrl: string;\n publishableKey?: string;\n}\n\nexport function inaiAuth(config: InAIAstroConfig): AstroIntegration {\n return {\n name: \"@inai-dev/astro\",\n hooks: {\n \"astro:config:setup\": ({ updateConfig }) => {\n updateConfig({\n vite: {\n define: {\n \"import.meta.env.INAI_API_URL\": JSON.stringify(config.apiUrl),\n \"import.meta.env.INAI_PUBLISHABLE_KEY\": JSON.stringify(\n config.publishableKey ?? \"\",\n ),\n },\n },\n });\n },\n },\n };\n}\n","import type { MiddlewareHandler } from \"astro\";\nimport type { AuthObject } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n getClaimsFromToken,\n isTokenExpired,\n} from \"@inai-dev/shared\";\n\nexport interface InAIAstroMiddlewareConfig {\n publicRoutes?: string[];\n signInUrl?: string;\n}\n\nexport function inaiAstroMiddleware(\n config: InAIAstroMiddlewareConfig = {},\n): MiddlewareHandler {\n const { publicRoutes = [], signInUrl = \"/login\" } = config;\n\n return async (context, next) => {\n const { pathname } = context.url;\n\n const isPublic =\n publicRoutes.some((route) => {\n if (route.endsWith(\"*\")) {\n return pathname.startsWith(route.slice(0, -1));\n }\n return pathname === route;\n }) ||\n pathname === signInUrl ||\n pathname.startsWith(\"/_\") ||\n pathname.startsWith(\"/api/\");\n\n if (isPublic) {\n return next();\n }\n\n const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n\n if (!token || isTokenExpired(token)) {\n return context.redirect(\n `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`,\n );\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return context.redirect(signInUrl);\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n const authObject: AuthObject = {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n\n (context.locals as Record<string, unknown>).auth = authObject;\n\n return next();\n };\n}\n","import type { AuthObject, UserResource } from \"@inai-dev/types\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport {\n COOKIE_AUTH_TOKEN,\n getClaimsFromToken,\n isTokenExpired,\n} from \"@inai-dev/shared\";\n\ninterface AstroContext {\n cookies: {\n get(name: string): { value: string } | undefined;\n };\n locals: Record<string, unknown>;\n}\n\nexport function auth(context: AstroContext): AuthObject | null {\n const existing = (context.locals as Record<string, unknown>).auth as AuthObject | undefined;\n if (existing) return existing;\n\n const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n if (!token || isTokenExpired(token)) return null;\n\n const claims = getClaimsFromToken(token);\n if (!claims) return null;\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n}\n\nexport async function currentUser(\n context: AstroContext,\n config: { apiUrl: string; publishableKey?: string },\n): Promise<UserResource | null> {\n const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n if (!token || isTokenExpired(token)) return null;\n\n const client = new InAIAuthClient({\n apiUrl: config.apiUrl,\n publishableKey: config.publishableKey,\n });\n\n try {\n const { data } = await client.getMe(token);\n return data;\n } catch {\n return null;\n }\n}\n"],"mappings":"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","names":["COOKIE_AUTH_TOKEN","getClaimsFromToken","isTokenExpired"]}
@@ -0,0 +1,9 @@
1
+ import { MiddlewareHandler } from 'astro';
2
+
3
+ interface InAIAstroMiddlewareConfig {
4
+ publicRoutes?: string[];
5
+ signInUrl?: string;
6
+ }
7
+ declare function inaiAstroMiddleware(config?: InAIAstroMiddlewareConfig): MiddlewareHandler;
8
+
9
+ export { type InAIAstroMiddlewareConfig, inaiAstroMiddleware };
@@ -0,0 +1,55 @@
1
+ // src/middleware.ts
2
+ import {
3
+ COOKIE_AUTH_TOKEN,
4
+ getClaimsFromToken,
5
+ isTokenExpired
6
+ } from "@inai-dev/shared";
7
+ function inaiAstroMiddleware(config = {}) {
8
+ const { publicRoutes = [], signInUrl = "/login" } = config;
9
+ return async (context, next) => {
10
+ const { pathname } = context.url;
11
+ const isPublic = publicRoutes.some((route) => {
12
+ if (route.endsWith("*")) {
13
+ return pathname.startsWith(route.slice(0, -1));
14
+ }
15
+ return pathname === route;
16
+ }) || pathname === signInUrl || pathname.startsWith("/_") || pathname.startsWith("/api/");
17
+ if (isPublic) {
18
+ return next();
19
+ }
20
+ const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;
21
+ if (!token || isTokenExpired(token)) {
22
+ return context.redirect(
23
+ `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`
24
+ );
25
+ }
26
+ const claims = getClaimsFromToken(token);
27
+ if (!claims) {
28
+ return context.redirect(signInUrl);
29
+ }
30
+ const roles = claims.roles ?? [];
31
+ const permissions = claims.permissions ?? [];
32
+ const authObject = {
33
+ userId: claims.sub,
34
+ tenantId: claims.tenant_id,
35
+ appId: claims.app_id ?? null,
36
+ envId: claims.env_id ?? null,
37
+ orgId: claims.org_id ?? null,
38
+ orgRole: claims.org_role ?? null,
39
+ sessionId: null,
40
+ getToken: async () => token,
41
+ has: (params) => {
42
+ if (params.role && roles.includes(params.role)) return true;
43
+ if (params.permission && permissions.includes(params.permission))
44
+ return true;
45
+ return false;
46
+ }
47
+ };
48
+ context.locals.auth = authObject;
49
+ return next();
50
+ };
51
+ }
52
+ export {
53
+ inaiAstroMiddleware
54
+ };
55
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import type { MiddlewareHandler } from \"astro\";\nimport type { AuthObject } from \"@inai-dev/types\";\nimport {\n COOKIE_AUTH_TOKEN,\n getClaimsFromToken,\n isTokenExpired,\n} from \"@inai-dev/shared\";\n\nexport interface InAIAstroMiddlewareConfig {\n publicRoutes?: string[];\n signInUrl?: string;\n}\n\nexport function inaiAstroMiddleware(\n config: InAIAstroMiddlewareConfig = {},\n): MiddlewareHandler {\n const { publicRoutes = [], signInUrl = \"/login\" } = config;\n\n return async (context, next) => {\n const { pathname } = context.url;\n\n const isPublic =\n publicRoutes.some((route) => {\n if (route.endsWith(\"*\")) {\n return pathname.startsWith(route.slice(0, -1));\n }\n return pathname === route;\n }) ||\n pathname === signInUrl ||\n pathname.startsWith(\"/_\") ||\n pathname.startsWith(\"/api/\");\n\n if (isPublic) {\n return next();\n }\n\n const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n\n if (!token || isTokenExpired(token)) {\n return context.redirect(\n `${signInUrl}?returnTo=${encodeURIComponent(pathname)}`,\n );\n }\n\n const claims = getClaimsFromToken(token);\n if (!claims) {\n return context.redirect(signInUrl);\n }\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n const authObject: AuthObject = {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n\n (context.locals as Record<string, unknown>).auth = authObject;\n\n return next();\n };\n}\n"],"mappings":";AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAOA,SAAS,oBACd,SAAoC,CAAC,GAClB;AACnB,QAAM,EAAE,eAAe,CAAC,GAAG,YAAY,SAAS,IAAI;AAEpD,SAAO,OAAO,SAAS,SAAS;AAC9B,UAAM,EAAE,SAAS,IAAI,QAAQ;AAE7B,UAAM,WACJ,aAAa,KAAK,CAAC,UAAU;AAC3B,UAAI,MAAM,SAAS,GAAG,GAAG;AACvB,eAAO,SAAS,WAAW,MAAM,MAAM,GAAG,EAAE,CAAC;AAAA,MAC/C;AACA,aAAO,aAAa;AAAA,IACtB,CAAC,KACD,aAAa,aACb,SAAS,WAAW,IAAI,KACxB,SAAS,WAAW,OAAO;AAE7B,QAAI,UAAU;AACZ,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,QAAQ,QAAQ,QAAQ,IAAI,iBAAiB,GAAG;AAEtD,QAAI,CAAC,SAAS,eAAe,KAAK,GAAG;AACnC,aAAO,QAAQ;AAAA,QACb,GAAG,SAAS,aAAa,mBAAmB,QAAQ,CAAC;AAAA,MACvD;AAAA,IACF;AAEA,UAAM,SAAS,mBAAmB,KAAK;AACvC,QAAI,CAAC,QAAQ;AACX,aAAO,QAAQ,SAAS,SAAS;AAAA,IACnC;AAEA,UAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,UAAM,cAAc,OAAO,eAAe,CAAC;AAE3C,UAAM,aAAyB;AAAA,MAC7B,QAAQ,OAAO;AAAA,MACf,UAAU,OAAO;AAAA,MACjB,OAAO,OAAO,UAAU;AAAA,MACxB,OAAO,OAAO,UAAU;AAAA,MACxB,OAAO,OAAO,UAAU;AAAA,MACxB,SAAS,OAAO,YAAY;AAAA,MAC5B,WAAW;AAAA,MACX,UAAU,YAAY;AAAA,MACtB,KAAK,CAAC,WAAmD;AACvD,YAAI,OAAO,QAAQ,MAAM,SAAS,OAAO,IAAI,EAAG,QAAO;AACvD,YAAI,OAAO,cAAc,YAAY,SAAS,OAAO,UAAU;AAC7D,iBAAO;AACT,eAAO;AAAA,MACT;AAAA,IACF;AAEA,IAAC,QAAQ,OAAmC,OAAO;AAEnD,WAAO,KAAK;AAAA,EACd;AACF;","names":[]}
@@ -0,0 +1,17 @@
1
+ import { AuthObject, UserResource } from '@inai-dev/types';
2
+
3
+ interface AstroContext {
4
+ cookies: {
5
+ get(name: string): {
6
+ value: string;
7
+ } | undefined;
8
+ };
9
+ locals: Record<string, unknown>;
10
+ }
11
+ declare function auth(context: AstroContext): AuthObject | null;
12
+ declare function currentUser(context: AstroContext, config: {
13
+ apiUrl: string;
14
+ publishableKey?: string;
15
+ }): Promise<UserResource | null>;
16
+
17
+ export { auth, currentUser };
package/dist/server.js ADDED
@@ -0,0 +1,52 @@
1
+ // src/server.ts
2
+ import { InAIAuthClient } from "@inai-dev/backend";
3
+ import {
4
+ COOKIE_AUTH_TOKEN,
5
+ getClaimsFromToken,
6
+ isTokenExpired
7
+ } from "@inai-dev/shared";
8
+ function auth(context) {
9
+ const existing = context.locals.auth;
10
+ if (existing) return existing;
11
+ const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;
12
+ if (!token || isTokenExpired(token)) return null;
13
+ const claims = getClaimsFromToken(token);
14
+ if (!claims) return null;
15
+ const roles = claims.roles ?? [];
16
+ const permissions = claims.permissions ?? [];
17
+ return {
18
+ userId: claims.sub,
19
+ tenantId: claims.tenant_id,
20
+ appId: claims.app_id ?? null,
21
+ envId: claims.env_id ?? null,
22
+ orgId: claims.org_id ?? null,
23
+ orgRole: claims.org_role ?? null,
24
+ sessionId: null,
25
+ getToken: async () => token,
26
+ has: (params) => {
27
+ if (params.role && roles.includes(params.role)) return true;
28
+ if (params.permission && permissions.includes(params.permission))
29
+ return true;
30
+ return false;
31
+ }
32
+ };
33
+ }
34
+ async function currentUser(context, config) {
35
+ const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;
36
+ if (!token || isTokenExpired(token)) return null;
37
+ const client = new InAIAuthClient({
38
+ apiUrl: config.apiUrl,
39
+ publishableKey: config.publishableKey
40
+ });
41
+ try {
42
+ const { data } = await client.getMe(token);
43
+ return data;
44
+ } catch {
45
+ return null;
46
+ }
47
+ }
48
+ export {
49
+ auth,
50
+ currentUser
51
+ };
52
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts"],"sourcesContent":["import type { AuthObject, UserResource } from \"@inai-dev/types\";\nimport { InAIAuthClient } from \"@inai-dev/backend\";\nimport {\n COOKIE_AUTH_TOKEN,\n getClaimsFromToken,\n isTokenExpired,\n} from \"@inai-dev/shared\";\n\ninterface AstroContext {\n cookies: {\n get(name: string): { value: string } | undefined;\n };\n locals: Record<string, unknown>;\n}\n\nexport function auth(context: AstroContext): AuthObject | null {\n const existing = (context.locals as Record<string, unknown>).auth as AuthObject | undefined;\n if (existing) return existing;\n\n const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n if (!token || isTokenExpired(token)) return null;\n\n const claims = getClaimsFromToken(token);\n if (!claims) return null;\n\n const roles = claims.roles ?? [];\n const permissions = claims.permissions ?? [];\n\n return {\n userId: claims.sub,\n tenantId: claims.tenant_id,\n appId: claims.app_id ?? null,\n envId: claims.env_id ?? null,\n orgId: claims.org_id ?? null,\n orgRole: claims.org_role ?? null,\n sessionId: null,\n getToken: async () => token,\n has: (params: { role?: string; permission?: string }) => {\n if (params.role && roles.includes(params.role)) return true;\n if (params.permission && permissions.includes(params.permission))\n return true;\n return false;\n },\n };\n}\n\nexport async function currentUser(\n context: AstroContext,\n config: { apiUrl: string; publishableKey?: string },\n): Promise<UserResource | null> {\n const token = context.cookies.get(COOKIE_AUTH_TOKEN)?.value;\n if (!token || isTokenExpired(token)) return null;\n\n const client = new InAIAuthClient({\n apiUrl: config.apiUrl,\n publishableKey: config.publishableKey,\n });\n\n try {\n const { data } = await client.getMe(token);\n return data;\n } catch {\n return null;\n }\n}\n"],"mappings":";AACA,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASA,SAAS,KAAK,SAA0C;AAC7D,QAAM,WAAY,QAAQ,OAAmC;AAC7D,MAAI,SAAU,QAAO;AAErB,QAAM,QAAQ,QAAQ,QAAQ,IAAI,iBAAiB,GAAG;AACtD,MAAI,CAAC,SAAS,eAAe,KAAK,EAAG,QAAO;AAE5C,QAAM,SAAS,mBAAmB,KAAK;AACvC,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,QAAM,cAAc,OAAO,eAAe,CAAC;AAE3C,SAAO;AAAA,IACL,QAAQ,OAAO;AAAA,IACf,UAAU,OAAO;AAAA,IACjB,OAAO,OAAO,UAAU;AAAA,IACxB,OAAO,OAAO,UAAU;AAAA,IACxB,OAAO,OAAO,UAAU;AAAA,IACxB,SAAS,OAAO,YAAY;AAAA,IAC5B,WAAW;AAAA,IACX,UAAU,YAAY;AAAA,IACtB,KAAK,CAAC,WAAmD;AACvD,UAAI,OAAO,QAAQ,MAAM,SAAS,OAAO,IAAI,EAAG,QAAO;AACvD,UAAI,OAAO,cAAc,YAAY,SAAS,OAAO,UAAU;AAC7D,eAAO;AACT,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,eAAsB,YACpB,SACA,QAC8B;AAC9B,QAAM,QAAQ,QAAQ,QAAQ,IAAI,iBAAiB,GAAG;AACtD,MAAI,CAAC,SAAS,eAAe,KAAK,EAAG,QAAO;AAE5C,QAAM,SAAS,IAAI,eAAe;AAAA,IAChC,QAAQ,OAAO;AAAA,IACf,gBAAgB,OAAO;AAAA,EACzB,CAAC;AAED,MAAI;AACF,UAAM,EAAE,KAAK,IAAI,MAAM,OAAO,MAAM,KAAK;AACzC,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@inai-dev/astro",
3
+ "version": "0.1.0",
4
+ "description": "Astro integration for InAI Auth SDK",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./middleware": {
14
+ "types": "./dist/middleware.d.ts",
15
+ "import": "./dist/middleware.js"
16
+ },
17
+ "./server": {
18
+ "types": "./dist/server.d.ts",
19
+ "import": "./dist/server.js"
20
+ }
21
+ },
22
+ "files": ["dist", "src/components"],
23
+ "scripts": {
24
+ "build": "tsup",
25
+ "dev": "tsup --watch",
26
+ "clean": "rm -rf dist",
27
+ "typecheck": "tsc --noEmit",
28
+ "prepublishOnly": "npm run build"
29
+ },
30
+ "dependencies": {
31
+ "@inai-dev/types": "^0.1.0",
32
+ "@inai-dev/shared": "^0.1.0",
33
+ "@inai-dev/backend": "^0.1.0"
34
+ },
35
+ "peerDependencies": {
36
+ "astro": ">=4.0.0"
37
+ },
38
+ "peerDependenciesMeta": {
39
+ "astro": {
40
+ "optional": false
41
+ }
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "author": "InAI <contact@inai.dev>",
47
+ "license": "MIT",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/InAI-Team/inai-auth-sdk.git",
51
+ "directory": "packages/astro"
52
+ },
53
+ "homepage": "https://inai.dev/",
54
+ "bugs": "https://github.com/InAI-Team/inai-auth-sdk/issues",
55
+ "keywords": ["inai", "auth", "astro", "middleware", "multi-tenant", "ssg"]
56
+ }
@@ -0,0 +1,6 @@
1
+ ---
2
+ const auth = Astro.locals.auth;
3
+ const isSignedIn = !!auth?.userId;
4
+ ---
5
+
6
+ {isSignedIn && <slot />}
@@ -0,0 +1,6 @@
1
+ ---
2
+ const auth = Astro.locals.auth;
3
+ const isSignedIn = !!auth?.userId;
4
+ ---
5
+
6
+ {!isSignedIn && <slot />}