gsap-nuxt-module 1.1.5 → 1.1.8

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/README.md CHANGED
@@ -18,7 +18,8 @@ Find and replace all on all files (CMD+SHIFT+F):
18
18
 
19
19
  **Enhance your Nuxt application with powerful animations and transitions using GSAP!**
20
20
 
21
- - [🏀 Online playground](https://stackblitz.com/edit/gsap-nuxt-module?file=app.vue)
21
+ - [📖 Documentation](https://lucaargentieri.github.io/gsap-nuxt-module/)
22
+ - [🏀 Online playground](https://stackblitz.com/edit/gsap-nuxt-module?file=README.md)
22
23
  - [📖 GSAP](https://gsap.com/)
23
24
 
24
25
  ## Features
@@ -100,6 +101,114 @@ onMounted(() => {
100
101
 
101
102
  That's it! You can now use gsap-nuxt-module in your Nuxt app ✨
102
103
 
104
+ ## useGsap()
105
+
106
+ `useGsap()` returns the GSAP instance directly — use it to access `gsap.timeline()`,
107
+ `gsap.to()`, `gsap.set()`, utility methods like `gsap.utils.toArray()`, and more.
108
+ No import needed; it is auto-imported like all other composables.
109
+
110
+ ```ts
111
+ <script setup lang="ts">
112
+ const gsap = useGsap()
113
+ const boxRef = ref(null)
114
+
115
+ onMounted(() => {
116
+ const tl = gsap.timeline({ repeat: -1, yoyo: true })
117
+ tl.to(boxRef.value, { x: 200, duration: 1, ease: 'power2.inOut' })
118
+ .to(boxRef.value, { rotation: 360, duration: 0.8 })
119
+ })
120
+ </script>
121
+ ```
122
+
123
+ ## Available composables
124
+
125
+ | Composable | Plugin | `nuxt.config.ts` key |
126
+ |---|---|---|
127
+ | `useGsap()` | GSAP core | — (always available) |
128
+ | `useScrollTrigger()` | ScrollTrigger | `ScrollTrigger` |
129
+ | `useScrollSmoother()` | ScrollSmoother | `ScrollSmoother` |
130
+ | `useSplitText()` | SplitText | `SplitText` |
131
+ | `useMotionPathHelper()` | MotionPathHelper | `MotionPathHelper` |
132
+ | `useDraggable()` | Draggable | `Draggable` |
133
+ | `useFlip()` | Flip | `Flip` |
134
+ | `useObserver()` | Observer | `Observer` |
135
+ | `useGSDevTools()` | GSDevTools | `GSDevTools` |
136
+ | `useCustomEase()` | CustomEase | `CustomEase` |
137
+ | `useCustomWiggle()` | CustomWiggle | `CustomWiggle` |
138
+ | `useCustomBounce()` | CustomBounce | `CustomBounce` |
139
+
140
+ ## Plugin loading
141
+
142
+ Only plugins listed in `nuxt.config.ts` are dynamically imported —
143
+ zero bundle overhead for unused plugins.
144
+
145
+ ```ts
146
+ // nuxt.config.ts
147
+ export default defineNuxtConfig({
148
+ gsap: {
149
+ plugins: ['ScrollTrigger', 'Draggable'],
150
+ // only these two will be bundled
151
+ },
152
+ })
153
+ ```
154
+
155
+ ## Cleanup
156
+
157
+ GSAP animations are not automatically cleaned up when a component unmounts.
158
+ Use `onUnmounted` to prevent memory leaks.
159
+
160
+ Plugin registration is handled once by the module at app startup — never call `gsap.registerPlugin()` manually.
161
+ In components, clean up only the instances your component created (tweens, timelines, ScrollTrigger instances, Draggable instances, etc.).
162
+
163
+ **Simple plugin instance cleanup (`Draggable`):**
164
+
165
+ ```ts
166
+ <script setup lang="ts">
167
+ const Draggable = useDraggable()
168
+ const boxRef = ref<HTMLElement | null>(null)
169
+ let draggables: ReturnType<typeof Draggable.create> = []
170
+
171
+ onMounted(() => {
172
+ if (!boxRef.value) return
173
+ draggables = Draggable.create(boxRef.value)
174
+ })
175
+
176
+ onUnmounted(() => {
177
+ draggables.forEach((instance) => instance.kill())
178
+ draggables = []
179
+ })
180
+ </script>
181
+ ```
182
+
183
+ See real cleanup examples in `playground/pages/draggable.vue`, `playground/pages/scroll-trigger.vue`, `playground/pages/split-text.vue`, and `playground/pages/scroll-smoother.vue`.
184
+
185
+ **Recommended — `gsap.context()` (covers all child tweens, timelines and ScrollTriggers):**
186
+
187
+ ```ts
188
+ <script setup lang="ts">
189
+ const gsap = useGsap()
190
+ let ctx: gsap.Context
191
+
192
+ onMounted(() => {
193
+ ctx = gsap.context(() => {
194
+ gsap.to('.box', { x: 100 })
195
+ })
196
+ })
197
+
198
+ onUnmounted(() => ctx.revert())
199
+ </script>
200
+ ```
201
+
202
+ **Single timeline:**
203
+
204
+ ```ts
205
+ const gsap = useGsap()
206
+ const tl = gsap.timeline()
207
+ onUnmounted(() => tl.kill())
208
+ ```
209
+
210
+ → [gsap.context() docs](https://gsap.com/docs/v3/GSAP/gsap.context())
211
+
103
212
  ## Contribution
104
213
 
105
214
  <details>
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=3.0.0"
6
6
  },
7
- "version": "1.1.5",
7
+ "version": "1.1.8",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -1,4 +1,3 @@
1
- import { fileURLToPath } from 'node:url';
2
1
  import { defineNuxtModule, createResolver, addPlugin, addImportsDir } from '@nuxt/kit';
3
2
 
4
3
  const module$1 = defineNuxtModule({
@@ -13,14 +12,13 @@ const module$1 = defineNuxtModule({
13
12
  plugins: []
14
13
  },
15
14
  setup(_options, _nuxt) {
16
- const resolver = createResolver(import.meta.url);
17
- const runtimeDir = fileURLToPath(new URL("./runtime", import.meta.url));
15
+ const { resolve } = createResolver(import.meta.url);
18
16
  _nuxt.options.runtimeConfig.public.gsap = {
19
17
  plugins: _options.plugins ?? []
20
18
  };
21
- addPlugin(resolver.resolve("./runtime/plugin"));
22
- addImportsDir(resolver.resolve(runtimeDir, "composables"));
23
- addImportsDir(resolver.resolve(runtimeDir, "utils"));
19
+ addPlugin({ src: resolve("./runtime/plugin"), mode: "client" });
20
+ addImportsDir(resolve("./runtime/composables"));
21
+ addImportsDir(resolve("./runtime/utils"));
24
22
  }
25
23
  });
26
24
 
@@ -1,3 +1,37 @@
1
+ import { gsap } from 'gsap';
2
+ import type { ComputedRef, Ref, WatchSource } from 'vue';
3
+ type ContextSafeFn = <F extends (...args: unknown[]) => unknown>(fn: F) => F;
4
+ export interface UseGsapOptions {
5
+ scope?: Ref<HTMLElement | null> | ComputedRef<HTMLElement | null>;
6
+ dependencies?: WatchSource | WatchSource[];
7
+ revertOnUpdate?: boolean;
8
+ }
9
+ /**
10
+ * Zero-argument overload — returns the raw GSAP instance.
11
+ *
12
+ * Use it to call `gsap.timeline()`, `gsap.to()`, `gsap.set()`,
13
+ * utility methods (`gsap.utils`, `gsap.ticker`), and more.
14
+ *
15
+ * **Cleanup is the caller's responsibility.**
16
+ *
17
+ * @see https://gsap.com/docs/v3/GSAP/
18
+ */
19
+ export declare function useGsap(): typeof gsap;
20
+ /**
21
+ * Setup-function overload — wraps `gsap.context()` with automatic revert.
22
+ *
23
+ * Animations declared inside `setup` are scoped to the optional `scope` element
24
+ * and are reverted automatically when the component unmounts (or the effect scope
25
+ * is disposed). Pass `dependencies` to re-run `setup` reactively.
26
+ *
27
+ * Returns `{ contextSafe }` — a wrapper for event handlers that need to add
28
+ * animations to the existing context after mount.
29
+ *
30
+ * @see https://gsap.com/docs/v3/GSAP/gsap.context()
31
+ */
32
+ export declare function useGsap(setup: (ctx: gsap.Context) => void, options?: UseGsapOptions): {
33
+ contextSafe: ContextSafeFn;
34
+ };
1
35
  export declare const useScrollTrigger: () => {
2
36
  new (vars: ScrollTrigger.StaticVars, animation?: gsap.core.Animation): {
3
37
  readonly animation?: gsap.core.Animation | undefined;
@@ -51,14 +85,14 @@ export declare const useScrollTrigger: () => {
51
85
  observe(vars: Observer.ObserverVars): Observer;
52
86
  positionInViewport(element: Element | string, referencePoint?: string | number, horizontal?: boolean): number;
53
87
  refresh(safe?: boolean): void;
54
- register(core: typeof gsap): void;
88
+ register(core: typeof globalThis.gsap): void;
55
89
  removeEventListener(event: "scrollStart" | "scrollEnd" | "refreshInit" | "refresh" | "matchMedia" | "revert", callback: gsap.Callback): void;
56
90
  saveStyles(targets: gsap.DOMTarget): void;
57
91
  scrollerProxy(scroller: gsap.DOMTarget, vars?: ScrollTrigger.ScrollerProxyVars): void;
58
92
  snapDirectional(incrementOrArray: number | number[]): ScrollTrigger.SnapDirectionalFunc;
59
93
  sort(func?: Function): ScrollTrigger[];
60
94
  update(): void;
61
- };
95
+ } | null;
62
96
  export declare const useScrollSmoother: () => {
63
97
  new (vars: ScrollSmoother.Vars): {
64
98
  readonly scrollTrigger: ScrollTrigger;
@@ -86,7 +120,7 @@ export declare const useScrollSmoother: () => {
86
120
  create(vars: ScrollSmoother.Vars): ScrollSmoother;
87
121
  get(): ScrollSmoother | undefined;
88
122
  refresh(safe?: boolean): void;
89
- };
123
+ } | null;
90
124
  export declare const useSplitText: () => {
91
125
  new (target: gsap.DOMTarget, vars?: SplitText.Vars): {
92
126
  readonly chars: Element[];
@@ -100,14 +134,14 @@ export declare const useSplitText: () => {
100
134
  split(vars: SplitText.Vars): SplitText;
101
135
  };
102
136
  create(target: gsap.DOMTarget, vars?: SplitText.Vars): SplitText;
103
- };
137
+ } | null;
104
138
  export declare const useMotionPathHelper: () => {
105
139
  new (target: gsap.DOMTarget, vars?: MotionPathHelper.Vars): {
106
140
  kill(): void;
107
141
  };
108
142
  create(target: gsap.DOMTarget, vars?: MotionPathHelper.Vars): MotionPathHelper;
109
143
  editPath(target: gsap.DOMTarget, vars?: MotionPathHelper.EditPathVars): MotionPathHelper;
110
- };
144
+ } | null;
111
145
  export declare const useDraggable: () => {
112
146
  new (target: gsap.DOMTarget, vars?: Draggable.Vars): {
113
147
  readonly autoScroll: number;
@@ -160,7 +194,7 @@ export declare const useDraggable: () => {
160
194
  get(target: gsap.DOMTarget): Draggable;
161
195
  hitTest(testObject1: Draggable.TestObject, testObject2: Draggable.TestObject, threshold?: number | string): boolean;
162
196
  timeSinceDrag(): number;
163
- };
197
+ } | null;
164
198
  export declare const useFlip: () => {
165
199
  new (): {};
166
200
  readonly version: string;
@@ -175,10 +209,10 @@ export declare const useFlip: () => {
175
209
  killFlipsOf(targets: gsap.DOMTarget, complete?: boolean): void;
176
210
  makeAbsolute(targets: gsap.DOMTarget | Flip.FlipState[]): Element[];
177
211
  to(state: Flip.FlipState, vars?: Flip.FromToVars): gsap.core.Timeline;
178
- register(core: typeof gsap): void;
212
+ register(core: typeof globalThis.gsap): void;
179
213
  ElementState: typeof Flip.ElementState;
180
214
  FlipState: typeof Flip.FlipState;
181
- };
215
+ } | null;
182
216
  export declare const useObserver: () => {
183
217
  new (): {
184
218
  readonly deltaX: number;
@@ -210,14 +244,14 @@ export declare const useObserver: () => {
210
244
  create(vars: Observer.ObserverVars): Observer;
211
245
  getAll(): Observer[];
212
246
  getById(id: string): Observer | undefined;
213
- };
247
+ } | null;
214
248
  export declare const useGSDevTools: () => {
215
249
  new (target: gsap.DOMTarget, vars?: GSDevTools.Vars): {
216
250
  kill(): void;
217
251
  };
218
252
  create(vars?: GSDevTools.Vars): GSDevTools;
219
253
  getById(id: string): GSDevTools | null;
220
- };
254
+ } | null;
221
255
  export declare const useCustomEase: () => {
222
256
  new (id: string, data?: string | number[], config?: CustomEaseConfig): {
223
257
  id: string;
@@ -231,18 +265,19 @@ export declare const useCustomEase: () => {
231
265
  register(core: object): void;
232
266
  get(id: string): EaseFunction;
233
267
  getSVGData(ease: CustomEase | EaseFunction | string, config?: CustomEaseConfig): string;
234
- };
268
+ } | null;
235
269
  export declare const useCustomWiggle: () => {
236
270
  new (id: string, vars?: CustomWiggleVars): {
237
271
  ease: EaseFunction;
238
272
  };
239
273
  create(id: string, vars?: CustomWiggleVars): EaseFunction;
240
274
  register(core: object): void;
241
- };
275
+ } | null;
242
276
  export declare const useCustomBounce: () => {
243
277
  new (id: string, vars?: CustomBounceVars): {
244
278
  ease: EaseFunction;
245
279
  };
246
280
  create(id: string, vars?: CustomBounceVars): EaseFunction;
247
281
  register(core: object): void;
248
- };
282
+ } | null;
283
+ export {};
@@ -1,4 +1,41 @@
1
+ import { gsap } from "gsap";
2
+ import { onMounted, onScopeDispose, watch } from "vue";
1
3
  import { createGsapComposable } from "../create-gsap-composable.js";
4
+ export function useGsap(setup, options) {
5
+ if (!setup) return gsap;
6
+ if (import.meta.server) {
7
+ return { contextSafe: (fn) => fn };
8
+ }
9
+ let ctx = null;
10
+ const runSetup = () => {
11
+ const scope = options?.scope?.value ?? void 0;
12
+ ctx = gsap.context(setup, scope);
13
+ };
14
+ onMounted(() => {
15
+ runSetup();
16
+ });
17
+ if (options?.dependencies !== void 0) {
18
+ const deps = Array.isArray(options.dependencies) ? options.dependencies : [options.dependencies];
19
+ watch(deps, () => {
20
+ if (options.revertOnUpdate === false) return;
21
+ ctx?.revert();
22
+ runSetup();
23
+ }, { flush: "post" });
24
+ }
25
+ onScopeDispose(() => {
26
+ ctx?.revert();
27
+ ctx = null;
28
+ });
29
+ const contextSafe = (fn) => {
30
+ return ((...args) => {
31
+ if (ctx) {
32
+ return ctx.add(() => fn(...args));
33
+ }
34
+ return fn(...args);
35
+ });
36
+ };
37
+ return { contextSafe };
38
+ }
2
39
  export const useScrollTrigger = createGsapComposable("ScrollTrigger");
3
40
  export const useScrollSmoother = createGsapComposable("ScrollSmoother");
4
41
  export const useSplitText = createGsapComposable("SplitText");
@@ -1,6 +1,15 @@
1
1
  /**
2
- * Factory to create GSAP plugin composables.
3
- * @param pluginName - Name of the GSAP plugin as provided in nuxtApp injects.
4
- * @param fallbackMessage - Optional error message for missing plugin.
2
+ * Factory that creates a composable returning a registered GSAP plugin.
3
+ *
4
+ * The returned composable reads the plugin from `nuxtApp` at call time.
5
+ * Returns `null` during SSR (plugin is client-only).
6
+ * Throws on the client if the plugin was not enabled in `nuxt.config.ts`.
7
+ *
8
+ * **Cleanup is the caller's responsibility.**
9
+ * Destroy instances created from the plugin (e.g. `Draggable`, `ScrollTrigger`)
10
+ * in `onUnmounted` to avoid memory leaks.
11
+ *
12
+ * @param pluginName - Name of the GSAP plugin as registered in nuxtApp.
13
+ * @param fallbackMessage - Optional custom error message for missing plugin.
5
14
  */
6
- export declare function createGsapComposable<T>(pluginName: string, fallbackMessage?: string): () => T;
15
+ export declare function createGsapComposable<T>(pluginName: string, fallbackMessage?: string): () => T | null;
@@ -1,6 +1,7 @@
1
1
  import { useNuxtApp } from "#app";
2
2
  export function createGsapComposable(pluginName, fallbackMessage) {
3
3
  return () => {
4
+ if (import.meta.server) return null;
4
5
  const nuxtApp = useNuxtApp();
5
6
  const plugin = nuxtApp[`$${pluginName}`];
6
7
  if (!plugin) {
@@ -0,0 +1,3 @@
1
+ export function loadFlip(): Promise<typeof import("gsap/Flip")>;
2
+ export function loadDraggable(): Promise<typeof import("gsap/Draggable")>;
3
+ export function loadObserver(): Promise<typeof import("gsap/Observer")>;
@@ -0,0 +1,7 @@
1
+ // @ts-nocheck
2
+
3
+ export const loadFlip = () => import('gsap/Flip')
4
+
5
+ export const loadDraggable = () => import('gsap/Draggable')
6
+
7
+ export const loadObserver = () => import('gsap/Observer')
@@ -1,7 +1,3 @@
1
- /**
2
- * This object contains lazy-loaded GSAP plugins for use in the application.
3
- *
4
- */
5
1
  export declare const gsapPlugins: {
6
2
  ScrollTrigger: () => Promise<{
7
3
  new (vars: ScrollTrigger.StaticVars, animation?: gsap.core.Animation): {
@@ -1,3 +1,4 @@
1
+ import { loadDraggable, loadFlip, loadObserver } from "./gsap-loaders.js";
1
2
  export const gsapPlugins = {
2
3
  // Scroll Plugins
3
4
  ScrollTrigger: () => import("gsap/ScrollTrigger").then((mod) => mod.ScrollTrigger),
@@ -13,10 +14,10 @@ export const gsapPlugins = {
13
14
  MotionPathPlugin: () => import("gsap/MotionPathPlugin").then((mod) => mod.MotionPathPlugin),
14
15
  MotionPathHelper: () => import("gsap/MotionPathHelper").then((mod) => mod.MotionPathHelper),
15
16
  // UI Plugins
16
- Flip: () => import("gsap/Flip").then((mod) => mod.Flip),
17
- Draggable: () => import("gsap/Draggable").then((mod) => mod.Draggable),
17
+ Flip: () => loadFlip().then((mod) => mod.Flip),
18
+ Draggable: () => loadDraggable().then((mod) => mod.Draggable),
18
19
  InertiaPlugin: () => import("gsap/InertiaPlugin").then((mod) => mod.InertiaPlugin),
19
- Observer: () => import("gsap/Observer").then((mod) => mod.Observer),
20
+ Observer: () => loadObserver().then((mod) => mod.Observer),
20
21
  // Other Plugins
21
22
  PixiPlugin: () => import("gsap/PixiPlugin").then((mod) => mod.PixiPlugin),
22
23
  EaselPlugin: () => import("gsap/EaselPlugin").then((mod) => mod.EaselPlugin),
@@ -1,37 +1,41 @@
1
1
  import { gsap } from "gsap";
2
2
  import { gsapPlugins } from "./gsap-plugins.js";
3
3
  import { defineNuxtPlugin, useRuntimeConfig } from "#app";
4
- export default defineNuxtPlugin(async (nuxtApp) => {
5
- const config = useRuntimeConfig().public.gsap;
6
- const pluginsToRegister = new Set(config.plugins || []);
7
- const pluginDependencies = {
8
- ScrollSmoother: ["ScrollTrigger"],
9
- CustomWiggle: ["CustomEase"],
10
- CustomBounce: ["CustomEase"]
11
- };
12
- const resolvedPlugins = /* @__PURE__ */ new Set();
13
- const resolvePlugin = (plugin) => {
14
- if (resolvedPlugins.has(plugin)) return;
15
- const deps = pluginDependencies[plugin] || [];
16
- deps.forEach(resolvePlugin);
17
- resolvedPlugins.add(plugin);
18
- };
19
- for (const plugin of pluginsToRegister) {
20
- resolvePlugin(plugin);
21
- }
22
- for (const pluginName of resolvedPlugins) {
23
- const loader = gsapPlugins[pluginName];
24
- if (!loader) {
25
- throw new Error(
26
- `[gsap-nuxt-module] Plugin "${pluginName}" not found. Available plugins: ${Object.keys(gsapPlugins).join(", ")}`
27
- );
4
+ export default defineNuxtPlugin({
5
+ name: "gsap-nuxt-module",
6
+ enforce: "post",
7
+ setup: async (nuxtApp) => {
8
+ const config = useRuntimeConfig().public.gsap;
9
+ const pluginsToRegister = new Set(config.plugins || []);
10
+ const pluginDependencies = {
11
+ ScrollSmoother: ["ScrollTrigger"],
12
+ CustomWiggle: ["CustomEase"],
13
+ CustomBounce: ["CustomEase"]
14
+ };
15
+ const resolvedPlugins = /* @__PURE__ */ new Set();
16
+ const resolvePlugin = (plugin) => {
17
+ if (resolvedPlugins.has(plugin)) return;
18
+ const deps = pluginDependencies[plugin] || [];
19
+ deps.forEach(resolvePlugin);
20
+ resolvedPlugins.add(plugin);
21
+ };
22
+ for (const plugin of pluginsToRegister) {
23
+ resolvePlugin(plugin);
28
24
  }
29
- try {
30
- const plugin = await loader();
31
- gsap.registerPlugin(plugin);
32
- nuxtApp.provide(pluginName, plugin);
33
- } catch (err) {
34
- console.error(`[gsap-nuxt-module] Failed to load plugin "${pluginName}":`, err);
25
+ for (const pluginName of resolvedPlugins) {
26
+ const loader = gsapPlugins[pluginName];
27
+ if (!loader) {
28
+ throw new Error(
29
+ `[gsap-nuxt-module] Plugin "${pluginName}" not found. Available plugins: ${Object.keys(gsapPlugins).join(", ")}`
30
+ );
31
+ }
32
+ try {
33
+ const plugin = await loader();
34
+ gsap.registerPlugin(plugin);
35
+ nuxtApp.provide(pluginName, plugin);
36
+ } catch (err) {
37
+ console.error(`[gsap-nuxt-module] Failed to load plugin "${pluginName}":`, err);
38
+ }
35
39
  }
36
40
  }
37
41
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsap-nuxt-module",
3
- "version": "1.1.5",
3
+ "version": "1.1.8",
4
4
  "description": "GSAP integration for Nuxt.",
5
5
  "repository": "LucaArgentieri/gsap-nuxt-module",
6
6
  "author": "Luca Argentieri",
@@ -29,26 +29,27 @@
29
29
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
30
30
  "release": "npm run lint && npm run prepack && changelogen --release --patch && npm publish && git push --follow-tags",
31
31
  "lint": "eslint .",
32
+ "lint:fix": "eslint . --fix",
32
33
  "test": "vitest run",
33
34
  "test:watch": "vitest watch",
34
- "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
35
+ "test:types": "vue-tsc --noEmit && nuxi prepare playground && cd playground && vue-tsc --noEmit"
35
36
  },
36
37
  "dependencies": {
37
- "@nuxt/kit": "^3.15.4",
38
+ "@nuxt/kit": "^4.0.0",
38
39
  "gsap": "^3.14.2"
39
40
  },
40
41
  "devDependencies": {
41
- "@nuxt/devtools": "^2.1.0",
42
+ "@nuxt/devtools": "^3.0.0",
42
43
  "@nuxt/eslint-config": "^1.1.0",
43
44
  "@nuxt/module-builder": "^1.0.1",
44
- "@nuxt/schema": "^3.15.4",
45
- "@nuxt/test-utils": "^3.17.0",
45
+ "@nuxt/schema": "^4.0.0",
46
+ "@nuxt/test-utils": "^4.0.0",
46
47
  "@types/node": "latest",
47
48
  "changelogen": "^0.6.0",
48
- "eslint": "^9.21.0",
49
- "nuxt": "^3.15.4",
49
+ "eslint": "^10.0.0",
50
+ "nuxt": "^4.0.0",
50
51
  "typescript": "^5.9.3",
51
- "vitest": "^3.0.7",
52
- "vue-tsc": "^2.2.4"
52
+ "vitest": "^4.0.0",
53
+ "vue-tsc": "^3.0.0"
53
54
  }
54
55
  }