@batijs/cli 0.0.243 → 0.0.245

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 (84) hide show
  1. package/dist/boilerplates/@batijs/authjs/files/$package.json.js +92 -0
  2. package/dist/boilerplates/@batijs/authjs/files/server/authjs-handler.ts +14 -13
  3. package/dist/boilerplates/@batijs/authjs/types/server/authjs-handler.d.ts +4 -2
  4. package/dist/boilerplates/@batijs/cloudflare/files/$package.json.js +2 -2
  5. package/dist/boilerplates/@batijs/compiled/files/$package.json.js +1 -1
  6. package/dist/boilerplates/@batijs/drizzle/files/$package.json.js +8 -8
  7. package/dist/boilerplates/@batijs/drizzle/files/database/{db.ts → drizzleDb.ts} +1 -2
  8. package/dist/boilerplates/@batijs/drizzle/files/database/seed.ts +4 -3
  9. package/dist/boilerplates/@batijs/drizzle/files/drizzle.config.ts +1 -1
  10. package/dist/boilerplates/@batijs/drizzle/types/database/drizzleDb.d.ts +1 -0
  11. package/dist/boilerplates/@batijs/eslint/files/$package.json.js +2 -2
  12. package/dist/boilerplates/@batijs/express/files/$package.json.js +4 -4
  13. package/dist/boilerplates/@batijs/express/files/express-entry.ts +31 -9
  14. package/dist/boilerplates/@batijs/fastify/files/$package.json.js +6 -6
  15. package/dist/boilerplates/@batijs/fastify/files/fastify-entry.ts +33 -45
  16. package/dist/boilerplates/@batijs/fastify/types/fastify-entry.d.ts +0 -4
  17. package/dist/boilerplates/@batijs/firebase-auth/files/$package.json.js +5 -4
  18. package/dist/boilerplates/@batijs/firebase-auth/files/server/firebase-auth-middleware.ts +16 -18
  19. package/dist/boilerplates/@batijs/firebase-auth/types/server/firebase-auth-middleware.d.ts +8 -3
  20. package/dist/boilerplates/@batijs/h3/files/$package.json.js +5 -2
  21. package/dist/boilerplates/@batijs/h3/files/h3-entry.ts +33 -24
  22. package/dist/boilerplates/@batijs/h3/types/h3-entry.d.ts +0 -4
  23. package/dist/boilerplates/@batijs/hattip/files/$package.json.js +5 -3
  24. package/dist/boilerplates/@batijs/hattip/files/hattip-entry.ts +33 -24
  25. package/dist/boilerplates/@batijs/hono/files/$package.json.js +7 -15
  26. package/dist/boilerplates/@batijs/hono/files/hono-entry.ts +31 -9
  27. package/dist/boilerplates/@batijs/lucia-auth/files/$.env.js +23 -0
  28. package/dist/boilerplates/@batijs/lucia-auth/files/$README.md.js +29 -0
  29. package/dist/boilerplates/@batijs/lucia-auth/files/$package.json.js +135 -0
  30. package/dist/boilerplates/@batijs/lucia-auth/files/database/auth-actions.ts +54 -0
  31. package/dist/boilerplates/@batijs/lucia-auth/files/database/schema/auth.ts +41 -0
  32. package/dist/boilerplates/@batijs/lucia-auth/files/database/sqliteDb.ts +30 -0
  33. package/dist/boilerplates/@batijs/lucia-auth/files/lib/lucia-auth.ts +96 -0
  34. package/dist/boilerplates/@batijs/lucia-auth/files/pages/login/+guard.ts +11 -0
  35. package/dist/boilerplates/@batijs/lucia-auth/files/pages/login/style.css +94 -0
  36. package/dist/boilerplates/@batijs/lucia-auth/files/server/lucia-auth-handlers.ts +340 -0
  37. package/dist/boilerplates/@batijs/lucia-auth/files/vike.d.ts +11 -0
  38. package/dist/boilerplates/@batijs/lucia-auth/types/database/auth-actions.d.ts +9 -0
  39. package/dist/boilerplates/@batijs/lucia-auth/types/database/schema/auth.d.ts +167 -0
  40. package/dist/boilerplates/@batijs/lucia-auth/types/database/sqliteDb.d.ts +2 -0
  41. package/dist/boilerplates/@batijs/lucia-auth/types/lib/lucia-auth.d.ts +43 -0
  42. package/dist/boilerplates/@batijs/lucia-auth/types/pages/login/+guard.d.ts +3 -0
  43. package/dist/boilerplates/@batijs/lucia-auth/types/server/lucia-auth-handlers.d.ts +58 -0
  44. package/dist/boilerplates/@batijs/react/files/$package.json.js +4 -4
  45. package/dist/boilerplates/@batijs/react/files/layouts/LayoutDefault.tsx +1 -0
  46. package/dist/boilerplates/@batijs/react/files/pages/+config.ts +1 -1
  47. package/dist/boilerplates/@batijs/react-lucia-auth/files/pages/login/+Page.tsx +96 -0
  48. package/dist/boilerplates/@batijs/react-lucia-auth/types/pages/login/+Page.d.ts +2 -0
  49. package/dist/boilerplates/@batijs/shared/files/package.json +2 -2
  50. package/dist/boilerplates/@batijs/shared-server/files/$package.json.js +103 -0
  51. package/dist/boilerplates/@batijs/shared-server/files/server/create-todo-handler.ts +6 -8
  52. package/dist/boilerplates/@batijs/shared-server/files/server/vike-handler.ts +3 -5
  53. package/dist/boilerplates/@batijs/shared-server/types/server/create-todo-handler.d.ts +2 -1
  54. package/dist/boilerplates/@batijs/shared-server/types/server/vike-handler.d.ts +2 -1
  55. package/dist/boilerplates/@batijs/shared-todo/files/pages/todo/+data.ts +3 -3
  56. package/dist/boilerplates/@batijs/solid/files/$package.json.js +5 -5
  57. package/dist/boilerplates/@batijs/solid/files/layouts/LayoutDefault.tsx +1 -0
  58. package/dist/boilerplates/@batijs/solid/files/pages/+config.ts +1 -1
  59. package/dist/boilerplates/@batijs/solid-lucia-auth/files/pages/login/+Page.tsx +96 -0
  60. package/dist/boilerplates/@batijs/solid-lucia-auth/types/pages/login/+Page.d.ts +2 -0
  61. package/dist/boilerplates/@batijs/tailwindcss/files/$package.json.js +3 -3
  62. package/dist/boilerplates/@batijs/telefunc/files/$package.json.js +4 -3
  63. package/dist/boilerplates/@batijs/telefunc/files/pages/todo/TodoList.telefunc.ts +3 -3
  64. package/dist/boilerplates/@batijs/telefunc/files/server/telefunc-handler.ts +3 -5
  65. package/dist/boilerplates/@batijs/telefunc/types/server/telefunc-handler.d.ts +2 -1
  66. package/dist/boilerplates/@batijs/trpc/files/$package.json.js +1 -1
  67. package/dist/boilerplates/@batijs/trpc/files/trpc/server.ts +3 -3
  68. package/dist/boilerplates/@batijs/ts-rest/files/$package.json.js +4 -3
  69. package/dist/boilerplates/@batijs/ts-rest/files/server/ts-rest-handler.ts +6 -9
  70. package/dist/boilerplates/@batijs/ts-rest/types/server/ts-rest-handler.d.ts +2 -1
  71. package/dist/boilerplates/@batijs/vercel/files/$package.json.js +4 -4
  72. package/dist/boilerplates/@batijs/vue/files/$package.json.js +7 -7
  73. package/dist/boilerplates/@batijs/vue/files/layouts/LayoutDefault.vue +2 -0
  74. package/dist/boilerplates/@batijs/vue/files/pages/+config.ts +1 -1
  75. package/dist/boilerplates/@batijs/vue/types/pages/+config.d.ts +6 -0
  76. package/dist/boilerplates/@batijs/vue-lucia-auth/files/pages/login/+Page.vue +87 -0
  77. package/dist/boilerplates/boilerplates.json +59 -0
  78. package/dist/{chunk-MFJ4ET44.js → chunk-FWD3UPBV.js} +5 -5
  79. package/dist/index.js +14 -14
  80. package/dist/{prompt-SUR66HP4.js → prompt-EYFUFJSI.js} +4 -4
  81. package/package.json +8 -8
  82. package/dist/boilerplates/@batijs/drizzle/types/database/db.d.ts +0 -2
  83. /package/dist/boilerplates/@batijs/drizzle/files/database/{schema.ts → schema/todos.ts} +0 -0
  84. /package/dist/boilerplates/@batijs/drizzle/types/database/{schema.d.ts → schema/todos.d.ts} +0 -0
@@ -0,0 +1,340 @@
1
+ import type { Session, User } from "lucia";
2
+ import { generateId, Scrypt, verifyRequestOrigin } from "lucia";
3
+ import type { DatabaseOAuthAccount, DatabaseUser, GitHubUser } from "../lib/lucia-auth";
4
+ import { github, lucia } from "../lib/lucia-auth";
5
+ import { SqliteError } from "better-sqlite3";
6
+ import { sqliteDb } from "../database/sqliteDb";
7
+ import { generateState, OAuth2RequestError } from "arctic";
8
+ import { parse, serialize } from "cookie";
9
+ import { drizzleDb } from "@batijs/drizzle/database/drizzleDb";
10
+ import { oauthAccountTable, userTable } from "../database/schema/auth";
11
+ import { getExistingAccount, getExistingUser, validateInput } from "../database/auth-actions";
12
+ import type { Get, UniversalHandler, UniversalMiddleware } from "@universal-middleware/core";
13
+
14
+ /**
15
+ * CSRF protection middleware
16
+ *
17
+ * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
18
+ */
19
+ export const luciaCsrfMiddleware = (() => async (request) => {
20
+ if (request.method === "GET") {
21
+ return;
22
+ }
23
+ if (!BATI_TEST) {
24
+ const originHeader = request.headers.get("Origin") ?? null;
25
+ const hostHeader = request.headers.get("Host") ?? null;
26
+
27
+ if (!originHeader || !hostHeader || !verifyRequestOrigin(originHeader, [hostHeader])) {
28
+ return new Response("Forbidden Request", {
29
+ status: 403,
30
+ });
31
+ }
32
+ }
33
+ }) satisfies Get<[], UniversalMiddleware>;
34
+
35
+ /**
36
+ * Validate session cookies middleware and set context
37
+ *
38
+ * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
39
+ */
40
+ export const luciaAuthContextMiddleware = (() => async (request, context) => {
41
+ const sessionId = lucia.readSessionCookie(request.headers.get("cookie") ?? "");
42
+
43
+ if (!sessionId) {
44
+ return {
45
+ ...context,
46
+ session: null,
47
+ user: null,
48
+ };
49
+ } else {
50
+ const { session, user } = await lucia.validateSession(sessionId);
51
+
52
+ return {
53
+ ...context,
54
+ sessionId,
55
+ session,
56
+ user,
57
+ };
58
+ }
59
+ }) satisfies Get<[], UniversalMiddleware>;
60
+
61
+ /**
62
+ * Set Set-Cookie headers if in context
63
+ */
64
+ export const luciaAuthCookieMiddleware = (() => (_request, context) => {
65
+ return (response: Response) => {
66
+ if (context.session?.fresh) {
67
+ response.headers.append("Set-Cookie", lucia.createSessionCookie(context.session.id).serialize());
68
+ }
69
+ if (context.sessionId && !context.session) {
70
+ response.headers.append("Set-Cookie", lucia.createBlankSessionCookie().serialize());
71
+ }
72
+
73
+ return response;
74
+ };
75
+ }) satisfies Get<[], UniversalMiddleware<{ session?: Session | null; user?: User | null; sessionId?: string | null }>>;
76
+
77
+ /**
78
+ * Register user handler
79
+ *
80
+ * @link {@see https://lucia-auth.com/guides/email-and-password/basics#register-user}
81
+ */
82
+ export const luciaAuthSignupHandler = (() => async (request) => {
83
+ const body = (await request.json()) as { username: string; password: string };
84
+ const username = body.username ?? "";
85
+ const password = body.password ?? "";
86
+
87
+ const validated = validateInput(username, password);
88
+
89
+ if (!validated.success) {
90
+ return new Response(JSON.stringify({ error: validated.error }), {
91
+ status: 422,
92
+ headers: {
93
+ "content-type": "application/json",
94
+ },
95
+ });
96
+ }
97
+
98
+ /**
99
+ * A pure JS implementation of Scrypt.
100
+ * It's portable but slower than implementations based on native code.
101
+ *
102
+ * @link {@see https://lucia-auth.com/reference/main/Scrypt}
103
+ * @link {@see https://lucia-auth.com/guides/email-and-password/basics#hashing-passwords}
104
+ */
105
+ const scrypt = new Scrypt();
106
+ const passwordHash = await scrypt.hash(password);
107
+
108
+ const userId = generateId(15);
109
+
110
+ try {
111
+ if (BATI.has("drizzle")) {
112
+ drizzleDb.insert(userTable).values({ id: userId, username, password: passwordHash }).run();
113
+ } else {
114
+ sqliteDb
115
+ .prepare("INSERT INTO users (id, username, password) VALUES(?, ?, ?)")
116
+ .run(userId, username, passwordHash);
117
+ }
118
+
119
+ const session = await lucia.createSession(userId, {});
120
+
121
+ return new Response(JSON.stringify({ status: "success" }), {
122
+ status: 200,
123
+ headers: {
124
+ "content-type": "application/json",
125
+ "set-cookie": lucia.createSessionCookie(session.id).serialize(),
126
+ },
127
+ });
128
+ } catch (error) {
129
+ if (error instanceof SqliteError && error.code === "SQLITE_CONSTRAINT_UNIQUE") {
130
+ return new Response(JSON.stringify({ error: { username: "Username already in use" } }), {
131
+ status: 422,
132
+ headers: {
133
+ "content-type": "application/json",
134
+ },
135
+ });
136
+ }
137
+
138
+ return new Response(JSON.stringify({ error: { invalid: "An unknown error has occurred" } }), {
139
+ status: 500,
140
+ headers: {
141
+ "content-type": "application/json",
142
+ },
143
+ });
144
+ }
145
+ }) satisfies Get<[], UniversalMiddleware>;
146
+
147
+ /**
148
+ * Sign in user handler
149
+ *
150
+ * @link {@see https://lucia-auth.com/guides/email-and-password/basics#sign-in-user}
151
+ */
152
+ export const luciaAuthLoginHandler = (() => async (request) => {
153
+ const body = (await request.json()) as { username: string; password: string };
154
+ const username = body.username ?? "";
155
+ const password = body.password ?? "";
156
+
157
+ const validated = validateInput(username, password);
158
+
159
+ if (!validated.success) {
160
+ return new Response(JSON.stringify({ error: validated.error }), {
161
+ status: 422,
162
+ headers: {
163
+ "content-type": "application/json",
164
+ },
165
+ });
166
+ }
167
+
168
+ const existingUser = getExistingUser(username) as DatabaseUser | undefined;
169
+ if (!existingUser) {
170
+ return new Response(JSON.stringify({ error: { invalid: "Incorrect username or password" } }), {
171
+ status: 422,
172
+ headers: {
173
+ "content-type": "application/json",
174
+ },
175
+ });
176
+ }
177
+
178
+ const scrypt = new Scrypt();
179
+ const validPassword = existingUser.password && (await scrypt.verify(existingUser.password, password));
180
+
181
+ if (!validPassword) {
182
+ return new Response(JSON.stringify({ error: { invalid: "Incorrect username or password" } }), {
183
+ status: 422,
184
+ headers: {
185
+ "content-type": "application/json",
186
+ },
187
+ });
188
+ }
189
+
190
+ const session = await lucia.createSession(existingUser.id, {});
191
+
192
+ return new Response(JSON.stringify({ status: "success" }), {
193
+ status: 200,
194
+ headers: {
195
+ "content-type": "application/json",
196
+ "set-cookie": lucia.createSessionCookie(session.id).serialize(),
197
+ },
198
+ });
199
+ }) satisfies Get<[], UniversalMiddleware>;
200
+
201
+ /**
202
+ * Log out user handler
203
+ */
204
+ export const luciaAuthLogoutHandler = (() => async (_request, context) => {
205
+ const session = context.session ?? null;
206
+
207
+ if (!session) {
208
+ return new Response("Unauthorized Request", {
209
+ status: 401,
210
+ });
211
+ }
212
+ /**
213
+ * Invalidate sessions
214
+ *
215
+ * @link {@see https://lucia-auth.com/basics/sessions#invalidate-sessions}
216
+ */
217
+ await lucia.invalidateSession(session.id);
218
+
219
+ /**
220
+ * Delete session cookie
221
+ *
222
+ * @link {@see https://lucia-auth.com/basics/sessions#delete-session-cookie}
223
+ */
224
+ return new Response(JSON.stringify({ status: "success" }), {
225
+ status: 200,
226
+ headers: {
227
+ "set-cookie": lucia.createBlankSessionCookie().serialize(),
228
+ },
229
+ });
230
+ }) satisfies Get<[], UniversalMiddleware<{ session?: Session | null }>>;
231
+
232
+ /**
233
+ * Github OAuth authorization handler
234
+ *
235
+ * @link {@see https://lucia-auth.com/guides/oauth/basics#creating-authorization-url}
236
+ */
237
+ export const luciaGithubLoginHandler = (() => async () => {
238
+ const state = generateState();
239
+ const url = await github.createAuthorizationURL(state);
240
+
241
+ return new Response(null, {
242
+ status: 302,
243
+ headers: {
244
+ Location: url.toString(),
245
+ "set-cookie": serialize("github_oauth_state", state, {
246
+ path: "/",
247
+ secure: process.env.NODE_ENV === "production",
248
+ httpOnly: true,
249
+ maxAge: 60 * 10,
250
+ sameSite: "lax",
251
+ }),
252
+ },
253
+ });
254
+ }) satisfies Get<[], UniversalHandler>;
255
+
256
+ /**
257
+ * Github OAuth validate callback handler
258
+ *
259
+ * @link {@see https://lucia-auth.com/guides/oauth/basics#validate-callback}
260
+ */
261
+ export const luciaGithubCallbackHandler = (() => async (request) => {
262
+ const cookies = parse(request.headers.get("cookie") ?? "");
263
+ const params = new URL(request.url).searchParams;
264
+ const code = params.get("code");
265
+ const state = params.get("state");
266
+ const storedState = cookies.github_oauth_state ?? null;
267
+
268
+ if (!code || !state || !storedState || state !== storedState) {
269
+ return new Response("Unauthorized Request", {
270
+ status: 401,
271
+ });
272
+ }
273
+
274
+ try {
275
+ const tokens = await github.validateAuthorizationCode(code);
276
+ const githubUserResponse = await fetch("https://api.github.com/user", {
277
+ headers: {
278
+ Authorization: `Bearer ${tokens.accessToken}`,
279
+ },
280
+ });
281
+ const githubUser = (await githubUserResponse.json()) as GitHubUser;
282
+
283
+ const existingAccount = getExistingAccount("github", githubUser.id) as DatabaseOAuthAccount | undefined;
284
+
285
+ if (existingAccount) {
286
+ const session = await lucia.createSession(
287
+ BATI.has("drizzle") ? existingAccount.userId : existingAccount.user_id,
288
+ {},
289
+ );
290
+ return new Response(null, {
291
+ status: 302,
292
+ headers: {
293
+ Location: "/",
294
+ "set-cookie": lucia.createSessionCookie(session.id).serialize(),
295
+ },
296
+ });
297
+ }
298
+
299
+ const userId = generateId(15);
300
+
301
+ if (BATI.has("drizzle")) {
302
+ await drizzleDb.transaction(async (tx) => {
303
+ await tx.insert(userTable).values({ id: userId, username: githubUser.login });
304
+ await tx.insert(oauthAccountTable).values({ providerId: "github", providerUserId: githubUser.id, userId });
305
+ });
306
+ } else {
307
+ sqliteDb.transaction(() => {
308
+ sqliteDb.prepare("INSERT INTO users (id, username) VALUES (?, ?)").run(userId, githubUser.login);
309
+ sqliteDb
310
+ .prepare("INSERT INTO oauth_accounts (provider_id, provider_user_id, user_id) VALUES (?, ?, ?)")
311
+ .run("github", githubUser.id, userId);
312
+ });
313
+ }
314
+
315
+ const session = await lucia.createSession(userId, {});
316
+
317
+ return new Response(null, {
318
+ status: 302,
319
+ headers: {
320
+ Location: "/",
321
+ "set-cookie": lucia.createSessionCookie(session.id).serialize(),
322
+ },
323
+ });
324
+ } catch (error) {
325
+ if (error instanceof OAuth2RequestError && error.message === "bad_verification_code") {
326
+ return new Response(JSON.stringify({ error: error.message }), {
327
+ status: 400,
328
+ headers: {
329
+ "content-type": "application/json",
330
+ },
331
+ });
332
+ }
333
+ return new Response(JSON.stringify({ error: error }), {
334
+ status: 500,
335
+ headers: {
336
+ "content-type": "application/json",
337
+ },
338
+ });
339
+ }
340
+ }) satisfies Get<[], UniversalHandler>;
@@ -0,0 +1,11 @@
1
+ import type { User } from "lucia";
2
+
3
+ declare global {
4
+ namespace Vike {
5
+ interface PageContext {
6
+ user?: User;
7
+ }
8
+ }
9
+ }
10
+
11
+ export {};
@@ -0,0 +1,9 @@
1
+ export declare function getExistingUser(username: string): unknown;
2
+ export declare function getExistingAccount(providerId: string, providerUserId: number): unknown;
3
+ export declare function validateInput(username: string | null, password: string | null): {
4
+ error: {
5
+ username: string | null;
6
+ password: string | null;
7
+ };
8
+ success: boolean;
9
+ };
@@ -0,0 +1,167 @@
1
+ export declare const userTable: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
2
+ name: "users";
3
+ schema: undefined;
4
+ columns: {
5
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
6
+ name: "id";
7
+ tableName: "users";
8
+ dataType: "string";
9
+ columnType: "SQLiteText";
10
+ data: string;
11
+ driverParam: string;
12
+ notNull: true;
13
+ hasDefault: false;
14
+ isPrimaryKey: true;
15
+ isAutoincrement: false;
16
+ hasRuntimeDefault: false;
17
+ enumValues: [string, ...string[]];
18
+ baseColumn: never;
19
+ generated: undefined;
20
+ }, object>;
21
+ username: import("drizzle-orm/sqlite-core").SQLiteColumn<{
22
+ name: "username";
23
+ tableName: "users";
24
+ dataType: "string";
25
+ columnType: "SQLiteText";
26
+ data: string;
27
+ driverParam: string;
28
+ notNull: true;
29
+ hasDefault: false;
30
+ isPrimaryKey: false;
31
+ isAutoincrement: false;
32
+ hasRuntimeDefault: false;
33
+ enumValues: [string, ...string[]];
34
+ baseColumn: never;
35
+ generated: undefined;
36
+ }, object>;
37
+ password: import("drizzle-orm/sqlite-core").SQLiteColumn<{
38
+ name: "password";
39
+ tableName: "users";
40
+ dataType: "string";
41
+ columnType: "SQLiteText";
42
+ data: string;
43
+ driverParam: string;
44
+ notNull: false;
45
+ hasDefault: false;
46
+ isPrimaryKey: false;
47
+ isAutoincrement: false;
48
+ hasRuntimeDefault: false;
49
+ enumValues: [string, ...string[]];
50
+ baseColumn: never;
51
+ generated: undefined;
52
+ }, object>;
53
+ };
54
+ dialect: "sqlite";
55
+ }>;
56
+ export declare const oauthAccountTable: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
57
+ name: "oauth_accounts";
58
+ schema: undefined;
59
+ columns: {
60
+ providerId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
61
+ name: "provider_id";
62
+ tableName: "oauth_accounts";
63
+ dataType: "string";
64
+ columnType: "SQLiteText";
65
+ data: string;
66
+ driverParam: string;
67
+ notNull: true;
68
+ hasDefault: false;
69
+ isPrimaryKey: false;
70
+ isAutoincrement: false;
71
+ hasRuntimeDefault: false;
72
+ enumValues: [string, ...string[]];
73
+ baseColumn: never;
74
+ generated: undefined;
75
+ }, object>;
76
+ providerUserId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
77
+ name: "provider_user_id";
78
+ tableName: "oauth_accounts";
79
+ dataType: "number";
80
+ columnType: "SQLiteInteger";
81
+ data: number;
82
+ driverParam: number;
83
+ notNull: true;
84
+ hasDefault: false;
85
+ isPrimaryKey: false;
86
+ isAutoincrement: false;
87
+ hasRuntimeDefault: false;
88
+ enumValues: undefined;
89
+ baseColumn: never;
90
+ generated: undefined;
91
+ }, object>;
92
+ userId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
93
+ name: "user_id";
94
+ tableName: "oauth_accounts";
95
+ dataType: "string";
96
+ columnType: "SQLiteText";
97
+ data: string;
98
+ driverParam: string;
99
+ notNull: true;
100
+ hasDefault: false;
101
+ isPrimaryKey: false;
102
+ isAutoincrement: false;
103
+ hasRuntimeDefault: false;
104
+ enumValues: [string, ...string[]];
105
+ baseColumn: never;
106
+ generated: undefined;
107
+ }, object>;
108
+ };
109
+ dialect: "sqlite";
110
+ }>;
111
+ export declare const sessionTable: import("drizzle-orm/sqlite-core").SQLiteTableWithColumns<{
112
+ name: "sessions";
113
+ schema: undefined;
114
+ columns: {
115
+ id: import("drizzle-orm/sqlite-core").SQLiteColumn<{
116
+ name: "id";
117
+ tableName: "sessions";
118
+ dataType: "string";
119
+ columnType: "SQLiteText";
120
+ data: string;
121
+ driverParam: string;
122
+ notNull: true;
123
+ hasDefault: false;
124
+ isPrimaryKey: true;
125
+ isAutoincrement: false;
126
+ hasRuntimeDefault: false;
127
+ enumValues: [string, ...string[]];
128
+ baseColumn: never;
129
+ generated: undefined;
130
+ }, object>;
131
+ userId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
132
+ name: "user_id";
133
+ tableName: "sessions";
134
+ dataType: "string";
135
+ columnType: "SQLiteText";
136
+ data: string;
137
+ driverParam: string;
138
+ notNull: true;
139
+ hasDefault: false;
140
+ isPrimaryKey: false;
141
+ isAutoincrement: false;
142
+ hasRuntimeDefault: false;
143
+ enumValues: [string, ...string[]];
144
+ baseColumn: never;
145
+ generated: undefined;
146
+ }, object>;
147
+ expiresAt: import("drizzle-orm/sqlite-core").SQLiteColumn<{
148
+ name: "expires_at";
149
+ tableName: "sessions";
150
+ dataType: "number";
151
+ columnType: "SQLiteInteger";
152
+ data: number;
153
+ driverParam: number;
154
+ notNull: true;
155
+ hasDefault: false;
156
+ isPrimaryKey: false;
157
+ isAutoincrement: false;
158
+ hasRuntimeDefault: false;
159
+ enumValues: undefined;
160
+ baseColumn: never;
161
+ generated: undefined;
162
+ }, object>;
163
+ };
164
+ dialect: "sqlite";
165
+ }>;
166
+ export type UserItem = typeof userTable.$inferSelect;
167
+ export type UserInsert = typeof userTable.$inferInsert;
@@ -0,0 +1,2 @@
1
+ import { type Database } from "better-sqlite3";
2
+ export declare const sqliteDb: Database;
@@ -0,0 +1,43 @@
1
+ import "dotenv/config";
2
+ import { Lucia } from "lucia";
3
+ import { GitHub } from "arctic";
4
+ /**
5
+ * Initialize Lucia
6
+ *
7
+ * @link {@see https://lucia-auth.com/getting-started/#initialize-lucia}
8
+ */
9
+ export declare const lucia: Lucia<Record<never, never>, {
10
+ username: string;
11
+ }>;
12
+ /**
13
+ * Initialize OAuth provider
14
+ *
15
+ * @link {@see https://lucia-auth.com/guides/oauth/basics#initialize-oauth-provider}
16
+ */
17
+ export declare const github: GitHub;
18
+ /**
19
+ * Define user attributes
20
+ *
21
+ * @link {@see https://lucia-auth.com/basics/users#define-user-attributes}
22
+ */
23
+ declare module "lucia" {
24
+ interface Register {
25
+ Lucia: typeof lucia;
26
+ DatabaseUserAttributes: Omit<DatabaseUser, "id">;
27
+ }
28
+ }
29
+ export interface DatabaseUser {
30
+ id: string;
31
+ username: string;
32
+ password?: string;
33
+ }
34
+ export interface DatabaseOAuthAccount {
35
+ provider_id: string;
36
+ provider_user_id: string;
37
+ userId: string;
38
+ user_id: string;
39
+ }
40
+ export interface GitHubUser {
41
+ id: number;
42
+ login: string;
43
+ }
@@ -0,0 +1,3 @@
1
+ import type { GuardAsync } from "vike/types";
2
+ declare const guard: GuardAsync;
3
+ export { guard };
@@ -0,0 +1,58 @@
1
+ import type { Session, User } from "lucia";
2
+ /**
3
+ * CSRF protection middleware
4
+ *
5
+ * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
6
+ */
7
+ export declare const luciaCsrfMiddleware: () => (request: Request) => Promise<Response | undefined>;
8
+ /**
9
+ * Validate session cookies middleware and set context
10
+ *
11
+ * @link {@see https://lucia-auth.com/guides/validate-session-cookies/}
12
+ */
13
+ export declare const luciaAuthContextMiddleware: () => (request: Request, context: Universal.Context) => Promise<{
14
+ session: null;
15
+ user: null;
16
+ } | {
17
+ sessionId: string;
18
+ session: Session | null;
19
+ user: User | null;
20
+ }>;
21
+ /**
22
+ * Set Set-Cookie headers if in context
23
+ */
24
+ export declare const luciaAuthCookieMiddleware: () => (_request: Request, context: {
25
+ session?: Session | null;
26
+ user?: User | null;
27
+ sessionId?: string | null;
28
+ }) => (response: Response) => Response;
29
+ /**
30
+ * Register user handler
31
+ *
32
+ * @link {@see https://lucia-auth.com/guides/email-and-password/basics#register-user}
33
+ */
34
+ export declare const luciaAuthSignupHandler: () => (request: Request) => Promise<Response>;
35
+ /**
36
+ * Sign in user handler
37
+ *
38
+ * @link {@see https://lucia-auth.com/guides/email-and-password/basics#sign-in-user}
39
+ */
40
+ export declare const luciaAuthLoginHandler: () => (request: Request) => Promise<Response>;
41
+ /**
42
+ * Log out user handler
43
+ */
44
+ export declare const luciaAuthLogoutHandler: () => (_request: Request, context: {
45
+ session?: Session | null;
46
+ }) => Promise<Response>;
47
+ /**
48
+ * Github OAuth authorization handler
49
+ *
50
+ * @link {@see https://lucia-auth.com/guides/oauth/basics#creating-authorization-url}
51
+ */
52
+ export declare const luciaGithubLoginHandler: () => () => Promise<Response>;
53
+ /**
54
+ * Github OAuth validate callback handler
55
+ *
56
+ * @link {@see https://lucia-auth.com/guides/oauth/basics#validate-callback}
57
+ */
58
+ export declare const luciaGithubCallbackHandler: () => (request: Request) => Promise<Response>;
@@ -57,11 +57,11 @@ var require_package = __commonJS({
57
57
  "cross-fetch": "^4.0.0",
58
58
  react: "^18.3.1",
59
59
  "react-dom": "^18.3.1",
60
- tailwindcss: "^3.4.9",
60
+ tailwindcss: "^3.4.10",
61
61
  typescript: "^5.5.4",
62
- vike: "^0.4.183",
63
- "vike-react": "^0.5.1",
64
- vite: "^5.4.0",
62
+ vike: "^0.4.187",
63
+ "vike-react": "^0.5.3",
64
+ vite: "^5.4.1",
65
65
  "vite-plugin-compiled-react": "^1.1.3"
66
66
  },
67
67
  dependencies: {
@@ -28,6 +28,7 @@ export default function LayoutDefault({ children }: { children: React.ReactNode
28
28
  <Link href="/">Welcome</Link>
29
29
  <Link href="/todo">Todo</Link>
30
30
  <Link href="/star-wars">Data Fetching</Link>
31
+ {BATI.has("firebase-auth") || BATI.has("lucia-auth") ? <Link href="/login">Login</Link> : ""}
31
32
  </Sidebar>
32
33
  <Content>{children}</Content>
33
34
  </div>
@@ -7,7 +7,7 @@ import Layout from "../layouts/LayoutDefault.js";
7
7
  export default {
8
8
  Layout,
9
9
  Head,
10
- //# BATI.has("auth0") || BATI.has("firebase-auth") || BATI.has("authjs")
10
+ //# BATI.has("auth0") || BATI.has("firebase-auth") || BATI.has("authjs") || BATI.has("lucia-auth")
11
11
  passToClient: ["user"],
12
12
  // <title>
13
13
  title: "My Vike App",