@smicolon/ai-kit 0.3.1 → 0.4.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 +73 -40
- package/dist/index.js +260 -126
- package/package.json +5 -5
- package/.claude-plugin/marketplace.json +0 -373
- package/packs/architect/CHANGELOG.md +0 -17
- package/packs/architect/README.md +0 -58
- package/packs/architect/agents/system-architect.md +0 -768
- package/packs/architect/commands/diagram-create.md +0 -300
- package/packs/better-auth/.mcp.json +0 -14
- package/packs/better-auth/CHANGELOG.md +0 -26
- package/packs/better-auth/README.md +0 -125
- package/packs/better-auth/agents/auth-architect.md +0 -278
- package/packs/better-auth/commands/auth-provider-add.md +0 -265
- package/packs/better-auth/commands/auth-setup.md +0 -298
- package/packs/better-auth/skills/auth-security/SKILL.md +0 -425
- package/packs/better-auth/skills/better-auth-patterns/SKILL.md +0 -455
- package/packs/dev-loop/CHANGELOG.md +0 -69
- package/packs/dev-loop/README.md +0 -155
- package/packs/dev-loop/commands/cancel-dev.md +0 -21
- package/packs/dev-loop/commands/dev-loop.md +0 -72
- package/packs/dev-loop/commands/dev-plan.md +0 -351
- package/packs/dev-loop/hooks/hooks.json +0 -15
- package/packs/dev-loop/hooks/stop-hook.sh +0 -178
- package/packs/dev-loop/scripts/setup-dev-loop.sh +0 -194
- package/packs/dev-loop/skills/tdd-planner/SKILL.md +0 -249
- package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +0 -874
- package/packs/dev-loop/skills/tdd-planner/references/good-example.md +0 -260
- package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +0 -275
- package/packs/django/CHANGELOG.md +0 -39
- package/packs/django/README.md +0 -92
- package/packs/django/agents/django-architect.md +0 -182
- package/packs/django/agents/django-builder.md +0 -250
- package/packs/django/agents/django-feature-based.md +0 -420
- package/packs/django/agents/django-reviewer.md +0 -253
- package/packs/django/agents/django-tester.md +0 -230
- package/packs/django/commands/api-endpoint.md +0 -285
- package/packs/django/commands/model-create.md +0 -178
- package/packs/django/commands/test-generate.md +0 -325
- package/packs/django/rules/migrations.md +0 -138
- package/packs/django/rules/models.md +0 -167
- package/packs/django/rules/serializers.md +0 -126
- package/packs/django/rules/services.md +0 -131
- package/packs/django/rules/tests.md +0 -140
- package/packs/django/rules/views.md +0 -102
- package/packs/django/skills/import-convention-enforcer/SKILL.md +0 -226
- package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +0 -343
- package/packs/django/skills/migration-safety-checker/SKILL.md +0 -375
- package/packs/django/skills/model-entity-validator/SKILL.md +0 -298
- package/packs/django/skills/performance-optimizer/SKILL.md +0 -447
- package/packs/django/skills/red-phase-verifier/SKILL.md +0 -180
- package/packs/django/skills/security-first-validator/SKILL.md +0 -435
- package/packs/django/skills/test-coverage-advisor/SKILL.md +0 -394
- package/packs/django/skills/test-validity-checker/SKILL.md +0 -194
- package/packs/failure-log/CHANGELOG.md +0 -20
- package/packs/failure-log/README.md +0 -168
- package/packs/failure-log/commands/failure-add.md +0 -106
- package/packs/failure-log/commands/failure-list.md +0 -89
- package/packs/failure-log/hooks/hooks.json +0 -16
- package/packs/failure-log/hooks/scripts/inject-failures.sh +0 -64
- package/packs/failure-log/skills/failure-log-manager/SKILL.md +0 -164
- package/packs/flutter/CHANGELOG.md +0 -19
- package/packs/flutter/README.md +0 -170
- package/packs/flutter/agents/flutter-architect.md +0 -166
- package/packs/flutter/agents/flutter-builder.md +0 -303
- package/packs/flutter/agents/release-manager.md +0 -355
- package/packs/flutter/commands/fastlane-setup.md +0 -188
- package/packs/flutter/commands/flutter-build.md +0 -90
- package/packs/flutter/commands/flutter-deploy.md +0 -133
- package/packs/flutter/commands/flutter-test.md +0 -117
- package/packs/flutter/commands/signing-setup.md +0 -209
- package/packs/flutter/hooks/hooks.json +0 -17
- package/packs/flutter/skills/fastlane-knowledge/SKILL.md +0 -193
- package/packs/flutter/skills/flutter-architecture/SKILL.md +0 -127
- package/packs/flutter/skills/store-publishing/SKILL.md +0 -163
- package/packs/hono/CHANGELOG.md +0 -19
- package/packs/hono/README.md +0 -143
- package/packs/hono/agents/hono-architect.md +0 -240
- package/packs/hono/agents/hono-builder.md +0 -285
- package/packs/hono/agents/hono-reviewer.md +0 -279
- package/packs/hono/agents/hono-tester.md +0 -346
- package/packs/hono/commands/middleware-create.md +0 -223
- package/packs/hono/commands/project-init.md +0 -306
- package/packs/hono/commands/route-create.md +0 -153
- package/packs/hono/commands/rpc-client.md +0 -263
- package/packs/hono/hooks/hooks.json +0 -4
- package/packs/hono/skills/cloudflare-bindings/SKILL.md +0 -408
- package/packs/hono/skills/hono-patterns/SKILL.md +0 -309
- package/packs/hono/skills/rpc-typesafe/SKILL.md +0 -388
- package/packs/hono/skills/zod-validation/SKILL.md +0 -332
- package/packs/nestjs/CHANGELOG.md +0 -29
- package/packs/nestjs/README.md +0 -75
- package/packs/nestjs/agents/nestjs-architect.md +0 -402
- package/packs/nestjs/agents/nestjs-builder.md +0 -301
- package/packs/nestjs/agents/nestjs-tester.md +0 -437
- package/packs/nestjs/commands/module-create.md +0 -369
- package/packs/nestjs/rules/controllers.md +0 -92
- package/packs/nestjs/rules/dto.md +0 -124
- package/packs/nestjs/rules/entities.md +0 -102
- package/packs/nestjs/rules/services.md +0 -106
- package/packs/nestjs/skills/barrel-export-manager/SKILL.md +0 -389
- package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +0 -365
- package/packs/nextjs/CHANGELOG.md +0 -36
- package/packs/nextjs/README.md +0 -76
- package/packs/nextjs/agents/frontend-tester.md +0 -680
- package/packs/nextjs/agents/frontend-visual.md +0 -820
- package/packs/nextjs/agents/nextjs-architect.md +0 -331
- package/packs/nextjs/agents/nextjs-modular.md +0 -433
- package/packs/nextjs/commands/component-create.md +0 -398
- package/packs/nextjs/rules/api-routes.md +0 -129
- package/packs/nextjs/rules/components.md +0 -106
- package/packs/nextjs/rules/hooks.md +0 -132
- package/packs/nextjs/skills/accessibility-validator/SKILL.md +0 -445
- package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +0 -399
- package/packs/nextjs/skills/react-form-validator/SKILL.md +0 -569
- package/packs/nuxtjs/CHANGELOG.md +0 -30
- package/packs/nuxtjs/README.md +0 -56
- package/packs/nuxtjs/agents/frontend-tester.md +0 -680
- package/packs/nuxtjs/agents/frontend-visual.md +0 -820
- package/packs/nuxtjs/agents/nuxtjs-architect.md +0 -537
- package/packs/nuxtjs/commands/component-create.md +0 -223
- package/packs/nuxtjs/rules/components.md +0 -101
- package/packs/nuxtjs/rules/composables.md +0 -118
- package/packs/nuxtjs/rules/server-routes.md +0 -127
- package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +0 -183
- package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +0 -196
- package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +0 -190
- package/packs/onboard/CHANGELOG.md +0 -22
- package/packs/onboard/README.md +0 -103
- package/packs/onboard/agents/onboard-guide.md +0 -118
- package/packs/onboard/commands/onboard.md +0 -313
- package/packs/onboard/skills/onboard-context-provider/SKILL.md +0 -98
- package/packs/tanstack-router/CHANGELOG.md +0 -30
- package/packs/tanstack-router/README.md +0 -113
- package/packs/tanstack-router/agents/tanstack-architect.md +0 -173
- package/packs/tanstack-router/agents/tanstack-builder.md +0 -360
- package/packs/tanstack-router/agents/tanstack-tester.md +0 -454
- package/packs/tanstack-router/commands/form-create.md +0 -313
- package/packs/tanstack-router/commands/query-create.md +0 -263
- package/packs/tanstack-router/commands/route-create.md +0 -190
- package/packs/tanstack-router/commands/table-create.md +0 -413
- package/packs/tanstack-router/skills/ai-patterns/SKILL.md +0 -370
- package/packs/tanstack-router/skills/db-patterns/SKILL.md +0 -346
- package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +0 -415
- package/packs/tanstack-router/skills/form-patterns/SKILL.md +0 -425
- package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +0 -341
- package/packs/tanstack-router/skills/query-patterns/SKILL.md +0 -359
- package/packs/tanstack-router/skills/router-patterns/SKILL.md +0 -285
- package/packs/tanstack-router/skills/store-patterns/SKILL.md +0 -351
- package/packs/tanstack-router/skills/table-patterns/SKILL.md +0 -531
- package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +0 -428
- package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +0 -490
- package/packs/worktree/CHANGELOG.md +0 -45
- package/packs/worktree/README.md +0 -219
- package/packs/worktree/commands/wt.md +0 -93
- package/packs/worktree/scripts/wt.sh +0 -957
- package/packs/worktree/skills/worktree-manager/SKILL.md +0 -113
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: component-create
|
|
3
|
-
description: Create a Nuxt.js/Vue 3 component following Smicolon conventions
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Nuxt.js Component Creation
|
|
7
|
-
|
|
8
|
-
## Component Types
|
|
9
|
-
|
|
10
|
-
1. **Page Component** - `/pages/*.vue`
|
|
11
|
-
2. **Layout Component** - `/layouts/*.vue`
|
|
12
|
-
3. **UI Component** - `/components/*.vue`
|
|
13
|
-
4. **Composable** - `/composables/*.ts`
|
|
14
|
-
|
|
15
|
-
## Template
|
|
16
|
-
|
|
17
|
-
### Basic Component
|
|
18
|
-
|
|
19
|
-
```vue
|
|
20
|
-
<script setup lang="ts">
|
|
21
|
-
// Props with TypeScript
|
|
22
|
-
interface Props {
|
|
23
|
-
title: string
|
|
24
|
-
variant?: 'primary' | 'secondary'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
28
|
-
variant: 'primary',
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
// Emits with TypeScript
|
|
32
|
-
const emit = defineEmits<{
|
|
33
|
-
(e: 'update', value: string): void
|
|
34
|
-
(e: 'close'): void
|
|
35
|
-
}>()
|
|
36
|
-
|
|
37
|
-
// Reactive state (auto-imported)
|
|
38
|
-
const isOpen = ref(false)
|
|
39
|
-
|
|
40
|
-
// Computed (auto-imported)
|
|
41
|
-
const buttonClass = computed(() => `btn-${props.variant}`)
|
|
42
|
-
|
|
43
|
-
// Methods
|
|
44
|
-
function handleClick() {
|
|
45
|
-
emit('update', 'new value')
|
|
46
|
-
}
|
|
47
|
-
</script>
|
|
48
|
-
|
|
49
|
-
<template>
|
|
50
|
-
<div class="component">
|
|
51
|
-
<h2>{{ title }}</h2>
|
|
52
|
-
<button
|
|
53
|
-
type="button"
|
|
54
|
-
:class="buttonClass"
|
|
55
|
-
@click="emit('close')"
|
|
56
|
-
>
|
|
57
|
-
Close
|
|
58
|
-
</button>
|
|
59
|
-
</div>
|
|
60
|
-
</template>
|
|
61
|
-
|
|
62
|
-
<style scoped>
|
|
63
|
-
.component {
|
|
64
|
-
/* Scoped styles */
|
|
65
|
-
}
|
|
66
|
-
</style>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Page Component
|
|
70
|
-
|
|
71
|
-
```vue
|
|
72
|
-
<script setup lang="ts">
|
|
73
|
-
// Page meta
|
|
74
|
-
definePageMeta({
|
|
75
|
-
title: 'User Profile',
|
|
76
|
-
middleware: ['auth'],
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
// Route params
|
|
80
|
-
const route = useRoute()
|
|
81
|
-
const userId = computed(() => route.params.id as string)
|
|
82
|
-
|
|
83
|
-
// Data fetching
|
|
84
|
-
const { data: user, pending, error } = await useFetch(`/api/users/${userId.value}`)
|
|
85
|
-
|
|
86
|
-
// SEO
|
|
87
|
-
useHead({
|
|
88
|
-
title: () => user.value?.name || 'User Profile',
|
|
89
|
-
})
|
|
90
|
-
</script>
|
|
91
|
-
|
|
92
|
-
<template>
|
|
93
|
-
<div>
|
|
94
|
-
<p v-if="pending">Loading...</p>
|
|
95
|
-
<p v-else-if="error">Error: {{ error.message }}</p>
|
|
96
|
-
<div v-else-if="user">
|
|
97
|
-
<h1>{{ user.name }}</h1>
|
|
98
|
-
<p>{{ user.email }}</p>
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
</template>
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
### Form Component
|
|
105
|
-
|
|
106
|
-
```vue
|
|
107
|
-
<script setup lang="ts">
|
|
108
|
-
import { useForm } from 'vee-validate'
|
|
109
|
-
import { toTypedSchema } from '@vee-validate/zod'
|
|
110
|
-
import { z } from 'zod'
|
|
111
|
-
|
|
112
|
-
const schema = toTypedSchema(
|
|
113
|
-
z.object({
|
|
114
|
-
name: z.string().min(1, 'Name required'),
|
|
115
|
-
email: z.string().email('Invalid email'),
|
|
116
|
-
})
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
const { handleSubmit, errors, defineField } = useForm({
|
|
120
|
-
validationSchema: schema,
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
const [name, nameAttrs] = defineField('name')
|
|
124
|
-
const [email, emailAttrs] = defineField('email')
|
|
125
|
-
|
|
126
|
-
const emit = defineEmits<{
|
|
127
|
-
(e: 'submit', data: { name: string; email: string }): void
|
|
128
|
-
}>()
|
|
129
|
-
|
|
130
|
-
const onSubmit = handleSubmit((values) => {
|
|
131
|
-
emit('submit', values)
|
|
132
|
-
})
|
|
133
|
-
</script>
|
|
134
|
-
|
|
135
|
-
<template>
|
|
136
|
-
<form @submit="onSubmit">
|
|
137
|
-
<div>
|
|
138
|
-
<label for="name">Name</label>
|
|
139
|
-
<input id="name" v-model="name" v-bind="nameAttrs" />
|
|
140
|
-
<span v-if="errors.name" role="alert">{{ errors.name }}</span>
|
|
141
|
-
</div>
|
|
142
|
-
<div>
|
|
143
|
-
<label for="email">Email</label>
|
|
144
|
-
<input id="email" v-model="email" v-bind="emailAttrs" type="email" />
|
|
145
|
-
<span v-if="errors.email" role="alert">{{ errors.email }}</span>
|
|
146
|
-
</div>
|
|
147
|
-
<button type="submit">Submit</button>
|
|
148
|
-
</form>
|
|
149
|
-
</template>
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Composable
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
// composables/useCounter.ts
|
|
156
|
-
export function useCounter(initial = 0) {
|
|
157
|
-
const count = useState('counter', () => initial)
|
|
158
|
-
|
|
159
|
-
function increment() {
|
|
160
|
-
count.value++
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function decrement() {
|
|
164
|
-
count.value--
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function reset() {
|
|
168
|
-
count.value = initial
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return {
|
|
172
|
-
count: readonly(count),
|
|
173
|
-
increment,
|
|
174
|
-
decrement,
|
|
175
|
-
reset,
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
## Accessibility Checklist
|
|
181
|
-
|
|
182
|
-
- [ ] Semantic HTML elements (`<button>`, `<nav>`, `<main>`)
|
|
183
|
-
- [ ] Keyboard navigation (tab order, focus management)
|
|
184
|
-
- [ ] ARIA attributes where needed
|
|
185
|
-
- [ ] Focus indicators visible
|
|
186
|
-
- [ ] Color contrast 4.5:1 minimum
|
|
187
|
-
- [ ] Form labels associated with inputs
|
|
188
|
-
- [ ] Error messages announced to screen readers
|
|
189
|
-
|
|
190
|
-
## Naming Conventions
|
|
191
|
-
|
|
192
|
-
- Components: PascalCase (`UserCard.vue`)
|
|
193
|
-
- Composables: camelCase with `use` prefix (`useAuth.ts`)
|
|
194
|
-
- Pages: kebab-case (`user-profile.vue`)
|
|
195
|
-
- Layouts: kebab-case (`default.vue`, `dashboard.vue`)
|
|
196
|
-
|
|
197
|
-
## File Structure
|
|
198
|
-
|
|
199
|
-
```
|
|
200
|
-
components/
|
|
201
|
-
├── ui/
|
|
202
|
-
│ ├── Button.vue
|
|
203
|
-
│ ├── Card.vue
|
|
204
|
-
│ └── Modal.vue
|
|
205
|
-
├── layout/
|
|
206
|
-
│ ├── Header.vue
|
|
207
|
-
│ └── Footer.vue
|
|
208
|
-
└── feature/
|
|
209
|
-
├── UserCard.vue
|
|
210
|
-
└── ProductList.vue
|
|
211
|
-
|
|
212
|
-
composables/
|
|
213
|
-
├── useAuth.ts
|
|
214
|
-
├── useUser.ts
|
|
215
|
-
└── useCart.ts
|
|
216
|
-
|
|
217
|
-
pages/
|
|
218
|
-
├── index.vue
|
|
219
|
-
├── login.vue
|
|
220
|
-
└── users/
|
|
221
|
-
├── index.vue
|
|
222
|
-
└── [id].vue
|
|
223
|
-
```
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/components/**/*.vue"
|
|
4
|
-
- "**/pages/**/*.vue"
|
|
5
|
-
- "**/layouts/**/*.vue"
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Nuxt.js Component Standards
|
|
9
|
-
|
|
10
|
-
## Script Setup Pattern (MANDATORY)
|
|
11
|
-
|
|
12
|
-
```vue
|
|
13
|
-
<script setup lang="ts">
|
|
14
|
-
// Props with TypeScript
|
|
15
|
-
interface Props {
|
|
16
|
-
title: string
|
|
17
|
-
variant?: 'primary' | 'secondary'
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const props = withDefaults(defineProps<Props>(), {
|
|
21
|
-
variant: 'primary',
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// Emits with TypeScript
|
|
25
|
-
const emit = defineEmits<{
|
|
26
|
-
(e: 'update', value: string): void
|
|
27
|
-
(e: 'close'): void
|
|
28
|
-
}>()
|
|
29
|
-
|
|
30
|
-
// Reactive state
|
|
31
|
-
const isOpen = ref(false)
|
|
32
|
-
|
|
33
|
-
// Computed
|
|
34
|
-
const buttonClass = computed(() => `btn-${props.variant}`)
|
|
35
|
-
</script>
|
|
36
|
-
|
|
37
|
-
<template>
|
|
38
|
-
<div class="component">
|
|
39
|
-
<h2>{{ title }}</h2>
|
|
40
|
-
<button type="button" :class="buttonClass" @click="emit('close')">
|
|
41
|
-
Close
|
|
42
|
-
</button>
|
|
43
|
-
</div>
|
|
44
|
-
</template>
|
|
45
|
-
|
|
46
|
-
<style scoped>
|
|
47
|
-
.component {
|
|
48
|
-
/* Scoped styles */
|
|
49
|
-
}
|
|
50
|
-
</style>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Accessibility (WCAG 2.1 AA)
|
|
54
|
-
|
|
55
|
-
```vue
|
|
56
|
-
<!-- WRONG -->
|
|
57
|
-
<div @click="handleAction">Click me</div>
|
|
58
|
-
|
|
59
|
-
<!-- CORRECT -->
|
|
60
|
-
<button type="button" @click="handleAction">
|
|
61
|
-
Click me
|
|
62
|
-
</button>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Auto-Imports
|
|
66
|
-
|
|
67
|
-
Nuxt auto-imports these - DON'T import explicitly:
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
// Already auto-imported:
|
|
71
|
-
// ref, reactive, computed, watch, watchEffect
|
|
72
|
-
// useFetch, useAsyncData, useState, useCookie
|
|
73
|
-
// useHead, useSeoMeta, useRoute, useRouter
|
|
74
|
-
// navigateTo, definePageMeta
|
|
75
|
-
|
|
76
|
-
// WRONG - unnecessary import
|
|
77
|
-
import { ref, computed } from 'vue'
|
|
78
|
-
|
|
79
|
-
// CORRECT - just use directly
|
|
80
|
-
const count = ref(0)
|
|
81
|
-
const doubled = computed(() => count.value * 2)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Path Aliases
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
// CORRECT
|
|
88
|
-
import { useAuth } from '~/composables/useAuth'
|
|
89
|
-
import type { User } from '~/types/user'
|
|
90
|
-
|
|
91
|
-
// WRONG
|
|
92
|
-
import { useAuth } from '../../../composables/useAuth'
|
|
93
|
-
import { useAuth } from '@/composables/useAuth' // Use ~/ for Nuxt
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Forbidden Patterns
|
|
97
|
-
|
|
98
|
-
- Options API (use Composition API with `<script setup>`)
|
|
99
|
-
- Explicit imports for auto-imported items
|
|
100
|
-
- `any` type
|
|
101
|
-
- Non-semantic interactive elements
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/composables/**/*.ts"
|
|
4
|
-
- "**/composables/**/*.js"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Nuxt.js Composables Standards
|
|
8
|
-
|
|
9
|
-
## Structure
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
interface UseUserOptions {
|
|
13
|
-
immediate?: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface UseUserReturn {
|
|
17
|
-
user: Ref<User | null>
|
|
18
|
-
isLoading: Ref<boolean>
|
|
19
|
-
error: Ref<Error | null>
|
|
20
|
-
refresh: () => Promise<void>
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function useUser(userId: string, options: UseUserOptions = {}): UseUserReturn {
|
|
24
|
-
const { immediate = true } = options
|
|
25
|
-
|
|
26
|
-
const user = ref<User | null>(null)
|
|
27
|
-
const isLoading = ref(false)
|
|
28
|
-
const error = ref<Error | null>(null)
|
|
29
|
-
|
|
30
|
-
async function refresh() {
|
|
31
|
-
isLoading.value = true
|
|
32
|
-
try {
|
|
33
|
-
const { data } = await useFetch<User>(`/api/users/${userId}`)
|
|
34
|
-
user.value = data.value
|
|
35
|
-
error.value = null
|
|
36
|
-
} catch (e) {
|
|
37
|
-
error.value = e instanceof Error ? e : new Error('Unknown error')
|
|
38
|
-
} finally {
|
|
39
|
-
isLoading.value = false
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (immediate) {
|
|
44
|
-
refresh()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return { user, isLoading, error, refresh }
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Naming Convention
|
|
52
|
-
|
|
53
|
-
- File: `use{Name}.ts`
|
|
54
|
-
- Function: `use{Name}`
|
|
55
|
-
- Always export named function
|
|
56
|
-
- Located in `~/composables/`
|
|
57
|
-
|
|
58
|
-
## Auto-Import Behavior
|
|
59
|
-
|
|
60
|
-
Composables in `~/composables/` are auto-imported:
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
// In any component - no import needed
|
|
64
|
-
const { user, isLoading } = useUser('123')
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## Data Fetching Pattern
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
// Using useFetch (auto-imported)
|
|
71
|
-
export function useProducts() {
|
|
72
|
-
const { data, pending, error, refresh } = useFetch<Product[]>('/api/products', {
|
|
73
|
-
key: 'products',
|
|
74
|
-
default: () => [],
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
products: data,
|
|
79
|
-
isLoading: pending,
|
|
80
|
-
error,
|
|
81
|
-
refresh,
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Using useAsyncData with custom fetch
|
|
86
|
-
export function useProduct(id: string) {
|
|
87
|
-
return useAsyncData(`product-${id}`, () => {
|
|
88
|
-
return $fetch<Product>(`/api/products/${id}`)
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## State Management Pattern
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
// Shared state across components
|
|
97
|
-
export function useCounter() {
|
|
98
|
-
// useState is auto-imported and persists across navigation
|
|
99
|
-
const count = useState('counter', () => 0)
|
|
100
|
-
|
|
101
|
-
function increment() {
|
|
102
|
-
count.value++
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function decrement() {
|
|
106
|
-
count.value--
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return { count, increment, decrement }
|
|
110
|
-
}
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Forbidden Patterns
|
|
114
|
-
|
|
115
|
-
- Options API style composables
|
|
116
|
-
- Explicit import of auto-imported functions
|
|
117
|
-
- Mutable shared state without useState
|
|
118
|
-
- Missing TypeScript types
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- "**/server/api/**/*.ts"
|
|
4
|
-
- "**/server/routes/**/*.ts"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Nuxt.js Server Routes Standards
|
|
8
|
-
|
|
9
|
-
## Structure
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
import { z } from 'zod'
|
|
13
|
-
|
|
14
|
-
const createUserSchema = z.object({
|
|
15
|
-
email: z.string().email(),
|
|
16
|
-
name: z.string().min(1),
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
export default defineEventHandler(async (event) => {
|
|
20
|
-
// Read and validate body
|
|
21
|
-
const body = await readBody(event)
|
|
22
|
-
const result = createUserSchema.safeParse(body)
|
|
23
|
-
|
|
24
|
-
if (!result.success) {
|
|
25
|
-
throw createError({
|
|
26
|
-
statusCode: 400,
|
|
27
|
-
message: 'Validation error',
|
|
28
|
-
data: result.error.issues,
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Business logic
|
|
33
|
-
const user = await createUser(result.data)
|
|
34
|
-
|
|
35
|
-
// Return response
|
|
36
|
-
return user
|
|
37
|
-
})
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Requirements
|
|
41
|
-
|
|
42
|
-
- Zod validation for inputs
|
|
43
|
-
- Proper error handling with createError
|
|
44
|
-
- TypeScript types
|
|
45
|
-
- No secrets in responses
|
|
46
|
-
|
|
47
|
-
## Event Handlers
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
// GET /api/users
|
|
51
|
-
export default defineEventHandler(async (event) => {
|
|
52
|
-
const query = getQuery(event)
|
|
53
|
-
return await getUsers(query)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
// POST /api/users
|
|
57
|
-
export default defineEventHandler(async (event) => {
|
|
58
|
-
const body = await readBody(event)
|
|
59
|
-
return await createUser(body)
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// GET /api/users/[id]
|
|
63
|
-
export default defineEventHandler(async (event) => {
|
|
64
|
-
const id = getRouterParam(event, 'id')
|
|
65
|
-
return await getUser(id)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
// PATCH /api/users/[id]
|
|
69
|
-
export default defineEventHandler(async (event) => {
|
|
70
|
-
const id = getRouterParam(event, 'id')
|
|
71
|
-
const body = await readBody(event)
|
|
72
|
-
return await updateUser(id, body)
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
// DELETE /api/users/[id]
|
|
76
|
-
export default defineEventHandler(async (event) => {
|
|
77
|
-
const id = getRouterParam(event, 'id')
|
|
78
|
-
await deleteUser(id)
|
|
79
|
-
return { success: true }
|
|
80
|
-
})
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Error Handling
|
|
84
|
-
|
|
85
|
-
```typescript
|
|
86
|
-
export default defineEventHandler(async (event) => {
|
|
87
|
-
const id = getRouterParam(event, 'id')
|
|
88
|
-
|
|
89
|
-
const user = await getUser(id)
|
|
90
|
-
|
|
91
|
-
if (!user) {
|
|
92
|
-
throw createError({
|
|
93
|
-
statusCode: 404,
|
|
94
|
-
message: `User ${id} not found`,
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return user
|
|
99
|
-
})
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Authentication
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
export default defineEventHandler(async (event) => {
|
|
106
|
-
// Check session/auth
|
|
107
|
-
const session = await getUserSession(event)
|
|
108
|
-
|
|
109
|
-
if (!session) {
|
|
110
|
-
throw createError({
|
|
111
|
-
statusCode: 401,
|
|
112
|
-
message: 'Unauthorized',
|
|
113
|
-
})
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Proceed with authenticated request
|
|
117
|
-
return await getProtectedData(session.user.id)
|
|
118
|
-
})
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
## Forbidden Patterns
|
|
122
|
-
|
|
123
|
-
- Unvalidated inputs
|
|
124
|
-
- Exposing stack traces
|
|
125
|
-
- Hardcoded secrets
|
|
126
|
-
- Missing error handling
|
|
127
|
-
- Any type
|