nuxtseo-shared 0.1.8 → 0.2.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 (55) hide show
  1. package/dist/content.d.mts +37 -37
  2. package/dist/content.d.ts +75 -0
  3. package/dist/content.mjs +31 -55
  4. package/dist/devtools.d.mts +10 -10
  5. package/dist/devtools.d.ts +14 -0
  6. package/dist/devtools.mjs +43 -37
  7. package/dist/i18n.d.mts +19 -19
  8. package/dist/i18n.d.ts +44 -0
  9. package/dist/i18n.mjs +117 -105
  10. package/dist/kit.d.mts +29 -14
  11. package/dist/kit.d.ts +57 -0
  12. package/dist/kit.mjs +105 -77
  13. package/dist/module.d.mts +4 -13
  14. package/dist/module.d.ts +5 -0
  15. package/dist/module.json +12 -0
  16. package/dist/module.mjs +31 -32
  17. package/dist/pro.d.mts +2 -16
  18. package/dist/pro.d.ts +3 -0
  19. package/dist/pro.mjs +66 -68
  20. package/dist/runtime/pure.d.ts +0 -0
  21. package/dist/runtime/pure.js +36 -0
  22. package/dist/runtime/server/kit.d.ts +0 -0
  23. package/dist/runtime/server/kit.js +22 -0
  24. package/dist/telemetry.d.mts +4 -4
  25. package/dist/telemetry.d.ts +11 -0
  26. package/dist/telemetry.mjs +58 -45
  27. package/dist/types.d.mts +7 -0
  28. package/package.json +23 -21
  29. package/src/runtime/pure.ts +57 -0
  30. package/src/runtime/server/kit.ts +26 -0
  31. package/dist/index.d.mts +0 -3
  32. package/dist/index.mjs +0 -3
  33. package/dist/layer-devtools/app.config.ts +0 -27
  34. package/dist/layer-devtools/assets/css/global.css +0 -593
  35. package/dist/layer-devtools/components/DevtoolsAlert.vue +0 -101
  36. package/dist/layer-devtools/components/DevtoolsCopyButton.vue +0 -20
  37. package/dist/layer-devtools/components/DevtoolsDocs.vue +0 -11
  38. package/dist/layer-devtools/components/DevtoolsEmptyState.vue +0 -105
  39. package/dist/layer-devtools/components/DevtoolsError.vue +0 -78
  40. package/dist/layer-devtools/components/DevtoolsKeyValue.vue +0 -109
  41. package/dist/layer-devtools/components/DevtoolsLayout.vue +0 -219
  42. package/dist/layer-devtools/components/DevtoolsLoading.vue +0 -8
  43. package/dist/layer-devtools/components/DevtoolsMetric.vue +0 -96
  44. package/dist/layer-devtools/components/DevtoolsPanel.vue +0 -76
  45. package/dist/layer-devtools/components/DevtoolsProductionError.vue +0 -41
  46. package/dist/layer-devtools/components/DevtoolsSnippet.vue +0 -51
  47. package/dist/layer-devtools/components/DevtoolsToolbar.vue +0 -42
  48. package/dist/layer-devtools/components/NuxtSeoLogo.vue +0 -77
  49. package/dist/layer-devtools/components/OCodeBlock.vue +0 -23
  50. package/dist/layer-devtools/components/OSectionBlock.vue +0 -139
  51. package/dist/layer-devtools/composables/clipboard.ts +0 -21
  52. package/dist/layer-devtools/composables/rpc.ts +0 -39
  53. package/dist/layer-devtools/composables/shiki.ts +0 -46
  54. package/dist/layer-devtools/composables/state.ts +0 -33
  55. package/dist/layer-devtools/nuxt.config.ts +0 -26
@@ -1,41 +0,0 @@
1
- <script setup lang="ts">
2
- import { previewSource, productionUrl } from '../composables/state'
3
-
4
- const { error } = defineProps<{
5
- error?: string | Error | null
6
- }>()
7
- </script>
8
-
9
- <template>
10
- <DevtoolsError
11
- icon="carbon:cloud-offline"
12
- title="Production site unreachable"
13
- :error="error"
14
- >
15
- <template v-if="!error">
16
- <p class="text-xs text-[var(--color-text-muted)] max-w-xs leading-relaxed">
17
- Could not connect to <code class="prod-url">{{ productionUrl }}</code>.
18
- Check that the site is deployed and accessible.
19
- </p>
20
- </template>
21
- <UButton
22
- variant="soft"
23
- size="xs"
24
- icon="carbon:laptop"
25
- @click="previewSource = 'local'"
26
- >
27
- Switch to local
28
- </UButton>
29
- </DevtoolsError>
30
- </template>
31
-
32
- <style scoped>
33
- .prod-url {
34
- font-family: var(--font-mono);
35
- font-size: 0.6875rem;
36
- padding: 0.125rem 0.375rem;
37
- border-radius: var(--radius-sm);
38
- background: var(--color-surface-sunken);
39
- border: 1px solid var(--color-border-subtle);
40
- }
41
- </style>
@@ -1,51 +0,0 @@
1
- <script setup lang="ts">
2
- const {
3
- label,
4
- code,
5
- lang = 'js',
6
- } = defineProps<{
7
- label?: string
8
- code: string
9
- lang?: 'js' | 'json' | 'xml'
10
- }>()
11
- </script>
12
-
13
- <template>
14
- <div class="devtools-snippet">
15
- <div v-if="label || $slots.header" class="devtools-snippet-header">
16
- <slot name="header">
17
- <code class="devtools-snippet-label">{{ label }}</code>
18
- </slot>
19
- <DevtoolsCopyButton :text="code" />
20
- </div>
21
- <OCodeBlock :code="code" :lang="lang" class="devtools-snippet-block" />
22
- </div>
23
- </template>
24
-
25
- <style scoped>
26
- .devtools-snippet {
27
- margin: 0.5rem 0.75rem;
28
- }
29
-
30
- .devtools-snippet-header {
31
- display: flex;
32
- align-items: center;
33
- justify-content: space-between;
34
- margin-bottom: 0.375rem;
35
- }
36
-
37
- .devtools-snippet-label {
38
- font-family: var(--font-mono);
39
- font-size: 0.6875rem;
40
- font-weight: 500;
41
- color: var(--color-text-muted);
42
- letter-spacing: -0.01em;
43
- }
44
-
45
- .devtools-snippet-block {
46
- border-radius: var(--radius-sm);
47
- font-size: 0.6875rem;
48
- line-height: 1.6;
49
- padding: 0.5rem 0.625rem !important;
50
- }
51
- </style>
@@ -1,42 +0,0 @@
1
- <script setup lang="ts">
2
- const {
3
- variant = 'default',
4
- } = defineProps<{
5
- variant?: 'default' | 'minimal'
6
- }>()
7
- </script>
8
-
9
- <template>
10
- <div class="devtools-toolbar" :class="`devtools-toolbar-${variant}`">
11
- <slot />
12
- </div>
13
- </template>
14
-
15
- <style scoped>
16
- .devtools-toolbar {
17
- display: flex;
18
- align-items: center;
19
- border-bottom: 1px solid var(--color-border);
20
- }
21
-
22
- .devtools-toolbar-default {
23
- justify-content: space-between;
24
- gap: 0.75rem;
25
- padding: 0.625rem 0.75rem;
26
- background: var(--color-surface-elevated);
27
- position: relative;
28
- }
29
-
30
- @media (min-width: 640px) {
31
- .devtools-toolbar-default {
32
- padding: 0.75rem 1rem;
33
- }
34
- }
35
-
36
- .devtools-toolbar-minimal {
37
- gap: 0.5rem;
38
- padding: 0.5rem 1rem;
39
- font-size: 0.75rem;
40
- background: var(--color-surface-sunken);
41
- }
42
- </style>
@@ -1,77 +0,0 @@
1
- <template>
2
- <div class="flex items-center gap-1">
3
- <svg viewBox="0 0 64 64" class="pop-quick w-7 h-7">
4
- <defs>
5
- <linearGradient id="wmLine1" x1="0%" y1="100%" x2="100%" y2="0%">
6
- <stop offset="0%" stop-color="#22c55e" />
7
- <stop offset="100%" stop-color="#86efac" />
8
- </linearGradient>
9
- <linearGradient id="wmFill1" x1="0%" y1="0%" x2="0%" y2="100%">
10
- <stop offset="0%" stop-color="#22c55e" stop-opacity="0.6" />
11
- <stop offset="100%" stop-color="#22c55e" stop-opacity="0" />
12
- </linearGradient>
13
- </defs>
14
- <path
15
- class="fill"
16
- d="M8 52 Q20 48 24 36 T40 20 T56 12 L56 56 L8 56 Z"
17
- fill="url(#wmFill1)"
18
- />
19
- <path
20
- class="line"
21
- d="M8 52 Q20 48 24 36 T40 20 T56 12"
22
- fill="none"
23
- stroke="url(#wmLine1)"
24
- stroke-width="4"
25
- stroke-linecap="round"
26
- />
27
- <circle class="node" cx="56" cy="12" r="6" fill="url(#wmLine1)" />
28
- </svg>
29
- <span class="-ml-1 dark:text-white text-black text-lg font-bold tracking-tight slide-right">
30
- Nuxt<span class="ml-1 text-green-400">SEO</span>
31
- </span>
32
- </div>
33
- </template>
34
-
35
- <style scoped>
36
- @keyframes drawLine {
37
- 0% { stroke-dashoffset: 100; }
38
- 100% { stroke-dashoffset: 0; }
39
- }
40
- @keyframes revealFill {
41
- 0% { clip-path: inset(0 100% 0 0); }
42
- 100% { clip-path: inset(0 0% 0 0); }
43
- }
44
- @keyframes popNode {
45
- 0%, 70% { opacity: 0; transform: scale(0); }
46
- 85% { transform: scale(1.3); opacity: 1; }
47
- 100% { transform: scale(1); opacity: 1; }
48
- }
49
- @keyframes slideRight {
50
- from {
51
- transform: scale(0.6) translateX(100%);
52
- opacity: 0;
53
- }
54
- to {
55
- transform: translateX(0);
56
- opacity: 1;
57
- }
58
- }
59
-
60
- .pop-quick .line {
61
- stroke-dasharray: 100;
62
- stroke-dashoffset: 100;
63
- animation: drawLine 0.8s ease-out forwards;
64
- }
65
- .pop-quick .fill {
66
- clip-path: inset(0 100% 0 0);
67
- animation: revealFill 0.4s ease-out forwards;
68
- }
69
- .pop-quick .node {
70
- opacity: 0;
71
- transform-origin: 56px 12px;
72
- animation: popNode 0.6s ease-out forwards;
73
- }
74
- .slide-right {
75
- animation: slideRight 400ms cubic-bezier(0.68, -0.55, 0.27, 1.55) forwards;
76
- }
77
- </style>
@@ -1,23 +0,0 @@
1
- <script setup lang="ts">
2
- import { useRenderCodeHighlight } from '../composables/shiki'
3
-
4
- const { code, lang, lines = false, transformRendered } = defineProps<{
5
- code: string
6
- lang: 'json' | 'xml' | 'js'
7
- lines?: boolean
8
- transformRendered?: (code: string) => string
9
- }>()
10
-
11
- const rendered = computed(() => {
12
- const highlight = useRenderCodeHighlight(code, lang)
13
- return transformRendered ? transformRendered(highlight.value || '') : highlight.value
14
- })
15
- </script>
16
-
17
- <template>
18
- <pre
19
- class="code-block p-5"
20
- :class="lines ? 'code-block-lines' : ''"
21
- v-html="rendered"
22
- />
23
- </template>
@@ -1,139 +0,0 @@
1
- <script setup lang="ts">
2
- const { icon, text, description, containerClass = '', collapse = true, padding = true, headerClass } = defineProps<{
3
- icon?: string
4
- text?: string
5
- description?: string
6
- containerClass?: string
7
- headerClass?: string
8
- collapse?: boolean
9
- open?: boolean
10
- padding?: boolean | string
11
- }>()
12
-
13
- const open = defineModel('open', { default: true })
14
-
15
- function onToggle(e: any) {
16
- open.value = e.target.open
17
- }
18
- </script>
19
-
20
- <template>
21
- <details :open="open" class="section-block" @toggle="onToggle">
22
- <summary class="section-header" :class="collapse ? '' : 'pointer-events-none'">
23
- <div class="section-title" :class="[open ? '' : 'opacity-60', headerClass]">
24
- <UIcon v-if="icon" :name="icon" class="section-icon" />
25
- <div class="flex-1 min-w-0">
26
- <div class="section-label">
27
- <slot name="text">
28
- {{ text }}
29
- </slot>
30
- </div>
31
- <div v-if="description || $slots.description" class="section-description">
32
- <slot name="description">
33
- {{ description }}
34
- </slot>
35
- </div>
36
- </div>
37
- <slot name="actions" />
38
- <UIcon
39
- v-if="collapse"
40
- name="carbon:chevron-down"
41
- class="chevron"
42
- />
43
- </div>
44
- </summary>
45
- <div
46
- class="section-content"
47
- :class="typeof padding === 'string' ? padding : padding ? 'px-4' : ''"
48
- >
49
- <slot name="details" />
50
- <div :class="containerClass">
51
- <slot />
52
- </div>
53
- <slot name="footer" />
54
- </div>
55
- </details>
56
- </template>
57
-
58
- <style scoped>
59
- .section-block {
60
- border: 1px solid var(--color-border);
61
- border-radius: var(--radius-lg);
62
- overflow: hidden;
63
- background: var(--color-surface-elevated);
64
- transition: border-color 200ms ease;
65
- }
66
-
67
- .section-block:hover {
68
- border-color: var(--color-neutral-300);
69
- }
70
-
71
- .dark .section-block:hover {
72
- border-color: var(--color-neutral-700);
73
- }
74
-
75
- .section-header {
76
- cursor: pointer;
77
- user-select: none;
78
- padding: 0.875rem 1rem;
79
- transition: background 150ms ease;
80
- list-style: none;
81
- }
82
-
83
- .section-header::-webkit-details-marker {
84
- display: none;
85
- }
86
-
87
- .section-header:hover {
88
- background: var(--color-surface-sunken);
89
- }
90
-
91
- details[open] .section-header {
92
- border-bottom: 1px solid var(--color-border);
93
- }
94
-
95
- .section-title {
96
- display: flex;
97
- align-items: center;
98
- gap: 0.625rem;
99
- transition: opacity 150ms ease;
100
- }
101
-
102
- .section-icon {
103
- color: var(--color-text-muted);
104
- font-size: 1.125rem;
105
- flex-shrink: 0;
106
- }
107
-
108
- .section-label {
109
- font-size: 0.875rem;
110
- font-weight: 600;
111
- color: var(--color-text);
112
- }
113
-
114
- .section-description {
115
- font-size: 0.75rem;
116
- color: var(--color-text-muted);
117
- margin-top: 0.125rem;
118
- }
119
-
120
- .chevron {
121
- color: var(--color-text-subtle);
122
- font-size: 0.875rem;
123
- flex-shrink: 0;
124
- transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
125
- }
126
-
127
- details[open] .chevron {
128
- transform: rotate(180deg);
129
- color: var(--color-text-muted);
130
- }
131
-
132
- .section-content {
133
- display: flex;
134
- flex-direction: column;
135
- gap: 0.75rem;
136
- padding: 1rem;
137
- background: var(--color-surface-sunken);
138
- }
139
- </style>
@@ -1,21 +0,0 @@
1
- import { useClipboard } from '@vueuse/core'
2
- import { ref, watch } from 'vue'
3
-
4
- export function useCopy(timeout = 2000) {
5
- const { copy, copied } = useClipboard({ legacy: true })
6
- const justCopied = ref(false)
7
-
8
- watch(copied, (val) => {
9
- if (val) {
10
- justCopied.value = true
11
- setTimeout(() => {
12
- justCopied.value = false
13
- }, timeout)
14
- }
15
- })
16
-
17
- return {
18
- copy,
19
- copied: justCopied,
20
- }
21
- }
@@ -1,39 +0,0 @@
1
- import type { NuxtDevtoolsClient } from '@nuxt/devtools-kit/types'
2
- import type { $Fetch } from 'nitropack/types'
3
- import type { Ref } from 'vue'
4
- import { onDevtoolsClientConnected } from '@nuxt/devtools-kit/iframe-client'
5
- import { ref, watchEffect } from 'vue'
6
-
7
- export const appFetch: Ref<$Fetch | undefined> = ref()
8
- export const devtools: Ref<NuxtDevtoolsClient | undefined> = ref()
9
- export const colorMode: Ref<'dark' | 'light'> = ref('dark')
10
-
11
- export interface DevtoolsConnectionOptions {
12
- onConnected?: (client: any) => void
13
- onRouteChange?: (route: any) => void
14
- }
15
-
16
- /**
17
- * Initialize the base devtools connection.
18
- * Call this in your module's devtools client setup.
19
- * Returns a cleanup function.
20
- */
21
- export function useDevtoolsConnection(options: DevtoolsConnectionOptions = {}): void {
22
- onDevtoolsClientConnected(async (client) => {
23
- // @ts-expect-error untyped
24
- appFetch.value = client.host.app.$fetch
25
- watchEffect(() => {
26
- colorMode.value = client.host.app.colorMode.value
27
- })
28
- devtools.value = client.devtools
29
- options.onConnected?.(client)
30
-
31
- if (options.onRouteChange) {
32
- const $route = client.host.nuxt.vueApp.config.globalProperties?.$route
33
- options.onRouteChange($route)
34
- client.host.nuxt.$router.afterEach((route: any) => {
35
- options.onRouteChange!(route)
36
- })
37
- }
38
- })
39
- }
@@ -1,46 +0,0 @@
1
- import type { HighlighterCore, LanguageRegistration } from 'shiki'
2
- import type { ComputedRef, MaybeRef, Ref } from 'vue'
3
- import { createHighlighterCore } from 'shiki/core'
4
- import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'
5
- import { computed, ref, toValue } from 'vue'
6
- import { colorMode } from './rpc'
7
-
8
- export const shiki: Ref<HighlighterCore | undefined> = ref()
9
-
10
- export interface LoadShikiOptions {
11
- extraLangs?: (LanguageRegistration | Promise<LanguageRegistration>)[]
12
- }
13
-
14
- export async function loadShiki(options: LoadShikiOptions = {}): Promise<HighlighterCore> {
15
- const langs: any[] = [
16
- import('@shikijs/langs/xml'),
17
- import('@shikijs/langs/json'),
18
- import('@shikijs/langs/js'),
19
- ]
20
- if (options.extraLangs) {
21
- langs.push(...options.extraLangs)
22
- }
23
-
24
- shiki.value = await createHighlighterCore({
25
- themes: [
26
- import('@shikijs/themes/vitesse-light'),
27
- import('@shikijs/themes/vitesse-dark'),
28
- ],
29
- langs,
30
- engine: createJavaScriptRegexEngine(),
31
- })
32
-
33
- return shiki.value
34
- }
35
-
36
- export function useRenderCodeHighlight(code: MaybeRef<string>, lang: string): ComputedRef<string> {
37
- return computed(() => {
38
- if (!shiki.value)
39
- return ''
40
- const theme = colorMode.value === 'dark' ? 'vitesse-dark' : 'vitesse-light'
41
- return shiki.value.codeToHtml(toValue(code) || '', {
42
- lang,
43
- theme,
44
- }) || ''
45
- })
46
- }
@@ -1,33 +0,0 @@
1
- import { useDebounceFn, useLocalStorage } from '@vueuse/core'
2
- import { hasProtocol, withBase } from 'ufo'
3
- import { computed, ref } from 'vue'
4
-
5
- export const refreshTime = ref(Date.now())
6
-
7
- export const hostname = window.location.host
8
- export const path = ref('/')
9
- export const query = ref()
10
- export const base = ref('/')
11
-
12
- export const host = computed(() => withBase(base.value, `${window.location.protocol}//${hostname}`))
13
-
14
- export const refreshSources = useDebounceFn(() => {
15
- refreshTime.value = Date.now()
16
- }, 200)
17
-
18
- export const slowRefreshSources = useDebounceFn(() => {
19
- refreshTime.value = Date.now()
20
- }, 1000)
21
-
22
- // Production preview state
23
- export const previewSource = useLocalStorage<'local' | 'production'>('nuxt-seo:preview-source', 'local')
24
- export const productionUrl = ref<string>('')
25
-
26
- export const hasProductionUrl = computed(() => {
27
- const url = productionUrl.value
28
- if (!url || !hasProtocol(url))
29
- return false
30
- return !url.includes('localhost') && !url.includes('127.0.0.1')
31
- })
32
-
33
- export const isProductionMode = computed(() => previewSource.value === 'production' && hasProductionUrl.value)
@@ -1,26 +0,0 @@
1
- import { createResolver } from '@nuxt/kit'
2
-
3
- const { resolve } = createResolver(import.meta.url)
4
-
5
- export default defineNuxtConfig({
6
- ssr: false,
7
-
8
- modules: [
9
- '@nuxt/fonts',
10
- '@nuxt/ui',
11
- ],
12
-
13
- css: [resolve('./assets/css/global.css')],
14
-
15
- fonts: {
16
- families: [
17
- { name: 'Hubot Sans' },
18
- ],
19
- },
20
-
21
- devtools: {
22
- enabled: false,
23
- },
24
-
25
- compatibilityDate: '2026-03-13',
26
- })