@lenne.tech/nuxt-extensions 1.0.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/LICENSE +21 -0
- package/README.md +339 -0
- package/dist/module.d.mts +10 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +126 -0
- package/dist/runtime/components/transition/LtTransitionFade.d.vue.ts +39 -0
- package/dist/runtime/components/transition/LtTransitionFade.vue +21 -0
- package/dist/runtime/components/transition/LtTransitionFade.vue.d.ts +39 -0
- package/dist/runtime/components/transition/LtTransitionFadeScale.d.vue.ts +42 -0
- package/dist/runtime/components/transition/LtTransitionFadeScale.vue +21 -0
- package/dist/runtime/components/transition/LtTransitionFadeScale.vue.d.ts +42 -0
- package/dist/runtime/components/transition/LtTransitionSlide.d.vue.ts +13 -0
- package/dist/runtime/components/transition/LtTransitionSlide.vue +16 -0
- package/dist/runtime/components/transition/LtTransitionSlide.vue.d.ts +13 -0
- package/dist/runtime/components/transition/LtTransitionSlideBottom.d.vue.ts +13 -0
- package/dist/runtime/components/transition/LtTransitionSlideBottom.vue +16 -0
- package/dist/runtime/components/transition/LtTransitionSlideBottom.vue.d.ts +13 -0
- package/dist/runtime/components/transition/LtTransitionSlideRevert.d.vue.ts +13 -0
- package/dist/runtime/components/transition/LtTransitionSlideRevert.vue +16 -0
- package/dist/runtime/components/transition/LtTransitionSlideRevert.vue.d.ts +13 -0
- package/dist/runtime/composables/auth/use-lt-auth.d.ts +32 -0
- package/dist/runtime/composables/auth/use-lt-auth.js +411 -0
- package/dist/runtime/composables/index.d.ts +5 -0
- package/dist/runtime/composables/index.js +5 -0
- package/dist/runtime/composables/use-lt-auth-client.d.ts +29 -0
- package/dist/runtime/composables/use-lt-auth-client.js +27 -0
- package/dist/runtime/composables/use-lt-file.d.ts +27 -0
- package/dist/runtime/composables/use-lt-file.js +60 -0
- package/dist/runtime/composables/use-lt-share.d.ts +32 -0
- package/dist/runtime/composables/use-lt-share.js +52 -0
- package/dist/runtime/composables/use-lt-tus-upload.d.ts +32 -0
- package/dist/runtime/composables/use-lt-tus-upload.js +236 -0
- package/dist/runtime/lib/auth-client.d.ts +831 -0
- package/dist/runtime/lib/auth-client.js +144 -0
- package/dist/runtime/lib/auth-state.d.ts +58 -0
- package/dist/runtime/lib/auth-state.js +131 -0
- package/dist/runtime/lib/index.d.ts +2 -0
- package/dist/runtime/lib/index.js +12 -0
- package/dist/runtime/locales/de.json +19 -0
- package/dist/runtime/locales/en.json +19 -0
- package/dist/runtime/plugins/auth-interceptor.client.d.ts +14 -0
- package/dist/runtime/plugins/auth-interceptor.client.js +88 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/types/auth.d.ts +127 -0
- package/dist/runtime/types/auth.js +0 -0
- package/dist/runtime/types/index.d.ts +3 -0
- package/dist/runtime/types/index.js +0 -0
- package/dist/runtime/types/module.d.ts +88 -0
- package/dist/runtime/types/module.js +0 -0
- package/dist/runtime/types/upload.d.ts +133 -0
- package/dist/runtime/types/upload.js +0 -0
- package/dist/runtime/utils/crypto.d.ts +40 -0
- package/dist/runtime/utils/crypto.js +17 -0
- package/dist/runtime/utils/index.d.ts +2 -0
- package/dist/runtime/utils/index.js +2 -0
- package/dist/runtime/utils/tw.d.ts +20 -0
- package/dist/runtime/utils/tw.js +1 -0
- package/dist/types.d.mts +9 -0
- package/package.json +99 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 lenne.Tech GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# @lenne.tech/nuxt-extensions
|
|
2
|
+
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![License][license-src]][license-href]
|
|
6
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
7
|
+
|
|
8
|
+
Reusable Nuxt 4 composables, components, and Better-Auth integration for lenne.tech projects.
|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
> **Want to start a new fullstack project?**
|
|
13
|
+
>
|
|
14
|
+
> Use the [nuxt-base-starter](https://github.com/lenneTech/nuxt-base-starter) (Frontend)
|
|
15
|
+
> together with the [nest-server-starter](https://github.com/lenneTech/nest-server-starter) (Backend)
|
|
16
|
+
> to initialize a complete fullstack project with this package pre-configured.
|
|
17
|
+
>
|
|
18
|
+
> Both starters are designed to work seamlessly together and serve as
|
|
19
|
+
> **reference implementations** showing how to use all features in a real application.
|
|
20
|
+
>
|
|
21
|
+
> **Quick initialization:**
|
|
22
|
+
> ```bash
|
|
23
|
+
> npx @lenne.tech/cli fullstack init my-project
|
|
24
|
+
> ```
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @lenne.tech/nuxt-extensions better-auth
|
|
30
|
+
# Optional: For passkey support
|
|
31
|
+
npm install @better-auth/passkey
|
|
32
|
+
# Optional: For TUS file uploads
|
|
33
|
+
npm install tus-js-client
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- **Better-Auth Integration** - Login, 2FA, Passkey/WebAuthn support
|
|
39
|
+
- **Cookie/JWT Dual-Mode** - Automatic fallback from cookies to JWT
|
|
40
|
+
- **TUS File Upload** - Resumable uploads with pause/resume
|
|
41
|
+
- **Transition Components** - Ready-to-use Vue transition wrappers
|
|
42
|
+
- **i18n Support** - English and German translations (works without i18n too)
|
|
43
|
+
- **Auto-imports** - All composables and components are auto-imported
|
|
44
|
+
|
|
45
|
+
## Configuration
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// nuxt.config.ts
|
|
49
|
+
export default defineNuxtConfig({
|
|
50
|
+
modules: ['@lenne.tech/nuxt-extensions'],
|
|
51
|
+
|
|
52
|
+
ltExtensions: {
|
|
53
|
+
// Auth configuration
|
|
54
|
+
auth: {
|
|
55
|
+
enabled: true, // Enable auth features
|
|
56
|
+
baseURL: '', // API base URL (empty = use Nuxt proxy)
|
|
57
|
+
basePath: '/iam', // Better-Auth endpoint prefix
|
|
58
|
+
loginPath: '/auth/login', // Login redirect path
|
|
59
|
+
twoFactorRedirectPath: '/auth/2fa', // 2FA redirect path
|
|
60
|
+
|
|
61
|
+
// Plugin options
|
|
62
|
+
enableAdmin: true, // Admin plugin
|
|
63
|
+
enableTwoFactor: true, // 2FA plugin
|
|
64
|
+
enablePasskey: true, // Passkey/WebAuthn plugin
|
|
65
|
+
|
|
66
|
+
// Interceptor options
|
|
67
|
+
interceptor: {
|
|
68
|
+
enabled: true, // 401 auto-handler
|
|
69
|
+
publicPaths: ['/auth/login', '/auth/register'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// TUS upload configuration
|
|
74
|
+
tus: {
|
|
75
|
+
defaultEndpoint: '/files/upload',
|
|
76
|
+
defaultChunkSize: 5 * 1024 * 1024, // 5MB
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
// i18n configuration (optional)
|
|
80
|
+
i18n: {
|
|
81
|
+
autoMerge: true, // Auto-merge locales with @nuxtjs/i18n
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Usage
|
|
88
|
+
|
|
89
|
+
### Authentication
|
|
90
|
+
|
|
91
|
+
```vue
|
|
92
|
+
<script setup>
|
|
93
|
+
// Auth composable (auto-imported)
|
|
94
|
+
const {
|
|
95
|
+
user,
|
|
96
|
+
isAuthenticated,
|
|
97
|
+
isLoading,
|
|
98
|
+
signIn,
|
|
99
|
+
signOut,
|
|
100
|
+
authenticateWithPasskey,
|
|
101
|
+
registerPasskey,
|
|
102
|
+
twoFactor,
|
|
103
|
+
} = useLtAuth();
|
|
104
|
+
|
|
105
|
+
// Login with email/password
|
|
106
|
+
async function handleLogin(email: string, password: string) {
|
|
107
|
+
const result = await signIn.email({ email, password });
|
|
108
|
+
if (result.requiresTwoFactor) {
|
|
109
|
+
navigateTo('/auth/2fa');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Passkey login
|
|
114
|
+
async function handlePasskeyLogin() {
|
|
115
|
+
const result = await authenticateWithPasskey();
|
|
116
|
+
if (result.success) {
|
|
117
|
+
navigateTo('/dashboard');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
</script>
|
|
121
|
+
|
|
122
|
+
<template>
|
|
123
|
+
<div v-if="isAuthenticated">
|
|
124
|
+
Welcome, {{ user?.name }}!
|
|
125
|
+
<button @click="signOut()">Logout</button>
|
|
126
|
+
</div>
|
|
127
|
+
</template>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### TUS File Upload
|
|
131
|
+
|
|
132
|
+
```vue
|
|
133
|
+
<script setup>
|
|
134
|
+
const {
|
|
135
|
+
addFiles,
|
|
136
|
+
uploads,
|
|
137
|
+
totalProgress,
|
|
138
|
+
isUploading,
|
|
139
|
+
pauseUpload,
|
|
140
|
+
resumeUpload,
|
|
141
|
+
cancelUpload,
|
|
142
|
+
} = useLtTusUpload({
|
|
143
|
+
endpoint: '/api/files/upload',
|
|
144
|
+
onSuccess: (item) => console.log('Uploaded:', item.url),
|
|
145
|
+
onError: (item, error) => console.error('Failed:', error),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const { formatFileSize } = useLtFile();
|
|
149
|
+
|
|
150
|
+
function handleFileSelect(event: Event) {
|
|
151
|
+
const input = event.target as HTMLInputElement;
|
|
152
|
+
if (input.files) {
|
|
153
|
+
addFiles(Array.from(input.files));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
</script>
|
|
157
|
+
|
|
158
|
+
<template>
|
|
159
|
+
<div>
|
|
160
|
+
<input type="file" multiple @change="handleFileSelect" />
|
|
161
|
+
|
|
162
|
+
<div v-for="upload in uploads" :key="upload.id">
|
|
163
|
+
<span>{{ upload.file.name }}</span>
|
|
164
|
+
<span>{{ formatFileSize(upload.progress.bytesUploaded) }} / {{ formatFileSize(upload.progress.bytesTotal) }}</span>
|
|
165
|
+
<span>{{ upload.progress.percentage }}%</span>
|
|
166
|
+
|
|
167
|
+
<button v-if="upload.status === 'uploading'" @click="pauseUpload(upload.id)">
|
|
168
|
+
Pause
|
|
169
|
+
</button>
|
|
170
|
+
<button v-if="upload.status === 'paused'" @click="resumeUpload(upload.id)">
|
|
171
|
+
Resume
|
|
172
|
+
</button>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
<div v-if="isUploading">
|
|
176
|
+
Total Progress: {{ totalProgress.percentage }}%
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
</template>
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Transition Components
|
|
183
|
+
|
|
184
|
+
```vue
|
|
185
|
+
<template>
|
|
186
|
+
<!-- Fade transition -->
|
|
187
|
+
<LtTransitionFade>
|
|
188
|
+
<div v-if="show">Content with fade</div>
|
|
189
|
+
</LtTransitionFade>
|
|
190
|
+
|
|
191
|
+
<!-- Fade with scale -->
|
|
192
|
+
<LtTransitionFadeScale :start-duration="200" :leave-duration="150">
|
|
193
|
+
<div v-if="show">Content with fade and scale</div>
|
|
194
|
+
</LtTransitionFadeScale>
|
|
195
|
+
|
|
196
|
+
<!-- Slide from right -->
|
|
197
|
+
<LtTransitionSlide>
|
|
198
|
+
<div v-if="show">Content slides from right</div>
|
|
199
|
+
</LtTransitionSlide>
|
|
200
|
+
|
|
201
|
+
<!-- Slide from bottom -->
|
|
202
|
+
<LtTransitionSlideBottom>
|
|
203
|
+
<div v-if="show">Content slides from bottom</div>
|
|
204
|
+
</LtTransitionSlideBottom>
|
|
205
|
+
|
|
206
|
+
<!-- Slide from left -->
|
|
207
|
+
<LtTransitionSlideRevert>
|
|
208
|
+
<div v-if="show">Content slides from left</div>
|
|
209
|
+
</LtTransitionSlideRevert>
|
|
210
|
+
</template>
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Web Share API
|
|
214
|
+
|
|
215
|
+
```vue
|
|
216
|
+
<script setup>
|
|
217
|
+
const { share } = useLtShare();
|
|
218
|
+
|
|
219
|
+
async function handleShare() {
|
|
220
|
+
await share('Check this out!', 'Amazing content');
|
|
221
|
+
// Uses native share on mobile, clipboard fallback on desktop
|
|
222
|
+
}
|
|
223
|
+
</script>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Utilities
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
// Tailwind TypeScript helper
|
|
230
|
+
const buttonClasses = tw`bg-blue-500 hover:bg-blue-700 text-white`;
|
|
231
|
+
|
|
232
|
+
// Crypto utilities (for WebAuthn)
|
|
233
|
+
const hash = await ltSha256('password');
|
|
234
|
+
const base64 = ltArrayBufferToBase64Url(buffer);
|
|
235
|
+
const uint8 = ltBase64UrlToUint8Array(base64String);
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## i18n Support
|
|
239
|
+
|
|
240
|
+
The package works **with or without** `@nuxtjs/i18n`:
|
|
241
|
+
|
|
242
|
+
| Setup | Language | Text Source |
|
|
243
|
+
|-------|----------|-------------|
|
|
244
|
+
| **Without i18n** | German | Hardcoded fallback texts |
|
|
245
|
+
| With i18n, Locale: `de` | German | From `de.json` |
|
|
246
|
+
| With i18n, Locale: `en` | English | From `en.json` |
|
|
247
|
+
| With i18n, other Locale | English | Fallback to `en.json` |
|
|
248
|
+
|
|
249
|
+
## API Reference
|
|
250
|
+
|
|
251
|
+
### Composables
|
|
252
|
+
|
|
253
|
+
| Composable | Description |
|
|
254
|
+
|------------|-------------|
|
|
255
|
+
| `useLtAuth()` | Better-Auth integration with session, passkey, 2FA |
|
|
256
|
+
| `useLtTusUpload()` | TUS protocol file uploads with pause/resume |
|
|
257
|
+
| `useLtFile()` | File utilities (size formatting, URLs) |
|
|
258
|
+
| `useLtShare()` | Web Share API with clipboard fallback |
|
|
259
|
+
|
|
260
|
+
### Components
|
|
261
|
+
|
|
262
|
+
| Component | Description |
|
|
263
|
+
|-----------|-------------|
|
|
264
|
+
| `<LtTransitionFade>` | Opacity fade transition |
|
|
265
|
+
| `<LtTransitionFadeScale>` | Fade with scale transition |
|
|
266
|
+
| `<LtTransitionSlide>` | Slide from right transition |
|
|
267
|
+
| `<LtTransitionSlideBottom>` | Slide from bottom transition |
|
|
268
|
+
| `<LtTransitionSlideRevert>` | Slide from left transition |
|
|
269
|
+
|
|
270
|
+
### Utilities
|
|
271
|
+
|
|
272
|
+
| Utility | Description |
|
|
273
|
+
|---------|-------------|
|
|
274
|
+
| `tw` | Tailwind TypeScript helper |
|
|
275
|
+
| `ltSha256()` | SHA256 hash function |
|
|
276
|
+
| `ltArrayBufferToBase64Url()` | ArrayBuffer to base64url conversion |
|
|
277
|
+
| `ltBase64UrlToUint8Array()` | Base64url to Uint8Array conversion |
|
|
278
|
+
| `createLtAuthClient()` | Auth client factory for custom configuration |
|
|
279
|
+
|
|
280
|
+
## Related Projects
|
|
281
|
+
|
|
282
|
+
| Project | Description |
|
|
283
|
+
|---------|-------------|
|
|
284
|
+
| [nuxt-base-starter](https://github.com/lenneTech/nuxt-base-starter) | Frontend starter template (uses this package) |
|
|
285
|
+
| [nest-server-starter](https://github.com/lenneTech/nest-server-starter) | Backend starter template (Better-Auth backend) |
|
|
286
|
+
| [@lenne.tech/nest-server](https://github.com/lenneTech/nest-server) | Backend framework with Better-Auth support |
|
|
287
|
+
| [@lenne.tech/cli](https://github.com/lenneTech/cli) | CLI tool for fullstack project initialization |
|
|
288
|
+
|
|
289
|
+
## Fullstack Architecture
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
+-------------------------------------------------------------+
|
|
293
|
+
| Your Fullstack App |
|
|
294
|
+
+-----------------------------+-------------------------------+
|
|
295
|
+
| Frontend | Backend |
|
|
296
|
+
| (nuxt-base-starter) | (nest-server-starter) |
|
|
297
|
+
+-----------------------------+-------------------------------+
|
|
298
|
+
| @lenne.tech/nuxt-extensions| @lenne.tech/nest-server |
|
|
299
|
+
| - useLtAuth() | - CoreBetterAuthModule |
|
|
300
|
+
| - useLtTusUpload() | - CoreFileModule |
|
|
301
|
+
| - <LtTransition*> | - CoreUserModule |
|
|
302
|
+
+-----------------------------+-------------------------------+
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Development
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Install dependencies
|
|
309
|
+
npm install
|
|
310
|
+
|
|
311
|
+
# Generate type stubs
|
|
312
|
+
npm run dev:prepare
|
|
313
|
+
|
|
314
|
+
# Develop with playground
|
|
315
|
+
npm run dev
|
|
316
|
+
|
|
317
|
+
# Build the module
|
|
318
|
+
npm run build
|
|
319
|
+
|
|
320
|
+
# Run tests
|
|
321
|
+
npm run test
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
[MIT](./LICENSE)
|
|
327
|
+
|
|
328
|
+
<!-- Badges -->
|
|
329
|
+
[npm-version-src]: https://img.shields.io/npm/v/@lenne.tech/nuxt-extensions/latest.svg?style=flat&colorA=020420&colorB=00DC82
|
|
330
|
+
[npm-version-href]: https://npmjs.com/package/@lenne.tech/nuxt-extensions
|
|
331
|
+
|
|
332
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/@lenne.tech/nuxt-extensions.svg?style=flat&colorA=020420&colorB=00DC82
|
|
333
|
+
[npm-downloads-href]: https://npm.chart.dev/@lenne.tech/nuxt-extensions
|
|
334
|
+
|
|
335
|
+
[license-src]: https://img.shields.io/npm/l/@lenne.tech/nuxt-extensions.svg?style=flat&colorA=020420&colorB=00DC82
|
|
336
|
+
[license-href]: https://npmjs.com/package/@lenne.tech/nuxt-extensions
|
|
337
|
+
|
|
338
|
+
[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt
|
|
339
|
+
[nuxt-href]: https://nuxt.com
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
import { LtExtensionsModuleOptions } from '../dist/runtime/types/index.js';
|
|
3
|
+
export { LtExtensionsModuleOptions } from '../dist/runtime/types/index.js';
|
|
4
|
+
|
|
5
|
+
declare const name = "@lenne.tech/nuxt-extensions";
|
|
6
|
+
declare const version = "1.0.0";
|
|
7
|
+
declare const configKey = "ltExtensions";
|
|
8
|
+
declare const _default: _nuxt_schema.NuxtModule<LtExtensionsModuleOptions, LtExtensionsModuleOptions, false>;
|
|
9
|
+
|
|
10
|
+
export { configKey, _default as default, name, version };
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, addImports, addComponent, addPlugin } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
const name = "@lenne.tech/nuxt-extensions";
|
|
4
|
+
const version = "1.0.0";
|
|
5
|
+
const configKey = "ltExtensions";
|
|
6
|
+
const defaultOptions = {
|
|
7
|
+
auth: {
|
|
8
|
+
basePath: "/iam",
|
|
9
|
+
baseURL: "",
|
|
10
|
+
enabled: true,
|
|
11
|
+
enableAdmin: true,
|
|
12
|
+
enablePasskey: true,
|
|
13
|
+
enableTwoFactor: true,
|
|
14
|
+
interceptor: {
|
|
15
|
+
enabled: true,
|
|
16
|
+
publicPaths: []
|
|
17
|
+
},
|
|
18
|
+
loginPath: "/auth/login",
|
|
19
|
+
twoFactorRedirectPath: "/auth/2fa"
|
|
20
|
+
},
|
|
21
|
+
i18n: {
|
|
22
|
+
autoMerge: true
|
|
23
|
+
},
|
|
24
|
+
tus: {
|
|
25
|
+
defaultChunkSize: 5 * 1024 * 1024,
|
|
26
|
+
// 5MB
|
|
27
|
+
defaultEndpoint: "/files/upload"
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const module$1 = defineNuxtModule({
|
|
31
|
+
meta: {
|
|
32
|
+
configKey,
|
|
33
|
+
name,
|
|
34
|
+
version
|
|
35
|
+
},
|
|
36
|
+
defaults: defaultOptions,
|
|
37
|
+
async setup(options, nuxt) {
|
|
38
|
+
const { resolve } = createResolver(import.meta.url);
|
|
39
|
+
const resolvedOptions = {
|
|
40
|
+
auth: { ...defaultOptions.auth, ...options.auth },
|
|
41
|
+
i18n: { ...defaultOptions.i18n, ...options.i18n },
|
|
42
|
+
tus: { ...defaultOptions.tus, ...options.tus }
|
|
43
|
+
};
|
|
44
|
+
nuxt.options.runtimeConfig.public.ltExtensions = {
|
|
45
|
+
auth: {
|
|
46
|
+
basePath: resolvedOptions.auth?.basePath || "/iam",
|
|
47
|
+
baseURL: resolvedOptions.auth?.baseURL || "",
|
|
48
|
+
enabled: resolvedOptions.auth?.enabled ?? true,
|
|
49
|
+
enableAdmin: resolvedOptions.auth?.enableAdmin ?? true,
|
|
50
|
+
enablePasskey: resolvedOptions.auth?.enablePasskey ?? true,
|
|
51
|
+
enableTwoFactor: resolvedOptions.auth?.enableTwoFactor ?? true,
|
|
52
|
+
interceptor: {
|
|
53
|
+
enabled: resolvedOptions.auth?.interceptor?.enabled ?? true,
|
|
54
|
+
publicPaths: resolvedOptions.auth?.interceptor?.publicPaths || []
|
|
55
|
+
},
|
|
56
|
+
loginPath: resolvedOptions.auth?.loginPath || "/auth/login",
|
|
57
|
+
twoFactorRedirectPath: resolvedOptions.auth?.twoFactorRedirectPath || "/auth/2fa"
|
|
58
|
+
},
|
|
59
|
+
tus: {
|
|
60
|
+
defaultChunkSize: resolvedOptions.tus?.defaultChunkSize || 5 * 1024 * 1024,
|
|
61
|
+
defaultEndpoint: resolvedOptions.tus?.defaultEndpoint || "/files/upload"
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
addImports([
|
|
65
|
+
// Composables
|
|
66
|
+
{ name: "useLtAuth", from: resolve("./runtime/composables/auth/use-lt-auth") },
|
|
67
|
+
{ name: "useLtAuthClient", from: resolve("./runtime/composables/use-lt-auth-client") },
|
|
68
|
+
{ name: "ltAuthClient", from: resolve("./runtime/composables/use-lt-auth-client") },
|
|
69
|
+
{ name: "useLtFile", from: resolve("./runtime/composables/use-lt-file") },
|
|
70
|
+
{ name: "useLtTusUpload", from: resolve("./runtime/composables/use-lt-tus-upload") },
|
|
71
|
+
{ name: "useLtShare", from: resolve("./runtime/composables/use-lt-share") },
|
|
72
|
+
// Utils
|
|
73
|
+
{ name: "ltSha256", from: resolve("./runtime/utils/crypto") },
|
|
74
|
+
{ name: "ltArrayBufferToBase64Url", from: resolve("./runtime/utils/crypto") },
|
|
75
|
+
{ name: "ltBase64UrlToUint8Array", from: resolve("./runtime/utils/crypto") },
|
|
76
|
+
{ name: "tw", from: resolve("./runtime/utils/tw") },
|
|
77
|
+
// Lib - Auth State
|
|
78
|
+
{ name: "createLtAuthClient", from: resolve("./runtime/lib/auth-client") },
|
|
79
|
+
{ name: "getLtAuthMode", from: resolve("./runtime/lib/auth-state") },
|
|
80
|
+
{ name: "setLtAuthMode", from: resolve("./runtime/lib/auth-state") },
|
|
81
|
+
{ name: "getLtJwtToken", from: resolve("./runtime/lib/auth-state") },
|
|
82
|
+
{ name: "setLtJwtToken", from: resolve("./runtime/lib/auth-state") },
|
|
83
|
+
{ name: "getLtApiBase", from: resolve("./runtime/lib/auth-state") },
|
|
84
|
+
{ name: "attemptLtJwtSwitch", from: resolve("./runtime/lib/auth-state") },
|
|
85
|
+
{ name: "isLtAuthenticated", from: resolve("./runtime/lib/auth-state") },
|
|
86
|
+
{ name: "createLtAuthFetch", from: resolve("./runtime/lib/auth-state") },
|
|
87
|
+
{ name: "ltAuthFetch", from: resolve("./runtime/lib/auth-state") }
|
|
88
|
+
]);
|
|
89
|
+
const transitionComponents = [
|
|
90
|
+
"LtTransitionFade",
|
|
91
|
+
"LtTransitionSlide",
|
|
92
|
+
"LtTransitionSlideBottom",
|
|
93
|
+
"LtTransitionSlideRevert",
|
|
94
|
+
"LtTransitionFadeScale"
|
|
95
|
+
];
|
|
96
|
+
for (const componentName of transitionComponents) {
|
|
97
|
+
addComponent({
|
|
98
|
+
name: componentName,
|
|
99
|
+
filePath: resolve(`./runtime/components/transition/${componentName}.vue`)
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (resolvedOptions.auth?.enabled && resolvedOptions.auth?.interceptor?.enabled) {
|
|
103
|
+
addPlugin(resolve("./runtime/plugins/auth-interceptor.client"));
|
|
104
|
+
}
|
|
105
|
+
if (resolvedOptions.i18n?.autoMerge) {
|
|
106
|
+
nuxt.hook("i18n:registerModule", (register) => {
|
|
107
|
+
register({
|
|
108
|
+
langDir: resolve("./runtime/locales"),
|
|
109
|
+
locales: [
|
|
110
|
+
{ code: "en", file: "en.json" },
|
|
111
|
+
{ code: "de", file: "de.json" }
|
|
112
|
+
]
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
nuxt.options.build.transpile.push(resolve("./runtime"));
|
|
117
|
+
nuxt.options.build.transpile.push("tus-js-client");
|
|
118
|
+
console.log(`[${name}] Module loaded with config:`, {
|
|
119
|
+
auth: resolvedOptions.auth?.enabled ? "enabled" : "disabled",
|
|
120
|
+
i18nAutoMerge: resolvedOptions.i18n?.autoMerge,
|
|
121
|
+
tusEndpoint: resolvedOptions.tus?.defaultEndpoint
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export { configKey, module$1 as default, name, version };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fade transition component
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple opacity fade animation for entering/leaving elements.
|
|
5
|
+
* Configurable duration for both enter and leave animations.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```vue
|
|
9
|
+
* <LtTransitionFade>
|
|
10
|
+
* <div v-if="show">Content fades in/out</div>
|
|
11
|
+
* </LtTransitionFade>
|
|
12
|
+
*
|
|
13
|
+
* <LtTransitionFade :start-duration="200" :leave-duration="150">
|
|
14
|
+
* <div v-if="show">Custom timing</div>
|
|
15
|
+
* </LtTransitionFade>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
type __VLS_Props = {
|
|
19
|
+
/** Duration in ms for the leave animation (default: 100) */
|
|
20
|
+
leaveDuration?: `${number}` | number;
|
|
21
|
+
/** Duration in ms for the enter animation (default: 100) */
|
|
22
|
+
startDuration?: `${number}` | number;
|
|
23
|
+
};
|
|
24
|
+
declare var __VLS_7: {};
|
|
25
|
+
type __VLS_Slots = {} & {
|
|
26
|
+
default?: (props: typeof __VLS_7) => any;
|
|
27
|
+
};
|
|
28
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
29
|
+
leaveDuration: `${number}` | number;
|
|
30
|
+
startDuration: `${number}` | number;
|
|
31
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
33
|
+
declare const _default: typeof __VLS_export;
|
|
34
|
+
export default _default;
|
|
35
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
36
|
+
new (): {
|
|
37
|
+
$slots: S;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
leaveDuration: { type: null, required: false, default: 100 },
|
|
4
|
+
startDuration: { type: null, required: false, default: 100 }
|
|
5
|
+
});
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<div :style="`--start-duration: ${props.startDuration}ms; --leave-duration: ${props.leaveDuration}ms;`">
|
|
10
|
+
<Transition
|
|
11
|
+
enter-active-class="transition ease-out duration-[--start-duration]"
|
|
12
|
+
enter-from-class="transform opacity-0"
|
|
13
|
+
enter-to-class="transform opacity-100"
|
|
14
|
+
leave-active-class="transition ease-in duration-[--leave-duration]"
|
|
15
|
+
leave-from-class="transform opacity-100"
|
|
16
|
+
leave-to-class="transform opacity-0"
|
|
17
|
+
>
|
|
18
|
+
<slot></slot>
|
|
19
|
+
</Transition>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fade transition component
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple opacity fade animation for entering/leaving elements.
|
|
5
|
+
* Configurable duration for both enter and leave animations.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```vue
|
|
9
|
+
* <LtTransitionFade>
|
|
10
|
+
* <div v-if="show">Content fades in/out</div>
|
|
11
|
+
* </LtTransitionFade>
|
|
12
|
+
*
|
|
13
|
+
* <LtTransitionFade :start-duration="200" :leave-duration="150">
|
|
14
|
+
* <div v-if="show">Custom timing</div>
|
|
15
|
+
* </LtTransitionFade>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
type __VLS_Props = {
|
|
19
|
+
/** Duration in ms for the leave animation (default: 100) */
|
|
20
|
+
leaveDuration?: `${number}` | number;
|
|
21
|
+
/** Duration in ms for the enter animation (default: 100) */
|
|
22
|
+
startDuration?: `${number}` | number;
|
|
23
|
+
};
|
|
24
|
+
declare var __VLS_7: {};
|
|
25
|
+
type __VLS_Slots = {} & {
|
|
26
|
+
default?: (props: typeof __VLS_7) => any;
|
|
27
|
+
};
|
|
28
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
29
|
+
leaveDuration: `${number}` | number;
|
|
30
|
+
startDuration: `${number}` | number;
|
|
31
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
33
|
+
declare const _default: typeof __VLS_export;
|
|
34
|
+
export default _default;
|
|
35
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
36
|
+
new (): {
|
|
37
|
+
$slots: S;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fade with scale transition component
|
|
3
|
+
*
|
|
4
|
+
* Provides a combined fade and scale animation.
|
|
5
|
+
* Elements fade in while scaling up from 95% to 100%,
|
|
6
|
+
* and fade out while scaling down to 95%.
|
|
7
|
+
*
|
|
8
|
+
* Great for modal dialogs, dropdown menus, and pop-ups.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```vue
|
|
12
|
+
* <LtTransitionFadeScale>
|
|
13
|
+
* <div v-if="show">Content fades and scales</div>
|
|
14
|
+
* </LtTransitionFadeScale>
|
|
15
|
+
*
|
|
16
|
+
* <LtTransitionFadeScale :start-duration="200" :leave-duration="150">
|
|
17
|
+
* <div v-if="show">Custom timing</div>
|
|
18
|
+
* </LtTransitionFadeScale>
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
type __VLS_Props = {
|
|
22
|
+
/** Duration in ms for the leave animation (default: 100) */
|
|
23
|
+
leaveDuration?: `${number}` | number;
|
|
24
|
+
/** Duration in ms for the enter animation (default: 100) */
|
|
25
|
+
startDuration?: `${number}` | number;
|
|
26
|
+
};
|
|
27
|
+
declare var __VLS_7: {};
|
|
28
|
+
type __VLS_Slots = {} & {
|
|
29
|
+
default?: (props: typeof __VLS_7) => any;
|
|
30
|
+
};
|
|
31
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
32
|
+
leaveDuration: `${number}` | number;
|
|
33
|
+
startDuration: `${number}` | number;
|
|
34
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
35
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
36
|
+
declare const _default: typeof __VLS_export;
|
|
37
|
+
export default _default;
|
|
38
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
39
|
+
new (): {
|
|
40
|
+
$slots: S;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
leaveDuration: { type: null, required: false, default: 100 },
|
|
4
|
+
startDuration: { type: null, required: false, default: 100 }
|
|
5
|
+
});
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<div :style="`--start-duration: ${props.startDuration}ms; --leave-duration: ${props.leaveDuration}ms;`">
|
|
10
|
+
<Transition
|
|
11
|
+
enter-active-class="transition ease-out duration-[--start-duration]"
|
|
12
|
+
enter-from-class="transform opacity-0 scale-95"
|
|
13
|
+
enter-to-class="transform opacity-100 scale-100"
|
|
14
|
+
leave-active-class="transition ease-in duration-[--leave-duration]"
|
|
15
|
+
leave-from-class="transform opacity-100 scale-100"
|
|
16
|
+
leave-to-class="transform opacity-0 scale-95"
|
|
17
|
+
>
|
|
18
|
+
<slot></slot>
|
|
19
|
+
</Transition>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|