@dargmuesli/nuxt-vio 20.5.2 → 20.6.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.
Files changed (47) hide show
  1. package/.config/certificates/mkcert.sh +42 -23
  2. package/app/components/vio/_/VioApp.vue +3 -6
  3. package/app/components/vio/_/VioError.vue +11 -11
  4. package/app/components/vio/_/VioLink.vue +12 -12
  5. package/app/components/vio/_/VioTime.vue +13 -15
  6. package/app/components/vio/button/VioButton.vue +14 -14
  7. package/app/components/vio/button/VioButtonColored.vue +9 -9
  8. package/app/components/vio/button/VioButtonIcon.vue +7 -7
  9. package/app/components/vio/button/VioButtonShare.vue +2 -3
  10. package/app/components/vio/card/VioCard.vue +5 -6
  11. package/app/components/vio/card/state/VioCardState.vue +2 -6
  12. package/app/components/vio/card/state/VioCardStateAlert.vue +2 -5
  13. package/app/components/vio/card/state/VioCardStateInfo.vue +2 -5
  14. package/app/components/vio/form/VioForm.vue +11 -13
  15. package/app/components/vio/form/VioFormCheckbox.vue +2 -6
  16. package/app/components/vio/form/VioFormContact.vue +3 -8
  17. package/app/components/vio/form/input/VioFormInput.vue +26 -30
  18. package/app/components/vio/form/input/VioFormInputCaptcha.vue +3 -6
  19. package/app/components/vio/form/input/VioFormInputEmailAddress.vue +8 -8
  20. package/app/components/vio/form/input/VioFormInputUrl.vue +6 -6
  21. package/app/components/vio/form/input/state/VioFormInputStateError.vue +6 -7
  22. package/app/components/vio/form/input/state/VioFormInputStateInfo.vue +6 -7
  23. package/app/components/vio/icon/VioIconArrowRight.vue +2 -3
  24. package/app/components/vio/icon/VioIconCalendar.vue +2 -3
  25. package/app/components/vio/icon/VioIconChartBar.vue +2 -3
  26. package/app/components/vio/icon/VioIconCheckCircle.vue +2 -3
  27. package/app/components/vio/icon/VioIconContainer.vue +5 -8
  28. package/app/components/vio/icon/VioIconDownload.vue +2 -3
  29. package/app/components/vio/icon/VioIconExclamationCircle.vue +2 -3
  30. package/app/components/vio/icon/VioIconHeart.vue +2 -3
  31. package/app/components/vio/icon/VioIconHome.vue +2 -3
  32. package/app/components/vio/icon/VioIconHourglass.vue +2 -3
  33. package/app/components/vio/icon/VioIconShare.vue +2 -3
  34. package/app/components/vio/icon/VioIconSignIn.vue +2 -3
  35. package/app/components/vio/icon/VioIconTv.vue +2 -3
  36. package/app/components/vio/layout/VioLayoutBreadcrumbs.vue +2 -6
  37. package/app/components/vio/layout/VioLayoutFooterCategory.vue +2 -3
  38. package/app/components/vio/layout/VioLayoutProse.vue +2 -3
  39. package/app/components/vio/layout/VioLayoutSpanList.vue +2 -3
  40. package/app/components/vio/loader/VioLoader.vue +8 -8
  41. package/app/components/vio/loader/VioLoaderImage.vue +11 -8
  42. package/app/components/vio/page/VioPagePrivacyPolicy.vue +14 -15
  43. package/app/composables/dateTime.ts +5 -1
  44. package/nuxt.config.ts +9 -9
  45. package/package.json +11 -10
  46. package/shared/utils/constants.ts +1 -4
  47. package/node.ts +0 -2
@@ -1,30 +1,49 @@
1
1
  #!/bin/sh
2
- THIS=$(dirname "$(readlink -f "$0")")
2
+ set -e
3
3
 
4
- create() {
5
- NAME="$1"
6
- shift
7
- CONTENT=$*
8
-
9
- path="$THIS/$NAME"
10
- certfile="$path.crt"
11
- keyfile="$path.key"
12
-
13
- if [ "$CONTENT" != "" ]; then
14
- # shellcheck disable=SC2086
15
- mkcert \
16
- -cert-file "$certfile" \
17
- -ecdsa \
18
- -key-file "$keyfile" $CONTENT
19
- fi
4
+ SCRIPT_DIRECTORY=$(dirname "$(readlink -f "$0")")
5
+ CERTIFICATE_SUFFIX="-dev"
6
+
7
+ [ -n "$CI" ] && CERTIFICATE_SUFFIX="-ci"
8
+
9
+ is_certificate_valid() {
10
+ certificate_path="$1"
11
+ root_ca_path="$(mkcert -CAROOT)/rootCA.pem"
20
12
 
21
- cat "$(mkcert -CAROOT)/rootCA.pem" >> "$certfile"
13
+ [ -f "$certificate_path" ] || return 1
14
+
15
+ openssl verify -CAfile "$root_ca_path" "$certificate_path" >/dev/null 2>&1 && openssl x509 -checkend 86400 -noout -in "$certificate_path" >/dev/null 2>&1
22
16
  }
23
17
 
24
- echo "key crt" | tr ' ' '\n' | while read -r glob; do
25
- if test -n "$(find "$THIS" -maxdepth 1 -name "*.$glob" -print -quit)"; then
26
- rm "$THIS"/*."$glob"
18
+ generate_certificate() {
19
+ certificate_name="$1"
20
+ shift
21
+ domains="$*"
22
+
23
+ certificate_path="${SCRIPT_DIRECTORY}/${certificate_name}${CERTIFICATE_SUFFIX}.crt"
24
+ key_file_path="${SCRIPT_DIRECTORY}/${certificate_name}${CERTIFICATE_SUFFIX}.key"
25
+
26
+ if is_certificate_valid "$certificate_path"; then
27
+ echo "✓ Certificate '${certificate_name}' is valid"
28
+ return 0
29
+ fi
30
+
31
+ if [ -f "$certificate_path" ]; then
32
+ echo "✗ Removing outdated certificate: '${certificate_name}'"
33
+ rm -f "$certificate_path" "$key_file_path"
27
34
  fi
28
- done
29
35
 
30
- create "ssl" "localhost" "127.0.0.1" "0.0.0.0"
36
+ echo " Generating certificate: '${certificate_name}'"
37
+ # shellcheck disable=SC2086
38
+ mkcert \
39
+ -cert-file "$certificate_path" \
40
+ -key-file "$key_file_path" \
41
+ -ecdsa \
42
+ $domains
43
+
44
+ cat "$(mkcert -CAROOT)/rootCA.pem" >> "$certificate_path"
45
+
46
+ echo "✓ Certificate generated: '${certificate_name}'"
47
+ }
48
+
49
+ generate_certificate "ssl" "localhost" "app.localhost" "127.0.0.1" "0.0.0.0"
@@ -10,12 +10,9 @@
10
10
  </template>
11
11
 
12
12
  <script setup lang="ts">
13
- interface Props {
13
+ const { ogImageComponent = undefined } = defineProps<{
14
14
  ogImageComponent?: string
15
- }
16
- const props = withDefaults(defineProps<Props>(), {
17
- ogImageComponent: undefined,
18
- })
15
+ }>()
19
16
 
20
17
  const { t } = useI18n()
21
18
  const timeZone = useTimeZone()
@@ -44,7 +41,7 @@ onMounted(() => indicateLoadingDone())
44
41
 
45
42
  // initialization
46
43
  defineOgImageComponent(
47
- props.ogImageComponent || 'NuxtSeo',
44
+ ogImageComponent || 'NuxtSeo',
48
45
  {},
49
46
  {
50
47
  alt: t('globalSeoOgImageAlt'),
@@ -12,29 +12,29 @@
12
12
  </template>
13
13
 
14
14
  <script setup lang="ts">
15
- interface Props {
15
+ const {
16
+ status = undefined,
17
+ statusCode = undefined,
18
+ statusMessage: _statusMessage = undefined,
19
+ statusText: _statusText = undefined,
20
+ description,
21
+ stack = undefined,
22
+ } = defineProps<{
16
23
  status?: number
17
24
  statusCode?: number
18
25
  statusMessage?: string
19
26
  statusText?: string
20
27
  description: string
21
28
  stack?: string
22
- }
23
- const props = withDefaults(defineProps<Props>(), {
24
- status: undefined,
25
- statusCode: undefined,
26
- statusMessage: undefined,
27
- statusText: undefined,
28
- stack: undefined,
29
- })
29
+ }>()
30
30
 
31
31
  const runtimeConfig = useRuntimeConfig()
32
32
  const { locale, t } = useI18n()
33
33
 
34
34
  // data
35
- const title = `${props.status || props.statusCode ? `${props.status || props.statusCode} - ` : ''}${
35
+ const title = `${status || statusCode ? `${status || statusCode} - ` : ''}${
36
36
  (await import('@http-util/status-i18n')).status(
37
- props.status || props.statusCode,
37
+ status || statusCode,
38
38
  locale.value,
39
39
  ) || t('error')
40
40
  }`
@@ -27,7 +27,15 @@
27
27
  <script setup lang="ts">
28
28
  import type { NuxtLinkProps } from '#app'
29
29
 
30
- interface Props {
30
+ const {
31
+ ariaLabel = undefined,
32
+ isColored = true,
33
+ isToRelative = false,
34
+ isUnderlined = false,
35
+ locale = undefined,
36
+ nofollow = false,
37
+ to,
38
+ } = defineProps<{
31
39
  ariaLabel?: string
32
40
  isColored?: boolean
33
41
  isToRelative?: boolean
@@ -35,15 +43,7 @@ interface Props {
35
43
  locale?: I18N_LOCALE_CODE
36
44
  nofollow?: boolean
37
45
  to: NuxtLinkProps['to']
38
- }
39
- const props = withDefaults(defineProps<Props>(), {
40
- ariaLabel: undefined,
41
- isColored: true,
42
- isToRelative: false,
43
- isUnderlined: false,
44
- locale: undefined,
45
- nofollow: false,
46
- })
46
+ }>()
47
47
 
48
48
  const emit = defineEmits<{
49
49
  click: []
@@ -55,8 +55,8 @@ const route = useRoute()
55
55
  const classes = computed(() => {
56
56
  return [
57
57
  'rounded-sm',
58
- ...(props.isColored ? ['text-link-dark dark:text-link-bright'] : []),
59
- ...(props.isUnderlined ? ['underline'] : []),
58
+ ...(isColored ? ['text-link-dark dark:text-link-bright'] : []),
59
+ ...(isUnderlined ? ['underline'] : []),
60
60
  ].join(' ')
61
61
  })
62
62
  </script>
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <NuxtTime
3
3
  v-bind="forwardedProps"
4
- :locale="props.options.locale || defaultLocale"
5
- :time-zone="props.options.timeZone || defaultTimeZone"
4
+ :locale="options.locale || defaultLocale"
5
+ :time-zone="options.timeZone || defaultTimeZone"
6
6
  />
7
7
  </template>
8
8
 
@@ -12,22 +12,20 @@ import type { NuxtTimeProps } from 'nuxt/app'
12
12
  const { locale: defaultLocale } = useI18n()
13
13
  const defaultTimeZone = useTimeZone()
14
14
 
15
- const props = withDefaults(
16
- defineProps<{
17
- datetime: NuxtTimeProps['datetime']
18
- options?: Omit<NuxtTimeProps, 'datetime'>
19
- }>(),
20
- {
21
- options: () => ({
22
- dateStyle: 'medium',
23
- timeStyle: 'short',
24
- }),
15
+ const {
16
+ datetime,
17
+ options = {
18
+ dateStyle: 'medium',
19
+ timeStyle: 'short',
25
20
  },
26
- )
21
+ } = defineProps<{
22
+ datetime: NuxtTimeProps['datetime']
23
+ options?: Omit<NuxtTimeProps, 'datetime'>
24
+ }>()
27
25
 
28
26
  const forwardedProps = computed(() => {
29
- const { locale, timeZone, ...delegated } = props.options
27
+ const { locale, timeZone, ...delegated } = options
30
28
 
31
- return { datetime: props.datetime, ...delegated }
29
+ return { datetime: datetime, ...delegated }
32
30
  })
33
31
  </script>
@@ -28,7 +28,16 @@
28
28
  </template>
29
29
 
30
30
  <script setup lang="ts">
31
- interface Props {
31
+ const {
32
+ ariaLabel,
33
+ classes = undefined,
34
+ disabled = false,
35
+ isBlock = false,
36
+ isLinkColored = false,
37
+ isToRelative = false,
38
+ to = undefined,
39
+ type = 'button',
40
+ } = defineProps<{
32
41
  ariaLabel: string
33
42
  classes?: string
34
43
  disabled?: boolean
@@ -37,16 +46,7 @@ interface Props {
37
46
  isToRelative?: boolean
38
47
  to?: string
39
48
  type?: 'button' | 'submit' | 'reset'
40
- }
41
- const props = withDefaults(defineProps<Props>(), {
42
- classes: undefined,
43
- disabled: false,
44
- isBlock: false,
45
- isLinkColored: false,
46
- isToRelative: false,
47
- to: undefined,
48
- type: 'button',
49
- })
49
+ }>()
50
50
 
51
51
  const emit = defineEmits<{
52
52
  click: [event?: MouseEvent]
@@ -55,9 +55,9 @@ const emit = defineEmits<{
55
55
  // computations
56
56
  const classesComputed = computed(() => {
57
57
  return [
58
- props.classes,
59
- ...(props.isBlock ? ['block'] : ['inline-flex items-center gap-2']),
60
- ...(props.isLinkColored ? ['text-link-dark dark:text-link-bright'] : []),
58
+ classes,
59
+ ...(isBlock ? ['block'] : ['inline-flex items-center gap-2']),
60
+ ...(isLinkColored ? ['text-link-dark dark:text-link-bright'] : []),
61
61
  ].join(' ')
62
62
  })
63
63
  </script>
@@ -30,21 +30,21 @@
30
30
  </template>
31
31
 
32
32
  <script setup lang="ts">
33
- interface Props {
33
+ const {
34
+ ariaLabel,
35
+ disabled = false,
36
+ isPrimary = true,
37
+ isToRelative = false,
38
+ to = undefined,
39
+ type = 'button',
40
+ } = defineProps<{
34
41
  ariaLabel: string
35
42
  disabled?: boolean
36
43
  isPrimary?: boolean
37
44
  isToRelative?: boolean
38
45
  to?: string
39
46
  type?: 'button' | 'reset' | 'submit'
40
- }
41
- withDefaults(defineProps<Props>(), {
42
- disabled: false,
43
- isPrimary: true,
44
- isToRelative: false,
45
- to: undefined,
46
- type: 'button',
47
- })
47
+ }>()
48
48
 
49
49
  const emit = defineEmits<{
50
50
  click: []
@@ -13,17 +13,17 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- interface Props {
16
+ const {
17
+ ariaLabel,
18
+ disabled = false,
19
+ to = undefined,
20
+ type = 'button',
21
+ } = defineProps<{
17
22
  ariaLabel: string
18
23
  disabled?: boolean
19
24
  to?: string
20
25
  type?: 'button' | 'submit' | 'reset'
21
- }
22
- withDefaults(defineProps<Props>(), {
23
- disabled: false,
24
- to: undefined,
25
- type: 'button',
26
- })
26
+ }>()
27
27
 
28
28
  const emit = defineEmits<{
29
29
  click: []
@@ -13,10 +13,9 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- interface Props {
16
+ const { url } = defineProps<{
17
17
  url: string
18
- }
19
- withDefaults(defineProps<Props>(), {})
18
+ }>()
20
19
 
21
20
  const { t } = useI18n()
22
21
 
@@ -8,12 +8,11 @@
8
8
  </template>
9
9
 
10
10
  <script setup lang="ts">
11
- interface Props {
11
+ const {
12
+ backgroundColor = 'bg-background-brighten dark:bg-background-darken',
13
+ isHigh = false,
14
+ } = defineProps<{
12
15
  backgroundColor?: string
13
16
  isHigh?: boolean
14
- }
15
- withDefaults(defineProps<Props>(), {
16
- backgroundColor: 'bg-background-brighten dark:bg-background-darken',
17
- isHigh: false,
18
- })
17
+ }>()
19
18
  </script>
@@ -9,12 +9,8 @@
9
9
  </template>
10
10
 
11
11
  <script setup lang="ts">
12
- interface Props {
12
+ const { backgroundColor = undefined, isEdgy = false } = defineProps<{
13
13
  backgroundColor?: string
14
14
  isEdgy?: boolean
15
- }
16
- withDefaults(defineProps<Props>(), {
17
- backgroundColor: undefined,
18
- isEdgy: false,
19
- })
15
+ }>()
20
16
  </script>
@@ -5,10 +5,7 @@
5
5
  </template>
6
6
 
7
7
  <script setup lang="ts">
8
- interface Props {
8
+ const { isEdgy = false } = defineProps<{
9
9
  isEdgy?: boolean
10
- }
11
- withDefaults(defineProps<Props>(), {
12
- isEdgy: false,
13
- })
10
+ }>()
14
11
  </script>
@@ -5,10 +5,7 @@
5
5
  </template>
6
6
 
7
7
  <script setup lang="ts">
8
- interface Props {
8
+ const { isEdgy = false } = defineProps<{
9
9
  isEdgy?: boolean
10
- }
11
- withDefaults(defineProps<Props>(), {
12
- isEdgy: false,
13
- })
10
+ }>()
14
11
  </script>
@@ -45,7 +45,15 @@
45
45
  <script setup lang="ts">
46
46
  import type { BaseValidation } from '@vuelidate/core'
47
47
 
48
- interface Props {
48
+ const {
49
+ errors = undefined,
50
+ errorsPgIds = undefined,
51
+ form,
52
+ formClass = undefined,
53
+ isFormSent: _isFormSent = false,
54
+ isLoading = undefined,
55
+ submitName = undefined,
56
+ } = defineProps<{
49
57
  errors?: BackendError[]
50
58
  errorsPgIds?: Record<string, string>
51
59
  form: BaseValidation
@@ -53,15 +61,7 @@ interface Props {
53
61
  isFormSent?: boolean
54
62
  isLoading?: boolean
55
63
  submitName?: string
56
- }
57
- const props = withDefaults(defineProps<Props>(), {
58
- errors: undefined,
59
- errorsPgIds: undefined,
60
- formClass: undefined,
61
- isFormSent: false,
62
- isLoading: undefined,
63
- submitName: undefined,
64
- })
64
+ }>()
65
65
 
66
66
  const emit = defineEmits<{
67
67
  click: []
@@ -72,9 +72,7 @@ const { t } = useI18n()
72
72
 
73
73
  // computations
74
74
  const errorMessages = computed(() =>
75
- props.errors
76
- ? getCombinedErrorMessages(props.errors, props.errorsPgIds)
77
- : undefined,
75
+ errors ? getCombinedErrorMessages(errors, errorsPgIds) : undefined,
78
76
  )
79
77
  </script>
80
78
 
@@ -12,14 +12,10 @@
12
12
  </template>
13
13
 
14
14
  <script setup lang="ts">
15
- interface Props {
15
+ const { formKey = undefined, value = undefined } = defineProps<{
16
16
  formKey?: string
17
17
  value?: boolean
18
- }
19
- withDefaults(defineProps<Props>(), {
20
- formKey: undefined,
21
- value: undefined,
22
- })
18
+ }>()
23
19
 
24
20
  const emit = defineEmits<{
25
21
  change: [change: boolean]
@@ -79,14 +79,9 @@ import { required } from '@vuelidate/validators'
79
79
 
80
80
  type FormValid = { emailAddress: string; name: string; message: string }
81
81
 
82
- withDefaults(
83
- defineProps<{
84
- isLoading?: boolean
85
- }>(),
86
- {
87
- isLoading: undefined,
88
- },
89
- )
82
+ const { isLoading = undefined } = defineProps<{
83
+ isLoading?: boolean
84
+ }>()
90
85
 
91
86
  const emit = defineEmits<{
92
87
  submit: [form: FormValid]
@@ -119,7 +119,23 @@
119
119
  import type { BaseValidation } from '@vuelidate/core'
120
120
  import { consola } from 'consola'
121
121
 
122
- interface Props {
122
+ const {
123
+ idLabel = undefined,
124
+ isDisabled = false,
125
+ isOptional = false,
126
+ isReadonly = false,
127
+ isRequired = false,
128
+ isValidatable = false,
129
+ name = undefined,
130
+ placeholder = undefined,
131
+ success = false,
132
+ title,
133
+ type = undefined,
134
+ validationProperty = undefined,
135
+ value = undefined,
136
+ valueFormatter = (x?: string) => x,
137
+ warning = false,
138
+ } = defineProps<{
123
139
  idLabel?: string
124
140
  isDisabled?: boolean
125
141
  isOptional?: boolean
@@ -135,23 +151,7 @@ interface Props {
135
151
  value?: BaseValidation
136
152
  valueFormatter?: (x?: string) => typeof x | undefined
137
153
  warning?: boolean
138
- }
139
- const props = withDefaults(defineProps<Props>(), {
140
- idLabel: undefined,
141
- isDisabled: false,
142
- isOptional: false,
143
- isReadonly: false,
144
- isRequired: false,
145
- isValidatable: false,
146
- name: undefined,
147
- placeholder: undefined,
148
- success: false,
149
- type: undefined,
150
- validationProperty: undefined,
151
- value: undefined,
152
- valueFormatter: (x?: string) => x,
153
- warning: false,
154
- })
154
+ }>()
155
155
 
156
156
  const emit = defineEmits<{
157
157
  icon: []
@@ -164,16 +164,16 @@ const runtimeConfig = useRuntimeConfig()
164
164
  const siteConfig = useSiteConfig()
165
165
 
166
166
  // data
167
- const idLabelFull = props.idLabel
167
+ const idLabelFull = idLabel
168
168
  ? `${siteConfig.id}-${
169
169
  runtimeConfig.public.vio.isInProduction ? 'prod' : 'dev'
170
- }-${props.idLabel}`
170
+ }-${idLabel}`
171
171
  : undefined
172
172
 
173
173
  // initialization
174
174
  if (
175
- !props.placeholder &&
176
- props.type &&
175
+ !placeholder &&
176
+ type &&
177
177
  ![
178
178
  'checkbox',
179
179
  'datetime-local',
@@ -182,17 +182,13 @@ if (
182
182
  'textarea',
183
183
  'tiptap',
184
184
  'radio',
185
- ].includes(props.type)
185
+ ].includes(type)
186
186
  ) {
187
- consola.warn(`placeholder is missing for ${props.idLabel}!`)
187
+ consola.warn(`placeholder is missing for ${idLabel}!`)
188
188
  }
189
189
 
190
- if (
191
- !props.value &&
192
- props.type &&
193
- !['checkbox', 'select'].includes(props.type)
194
- ) {
195
- consola.warn(`value is missing for ${props.idLabel}!`)
190
+ if (!value && type && !['checkbox', 'select'].includes(type)) {
191
+ consola.warn(`value is missing for ${idLabel}!`)
196
192
  }
197
193
  </script>
198
194
 
@@ -49,12 +49,9 @@
49
49
  <script setup lang="ts">
50
50
  import type { BaseValidation } from '@vuelidate/core'
51
51
 
52
- withDefaults(
53
- defineProps<{
54
- formInput: BaseValidation
55
- }>(),
56
- {},
57
- )
52
+ const { formInput } = defineProps<{
53
+ formInput: BaseValidation
54
+ }>()
58
55
 
59
56
  const emit = defineEmits<{
60
57
  input: [event?: string]
@@ -36,19 +36,19 @@
36
36
  <script setup lang="ts">
37
37
  import type { BaseValidation } from '@vuelidate/core'
38
38
 
39
- interface Props {
39
+ const {
40
+ formInput,
41
+ id = 'email-address',
42
+ isOptional = false,
43
+ isRequired = false,
44
+ title = undefined,
45
+ } = defineProps<{
40
46
  formInput: BaseValidation
41
47
  id?: string
42
48
  isOptional?: boolean
43
49
  isRequired?: boolean
44
50
  title?: string
45
- }
46
- withDefaults(defineProps<Props>(), {
47
- id: 'email-address',
48
- isOptional: false,
49
- isRequired: false,
50
- title: undefined,
51
- })
51
+ }>()
52
52
 
53
53
  const emit = defineEmits<{
54
54
  input: [event: string]
@@ -29,15 +29,15 @@
29
29
  <script setup lang="ts">
30
30
  import type { BaseValidation } from '@vuelidate/core'
31
31
 
32
- interface Props {
32
+ const {
33
+ formInput,
34
+ id = 'phone-number',
35
+ isOptional = false,
36
+ } = defineProps<{
33
37
  formInput: BaseValidation
34
38
  id?: string
35
39
  isOptional?: boolean
36
- }
37
- withDefaults(defineProps<Props>(), {
38
- id: 'phone-number',
39
- isOptional: false,
40
- })
40
+ }>()
41
41
 
42
42
  const emit = defineEmits<{
43
43
  input: [event: string]
@@ -19,14 +19,13 @@
19
19
  <script setup lang="ts">
20
20
  import type { BaseValidation } from '@vuelidate/core'
21
21
 
22
- interface Props {
22
+ const {
23
+ formInput = undefined,
24
+ isValidationLive = false,
25
+ validationProperty = undefined,
26
+ } = defineProps<{
23
27
  formInput?: BaseValidation
24
28
  isValidationLive?: boolean
25
29
  validationProperty?: string
26
- }
27
- withDefaults(defineProps<Props>(), {
28
- formInput: undefined,
29
- isValidationLive: false,
30
- validationProperty: undefined,
31
- })
30
+ }>()
32
31
  </script>
@@ -19,14 +19,13 @@
19
19
  <script setup lang="ts">
20
20
  import type { BaseValidation } from '@vuelidate/core'
21
21
 
22
- interface Props {
22
+ const {
23
+ formInput = undefined,
24
+ isValidationLive = false,
25
+ validationProperty = undefined,
26
+ } = defineProps<{
23
27
  formInput?: BaseValidation
24
28
  isValidationLive?: boolean
25
29
  validationProperty?: string
26
- }
27
- withDefaults(defineProps<Props>(), {
28
- formInput: undefined,
29
- isValidationLive: false,
30
- validationProperty: undefined,
31
- })
30
+ }>()
32
31
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -13,10 +13,9 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- interface Props {
16
+ const { title } = defineProps<{
17
17
  title?: string // eslint-disable-line vue/require-default-prop
18
- }
19
- withDefaults(defineProps<Props>(), {})
18
+ }>()
20
19
 
21
20
  const { t } = useI18n()
22
21
  </script>
@@ -5,12 +5,9 @@
5
5
  </template>
6
6
 
7
7
  <script setup lang="ts">
8
- interface Props {
9
- classes?: string
10
- title?: string
11
- }
12
- withDefaults(defineProps<Props>(), {
13
- classes: 'h-5 md:h-6 w-5 md:w-6 shrink-0',
14
- title: undefined,
15
- })
8
+ const { classes = 'h-5 md:h-6 w-5 md:w-6 shrink-0', title = undefined } =
9
+ defineProps<{
10
+ classes?: string
11
+ title?: string
12
+ }>()
16
13
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -13,10 +13,9 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- interface Props {
16
+ const { title } = defineProps<{
17
17
  title?: string // eslint-disable-line vue/require-default-prop
18
- }
19
- withDefaults(defineProps<Props>(), {})
18
+ }>()
20
19
 
21
20
  const { t } = useI18n()
22
21
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -16,10 +16,9 @@
16
16
  </template>
17
17
 
18
18
  <script setup lang="ts">
19
- interface Props {
19
+ const { title } = defineProps<{
20
20
  title?: string // eslint-disable-line vue/require-default-prop
21
- }
22
- withDefaults(defineProps<Props>(), {})
21
+ }>()
23
22
 
24
23
  const { t } = useI18n()
25
24
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -15,10 +15,9 @@
15
15
  </template>
16
16
 
17
17
  <script setup lang="ts">
18
- interface Props {
18
+ const { title } = defineProps<{
19
19
  title?: string // eslint-disable-line vue/require-default-prop
20
- }
21
- withDefaults(defineProps<Props>(), {})
20
+ }>()
22
21
 
23
22
  const { t } = useI18n()
24
23
  </script>
@@ -60,14 +60,10 @@ export interface Breadcrumb {
60
60
  to: string
61
61
  }
62
62
 
63
- interface Props {
63
+ const { prefixes = undefined, suffixes = undefined } = defineProps<{
64
64
  prefixes?: Breadcrumb[]
65
65
  suffixes?: Breadcrumb[]
66
- }
67
- withDefaults(defineProps<Props>(), {
68
- prefixes: undefined,
69
- suffixes: undefined,
70
- })
66
+ }>()
71
67
 
72
68
  const localePath = useLocalePath()
73
69
  const { t } = useI18n()
@@ -10,8 +10,7 @@
10
10
  </template>
11
11
 
12
12
  <script setup lang="ts">
13
- interface Props {
13
+ const { heading } = defineProps<{
14
14
  heading: string
15
- }
16
- withDefaults(defineProps<Props>(), {})
15
+ }>()
17
16
  </script>
@@ -14,8 +14,7 @@
14
14
  </template>
15
15
 
16
16
  <script setup lang="ts">
17
- interface Props {
17
+ const { isFullWidth } = defineProps<{
18
18
  isFullWidth?: boolean
19
- }
20
- withDefaults(defineProps<Props>(), {})
19
+ }>()
21
20
  </script>
@@ -13,8 +13,7 @@
13
13
  </template>
14
14
 
15
15
  <script setup lang="ts">
16
- interface Props {
16
+ const { span } = defineProps<{
17
17
  span: (string | string[])[]
18
- }
19
- withDefaults(defineProps<Props>(), {})
18
+ }>()
20
19
  </script>
@@ -16,21 +16,21 @@
16
16
  <script setup lang="ts">
17
17
  import type { UnwrapRef } from 'vue'
18
18
 
19
- interface Props {
19
+ const {
20
+ api,
21
+ errorPgIds = undefined,
22
+ classes = undefined,
23
+ indicator = undefined,
24
+ } = defineProps<{
20
25
  api: UnwrapRef<ApiData>
21
26
  errorPgIds?: Record<string, string>
22
27
  classes?: string
23
28
  indicator?: string
24
- }
25
- const props = withDefaults(defineProps<Props>(), {
26
- errorPgIds: undefined,
27
- classes: undefined,
28
- indicator: undefined,
29
- })
29
+ }>()
30
30
 
31
31
  // computations
32
32
  const errorMessages = computed(() =>
33
- getCombinedErrorMessages(props.api.errors, props.errorPgIds),
33
+ getCombinedErrorMessages(api.errors, errorPgIds),
34
34
  )
35
35
  </script>
36
36
 
@@ -19,18 +19,21 @@
19
19
  <script setup lang="ts">
20
20
  import { debounce } from 'lodash-es'
21
21
 
22
- interface Props {
22
+ const {
23
+ alt,
24
+ aspect,
25
+ classes = undefined,
26
+ height,
27
+ src,
28
+ width,
29
+ } = defineProps<{
23
30
  alt: string
24
31
  aspect: string
25
32
  classes?: string
26
33
  height: string
27
34
  src: string
28
35
  width: string
29
- }
30
- const props = withDefaults(defineProps<Props>(), {
31
- classes: undefined,
32
- })
33
- const srcProp = toRef(() => props.src)
36
+ }>()
34
37
 
35
38
  const { t } = useI18n()
36
39
 
@@ -40,7 +43,7 @@ const isError = ref(false)
40
43
  const isLoading = ref(false)
41
44
  const loadingId = Math.random()
42
45
  const loadingIds = useState('loadingIds', () => [] as number[])
43
- const srcWhenLoaded = ref<string | undefined>(srcProp.value)
46
+ const srcWhenLoaded = ref<string | undefined>(src)
44
47
 
45
48
  // methods
46
49
  const loadOnClient = () => {
@@ -55,7 +58,7 @@ const loadOnClient = () => {
55
58
  loadingStop()
56
59
  isError.value = true
57
60
  }
58
- img.value.src = props.src
61
+ img.value.src = src
59
62
  }
60
63
  const loadingStart = () => {
61
64
  srcWhenLoaded.value = undefined
@@ -442,7 +442,19 @@
442
442
  </template>
443
443
 
444
444
  <script setup lang="ts">
445
- interface Props {
445
+ const {
446
+ isEnabled = {
447
+ summary: {
448
+ generalNotes: true,
449
+ dataCollection: {
450
+ liability: true,
451
+ method: true,
452
+ use: true,
453
+ rights: true,
454
+ },
455
+ },
456
+ },
457
+ } = defineProps<{
446
458
  isEnabled?: {
447
459
  summary?: {
448
460
  generalNotes?: boolean
@@ -496,20 +508,7 @@ interface Props {
496
508
  googleReCaptcha?: boolean
497
509
  }
498
510
  }
499
- }
500
- withDefaults(defineProps<Props>(), {
501
- isEnabled: () => ({
502
- summary: {
503
- generalNotes: true,
504
- dataCollection: {
505
- liability: true,
506
- method: true,
507
- use: true,
508
- rights: true,
509
- },
510
- },
511
- }),
512
- })
511
+ }>()
513
512
 
514
513
  const appConfig = useAppConfig()
515
514
  const { t } = useI18n()
@@ -9,7 +9,11 @@ export const useTimeZone = () =>
9
9
  ? Intl.DateTimeFormat().resolvedOptions().timeZone
10
10
  : undefined)
11
11
 
12
- export const useNow = () => useState(STATE_KEY_NOW, () => new Date())
12
+ export const useNow = () => {
13
+ const isTesting = useIsTesting()
14
+
15
+ return useState(STATE_KEY_NOW, () => (isTesting ? new Date(0) : new Date()))
16
+ }
13
17
 
14
18
  export const useFromNow = () => {
15
19
  const { locale } = useI18n()
package/nuxt.config.ts CHANGED
@@ -1,12 +1,9 @@
1
- import { fileURLToPath } from 'node:url'
2
- import { dirname, join } from 'node:path'
3
-
4
1
  import tailwindcss from '@tailwindcss/vite'
5
2
  import { defu } from 'defu'
3
+ import { createResolver } from 'nuxt/kit'
6
4
 
7
- import { IS_IN_STACK } from './node'
5
+ import { IS_IN_STACK, SITE_URL } from './node/static'
8
6
  import {
9
- SITE_URL,
10
7
  VIO_SITE_NAME,
11
8
  TIMEZONE_COOKIE_NAME,
12
9
  GTAG_COOKIE_ID,
@@ -14,7 +11,7 @@ import {
14
11
  } from './shared/utils/constants'
15
12
  import { VIO_NUXT_BASE_CONFIG } from './shared/utils/nuxt'
16
13
 
17
- const currentDir = dirname(fileURLToPath(import.meta.url))
14
+ const { resolve } = createResolver(import.meta.url)
18
15
 
19
16
  export default defineNuxtConfig(
20
17
  defu(
@@ -35,8 +32,8 @@ export default defineNuxtConfig(
35
32
  : {
36
33
  devServer: {
37
34
  https: {
38
- key: './.config/certificates/ssl.key',
39
- cert: './.config/certificates/ssl.crt',
35
+ key: './.config/certificates/ssl-dev.key',
36
+ cert: './.config/certificates/ssl-dev.crt',
40
37
  },
41
38
  },
42
39
  }),
@@ -122,6 +119,9 @@ export default defineNuxtConfig(
122
119
  },
123
120
  },
124
121
  typescript: {
122
+ nodeTsConfig: {
123
+ include: [resolve('./node')],
124
+ },
125
125
  tsConfig: {
126
126
  vueCompilerOptions: {
127
127
  htmlAttributes: [], // https://github.com/johnsoncodehk/volar/issues/1970#issuecomment-1276994634
@@ -282,7 +282,7 @@ export default defineNuxtConfig(
282
282
  },
283
283
  shadcn: {
284
284
  prefix: '',
285
- componentDir: join(currentDir, './app/components/scn'),
285
+ componentDir: resolve('./app/components/scn'),
286
286
  },
287
287
  site: {
288
288
  url: SITE_URL,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "dependencies": {
3
- "@dargmuesli/nuxt-cookie-control": "9.1.14",
3
+ "@dargmuesli/nuxt-cookie-control": "9.1.15",
4
4
  "@eslint/compat": "2.0.2",
5
5
  "@heroicons/vue": "2.2.0",
6
6
  "@nuxtjs/turnstile": "1.1.1",
@@ -25,7 +25,7 @@
25
25
  "@vuelidate/validators": "2.0.4",
26
26
  "@vueuse/core": "14.2.0",
27
27
  "class-variance-authority": "0.7.1",
28
- "clipboardy": "5.2.0",
28
+ "clipboardy": "5.2.1",
29
29
  "clsx": "2.1.1",
30
30
  "eslint": "9.39.2",
31
31
  "eslint-config-prettier": "10.1.8",
@@ -36,7 +36,7 @@
36
36
  "jiti": "2.6.1",
37
37
  "jose": "6.1.3",
38
38
  "lucide-vue-next": "0.563.0",
39
- "nodemailer": "7.0.13",
39
+ "nodemailer": "8.0.0",
40
40
  "nuxt-gtag": "4.1.0",
41
41
  "nuxt-security": "2.5.1",
42
42
  "reka-ui": "2.8.0",
@@ -47,7 +47,7 @@
47
47
  "vue-tsc": "3.2.4"
48
48
  },
49
49
  "devDependencies": {
50
- "@types/node": "24.10.9",
50
+ "@types/node": "24.10.10",
51
51
  "@urql/devtools": "2.0.3",
52
52
  "@urql/exchange-graphcache": "9.0.0",
53
53
  "@vueuse/core": "14.2.0",
@@ -61,10 +61,10 @@
61
61
  "prettier-plugin-tailwindcss": "0.7.2",
62
62
  "serve": "14.2.5",
63
63
  "sharp": "0.34.5",
64
- "stylelint": "17.1.0",
64
+ "stylelint": "17.1.1",
65
65
  "stylelint-config-recommended-vue": "1.6.1",
66
66
  "stylelint-config-standard": "40.0.0",
67
- "stylelint-no-unsupported-browser-features": "8.0.5",
67
+ "stylelint-no-unsupported-browser-features": "8.1.1",
68
68
  "tailwindcss": "4.1.18",
69
69
  "vue": "3.5.27",
70
70
  "vue-router": "4.6.4"
@@ -101,6 +101,7 @@
101
101
  "build:node": "nuxt build playground",
102
102
  "build:static": "nuxt generate playground",
103
103
  "build:static:test": "NUXT_PUBLIC_SITE_URL=https://localhost:3002 pnpm run build:static",
104
+ "certificates": ".config/certificates/mkcert.sh",
104
105
  "dev": "pnpm run start:dev",
105
106
  "generate": "pnpm run build:static",
106
107
  "lint": "pnpm run lint:js && pnpm run lint:ts && pnpm run lint:style",
@@ -112,10 +113,10 @@
112
113
  "prepare": "nuxt prepare && nuxt prepare playground && ./.config/certificates/mkcert.sh",
113
114
  "preview": "nuxt preview playground",
114
115
  "start": "pnpm run start:node",
115
- "start:dev": "nuxt dev playground",
116
- "start:node": "node playground/.output/server/index.mjs",
117
- "start:static": "serve playground/.output/public --ssl-cert ./.config/certificates/ssl.crt --ssl-key ./.config/certificates/ssl.key"
116
+ "start:dev": "pnpm run certificates && NODE_EXTRA_CA_CERTS=\"$(mkcert -CAROOT)/rootCA.pem\" nuxt dev playground",
117
+ "start:node": "node scripts/server/node.mjs",
118
+ "start:static": "node scripts/server/static.mjs"
118
119
  },
119
120
  "type": "module",
120
- "version": "20.5.2"
121
+ "version": "20.6.0"
121
122
  }
@@ -2,14 +2,11 @@ import { DEFAULTS } from '@dargmuesli/nuxt-cookie-control/runtime/types.js'
2
2
  import { helpers } from '@vuelidate/validators'
3
3
  import { defu } from 'defu'
4
4
 
5
- import { IS_IN_PRODUCTION, IS_IN_STACK } from '../../node'
5
+ import { IS_IN_PRODUCTION, IS_IN_STACK } from '../../node/static'
6
6
 
7
7
  export const VIO_SITE_NAME = 'Vio'
8
8
 
9
9
  export const IS_IN_FRONTEND_DEVELOPMENT = !IS_IN_PRODUCTION && !IS_IN_STACK
10
- export const SITE_URL =
11
- process.env.NUXT_PUBLIC_SITE_URL ||
12
- `https://${process.env.HOST || 'localhost'}:${process.env.PORT || '3000'}`
13
10
  export const CACHE_VERSION = 'zeMtipb6C9'
14
11
  export const COOKIE_CONTROL_CONSENT_COOKIE_NAME =
15
12
  DEFAULTS.cookieNameIsConsentGiven
package/node.ts DELETED
@@ -1,2 +0,0 @@
1
- export const IS_IN_PRODUCTION = process.env.NODE_ENV === 'production'
2
- export const IS_IN_STACK = !!process.env.NUXT_PUBLIC_SITE_URL