create-nuxt-base 0.3.17 → 1.0.2

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.
Files changed (41) hide show
  1. package/.github/workflows/publish.yml +4 -2
  2. package/.oxfmtrc.jsonc +7 -0
  3. package/CHANGELOG.md +20 -8
  4. package/nuxt-base-template/.dockerignore +44 -0
  5. package/nuxt-base-template/.nuxtrc +1 -0
  6. package/nuxt-base-template/.oxfmtrc.jsonc +8 -0
  7. package/nuxt-base-template/Dockerfile.dev +23 -0
  8. package/nuxt-base-template/app/components/Modal/ModalBackupCodes.vue +117 -0
  9. package/nuxt-base-template/app/components/Upload/TusFileUpload.vue +302 -0
  10. package/nuxt-base-template/app/composables/use-better-auth.ts +25 -0
  11. package/nuxt-base-template/app/composables/use-file.ts +39 -4
  12. package/nuxt-base-template/app/composables/use-share.ts +1 -1
  13. package/nuxt-base-template/app/composables/use-tus-upload.ts +278 -0
  14. package/nuxt-base-template/app/interfaces/upload.interface.ts +58 -0
  15. package/nuxt-base-template/app/interfaces/user.interface.ts +12 -0
  16. package/nuxt-base-template/app/lib/auth-client.ts +135 -0
  17. package/nuxt-base-template/app/middleware/admin.global.ts +23 -0
  18. package/nuxt-base-template/app/middleware/auth.global.ts +18 -0
  19. package/nuxt-base-template/app/middleware/guest.global.ts +18 -0
  20. package/nuxt-base-template/app/pages/app/settings/security.vue +409 -0
  21. package/nuxt-base-template/app/pages/auth/2fa.vue +120 -0
  22. package/nuxt-base-template/app/pages/auth/forgot-password.vue +72 -21
  23. package/nuxt-base-template/app/pages/auth/login.vue +75 -11
  24. package/nuxt-base-template/app/pages/auth/register.vue +184 -0
  25. package/nuxt-base-template/app/pages/auth/reset-password.vue +153 -0
  26. package/nuxt-base-template/app/utils/crypto.ts +13 -0
  27. package/nuxt-base-template/docker-entrypoint.sh +21 -0
  28. package/nuxt-base-template/nuxt.config.ts +4 -1
  29. package/nuxt-base-template/oxlint.json +14 -0
  30. package/nuxt-base-template/package-lock.json +11582 -10675
  31. package/nuxt-base-template/package.json +35 -32
  32. package/nuxt-base-template/tests/iam.spec.ts +247 -0
  33. package/package.json +14 -11
  34. package/.eslintignore +0 -14
  35. package/.eslintrc +0 -3
  36. package/.prettierignore +0 -5
  37. package/.prettierrc +0 -6
  38. package/nuxt-base-template/CLAUDE.md +0 -361
  39. package/nuxt-base-template/app/pages/auth/reset-password/[token].vue +0 -110
  40. package/nuxt-base-template/app/public/favicon.ico +0 -0
  41. package/nuxt-base-template/eslint.config.mjs +0 -4
@@ -1,361 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- This is a **Nuxt 4** (v4.1.3) SSR starter template built with Vue 3 Composition API, TypeScript, and Tailwind CSS v4. The project uses NuxtUI for components and follows strict TypeScript typing conventions.
8
-
9
- **Requirements:**
10
- - Node.js >= 22
11
- - npm >= 10
12
-
13
- ## Essential Commands
14
-
15
- ### Development
16
- ```bash
17
- npm run dev # Start dev server on http://localhost:3001
18
- npm run start:extern # Dev server on 0.0.0.0 (external access)
19
- ```
20
-
21
- ### Code Quality (Run Before Commits)
22
- ```bash
23
- npm run check # Run lint + format check
24
- npm run fix # Auto-fix lint + format issues
25
- npm run lint # ESLint only
26
- npm run format # Prettier format
27
- ```
28
-
29
- ### Build & Preview
30
- ```bash
31
- npm run build # Production build
32
- npm run build:develop # Development environment build
33
- npm run build:test # Test environment build
34
- npm run build:prod # Production environment build
35
- npm run preview # Preview production build
36
- ```
37
-
38
- ### Testing
39
- ```bash
40
- npm run test # Run Playwright E2E tests
41
- ```
42
-
43
- ### API Types
44
- ```bash
45
- npm run generate-types # Generate API client from OpenAPI schema
46
- ```
47
-
48
- ### Maintenance
49
- ```bash
50
- npm run clean # Remove .nuxt, .output, node_modules/.vite
51
- npm run reinit # Complete reset and reinstall
52
- ```
53
-
54
- ## Architecture Overview
55
-
56
- ### Directory Structure
57
-
58
- ```
59
- app/
60
- ├── assets/css/ # Tailwind v4 configuration
61
- ├── components/ # Vue components (auto-imported)
62
- │ ├── Modal/ # Reusable modal component
63
- │ └── Transition/ # Vue transition wrappers
64
- ├── composables/ # Vue composables (auto-imported)
65
- ├── interfaces/ # TypeScript interfaces (auto-imported)
66
- ├── layouts/ # Nuxt layouts (default, slim)
67
- ├── pages/ # File-based routing
68
- ├── public/ # Static assets
69
- ├── app.vue # Root component
70
- └── app.config.ts # NuxtUI configuration
71
-
72
- docs/ # Dev-only documentation layer
73
- tests/ # Playwright E2E tests
74
- ```
75
-
76
- ### Auto-Import Configuration
77
-
78
- The following directories are auto-imported by Nuxt:
79
- - `components/` - Vue components
80
- - `composables/` - Composables (use-*.ts)
81
- - `interfaces/` - TypeScript interfaces
82
- - `states/` - State management
83
- - `stores/` - Pinia stores
84
- - `forms/` - Form definitions
85
- - `plugins/` - Vue plugins
86
-
87
- ### Key Configuration Files
88
-
89
- - **nuxt.config.ts** - Main Nuxt configuration
90
- - Dev server: Port 3001
91
- - SSR: Enabled
92
- - Experimental: asyncContext, typedPages
93
- - Modules: NuxtUI, Pinia, VueUse, Dayjs, NuxtImage, SEO, Plausible
94
- - Docs layer enabled in development only
95
-
96
- - **app.config.ts** - NuxtUI configuration
97
- - Color palette: Primary (green), Secondary (indigo), Success (emerald), Info (blue), Warning (amber), Error (red), Neutral (slate)
98
- - Dark/light mode with Lucide icons
99
- - Toast: 5s duration, bottom-right position
100
-
101
- - **eslint.config.mjs** - Uses `@lenne.tech/eslint-config-vue` with perfectionist sorting rules
102
-
103
- - **openapi-ts.config.ts** - API client generation
104
- - Client: @hey-api/client-fetch
105
- - Output: ./app/api-client
106
-
107
- ### API Integration
108
-
109
- API client is auto-generated from OpenAPI schema:
110
-
111
- ```bash
112
- npm run generate-types # Generate types from API schema
113
- ```
114
-
115
- Generated client location: `./app/api-client`
116
-
117
- Use environment variable `API_URL` to configure the API endpoint.
118
-
119
- ### TypeScript & Interface Management
120
-
121
- **ALL interfaces must be extracted to separate files:**
122
- - Location: `app/interfaces/`
123
- - Naming: `{name}.interface.ts` (e.g., `season.interface.ts`)
124
- - Auto-imported via Nuxt configuration
125
- - No inline interfaces in components (except local helper types)
126
-
127
- **Full typing is mandatory:**
128
- - All variables have explicit types
129
- - All function parameters are typed
130
- - All function return types declared
131
- - Computed properties: `computed<Type>(() => ...)`
132
-
133
- ### Component Structure
134
-
135
- Vue components follow strict section ordering:
136
-
137
- ```vue
138
- <script setup lang="ts">
139
- // ============================================================================
140
- // Imports
141
- // ============================================================================
142
- // 1. Vue & Nuxt core
143
- // 2. Third-party libraries
144
- // 3. Type imports (grouped)
145
- // 4. Composables
146
- // 5. Components
147
-
148
- // ============================================================================
149
- // Composables
150
- // ============================================================================
151
-
152
- // ============================================================================
153
- // Page Meta
154
- // ============================================================================
155
-
156
- // ============================================================================
157
- // Variables
158
- // ============================================================================
159
-
160
- // ============================================================================
161
- // Computed Properties
162
- // ============================================================================
163
-
164
- // ============================================================================
165
- // Lifecycle Hooks
166
- // ============================================================================
167
-
168
- // ============================================================================
169
- // Functions
170
- // ============================================================================
171
- </script>
172
-
173
- <template>
174
- <!-- Template content -->
175
- </template>
176
- ```
177
-
178
- ### Composables Pattern
179
-
180
- ```typescript
181
- // app/composables/use-example.ts
182
- export function useExample() {
183
- // State
184
- const loading = ref<boolean>(false);
185
- const data = ref<DataType[]>([]);
186
-
187
- // Methods
188
- async function fetchData(): Promise<void> {
189
- // Implementation
190
- }
191
-
192
- // Return public API
193
- return {
194
- loading,
195
- data,
196
- fetchData
197
- };
198
- }
199
- ```
200
-
201
- ### ESLint Rules
202
-
203
- Key rules enforced:
204
- - `perfectionist/sort-modules` - Alphabetically sort interfaces/types
205
- - `perfectionist/sort-union-types` - Sort union types alphabetically
206
- - `perfectionist/sort-objects` - Sort object properties
207
- - `curly` - Always use curly braces for if/else
208
- - `max-statements-per-line` - One statement per line
209
-
210
- **Always run `npm run check` before committing.**
211
-
212
- ### Testing with Playwright
213
-
214
- Configuration:
215
- - Base URL: http://localhost:3001
216
- - Test directory: `./tests`
217
- - Browser: Desktop Chrome
218
- - Locale: German (de)
219
- - Retries: 2 on CI, 0 locally
220
-
221
- Example test:
222
- ```typescript
223
- import { test } from '@nuxt/test-utils/playwright';
224
-
225
- test('example test', async ({ goto, page }) => {
226
- await goto('.', { waitUntil: 'domcontentloaded' });
227
- // Test logic
228
- });
229
- ```
230
-
231
- ### Environment Variables
232
-
233
- Required variables (see `.env.example`):
234
- ```
235
- SITE_URL=http://localhost:3001
236
- API_URL=http://localhost:3000
237
- APP_ENV=development
238
- NODE_ENV=development
239
- ```
240
-
241
- Optional:
242
- - `WEB_PUSH_KEY` - Web push notifications
243
- - `LINEAR_API_KEY`, `LINEAR_TEAM_NAME`, `LINEAR_PROJECT_NAME` - Bug reporting
244
- - `API_SCHEMA` - Path to API schema for type generation
245
- - `STORAGE_PREFIX` - Local storage prefix
246
-
247
- ### Special Features
248
-
249
- **NuxtUI (v4.0.1):**
250
- - Component library with semantic color system
251
- - Dark/light mode support
252
- - Pre-configured toast notifications
253
- - Form validation utilities
254
-
255
- **SEO (@nuxtjs/seo):**
256
- - Sitemap generation (excludes /app/**, /auth/**)
257
- - Robots.txt (disallows /app, /auth, /admin)
258
- - OG image generation
259
-
260
- **Analytics:**
261
- - Plausible Analytics (disabled on localhost)
262
-
263
- **Bug Reporting:**
264
- - Linear integration via @lenne.tech/bug.lt
265
- - Disabled in production
266
- - Requires LINEAR_* environment variables
267
-
268
- **State Management:**
269
- - Pinia stores with auto-imports
270
-
271
- **Image Optimization:**
272
- - NuxtImage with IPX provider
273
- - 30-day cache
274
-
275
- ### Naming Conventions
276
-
277
- - **Files:**
278
- - Interfaces: `{name}.interface.ts`
279
- - Composables: `use-{name}.ts`
280
- - Components: PascalCase (e.g., `ModalBase.vue`)
281
- - Pages: kebab-case (e.g., `login.vue`, `[id].vue`)
282
-
283
- - **Code:**
284
- - Variables: camelCase
285
- - Booleans: `isLoading`, `hasError`, `canSubmit`
286
- - Functions: Verb-based (`handleSubmit`, `fetchData`)
287
- - Event handlers: `handle{Action}` or `on{Action}`
288
-
289
- ### Development Workflow
290
-
291
- 1. **Starting a feature:**
292
- - Plan structure with interfaces in `app/interfaces/`
293
- - Create composables in `app/composables/` if needed
294
- - Build components following the strict section ordering
295
-
296
- 2. **Before committing:**
297
- ```bash
298
- npm run check # Lint + format check
299
- npm run test # E2E tests
300
- npm run build # Verify production build
301
- ```
302
-
303
- 3. **API changes:**
304
- ```bash
305
- npm run generate-types # Regenerate API client
306
- ```
307
-
308
- 4. **Type safety:**
309
- - Extract all interfaces to separate files
310
- - Add explicit types to all variables and functions
311
- - Never use implicit `any`
312
-
313
- ### Common Patterns
314
-
315
- **Reactive state:**
316
- ```typescript
317
- // Single values
318
- const loading = ref<boolean>(false);
319
-
320
- // Objects
321
- const state: FormState = reactive({
322
- title: '',
323
- date: null
324
- });
325
-
326
- // Derived data
327
- const filtered = computed<Type[]>(() => ...);
328
- ```
329
-
330
- **Modal usage:**
331
- ```vue
332
- <ModalBase :model-value="isOpen" @close="handleClose">
333
- <template #header>Title</template>
334
- <template #default>Content</template>
335
- <template #footer>
336
- <UButton @click="handleClose">Close</UButton>
337
- </template>
338
- </ModalBase>
339
- ```
340
-
341
- **Transitions:**
342
- ```vue
343
- <TransitionFade>
344
- <div v-if="show">Content</div>
345
- </TransitionFade>
346
- ```
347
-
348
- ### Project Status
349
-
350
- **Current Branch:** DEV-609 (development branch)
351
- **Main Branch:** main (use for PRs)
352
-
353
- Recent focus: Package dependency updates and ESLint configuration improvements.
354
-
355
- ### Important Notes
356
-
357
- - **Port:** Dev server runs on **3001** (not 3000)
358
- - **Docs layer:** Enabled only in development (extends config)
359
- - **TypeScript target:** ES2022
360
- - **SSR:** Enabled by default
361
- - **npm configuration:** shamefully-hoist=true, strict-peer-dependencies=false
@@ -1,110 +0,0 @@
1
- <script setup lang="ts">
2
- // ============================================================================
3
- // Imports
4
- // ============================================================================
5
- import type { AuthFormField, FormSubmitEvent } from '@nuxt/ui';
6
- import type { InferOutput } from 'valibot';
7
-
8
- import * as v from 'valibot';
9
-
10
- // ============================================================================
11
- // Composables
12
- // ============================================================================
13
- const route = useRoute('auth-reset-password-token');
14
- const toast = useToast();
15
-
16
- // ============================================================================
17
- // Page Meta
18
- // ============================================================================
19
- definePageMeta({
20
- layout: 'slim',
21
- });
22
-
23
- // ============================================================================
24
- // Variables
25
- // ============================================================================
26
- const token = computed<string>(() => {
27
- const paramToken: string | string[] = route.params.token;
28
- return Array.isArray(paramToken) ? paramToken[0] : paramToken || '';
29
- });
30
-
31
- const isTokenValid = computed<boolean>(() => token.value.length > 0);
32
-
33
- const isSubmitting = ref<boolean>(false);
34
-
35
- const fields: AuthFormField[] = [
36
- {
37
- label: 'Password',
38
- name: 'password',
39
- placeholder: 'Enter your new password',
40
- required: true,
41
- type: 'password',
42
- },
43
- {
44
- label: 'Password Confirmation',
45
- name: 'passwordConfirmation',
46
- placeholder: 'Confirm your new password',
47
- required: true,
48
- type: 'password',
49
- },
50
- ];
51
-
52
- const schema = v.pipe(
53
- v.object({
54
- password: v.pipe(v.string('Password is required'), v.minLength(5, 'Must be at least 5 characters')),
55
- passwordConfirmation: v.pipe(v.string('Password confirmation is required'), v.minLength(5, 'Must be at least 5 characters')),
56
- }),
57
- v.forward(
58
- v.check((data) => data.password === data.passwordConfirmation, 'Passwords must match'),
59
- ['passwordConfirmation'],
60
- ),
61
- );
62
-
63
- type Schema = InferOutput<typeof schema>;
64
-
65
- // ============================================================================
66
- // Lifecycle Hooks
67
- // ============================================================================
68
- onMounted(() => {
69
- if (!isTokenValid.value) {
70
- toast.add({
71
- color: 'error',
72
- description: 'The password reset link is invalid or missing',
73
- title: 'Invalid Link',
74
- });
75
- }
76
- });
77
-
78
- // ============================================================================
79
- // Functions
80
- // ============================================================================
81
- async function onSubmit(payload: FormSubmitEvent<Schema>): Promise<void> {
82
- console.debug('Forgot password request for:', payload);
83
- }
84
- </script>
85
-
86
- <template>
87
- <UPageCard class="w-md" variant="naked">
88
- <UAlert
89
- v-if="!isTokenValid"
90
- color="error"
91
- description="The password reset link is invalid or missing. Please request a new password reset."
92
- icon="i-heroicons-exclamation-triangle"
93
- title="Invalid Reset Link"
94
- class="mb-4"
95
- />
96
- <UAuthForm
97
- :schema="schema"
98
- title="Set password"
99
- icon="i-heroicons-shield-check"
100
- :fields="fields"
101
- :loading="isSubmitting"
102
- :submit="{
103
- label: 'Continue',
104
- block: true,
105
- disabled: !isTokenValid,
106
- }"
107
- @submit="onSubmit"
108
- />
109
- </UPageCard>
110
- </template>
@@ -1,4 +0,0 @@
1
- import vue from '@lenne.tech/eslint-config-vue';
2
-
3
- // Override the problematic rule configuration
4
- export default vue