@onmax/nuxt-better-auth 0.0.2-alpha.1 → 0.0.2-alpha.3
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/dist/module.json +1 -1
- package/dist/module.mjs +64 -25
- package/dist/runtime/app/composables/useUserSession.js +15 -10
- package/dist/runtime/app/middleware/auth.global.js +9 -3
- package/dist/runtime/app/plugins/session.server.js +2 -1
- package/dist/runtime/config.d.ts +5 -0
- package/dist/runtime/server/api/_better-auth/config.get.d.ts +2 -2
- package/dist/runtime/server/api/_better-auth/config.get.js +2 -1
- package/dist/runtime/server/api/_better-auth/sessions.get.js +10 -1
- package/package.json +4 -2
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -22,46 +22,60 @@ function setupDevTools(nuxt) {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
function generateDrizzleSchema(tables, dialect) {
|
|
26
|
-
const
|
|
27
|
-
const
|
|
25
|
+
function generateDrizzleSchema(tables, dialect, options) {
|
|
26
|
+
const typedTables = tables;
|
|
27
|
+
const imports = getImports(dialect, options);
|
|
28
|
+
const tableDefinitions = Object.entries(typedTables).map(([tableName, table]) => generateTable(tableName, table, dialect, typedTables, options)).join("\n\n");
|
|
28
29
|
return `${imports}
|
|
29
30
|
|
|
30
31
|
${tableDefinitions}
|
|
31
32
|
`;
|
|
32
33
|
}
|
|
33
|
-
function getImports(dialect) {
|
|
34
|
+
function getImports(dialect, options) {
|
|
34
35
|
switch (dialect) {
|
|
35
36
|
case "sqlite":
|
|
36
37
|
return `import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'`;
|
|
37
38
|
case "postgresql":
|
|
38
|
-
return `import { boolean, pgTable, text, timestamp, integer } from 'drizzle-orm/pg-core'`;
|
|
39
|
+
return options?.useUuid ? `import { boolean, integer, pgTable, text, timestamp, uuid } from 'drizzle-orm/pg-core'` : `import { boolean, integer, pgTable, text, timestamp } from 'drizzle-orm/pg-core'`;
|
|
39
40
|
case "mysql":
|
|
40
41
|
return `import { boolean, int, mysqlTable, text, timestamp, varchar } from 'drizzle-orm/mysql-core'`;
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
function generateTable(tableName, table, dialect, allTables) {
|
|
44
|
+
function generateTable(tableName, table, dialect, allTables, options) {
|
|
44
45
|
const tableFunc = dialect === "sqlite" ? "sqliteTable" : dialect === "postgresql" ? "pgTable" : "mysqlTable";
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
let dbTableName = table.modelName || tableName;
|
|
47
|
+
if (options?.usePlural && !table.modelName) {
|
|
48
|
+
dbTableName = `${tableName}s`;
|
|
49
|
+
}
|
|
50
|
+
const fields = Object.entries(table.fields).map(([fieldName, field]) => generateField(fieldName, field, dialect, allTables, options)).join(",\n ");
|
|
51
|
+
const idField = generateIdField(dialect, options);
|
|
48
52
|
return `export const ${tableName} = ${tableFunc}('${dbTableName}', {
|
|
49
53
|
${idField},
|
|
50
54
|
${fields}
|
|
51
55
|
})`;
|
|
52
56
|
}
|
|
53
|
-
function generateIdField(dialect) {
|
|
57
|
+
function generateIdField(dialect, options) {
|
|
54
58
|
switch (dialect) {
|
|
55
59
|
case "sqlite":
|
|
56
|
-
|
|
60
|
+
if (options?.useUuid)
|
|
61
|
+
consola$1.warn("[@onmax/nuxt-better-auth] useUuid ignored for SQLite (no native uuid type). Using text.");
|
|
57
62
|
return `id: text('id').primaryKey()`;
|
|
63
|
+
case "postgresql":
|
|
64
|
+
return options?.useUuid ? `id: uuid('id').defaultRandom().primaryKey()` : `id: text('id').primaryKey()`;
|
|
58
65
|
case "mysql":
|
|
59
66
|
return `id: varchar('id', { length: 36 }).primaryKey()`;
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
|
-
function generateField(fieldName, field, dialect, allTables) {
|
|
69
|
+
function generateField(fieldName, field, dialect, allTables, options) {
|
|
63
70
|
const dbFieldName = fieldName;
|
|
64
|
-
|
|
71
|
+
const isFkToId = options?.useUuid && field.references?.field === "id";
|
|
72
|
+
let fieldDef;
|
|
73
|
+
if (isFkToId && dialect === "postgresql")
|
|
74
|
+
fieldDef = `uuid('${dbFieldName}')`;
|
|
75
|
+
else if (isFkToId && dialect === "mysql")
|
|
76
|
+
fieldDef = `varchar('${dbFieldName}', { length: 36 })`;
|
|
77
|
+
else
|
|
78
|
+
fieldDef = getFieldType(field.type, dialect, dbFieldName);
|
|
65
79
|
if (field.required && field.defaultValue === void 0)
|
|
66
80
|
fieldDef += ".notNull()";
|
|
67
81
|
if (field.unique)
|
|
@@ -136,17 +150,23 @@ function getMysqlType(type, fieldName) {
|
|
|
136
150
|
return `text('${fieldName}')`;
|
|
137
151
|
}
|
|
138
152
|
}
|
|
139
|
-
async function loadUserAuthConfig(configPath) {
|
|
153
|
+
async function loadUserAuthConfig(configPath, throwOnError = false) {
|
|
140
154
|
const { createJiti } = await import('jiti');
|
|
141
155
|
const jiti = createJiti(import.meta.url, { interopDefault: true });
|
|
142
156
|
try {
|
|
143
157
|
const mod = await jiti.import(configPath);
|
|
144
|
-
const configFn = mod.default
|
|
158
|
+
const configFn = typeof mod === "object" && mod !== null && "default" in mod ? mod.default : mod;
|
|
145
159
|
if (typeof configFn === "function") {
|
|
146
160
|
return configFn({ runtimeConfig: {}, db: null });
|
|
147
161
|
}
|
|
162
|
+
if (throwOnError) {
|
|
163
|
+
throw new Error("auth.config.ts must export default defineServerAuth(...)");
|
|
164
|
+
}
|
|
148
165
|
return {};
|
|
149
166
|
} catch (error) {
|
|
167
|
+
if (throwOnError) {
|
|
168
|
+
throw new Error(`Failed to load auth config: ${error instanceof Error ? error.message : error}`);
|
|
169
|
+
}
|
|
150
170
|
consola$1.error("[@onmax/nuxt-better-auth] Failed to load auth config for schema generation. Schema may be incomplete:", error);
|
|
151
171
|
return {};
|
|
152
172
|
}
|
|
@@ -186,7 +206,14 @@ const module$1 = defineNuxtModule({
|
|
|
186
206
|
redirects: { login: options.redirects?.login ?? "/login", guest: options.redirects?.guest ?? "/" },
|
|
187
207
|
useDatabase: hasHubDb
|
|
188
208
|
});
|
|
189
|
-
|
|
209
|
+
const betterAuthSecret = process.env.BETTER_AUTH_SECRET || process.env.NUXT_BETTER_AUTH_SECRET || nuxt.options.runtimeConfig.betterAuthSecret || "";
|
|
210
|
+
if (!nuxt.options.dev && !betterAuthSecret) {
|
|
211
|
+
throw new Error("[nuxt-better-auth] BETTER_AUTH_SECRET is required in production. Set BETTER_AUTH_SECRET or NUXT_BETTER_AUTH_SECRET environment variable.");
|
|
212
|
+
}
|
|
213
|
+
if (betterAuthSecret && betterAuthSecret.length < 32) {
|
|
214
|
+
throw new Error("[nuxt-better-auth] BETTER_AUTH_SECRET must be at least 32 characters for security");
|
|
215
|
+
}
|
|
216
|
+
nuxt.options.runtimeConfig.betterAuthSecret = betterAuthSecret;
|
|
190
217
|
nuxt.options.runtimeConfig.auth = defu(nuxt.options.runtimeConfig.auth, {
|
|
191
218
|
secondaryStorage: secondaryStorageEnabled
|
|
192
219
|
});
|
|
@@ -204,9 +231,13 @@ export function createSecondaryStorage() {
|
|
|
204
231
|
const secondaryStorageTemplate = addTemplate({ filename: "better-auth/secondary-storage.mjs", getContents: () => secondaryStorageCode, write: true });
|
|
205
232
|
nuxt.options.alias["#auth/secondary-storage"] = secondaryStorageTemplate.dst;
|
|
206
233
|
const hubDbPath = nuxt.options.alias["hub:db"];
|
|
234
|
+
if (hasHubDb && !hubDbPath) {
|
|
235
|
+
throw new Error("[nuxt-better-auth] hub:db alias not found. Ensure @nuxthub/core is loaded before this module.");
|
|
236
|
+
}
|
|
237
|
+
const hubDialect = typeof hub?.db === "string" ? hub.db : (typeof hub?.db === "object" ? hub.db.dialect : void 0) ?? "sqlite";
|
|
207
238
|
const databaseCode = hasHubDb && hubDbPath ? `import { db, schema } from '${hubDbPath}'
|
|
208
239
|
import { drizzleAdapter } from 'better-auth/adapters/drizzle'
|
|
209
|
-
const rawDialect = '${
|
|
240
|
+
const rawDialect = '${hubDialect}'
|
|
210
241
|
const dialect = rawDialect === 'postgresql' ? 'pg' : rawDialect
|
|
211
242
|
export function createDatabase() { return drizzleAdapter(db, { provider: dialect, schema }) }
|
|
212
243
|
export { db }` : `export function createDatabase() { return undefined }
|
|
@@ -298,9 +329,10 @@ declare module 'nitropack/types' {
|
|
|
298
329
|
app.middleware.push({ name: "auth", path: resolver.resolve("./runtime/app/middleware/auth.global"), global: true });
|
|
299
330
|
});
|
|
300
331
|
if (hasHubDb) {
|
|
301
|
-
await setupBetterAuthSchema(nuxt, serverConfigPath);
|
|
332
|
+
await setupBetterAuthSchema(nuxt, serverConfigPath, options);
|
|
302
333
|
}
|
|
303
|
-
|
|
334
|
+
const isProduction = process.env.NODE_ENV === "production" || !nuxt.options.dev;
|
|
335
|
+
if (!isProduction) {
|
|
304
336
|
setupDevTools(nuxt);
|
|
305
337
|
addServerHandler({ route: "/api/_better-auth/config", method: "get", handler: resolver.resolve("./runtime/server/api/_better-auth/config.get") });
|
|
306
338
|
if (hasHubDb) {
|
|
@@ -333,22 +365,25 @@ declare module 'nitropack/types' {
|
|
|
333
365
|
});
|
|
334
366
|
}
|
|
335
367
|
});
|
|
336
|
-
async function setupBetterAuthSchema(nuxt, serverConfigPath) {
|
|
368
|
+
async function setupBetterAuthSchema(nuxt, serverConfigPath, options) {
|
|
337
369
|
const hub = nuxt.options.hub;
|
|
338
|
-
const dialect = typeof hub
|
|
370
|
+
const dialect = typeof hub?.db === "string" ? hub.db : typeof hub?.db === "object" ? hub.db.dialect : void 0;
|
|
339
371
|
if (!dialect || !["sqlite", "postgresql", "mysql"].includes(dialect)) {
|
|
340
372
|
consola.warn(`Unsupported database dialect: ${dialect}`);
|
|
341
373
|
return;
|
|
342
374
|
}
|
|
375
|
+
const isProduction = !nuxt.options.dev;
|
|
343
376
|
try {
|
|
344
377
|
const configFile = `${serverConfigPath}.ts`;
|
|
345
|
-
const userConfig = await loadUserAuthConfig(configFile);
|
|
378
|
+
const userConfig = await loadUserAuthConfig(configFile, isProduction);
|
|
346
379
|
const extendedConfig = {};
|
|
347
380
|
await nuxt.callHook("better-auth:config:extend", extendedConfig);
|
|
348
381
|
const plugins = [...userConfig.plugins || [], ...extendedConfig.plugins || []];
|
|
349
382
|
const { getAuthTables } = await import('better-auth/db');
|
|
350
383
|
const tables = getAuthTables({ plugins });
|
|
351
|
-
const
|
|
384
|
+
const useUuid = userConfig.advanced?.database?.generateId === "uuid";
|
|
385
|
+
const schemaOptions = { ...options.schema, useUuid };
|
|
386
|
+
const schemaCode = generateDrizzleSchema(tables, dialect, schemaOptions);
|
|
352
387
|
const schemaDir = join(nuxt.options.buildDir, "better-auth");
|
|
353
388
|
const schemaPath = join(schemaDir, `schema.${dialect}.ts`);
|
|
354
389
|
await mkdir(schemaDir, { recursive: true });
|
|
@@ -356,12 +391,16 @@ async function setupBetterAuthSchema(nuxt, serverConfigPath) {
|
|
|
356
391
|
addTemplate({ filename: `better-auth/schema.${dialect}.ts`, getContents: () => schemaCode, write: true });
|
|
357
392
|
consola.info(`Generated ${dialect} schema with ${Object.keys(tables).length} tables`);
|
|
358
393
|
} catch (error) {
|
|
394
|
+
if (isProduction) {
|
|
395
|
+
throw error;
|
|
396
|
+
}
|
|
359
397
|
consola.error("Failed to generate schema:", error);
|
|
360
398
|
}
|
|
361
|
-
|
|
399
|
+
const nuxtWithHubHooks = nuxt;
|
|
400
|
+
nuxtWithHubHooks.hook("hub:db:schema:extend", ({ paths, dialect: hookDialect }) => {
|
|
362
401
|
const schemaPath = join(nuxt.options.buildDir, "better-auth", `schema.${hookDialect}.ts`);
|
|
363
402
|
if (existsSync(schemaPath)) {
|
|
364
|
-
paths.
|
|
403
|
+
paths.unshift(schemaPath);
|
|
365
404
|
}
|
|
366
405
|
});
|
|
367
406
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { createAppAuthClient } from "#auth/client";
|
|
2
|
-
import { computed, useRequestHeaders, useRequestURL, useRuntimeConfig, useState, watch } from "#imports";
|
|
3
|
-
import { consola } from "consola";
|
|
2
|
+
import { computed, nextTick, useRequestHeaders, useRequestURL, useRuntimeConfig, useState, watch } from "#imports";
|
|
4
3
|
let _client = null;
|
|
5
4
|
function getClient(baseURL) {
|
|
6
5
|
if (!_client)
|
|
@@ -30,7 +29,8 @@ export function useUserSession() {
|
|
|
30
29
|
() => clientSession.value,
|
|
31
30
|
(newSession) => {
|
|
32
31
|
if (newSession?.data?.session && newSession?.data?.user) {
|
|
33
|
-
|
|
32
|
+
const { token: _, ...safeSession } = newSession.data.session;
|
|
33
|
+
session.value = safeSession;
|
|
34
34
|
user.value = newSession.data.user;
|
|
35
35
|
} else if (!newSession?.isPending) {
|
|
36
36
|
clearSession();
|
|
@@ -62,6 +62,9 @@ export function useUserSession() {
|
|
|
62
62
|
function wrapOnSuccess(cb) {
|
|
63
63
|
return async (ctx) => {
|
|
64
64
|
await fetchSession({ force: true });
|
|
65
|
+
if (!loggedIn.value)
|
|
66
|
+
await waitForSession();
|
|
67
|
+
await nextTick();
|
|
65
68
|
await cb(ctx);
|
|
66
69
|
};
|
|
67
70
|
}
|
|
@@ -79,10 +82,11 @@ export function useUserSession() {
|
|
|
79
82
|
}
|
|
80
83
|
const signIn = client?.signIn ? new Proxy(client.signIn, {
|
|
81
84
|
get(target, prop) {
|
|
82
|
-
const
|
|
85
|
+
const targetRecord = target;
|
|
86
|
+
const method = targetRecord[prop];
|
|
83
87
|
if (typeof method !== "function")
|
|
84
88
|
return method;
|
|
85
|
-
return wrapAuthMethod((...args) =>
|
|
89
|
+
return wrapAuthMethod((...args) => targetRecord[prop](...args));
|
|
86
90
|
}
|
|
87
91
|
}) : new Proxy({}, {
|
|
88
92
|
get: (_, prop) => {
|
|
@@ -91,10 +95,11 @@ export function useUserSession() {
|
|
|
91
95
|
});
|
|
92
96
|
const signUp = client?.signUp ? new Proxy(client.signUp, {
|
|
93
97
|
get(target, prop) {
|
|
94
|
-
const
|
|
98
|
+
const targetRecord = target;
|
|
99
|
+
const method = targetRecord[prop];
|
|
95
100
|
if (typeof method !== "function")
|
|
96
101
|
return method;
|
|
97
|
-
return wrapAuthMethod((...args) =>
|
|
102
|
+
return wrapAuthMethod((...args) => targetRecord[prop](...args));
|
|
98
103
|
}
|
|
99
104
|
}) : new Proxy({}, {
|
|
100
105
|
get: (_, prop) => {
|
|
@@ -115,15 +120,15 @@ export function useUserSession() {
|
|
|
115
120
|
const result = await client.getSession({ query }, fetchOptions);
|
|
116
121
|
const data = result.data;
|
|
117
122
|
if (data?.session && data?.user) {
|
|
118
|
-
|
|
123
|
+
const { token: _, ...safeSession } = data.session;
|
|
124
|
+
session.value = safeSession;
|
|
119
125
|
user.value = data.user;
|
|
120
126
|
} else {
|
|
121
127
|
clearSession();
|
|
122
128
|
}
|
|
123
129
|
} catch (error) {
|
|
124
130
|
clearSession();
|
|
125
|
-
|
|
126
|
-
consola.error("Failed to fetch auth session:", error);
|
|
131
|
+
console.error("[nuxt-better-auth] Failed to fetch session:", error);
|
|
127
132
|
} finally {
|
|
128
133
|
if (!authReady.value)
|
|
129
134
|
authReady.value = true;
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { createError, defineNuxtRouteMiddleware, getRouteRules, navigateTo, useRequestHeaders, useRuntimeConfig } from "#imports";
|
|
1
|
+
import { createError, defineNuxtRouteMiddleware, getRouteRules, navigateTo, useNuxtApp, useRequestHeaders, useRuntimeConfig } from "#imports";
|
|
2
2
|
import { matchesUser } from "../../utils/match-user.js";
|
|
3
3
|
export default defineNuxtRouteMiddleware(async (to) => {
|
|
4
|
+
const nuxtApp = useNuxtApp();
|
|
5
|
+
if (import.meta.client) {
|
|
6
|
+
const isPrerendered = nuxtApp.payload.prerenderedAt || nuxtApp.payload.isCached;
|
|
7
|
+
if (isPrerendered && nuxtApp.isHydrating)
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
4
10
|
if (to.meta.auth === void 0) {
|
|
5
11
|
const rules = await getRouteRules({ path: to.path });
|
|
6
12
|
if (rules.auth !== void 0)
|
|
@@ -10,8 +16,8 @@ export default defineNuxtRouteMiddleware(async (to) => {
|
|
|
10
16
|
if (auth === void 0 || auth === false)
|
|
11
17
|
return;
|
|
12
18
|
const config = useRuntimeConfig().public.auth;
|
|
13
|
-
const { fetchSession, user, loggedIn
|
|
14
|
-
if (!loggedIn.value
|
|
19
|
+
const { fetchSession, user, loggedIn } = useUserSession();
|
|
20
|
+
if (!loggedIn.value) {
|
|
15
21
|
const headers = import.meta.server ? useRequestHeaders(["cookie"]) : void 0;
|
|
16
22
|
await fetchSession({ headers });
|
|
17
23
|
}
|
|
@@ -12,7 +12,8 @@ export default defineNuxtPlugin({
|
|
|
12
12
|
const headers = useRequestHeaders(["cookie"]);
|
|
13
13
|
const data = await $fetch("/api/auth/get-session", { headers });
|
|
14
14
|
if (data?.session && data?.user) {
|
|
15
|
-
|
|
15
|
+
const { token: _, ...safeSession } = data.session;
|
|
16
|
+
session.value = safeSession;
|
|
16
17
|
user.value = data.user;
|
|
17
18
|
}
|
|
18
19
|
} catch {
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -22,6 +22,11 @@ export interface BetterAuthModuleOptions {
|
|
|
22
22
|
};
|
|
23
23
|
/** Enable KV secondary storage for sessions. Requires hub.kv: true */
|
|
24
24
|
secondaryStorage?: boolean;
|
|
25
|
+
/** Schema generation options. Must match drizzleAdapter config. */
|
|
26
|
+
schema?: {
|
|
27
|
+
/** Plural table names: user → users. Default: false */
|
|
28
|
+
usePlural?: boolean;
|
|
29
|
+
};
|
|
25
30
|
}
|
|
26
31
|
export interface AuthRuntimeConfig {
|
|
27
32
|
redirects: {
|
|
@@ -12,7 +12,7 @@ declare const _default: import("h3").EventHandler<import("h3").EventHandlerReque
|
|
|
12
12
|
baseURL: string | undefined;
|
|
13
13
|
basePath: string;
|
|
14
14
|
socialProviders: string[];
|
|
15
|
-
plugins:
|
|
15
|
+
plugins: string[];
|
|
16
16
|
trustedOrigins: string[] | ((request: Request) => string[] | Promise<string[]>);
|
|
17
17
|
session: {
|
|
18
18
|
expiresIn: string;
|
|
@@ -30,6 +30,6 @@ declare const _default: import("h3").EventHandler<import("h3").EventHandlerReque
|
|
|
30
30
|
error?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
config: null;
|
|
33
|
-
error:
|
|
33
|
+
error: string;
|
|
34
34
|
}>>;
|
|
35
35
|
export default _default;
|
|
@@ -41,6 +41,7 @@ export default defineEventHandler(async (event) => {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
} catch (error) {
|
|
44
|
-
|
|
44
|
+
console.error("[DevTools] Config fetch failed:", error);
|
|
45
|
+
return { config: null, error: "Failed to fetch configuration" };
|
|
45
46
|
}
|
|
46
47
|
});
|
|
@@ -26,7 +26,16 @@ export default defineEventHandler(async (event) => {
|
|
|
26
26
|
dbQuery.orderBy(desc(schema.session.createdAt)).limit(limit).offset(offset),
|
|
27
27
|
countQuery
|
|
28
28
|
]);
|
|
29
|
-
|
|
29
|
+
const safeSessions = sessions.map((s) => ({
|
|
30
|
+
id: s.id,
|
|
31
|
+
userId: s.userId,
|
|
32
|
+
createdAt: s.createdAt,
|
|
33
|
+
updatedAt: s.updatedAt,
|
|
34
|
+
expiresAt: s.expiresAt,
|
|
35
|
+
ipAddress: s.ipAddress,
|
|
36
|
+
userAgent: s.userAgent
|
|
37
|
+
}));
|
|
38
|
+
return { sessions: safeSessions, total: totalResult[0]?.count ?? 0, page, limit };
|
|
30
39
|
} catch (error) {
|
|
31
40
|
console.error("[DevTools] Fetch sessions failed:", error);
|
|
32
41
|
return { sessions: [], total: 0, error: "Failed to fetch sessions" };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onmax/nuxt-better-auth",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.2-alpha.
|
|
4
|
+
"version": "0.0.2-alpha.3",
|
|
5
5
|
"packageManager": "pnpm@10.15.1",
|
|
6
6
|
"description": "Nuxt module for Better Auth integration with NuxtHub, route protection, session management, and role-based access",
|
|
7
7
|
"author": "onmax",
|
|
@@ -95,9 +95,11 @@
|
|
|
95
95
|
},
|
|
96
96
|
"pnpm": {
|
|
97
97
|
"onlyBuiltDependencies": [
|
|
98
|
+
"@parcel/watcher",
|
|
98
99
|
"better-sqlite3",
|
|
99
100
|
"esbuild",
|
|
100
|
-
"
|
|
101
|
+
"sharp",
|
|
102
|
+
"workerd"
|
|
101
103
|
],
|
|
102
104
|
"patchedDependencies": {
|
|
103
105
|
"@peculiar/x509@1.14.2": "patches/@peculiar__x509@1.14.2.patch",
|