nuxt-ignis 0.3.1 → 0.3.3
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/.data/content/contents.sqlite +0 -0
- package/.env +3 -3
- package/.nuxt/app.config.mjs +227 -1
- package/.nuxt/components.d.ts +372 -140
- package/.nuxt/content/components.ts +93 -36
- package/.nuxt/dev/index.mjs +7609 -0
- package/.nuxt/dev/index.mjs.map +1 -0
- package/.nuxt/dist/server/client.manifest.json +2 -2
- package/.nuxt/dist/server/client.manifest.mjs +2 -2
- package/.nuxt/eslint.config.d.mts +2 -2
- package/.nuxt/eslint.config.mjs +2 -2
- package/.nuxt/imports.d.ts +59 -42
- package/.nuxt/manifest/latest.json +1 -1
- package/.nuxt/manifest/meta/dev.json +1 -1
- package/.nuxt/module/@nuxtjs-sitemap.d.ts +8 -8
- package/.nuxt/module/nuxt-robots.d.ts +3 -3
- package/.nuxt/module/nuxt-seo-utils.d.ts +6 -6
- package/.nuxt/module/nuxt-site-config.d.ts +8 -8
- package/.nuxt/nitro.json +4 -4
- package/.nuxt/nuxt.d.ts +11 -9
- package/.nuxt/nuxt.json +2 -2
- package/.nuxt/schema/nuxt.schema.d.ts +193 -0
- package/.nuxt/schema/nuxt.schema.json +261 -1
- package/.nuxt/tsconfig.json +133 -110
- package/.nuxt/tsconfig.server.json +82 -64
- package/.nuxt/types/app.config.d.ts +227 -1
- package/.nuxt/types/build.d.ts +2 -1
- package/.nuxt/types/i18n-plugin.d.ts +2 -2
- package/.nuxt/types/imports.d.ts +320 -264
- package/.nuxt/types/neon.d.ts +136 -34
- package/.nuxt/types/nitro-imports.d.ts +40 -40
- package/.nuxt/types/nitro-routes.d.ts +21 -18
- package/.nuxt/types/plugins.d.ts +38 -33
- package/.nuxt/types/schema.d.ts +110 -36
- package/.nuxt/types/ui.d.ts +1 -1
- package/.nuxt/ui/checkbox-group.ts +1 -1
- package/.nuxt/ui/context-menu.ts +2 -1
- package/.nuxt/ui/dropdown-menu.ts +2 -1
- package/.nuxt/ui/input-menu.ts +2 -2
- package/.nuxt/ui/navigation-menu.ts +43 -34
- package/.nuxt/ui/radio-group.ts +1 -1
- package/.nuxt/ui/select-menu.ts +2 -2
- package/.nuxt/ui/select.ts +2 -2
- package/.nuxt/ui/tooltip.ts +1 -1
- package/.nuxt/ui.css +4 -1
- package/app.vue +2 -2
- package/components/AppFeatureList.vue +5 -0
- package/composables/useValibot.ts +16 -0
- package/composables/useZod.ts +16 -0
- package/content.config.ts +6 -10
- package/features.ts +59 -6
- package/i18n/locales/en.json +2 -0
- package/nuxt.config.ts +15 -5
- package/package.json +20 -16
- package/plugins/errorHandler.ts +26 -0
- package/server/api/neonTest.ts +7 -5
- package/test/config/default.txt +16 -0
- package/test/config/equipment-1-composable.txt +22 -0
- package/test/config/equipment-2-plugins.txt +23 -0
- package/test/config/equipment-all.txt +28 -0
- package/test/config.test.ts +47 -0
- package/test/features/db-neon.txt +3 -0
- package/test/features/db-off.txt +3 -0
- package/test/features/db-supabase.txt +3 -0
- package/test/features/default.txt +3 -0
- package/test/features/disable-core.txt +3 -0
- package/test/features/enable-all.txt +4 -0
- package/test/features/equipment.txt +3 -0
- package/test/features/forms-formkit.txt +3 -0
- package/test/features/forms-off.txt +3 -0
- package/test/features/forms-vueform.txt +3 -0
- package/test/features/ui-nuxt-ui.txt +3 -0
- package/test/features/ui-off.txt +3 -0
- package/test/features/ui-tailwind.txt +4 -0
- package/test/features/validation-off.txt +3 -0
- package/test/features/validation-valibot.txt +4 -0
- package/test/features/validation-zod.txt +4 -0
- package/test/features.test.ts +239 -0
- package/utils/config/content.ts +35 -0
- package/utils/config/vueform.ts +25 -0
- package/utils/consola.ts +23 -13
- package/utils/content.ts +18 -0
- package/utils/tailwind.ts +19 -0
- package/utils/vueform.ts +19 -0
- package/vueform.config.ts +4 -18
- package/.nuxt/component-chunk.mjs +0 -1
- package/.nuxt/dist/server/server.mjs +0 -1
- package/.nuxt/tailwind/postcss.mjs +0 -15
|
@@ -43,24 +43,25 @@ export default {
|
|
|
43
43
|
"linkLeadingIcon": "shrink-0 size-5",
|
|
44
44
|
"linkLeadingAvatar": "shrink-0",
|
|
45
45
|
"linkLeadingAvatarSize": "2xs",
|
|
46
|
-
"linkTrailing": "ms-auto inline-flex gap-1.5 items-center",
|
|
46
|
+
"linkTrailing": "group ms-auto inline-flex gap-1.5 items-center",
|
|
47
47
|
"linkTrailingBadge": "shrink-0",
|
|
48
48
|
"linkTrailingBadgeSize": "sm",
|
|
49
49
|
"linkTrailingIcon": "size-5 transform shrink-0 group-data-[state=open]:rotate-180 transition-transform duration-200",
|
|
50
50
|
"linkLabel": "truncate",
|
|
51
51
|
"linkLabelExternalIcon": "inline-block size-3 align-top text-dimmed",
|
|
52
|
-
"childList": "",
|
|
52
|
+
"childList": "isolate",
|
|
53
|
+
"childLabel": "text-xs text-highlighted",
|
|
53
54
|
"childItem": "",
|
|
54
|
-
"childLink": "group size-full
|
|
55
|
-
"childLinkWrapper": "
|
|
55
|
+
"childLink": "group relative size-full flex items-start text-start text-sm before:absolute before:z-[-1] before:rounded-md focus:outline-none focus-visible:outline-none dark:focus-visible:outline-none focus-visible:before:ring-inset focus-visible:before:ring-2",
|
|
56
|
+
"childLinkWrapper": "min-w-0",
|
|
56
57
|
"childLinkIcon": "size-5 shrink-0",
|
|
57
|
-
"childLinkLabel": "
|
|
58
|
+
"childLinkLabel": "truncate",
|
|
58
59
|
"childLinkLabelExternalIcon": "inline-block size-3 align-top text-dimmed",
|
|
59
|
-
"childLinkDescription": "text-
|
|
60
|
+
"childLinkDescription": "text-muted",
|
|
60
61
|
"separator": "px-2 h-px bg-border",
|
|
61
62
|
"viewportWrapper": "absolute top-full left-0 flex w-full",
|
|
62
63
|
"viewport": "relative overflow-hidden bg-default shadow-lg rounded-md ring ring-default h-(--reka-navigation-menu-viewport-height) w-full transition-[width,height,left] duration-200 origin-[top_center] data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] z-[1]",
|
|
63
|
-
"content": "
|
|
64
|
+
"content": "",
|
|
64
65
|
"indicator": "absolute data-[state=visible]:animate-[fade-in_100ms_ease-out] data-[state=hidden]:animate-[fade-out_100ms_ease-in] data-[state=hidden]:opacity-0 bottom-0 z-[2] w-(--reka-navigation-menu-indicator-size) translate-x-(--reka-navigation-menu-indicator-position) flex h-2.5 items-end justify-center overflow-hidden transition-[translate,width] duration-200",
|
|
65
66
|
"arrow": "relative top-[50%] size-2.5 rotate-45 border border-default bg-default z-[1] rounded-xs"
|
|
66
67
|
},
|
|
@@ -68,31 +69,31 @@ export default {
|
|
|
68
69
|
"color": {
|
|
69
70
|
"primary": {
|
|
70
71
|
"link": "focus-visible:before:ring-primary",
|
|
71
|
-
"childLink": "focus-visible:
|
|
72
|
+
"childLink": "focus-visible:before:ring-primary"
|
|
72
73
|
},
|
|
73
74
|
"secondary": {
|
|
74
75
|
"link": "focus-visible:before:ring-secondary",
|
|
75
|
-
"childLink": "focus-visible:
|
|
76
|
+
"childLink": "focus-visible:before:ring-secondary"
|
|
76
77
|
},
|
|
77
78
|
"success": {
|
|
78
79
|
"link": "focus-visible:before:ring-success",
|
|
79
|
-
"childLink": "focus-visible:
|
|
80
|
+
"childLink": "focus-visible:before:ring-success"
|
|
80
81
|
},
|
|
81
82
|
"info": {
|
|
82
83
|
"link": "focus-visible:before:ring-info",
|
|
83
|
-
"childLink": "focus-visible:
|
|
84
|
+
"childLink": "focus-visible:before:ring-info"
|
|
84
85
|
},
|
|
85
86
|
"warning": {
|
|
86
87
|
"link": "focus-visible:before:ring-warning",
|
|
87
|
-
"childLink": "focus-visible:
|
|
88
|
+
"childLink": "focus-visible:before:ring-warning"
|
|
88
89
|
},
|
|
89
90
|
"error": {
|
|
90
91
|
"link": "focus-visible:before:ring-error",
|
|
91
|
-
"childLink": "focus-visible:
|
|
92
|
+
"childLink": "focus-visible:before:ring-error"
|
|
92
93
|
},
|
|
93
94
|
"neutral": {
|
|
94
95
|
"link": "focus-visible:before:ring-inverted",
|
|
95
|
-
"childLink": "focus-visible:
|
|
96
|
+
"childLink": "focus-visible:before:ring-inverted"
|
|
96
97
|
}
|
|
97
98
|
},
|
|
98
99
|
"highlightColor": {
|
|
@@ -114,11 +115,16 @@ export default {
|
|
|
114
115
|
"list": "flex items-center",
|
|
115
116
|
"item": "py-2",
|
|
116
117
|
"link": "px-2.5 py-1.5 before:inset-x-px before:inset-y-0",
|
|
117
|
-
"childList": "grid p-2"
|
|
118
|
+
"childList": "grid p-2",
|
|
119
|
+
"childLink": "px-3 py-2 gap-2 before:inset-x-px before:inset-y-0",
|
|
120
|
+
"childLinkLabel": "font-medium",
|
|
121
|
+
"content": "absolute top-0 left-0 w-full"
|
|
118
122
|
},
|
|
119
123
|
"vertical": {
|
|
120
124
|
"root": "flex-col",
|
|
121
|
-
"link": "flex-row px-2.5 py-1.5 before:inset-y-px before:inset-x-0"
|
|
125
|
+
"link": "flex-row px-2.5 py-1.5 before:inset-y-px before:inset-x-0",
|
|
126
|
+
"childLabel": "px-1.5 py-0.5",
|
|
127
|
+
"childLink": "p-1.5 gap-1.5 before:inset-y-px before:inset-x-0"
|
|
122
128
|
}
|
|
123
129
|
},
|
|
124
130
|
"contentOrientation": {
|
|
@@ -132,15 +138,15 @@ export default {
|
|
|
132
138
|
},
|
|
133
139
|
"active": {
|
|
134
140
|
"true": {
|
|
135
|
-
"childLink": "bg-elevated text-highlighted",
|
|
141
|
+
"childLink": "before:bg-elevated text-highlighted",
|
|
136
142
|
"childLinkIcon": "text-default"
|
|
137
143
|
},
|
|
138
144
|
"false": {
|
|
139
145
|
"link": "text-muted",
|
|
140
146
|
"linkLeadingIcon": "text-dimmed",
|
|
141
147
|
"childLink": [
|
|
142
|
-
"hover:bg-elevated/50 text-default hover:text-highlighted",
|
|
143
|
-
"transition-colors"
|
|
148
|
+
"hover:before:bg-elevated/50 text-default hover:text-highlighted",
|
|
149
|
+
"transition-colors before:transition-colors"
|
|
144
150
|
],
|
|
145
151
|
"childLinkIcon": [
|
|
146
152
|
"text-dimmed group-hover:text-default",
|
|
@@ -179,6 +185,23 @@ export default {
|
|
|
179
185
|
"content": "w-60"
|
|
180
186
|
}
|
|
181
187
|
},
|
|
188
|
+
{
|
|
189
|
+
"orientation": "vertical" as typeof orientation[number],
|
|
190
|
+
"collapsed": false,
|
|
191
|
+
"class": {
|
|
192
|
+
"childList": "ms-5 border-s border-default",
|
|
193
|
+
"childItem": "ps-1.5 -ms-px",
|
|
194
|
+
"content": "data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden"
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"orientation": "vertical" as typeof orientation[number],
|
|
199
|
+
"collapsed": true,
|
|
200
|
+
"class": {
|
|
201
|
+
"link": "px-1.5",
|
|
202
|
+
"content": "shadow-sm rounded-sm min-h-6 p-1"
|
|
203
|
+
}
|
|
204
|
+
},
|
|
182
205
|
{
|
|
183
206
|
"orientation": "horizontal" as typeof orientation[number],
|
|
184
207
|
"highlight": true,
|
|
@@ -319,6 +342,7 @@ export default {
|
|
|
319
342
|
"variant": "pill" as typeof variant[number],
|
|
320
343
|
"active": true,
|
|
321
344
|
"highlight": true,
|
|
345
|
+
"disabled": false,
|
|
322
346
|
"class": {
|
|
323
347
|
"link": [
|
|
324
348
|
"hover:before:bg-elevated/50",
|
|
@@ -476,21 +500,6 @@ export default {
|
|
|
476
500
|
"class": {
|
|
477
501
|
"link": "after:bg-inverted"
|
|
478
502
|
}
|
|
479
|
-
},
|
|
480
|
-
{
|
|
481
|
-
"orientation": "vertical" as typeof orientation[number],
|
|
482
|
-
"collapsed": false,
|
|
483
|
-
"class": {
|
|
484
|
-
"childList": "ms-5 border-s border-default",
|
|
485
|
-
"childItem": "ps-1.5 -ms-px"
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
{
|
|
489
|
-
"orientation": "vertical" as typeof orientation[number],
|
|
490
|
-
"collapsed": true,
|
|
491
|
-
"class": {
|
|
492
|
-
"link": "px-1.5"
|
|
493
|
-
}
|
|
494
503
|
}
|
|
495
504
|
],
|
|
496
505
|
"defaultVariants": {
|
package/.nuxt/ui/radio-group.ts
CHANGED
|
@@ -219,7 +219,7 @@ export default {
|
|
|
219
219
|
"orientation": "horizontal" as typeof orientation[number],
|
|
220
220
|
"variant": "table" as typeof variant[number],
|
|
221
221
|
"class": {
|
|
222
|
-
"item": "first-of-type:rounded-
|
|
222
|
+
"item": "first-of-type:rounded-s-lg last-of-type:rounded-e-lg",
|
|
223
223
|
"fieldset": "gap-0 -space-x-px"
|
|
224
224
|
}
|
|
225
225
|
},
|
package/.nuxt/ui/select-menu.ts
CHANGED
|
@@ -40,10 +40,10 @@ export default {
|
|
|
40
40
|
"placeholder": "truncate text-dimmed",
|
|
41
41
|
"arrow": "fill-default",
|
|
42
42
|
"content": [
|
|
43
|
-
"max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto",
|
|
43
|
+
"max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto flex flex-col",
|
|
44
44
|
"origin-(--reka-combobox-content-transform-origin) w-(--reka-combobox-trigger-width)"
|
|
45
45
|
],
|
|
46
|
-
"viewport": "divide-y divide-default scroll-py-1",
|
|
46
|
+
"viewport": "relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1",
|
|
47
47
|
"group": "p-1 isolate",
|
|
48
48
|
"empty": "py-2 text-center text-sm text-muted",
|
|
49
49
|
"label": "font-semibold text-highlighted",
|
package/.nuxt/ui/select.ts
CHANGED
|
@@ -39,8 +39,8 @@ export default {
|
|
|
39
39
|
"value": "truncate pointer-events-none",
|
|
40
40
|
"placeholder": "truncate text-dimmed",
|
|
41
41
|
"arrow": "fill-default",
|
|
42
|
-
"content": "max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto",
|
|
43
|
-
"viewport": "divide-y divide-default scroll-py-1",
|
|
42
|
+
"content": "max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto flex flex-col",
|
|
43
|
+
"viewport": "relative divide-y divide-default scroll-py-1 overflow-y-auto flex-1",
|
|
44
44
|
"group": "p-1 isolate",
|
|
45
45
|
"empty": "py-2 text-center text-sm text-muted",
|
|
46
46
|
"label": "font-semibold text-highlighted",
|
package/.nuxt/ui/tooltip.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"slots": {
|
|
3
|
-
"content": "flex items-center gap-1 bg-default text-highlighted shadow-sm rounded-sm ring ring-default h-6 px-2 py-1 text-xs select-none data-[state=delayed-open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-tooltip-content-transform-origin) pointer-events-auto",
|
|
3
|
+
"content": "flex items-center gap-1 bg-default text-highlighted shadow-sm rounded-sm ring ring-default h-6 px-2.5 py-1 text-xs select-none data-[state=delayed-open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-tooltip-content-transform-origin) pointer-events-auto",
|
|
4
4
|
"arrow": "fill-default",
|
|
5
5
|
"text": "truncate",
|
|
6
6
|
"kbds": "hidden lg:inline-flex items-center shrink-0 gap-0.5 before:content-['·'] before:me-0.5",
|
package/.nuxt/ui.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
@source "./ui";
|
|
2
2
|
|
|
3
|
-
@theme
|
|
3
|
+
@theme static {
|
|
4
4
|
--color-old-neutral-50: oklch(98.5% 0 0);
|
|
5
5
|
--color-old-neutral-100: oklch(97% 0 0);
|
|
6
6
|
--color-old-neutral-200: oklch(92.2% 0 0);
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
--color-old-neutral-800: oklch(26.9% 0 0);
|
|
13
13
|
--color-old-neutral-900: oklch(20.5% 0 0);
|
|
14
14
|
--color-old-neutral-950: oklch(14.5% 0 0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@theme default inline {
|
|
15
18
|
--color-primary-50: var(--ui-color-primary-50);
|
|
16
19
|
--color-primary-100: var(--ui-color-primary-100);
|
|
17
20
|
--color-primary-200: var(--ui-color-primary-200);
|
package/app.vue
CHANGED
|
@@ -21,11 +21,11 @@ useHead({
|
|
|
21
21
|
})
|
|
22
22
|
initConsola()
|
|
23
23
|
|
|
24
|
-
log.info('Nuxt Ignis was here!')
|
|
25
|
-
|
|
26
24
|
const config = useRuntimeConfig().public.ignis
|
|
27
25
|
const pages = config.pages
|
|
28
26
|
const ui = config.ui || config.preset.ui
|
|
27
|
+
|
|
28
|
+
log.info('Nuxt Ignis initialized')
|
|
29
29
|
</script>
|
|
30
30
|
|
|
31
31
|
<style scoped>
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
<AppFeature :active="i18n" :text="useIgnisT('features.i18n')" />
|
|
31
31
|
<AppFeature :active="vueform" :text="useIgnisT('features.vueform')" />
|
|
32
32
|
<AppFeature :active="formkit" :text="useIgnisT('features.formkit')" />
|
|
33
|
+
<AppFeature :active="valibot" :text="useIgnisT('features.valibot')" />
|
|
34
|
+
<AppFeature :active="zod" :text="useIgnisT('features.zod')" />
|
|
33
35
|
<AppFeature :active="content" :text="useIgnisT('features.content')" />
|
|
34
36
|
<AppFeature :active="seo" :text="useIgnisT('features.seo')" />
|
|
35
37
|
<AppFeature :active="auth" :text="useIgnisT('features.auth')" />
|
|
@@ -63,6 +65,9 @@ const i18n = setup.i18n.enabled
|
|
|
63
65
|
const forms = setup.preset.forms
|
|
64
66
|
const vueform = forms === 'vueform' || (forms === 'off' && setup.vueform)
|
|
65
67
|
const formkit = forms === 'formkit' || (forms === 'off' && setup.formkit.enabled)
|
|
68
|
+
const validation = setup.preset.validation
|
|
69
|
+
const valibot = validation === 'valibot' || (validation === 'off' && setup.valibot)
|
|
70
|
+
const zod = validation === 'zod' || (validation === 'off' && setup.zod)
|
|
66
71
|
const content = setup.content
|
|
67
72
|
const seo = setup.seo
|
|
68
73
|
const auth = setup.auth
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exposes Valibot schema validation functions. Requires `NUXT_PUBLIC_IGNIS_PRESET_VALIDATION=valibot` or `NUXT_PUBLIC_IGNIS_VALIBOT=true` to work properly.
|
|
3
|
+
*
|
|
4
|
+
* Usage: `const v = (await useValibot())!`
|
|
5
|
+
*
|
|
6
|
+
* @returns Valibot `v` object for schema validation
|
|
7
|
+
*/
|
|
8
|
+
export const useValibot = async () => {
|
|
9
|
+
const config = useRuntimeConfig().public.ignis
|
|
10
|
+
if (config.preset.validation === 'valibot' || config.valibot === true) {
|
|
11
|
+
const valibot = await import('valibot')
|
|
12
|
+
return valibot
|
|
13
|
+
} else {
|
|
14
|
+
log.warn('Valibot is not enabled (set NUXT_PUBLIC_IGNIS_PRESET_VALIDATION=valibot or NUXT_PUBLIC_IGNIS_VALIBOT=true)')
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exposes Zod schema validation functions. Requires `NUXT_PUBLIC_IGNIS_PRESET_VALIDATION=zod` or `NUXT_PUBLIC_IGNIS_ZOD=true` to work properly.
|
|
3
|
+
*
|
|
4
|
+
* Usage: `const z = (await useZod())!`
|
|
5
|
+
*
|
|
6
|
+
* @returns Zod `z` object for schema validation
|
|
7
|
+
*/
|
|
8
|
+
export const useZod = async () => {
|
|
9
|
+
const config = useRuntimeConfig().public.ignis
|
|
10
|
+
if (config.preset.validation === 'zod' || config.zod === true) {
|
|
11
|
+
const zod = await import('zod/v4')
|
|
12
|
+
return zod.z
|
|
13
|
+
} else {
|
|
14
|
+
log.warn('Zod is not enabled (set NUXT_PUBLIC_IGNIS_PRESET_VALIDATION=zod or NUXT_PUBLIC_IGNIS_ZOD=true)')
|
|
15
|
+
}
|
|
16
|
+
}
|
package/content.config.ts
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
// minimal config for Nuxt Content
|
|
2
|
+
// currently required to be loaded like this...
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
content: defineCollection({
|
|
8
|
-
source: '**',
|
|
9
|
-
type: 'page',
|
|
10
|
-
}),
|
|
11
|
-
},
|
|
4
|
+
import { loadContentConfig } from './utils/content'
|
|
5
|
+
|
|
6
|
+
export default loadContentConfig({
|
|
7
|
+
// custom config here
|
|
12
8
|
})
|
package/features.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { defu } from 'defu'
|
|
|
4
4
|
import OpenProps from 'open-props'
|
|
5
5
|
import tailwindcss from '@tailwindcss/vite'
|
|
6
6
|
import { log } from './utils/consola'
|
|
7
|
+
import { ignisTailwindcssFix } from './utils/tailwind'
|
|
7
8
|
|
|
8
9
|
const currentDir = dirname(fileURLToPath(import.meta.url))
|
|
9
10
|
|
|
@@ -37,11 +38,6 @@ export function setFeatures() {
|
|
|
37
38
|
nuxtConfig.modules.push('@nuxt/image')
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
// https://pinia.vuejs.org/ssr/nuxt.html
|
|
41
|
-
if (process.env.NUXT_PUBLIC_IGNIS_CORE_PINIA !== 'false') {
|
|
42
|
-
nuxtConfig.modules.push('@pinia/nuxt')
|
|
43
|
-
}
|
|
44
|
-
|
|
45
41
|
// https://scripts.nuxt.com/
|
|
46
42
|
if (process.env.NUXT_PUBLIC_IGNIS_CORE_SCRIPTS !== 'false') {
|
|
47
43
|
nuxtConfig.modules.push('@nuxt/scripts')
|
|
@@ -57,6 +53,11 @@ export function setFeatures() {
|
|
|
57
53
|
nuxtConfig.modules.push('@vueuse/nuxt')
|
|
58
54
|
}
|
|
59
55
|
|
|
56
|
+
// https://pinia.vuejs.org/ssr/nuxt.html
|
|
57
|
+
if (process.env.NUXT_PUBLIC_IGNIS_CORE_PINIA !== 'false') {
|
|
58
|
+
nuxtConfig.modules.push('@pinia/nuxt')
|
|
59
|
+
}
|
|
60
|
+
|
|
60
61
|
// 2. optional modules & features
|
|
61
62
|
// (excluded unless enabled)
|
|
62
63
|
|
|
@@ -67,7 +68,9 @@ export function setFeatures() {
|
|
|
67
68
|
process.env.NUXT_PUBLIC_IGNIS_PRESET_UI = uiPreset = 'off'
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
let tailwindFixRequired = false
|
|
70
72
|
if (uiPreset === 'nuxt-ui' || process.env.NUXT_PUBLIC_IGNIS_UI === 'true') {
|
|
73
|
+
tailwindFixRequired = true
|
|
71
74
|
nuxtConfig.modules.push('@nuxt/ui')
|
|
72
75
|
// import tailwind css file
|
|
73
76
|
nuxtConfig = defu({
|
|
@@ -85,6 +88,7 @@ export function setFeatures() {
|
|
|
85
88
|
|
|
86
89
|
// evaluate separate Tailwind CSS module
|
|
87
90
|
if (uiPreset === 'tailwind' || (process.env.NUXT_PUBLIC_IGNIS_TAILWIND === 'true' && uiPreset !== 'nuxt-ui')) {
|
|
91
|
+
tailwindFixRequired = true
|
|
88
92
|
// nuxtConfig.modules.push('@nuxtjs/tailwindcss') // temporary disabled until v7 is released
|
|
89
93
|
extras.push('Tailwind CSS')
|
|
90
94
|
// import tailwind css file
|
|
@@ -97,6 +101,15 @@ export function setFeatures() {
|
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
// TODO occasionaly check https://github.com/tailwindlabs/tailwindcss/discussions/16119 for solution
|
|
105
|
+
if (tailwindFixRequired) {
|
|
106
|
+
nuxtConfig = defu({
|
|
107
|
+
vite: {
|
|
108
|
+
plugins: [ignisTailwindcssFix],
|
|
109
|
+
},
|
|
110
|
+
}, nuxtConfig)
|
|
111
|
+
}
|
|
112
|
+
|
|
100
113
|
// database
|
|
101
114
|
let dbPreset = process.env.NUXT_PUBLIC_IGNIS_PRESET_DB
|
|
102
115
|
if (dbPreset && !['neon', 'supabase'].includes(dbPreset)) {
|
|
@@ -163,6 +176,19 @@ export function setFeatures() {
|
|
|
163
176
|
}, nuxtConfig)
|
|
164
177
|
}
|
|
165
178
|
|
|
179
|
+
// validation
|
|
180
|
+
let validationPreset = process.env.NUXT_PUBLIC_IGNIS_PRESET_VALIDATION
|
|
181
|
+
if (validationPreset && !['zod', 'valibot'].includes(validationPreset)) {
|
|
182
|
+
// surpress other values
|
|
183
|
+
process.env.NUXT_PUBLIC_IGNIS_PRESET_VALIDATION = validationPreset = 'off'
|
|
184
|
+
}
|
|
185
|
+
if (validationPreset === 'zod' || process.env.NUXT_PUBLIC_IGNIS_ZOD === 'true') {
|
|
186
|
+
extras.push('zod')
|
|
187
|
+
}
|
|
188
|
+
if (validationPreset === 'valibot' || process.env.NUXT_PUBLIC_IGNIS_VALIBOT === 'true') {
|
|
189
|
+
extras.push('valibot')
|
|
190
|
+
}
|
|
191
|
+
|
|
166
192
|
// seo
|
|
167
193
|
// 2025/04 - must be before @nuxt/content (https://nuxtseo.com/docs/nuxt-seo/guides/nuxt-content)
|
|
168
194
|
if (process.env.NUXT_PUBLIC_IGNIS_SEO === 'true') {
|
|
@@ -188,6 +214,29 @@ export function setFeatures() {
|
|
|
188
214
|
nuxtConfig.modules.push('nuxt-auth-utils')
|
|
189
215
|
}
|
|
190
216
|
|
|
217
|
+
// https://www.vue.equipment/
|
|
218
|
+
if (process.env.NUXT_PUBLIC_IGNIS_EQUIPMENT_ENABLED === 'true') {
|
|
219
|
+
nuxtConfig.modules.push('@maas/vue-equipment/nuxt')
|
|
220
|
+
// composables to be included
|
|
221
|
+
if (process.env.NUXT_PUBLIC_IGNIS_EQUIPMENT_COMPOSABLES) {
|
|
222
|
+
// values MUST be delimited by "," (spaces will be trimmed)
|
|
223
|
+
nuxtConfig = defu({
|
|
224
|
+
vueEquipment: {
|
|
225
|
+
composables: process.env.NUXT_PUBLIC_IGNIS_EQUIPMENT_COMPOSABLES.split(',').map(p => p?.trim()),
|
|
226
|
+
},
|
|
227
|
+
}, nuxtConfig)
|
|
228
|
+
}
|
|
229
|
+
// plugins to be included
|
|
230
|
+
if (process.env.NUXT_PUBLIC_IGNIS_EQUIPMENT_PLUGINS) {
|
|
231
|
+
// values MUST be delimited by "," (spaces will be trimmed)
|
|
232
|
+
nuxtConfig = defu({
|
|
233
|
+
vueEquipment: {
|
|
234
|
+
plugins: process.env.NUXT_PUBLIC_IGNIS_EQUIPMENT_PLUGINS.split(',').map(p => p?.trim()),
|
|
235
|
+
},
|
|
236
|
+
}, nuxtConfig)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
191
240
|
// Open Props CSS
|
|
192
241
|
if (process.env.NUXT_PUBLIC_IGNIS_OPENPROPS === 'true') {
|
|
193
242
|
extras.push('Open Props CSS')
|
|
@@ -230,12 +279,16 @@ export function setFeatures() {
|
|
|
230
279
|
// this means e.g. 2 database modules or 2 form solutions
|
|
231
280
|
if (process.env.NUXT_PUBLIC_IGNIS_WARN_DUPLICATES !== 'false') {
|
|
232
281
|
const used = nuxtConfig.modules
|
|
233
|
-
if (used.includes('nuxt-neon') && used.includes('
|
|
282
|
+
if (used.includes('nuxt-neon') && used.includes('@nuxtjs/supabase')) {
|
|
234
283
|
log.warn('You have both DB connector modules (Neon and Supabase) active, which is not recommended. If this is intentional, you can use `process.env.NUXT_PUBLIC_IGNIS_WARN_DUPLICATES=false` to surpress this warning.')
|
|
235
284
|
}
|
|
236
285
|
if (used.includes('@vueform/nuxt') && used.includes('@formkit/nuxt')) {
|
|
237
286
|
log.warn('You have both Form solution provider modules (Vueform and Formkit) active, which is not recommended. If this is intentional, you can use `process.env.NUXT_PUBLIC_IGNIS_WARN_DUPLICATES=false` to surpress this warning.')
|
|
238
287
|
}
|
|
288
|
+
// validation - not imported as modules
|
|
289
|
+
if (extras.includes('zod') && extras.includes('valibot')) {
|
|
290
|
+
log.warn('You have both validation libraries (Zod and Valibot) active, which is not recommended. If this is intentional, you can use `process.env.NUXT_PUBLIC_IGNIS_WARN_DUPLICATES=false` to surpress this warning.')
|
|
291
|
+
}
|
|
239
292
|
}
|
|
240
293
|
|
|
241
294
|
// 5. verify results
|
package/i18n/locales/en.json
CHANGED
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"neon" : "Neon for DB services",
|
|
25
25
|
"formkit" : "FormKit for input forms",
|
|
26
26
|
"vueform" : "Vueform for input forms",
|
|
27
|
+
"valibot" : "Valibot for schema validation",
|
|
28
|
+
"zod": "Zod for schema validation",
|
|
27
29
|
"content" : "Nuxt Content for creating and editing content",
|
|
28
30
|
"seo" : "Nuxt SEO collection of SEO-related modules",
|
|
29
31
|
"auth" : "Nuxt Auth Utils for easy and secure authentication",
|
package/nuxt.config.ts
CHANGED
|
@@ -12,7 +12,7 @@ const nuxtConfig = defu(ignisFeatures, {
|
|
|
12
12
|
],
|
|
13
13
|
|
|
14
14
|
// https://nuxt.com/docs/api/nuxt-config#compatibilitydate
|
|
15
|
-
compatibilityDate: '2025-
|
|
15
|
+
compatibilityDate: '2025-06-07',
|
|
16
16
|
|
|
17
17
|
// simple eslint config - see eslint.config.mjs
|
|
18
18
|
eslint: {
|
|
@@ -47,6 +47,9 @@ const nuxtConfig = defu(ignisFeatures, {
|
|
|
47
47
|
level: 'info',
|
|
48
48
|
},
|
|
49
49
|
|
|
50
|
+
// central error handler
|
|
51
|
+
error: true, // true/false
|
|
52
|
+
|
|
50
53
|
// nuxt-related config
|
|
51
54
|
ssr: true, // true/false
|
|
52
55
|
pages: true, // true/false
|
|
@@ -56,6 +59,7 @@ const nuxtConfig = defu(ignisFeatures, {
|
|
|
56
59
|
ui: 'off', // nuxt-ui/tailwind/off
|
|
57
60
|
db: 'off', // neon/supabase/off
|
|
58
61
|
forms: 'off', // formkit/vueform/off
|
|
62
|
+
validation: 'off', // valibot/zod/off
|
|
59
63
|
},
|
|
60
64
|
|
|
61
65
|
// core modules
|
|
@@ -64,11 +68,10 @@ const nuxtConfig = defu(ignisFeatures, {
|
|
|
64
68
|
eslint: true,
|
|
65
69
|
fonts: true,
|
|
66
70
|
image: true,
|
|
67
|
-
pinia: true,
|
|
68
|
-
time: true,
|
|
69
71
|
scripts: true,
|
|
70
72
|
security: true,
|
|
71
73
|
vueuse: true,
|
|
74
|
+
pinia: true,
|
|
72
75
|
},
|
|
73
76
|
|
|
74
77
|
// optional modules
|
|
@@ -87,14 +90,21 @@ const nuxtConfig = defu(ignisFeatures, {
|
|
|
87
90
|
config: './formkit.config.ts', // path to config file
|
|
88
91
|
},
|
|
89
92
|
vueform: false, // true/false
|
|
93
|
+
valibot: false, // true/false
|
|
94
|
+
zod: false, // true/false
|
|
90
95
|
content: false, // true/false
|
|
96
|
+
seo: false, // true/false
|
|
97
|
+
auth: false, // true/false
|
|
91
98
|
openprops: false, // true/false
|
|
92
99
|
pslo: {
|
|
93
100
|
enabled: false, // true/false (elrh-pslo will (not) be used)
|
|
94
101
|
content: false, // true/false (elrh-pslo will (not) be aplied on nuxt-content)
|
|
95
102
|
},
|
|
96
|
-
|
|
97
|
-
|
|
103
|
+
equipment: {
|
|
104
|
+
enabled: false, // true/false
|
|
105
|
+
composables: '', // list of Vue Equipment composables
|
|
106
|
+
plugins: '', // list of Vue Equipment plugins
|
|
107
|
+
},
|
|
98
108
|
|
|
99
109
|
// extra behavior
|
|
100
110
|
warn: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-ignis",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "Enhanced and customizable Nuxt application starter pack",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nuxt",
|
|
@@ -26,36 +26,40 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@formkit/nuxt": "1.6.9",
|
|
29
|
-
"@
|
|
29
|
+
"@maas/vue-equipment": "1.0.0-beta.30",
|
|
30
|
+
"@nuxt/content": "3.6.1",
|
|
30
31
|
"@nuxt/eslint": "1.4.1",
|
|
31
32
|
"@nuxt/fonts": "0.11.4",
|
|
32
33
|
"@nuxt/image": "1.10.0",
|
|
33
|
-
"@nuxt/scripts": "0.11.
|
|
34
|
-
"@nuxt/ui": "3.1.
|
|
35
|
-
"@nuxtjs/i18n": "9.5.
|
|
34
|
+
"@nuxt/scripts": "0.11.8",
|
|
35
|
+
"@nuxt/ui": "3.1.3",
|
|
36
|
+
"@nuxtjs/i18n": "9.5.5",
|
|
36
37
|
"@nuxtjs/seo": "3.0.3",
|
|
37
|
-
"@nuxtjs/supabase": "1.5.
|
|
38
|
+
"@nuxtjs/supabase": "1.5.2",
|
|
38
39
|
"@nuxtjs/tailwindcss": "6.14.0",
|
|
39
|
-
"@pinia/nuxt": "0.11.
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@vueuse/
|
|
43
|
-
"@
|
|
40
|
+
"@pinia/nuxt": "0.11.1",
|
|
41
|
+
"@tailwindcss/vite": "4.1.10",
|
|
42
|
+
"@vueform/nuxt": "1.16.0",
|
|
43
|
+
"@vueuse/core": "13.4.0",
|
|
44
|
+
"@vueuse/nuxt": "13.4.0",
|
|
44
45
|
"consola": "3.4.2",
|
|
46
|
+
"date-fns": "4.1.0",
|
|
45
47
|
"defu": "6.1.4",
|
|
46
48
|
"elrh-pslo": "1.1.6",
|
|
47
49
|
"nuxt-auth-utils": "0.5.20",
|
|
48
|
-
"nuxt-neon": "0.6.
|
|
50
|
+
"nuxt-neon": "0.6.2",
|
|
49
51
|
"nuxt-security": "2.2.0",
|
|
50
52
|
"nuxt-spec": "0.0.4",
|
|
51
53
|
"open-props": "1.7.15",
|
|
52
|
-
"pinia": "3.0.
|
|
54
|
+
"pinia": "3.0.3",
|
|
53
55
|
"postcss-jit-props": "1.0.16",
|
|
54
|
-
"typescript": "5.8.3"
|
|
56
|
+
"typescript": "5.8.3",
|
|
57
|
+
"valibot": "1.1.0",
|
|
58
|
+
"zod": "3.25.67"
|
|
55
59
|
},
|
|
56
60
|
"devDependencies": {
|
|
57
|
-
"nuxt": "3.17.
|
|
58
|
-
"vue": "3.5.
|
|
61
|
+
"nuxt": "3.17.5",
|
|
62
|
+
"vue": "3.5.16",
|
|
59
63
|
"vue-router": "4.5.1"
|
|
60
64
|
},
|
|
61
65
|
"scripts": {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// This registeres custom error and warn handlers within Nuxt Ignis app.
|
|
2
|
+
// You can set NUXT_PUBLIC_IGNIS_ERROR to 'false' to disable this feature.
|
|
3
|
+
|
|
4
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
5
|
+
if (useRuntimeConfig().public.ignis.error) {
|
|
6
|
+
nuxtApp.vueApp.config.errorHandler = (err, instance, info) => {
|
|
7
|
+
log.error(err)
|
|
8
|
+
// capture additional context
|
|
9
|
+
log.debug(`Nuxt Ignis error handler - raw error:\n${err}`)
|
|
10
|
+
log.debug(`Nuxt Ignis error handler - source:\n${instance?.$options?.__name || 'Unknown'} (${instance?.$options?.__file || '???'})`)
|
|
11
|
+
log.debug(`Nuxt Ignis error handler - additional error context:\n${info}`)
|
|
12
|
+
}
|
|
13
|
+
nuxtApp.vueApp.config.warnHandler = (msg, instance, trace) => {
|
|
14
|
+
log.warn(msg)
|
|
15
|
+
// capture additional context
|
|
16
|
+
log.debug(`Nuxt Ignis warn handler - raw warning:\n${msg}`)
|
|
17
|
+
log.debug(`Nuxt Ignis warn handler - source:\n${instance?.$options?.__name || 'Unknown'} (${instance?.$options?.__file || '???'})`)
|
|
18
|
+
log.debug(`Nuxt Ignis warn handler - additional warn context:\n${trace}`)
|
|
19
|
+
}
|
|
20
|
+
// set NUXT_PUBLIC_IGNIS_ERROR=false to turn them off
|
|
21
|
+
log.info('Nuxt Ignis error/warn handlers were registered')
|
|
22
|
+
} else {
|
|
23
|
+
// set NUXT_PUBLIC_IGNIS_ERROR=true to turn them on
|
|
24
|
+
log.info('Nuxt Ignis error/warn handlers were NOT registered')
|
|
25
|
+
}
|
|
26
|
+
})
|
package/server/api/neonTest.ts
CHANGED
|
@@ -3,11 +3,13 @@ export default defineEventHandler(async () => {
|
|
|
3
3
|
if (config.preset.db === 'neon' || config.neon === true) {
|
|
4
4
|
return await select(
|
|
5
5
|
getNeonClient(),
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
{
|
|
7
|
+
columns: ['name', 'value'],
|
|
8
|
+
from: 'playing_with_neon',
|
|
9
|
+
where: { column: 'name', condition: 'LIKE', value: '\'test%\'' },
|
|
10
|
+
order: 'name DESC',
|
|
11
|
+
limit: 2,
|
|
12
|
+
},
|
|
11
13
|
)
|
|
12
14
|
} else {
|
|
13
15
|
return 'Neon DB module not enabled'
|