@dargmuesli/nuxt-vio 19.0.2 → 19.1.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/.config/lint.js CHANGED
@@ -36,13 +36,6 @@ export const VIO_ESLINT_CONFIG = [
36
36
  },
37
37
  },
38
38
  rules: {
39
- '@intlify/vue-i18n/no-missing-keys': 'error',
40
- '@intlify/vue-i18n/no-raw-text': 'error',
41
- '@intlify/vue-i18n/no-deprecated-i18n-component': 'error', // TODO: do not specify below rules manually, but have them included in `recommended` https://github.com/intlify/eslint-plugin-vue-i18n/issues/275
42
- '@intlify/vue-i18n/no-deprecated-i18n-place-attr': 'error',
43
- '@intlify/vue-i18n/no-deprecated-i18n-places-prop': 'error',
44
- '@intlify/vue-i18n/no-i18n-t-path-prop': 'error',
45
- '@intlify/vue-i18n/valid-message-syntax': 'error',
46
39
  '@intlify/vue-i18n/key-format-style': 'error',
47
40
  '@intlify/vue-i18n/no-duplicate-keys-in-locale': 'error',
48
41
  '@intlify/vue-i18n/no-dynamic-keys': 'error',
package/app/app.config.ts CHANGED
@@ -5,55 +5,57 @@ export default defineAppConfig({
5
5
  },
6
6
  })
7
7
 
8
- export type AppConfig = {
9
- vio: {
10
- pages?: {
11
- legalNotice?: {
12
- contact: {
13
- email: string
14
- }
15
- responsibility: {
16
- address: {
17
- city: string
18
- name: string
19
- street: string
20
- }
21
- }
22
- tmg: {
23
- address: {
24
- city: string
25
- name: string
26
- street: string
8
+ declare module 'nuxt/schema' {
9
+ interface AppConfig {
10
+ vio: {
11
+ pages?: {
12
+ legalNotice?: {
13
+ contact: {
14
+ email: string
27
15
  }
28
- }
29
- }
30
- privacyPolicy?: {
31
- hostingCdn?: {
32
- external: {
16
+ responsibility: {
33
17
  address: {
34
18
  city: string
35
19
  name: string
36
20
  street: string
37
21
  }
38
22
  }
39
- }
40
- mandatoryInfo?: {
41
- responsible: {
23
+ tmg: {
42
24
  address: {
43
25
  city: string
44
- email: string
45
26
  name: string
46
27
  street: string
47
28
  }
48
29
  }
49
30
  }
31
+ privacyPolicy?: {
32
+ hostingCdn?: {
33
+ external: {
34
+ address: {
35
+ city: string
36
+ name: string
37
+ street: string
38
+ }
39
+ }
40
+ }
41
+ mandatoryInfo?: {
42
+ responsible: {
43
+ address: {
44
+ city: string
45
+ email: string
46
+ name: string
47
+ street: string
48
+ }
49
+ }
50
+ }
51
+ }
50
52
  }
51
- }
52
- server?: {
53
- middleware: {
54
- headers: Record<string, string>
53
+ server?: {
54
+ middleware: {
55
+ headers: Record<string, string>
56
+ }
55
57
  }
58
+ themeColor?: string
56
59
  }
57
- themeColor?: string
58
60
  }
59
61
  }
@@ -1,53 +1,72 @@
1
1
  <template>
2
2
  <VioLayoutProse class="m-auto">
3
3
  <h1>{{ title }}</h1>
4
- <h2>{{ t('tmg') }}</h2>
5
- <address>
6
- <slot v-if="$slots.tmgAddress" name="tmgAddress" />
7
- <i18n-t v-else keypath="tmgAddress">
8
- <template #br>
9
- <br />
10
- </template>
11
- <template #city>
12
- {{ appConfig.vio.pages.legalNotice.tmg.address.city }}
13
- </template>
14
- <template #name>
15
- {{ appConfig.vio.pages.legalNotice.tmg.address.name }}
16
- </template>
17
- <template #street>
18
- {{ appConfig.vio.pages.legalNotice.tmg.address.street }}
19
- </template>
20
- </i18n-t>
21
- </address>
22
4
 
23
- <h2>{{ t('contact') }}</h2>
24
- <p>
25
- <slot v-if="$slots.contactEmail" name="contactEmail" />
26
- <span v-else>
27
- {{
28
- t('email', { email: appConfig.vio.pages.legalNotice.contact.email })
29
- }}
30
- </span>
31
- </p>
5
+ <section
6
+ v-if="appConfig.vio.pages?.legalNotice"
7
+ :aria-labelledby="templateIdTmg"
8
+ >
9
+ <h2 :id="templateIdTmg">{{ t('tmg') }}</h2>
10
+ <address>
11
+ <slot v-if="$slots.tmgAddress" name="tmgAddress" />
12
+ <i18n-t v-else keypath="tmgAddress">
13
+ <template #br>
14
+ <br />
15
+ </template>
16
+ <template #city>
17
+ {{ appConfig.vio.pages.legalNotice.tmg.address.city }}
18
+ </template>
19
+ <template #name>
20
+ {{ appConfig.vio.pages.legalNotice.tmg.address.name }}
21
+ </template>
22
+ <template #street>
23
+ {{ appConfig.vio.pages.legalNotice.tmg.address.street }}
24
+ </template>
25
+ </i18n-t>
26
+ </address>
27
+ </section>
32
28
 
33
- <h2>{{ t('responsibility') }}</h2>
34
- <address>
35
- <slot v-if="$slots.responsibilityAddress" name="responsibilityAddress" />
36
- <i18n-t v-else keypath="responsibilityAddress">
37
- <template #br>
38
- <br />
39
- </template>
40
- <template #city>
41
- {{ appConfig.vio.pages.legalNotice.responsibility.address.city }}
42
- </template>
43
- <template #name>
44
- {{ appConfig.vio.pages.legalNotice.responsibility.address.name }}
45
- </template>
46
- <template #street>
47
- {{ appConfig.vio.pages.legalNotice.responsibility.address.street }}
48
- </template>
49
- </i18n-t>
50
- </address>
29
+ <section
30
+ v-if="appConfig.vio.pages?.legalNotice"
31
+ :aria-labelledby="templateIdContact"
32
+ >
33
+ <h2 :id="templateIdContact">{{ t('contact') }}</h2>
34
+ <p>
35
+ <slot v-if="$slots.contactEmail" name="contactEmail" />
36
+ <span v-else>
37
+ {{
38
+ t('email', { email: appConfig.vio.pages.legalNotice.contact.email })
39
+ }}
40
+ </span>
41
+ </p>
42
+ </section>
43
+
44
+ <section
45
+ v-if="appConfig.vio.pages?.legalNotice"
46
+ :aria-labelledby="templateIdResponsibility"
47
+ >
48
+ <h2 :id="templateIdResponsibility">{{ t('responsibility') }}</h2>
49
+ <address>
50
+ <slot
51
+ v-if="$slots.responsibilityAddress"
52
+ name="responsibilityAddress"
53
+ />
54
+ <i18n-t v-else keypath="responsibilityAddress">
55
+ <template #br>
56
+ <br />
57
+ </template>
58
+ <template #city>
59
+ {{ appConfig.vio.pages.legalNotice.responsibility.address.city }}
60
+ </template>
61
+ <template #name>
62
+ {{ appConfig.vio.pages.legalNotice.responsibility.address.name }}
63
+ </template>
64
+ <template #street>
65
+ {{ appConfig.vio.pages.legalNotice.responsibility.address.street }}
66
+ </template>
67
+ </i18n-t>
68
+ </address>
69
+ </section>
51
70
 
52
71
  <h3>{{ t('liabilityContentTitle') }}</h3>
53
72
  <p>{{ t('liabilityContentDescription1') }}</p>
@@ -73,6 +92,11 @@ const { t } = useI18n()
73
92
 
74
93
  // data
75
94
  const title = t('title')
95
+
96
+ // template
97
+ const templateIdContact = useId()
98
+ const templateIdResponsibility = useId()
99
+ const templateIdTmg = useId()
76
100
  </script>
77
101
 
78
102
  <i18n lang="yaml">
@@ -44,7 +44,11 @@
44
44
  </section>
45
45
  </section>
46
46
  </li>
47
- <li v-if="isEnabled.hostingCdn">
47
+ <li
48
+ v-if="
49
+ isEnabled.hostingCdn && appConfig.vio.pages?.privacyPolicy?.hostingCdn
50
+ "
51
+ >
48
52
  <section>
49
53
  <h2>{{ t('hostingCdn') }}</h2>
50
54
 
@@ -102,7 +106,12 @@
102
106
  <p>{{ t('mandatoryInfoPrivacyDescription3') }}</p>
103
107
  </section>
104
108
 
105
- <section v-if="isEnabled.mandatoryInfo.responsible">
109
+ <section
110
+ v-if="
111
+ isEnabled.mandatoryInfo.responsible &&
112
+ appConfig.vio.pages?.privacyPolicy?.mandatoryInfo
113
+ "
114
+ >
106
115
  <h3>{{ t('mandatoryInfoResponsibleTitle') }}</h3>
107
116
  <p>{{ t('mandatoryInfoResponsibleDescription1') }}</p>
108
117
  <address>
package/nuxt.config.ts CHANGED
@@ -65,11 +65,6 @@ export default defineNuxtConfig(
65
65
  ) {
66
66
  if (nuxt.options.nitro.static) {
67
67
  nuxtConfigSecurityHeaders.contentSecurityPolicy = defu(
68
- {
69
- 'script-src-elem': [
70
- "'unsafe-inline'", // TODO: remove (https://github.com/Baroshem/nuxt-security/pull/659)
71
- ],
72
- },
73
68
  VIO_GET_CSP({ siteUrl: new URL(SITE_URL) }),
74
69
  nuxtConfigSecurityHeaders.contentSecurityPolicy,
75
70
  )
@@ -256,7 +251,8 @@ export default defineNuxtConfig(
256
251
  },
257
252
  nitro: {
258
253
  experimental: {
259
- openAPI: false, // TODO: set to true (https://github.com/nuxt/content/issues/2839)
254
+ asyncContext: true,
255
+ openAPI: true,
260
256
  },
261
257
  },
262
258
  runtimeConfig: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
- "@dargmuesli/nuxt-cookie-control": "9.1.7",
4
- "@eslint/compat": "1.4.1",
3
+ "@dargmuesli/nuxt-cookie-control": "9.1.8",
4
+ "@eslint/compat": "2.0.0",
5
5
  "@heroicons/vue": "2.2.0",
6
6
  "@http-util/status-i18n": "0.9.0",
7
7
  "@intlify/eslint-plugin-vue-i18n": "4.1.0",
@@ -10,7 +10,7 @@
10
10
  "@nuxt/image": "2.0.0",
11
11
  "@nuxtjs/color-mode": "4.0.0",
12
12
  "@nuxtjs/html-validator": "2.1.0",
13
- "@nuxtjs/i18n": "10.2.0",
13
+ "@nuxtjs/i18n": "10.2.1",
14
14
  "@nuxtjs/seo": "3.2.2",
15
15
  "@pinia/nuxt": "0.11.3",
16
16
  "@tailwindcss/forms": "0.5.10",
@@ -21,7 +21,7 @@
21
21
  "@urql/vue": "2.0.0",
22
22
  "@vuelidate/core": "2.0.3",
23
23
  "@vuelidate/validators": "2.0.4",
24
- "clipboardy": "5.0.0",
24
+ "clipboardy": "5.0.1",
25
25
  "dayjs": "2.0.0-alpha.4",
26
26
  "eslint": "9.39.1",
27
27
  "eslint-config-prettier": "10.1.8",
@@ -30,14 +30,14 @@
30
30
  "eslint-plugin-yml": "1.19.0",
31
31
  "globals": "16.5.0",
32
32
  "jiti": "2.6.1",
33
- "jose": "6.1.1",
33
+ "jose": "6.1.2",
34
34
  "nuxt-gtag": "4.1.0",
35
- "nuxt-security": "2.4.0",
35
+ "nuxt-security": "2.5.0",
36
36
  "sweetalert2": "11.26.3",
37
- "vue-tsc": "3.1.3"
37
+ "vue-tsc": "3.1.5"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "24.10.0",
40
+ "@types/node": "24.10.1",
41
41
  "@urql/devtools": "2.0.3",
42
42
  "@urql/exchange-graphcache": "8.1.0",
43
43
  "consola": "3.4.2",
@@ -50,12 +50,12 @@
50
50
  "prettier-plugin-tailwindcss": "0.7.1",
51
51
  "serve": "14.2.5",
52
52
  "sharp": "0.34.5",
53
- "stylelint": "16.25.0",
53
+ "stylelint": "16.26.0",
54
54
  "stylelint-config-recommended-vue": "1.6.1",
55
55
  "stylelint-config-standard": "39.0.1",
56
56
  "stylelint-no-unsupported-browser-features": "8.0.5",
57
57
  "tailwindcss": "4.1.17",
58
- "vue": "3.5.24",
58
+ "vue": "3.5.25",
59
59
  "vue-router": "4.6.3"
60
60
  },
61
61
  "engines": {
@@ -106,5 +106,5 @@
106
106
  "start:static": "serve playground/.output/public --ssl-cert ./.config/certificates/ssl.crt --ssl-key ./.config/certificates/ssl.key"
107
107
  },
108
108
  "type": "module",
109
- "version": "19.0.2"
109
+ "version": "19.1.0"
110
110
  }
@@ -1,5 +1,7 @@
1
+ import type { AppConfig } from 'nuxt/schema'
2
+
1
3
  export default defineEventHandler(async (event) => {
2
- const config = useAppConfig() as AppConfig
4
+ const config = useAppConfig(event) as AppConfig
3
5
 
4
6
  if (!config.vio.server) return
5
7
 
@@ -1,5 +1,5 @@
1
1
  export default defineEventHandler(async (event) => {
2
- event.context.$timezone = await getTimezoneServer(event)
2
+ event.context.$timezone = await getTimezone(event)
3
3
  })
4
4
 
5
5
  declare module 'h3' {
@@ -1,9 +1,9 @@
1
1
  import { defu } from 'defu'
2
- import type { NuxtOptions } from 'nuxt/schema'
2
+ import type { ModuleOptions } from 'nuxt-security'
3
3
 
4
4
  // remove invalid `'none'`s and duplicates
5
5
  export const cleanupCsp = (
6
- nuxtSecurityConfiguration: Partial<NuxtOptions['security']>,
6
+ nuxtSecurityConfiguration: Partial<ModuleOptions>,
7
7
  ) => {
8
8
  if (
9
9
  nuxtSecurityConfiguration.headers &&
@@ -4,6 +4,6 @@ export const useSiteUrl = () => {
4
4
 
5
5
  return {
6
6
  siteUrl,
7
- siteUrlTyped: new URL(siteUrl), // eslint-disable-line compat/compat
7
+ siteUrlTyped: new URL(siteUrl),
8
8
  }
9
9
  }
@@ -1,7 +1,6 @@
1
1
  import type { H3Event } from 'h3'
2
2
 
3
- // TODO: rename to `getTimezone` (https://github.com/nuxt/cli/issues/266)
4
- export const getTimezoneServer = async (event: H3Event) => {
3
+ export const getTimezone = async (event: H3Event) => {
5
4
  const timezoneBySsr = event.context.$timezone
6
5
 
7
6
  if (timezoneBySsr) return timezoneBySsr
@@ -113,14 +113,6 @@ export const VIO_GET_CSP = ({ siteUrl }: { siteUrl: URL }) =>
113
113
  : {}),
114
114
  'connect-src': [
115
115
  "'self'", // e.g. `/_nuxt/builds/meta/`, `/_payload.json`, `/privacy-policy/_payload.json`
116
- // ...(process.env.NODE_ENV === 'development'
117
- // ? [
118
- // 'http://localhost:3000/_nuxt/', // hot reload
119
- // 'https://localhost:3000/_nuxt/', // hot reload
120
- // 'ws://localhost:3000/_nuxt/', // hot reload
121
- // 'wss://localhost:3000/_nuxt/', // hot reload
122
- // ] // TODO: generalize for different ports
123
- // : []),
124
116
  ],
125
117
  'img-src': [
126
118
  "'self'", // e.g. favicon
@@ -1,5 +1,6 @@
1
1
  import type { Validation } from '@vuelidate/core'
2
2
  import { consola } from 'consola'
3
+ import type { Ref } from 'vue'
3
4
 
4
5
  export const isFormValid = async ({
5
6
  v$,
@@ -1,7 +1,10 @@
1
1
  import type { CombinedError } from '@urql/core'
2
2
  import type { H3Event } from 'h3'
3
+ import { computed, reactive } from 'vue'
3
4
  import type { Ref } from 'vue'
4
5
 
6
+ import type { ApiData, BackendError } from '../types/api'
7
+
5
8
  export const getApiDataDefault = (): ApiData =>
6
9
  computed(() =>
7
10
  reactive({
@@ -100,9 +103,7 @@ export const getServiceHref = ({
100
103
 
101
104
  if (stagingHost) {
102
105
  return `https://${nameSubdomainString}${stagingHost}`
103
- // TODO: remove disable below (https://github.com/nuxt/nuxt/issues/25323)
104
- // eslint-disable-next-line nuxt/prefer-import-meta
105
- } else if (isSsr && process.server) {
106
+ } else if (isSsr && import.meta.server) {
106
107
  return `http://${name}${portString}`
107
108
  } else {
108
109
  return `https://${nameSubdomainString}${getRootHost(host)}`
@@ -1,3 +1,5 @@
1
+ import type { defineNuxtConfig } from 'nuxt/config'
2
+
1
3
  import { I18N_MODULE_CONFIG } from './constants'
2
4
 
3
5
  export const VIO_NUXT_BASE_CONFIG = ({
@@ -1,4 +1,4 @@
1
- import type { RouteLocationRaw } from '#vue-router'
1
+ import type { RouteLocationRaw } from 'vue-router'
2
2
 
3
3
  export const append = (path: string, pathToAppend?: RouteLocationRaw) =>
4
4
  path + (path.endsWith('/') ? '' : '/') + (pathToAppend ?? '')
@@ -1,3 +0,0 @@
1
- {
2
- "extends": "../playground/.nuxt/tsconfig.server.json"
3
- }
@@ -1,126 +0,0 @@
1
- import type { Client } from '@urql/vue'
2
- import { consola } from 'consola'
3
- import { setCookie } from 'h3'
4
- import type { H3Event } from 'h3'
5
- import { decodeJwt } from 'jose'
6
-
7
- import { useVioAuthStore } from '../../app/stores/auth'
8
-
9
- export const getJwtFromCookie = () => {
10
- const cookie = useCookie(JWT_NAME())
11
-
12
- if (!cookie.value) {
13
- consola.debug('No token cookie.')
14
- return
15
- }
16
-
17
- const jwt = decodeJwt(cookie.value)
18
-
19
- if (jwt.exp === undefined || jwt.exp <= Date.now() / 1000) {
20
- consola.info('Token expired.')
21
- return
22
- }
23
-
24
- return {
25
- jwt: cookie.value,
26
- jwtDecoded: jwt,
27
- }
28
- }
29
-
30
- export const jwtStore = async ({
31
- $urqlReset,
32
- event,
33
- isInProduction,
34
- jwt,
35
- store,
36
- }: {
37
- $urqlReset: () => Client
38
- event?: H3Event
39
- isInProduction: boolean
40
- jwt?: string
41
- store: ReturnType<typeof useVioAuthStore>
42
- }) => {
43
- $urqlReset()
44
-
45
- consola.trace('Storing the following JWT: ' + jwt)
46
- store.jwtSet(jwt)
47
-
48
- if (event) {
49
- setCookie(event, JWT_NAME(), jwt || '', {
50
- expires: jwt ? new Date(Date.now() + 86400 * 1000 * 31) : new Date(0),
51
- httpOnly: true,
52
- path: '/',
53
- sameSite: 'lax', // Cannot be 'strict' to allow authentications after clicking on links within webmailers.
54
- secure: isInProduction,
55
- })
56
- } else {
57
- try {
58
- await $fetch('/api/auth', {
59
- method: 'POST',
60
- ...(jwt ? { headers: { Authorization: `Bearer ${jwt}` } } : {}),
61
- })
62
- } catch (error) {
63
- console.error(error)
64
- return Promise.reject(Error('Authentication api call failed.'))
65
- }
66
- }
67
- }
68
-
69
- export const useJwtStore = () => {
70
- const { $urqlReset, ssrContext } = useNuxtApp()
71
- const store = useVioAuthStore()
72
- const runtimeConfig = useRuntimeConfig()
73
-
74
- return {
75
- async jwtStore(jwt?: string) {
76
- await jwtStore({
77
- $urqlReset: $urqlReset as () => Client,
78
- event: ssrContext?.event,
79
- isInProduction: runtimeConfig.public.vio.isInProduction,
80
- jwt,
81
- store,
82
- })
83
- },
84
- }
85
- }
86
-
87
- export const signOut = async ({
88
- $urqlReset,
89
- // client,
90
- event,
91
- isInProduction,
92
- store,
93
- }: {
94
- $urqlReset: () => Client
95
- client: Client
96
- event?: H3Event
97
- isInProduction: boolean
98
- store: ReturnType<typeof useVioAuthStore>
99
- }) => {
100
- await jwtStore({ $urqlReset, event, isInProduction, store })
101
- // await authenticationAnonymous({
102
- // $urqlReset,
103
- // client,
104
- // event,
105
- // isInProduction,
106
- // store,
107
- // })
108
- }
109
-
110
- export const useSignOut = () => {
111
- const { $urql, $urqlReset, ssrContext } = useNuxtApp()
112
- const store = useVioAuthStore()
113
- const runtimeConfig = useRuntimeConfig()
114
-
115
- return {
116
- async signOut() {
117
- await signOut({
118
- $urqlReset: $urqlReset as () => Client,
119
- client: ($urql as Ref<Client>).value,
120
- event: ssrContext?.event,
121
- isInProduction: runtimeConfig.public.vio.isInProduction,
122
- store,
123
- })
124
- },
125
- }
126
- }
File without changes