@contentgrowth/content-auth 0.4.9 → 0.5.1
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 +68 -2
- package/dist/{chunk-CTASTCWI.js → chunk-3HNFZJ7S.js} +6 -6
- package/dist/chunk-CBNSTIX6.js +17 -0
- package/dist/chunk-F2G7XJIZ.js +17 -0
- package/dist/frontend/astro.d.ts +6 -0
- package/dist/frontend/astro.js +9 -0
- package/dist/frontend/client.d.ts +54 -18
- package/dist/frontend/clients/astro-client.d.ts +3134 -0
- package/dist/frontend/clients/astro-client.js +9 -0
- package/dist/frontend/clients/vue-client.d.ts +3520 -0
- package/dist/frontend/clients/vue-client.js +9 -0
- package/dist/frontend/components/astro/AuthForm.astro +389 -0
- package/dist/frontend/components/astro/ForgotPasswordForm.astro +127 -0
- package/dist/frontend/components/astro/Organization.astro +254 -0
- package/dist/frontend/components/astro/PasswordChanger.astro +128 -0
- package/dist/frontend/components/astro/ProfileEditor.astro +133 -0
- package/dist/frontend/components/astro/ResetPasswordForm.astro +172 -0
- package/dist/frontend/components/vue/AuthForm.vue +337 -0
- package/dist/frontend/components/vue/ForgotPasswordForm.vue +108 -0
- package/dist/frontend/components/vue/Organization.vue +215 -0
- package/dist/frontend/components/vue/PasswordChanger.vue +115 -0
- package/dist/frontend/components/vue/ProfileEditor.vue +112 -0
- package/dist/frontend/components/vue/ResetPasswordForm.vue +150 -0
- package/dist/frontend/index.js +1 -1
- package/dist/frontend/vue.d.ts +12 -0
- package/dist/frontend/vue.js +23 -0
- package/dist/index.js +1 -1
- package/package.json +31 -5
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed } from 'vue';
|
|
3
|
+
import { createClient } from '../../clients/vue-client';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
11
|
+
className: '',
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const emit = defineEmits<{
|
|
15
|
+
(e: 'success', data?: any): void;
|
|
16
|
+
(e: 'error', error: string): void;
|
|
17
|
+
}>();
|
|
18
|
+
|
|
19
|
+
const client = computed(() => createClient(props.baseUrl));
|
|
20
|
+
|
|
21
|
+
const currentPassword = ref('');
|
|
22
|
+
const newPassword = ref('');
|
|
23
|
+
const confirmPassword = ref('');
|
|
24
|
+
const loading = ref(false);
|
|
25
|
+
const error = ref<string | null>(null);
|
|
26
|
+
const success = ref(false);
|
|
27
|
+
|
|
28
|
+
const handleSubmit = async () => {
|
|
29
|
+
if (newPassword.value !== confirmPassword.value) {
|
|
30
|
+
error.value = "New passwords don't match";
|
|
31
|
+
emit('error', error.value);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
loading.value = true;
|
|
36
|
+
error.value = null;
|
|
37
|
+
success.value = false;
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
const res = await client.value.changePassword({
|
|
41
|
+
currentPassword: currentPassword.value,
|
|
42
|
+
newPassword: newPassword.value
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (res?.error) {
|
|
46
|
+
throw new Error(res.error.message);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Clear form on success
|
|
50
|
+
currentPassword.value = '';
|
|
51
|
+
newPassword.value = '';
|
|
52
|
+
confirmPassword.value = '';
|
|
53
|
+
success.value = true;
|
|
54
|
+
|
|
55
|
+
emit('success', res?.data);
|
|
56
|
+
} catch (err: any) {
|
|
57
|
+
if (err?.code === 'CREDENTIAL_ACCOUNT_NOT_FOUND' || err?.message?.includes('Credential account not found')) {
|
|
58
|
+
error.value = "You are logged in via a social provider (e.g. GitHub, Google) and do not have a password set.";
|
|
59
|
+
} else {
|
|
60
|
+
error.value = err.message || 'Failed to change password';
|
|
61
|
+
}
|
|
62
|
+
emit('error', error.value);
|
|
63
|
+
} finally {
|
|
64
|
+
loading.value = false;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<template>
|
|
70
|
+
<form :class="`ca-form ${className}`" @submit.prevent="handleSubmit">
|
|
71
|
+
<div class="ca-input-group">
|
|
72
|
+
<label class="ca-label" for="current-password">Current Password</label>
|
|
73
|
+
<input
|
|
74
|
+
id="current-password"
|
|
75
|
+
v-model="currentPassword"
|
|
76
|
+
type="password"
|
|
77
|
+
class="ca-input"
|
|
78
|
+
required
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<div class="ca-input-group">
|
|
83
|
+
<label class="ca-label" for="new-password">New Password</label>
|
|
84
|
+
<input
|
|
85
|
+
id="new-password"
|
|
86
|
+
v-model="newPassword"
|
|
87
|
+
type="password"
|
|
88
|
+
class="ca-input"
|
|
89
|
+
minlength="8"
|
|
90
|
+
required
|
|
91
|
+
/>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="ca-input-group">
|
|
95
|
+
<label class="ca-label" for="confirm-password">Confirm New Password</label>
|
|
96
|
+
<input
|
|
97
|
+
id="confirm-password"
|
|
98
|
+
v-model="confirmPassword"
|
|
99
|
+
type="password"
|
|
100
|
+
class="ca-input"
|
|
101
|
+
minlength="8"
|
|
102
|
+
required
|
|
103
|
+
/>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div v-if="error" class="ca-error">{{ error }}</div>
|
|
107
|
+
<div v-if="success" class="ca-success-message" style="padding: 0.75rem; background: #d1fae5; border-radius: 6px; color: #065f46; text-align: center;">
|
|
108
|
+
Password updated successfully!
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<button type="submit" class="ca-button" :disabled="loading">
|
|
112
|
+
{{ loading ? 'Updating...' : 'Update Password' }}
|
|
113
|
+
</button>
|
|
114
|
+
</form>
|
|
115
|
+
</template>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed, watch } from 'vue';
|
|
3
|
+
import { createClient } from '../../clients/vue-client';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
defaultName?: string;
|
|
8
|
+
defaultImage?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
13
|
+
defaultName: '',
|
|
14
|
+
defaultImage: '',
|
|
15
|
+
className: '',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
(e: 'success', data?: any): void;
|
|
20
|
+
(e: 'error', error: string): void;
|
|
21
|
+
}>();
|
|
22
|
+
|
|
23
|
+
const client = computed(() => createClient(props.baseUrl));
|
|
24
|
+
|
|
25
|
+
const name = ref(props.defaultName);
|
|
26
|
+
const image = ref(props.defaultImage);
|
|
27
|
+
const loading = ref(false);
|
|
28
|
+
const error = ref<string | null>(null);
|
|
29
|
+
const success = ref(false);
|
|
30
|
+
const imageError = ref(false);
|
|
31
|
+
|
|
32
|
+
watch(() => props.defaultName, (val) => { if (val) name.value = val; });
|
|
33
|
+
watch(() => props.defaultImage, (val) => { if (val) image.value = val; });
|
|
34
|
+
|
|
35
|
+
const handleSubmit = async () => {
|
|
36
|
+
loading.value = true;
|
|
37
|
+
error.value = null;
|
|
38
|
+
success.value = false;
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await client.value.updateUser({
|
|
42
|
+
name: name.value,
|
|
43
|
+
image: image.value
|
|
44
|
+
});
|
|
45
|
+
success.value = true;
|
|
46
|
+
emit('success');
|
|
47
|
+
} catch (err: any) {
|
|
48
|
+
error.value = err.message || 'Failed to update profile';
|
|
49
|
+
emit('error', error.value);
|
|
50
|
+
} finally {
|
|
51
|
+
loading.value = false;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const handleImageError = () => {
|
|
56
|
+
imageError.value = true;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const handleImageInput = () => {
|
|
60
|
+
imageError.value = false;
|
|
61
|
+
};
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<template>
|
|
65
|
+
<form :class="`ca-form ${className}`" @submit.prevent="handleSubmit">
|
|
66
|
+
<div class="ca-input-group">
|
|
67
|
+
<label class="ca-label" for="profile-name">Name</label>
|
|
68
|
+
<input
|
|
69
|
+
id="profile-name"
|
|
70
|
+
v-model="name"
|
|
71
|
+
type="text"
|
|
72
|
+
class="ca-input"
|
|
73
|
+
placeholder="Your Name"
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
<div class="ca-input-group">
|
|
78
|
+
<label class="ca-label" for="profile-image">Avatar URL</label>
|
|
79
|
+
<div style="display: flex; gap: 10px; align-items: center;">
|
|
80
|
+
<input
|
|
81
|
+
id="profile-image"
|
|
82
|
+
v-model="image"
|
|
83
|
+
type="url"
|
|
84
|
+
class="ca-input"
|
|
85
|
+
placeholder="https://example.com/avatar.jpg"
|
|
86
|
+
style="flex: 1;"
|
|
87
|
+
@input="handleImageInput"
|
|
88
|
+
/>
|
|
89
|
+
<div
|
|
90
|
+
v-if="image && !imageError"
|
|
91
|
+
style="width: 40px; height: 40px; border-radius: 50%; overflow: hidden; flex-shrink: 0; border: 1px solid #eee;"
|
|
92
|
+
>
|
|
93
|
+
<img
|
|
94
|
+
:src="image"
|
|
95
|
+
alt="Preview"
|
|
96
|
+
style="width: 100%; height: 100%; object-fit: cover;"
|
|
97
|
+
@error="handleImageError"
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div v-if="error" class="ca-error">{{ error }}</div>
|
|
104
|
+
<div v-if="success" class="ca-success-message" style="padding: 0.75rem; background: #d1fae5; border-radius: 6px; color: #065f46; text-align: center;">
|
|
105
|
+
Profile updated successfully!
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<button type="submit" class="ca-button" :disabled="loading">
|
|
109
|
+
{{ loading ? 'Saving...' : 'Save Profile' }}
|
|
110
|
+
</button>
|
|
111
|
+
</form>
|
|
112
|
+
</template>
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref, computed } from 'vue';
|
|
3
|
+
import { createClient } from '../../clients/vue-client';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
token?: string | null;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
backToLoginUrl?: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
width?: 'default' | 'compact' | 'wide';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
14
|
+
title: 'Set New Password',
|
|
15
|
+
width: 'default',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const emit = defineEmits<{
|
|
19
|
+
(e: 'success'): void;
|
|
20
|
+
(e: 'error', error: string): void;
|
|
21
|
+
}>();
|
|
22
|
+
|
|
23
|
+
const client = computed(() => createClient(props.baseUrl));
|
|
24
|
+
|
|
25
|
+
const password = ref('');
|
|
26
|
+
const confirmPassword = ref('');
|
|
27
|
+
const loading = ref(false);
|
|
28
|
+
const error = ref<string | null>(null);
|
|
29
|
+
const success = ref(false);
|
|
30
|
+
|
|
31
|
+
const widthClass = computed(() => {
|
|
32
|
+
if (props.width === 'compact') return 'ca-width-compact';
|
|
33
|
+
if (props.width === 'wide') return 'ca-width-wide';
|
|
34
|
+
return 'ca-width-default';
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const hasToken = computed(() => !!props.token);
|
|
38
|
+
|
|
39
|
+
const handleSubmit = async () => {
|
|
40
|
+
if (password.value !== confirmPassword.value) {
|
|
41
|
+
error.value = 'Passwords do not match';
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (password.value.length < 8) {
|
|
46
|
+
error.value = 'Password must be at least 8 characters';
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
loading.value = true;
|
|
51
|
+
error.value = null;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const { error: err } = await client.value.resetPassword({
|
|
55
|
+
token: props.token!,
|
|
56
|
+
newPassword: password.value
|
|
57
|
+
});
|
|
58
|
+
if (err) throw err;
|
|
59
|
+
success.value = true;
|
|
60
|
+
emit('success');
|
|
61
|
+
} catch (err: any) {
|
|
62
|
+
error.value = err.message || 'Failed to reset password';
|
|
63
|
+
emit('error', error.value);
|
|
64
|
+
} finally {
|
|
65
|
+
loading.value = false;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<template>
|
|
71
|
+
<div :class="`ca-container ${widthClass}`">
|
|
72
|
+
<h2 class="ca-title">{{ title }}</h2>
|
|
73
|
+
|
|
74
|
+
<!-- Missing Token State -->
|
|
75
|
+
<template v-if="!hasToken">
|
|
76
|
+
<div class="ca-error-message">
|
|
77
|
+
<svg class="ca-error-icon" viewBox="0 0 24 24" width="48" height="48">
|
|
78
|
+
<circle cx="12" cy="12" r="10" fill="#EF4444" />
|
|
79
|
+
<path d="M12 8v4M12 16h.01" stroke="white" stroke-width="2" stroke-linecap="round" />
|
|
80
|
+
</svg>
|
|
81
|
+
<h3 class="ca-error-title">Invalid or Missing Token</h3>
|
|
82
|
+
<p class="ca-error-text">
|
|
83
|
+
The password reset link is invalid or has expired.
|
|
84
|
+
Please request a new password reset.
|
|
85
|
+
</p>
|
|
86
|
+
</div>
|
|
87
|
+
<div v-if="backToLoginUrl" class="ca-footer">
|
|
88
|
+
<a :href="backToLoginUrl" class="ca-link">Back to Sign In</a>
|
|
89
|
+
</div>
|
|
90
|
+
</template>
|
|
91
|
+
|
|
92
|
+
<!-- Success State -->
|
|
93
|
+
<template v-else-if="success">
|
|
94
|
+
<div class="ca-success-message">
|
|
95
|
+
<svg class="ca-success-icon" viewBox="0 0 24 24" width="48" height="48">
|
|
96
|
+
<circle cx="12" cy="12" r="10" fill="#10B981" />
|
|
97
|
+
<path d="M8 12l2.5 2.5L16 9" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round" />
|
|
98
|
+
</svg>
|
|
99
|
+
<h3 class="ca-success-title">Password Reset Successful</h3>
|
|
100
|
+
<p class="ca-success-text">
|
|
101
|
+
Your password has been successfully reset. You can now sign in with your new password.
|
|
102
|
+
</p>
|
|
103
|
+
</div>
|
|
104
|
+
<div v-if="backToLoginUrl" class="ca-footer">
|
|
105
|
+
<a :href="backToLoginUrl" class="ca-link">Sign In</a>
|
|
106
|
+
</div>
|
|
107
|
+
</template>
|
|
108
|
+
|
|
109
|
+
<!-- Form State -->
|
|
110
|
+
<template v-else>
|
|
111
|
+
<p class="ca-subtitle">Enter your new password below.</p>
|
|
112
|
+
<form class="ca-form" @submit.prevent="handleSubmit">
|
|
113
|
+
<div class="ca-input-group">
|
|
114
|
+
<label class="ca-label" for="password">New Password</label>
|
|
115
|
+
<input
|
|
116
|
+
id="password"
|
|
117
|
+
v-model="password"
|
|
118
|
+
type="password"
|
|
119
|
+
class="ca-input"
|
|
120
|
+
placeholder="At least 8 characters"
|
|
121
|
+
minlength="8"
|
|
122
|
+
required
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<div class="ca-input-group">
|
|
127
|
+
<label class="ca-label" for="confirmPassword">Confirm Password</label>
|
|
128
|
+
<input
|
|
129
|
+
id="confirmPassword"
|
|
130
|
+
v-model="confirmPassword"
|
|
131
|
+
type="password"
|
|
132
|
+
class="ca-input"
|
|
133
|
+
placeholder="Confirm your password"
|
|
134
|
+
required
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div v-if="error" class="ca-error">{{ error }}</div>
|
|
139
|
+
|
|
140
|
+
<button type="submit" class="ca-button" :disabled="loading">
|
|
141
|
+
{{ loading ? 'Resetting...' : 'Reset Password' }}
|
|
142
|
+
</button>
|
|
143
|
+
</form>
|
|
144
|
+
|
|
145
|
+
<div v-if="backToLoginUrl" class="ca-footer">
|
|
146
|
+
<a :href="backToLoginUrl" class="ca-link">Back to Sign In</a>
|
|
147
|
+
</div>
|
|
148
|
+
</template>
|
|
149
|
+
</div>
|
|
150
|
+
</template>
|
package/dist/frontend/index.js
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { default as AuthForm } from './components/vue/AuthForm.vue';
|
|
2
|
+
export { default as ForgotPasswordForm } from './components/vue/ForgotPasswordForm.vue';
|
|
3
|
+
export { default as ResetPasswordForm } from './components/vue/ResetPasswordForm.vue';
|
|
4
|
+
export { default as PasswordChanger } from './components/vue/PasswordChanger.vue';
|
|
5
|
+
export { default as ProfileEditor } from './components/vue/ProfileEditor.vue';
|
|
6
|
+
export { default as Organization } from './components/vue/Organization.vue';
|
|
7
|
+
export { authClient, createClient } from './clients/vue-client.js';
|
|
8
|
+
import 'nanostores';
|
|
9
|
+
import 'vue';
|
|
10
|
+
import 'better-auth';
|
|
11
|
+
import '@better-fetch/fetch';
|
|
12
|
+
import 'better-auth/plugins';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
authClient,
|
|
3
|
+
createClient
|
|
4
|
+
} from "../chunk-F2G7XJIZ.js";
|
|
5
|
+
import "../chunk-R5U7XKVJ.js";
|
|
6
|
+
|
|
7
|
+
// src/frontend/vue.ts
|
|
8
|
+
import { default as default2 } from "./components/vue/AuthForm.vue";
|
|
9
|
+
import { default as default3 } from "./components/vue/ForgotPasswordForm.vue";
|
|
10
|
+
import { default as default4 } from "./components/vue/ResetPasswordForm.vue";
|
|
11
|
+
import { default as default5 } from "./components/vue/PasswordChanger.vue";
|
|
12
|
+
import { default as default6 } from "./components/vue/ProfileEditor.vue";
|
|
13
|
+
import { default as default7 } from "./components/vue/Organization.vue";
|
|
14
|
+
export {
|
|
15
|
+
default2 as AuthForm,
|
|
16
|
+
default3 as ForgotPasswordForm,
|
|
17
|
+
default7 as Organization,
|
|
18
|
+
default5 as PasswordChanger,
|
|
19
|
+
default6 as ProfileEditor,
|
|
20
|
+
default4 as ResetPasswordForm,
|
|
21
|
+
authClient,
|
|
22
|
+
createClient
|
|
23
|
+
};
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentgrowth/content-auth",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Better Auth wrapper with UI components for Cloudflare Workers & Pages. Includes custom schema mapping, Turnstile bot protection, and email normalization.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,6 +26,24 @@
|
|
|
26
26
|
"types": "./dist/frontend/client.d.ts",
|
|
27
27
|
"import": "./dist/frontend/client.js"
|
|
28
28
|
},
|
|
29
|
+
"./astro": {
|
|
30
|
+
"types": "./dist/frontend/astro.d.ts",
|
|
31
|
+
"import": "./dist/frontend/astro.js"
|
|
32
|
+
},
|
|
33
|
+
"./astro/client": {
|
|
34
|
+
"types": "./dist/frontend/clients/astro-client.d.ts",
|
|
35
|
+
"import": "./dist/frontend/clients/astro-client.js"
|
|
36
|
+
},
|
|
37
|
+
"./vue": {
|
|
38
|
+
"types": "./dist/frontend/vue.d.ts",
|
|
39
|
+
"import": "./dist/frontend/vue.js"
|
|
40
|
+
},
|
|
41
|
+
"./vue/client": {
|
|
42
|
+
"types": "./dist/frontend/clients/vue-client.d.ts",
|
|
43
|
+
"import": "./dist/frontend/clients/vue-client.js"
|
|
44
|
+
},
|
|
45
|
+
"./astro/components/*": "./dist/frontend/components/astro/*",
|
|
46
|
+
"./vue/components/*": "./dist/frontend/components/vue/*",
|
|
29
47
|
"./styles.css": "./dist/styles.css"
|
|
30
48
|
},
|
|
31
49
|
"files": [
|
|
@@ -35,7 +53,7 @@
|
|
|
35
53
|
"LICENSE"
|
|
36
54
|
],
|
|
37
55
|
"scripts": {
|
|
38
|
-
"build": "tsup && cp src/styles.css dist/styles.css",
|
|
56
|
+
"build": "tsup && cp src/styles.css dist/styles.css && mkdir -p dist/frontend/components && cp -r src/frontend/components/vue dist/frontend/components/ && cp -r src/frontend/components/astro dist/frontend/components/",
|
|
39
57
|
"dev": "tsup --watch",
|
|
40
58
|
"prepublishOnly": "npm run build"
|
|
41
59
|
},
|
|
@@ -45,14 +63,17 @@
|
|
|
45
63
|
"cloudflare",
|
|
46
64
|
"workers",
|
|
47
65
|
"pages",
|
|
48
|
-
"react"
|
|
66
|
+
"react",
|
|
67
|
+
"astro",
|
|
68
|
+
"vue"
|
|
49
69
|
],
|
|
50
70
|
"author": "Content Growth",
|
|
51
71
|
"license": "MIT",
|
|
52
72
|
"peerDependencies": {
|
|
53
73
|
"@marsidev/react-turnstile": ">=0.5.0",
|
|
54
74
|
"react": "^18.0.0 || ^19.0.0",
|
|
55
|
-
"react-dom": "^18.0.0 || ^19.0.0"
|
|
75
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
76
|
+
"vue": "^3.3.0"
|
|
56
77
|
},
|
|
57
78
|
"peerDependenciesMeta": {
|
|
58
79
|
"@marsidev/react-turnstile": {
|
|
@@ -63,6 +84,9 @@
|
|
|
63
84
|
},
|
|
64
85
|
"react-dom": {
|
|
65
86
|
"optional": true
|
|
87
|
+
},
|
|
88
|
+
"vue": {
|
|
89
|
+
"optional": true
|
|
66
90
|
}
|
|
67
91
|
},
|
|
68
92
|
"dependencies": {
|
|
@@ -77,9 +101,11 @@
|
|
|
77
101
|
"@types/node": "^25.0.3",
|
|
78
102
|
"@types/react": "^19.2.7",
|
|
79
103
|
"@types/react-dom": "^19.2.3",
|
|
104
|
+
"esbuild-plugin-vue": "^0.2.4",
|
|
80
105
|
"react": "^19.2.3",
|
|
81
106
|
"react-dom": "^19.2.3",
|
|
82
107
|
"tsup": "^8.5.1",
|
|
83
|
-
"typescript": "^5.9.3"
|
|
108
|
+
"typescript": "^5.9.3",
|
|
109
|
+
"vue": "^3.5.27"
|
|
84
110
|
}
|
|
85
111
|
}
|