abckit 0.0.51 → 0.0.54
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.d.mts +3 -15
- package/dist/module.mjs +40 -13
- package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.d.vue.ts +2 -2
- package/dist/runtime/components/ui/native-select/NativeSelectOptGroup.vue.d.ts +2 -2
- package/dist/runtime/components/ui/native-select/NativeSelectOption.d.vue.ts +2 -2
- package/dist/runtime/components/ui/native-select/NativeSelectOption.vue.d.ts +2 -2
- package/dist/runtime/error.d.vue.ts +11 -9
- package/dist/runtime/error.vue +103 -143
- package/dist/runtime/error.vue.d.ts +11 -9
- package/dist/runtime/plugins/sentry-user.client.d.ts +6 -0
- package/dist/runtime/plugins/sentry-user.client.js +13 -0
- package/package.json +9 -1
- package/dist/runtime/composables/useAuth.d.ts +0 -1941
- package/dist/runtime/composables/useAuth.js +0 -117
- package/dist/runtime/middleware/auth.d.ts +0 -6
- package/dist/runtime/middleware/auth.js +0 -15
package/dist/module.d.mts
CHANGED
|
@@ -28,21 +28,11 @@ interface SetupConfig {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
interface AuthClientOptions {
|
|
31
|
-
/**
|
|
32
|
-
* Base URL for Better Auth client
|
|
33
|
-
* Required for Capacitor/mobile apps where the default URL is not http/https
|
|
34
|
-
* @example 'https://api.example.com'
|
|
35
|
-
*/
|
|
36
|
-
baseURL?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Base path for Better Auth API endpoints
|
|
39
|
-
* @default '/api/auth'
|
|
40
|
-
*/
|
|
41
|
-
basePath?: string;
|
|
42
31
|
/**
|
|
43
32
|
* Enable Capacitor mode for mobile apps
|
|
44
|
-
*
|
|
45
|
-
* @
|
|
33
|
+
* Injects Capacitor plugin via better-auth:config:extend hook
|
|
34
|
+
* Uses Bearer token auth with @capacitor/preferences storage
|
|
35
|
+
* @default false (or true if MOBILE_BUILD env is set)
|
|
46
36
|
*/
|
|
47
37
|
capacitor?: boolean;
|
|
48
38
|
/**
|
|
@@ -197,8 +187,6 @@ declare module '@nuxt/schema' {
|
|
|
197
187
|
abckit: {
|
|
198
188
|
sentry: boolean;
|
|
199
189
|
auth: {
|
|
200
|
-
baseURL?: string;
|
|
201
|
-
basePath?: string;
|
|
202
190
|
capacitor?: boolean;
|
|
203
191
|
oauthProvider?: boolean;
|
|
204
192
|
};
|
package/dist/module.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { updateRuntimeConfig, addTypeTemplate, addServerScanDir,
|
|
1
|
+
import { updateRuntimeConfig, addTypeTemplate, addServerScanDir, addPlugin, defineNuxtModule, createResolver } from '@nuxt/kit';
|
|
2
2
|
import { defu } from 'defu';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { networkInterfaces } from 'node:os';
|
|
@@ -28,6 +28,7 @@ function getModuleDependencies(nuxt) {
|
|
|
28
28
|
const opts = nuxt.options.abckit;
|
|
29
29
|
const isEnabled = createModuleChecker(opts);
|
|
30
30
|
return {
|
|
31
|
+
"@onmax/nuxt-better-auth": { optional: false },
|
|
31
32
|
"@nuxtjs/tailwindcss": { optional: !isEnabled("tailwindcss") },
|
|
32
33
|
"notivue/nuxt": { optional: !isEnabled("notivue") },
|
|
33
34
|
"@nuxt/icon": { optional: !isEnabled("icon") },
|
|
@@ -97,8 +98,8 @@ const ALIAS_PATHS = {
|
|
|
97
98
|
"abckit/components": "./runtime/components",
|
|
98
99
|
"abckit/shadcn": "./runtime/components/ui",
|
|
99
100
|
"abckit/composables": "./runtime/composables",
|
|
100
|
-
"abckit/middleware": "./runtime/middleware",
|
|
101
101
|
"abckit/plugins": "./runtime/plugins",
|
|
102
|
+
"abckit/plugins/capacitor": "./runtime/plugins/capacitor-client",
|
|
102
103
|
"abckit/graphql": "./runtime/graphql",
|
|
103
104
|
"abckit/stores": "./runtime/stores",
|
|
104
105
|
"abckit/utils": "./runtime/utils",
|
|
@@ -115,6 +116,9 @@ const NPM_TS_PATHS = {
|
|
|
115
116
|
const H3_TYPE_TEMPLATE = `
|
|
116
117
|
declare module 'nitro/h3' {
|
|
117
118
|
interface H3EventContext {
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated Use getUserSession(event) or requireUserSession(event) from nuxt-better-auth
|
|
121
|
+
*/
|
|
118
122
|
auth: {
|
|
119
123
|
user: {
|
|
120
124
|
id: string
|
|
@@ -124,7 +128,7 @@ declare module 'nitro/h3' {
|
|
|
124
128
|
image?: string
|
|
125
129
|
createdAt: Date
|
|
126
130
|
updatedAt: Date
|
|
127
|
-
role
|
|
131
|
+
role?: string
|
|
128
132
|
}
|
|
129
133
|
session: {
|
|
130
134
|
id: string
|
|
@@ -141,8 +145,8 @@ declare module 'nitro/h3' {
|
|
|
141
145
|
statusCode: number
|
|
142
146
|
statusMessage: string
|
|
143
147
|
}
|
|
144
|
-
isPremium
|
|
145
|
-
subscription
|
|
148
|
+
isPremium?: boolean
|
|
149
|
+
subscription?: any | null
|
|
146
150
|
}
|
|
147
151
|
}
|
|
148
152
|
|
|
@@ -169,9 +173,7 @@ async function setupRuntimeConfig(nuxt, options, isSentryEnabled) {
|
|
|
169
173
|
nuxt.options.runtimeConfig.public.abckit = {
|
|
170
174
|
sentry: isSentryEnabled,
|
|
171
175
|
auth: {
|
|
172
|
-
|
|
173
|
-
basePath: nuxt.options.runtimeConfig.public.abckit?.auth?.basePath ?? options.auth?.basePath,
|
|
174
|
-
capacitor: isMobileBuild,
|
|
176
|
+
capacitor: options.auth?.capacitor ?? isMobileBuild,
|
|
175
177
|
oauthProvider: options.auth?.oauthProvider ?? false
|
|
176
178
|
}
|
|
177
179
|
};
|
|
@@ -298,9 +300,9 @@ function setupColorMode(nuxt) {
|
|
|
298
300
|
}
|
|
299
301
|
function setupRouting(nuxt, resolve) {
|
|
300
302
|
addServerScanDir(resolve("./runtime/server"));
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
addPlugin({
|
|
304
|
+
src: resolve("./runtime/plugins/sentry-user.client"),
|
|
305
|
+
mode: "client"
|
|
304
306
|
});
|
|
305
307
|
nuxt.options.routeRules = nuxt.options.routeRules || {};
|
|
306
308
|
nuxt.options.routeRules["/**"] = defu(nuxt.options.routeRules["/**"] || {}, { ssr: false });
|
|
@@ -328,6 +330,32 @@ function setupDevtools(nuxt) {
|
|
|
328
330
|
enabled: false
|
|
329
331
|
});
|
|
330
332
|
}
|
|
333
|
+
function setupBetterAuth(nuxt, options, _resolve) {
|
|
334
|
+
const isCapacitor = options.auth?.capacitor ?? isMobileBuild;
|
|
335
|
+
nuxt.options["nuxt-better-auth"] = defu(nuxt.options["nuxt-better-auth"] || {}, {
|
|
336
|
+
clientOnly: isCapacitor,
|
|
337
|
+
redirects: {
|
|
338
|
+
login: "/auth/login",
|
|
339
|
+
guest: "/"
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
nuxt.hook("better-auth:config:extend", async (config) => {
|
|
343
|
+
const plugins = config.plugins || [];
|
|
344
|
+
const { adminClient } = await import('better-auth/client/plugins');
|
|
345
|
+
plugins.push(adminClient());
|
|
346
|
+
if (isCapacitor) {
|
|
347
|
+
const { capacitorClient } = await import('../dist/runtime/plugins/capacitor-client.js');
|
|
348
|
+
plugins.push(capacitorClient({
|
|
349
|
+
storagePrefix: "better-auth"
|
|
350
|
+
}));
|
|
351
|
+
}
|
|
352
|
+
if (options.auth?.oauthProvider) {
|
|
353
|
+
const { oauthProviderClient } = await import('@better-auth/oauth-provider/client');
|
|
354
|
+
plugins.push(oauthProviderClient());
|
|
355
|
+
}
|
|
356
|
+
config.plugins = plugins;
|
|
357
|
+
});
|
|
358
|
+
}
|
|
331
359
|
|
|
332
360
|
const FEATURE_GROUPS = {
|
|
333
361
|
core: {
|
|
@@ -475,8 +503,6 @@ const module$1 = defineNuxtModule({
|
|
|
475
503
|
disk: false
|
|
476
504
|
},
|
|
477
505
|
auth: {
|
|
478
|
-
baseURL: isMobileBuild ? mobileBaseURL : void 0,
|
|
479
|
-
basePath: "/api/auth",
|
|
480
506
|
capacitor: isMobileBuild
|
|
481
507
|
},
|
|
482
508
|
npm: false
|
|
@@ -512,6 +538,7 @@ const module$1 = defineNuxtModule({
|
|
|
512
538
|
setupTypeScript(nuxt);
|
|
513
539
|
setupColorMode(nuxt);
|
|
514
540
|
setupRouting(nuxt, resolve);
|
|
541
|
+
setupBetterAuth(nuxt, options);
|
|
515
542
|
}
|
|
516
543
|
});
|
|
517
544
|
|
|
@@ -68,7 +68,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
68
68
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
69
69
|
'aria-flowto'?: string | undefined | undefined;
|
|
70
70
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
71
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
71
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
72
72
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
73
73
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
74
74
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -262,7 +262,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
262
262
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
263
263
|
'aria-flowto'?: string | undefined | undefined;
|
|
264
264
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
265
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
265
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
266
266
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
267
267
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
268
268
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -68,7 +68,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
68
68
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
69
69
|
'aria-flowto'?: string | undefined | undefined;
|
|
70
70
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
71
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
71
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
72
72
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
73
73
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
74
74
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -262,7 +262,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
262
262
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
263
263
|
'aria-flowto'?: string | undefined | undefined;
|
|
264
264
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
265
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
265
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
266
266
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
267
267
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
268
268
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -70,7 +70,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
70
70
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
71
71
|
'aria-flowto'?: string | undefined | undefined;
|
|
72
72
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
73
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
73
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
74
74
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
75
75
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
76
76
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -266,7 +266,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
266
266
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
267
267
|
'aria-flowto'?: string | undefined | undefined;
|
|
268
268
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
269
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
269
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
270
270
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
271
271
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
272
272
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -70,7 +70,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
70
70
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
71
71
|
'aria-flowto'?: string | undefined | undefined;
|
|
72
72
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
73
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
73
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
74
74
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
75
75
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
76
76
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -266,7 +266,7 @@ declare const __VLS_base: import("vue").DefineComponent<{
|
|
|
266
266
|
'aria-expanded'?: (boolean | "true" | "false") | undefined;
|
|
267
267
|
'aria-flowto'?: string | undefined | undefined;
|
|
268
268
|
'aria-grabbed'?: (boolean | "true" | "false") | undefined;
|
|
269
|
-
'aria-haspopup'?: "dialog" | "menu" | (boolean | "true" | "false") | "listbox" | "tree" |
|
|
269
|
+
'aria-haspopup'?: "dialog" | "menu" | "grid" | (boolean | "true" | "false") | "listbox" | "tree" | undefined;
|
|
270
270
|
'aria-hidden'?: (boolean | "true" | "false") | undefined;
|
|
271
271
|
'aria-invalid'?: (boolean | "true" | "false") | "grammar" | "spelling" | undefined;
|
|
272
272
|
'aria-keyshortcuts'?: string | undefined | undefined;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
type __VLS_Props = {
|
|
2
|
-
error: {
|
|
3
|
-
statusCode: number;
|
|
4
|
-
statusMessage?: string;
|
|
5
|
-
message?: string;
|
|
6
|
-
stack?: string;
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
1
|
declare const _default: typeof __VLS_export;
|
|
11
2
|
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
error: {
|
|
5
|
+
type: ObjectConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
9
|
+
error: {
|
|
10
|
+
type: ObjectConstructor;
|
|
11
|
+
required: true;
|
|
12
|
+
};
|
|
13
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/dist/runtime/error.vue
CHANGED
|
@@ -121,59 +121,59 @@ function switchUser() {
|
|
|
121
121
|
</script>
|
|
122
122
|
|
|
123
123
|
<template>
|
|
124
|
-
<div class="min-h-dvh bg-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
<div class="
|
|
124
|
+
<div class="min-h-dvh bg-background flex flex-col safe-area-inset">
|
|
125
|
+
<!-- Mobile App Header -->
|
|
126
|
+
<header class="shrink-0 pt-safe-top border-b border-border/50">
|
|
127
|
+
<div class="h-14 flex items-center justify-between relative">
|
|
128
|
+
<!-- Back Button -->
|
|
129
|
+
<Button
|
|
130
|
+
variant="ghost"
|
|
131
|
+
size="icon"
|
|
132
|
+
class="size-14 rounded-none active:bg-muted transition-colors"
|
|
133
|
+
@click="goBack"
|
|
134
|
+
>
|
|
135
|
+
<Icon name="lucide:chevron-left" class="size-6" />
|
|
136
|
+
</Button>
|
|
137
|
+
|
|
138
|
+
<!-- Center: Error Code Badge -->
|
|
139
|
+
<div class="absolute left-1/2 -translate-x-1/2">
|
|
140
|
+
<span class="px-3 py-1 bg-destructive/10 text-destructive text-sm font-medium rounded-full">
|
|
141
|
+
{{ error.statusCode }}
|
|
142
|
+
</span>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<!-- Home Button -->
|
|
146
|
+
<Button
|
|
147
|
+
variant="ghost"
|
|
148
|
+
size="icon"
|
|
149
|
+
class="size-14 rounded-none active:bg-muted transition-colors"
|
|
150
|
+
@click="goHome"
|
|
151
|
+
>
|
|
152
|
+
<Icon name="lucide:home" class="size-5" />
|
|
153
|
+
</Button>
|
|
154
|
+
</div>
|
|
155
|
+
</header>
|
|
156
|
+
|
|
157
|
+
<!-- Main Content -->
|
|
158
|
+
<div class="flex-1 flex flex-col items-center justify-center px-6 pb-8">
|
|
159
|
+
<div class="w-full max-w-sm text-center space-y-6">
|
|
128
160
|
<!-- Emoji Icon -->
|
|
129
|
-
<div class="text-
|
|
161
|
+
<div class="text-7xl select-none animate-bounce-slow">
|
|
130
162
|
{{ getErrorData().emoji }}
|
|
131
163
|
</div>
|
|
132
164
|
|
|
133
165
|
<!-- Title & Description -->
|
|
134
|
-
<div class="space-y-
|
|
135
|
-
<h1 class="text-
|
|
166
|
+
<div class="space-y-3">
|
|
167
|
+
<h1 class="text-2xl font-bold text-foreground">
|
|
136
168
|
{{ getErrorData().title }}
|
|
137
169
|
</h1>
|
|
138
|
-
<p class="text-
|
|
170
|
+
<p class="text-base text-muted-foreground leading-relaxed">
|
|
139
171
|
{{ getErrorData().description }}
|
|
140
172
|
</p>
|
|
141
173
|
</div>
|
|
142
174
|
|
|
143
|
-
<!--
|
|
144
|
-
<div class="
|
|
145
|
-
<Button
|
|
146
|
-
size="lg"
|
|
147
|
-
class="w-full h-12 text-base font-medium"
|
|
148
|
-
@click="getErrorData().primaryHandler"
|
|
149
|
-
>
|
|
150
|
-
{{ getErrorData().primaryAction }}
|
|
151
|
-
</Button>
|
|
152
|
-
|
|
153
|
-
<div class="flex gap-3">
|
|
154
|
-
<Button
|
|
155
|
-
variant="outline"
|
|
156
|
-
size="lg"
|
|
157
|
-
class="flex-1 h-12"
|
|
158
|
-
@click="goHome"
|
|
159
|
-
>
|
|
160
|
-
<Icon name="lucide:home" class="mr-2 size-4" />
|
|
161
|
-
Home
|
|
162
|
-
</Button>
|
|
163
|
-
<Button
|
|
164
|
-
variant="outline"
|
|
165
|
-
size="lg"
|
|
166
|
-
class="flex-1 h-12"
|
|
167
|
-
@click="goBack"
|
|
168
|
-
>
|
|
169
|
-
<Icon name="lucide:arrow-left" class="mr-2 size-4" />
|
|
170
|
-
Back
|
|
171
|
-
</Button>
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
|
|
175
|
-
<!-- Help Text -->
|
|
176
|
-
<div class="bg-white/60 dark:bg-slate-800/60 backdrop-blur-sm rounded-xl p-4 text-sm text-slate-600 dark:text-slate-400">
|
|
175
|
+
<!-- Help Text Card -->
|
|
176
|
+
<div class="bg-muted/50 rounded-2xl p-4 text-sm text-muted-foreground">
|
|
177
177
|
<template v-if="error.statusCode === 401">
|
|
178
178
|
Your session has ended for security purposes. Please sign in again.
|
|
179
179
|
</template>
|
|
@@ -188,118 +188,78 @@ function switchUser() {
|
|
|
188
188
|
</template>
|
|
189
189
|
</div>
|
|
190
190
|
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<!-- Bottom Action Button (Mobile App Style) -->
|
|
194
|
+
<div class="flex-shrink-0 px-6 pb-6 pt-2 space-y-4">
|
|
195
|
+
<Button
|
|
196
|
+
size="lg"
|
|
197
|
+
class="w-full h-14 text-base font-semibold rounded-2xl"
|
|
198
|
+
@click="getErrorData().primaryHandler"
|
|
199
|
+
>
|
|
200
|
+
{{ getErrorData().primaryAction }}
|
|
201
|
+
</Button>
|
|
191
202
|
|
|
192
203
|
<!-- Debug Panel (Development Only) -->
|
|
193
|
-
<
|
|
194
|
-
<
|
|
195
|
-
<
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
<div class="
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
<div class="font-medium text-slate-500 dark:text-slate-400 text-xs mb-1">
|
|
215
|
-
Status Code
|
|
216
|
-
</div>
|
|
217
|
-
<div class="font-mono text-slate-900 dark:text-slate-100">
|
|
218
|
-
{{ error.statusCode }}
|
|
219
|
-
</div>
|
|
204
|
+
<details v-if="isDev" class="bg-muted rounded-2xl">
|
|
205
|
+
<summary class="cursor-pointer p-4 font-medium text-muted-foreground flex items-center justify-between rounded-2xl">
|
|
206
|
+
<div class="flex items-center gap-2">
|
|
207
|
+
<Icon name="lucide:bug" class="size-4" />
|
|
208
|
+
Debug
|
|
209
|
+
</div>
|
|
210
|
+
<Button
|
|
211
|
+
size="sm"
|
|
212
|
+
variant="outline"
|
|
213
|
+
class="h-8 px-3 text-xs rounded-xl"
|
|
214
|
+
@click.stop="copyDebugInfo"
|
|
215
|
+
>
|
|
216
|
+
<Icon name="lucide:copy" class="size-3 mr-1" />
|
|
217
|
+
{{ copied ? "Copied!" : "Copy" }}
|
|
218
|
+
</Button>
|
|
219
|
+
</summary>
|
|
220
|
+
<div class="px-4 pb-4 space-y-3 text-sm">
|
|
221
|
+
<div class="grid grid-cols-2 gap-3 p-3 bg-background rounded-xl">
|
|
222
|
+
<div>
|
|
223
|
+
<div class="text-muted-foreground text-xs mb-1">
|
|
224
|
+
Status
|
|
220
225
|
</div>
|
|
221
|
-
<div>
|
|
222
|
-
|
|
223
|
-
Timestamp
|
|
224
|
-
</div>
|
|
225
|
-
<div class="font-mono text-slate-900 dark:text-slate-100 text-xs">
|
|
226
|
-
{{ (/* @__PURE__ */ new Date()).toLocaleString() }}
|
|
227
|
-
</div>
|
|
226
|
+
<div class="font-mono text-foreground">
|
|
227
|
+
{{ error.statusCode }}
|
|
228
228
|
</div>
|
|
229
229
|
</div>
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
<div v-if="error.statusMessage">
|
|
234
|
-
<div class="flex items-center justify-between mb-2">
|
|
235
|
-
<span class="font-medium text-slate-600 dark:text-slate-400">Status Message</span>
|
|
236
|
-
<Button
|
|
237
|
-
size="sm"
|
|
238
|
-
variant="ghost"
|
|
239
|
-
class="h-6 w-6 p-0"
|
|
240
|
-
@click="copyToClipboard(error.statusMessage || '')"
|
|
241
|
-
>
|
|
242
|
-
<Icon name="lucide:copy" class="size-3" />
|
|
243
|
-
</Button>
|
|
244
|
-
</div>
|
|
245
|
-
<div class="p-2 bg-slate-50 dark:bg-slate-900 rounded font-mono text-xs break-all">
|
|
246
|
-
{{ error.statusMessage }}
|
|
247
|
-
</div>
|
|
230
|
+
<div>
|
|
231
|
+
<div class="text-muted-foreground text-xs mb-1">
|
|
232
|
+
Time
|
|
248
233
|
</div>
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
<div class="flex items-center justify-between mb-2">
|
|
252
|
-
<span class="font-medium text-slate-600 dark:text-slate-400">Error Message</span>
|
|
253
|
-
<Button
|
|
254
|
-
size="sm"
|
|
255
|
-
variant="ghost"
|
|
256
|
-
class="h-6 w-6 p-0"
|
|
257
|
-
@click="copyToClipboard(error.message || '')"
|
|
258
|
-
>
|
|
259
|
-
<Icon name="lucide:copy" class="size-3" />
|
|
260
|
-
</Button>
|
|
261
|
-
</div>
|
|
262
|
-
<div class="p-2 bg-slate-50 dark:bg-slate-900 rounded font-mono text-xs break-all">
|
|
263
|
-
{{ error.message }}
|
|
264
|
-
</div>
|
|
234
|
+
<div class="font-mono text-foreground text-xs">
|
|
235
|
+
{{ (/* @__PURE__ */ new Date()).toLocaleTimeString() }}
|
|
265
236
|
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
266
239
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
</div>
|
|
279
|
-
<pre class="text-xs bg-slate-50 dark:bg-slate-900 rounded p-3 overflow-auto max-h-40 font-mono border">{{ error.stack }}</pre>
|
|
280
|
-
</div>
|
|
240
|
+
<div v-if="error.message" class="space-y-2">
|
|
241
|
+
<div class="flex items-center justify-between">
|
|
242
|
+
<span class="text-muted-foreground text-xs">Message</span>
|
|
243
|
+
<Button size="sm" variant="ghost" class="size-6 p-0" @click="copyToClipboard(error.message || '')">
|
|
244
|
+
<Icon name="lucide:copy" class="size-3" />
|
|
245
|
+
</Button>
|
|
246
|
+
</div>
|
|
247
|
+
<div class="p-2 bg-background rounded-xl font-mono text-xs break-all">
|
|
248
|
+
{{ error.message }}
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
281
251
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
variant="ghost"
|
|
289
|
-
class="h-6 w-6 p-0"
|
|
290
|
-
@click="copyToClipboard(currentUrl)"
|
|
291
|
-
>
|
|
292
|
-
<Icon name="lucide:copy" class="size-3" />
|
|
293
|
-
</Button>
|
|
294
|
-
</div>
|
|
295
|
-
<div class="p-2 bg-slate-50 dark:bg-slate-900 rounded font-mono text-xs break-all">
|
|
296
|
-
{{ currentUrl }}
|
|
297
|
-
</div>
|
|
298
|
-
</div>
|
|
252
|
+
<div v-if="error.stack" class="space-y-2">
|
|
253
|
+
<div class="flex items-center justify-between">
|
|
254
|
+
<span class="text-muted-foreground text-xs">Stack</span>
|
|
255
|
+
<Button size="sm" variant="ghost" class="size-6 p-0" @click="copyToClipboard(error.stack || '')">
|
|
256
|
+
<Icon name="lucide:copy" class="size-3" />
|
|
257
|
+
</Button>
|
|
299
258
|
</div>
|
|
259
|
+
<pre class="text-xs bg-background rounded-xl p-3 overflow-auto max-h-32 font-mono">{{ error.stack }}</pre>
|
|
300
260
|
</div>
|
|
301
|
-
</
|
|
302
|
-
</
|
|
261
|
+
</div>
|
|
262
|
+
</details>
|
|
303
263
|
</div>
|
|
304
264
|
</div>
|
|
305
265
|
</template>
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
type __VLS_Props = {
|
|
2
|
-
error: {
|
|
3
|
-
statusCode: number;
|
|
4
|
-
statusMessage?: string;
|
|
5
|
-
message?: string;
|
|
6
|
-
stack?: string;
|
|
7
|
-
};
|
|
8
|
-
};
|
|
9
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
1
|
declare const _default: typeof __VLS_export;
|
|
11
2
|
export default _default;
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
error: {
|
|
5
|
+
type: ObjectConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
9
|
+
error: {
|
|
10
|
+
type: ObjectConstructor;
|
|
11
|
+
required: true;
|
|
12
|
+
};
|
|
13
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRuntimeConfig } from "#app";
|
|
2
|
+
import { useUserSession } from "#imports";
|
|
3
|
+
import { watch } from "vue";
|
|
4
|
+
export default defineNuxtPlugin(() => {
|
|
5
|
+
const config = useRuntimeConfig();
|
|
6
|
+
if (!config.public.abckit?.sentry)
|
|
7
|
+
return;
|
|
8
|
+
const { user } = useUserSession();
|
|
9
|
+
watch(user, async (currentUser) => {
|
|
10
|
+
const Sentry = await import("@sentry/nuxt");
|
|
11
|
+
Sentry.setUser(currentUser ? { id: currentUser.id } : null);
|
|
12
|
+
}, { immediate: true });
|
|
13
|
+
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abckit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.54",
|
|
5
5
|
"description": "Nuxt 4 module — UI components, auth, storage, GraphQL",
|
|
6
6
|
"author": "productdevbook",
|
|
7
7
|
"license": "MIT",
|
|
@@ -62,6 +62,10 @@
|
|
|
62
62
|
"./colada": {
|
|
63
63
|
"types": "./dist/runtime/colada.options.d.ts",
|
|
64
64
|
"import": "./dist/runtime/colada.options.js"
|
|
65
|
+
},
|
|
66
|
+
"./plugins/capacitor": {
|
|
67
|
+
"types": "./dist/runtime/plugins/capacitor-client.d.ts",
|
|
68
|
+
"import": "./dist/runtime/plugins/capacitor-client.js"
|
|
65
69
|
}
|
|
66
70
|
},
|
|
67
71
|
"types": "./dist/module.d.mts",
|
|
@@ -77,6 +81,7 @@
|
|
|
77
81
|
},
|
|
78
82
|
"peerDependencies": {
|
|
79
83
|
"@better-auth/oauth-provider": "^1.4.12",
|
|
84
|
+
"@onmax/nuxt-better-auth": "^0.0.2-alpha.17",
|
|
80
85
|
"@capacitor/android": "^8.0.1",
|
|
81
86
|
"@capacitor/app": "^8.0.0",
|
|
82
87
|
"@capacitor/browser": "^8.0.0",
|
|
@@ -154,6 +159,9 @@
|
|
|
154
159
|
"@better-auth/oauth-provider": {
|
|
155
160
|
"optional": true
|
|
156
161
|
},
|
|
162
|
+
"@onmax/nuxt-better-auth": {
|
|
163
|
+
"optional": true
|
|
164
|
+
},
|
|
157
165
|
"@capacitor/android": {
|
|
158
166
|
"optional": true
|
|
159
167
|
},
|