tiktok-live-nuxt 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-present TikTool (tik.tools)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ <p align="center">
2
+ <img src="banner.png" alt="tiktok-live-nuxt" width="100%" />
3
+ </p>
4
+
5
+ <h1 align="center">tiktok-live-nuxt</h1>
6
+
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/tiktok-live-nuxt"><img src="https://img.shields.io/npm/v/tiktok-live-nuxt?color=%2300dc82&logo=nuxt.js&logoColor=white" alt="npm version"></a>
9
+ <a href="https://www.npmjs.com/package/tiktok-live-nuxt"><img src="https://img.shields.io/npm/dm/tiktok-live-nuxt?color=%2300dc82" alt="npm downloads"></a>
10
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
11
+ </p>
12
+
13
+ <p align="center">
14
+ Nuxt module for <a href="https://tik.tools">TikTok LIVE API</a> — real-time chat, gifts, viewers, battles & AI captions from any TikTok LIVE stream.
15
+ </p>
16
+
17
+ ---
18
+
19
+ ```vue
20
+ <script setup>
21
+ const { messages, viewers, gifts, connected } = useTikTokLive('gbnews')
22
+ </script>
23
+
24
+ <template>
25
+ <div>
26
+ <p>👀 {{ viewers }} viewers</p>
27
+ <div v-for="msg in messages" :key="msg.data?.msgId">
28
+ <b>{{ msg.data?.user?.uniqueId }}:</b> {{ msg.data?.comment }}
29
+ </div>
30
+ </div>
31
+ </template>
32
+ ```
33
+
34
+ That's it. Auto-imported, reactive, auto-connects on mount. ☝️
35
+
36
+ ---
37
+
38
+ ## Quick Setup
39
+
40
+ ### 1. Install
41
+
42
+ ```bash
43
+ # npm
44
+ npm install tiktok-live-nuxt
45
+
46
+ # pnpm
47
+ pnpm add tiktok-live-nuxt
48
+
49
+ # bun
50
+ bun add tiktok-live-nuxt
51
+
52
+ # yarn
53
+ yarn add tiktok-live-nuxt
54
+ ```
55
+
56
+ ### 2. Configure
57
+
58
+ Add to `nuxt.config.ts`:
59
+
60
+ ```typescript
61
+ export default defineNuxtConfig({
62
+ modules: ['tiktok-live-nuxt'],
63
+ tiktool: {
64
+ apiKey: 'YOUR_API_KEY' // Get free key → https://tik.tools
65
+ }
66
+ })
67
+ ```
68
+
69
+ Or via environment variable (recommended for production):
70
+
71
+ ```env
72
+ TIKTOOL_API_KEY=your_api_key
73
+ ```
74
+
75
+ ### 3. Use
76
+
77
+ ```vue
78
+ <script setup>
79
+ const { messages, viewers, gifts, connected, error } = useTikTokLive('username')
80
+ </script>
81
+ ```
82
+
83
+ No imports needed — `useTikTokLive` is auto-imported by the module.
84
+
85
+ ---
86
+
87
+ ## SSR & Client-Side
88
+
89
+ This composable uses **WebSocket** which only runs in the browser. It's designed to work correctly in both SSR and CSR modes:
90
+
91
+ | Mode | Behavior |
92
+ |------|----------|
93
+ | **SSR** (`ssr: true`) | Server renders initial empty state. WebSocket connects on client hydration via `onMounted`. |
94
+ | **SPA** (`ssr: false`) | WebSocket connects immediately on mount. |
95
+ | **Client-only component** | Wrap in `<ClientOnly>` if you want to avoid SSR flash of empty state. |
96
+
97
+ ```vue
98
+ <!-- Option 1: Works out of the box (SSR-safe) -->
99
+ <script setup>
100
+ const { messages, connected } = useTikTokLive('gbnews')
101
+ </script>
102
+
103
+ <!-- Option 2: Client-only wrapper (avoids empty state flash) -->
104
+ <ClientOnly>
105
+ <TikTokChat username="gbnews" />
106
+ </ClientOnly>
107
+ ```
108
+
109
+ ---
110
+
111
+ ## API Reference
112
+
113
+ ### `useTikTokLive(uniqueId, options?)`
114
+
115
+ | Param | Type | Default | Description |
116
+ |-------|------|---------|-------------|
117
+ | `uniqueId` | `string` | — | TikTok username (with or without `@`) |
118
+ | `options.apiKey` | `string` | from config | Override the module-level API key |
119
+ | `options.autoConnect` | `boolean` | `true` | Connect on mount |
120
+
121
+ ### Reactive Returns
122
+
123
+ | Property | Type | Description |
124
+ |----------|------|-------------|
125
+ | `connected` | `Ref<boolean>` | WebSocket connection state |
126
+ | `viewers` | `Ref<number>` | Current viewer count |
127
+ | `messages` | `Ref<TikTokEvent[]>` | Chat messages (last 100) |
128
+ | `gifts` | `Ref<TikTokEvent[]>` | Gift events (last 50) |
129
+ | `allEvents` | `Ref<TikTokEvent[]>` | All events (last 200) |
130
+ | `eventCount` | `Ref<number>` | Total events received |
131
+ | `error` | `Ref<string \| null>` | Last error message |
132
+
133
+ ### Methods
134
+
135
+ | Method | Description |
136
+ |--------|-------------|
137
+ | `connect()` | Manually connect (if `autoConnect: false`) |
138
+ | `disconnect()` | Close the connection |
139
+ | `on(event, handler)` | Register a custom event handler |
140
+
141
+ ---
142
+
143
+ ## Events
144
+
145
+ ```vue
146
+ <script setup>
147
+ const tiktok = useTikTokLive('gbnews')
148
+
149
+ tiktok.on('chat', (data) => {
150
+ // data.user.uniqueId, data.comment
151
+ })
152
+
153
+ tiktok.on('gift', (data) => {
154
+ // data.user.uniqueId, data.giftName, data.diamondCount
155
+ })
156
+
157
+ tiktok.on('like', (data) => {
158
+ // data.user.uniqueId, data.likeCount
159
+ })
160
+
161
+ tiktok.on('follow', (data) => {
162
+ // data.user.uniqueId
163
+ })
164
+
165
+ tiktok.on('roomUserSeq', (data) => {
166
+ // data.viewerCount
167
+ })
168
+ </script>
169
+ ```
170
+
171
+ | Event | Key Fields |
172
+ |-------|-----------|
173
+ | `chat` | `user.uniqueId`, `comment` |
174
+ | `gift` | `user.uniqueId`, `giftName`, `diamondCount` |
175
+ | `like` | `user.uniqueId`, `likeCount` |
176
+ | `follow` | `user.uniqueId` |
177
+ | `member` | `user.uniqueId` (viewer joined) |
178
+ | `roomUserSeq` | `viewerCount` |
179
+ | `battle` | `type`, `teams`, `scores` |
180
+
181
+ ---
182
+
183
+ ## Full Example
184
+
185
+ ```vue
186
+ <script setup>
187
+ const username = ref('gbnews')
188
+ const tiktok = useTikTokLive(username.value)
189
+
190
+ const topGifters = computed(() => {
191
+ const map = new Map()
192
+ for (const g of tiktok.gifts.value) {
193
+ const user = g.data?.user?.uniqueId
194
+ const diamonds = g.data?.diamondCount || 0
195
+ map.set(user, (map.get(user) || 0) + diamonds)
196
+ }
197
+ return [...map.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5)
198
+ })
199
+ </script>
200
+
201
+ <template>
202
+ <div v-if="tiktok.error.value" class="error">{{ tiktok.error.value }}</div>
203
+
204
+ <div v-else-if="!tiktok.connected.value">Connecting to @{{ username }}...</div>
205
+
206
+ <div v-else>
207
+ <p>✅ Connected — 👀 {{ tiktok.viewers.value }} viewers — {{ tiktok.eventCount.value }} events</p>
208
+
209
+ <h3>💬 Chat</h3>
210
+ <div v-for="msg in tiktok.messages.value" :key="msg.data?.msgId">
211
+ <b>{{ msg.data?.user?.uniqueId }}:</b> {{ msg.data?.comment }}
212
+ </div>
213
+
214
+ <h3>🏆 Top Gifters</h3>
215
+ <div v-for="([name, diamonds], i) in topGifters" :key="name">
216
+ {{ i + 1 }}. @{{ name }} — {{ diamonds }} 💎
217
+ </div>
218
+ </div>
219
+ </template>
220
+ ```
221
+
222
+ ---
223
+
224
+ ## Other SDKs
225
+
226
+ | Platform | Package | Install |
227
+ |----------|---------|---------|
228
+ | **Node.js / TypeScript** | [tiktok-live-api](https://www.npmjs.com/package/tiktok-live-api) | `npm i tiktok-live-api` |
229
+ | **Python** | [tiktok-live-api](https://pypi.org/project/tiktok-live-api/) | `pip install tiktok-live-api` |
230
+ | **Any language** | [WebSocket API](https://tik.tools/docs) | `wss://api.tik.tools` |
231
+
232
+ ## Links
233
+
234
+ - 🌐 [tik.tools](https://tik.tools) — Dashboard & API keys
235
+ - 📖 [Documentation](https://tik.tools/docs)
236
+ - 🎙️ [AI Live Captions](https://tik.tools/captions)
237
+ - 💬 [Discord](https://discord.gg/y8TwuFBAmD)
238
+
239
+ ## License
240
+
241
+ MIT — [tik.tools](https://tik.tools)
package/banner.png ADDED
Binary file
@@ -0,0 +1,5 @@
1
+ module.exports = function(...args) {
2
+ return import('./module.mjs').then(m => m.default.call(this, ...args))
3
+ }
4
+ const _meta = module.exports.meta = require('./module.json')
5
+ module.exports.getMeta = () => Promise.resolve(_meta)
@@ -0,0 +1,13 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ /**
5
+ * Your TikTool API key. Get one free at https://tik.tools
6
+ * Can also be set via TIKTOOL_API_KEY environment variable.
7
+ */
8
+ apiKey?: string;
9
+ }
10
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
11
+
12
+ export { _default as default };
13
+ export type { ModuleOptions };
@@ -0,0 +1,13 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ /**
5
+ * Your TikTool API key. Get one free at https://tik.tools
6
+ * Can also be set via TIKTOOL_API_KEY environment variable.
7
+ */
8
+ apiKey?: string;
9
+ }
10
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
11
+
12
+ export { _default as default };
13
+ export type { ModuleOptions };
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "tiktok-live-nuxt",
3
+ "configKey": "tiktool",
4
+ "compatibility": {
5
+ "nuxt": ">=3.0.0"
6
+ },
7
+ "version": "1.0.0",
8
+ "builder": {
9
+ "@nuxt/module-builder": "0.8.4",
10
+ "unbuild": "2.0.0"
11
+ }
12
+ }
@@ -0,0 +1,24 @@
1
+ import { defineNuxtModule, createResolver, addImportsDir } from '@nuxt/kit';
2
+
3
+ const module = defineNuxtModule({
4
+ meta: {
5
+ name: "tiktok-live-nuxt",
6
+ configKey: "tiktool",
7
+ compatibility: {
8
+ nuxt: ">=3.0.0"
9
+ }
10
+ },
11
+ defaults: {
12
+ apiKey: ""
13
+ },
14
+ setup(options, nuxt) {
15
+ const resolver = createResolver(import.meta.url);
16
+ const apiKey = options.apiKey || process.env.TIKTOOL_API_KEY || "";
17
+ nuxt.options.runtimeConfig.public.tiktool = {
18
+ apiKey
19
+ };
20
+ addImportsDir(resolver.resolve("runtime/composables"));
21
+ }
22
+ });
23
+
24
+ export { module as default };
@@ -0,0 +1,56 @@
1
+ import { type Ref } from 'vue';
2
+ interface TikTokEvent {
3
+ event: string;
4
+ data: Record<string, any>;
5
+ }
6
+ interface UseTikTokLiveOptions {
7
+ /** Override the API key from module config */
8
+ apiKey?: string;
9
+ /** Auto-connect on mount (default: true) */
10
+ autoConnect?: boolean;
11
+ /** Events to listen for (default: all) */
12
+ events?: string[];
13
+ }
14
+ interface UseTikTokLiveReturn {
15
+ /** Whether the WebSocket is connected */
16
+ connected: Ref<boolean>;
17
+ /** Current viewer count */
18
+ viewers: Ref<number>;
19
+ /** Recent chat messages (last 100) */
20
+ messages: Ref<TikTokEvent[]>;
21
+ /** Recent gift events (last 50) */
22
+ gifts: Ref<TikTokEvent[]>;
23
+ /** All events (last 200) */
24
+ allEvents: Ref<TikTokEvent[]>;
25
+ /** Total events received */
26
+ eventCount: Ref<number>;
27
+ /** Last error */
28
+ error: Ref<string | null>;
29
+ /** Connect to the stream */
30
+ connect: () => void;
31
+ /** Disconnect from the stream */
32
+ disconnect: () => void;
33
+ /** Register a custom event handler */
34
+ on: (event: string, handler: (data: any) => void) => void;
35
+ }
36
+ /**
37
+ * Composable to connect to a TikTok LIVE stream and receive real-time events.
38
+ *
39
+ * @example
40
+ * ```vue
41
+ * <script setup>
42
+ * const { messages, viewers, gifts, connected } = useTikTokLive('gbnews')
43
+ * </script>
44
+ *
45
+ * <template>
46
+ * <div v-if="connected">
47
+ * <p>👀 {{ viewers }} viewers</p>
48
+ * <div v-for="msg in messages" :key="msg.data?.msgId">
49
+ * {{ msg.data?.user?.uniqueId }}: {{ msg.data?.comment }}
50
+ * </div>
51
+ * </div>
52
+ * </template>
53
+ * ```
54
+ */
55
+ export declare function useTikTokLive(uniqueId: string, options?: UseTikTokLiveOptions): UseTikTokLiveReturn;
56
+ export {};
@@ -0,0 +1,112 @@
1
+ import { ref, onMounted, onUnmounted } from "vue";
2
+ import { useRuntimeConfig } from "#imports";
3
+ export function useTikTokLive(uniqueId, options = {}) {
4
+ const config = useRuntimeConfig();
5
+ const apiKey = options.apiKey || config.public.tiktool?.apiKey || "";
6
+ const connected = ref(false);
7
+ const viewers = ref(0);
8
+ const messages = ref([]);
9
+ const gifts = ref([]);
10
+ const allEvents = ref([]);
11
+ const eventCount = ref(0);
12
+ const error = ref(null);
13
+ let ws = null;
14
+ const customHandlers = /* @__PURE__ */ new Map();
15
+ function on(event, handler) {
16
+ if (!customHandlers.has(event)) {
17
+ customHandlers.set(event, /* @__PURE__ */ new Set());
18
+ }
19
+ customHandlers.get(event).add(handler);
20
+ }
21
+ function emitCustom(event, data) {
22
+ const handlers = customHandlers.get(event);
23
+ if (handlers) {
24
+ for (const handler of handlers) {
25
+ try {
26
+ handler(data);
27
+ } catch (e) {
28
+ console.error(e);
29
+ }
30
+ }
31
+ }
32
+ }
33
+ function connect() {
34
+ if (ws) return;
35
+ if (!apiKey) {
36
+ error.value = "No API key. Set it in nuxt.config.ts under tiktool.apiKey or via TIKTOOL_API_KEY env var.";
37
+ console.error("[TikTool]", error.value);
38
+ return;
39
+ }
40
+ const cleanId = uniqueId.replace(/^@/, "");
41
+ const url = `wss://api.tik.tools?uniqueId=${cleanId}&apiKey=${apiKey}`;
42
+ try {
43
+ ws = new WebSocket(url);
44
+ } catch (e) {
45
+ error.value = e.message;
46
+ return;
47
+ }
48
+ ws.onopen = () => {
49
+ connected.value = true;
50
+ error.value = null;
51
+ emitCustom("connected", { uniqueId: cleanId });
52
+ };
53
+ ws.onmessage = (evt) => {
54
+ try {
55
+ const event = JSON.parse(evt.data);
56
+ eventCount.value++;
57
+ const eventType = event.event || "unknown";
58
+ const data = event.data || event;
59
+ allEvents.value = [event, ...allEvents.value].slice(0, 200);
60
+ switch (eventType) {
61
+ case "chat":
62
+ messages.value = [event, ...messages.value].slice(0, 100);
63
+ break;
64
+ case "gift":
65
+ gifts.value = [event, ...gifts.value].slice(0, 50);
66
+ break;
67
+ case "roomUserSeq":
68
+ viewers.value = data.viewerCount || 0;
69
+ break;
70
+ }
71
+ emitCustom("event", event);
72
+ emitCustom(eventType, data);
73
+ } catch {
74
+ }
75
+ };
76
+ ws.onclose = () => {
77
+ connected.value = false;
78
+ ws = null;
79
+ emitCustom("disconnected", { uniqueId: cleanId });
80
+ };
81
+ ws.onerror = (e) => {
82
+ error.value = "WebSocket error";
83
+ emitCustom("error", { error: "WebSocket error" });
84
+ };
85
+ }
86
+ function disconnect() {
87
+ if (ws) {
88
+ ws.close();
89
+ ws = null;
90
+ }
91
+ connected.value = false;
92
+ }
93
+ const autoConnect = options.autoConnect !== false;
94
+ onMounted(() => {
95
+ if (autoConnect) connect();
96
+ });
97
+ onUnmounted(() => {
98
+ disconnect();
99
+ });
100
+ return {
101
+ connected,
102
+ viewers,
103
+ messages,
104
+ gifts,
105
+ allEvents,
106
+ eventCount,
107
+ error,
108
+ connect,
109
+ disconnect,
110
+ on
111
+ };
112
+ }
@@ -0,0 +1,7 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+
3
+ import type { default as Module } from './module.js'
4
+
5
+ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
+
7
+ export { default } from './module.js'
@@ -0,0 +1,7 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+
3
+ import type { default as Module } from './module'
4
+
5
+ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
+
7
+ export { default } from './module'
package/logo.svg ADDED
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg id="Layer_2" data-name="Layer 2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 90.68 90.68">
3
+ <defs>
4
+ <style>
5
+ .cls-1 {
6
+ fill: url(#linear-gradient);
7
+ }
8
+ </style>
9
+ <linearGradient id="linear-gradient" x1="49.6" y1="49.98" x2="82.57" y2="85.91" gradientUnits="userSpaceOnUse">
10
+ <stop offset=".1" stop-color="#fff"/>
11
+ <stop offset=".98" stop-color="#bcbec0"/>
12
+ </linearGradient>
13
+ </defs>
14
+ <g id="Layer_1-2" data-name="Layer 1">
15
+ <path class="cls-1" d="M70.93,0H19.76C8.85,0,0,8.85,0,19.76v51.17c0,10.91,8.85,19.76,19.76,19.76h26.81c1.8,0,3.52-.71,4.79-1.98l37.6-37.6c1.11-1.11,1.73-2.61,1.73-4.18v-27.17c0-10.91-8.85-19.76-19.76-19.76ZM73.65,32.95c0,1.64-1.33,2.96-2.96,2.96h-13.42c-1.64,0-2.96,1.33-2.96,2.96v23.97c0,.5-.2.99-.56,1.34l-8.98,8.98c-.32.32-.75.5-1.2.5h-4.25c-1.64,0-2.96-1.33-2.96-2.96v-31.82c0-1.64-1.33-2.96-2.96-2.96h-13.41c-1.64,0-2.96-1.33-2.96-2.96v-12.95c0-1.64,1.33-2.96,2.96-2.96h50.69c1.64,0,2.96,1.33,2.96,2.96v12.95Z"/>
16
+ </g>
17
+ </svg>
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "tiktok-live-nuxt",
3
+ "version": "1.0.0",
4
+ "description": "Nuxt module for TikTok LIVE API — real-time chat, gifts, viewers, battles, and AI captions",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/types.d.mts",
10
+ "import": "./dist/module.mjs",
11
+ "require": "./dist/module.cjs"
12
+ }
13
+ },
14
+ "main": "./dist/module.cjs",
15
+ "types": "./dist/types.d.mts",
16
+ "files": [
17
+ "dist",
18
+ "banner.png",
19
+ "logo.svg"
20
+ ],
21
+ "keywords": [
22
+ "nuxt",
23
+ "nuxt-module",
24
+ "tiktok",
25
+ "tiktok-live",
26
+ "tiktok-api",
27
+ "websocket",
28
+ "live-streaming",
29
+ "real-time",
30
+ "chat",
31
+ "gifts",
32
+ "captions",
33
+ "speech-to-text"
34
+ ],
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/tiktool/tiktok-live-nuxt"
38
+ },
39
+ "homepage": "https://tik.tools",
40
+ "bugs": {
41
+ "url": "https://github.com/tiktool/tiktok-live-nuxt/issues"
42
+ },
43
+ "scripts": {
44
+ "prepack": "nuxt-module-build build",
45
+ "dev": "nuxi dev playground",
46
+ "dev:build": "nuxi build playground",
47
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
48
+ "lint": "eslint .",
49
+ "test": "vitest run",
50
+ "test:watch": "vitest watch"
51
+ },
52
+ "dependencies": {
53
+ "@nuxt/kit": "^3.16.0",
54
+ "tiktok-live-api": "^1.0.0"
55
+ },
56
+ "devDependencies": {
57
+ "@nuxt/module-builder": "^0.8.0",
58
+ "@nuxt/schema": "^3.16.0",
59
+ "nuxt": "^3.16.0",
60
+ "typescript": "^5.5.0"
61
+ }
62
+ }