@floatingpixels/supabase-nuxt 0.1.1

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 ADDED
@@ -0,0 +1,94 @@
1
+ <!--
2
+ Get your module up and running quickly.
3
+
4
+ Find and replace all on all files (CMD+SHIFT+F):
5
+ - Name: My Module
6
+ - Package name: my-module
7
+ - Description: My new Nuxt module
8
+ -->
9
+
10
+ # My Module
11
+
12
+ [![npm version][npm-version-src]][npm-version-href]
13
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
14
+ [![License][license-src]][license-href]
15
+ [![Nuxt][nuxt-src]][nuxt-href]
16
+
17
+ My new Nuxt module for doing amazing things.
18
+
19
+ - [✨ &nbsp;Release Notes](/CHANGELOG.md)
20
+ <!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
21
+ <!-- - [📖 &nbsp;Documentation](https://example.com) -->
22
+
23
+ ## Features
24
+
25
+ <!-- Highlight some of the features your module provide here -->
26
+ - ⛰ &nbsp;Foo
27
+ - 🚠 &nbsp;Bar
28
+ - 🌲 &nbsp;Baz
29
+
30
+ ## Quick Setup
31
+
32
+ 1. Add `my-module` dependency to your project
33
+
34
+ ```bash
35
+ # Using pnpm
36
+ pnpm add -D my-module
37
+
38
+ # Using yarn
39
+ yarn add --dev my-module
40
+
41
+ # Using npm
42
+ npm install --save-dev my-module
43
+ ```
44
+
45
+ 2. Add `my-module` to the `modules` section of `nuxt.config.ts`
46
+
47
+ ```js
48
+ export default defineNuxtConfig({
49
+ modules: [
50
+ 'my-module'
51
+ ]
52
+ })
53
+ ```
54
+
55
+ That's it! You can now use My Module in your Nuxt app ✨
56
+
57
+ ## Development
58
+
59
+ ```bash
60
+ # Install dependencies
61
+ npm install
62
+
63
+ # Generate type stubs
64
+ npm run dev:prepare
65
+
66
+ # Develop with the playground
67
+ npm run dev
68
+
69
+ # Build the playground
70
+ npm run dev:build
71
+
72
+ # Run ESLint
73
+ npm run lint
74
+
75
+ # Run Vitest
76
+ npm run test
77
+ npm run test:watch
78
+
79
+ # Release new version
80
+ npm run release
81
+ ```
82
+
83
+ <!-- Badges -->
84
+ [npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
85
+ [npm-version-href]: https://npmjs.com/package/my-module
86
+
87
+ [npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=18181B&colorB=28CF8D
88
+ [npm-downloads-href]: https://npmjs.com/package/my-module
89
+
90
+ [license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=18181B&colorB=28CF8D
91
+ [license-href]: https://npmjs.com/package/my-module
92
+
93
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-18181B?logo=nuxt.js
94
+ [nuxt-href]: https://nuxt.com
@@ -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,68 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ /**
5
+ * Supabase API URL
6
+ * @default process.env.SUPABASE_URL
7
+ * @example 'https://*.supabase.co'
8
+ * @type string
9
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
10
+ */
11
+ url: string
12
+
13
+ /**
14
+ * Supabase Client API Key
15
+ * @default process.env.SUPABASE_KEY
16
+ * @example '123456789'
17
+ * @type string
18
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
19
+ */
20
+ key: string
21
+
22
+ /**
23
+ * Supabase Service key
24
+ * @default process.env.SUPABASE_SERVICE_KEY
25
+ * @example '123456789'
26
+ * @type string
27
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
28
+ */
29
+ serviceKey?: string
30
+
31
+ /**
32
+ * Redirect automatically to login page if user is not authenticated
33
+ * @default `false`
34
+ * @type boolean
35
+ */
36
+ redirect?: boolean
37
+
38
+ /**
39
+ * Redirection options, set routes for login and callback redirect
40
+ * @default
41
+ * {
42
+ login: '/login',
43
+ callback: '/confirm',
44
+ exclude: [],
45
+ }
46
+ * @type RedirectOptions
47
+ */
48
+ redirectOptions?: RedirectOptions
49
+ }
50
+
51
+ interface RedirectOptions {
52
+ /**
53
+ * Login route
54
+ * @default '/login'
55
+ * @type string
56
+ */
57
+ login?: string
58
+ /**
59
+ * Callback route
60
+ * @default []
61
+ * @type string[]
62
+ */
63
+ exclude?: string[]
64
+ }
65
+
66
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
67
+
68
+ export { _default as default };
@@ -0,0 +1,68 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ /**
5
+ * Supabase API URL
6
+ * @default process.env.SUPABASE_URL
7
+ * @example 'https://*.supabase.co'
8
+ * @type string
9
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
10
+ */
11
+ url: string
12
+
13
+ /**
14
+ * Supabase Client API Key
15
+ * @default process.env.SUPABASE_KEY
16
+ * @example '123456789'
17
+ * @type string
18
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
19
+ */
20
+ key: string
21
+
22
+ /**
23
+ * Supabase Service key
24
+ * @default process.env.SUPABASE_SERVICE_KEY
25
+ * @example '123456789'
26
+ * @type string
27
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
28
+ */
29
+ serviceKey?: string
30
+
31
+ /**
32
+ * Redirect automatically to login page if user is not authenticated
33
+ * @default `false`
34
+ * @type boolean
35
+ */
36
+ redirect?: boolean
37
+
38
+ /**
39
+ * Redirection options, set routes for login and callback redirect
40
+ * @default
41
+ * {
42
+ login: '/login',
43
+ callback: '/confirm',
44
+ exclude: [],
45
+ }
46
+ * @type RedirectOptions
47
+ */
48
+ redirectOptions?: RedirectOptions
49
+ }
50
+
51
+ interface RedirectOptions {
52
+ /**
53
+ * Login route
54
+ * @default '/login'
55
+ * @type string
56
+ */
57
+ login?: string
58
+ /**
59
+ * Callback route
60
+ * @default []
61
+ * @type string[]
62
+ */
63
+ exclude?: string[]
64
+ }
65
+
66
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
67
+
68
+ export { _default as default };
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "supabase-nuxt",
3
+ "configKey": "supabase",
4
+ "compatibility": {
5
+ "nuxt": ">3.0.0"
6
+ },
7
+ "version": "0.1.1"
8
+ }
@@ -0,0 +1,73 @@
1
+ import { defineNuxtModule, createResolver, addPlugin, addServerHandler, addTemplate } from '@nuxt/kit';
2
+ import { defu } from 'defu';
3
+
4
+ const module = defineNuxtModule({
5
+ meta: {
6
+ name: "supabase-nuxt",
7
+ configKey: "supabase",
8
+ compatibility: {
9
+ nuxt: ">3.0.0"
10
+ }
11
+ },
12
+ // Default configuration options of the Nuxt module
13
+ defaults: {
14
+ url: process.env.SUPABASE_URL,
15
+ key: process.env.SUPABASE_KEY,
16
+ serviceKey: process.env.SUPABASE_SERVICE_KEY,
17
+ redirect: false,
18
+ redirectOptions: {
19
+ login: "/login",
20
+ exclude: []
21
+ }
22
+ },
23
+ setup(options, nuxt) {
24
+ const { resolve } = createResolver(import.meta.url);
25
+ console.log("Module setup function");
26
+ if (!options.url) {
27
+ console.warn("Missing `SUPABASE_URL` in `.env`");
28
+ }
29
+ if (!options.key) {
30
+ console.warn("Missing `SUPABASE_KEY` in `.env`");
31
+ }
32
+ nuxt.options.runtimeConfig.public.supabase = defu(nuxt.options.runtimeConfig.public.supabase, {
33
+ url: options.url,
34
+ key: options.key,
35
+ redirect: options.redirect,
36
+ redirectOptions: options.redirectOptions
37
+ });
38
+ nuxt.options.runtimeConfig.supabase = defu(nuxt.options.runtimeConfig.supabase, {
39
+ serviceKey: options.serviceKey
40
+ });
41
+ addPlugin(resolve("./runtime/plugins/supabase.server"));
42
+ addPlugin(resolve("./runtime/plugins/supabase.client"));
43
+ nuxt.hook("imports:dirs", (dirs) => {
44
+ dirs.push(resolve("./runtime/composables"));
45
+ });
46
+ addServerHandler({
47
+ route: "/supabase/confirm",
48
+ handler: resolve("./runtime/server/api/confirm.ts")
49
+ });
50
+ if (options.redirect) {
51
+ addPlugin(resolve("./runtime/plugins/auth-redirect"));
52
+ }
53
+ nuxt.hook("nitro:config", (nitroConfig) => {
54
+ nitroConfig.alias = nitroConfig.alias || {};
55
+ nitroConfig.alias["#supabase/server"] = resolve("./runtime/server/services");
56
+ nitroConfig.externals = defu(typeof nitroConfig.externals === "object" ? nitroConfig.externals : {}, {
57
+ inline: [resolve("./runtime")]
58
+ });
59
+ });
60
+ addTemplate({
61
+ filename: "types/supabase.d.ts",
62
+ getContents: () => [
63
+ "declare module '#supabase/server' {",
64
+ ` const supabaseServerClient: typeof import('${resolve("./runtime/server/services")}').supabaseServerClient`,
65
+ ` const supabaseServiceRole: typeof import('${resolve("./runtime/server/services")}').supabaseServiceRole`,
66
+ // ` const serverSupabaseUser: typeof import('${resolve('./runtime/server/services')}').serverSupabaseUser`,
67
+ "}"
68
+ ].join("\n")
69
+ });
70
+ }
71
+ });
72
+
73
+ export { module as default };
@@ -0,0 +1,2 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ export declare const useSupabaseClient: <T>() => SupabaseClient<T, "public" extends keyof T ? keyof T & "public" : string & keyof T, T["public" extends keyof T ? keyof T & "public" : string & keyof T] extends import("@supabase/supabase-js/dist/module/lib/types").GenericSchema ? T["public" extends keyof T ? keyof T & "public" : string & keyof T] : any>;
@@ -0,0 +1,4 @@
1
+ import { useNuxtApp } from "#imports";
2
+ export const useSupabaseClient = () => {
3
+ return useNuxtApp().$supabase?.client;
4
+ };
@@ -0,0 +1 @@
1
+ export declare const useSupabaseUser: () => Promise<import("@supabase/supabase-js").AuthUser | null>;
@@ -0,0 +1,11 @@
1
+ import { useSupabaseClient } from "./useSupabaseClient.mjs";
2
+ export const useSupabaseUser = async () => {
3
+ const supabase = useSupabaseClient();
4
+ const {
5
+ data: { session }
6
+ } = await supabase.auth.getSession();
7
+ if (!session?.user) {
8
+ return null;
9
+ }
10
+ return session.user;
11
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,35 @@
1
+ import { useSupabaseUser } from "../composables/useSupabaseUser.mjs";
2
+ import {
3
+ defineNuxtPlugin,
4
+ addRouteMiddleware,
5
+ defineNuxtRouteMiddleware,
6
+ useRuntimeConfig,
7
+ navigateTo,
8
+ abortNavigation
9
+ } from "#imports";
10
+ export default defineNuxtPlugin({
11
+ name: "auth-redirect",
12
+ setup() {
13
+ addRouteMiddleware(
14
+ "global-auth",
15
+ defineNuxtRouteMiddleware(async (to) => {
16
+ if (to.path === "/supabase/confirm")
17
+ abortNavigation();
18
+ const config = useRuntimeConfig().public.supabase;
19
+ const { login, exclude } = config.redirectOptions;
20
+ const isExcluded = [...exclude, login, "/supabase/confirm"]?.some((path) => {
21
+ const regex = new RegExp(`^${path.replace(/\*/g, ".*")}$`);
22
+ return regex.test(to.path);
23
+ });
24
+ if (isExcluded)
25
+ return;
26
+ const user = await useSupabaseUser();
27
+ if (!user) {
28
+ if (to.path !== "/login")
29
+ return navigateTo("/login");
30
+ }
31
+ }),
32
+ { global: true }
33
+ );
34
+ }
35
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,21 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
2
+ import { createBrowserClient } from "@supabase/ssr";
3
+ export default defineNuxtPlugin({
4
+ name: "supabase",
5
+ enforce: "pre",
6
+ async setup() {
7
+ const config = useRuntimeConfig().public.supabase;
8
+ const { url, key } = config;
9
+ const supabaseBrowserClient = createBrowserClient(url, key);
10
+ return {
11
+ provide: {
12
+ supabase: {
13
+ client: supabaseBrowserClient
14
+ }
15
+ }
16
+ };
17
+ },
18
+ env: {
19
+ islands: false
20
+ }
21
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,28 @@
1
+ import { defineNuxtPlugin, useRuntimeConfig, useRequestEvent } from "#imports";
2
+ import { createServerClient } from "@supabase/ssr";
3
+ import { getCookie } from "h3";
4
+ export default defineNuxtPlugin({
5
+ name: "supabase",
6
+ enforce: "pre",
7
+ async setup() {
8
+ const { url, key } = useRuntimeConfig().public.supabase;
9
+ const event = useRequestEvent();
10
+ const supabaseServerClient = createServerClient(url, key, {
11
+ cookies: {
12
+ get(name) {
13
+ return getCookie(event, name);
14
+ }
15
+ }
16
+ });
17
+ return {
18
+ provide: {
19
+ supabase: {
20
+ client: supabaseServerClient
21
+ }
22
+ }
23
+ };
24
+ },
25
+ env: {
26
+ islands: true
27
+ }
28
+ });
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,18 @@
1
+ import { defineEventHandler } from "#imports";
2
+ import { createError, getQuery, sendRedirect } from "h3";
3
+ import { supabaseServerClient } from "#supabase/server";
4
+ export default defineEventHandler(async (event) => {
5
+ const query = getQuery(event);
6
+ const token_hash = query.token_hash;
7
+ const type = query.type;
8
+ const next = query.next ?? "/";
9
+ if (!token_hash || !type) {
10
+ throw createError({ statusMessage: "Invalid token" });
11
+ }
12
+ const supabase = await supabaseServerClient(event);
13
+ const { error } = await supabase.auth.verifyOtp({ type, token_hash });
14
+ if (error) {
15
+ throw createError({ statusMessage: error.message });
16
+ }
17
+ await sendRedirect(event, next, 302);
18
+ });
@@ -0,0 +1,2 @@
1
+ export { supabaseServerClient } from './supabaseServerClient';
2
+ export { supabaseServiceRole } from './supabaseServiceRole';
@@ -0,0 +1,2 @@
1
+ export { supabaseServerClient } from "./supabaseServerClient.mjs";
2
+ export { supabaseServiceRole } from "./supabaseServiceRole.mjs";
@@ -0,0 +1,3 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ import type { H3Event } from 'h3';
3
+ export declare const supabaseServerClient: <T>(event: H3Event) => Promise<SupabaseClient<T, "public" extends keyof T ? keyof T & "public" : string & keyof T, T["public" extends keyof T ? keyof T & "public" : string & keyof T] extends import("@supabase/supabase-js/dist/module/lib/types").GenericSchema ? T["public" extends keyof T ? keyof T & "public" : string & keyof T] : any>>;
@@ -0,0 +1,26 @@
1
+ import { createServerClient } from "@supabase/ssr";
2
+ import { getCookie, setCookie } from "h3";
3
+ import { useRuntimeConfig } from "#imports";
4
+ export const supabaseServerClient = async (event) => {
5
+ const {
6
+ supabase: { url, key }
7
+ } = useRuntimeConfig(event).public;
8
+ let supabaseClient = event.context._supabaseClient;
9
+ if (!supabaseClient) {
10
+ supabaseClient = createServerClient(url, key, {
11
+ cookies: {
12
+ get(name) {
13
+ return getCookie(event, name);
14
+ },
15
+ set(name, value) {
16
+ setCookie(event, name, value);
17
+ },
18
+ remove(key2, options) {
19
+ setCookie(event, key2, "", { ...options, expires: 0 });
20
+ }
21
+ }
22
+ });
23
+ event.context._supabaseClient = supabaseClient;
24
+ }
25
+ return supabaseClient;
26
+ };
@@ -0,0 +1,3 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ import type { H3Event } from 'h3';
3
+ export declare const supabaseServiceRole: <T>(event: H3Event) => Promise<SupabaseClient<T, "public" extends keyof T ? keyof T & "public" : string & keyof T, T["public" extends keyof T ? keyof T & "public" : string & keyof T] extends import("@supabase/supabase-js/dist/module/lib/types").GenericSchema ? T["public" extends keyof T ? keyof T & "public" : string & keyof T] : any>>;
@@ -0,0 +1,26 @@
1
+ import { createServerClient } from "@supabase/ssr";
2
+ import { getCookie } from "h3";
3
+ import { useRuntimeConfig } from "#imports";
4
+ export const supabaseServiceRole = async (event) => {
5
+ const {
6
+ supabase: { serviceKey },
7
+ public: {
8
+ supabase: { url }
9
+ }
10
+ } = useRuntimeConfig(event);
11
+ if (!serviceKey) {
12
+ throw new Error("Missing `SUPABASE_SERVICE_KEY` in `.env`");
13
+ }
14
+ let supabaseClient = event.context._supabaseServiceRole;
15
+ if (!supabaseClient) {
16
+ supabaseClient = createServerClient(url, serviceKey, {
17
+ cookies: {
18
+ get(name) {
19
+ return getCookie(event, name);
20
+ }
21
+ }
22
+ });
23
+ event.context._supabaseServiceRole = supabaseClient;
24
+ }
25
+ return supabaseClient;
26
+ };
@@ -0,0 +1,62 @@
1
+ export interface ModuleOptions {
2
+ /**
3
+ * Supabase API URL
4
+ * @default process.env.SUPABASE_URL
5
+ * @example 'https://*.supabase.co'
6
+ * @type string
7
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
8
+ */
9
+ url: string
10
+
11
+ /**
12
+ * Supabase Client API Key
13
+ * @default process.env.SUPABASE_KEY
14
+ * @example '123456789'
15
+ * @type string
16
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
17
+ */
18
+ key: string
19
+
20
+ /**
21
+ * Supabase Service key
22
+ * @default process.env.SUPABASE_SERVICE_KEY
23
+ * @example '123456789'
24
+ * @type string
25
+ * @docs https://supabase.com/docs/reference/javascript/initializing#parameters
26
+ */
27
+ serviceKey?: string
28
+
29
+ /**
30
+ * Redirect automatically to login page if user is not authenticated
31
+ * @default `false`
32
+ * @type boolean
33
+ */
34
+ redirect?: boolean
35
+
36
+ /**
37
+ * Redirection options, set routes for login and callback redirect
38
+ * @default
39
+ * {
40
+ login: '/login',
41
+ callback: '/confirm',
42
+ exclude: [],
43
+ }
44
+ * @type RedirectOptions
45
+ */
46
+ redirectOptions?: RedirectOptions
47
+ }
48
+
49
+ export interface RedirectOptions {
50
+ /**
51
+ * Login route
52
+ * @default '/login'
53
+ * @type string
54
+ */
55
+ login?: string
56
+ /**
57
+ * Callback route
58
+ * @default []
59
+ * @type string[]
60
+ */
61
+ exclude?: string[]
62
+ }
@@ -0,0 +1,8 @@
1
+
2
+ import type { } from './module.js'
3
+
4
+
5
+
6
+
7
+
8
+ export type { default } from './module.js'
@@ -0,0 +1,8 @@
1
+
2
+ import type { } from './module'
3
+
4
+
5
+
6
+
7
+
8
+ export type { default } from './module'
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@floatingpixels/supabase-nuxt",
3
+ "version": "0.1.1",
4
+ "description": "Nuxt module for Supabase",
5
+ "repository": "floatingpixels/supabase-nuxt",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "release-it": {
9
+ "github": {
10
+ "release": true,
11
+ "releaseName": "v${version}",
12
+ "preRelease": false,
13
+ "draft": false,
14
+ "tokenRef": "GITHUB_TOKEN"
15
+ },
16
+ "npm": {
17
+ "publish": true,
18
+ "publishArgs": [
19
+ "--access",
20
+ "public"
21
+ ]
22
+ }
23
+ },
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/types.d.ts",
27
+ "import": "./dist/module.mjs",
28
+ "require": "./dist/module.cjs"
29
+ }
30
+ },
31
+ "main": "./dist/module.cjs",
32
+ "types": "./dist/types.d.ts",
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "scripts": {
37
+ "prepack": "nuxt-module-build build",
38
+ "dev": "nuxi dev playground",
39
+ "dev:build": "nuxi build playground",
40
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
41
+ "release": "npm run lint && npm run prepack && release-it",
42
+ "lint": "eslint .",
43
+ "test": "vitest run",
44
+ "test:watch": "vitest watch"
45
+ },
46
+ "dependencies": {
47
+ "@nuxt/kit": "^3.9.3",
48
+ "@supabase/ssr": "^0.0.10",
49
+ "@supabase/supabase-js": "^2.39.3",
50
+ "defu": "^6.1.4"
51
+ },
52
+ "devDependencies": {
53
+ "@nuxt/devtools": "latest",
54
+ "@nuxt/eslint-config": "^0.2.0",
55
+ "@nuxt/module-builder": "^0.5.5",
56
+ "@nuxt/schema": "^3.9.3",
57
+ "@nuxt/test-utils": "^3.10.0",
58
+ "@types/node": "^20.11.5",
59
+ "@vue/test-utils": "^2.4.3",
60
+ "changelogen": "^0.5.5",
61
+ "eslint": "^8.56.0",
62
+ "eslint-config-prettier": "^9.1.0",
63
+ "happy-dom": "^13.3.1",
64
+ "nuxt": "^3.9.3",
65
+ "playwright-core": "^1.41.1",
66
+ "prettier": "^3.2.4",
67
+ "release-it": "^17.0.3",
68
+ "vitest": "^1.2.1"
69
+ }
70
+ }