@authon/vue 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,125 @@
1
+ # @authon/vue
2
+
3
+ Vue 3 SDK for [Authon](https://authon.dev) — plugin, composables, and components.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @authon/vue
9
+ # or
10
+ pnpm add @authon/vue
11
+ ```
12
+
13
+ Requires `vue >= 3.3.0`.
14
+
15
+ ## Quick Start
16
+
17
+ ### 1. Install the Plugin
18
+
19
+ ```ts
20
+ // main.ts
21
+ import { createApp } from 'vue';
22
+ import { AuthonPlugin } from '@authon/vue';
23
+ import App from './App.vue';
24
+
25
+ const app = createApp(App);
26
+ app.use(AuthonPlugin, {
27
+ publishableKey: 'pk_live_...',
28
+ });
29
+ app.mount('#app');
30
+ ```
31
+
32
+ ### 2. Use Composables
33
+
34
+ ```vue
35
+ <script setup lang="ts">
36
+ import { useAuthon, useUser } from '@authon/vue';
37
+
38
+ const { isSignedIn, openSignIn, signOut } = useAuthon();
39
+ const { user, isLoading } = useUser();
40
+ </script>
41
+
42
+ <template>
43
+ <div v-if="isLoading">Loading...</div>
44
+ <div v-else-if="isSignedIn">
45
+ <p>Welcome, {{ user?.displayName }}</p>
46
+ <button @click="signOut()">Sign Out</button>
47
+ </div>
48
+ <div v-else>
49
+ <button @click="openSignIn()">Sign In</button>
50
+ </div>
51
+ </template>
52
+ ```
53
+
54
+ ### 3. Use Components
55
+
56
+ ```vue
57
+ <template>
58
+ <SignedIn>
59
+ <UserButton />
60
+ </SignedIn>
61
+ <SignedOut>
62
+ <button @click="openSignIn()">Sign In</button>
63
+ </SignedOut>
64
+ </template>
65
+
66
+ <script setup lang="ts">
67
+ import { SignedIn, SignedOut, UserButton, useAuthon } from '@authon/vue';
68
+
69
+ const { openSignIn } = useAuthon();
70
+ </script>
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ ### Plugin
76
+
77
+ ```ts
78
+ app.use(AuthonPlugin, {
79
+ publishableKey: string;
80
+ apiUrl?: string;
81
+ theme?: 'light' | 'dark' | 'auto';
82
+ locale?: string;
83
+ appearance?: Partial<BrandingConfig>;
84
+ });
85
+ ```
86
+
87
+ ### Composables
88
+
89
+ #### `useAuthon()`
90
+
91
+ ```ts
92
+ const {
93
+ isSignedIn, // Ref<boolean>
94
+ isLoading, // Ref<boolean>
95
+ user, // Ref<AuthonUser | null>
96
+ signOut, // () => Promise<void>
97
+ openSignIn, // () => Promise<void>
98
+ openSignUp, // () => Promise<void>
99
+ getToken, // () => string | null
100
+ client, // Authon instance
101
+ } = useAuthon();
102
+ ```
103
+
104
+ #### `useUser()`
105
+
106
+ ```ts
107
+ const { user, isLoading } = useUser();
108
+ ```
109
+
110
+ ### Components
111
+
112
+ | Component | Description |
113
+ |-----------|-------------|
114
+ | `<SignedIn>` | Renders slot only when signed in |
115
+ | `<SignedOut>` | Renders slot only when signed out |
116
+ | `<UserButton>` | Avatar dropdown with sign-out |
117
+ | `<Protect>` | Conditional rendering with fallback slot |
118
+
119
+ ## Documentation
120
+
121
+ [authon.dev/docs](https://authon.dev/docs)
122
+
123
+ ## License
124
+
125
+ [MIT](../../LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,299 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AUTHON_KEY: () => AUTHON_KEY,
24
+ AuthonSignIn: () => AuthonSignIn,
25
+ AuthonSignUp: () => AuthonSignUp,
26
+ AuthonSignedIn: () => AuthonSignedIn,
27
+ AuthonSignedOut: () => AuthonSignedOut,
28
+ AuthonUserButton: () => AuthonUserButton,
29
+ createAuthon: () => createAuthon,
30
+ useAuthon: () => useAuthon,
31
+ useUser: () => useUser
32
+ });
33
+ module.exports = __toCommonJS(index_exports);
34
+
35
+ // src/plugin.ts
36
+ var import_vue = require("vue");
37
+ var import_js = require("@authon/js");
38
+ var AUTHON_KEY = /* @__PURE__ */ Symbol("authon");
39
+ function createAuthon(options) {
40
+ const state = (0, import_vue.reactive)({
41
+ isSignedIn: false,
42
+ isLoading: true,
43
+ user: null,
44
+ client: null
45
+ });
46
+ return {
47
+ install(app) {
48
+ const client = new import_js.Authon(options.publishableKey, options.config);
49
+ state.client = client;
50
+ client.on("signedIn", (user) => {
51
+ state.user = user;
52
+ state.isSignedIn = true;
53
+ state.isLoading = false;
54
+ });
55
+ client.on("signedOut", () => {
56
+ state.user = null;
57
+ state.isSignedIn = false;
58
+ });
59
+ client.on("error", () => {
60
+ state.isLoading = false;
61
+ });
62
+ state.isLoading = false;
63
+ app.provide(AUTHON_KEY, state);
64
+ app.config.globalProperties.$authon = state;
65
+ }
66
+ };
67
+ }
68
+
69
+ // src/composables.ts
70
+ var import_vue2 = require("vue");
71
+ function requireState() {
72
+ const state = (0, import_vue2.inject)(AUTHON_KEY);
73
+ if (!state) {
74
+ throw new Error("useAuthon() must be called inside a component tree with createAuthon() installed");
75
+ }
76
+ return state;
77
+ }
78
+ function useAuthon() {
79
+ const s = requireState();
80
+ async function signOut() {
81
+ await s.client?.signOut();
82
+ s.user = null;
83
+ s.isSignedIn = false;
84
+ }
85
+ async function openSignIn() {
86
+ await s.client?.openSignIn();
87
+ }
88
+ async function openSignUp() {
89
+ await s.client?.openSignUp();
90
+ }
91
+ function getToken() {
92
+ return s.client?.getToken() ?? null;
93
+ }
94
+ return {
95
+ ...s,
96
+ signOut,
97
+ openSignIn,
98
+ openSignUp,
99
+ getToken
100
+ };
101
+ }
102
+ function useUser() {
103
+ const s = requireState();
104
+ return {
105
+ user: (0, import_vue2.computed)(() => s.user),
106
+ isLoading: (0, import_vue2.computed)(() => s.isLoading)
107
+ };
108
+ }
109
+
110
+ // src/components.ts
111
+ var import_vue3 = require("vue");
112
+ var AuthonSignIn = (0, import_vue3.defineComponent)({
113
+ name: "AuthonSignIn",
114
+ props: {
115
+ mode: {
116
+ type: String,
117
+ default: "popup"
118
+ }
119
+ },
120
+ setup(props) {
121
+ const { client } = useAuthon();
122
+ (0, import_vue3.onMounted)(() => {
123
+ if (props.mode === "popup") {
124
+ client?.openSignIn();
125
+ }
126
+ });
127
+ return () => {
128
+ if (props.mode === "embedded") {
129
+ return (0, import_vue3.h)("div", { id: "authon-signin-container" });
130
+ }
131
+ return null;
132
+ };
133
+ }
134
+ });
135
+ var AuthonSignUp = (0, import_vue3.defineComponent)({
136
+ name: "AuthonSignUp",
137
+ props: {
138
+ mode: {
139
+ type: String,
140
+ default: "popup"
141
+ }
142
+ },
143
+ setup(props) {
144
+ const { client } = useAuthon();
145
+ (0, import_vue3.onMounted)(() => {
146
+ if (props.mode === "popup") {
147
+ client?.openSignUp();
148
+ }
149
+ });
150
+ return () => {
151
+ if (props.mode === "embedded") {
152
+ return (0, import_vue3.h)("div", { id: "authon-signup-container" });
153
+ }
154
+ return null;
155
+ };
156
+ }
157
+ });
158
+ var AuthonUserButton = (0, import_vue3.defineComponent)({
159
+ name: "AuthonUserButton",
160
+ setup() {
161
+ const { user, isSignedIn, signOut, openSignIn } = useAuthon();
162
+ const open = (0, import_vue3.ref)(false);
163
+ const initials = (0, import_vue3.computed)(() => {
164
+ if (!user) return "?";
165
+ const u = user;
166
+ if (u.displayName) {
167
+ return u.displayName.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
168
+ }
169
+ return (u.email?.[0] ?? "?").toUpperCase();
170
+ });
171
+ return () => {
172
+ if (!isSignedIn) {
173
+ return (0, import_vue3.h)(
174
+ "button",
175
+ {
176
+ onClick: () => openSignIn(),
177
+ style: {
178
+ padding: "8px 16px",
179
+ borderRadius: "8px",
180
+ border: "none",
181
+ background: "linear-gradient(135deg, #7c3aed, #4f46e5)",
182
+ color: "#fff",
183
+ cursor: "pointer",
184
+ fontSize: "14px",
185
+ fontWeight: 600
186
+ }
187
+ },
188
+ "Sign In"
189
+ );
190
+ }
191
+ const avatarUrl = user?.avatarUrl;
192
+ const displayName = user?.displayName;
193
+ const email = user?.email;
194
+ return (0, import_vue3.h)("div", { style: { position: "relative", display: "inline-block" } }, [
195
+ (0, import_vue3.h)(
196
+ "button",
197
+ {
198
+ onClick: () => open.value = !open.value,
199
+ style: {
200
+ width: "36px",
201
+ height: "36px",
202
+ borderRadius: "50%",
203
+ border: "2px solid #7c3aed",
204
+ background: avatarUrl ? "transparent" : "linear-gradient(135deg, #7c3aed, #4f46e5)",
205
+ cursor: "pointer",
206
+ padding: 0,
207
+ overflow: "hidden",
208
+ display: "flex",
209
+ alignItems: "center",
210
+ justifyContent: "center",
211
+ color: "#fff",
212
+ fontSize: "13px",
213
+ fontWeight: 700
214
+ }
215
+ },
216
+ avatarUrl ? [(0, import_vue3.h)("img", { src: avatarUrl, alt: displayName ?? "avatar", style: { width: "100%", height: "100%", objectFit: "cover" } })] : [initials.value]
217
+ ),
218
+ open.value ? (0, import_vue3.h)(
219
+ "div",
220
+ {
221
+ style: {
222
+ position: "absolute",
223
+ right: 0,
224
+ top: "44px",
225
+ minWidth: "200px",
226
+ background: "#fff",
227
+ border: "1px solid #e5e7eb",
228
+ borderRadius: "12px",
229
+ boxShadow: "0 8px 24px rgba(0,0,0,0.12)",
230
+ zIndex: 9999,
231
+ overflow: "hidden"
232
+ }
233
+ },
234
+ [
235
+ (0, import_vue3.h)("div", { style: { padding: "12px 16px", borderBottom: "1px solid #f3f4f6" } }, [
236
+ displayName && (0, import_vue3.h)("div", { style: { fontSize: "14px", fontWeight: 600, color: "#111827" } }, displayName),
237
+ email && (0, import_vue3.h)("div", { style: { fontSize: "12px", color: "#6b7280", marginTop: "2px" } }, email)
238
+ ]),
239
+ (0, import_vue3.h)(
240
+ "button",
241
+ {
242
+ onClick: async () => {
243
+ open.value = false;
244
+ await signOut();
245
+ },
246
+ style: {
247
+ display: "block",
248
+ width: "100%",
249
+ padding: "10px 16px",
250
+ textAlign: "left",
251
+ background: "none",
252
+ border: "none",
253
+ cursor: "pointer",
254
+ fontSize: "14px",
255
+ color: "#ef4444",
256
+ fontWeight: 500
257
+ }
258
+ },
259
+ "Sign out"
260
+ )
261
+ ]
262
+ ) : null
263
+ ]);
264
+ };
265
+ }
266
+ });
267
+ var AuthonSignedIn = (0, import_vue3.defineComponent)({
268
+ name: "AuthonSignedIn",
269
+ setup(_, { slots }) {
270
+ const { isSignedIn, isLoading } = useAuthon();
271
+ return () => {
272
+ if (isLoading || !isSignedIn) return null;
273
+ return slots.default?.();
274
+ };
275
+ }
276
+ });
277
+ var AuthonSignedOut = (0, import_vue3.defineComponent)({
278
+ name: "AuthonSignedOut",
279
+ setup(_, { slots }) {
280
+ const { isSignedIn, isLoading } = useAuthon();
281
+ return () => {
282
+ if (isLoading || isSignedIn) return null;
283
+ return slots.default?.();
284
+ };
285
+ }
286
+ });
287
+ // Annotate the CommonJS export names for ESM import in node:
288
+ 0 && (module.exports = {
289
+ AUTHON_KEY,
290
+ AuthonSignIn,
291
+ AuthonSignUp,
292
+ AuthonSignedIn,
293
+ AuthonSignedOut,
294
+ AuthonUserButton,
295
+ createAuthon,
296
+ useAuthon,
297
+ useUser
298
+ });
299
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/plugin.ts","../src/composables.ts","../src/components.ts"],"sourcesContent":["export { createAuthon, AUTHON_KEY } from './plugin';\nexport type { AuthonState, AuthonPluginOptions } from './plugin';\nexport { useAuthon, useUser } from './composables';\nexport {\n AuthonSignIn,\n AuthonSignUp,\n AuthonUserButton,\n AuthonSignedIn,\n AuthonSignedOut,\n} from './components';\n","import type { App } from 'vue';\nimport { reactive } from 'vue';\nimport { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\nexport const AUTHON_KEY = Symbol('authon');\n\nexport interface AuthonState {\n isSignedIn: boolean;\n isLoading: boolean;\n user: AuthonUser | null;\n client: Authon | null;\n}\n\nexport interface AuthonPluginOptions {\n publishableKey: string;\n config?: AuthonConfig;\n}\n\nexport function createAuthon(options: AuthonPluginOptions) {\n const state = reactive<AuthonState>({\n isSignedIn: false,\n isLoading: true,\n user: null,\n client: null,\n });\n\n return {\n install(app: App) {\n const client = new Authon(options.publishableKey, options.config);\n state.client = client as unknown as Authon;\n\n client.on('signedIn', (user) => {\n state.user = user as AuthonUser;\n state.isSignedIn = true;\n state.isLoading = false;\n });\n\n client.on('signedOut', () => {\n state.user = null;\n state.isSignedIn = false;\n });\n\n client.on('error', () => {\n state.isLoading = false;\n });\n\n state.isLoading = false;\n\n app.provide(AUTHON_KEY, state);\n\n app.config.globalProperties.$authon = state;\n },\n };\n}\n","import { inject, computed } from 'vue';\nimport type { ComputedRef } from 'vue';\nimport { AUTHON_KEY } from './plugin';\nimport type { AuthonState } from './plugin';\nimport type { AuthonUser } from '@authon/shared';\n\nfunction requireState(): AuthonState {\n const state = inject<AuthonState>(AUTHON_KEY);\n if (!state) {\n throw new Error('useAuthon() must be called inside a component tree with createAuthon() installed');\n }\n return state;\n}\n\nexport function useAuthon(): AuthonState & {\n signOut: () => Promise<void>;\n openSignIn: () => Promise<void>;\n openSignUp: () => Promise<void>;\n getToken: () => string | null;\n} {\n const s = requireState();\n\n async function signOut(): Promise<void> {\n await s.client?.signOut();\n s.user = null;\n s.isSignedIn = false;\n }\n\n async function openSignIn(): Promise<void> {\n await s.client?.openSignIn();\n }\n\n async function openSignUp(): Promise<void> {\n await s.client?.openSignUp();\n }\n\n function getToken(): string | null {\n return s.client?.getToken() ?? null;\n }\n\n return {\n ...s,\n signOut,\n openSignIn,\n openSignUp,\n getToken,\n };\n}\n\nexport function useUser(): { user: ComputedRef<AuthonUser | null>; isLoading: ComputedRef<boolean> } {\n const s = requireState();\n return {\n user: computed(() => s.user),\n isLoading: computed(() => s.isLoading),\n };\n}\n","import { defineComponent, h, onMounted, ref, computed } from 'vue';\nimport { useAuthon } from './composables';\n\nexport const AuthonSignIn = defineComponent({\n name: 'AuthonSignIn',\n props: {\n mode: {\n type: String as () => 'popup' | 'embedded',\n default: 'popup',\n },\n },\n setup(props) {\n const { client } = useAuthon();\n\n onMounted(() => {\n if (props.mode === 'popup') {\n client?.openSignIn();\n }\n });\n\n return () => {\n if (props.mode === 'embedded') {\n return h('div', { id: 'authon-signin-container' });\n }\n return null;\n };\n },\n});\n\nexport const AuthonSignUp = defineComponent({\n name: 'AuthonSignUp',\n props: {\n mode: {\n type: String as () => 'popup' | 'embedded',\n default: 'popup',\n },\n },\n setup(props) {\n const { client } = useAuthon();\n\n onMounted(() => {\n if (props.mode === 'popup') {\n client?.openSignUp();\n }\n });\n\n return () => {\n if (props.mode === 'embedded') {\n return h('div', { id: 'authon-signup-container' });\n }\n return null;\n };\n },\n});\n\nexport const AuthonUserButton = defineComponent({\n name: 'AuthonUserButton',\n setup() {\n const { user, isSignedIn, signOut, openSignIn } = useAuthon();\n const open = ref(false);\n\n const initials = computed(() => {\n if (!user) return '?';\n const u = user as typeof user;\n if ((u as { displayName?: string | null }).displayName) {\n return ((u as { displayName: string }).displayName)\n .split(' ')\n .map((n: string) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n }\n return ((u as { email?: string | null }).email?.[0] ?? '?').toUpperCase();\n });\n\n return () => {\n if (!isSignedIn) {\n return h(\n 'button',\n {\n onClick: () => openSignIn(),\n style: {\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n background: 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n },\n },\n 'Sign In',\n );\n }\n\n const avatarUrl = (user as { avatarUrl?: string | null } | null)?.avatarUrl;\n const displayName = (user as { displayName?: string | null } | null)?.displayName;\n const email = (user as { email?: string | null } | null)?.email;\n\n return h('div', { style: { position: 'relative', display: 'inline-block' } }, [\n h(\n 'button',\n {\n onClick: () => (open.value = !open.value),\n style: {\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '2px solid #7c3aed',\n background: avatarUrl ? 'transparent' : 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n cursor: 'pointer',\n padding: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '13px',\n fontWeight: 700,\n },\n },\n avatarUrl\n ? [h('img', { src: avatarUrl, alt: displayName ?? 'avatar', style: { width: '100%', height: '100%', objectFit: 'cover' } })]\n : [initials.value],\n ),\n open.value\n ? h(\n 'div',\n {\n style: {\n position: 'absolute',\n right: 0,\n top: '44px',\n minWidth: '200px',\n background: '#fff',\n border: '1px solid #e5e7eb',\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.12)',\n zIndex: 9999,\n overflow: 'hidden',\n },\n },\n [\n h('div', { style: { padding: '12px 16px', borderBottom: '1px solid #f3f4f6' } }, [\n displayName && h('div', { style: { fontSize: '14px', fontWeight: 600, color: '#111827' } }, displayName),\n email && h('div', { style: { fontSize: '12px', color: '#6b7280', marginTop: '2px' } }, email),\n ]),\n h(\n 'button',\n {\n onClick: async () => {\n open.value = false;\n await signOut();\n },\n style: {\n display: 'block',\n width: '100%',\n padding: '10px 16px',\n textAlign: 'left',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n },\n },\n 'Sign out',\n ),\n ],\n )\n : null,\n ]);\n };\n },\n});\n\nexport const AuthonSignedIn = defineComponent({\n name: 'AuthonSignedIn',\n setup(_, { slots }) {\n const { isSignedIn, isLoading } = useAuthon();\n return () => {\n if (isLoading || !isSignedIn) return null;\n return slots.default?.();\n };\n },\n});\n\nexport const AuthonSignedOut = defineComponent({\n name: 'AuthonSignedOut',\n setup(_, { slots }) {\n const { isSignedIn, isLoading } = useAuthon();\n return () => {\n if (isLoading || isSignedIn) return null;\n return slots.default?.();\n };\n },\n});\n"],"mappings":"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","names":["import_vue","import_vue"]}
@@ -0,0 +1,72 @@
1
+ import * as vue from 'vue';
2
+ import { App, ComputedRef } from 'vue';
3
+ import { AuthonConfig, Authon } from '@authon/js';
4
+ import { AuthonUser } from '@authon/shared';
5
+
6
+ declare const AUTHON_KEY: unique symbol;
7
+ interface AuthonState {
8
+ isSignedIn: boolean;
9
+ isLoading: boolean;
10
+ user: AuthonUser | null;
11
+ client: Authon | null;
12
+ }
13
+ interface AuthonPluginOptions {
14
+ publishableKey: string;
15
+ config?: AuthonConfig;
16
+ }
17
+ declare function createAuthon(options: AuthonPluginOptions): {
18
+ install(app: App): void;
19
+ };
20
+
21
+ declare function useAuthon(): AuthonState & {
22
+ signOut: () => Promise<void>;
23
+ openSignIn: () => Promise<void>;
24
+ openSignUp: () => Promise<void>;
25
+ getToken: () => string | null;
26
+ };
27
+ declare function useUser(): {
28
+ user: ComputedRef<AuthonUser | null>;
29
+ isLoading: ComputedRef<boolean>;
30
+ };
31
+
32
+ declare const AuthonSignIn: vue.DefineComponent<vue.ExtractPropTypes<{
33
+ mode: {
34
+ type: () => "popup" | "embedded";
35
+ default: string;
36
+ };
37
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
38
+ [key: string]: any;
39
+ }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
40
+ mode: {
41
+ type: () => "popup" | "embedded";
42
+ default: string;
43
+ };
44
+ }>> & Readonly<{}>, {
45
+ mode: "popup" | "embedded";
46
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
47
+ declare const AuthonSignUp: vue.DefineComponent<vue.ExtractPropTypes<{
48
+ mode: {
49
+ type: () => "popup" | "embedded";
50
+ default: string;
51
+ };
52
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
53
+ [key: string]: any;
54
+ }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
55
+ mode: {
56
+ type: () => "popup" | "embedded";
57
+ default: string;
58
+ };
59
+ }>> & Readonly<{}>, {
60
+ mode: "popup" | "embedded";
61
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
62
+ declare const AuthonUserButton: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
63
+ [key: string]: any;
64
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
65
+ declare const AuthonSignedIn: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
66
+ [key: string]: any;
67
+ }>[] | null | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
68
+ declare const AuthonSignedOut: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
69
+ [key: string]: any;
70
+ }>[] | null | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
71
+
72
+ export { AUTHON_KEY, type AuthonPluginOptions, AuthonSignIn, AuthonSignUp, AuthonSignedIn, AuthonSignedOut, type AuthonState, AuthonUserButton, createAuthon, useAuthon, useUser };
@@ -0,0 +1,72 @@
1
+ import * as vue from 'vue';
2
+ import { App, ComputedRef } from 'vue';
3
+ import { AuthonConfig, Authon } from '@authon/js';
4
+ import { AuthonUser } from '@authon/shared';
5
+
6
+ declare const AUTHON_KEY: unique symbol;
7
+ interface AuthonState {
8
+ isSignedIn: boolean;
9
+ isLoading: boolean;
10
+ user: AuthonUser | null;
11
+ client: Authon | null;
12
+ }
13
+ interface AuthonPluginOptions {
14
+ publishableKey: string;
15
+ config?: AuthonConfig;
16
+ }
17
+ declare function createAuthon(options: AuthonPluginOptions): {
18
+ install(app: App): void;
19
+ };
20
+
21
+ declare function useAuthon(): AuthonState & {
22
+ signOut: () => Promise<void>;
23
+ openSignIn: () => Promise<void>;
24
+ openSignUp: () => Promise<void>;
25
+ getToken: () => string | null;
26
+ };
27
+ declare function useUser(): {
28
+ user: ComputedRef<AuthonUser | null>;
29
+ isLoading: ComputedRef<boolean>;
30
+ };
31
+
32
+ declare const AuthonSignIn: vue.DefineComponent<vue.ExtractPropTypes<{
33
+ mode: {
34
+ type: () => "popup" | "embedded";
35
+ default: string;
36
+ };
37
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
38
+ [key: string]: any;
39
+ }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
40
+ mode: {
41
+ type: () => "popup" | "embedded";
42
+ default: string;
43
+ };
44
+ }>> & Readonly<{}>, {
45
+ mode: "popup" | "embedded";
46
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
47
+ declare const AuthonSignUp: vue.DefineComponent<vue.ExtractPropTypes<{
48
+ mode: {
49
+ type: () => "popup" | "embedded";
50
+ default: string;
51
+ };
52
+ }>, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
53
+ [key: string]: any;
54
+ }> | null, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<vue.ExtractPropTypes<{
55
+ mode: {
56
+ type: () => "popup" | "embedded";
57
+ default: string;
58
+ };
59
+ }>> & Readonly<{}>, {
60
+ mode: "popup" | "embedded";
61
+ }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
62
+ declare const AuthonUserButton: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
63
+ [key: string]: any;
64
+ }>, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
65
+ declare const AuthonSignedIn: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
66
+ [key: string]: any;
67
+ }>[] | null | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
68
+ declare const AuthonSignedOut: vue.DefineComponent<{}, () => vue.VNode<vue.RendererNode, vue.RendererElement, {
69
+ [key: string]: any;
70
+ }>[] | null | undefined, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
71
+
72
+ export { AUTHON_KEY, type AuthonPluginOptions, AuthonSignIn, AuthonSignUp, AuthonSignedIn, AuthonSignedOut, type AuthonState, AuthonUserButton, createAuthon, useAuthon, useUser };
package/dist/index.js ADDED
@@ -0,0 +1,264 @@
1
+ // src/plugin.ts
2
+ import { reactive } from "vue";
3
+ import { Authon } from "@authon/js";
4
+ var AUTHON_KEY = /* @__PURE__ */ Symbol("authon");
5
+ function createAuthon(options) {
6
+ const state = reactive({
7
+ isSignedIn: false,
8
+ isLoading: true,
9
+ user: null,
10
+ client: null
11
+ });
12
+ return {
13
+ install(app) {
14
+ const client = new Authon(options.publishableKey, options.config);
15
+ state.client = client;
16
+ client.on("signedIn", (user) => {
17
+ state.user = user;
18
+ state.isSignedIn = true;
19
+ state.isLoading = false;
20
+ });
21
+ client.on("signedOut", () => {
22
+ state.user = null;
23
+ state.isSignedIn = false;
24
+ });
25
+ client.on("error", () => {
26
+ state.isLoading = false;
27
+ });
28
+ state.isLoading = false;
29
+ app.provide(AUTHON_KEY, state);
30
+ app.config.globalProperties.$authon = state;
31
+ }
32
+ };
33
+ }
34
+
35
+ // src/composables.ts
36
+ import { inject, computed } from "vue";
37
+ function requireState() {
38
+ const state = inject(AUTHON_KEY);
39
+ if (!state) {
40
+ throw new Error("useAuthon() must be called inside a component tree with createAuthon() installed");
41
+ }
42
+ return state;
43
+ }
44
+ function useAuthon() {
45
+ const s = requireState();
46
+ async function signOut() {
47
+ await s.client?.signOut();
48
+ s.user = null;
49
+ s.isSignedIn = false;
50
+ }
51
+ async function openSignIn() {
52
+ await s.client?.openSignIn();
53
+ }
54
+ async function openSignUp() {
55
+ await s.client?.openSignUp();
56
+ }
57
+ function getToken() {
58
+ return s.client?.getToken() ?? null;
59
+ }
60
+ return {
61
+ ...s,
62
+ signOut,
63
+ openSignIn,
64
+ openSignUp,
65
+ getToken
66
+ };
67
+ }
68
+ function useUser() {
69
+ const s = requireState();
70
+ return {
71
+ user: computed(() => s.user),
72
+ isLoading: computed(() => s.isLoading)
73
+ };
74
+ }
75
+
76
+ // src/components.ts
77
+ import { defineComponent, h, onMounted, ref, computed as computed2 } from "vue";
78
+ var AuthonSignIn = defineComponent({
79
+ name: "AuthonSignIn",
80
+ props: {
81
+ mode: {
82
+ type: String,
83
+ default: "popup"
84
+ }
85
+ },
86
+ setup(props) {
87
+ const { client } = useAuthon();
88
+ onMounted(() => {
89
+ if (props.mode === "popup") {
90
+ client?.openSignIn();
91
+ }
92
+ });
93
+ return () => {
94
+ if (props.mode === "embedded") {
95
+ return h("div", { id: "authon-signin-container" });
96
+ }
97
+ return null;
98
+ };
99
+ }
100
+ });
101
+ var AuthonSignUp = defineComponent({
102
+ name: "AuthonSignUp",
103
+ props: {
104
+ mode: {
105
+ type: String,
106
+ default: "popup"
107
+ }
108
+ },
109
+ setup(props) {
110
+ const { client } = useAuthon();
111
+ onMounted(() => {
112
+ if (props.mode === "popup") {
113
+ client?.openSignUp();
114
+ }
115
+ });
116
+ return () => {
117
+ if (props.mode === "embedded") {
118
+ return h("div", { id: "authon-signup-container" });
119
+ }
120
+ return null;
121
+ };
122
+ }
123
+ });
124
+ var AuthonUserButton = defineComponent({
125
+ name: "AuthonUserButton",
126
+ setup() {
127
+ const { user, isSignedIn, signOut, openSignIn } = useAuthon();
128
+ const open = ref(false);
129
+ const initials = computed2(() => {
130
+ if (!user) return "?";
131
+ const u = user;
132
+ if (u.displayName) {
133
+ return u.displayName.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
134
+ }
135
+ return (u.email?.[0] ?? "?").toUpperCase();
136
+ });
137
+ return () => {
138
+ if (!isSignedIn) {
139
+ return h(
140
+ "button",
141
+ {
142
+ onClick: () => openSignIn(),
143
+ style: {
144
+ padding: "8px 16px",
145
+ borderRadius: "8px",
146
+ border: "none",
147
+ background: "linear-gradient(135deg, #7c3aed, #4f46e5)",
148
+ color: "#fff",
149
+ cursor: "pointer",
150
+ fontSize: "14px",
151
+ fontWeight: 600
152
+ }
153
+ },
154
+ "Sign In"
155
+ );
156
+ }
157
+ const avatarUrl = user?.avatarUrl;
158
+ const displayName = user?.displayName;
159
+ const email = user?.email;
160
+ return h("div", { style: { position: "relative", display: "inline-block" } }, [
161
+ h(
162
+ "button",
163
+ {
164
+ onClick: () => open.value = !open.value,
165
+ style: {
166
+ width: "36px",
167
+ height: "36px",
168
+ borderRadius: "50%",
169
+ border: "2px solid #7c3aed",
170
+ background: avatarUrl ? "transparent" : "linear-gradient(135deg, #7c3aed, #4f46e5)",
171
+ cursor: "pointer",
172
+ padding: 0,
173
+ overflow: "hidden",
174
+ display: "flex",
175
+ alignItems: "center",
176
+ justifyContent: "center",
177
+ color: "#fff",
178
+ fontSize: "13px",
179
+ fontWeight: 700
180
+ }
181
+ },
182
+ avatarUrl ? [h("img", { src: avatarUrl, alt: displayName ?? "avatar", style: { width: "100%", height: "100%", objectFit: "cover" } })] : [initials.value]
183
+ ),
184
+ open.value ? h(
185
+ "div",
186
+ {
187
+ style: {
188
+ position: "absolute",
189
+ right: 0,
190
+ top: "44px",
191
+ minWidth: "200px",
192
+ background: "#fff",
193
+ border: "1px solid #e5e7eb",
194
+ borderRadius: "12px",
195
+ boxShadow: "0 8px 24px rgba(0,0,0,0.12)",
196
+ zIndex: 9999,
197
+ overflow: "hidden"
198
+ }
199
+ },
200
+ [
201
+ h("div", { style: { padding: "12px 16px", borderBottom: "1px solid #f3f4f6" } }, [
202
+ displayName && h("div", { style: { fontSize: "14px", fontWeight: 600, color: "#111827" } }, displayName),
203
+ email && h("div", { style: { fontSize: "12px", color: "#6b7280", marginTop: "2px" } }, email)
204
+ ]),
205
+ h(
206
+ "button",
207
+ {
208
+ onClick: async () => {
209
+ open.value = false;
210
+ await signOut();
211
+ },
212
+ style: {
213
+ display: "block",
214
+ width: "100%",
215
+ padding: "10px 16px",
216
+ textAlign: "left",
217
+ background: "none",
218
+ border: "none",
219
+ cursor: "pointer",
220
+ fontSize: "14px",
221
+ color: "#ef4444",
222
+ fontWeight: 500
223
+ }
224
+ },
225
+ "Sign out"
226
+ )
227
+ ]
228
+ ) : null
229
+ ]);
230
+ };
231
+ }
232
+ });
233
+ var AuthonSignedIn = defineComponent({
234
+ name: "AuthonSignedIn",
235
+ setup(_, { slots }) {
236
+ const { isSignedIn, isLoading } = useAuthon();
237
+ return () => {
238
+ if (isLoading || !isSignedIn) return null;
239
+ return slots.default?.();
240
+ };
241
+ }
242
+ });
243
+ var AuthonSignedOut = defineComponent({
244
+ name: "AuthonSignedOut",
245
+ setup(_, { slots }) {
246
+ const { isSignedIn, isLoading } = useAuthon();
247
+ return () => {
248
+ if (isLoading || isSignedIn) return null;
249
+ return slots.default?.();
250
+ };
251
+ }
252
+ });
253
+ export {
254
+ AUTHON_KEY,
255
+ AuthonSignIn,
256
+ AuthonSignUp,
257
+ AuthonSignedIn,
258
+ AuthonSignedOut,
259
+ AuthonUserButton,
260
+ createAuthon,
261
+ useAuthon,
262
+ useUser
263
+ };
264
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugin.ts","../src/composables.ts","../src/components.ts"],"sourcesContent":["import type { App } from 'vue';\nimport { reactive } from 'vue';\nimport { Authon } from '@authon/js';\nimport type { AuthonConfig } from '@authon/js';\nimport type { AuthonUser } from '@authon/shared';\n\nexport const AUTHON_KEY = Symbol('authon');\n\nexport interface AuthonState {\n isSignedIn: boolean;\n isLoading: boolean;\n user: AuthonUser | null;\n client: Authon | null;\n}\n\nexport interface AuthonPluginOptions {\n publishableKey: string;\n config?: AuthonConfig;\n}\n\nexport function createAuthon(options: AuthonPluginOptions) {\n const state = reactive<AuthonState>({\n isSignedIn: false,\n isLoading: true,\n user: null,\n client: null,\n });\n\n return {\n install(app: App) {\n const client = new Authon(options.publishableKey, options.config);\n state.client = client as unknown as Authon;\n\n client.on('signedIn', (user) => {\n state.user = user as AuthonUser;\n state.isSignedIn = true;\n state.isLoading = false;\n });\n\n client.on('signedOut', () => {\n state.user = null;\n state.isSignedIn = false;\n });\n\n client.on('error', () => {\n state.isLoading = false;\n });\n\n state.isLoading = false;\n\n app.provide(AUTHON_KEY, state);\n\n app.config.globalProperties.$authon = state;\n },\n };\n}\n","import { inject, computed } from 'vue';\nimport type { ComputedRef } from 'vue';\nimport { AUTHON_KEY } from './plugin';\nimport type { AuthonState } from './plugin';\nimport type { AuthonUser } from '@authon/shared';\n\nfunction requireState(): AuthonState {\n const state = inject<AuthonState>(AUTHON_KEY);\n if (!state) {\n throw new Error('useAuthon() must be called inside a component tree with createAuthon() installed');\n }\n return state;\n}\n\nexport function useAuthon(): AuthonState & {\n signOut: () => Promise<void>;\n openSignIn: () => Promise<void>;\n openSignUp: () => Promise<void>;\n getToken: () => string | null;\n} {\n const s = requireState();\n\n async function signOut(): Promise<void> {\n await s.client?.signOut();\n s.user = null;\n s.isSignedIn = false;\n }\n\n async function openSignIn(): Promise<void> {\n await s.client?.openSignIn();\n }\n\n async function openSignUp(): Promise<void> {\n await s.client?.openSignUp();\n }\n\n function getToken(): string | null {\n return s.client?.getToken() ?? null;\n }\n\n return {\n ...s,\n signOut,\n openSignIn,\n openSignUp,\n getToken,\n };\n}\n\nexport function useUser(): { user: ComputedRef<AuthonUser | null>; isLoading: ComputedRef<boolean> } {\n const s = requireState();\n return {\n user: computed(() => s.user),\n isLoading: computed(() => s.isLoading),\n };\n}\n","import { defineComponent, h, onMounted, ref, computed } from 'vue';\nimport { useAuthon } from './composables';\n\nexport const AuthonSignIn = defineComponent({\n name: 'AuthonSignIn',\n props: {\n mode: {\n type: String as () => 'popup' | 'embedded',\n default: 'popup',\n },\n },\n setup(props) {\n const { client } = useAuthon();\n\n onMounted(() => {\n if (props.mode === 'popup') {\n client?.openSignIn();\n }\n });\n\n return () => {\n if (props.mode === 'embedded') {\n return h('div', { id: 'authon-signin-container' });\n }\n return null;\n };\n },\n});\n\nexport const AuthonSignUp = defineComponent({\n name: 'AuthonSignUp',\n props: {\n mode: {\n type: String as () => 'popup' | 'embedded',\n default: 'popup',\n },\n },\n setup(props) {\n const { client } = useAuthon();\n\n onMounted(() => {\n if (props.mode === 'popup') {\n client?.openSignUp();\n }\n });\n\n return () => {\n if (props.mode === 'embedded') {\n return h('div', { id: 'authon-signup-container' });\n }\n return null;\n };\n },\n});\n\nexport const AuthonUserButton = defineComponent({\n name: 'AuthonUserButton',\n setup() {\n const { user, isSignedIn, signOut, openSignIn } = useAuthon();\n const open = ref(false);\n\n const initials = computed(() => {\n if (!user) return '?';\n const u = user as typeof user;\n if ((u as { displayName?: string | null }).displayName) {\n return ((u as { displayName: string }).displayName)\n .split(' ')\n .map((n: string) => n[0])\n .join('')\n .toUpperCase()\n .slice(0, 2);\n }\n return ((u as { email?: string | null }).email?.[0] ?? '?').toUpperCase();\n });\n\n return () => {\n if (!isSignedIn) {\n return h(\n 'button',\n {\n onClick: () => openSignIn(),\n style: {\n padding: '8px 16px',\n borderRadius: '8px',\n border: 'none',\n background: 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n color: '#fff',\n cursor: 'pointer',\n fontSize: '14px',\n fontWeight: 600,\n },\n },\n 'Sign In',\n );\n }\n\n const avatarUrl = (user as { avatarUrl?: string | null } | null)?.avatarUrl;\n const displayName = (user as { displayName?: string | null } | null)?.displayName;\n const email = (user as { email?: string | null } | null)?.email;\n\n return h('div', { style: { position: 'relative', display: 'inline-block' } }, [\n h(\n 'button',\n {\n onClick: () => (open.value = !open.value),\n style: {\n width: '36px',\n height: '36px',\n borderRadius: '50%',\n border: '2px solid #7c3aed',\n background: avatarUrl ? 'transparent' : 'linear-gradient(135deg, #7c3aed, #4f46e5)',\n cursor: 'pointer',\n padding: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: '#fff',\n fontSize: '13px',\n fontWeight: 700,\n },\n },\n avatarUrl\n ? [h('img', { src: avatarUrl, alt: displayName ?? 'avatar', style: { width: '100%', height: '100%', objectFit: 'cover' } })]\n : [initials.value],\n ),\n open.value\n ? h(\n 'div',\n {\n style: {\n position: 'absolute',\n right: 0,\n top: '44px',\n minWidth: '200px',\n background: '#fff',\n border: '1px solid #e5e7eb',\n borderRadius: '12px',\n boxShadow: '0 8px 24px rgba(0,0,0,0.12)',\n zIndex: 9999,\n overflow: 'hidden',\n },\n },\n [\n h('div', { style: { padding: '12px 16px', borderBottom: '1px solid #f3f4f6' } }, [\n displayName && h('div', { style: { fontSize: '14px', fontWeight: 600, color: '#111827' } }, displayName),\n email && h('div', { style: { fontSize: '12px', color: '#6b7280', marginTop: '2px' } }, email),\n ]),\n h(\n 'button',\n {\n onClick: async () => {\n open.value = false;\n await signOut();\n },\n style: {\n display: 'block',\n width: '100%',\n padding: '10px 16px',\n textAlign: 'left',\n background: 'none',\n border: 'none',\n cursor: 'pointer',\n fontSize: '14px',\n color: '#ef4444',\n fontWeight: 500,\n },\n },\n 'Sign out',\n ),\n ],\n )\n : null,\n ]);\n };\n },\n});\n\nexport const AuthonSignedIn = defineComponent({\n name: 'AuthonSignedIn',\n setup(_, { slots }) {\n const { isSignedIn, isLoading } = useAuthon();\n return () => {\n if (isLoading || !isSignedIn) return null;\n return slots.default?.();\n };\n },\n});\n\nexport const AuthonSignedOut = defineComponent({\n name: 'AuthonSignedOut',\n setup(_, { slots }) {\n const { isSignedIn, isLoading } = useAuthon();\n return () => {\n if (isLoading || isSignedIn) return null;\n return slots.default?.();\n };\n },\n});\n"],"mappings":"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","names":["computed","computed"]}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@authon/vue",
3
+ "version": "0.1.0",
4
+ "description": "Authon Vue 3 SDK — plugin, composables, and components",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": ["dist"],
17
+ "scripts": {
18
+ "build": "tsup",
19
+ "dev": "tsup --watch"
20
+ },
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/mikusnuz/authon-sdk.git",
25
+ "directory": "packages/vue"
26
+ },
27
+ "homepage": "https://github.com/mikusnuz/authon-sdk/tree/main/packages/vue",
28
+ "publishConfig": { "access": "public" },
29
+ "keywords": ["authon", "auth", "vue", "composables", "sdk"],
30
+ "dependencies": {
31
+ "@authon/js": "workspace:*",
32
+ "@authon/shared": "workspace:*"
33
+ },
34
+ "peerDependencies": {
35
+ "vue": "^3.3.0"
36
+ },
37
+ "devDependencies": {
38
+ "vue": "^3.5.0",
39
+ "tsup": "^8.0.0",
40
+ "typescript": "^5.9.3"
41
+ }
42
+ }