@stonecrop/nuxt-grafserv 0.7.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/README.md ADDED
@@ -0,0 +1,180 @@
1
+ # Nuxt Grafserv
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![License][license-src]][license-href]
6
+ [![Nuxt][nuxt-src]][nuxt-href]
7
+
8
+ Pluggable Grafserv GraphQL server as a Nuxt Module. Uses the Grafast execution engine for high-performance GraphQL.
9
+
10
+ - [✨  Release Notes](/CHANGELOG.md)
11
+
12
+ ## Features
13
+
14
+ - 🚀  Grafserv Server Integration
15
+ - ⚡️  Grafast Execution Engine (faster than graphql-js)
16
+ - 🔄  Schema Stitching Support
17
+ - 🛠  Middleware Support
18
+ - 📝  TypeScript Support
19
+ - 🔍  GraphiQL Interface
20
+ - ⚡️  Hot Module Reloading
21
+
22
+ ## Quick Setup
23
+
24
+ 1. Add `@stonecrop/nuxt-grafserv` dependency to your project:
25
+
26
+ ```bash
27
+ # Using pnpm
28
+ pnpm add @stonecrop/nuxt-grafserv
29
+
30
+ # Using yarn
31
+ yarn add @stonecrop/nuxt-grafserv
32
+
33
+ # Using npm
34
+ npm install @stonecrop/nuxt-grafserv
35
+ ```
36
+
37
+ 2. Add `@stonecrop/nuxt-grafserv` to the `modules` section of `nuxt.config.ts`:
38
+
39
+ ```ts
40
+ export default defineNuxtConfig({
41
+ modules: ['@stonecrop/nuxt-grafserv'],
42
+ grafserv: {
43
+ schema: './server/**/*.graphql',
44
+ resolvers: './server/resolvers.ts',
45
+ url: '/graphql/',
46
+ }
47
+ })
48
+ ```
49
+
50
+ ## Configuration
51
+
52
+ Here's a full example of all available options:
53
+
54
+ ```ts
55
+ export default defineNuxtConfig({
56
+ modules: ['@stonecrop/nuxt-grafserv'],
57
+ grafserv: {
58
+ // Path to your GraphQL schema files
59
+ schema: './server/**/*.graphql',
60
+
61
+ // Path to your resolvers
62
+ resolvers: './server/resolvers.ts',
63
+
64
+ // GraphQL endpoint URL (default: /graphql/)
65
+ url: '/graphql/',
66
+
67
+ // Enable GraphiQL IDE (default: true in dev, false in prod)
68
+ graphiql: true,
69
+
70
+ // Middleware functions
71
+ middleware: [
72
+ async (ctx, next) => {
73
+ const start = Date.now()
74
+ const result = await next()
75
+ console.log(`Request took ${Date.now() - start}ms`)
76
+ return result
77
+ }
78
+ ],
79
+
80
+ // Grafserv-specific options
81
+ grafserv: {
82
+ websockets: false,
83
+ introspection: true
84
+ }
85
+ }
86
+ })
87
+ ```
88
+
89
+ ## Basic Usage
90
+
91
+ 1. Create your GraphQL schema (`server/schema.graphql`):
92
+
93
+ ```graphql
94
+ type Query {
95
+ hello: String!
96
+ ping: Boolean!
97
+ }
98
+
99
+ type Mutation {
100
+ echo(message: String!): String!
101
+ }
102
+ ```
103
+
104
+ 2. Create your resolvers (`server/resolvers.ts`):
105
+
106
+ ```typescript
107
+ export default {
108
+ Query: {
109
+ hello: () => 'world',
110
+ ping: () => true
111
+ },
112
+ Mutation: {
113
+ echo: (_: unknown, { message }: { message: string }) => message
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## Middleware
119
+
120
+ Add middleware functions to process requests:
121
+
122
+ ```ts
123
+ grafserv: {
124
+ middleware: [
125
+ // Logging middleware
126
+ async (ctx, next) => {
127
+ const start = Date.now()
128
+ const result = await next()
129
+ console.log(`Request took ${Date.now() - start}ms`)
130
+ return result
131
+ },
132
+ // Authentication middleware
133
+ async (ctx, next) => {
134
+ const token = ctx.req.headers.get('authorization')
135
+ if (!token) throw new Error('Unauthorized')
136
+ return next()
137
+ }
138
+ ]
139
+ }
140
+ ```
141
+
142
+ ## Development
143
+
144
+ ```bash
145
+ # Install dependencies
146
+ pnpm install
147
+
148
+ # Generate type stubs
149
+ pnpm run dev:prepare
150
+
151
+ # Develop with the playground
152
+ pnpm run dev
153
+
154
+ # Build the module
155
+ pnpm run build
156
+
157
+ # Run ESLint
158
+ pnpm run lint
159
+
160
+ # Run tests
161
+ pnpm run test
162
+ pnpm run test:watch
163
+ ```
164
+
165
+ ## License
166
+
167
+ [MIT License](./LICENSE)
168
+
169
+ <!-- Badges -->
170
+ [npm-version-src]: https://img.shields.io/npm/v/@stonecrop/nuxt-grafserv/latest.svg?style=flat&colorA=020420&colorB=00DC82
171
+ [npm-version-href]: https://npmjs.com/package/@stonecrop/nuxt-grafserv
172
+
173
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@stonecrop/nuxt-grafserv.svg?style=flat&colorA=020420&colorB=00DC82
174
+ [npm-downloads-href]: https://npm.chart.dev/@stonecrop/nuxt-grafserv
175
+
176
+ [license-src]: https://img.shields.io/npm/l/@stonecrop/nuxt-grafserv.svg?style=flat&colorA=020420&colorB=00DC82
177
+ [license-href]: https://npmjs.com/package/@stonecrop/nuxt-grafserv
178
+
179
+ [nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt.js
180
+ [nuxt-href]: https://nuxt.com
@@ -0,0 +1,61 @@
1
+ import { NuxtModule } from '@nuxt/schema';
2
+ import { GraphQLSchema } from 'graphql';
3
+ import { GraphileConfig } from 'graphile-config';
4
+
5
+ /**
6
+ * Context provided to GraphQL resolvers
7
+ */
8
+ type GrafastContext = {
9
+ req: Request;
10
+ params: Record<string, string>;
11
+ [key: string]: unknown;
12
+ };
13
+ /**
14
+ * Middleware function type for request processing
15
+ */
16
+ type MiddlewareFunction = (context: GrafastContext, next: () => Promise<GrafastContext>) => Promise<GrafastContext>;
17
+ /**
18
+ * Schema provider function - returns a GraphQL schema
19
+ */
20
+ type SchemaProvider = () => GraphQLSchema | Promise<GraphQLSchema>;
21
+ /**
22
+ * Configuration for the Grafast module
23
+ */
24
+ interface ModuleOptions {
25
+ /** Path to schema file(s) or a schema provider function */
26
+ schema?: string | string[] | SchemaProvider;
27
+ /** Path to resolvers file (for .graphql schema files) */
28
+ resolvers?: string;
29
+ /** GraphQL endpoint URL (default: '/graphql/') */
30
+ url?: string;
31
+ /** Whether to enable GraphiQL IDE (default: true in dev, false in prod) */
32
+ graphiql?: boolean;
33
+ /**
34
+ * Path to middleware file that exports an array of middleware functions.
35
+ * This is the recommended approach as it preserves imports/dependencies.
36
+ * Example: './server/middleware.ts'
37
+ */
38
+ middlewarePath?: string;
39
+ /**
40
+ * Middleware functions to process requests (inline).
41
+ * Note: Inline middleware cannot reference external modules.
42
+ * For middleware with dependencies, use middlewarePath instead.
43
+ * @deprecated Use middlewarePath for middleware with external dependencies
44
+ */
45
+ middleware?: MiddlewareFunction[];
46
+ /** Custom Graphile preset to extend (for advanced grafast configuration) */
47
+ preset?: GraphileConfig.Preset;
48
+ /** Additional Graphile plugins */
49
+ plugins?: GraphileConfig.Plugin[];
50
+ /** Grafserv options */
51
+ grafserv?: {
52
+ /** Whether to enable the GraphQL websocket endpoint */
53
+ websockets?: boolean;
54
+ /** Whether to enable introspection (default: true in dev) */
55
+ introspection?: boolean;
56
+ };
57
+ }
58
+
59
+ declare const module$1: NuxtModule<ModuleOptions>;
60
+
61
+ export { module$1 as default };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "nuxt-grafserv",
3
+ "configKey": "grafserv",
4
+ "version": "0.7.0",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "unknown"
8
+ }
9
+ }
@@ -0,0 +1,117 @@
1
+ import { join } from 'node:path';
2
+ import { useLogger, defineNuxtModule, createResolver } from '@nuxt/kit';
3
+
4
+ const logger = useLogger("nuxt-grafserv");
5
+ const module$1 = defineNuxtModule({
6
+ meta: {
7
+ name: "nuxt-grafserv",
8
+ configKey: "grafserv"
9
+ },
10
+ defaults: (_nuxt) => ({
11
+ schema: "./server/**/*.graphql",
12
+ resolvers: "./server/resolvers.ts",
13
+ url: "/graphql/",
14
+ graphiql: void 0,
15
+ // Will default based on dev mode
16
+ middleware: [],
17
+ plugins: [],
18
+ grafserv: {
19
+ websockets: false,
20
+ introspection: void 0
21
+ // Will default based on dev mode
22
+ }
23
+ }),
24
+ setup(options, nuxt) {
25
+ const { resolve } = createResolver(import.meta.url);
26
+ nuxt.hook("nitro:config", (config) => {
27
+ const resolverPath = options.resolvers ? join(nuxt.options.srcDir, options.resolvers) : void 0;
28
+ config.runtimeConfig = config.runtimeConfig || {};
29
+ config.runtimeConfig.grafserv = {
30
+ ...options,
31
+ // Resolve schema paths
32
+ schema: typeof options.schema === "string" ? join(nuxt.options.srcDir, options.schema) : Array.isArray(options.schema) ? options.schema.map((s) => join(nuxt.options.srcDir, s)) : options.schema
33
+ // function passed through
34
+ };
35
+ config.virtual = config.virtual || {};
36
+ if (resolverPath) {
37
+ config.virtual["#internal/grafserv/resolvers"] = `export { default } from '${resolverPath}'`;
38
+ }
39
+ let middlewareCode;
40
+ if (options.middlewarePath) {
41
+ const middlewarePath = join(nuxt.options.srcDir, options.middlewarePath);
42
+ middlewareCode = `export { default } from '${middlewarePath}'`;
43
+ } else if (options.middleware?.length) {
44
+ logger.warn("Inline middleware is deprecated. Use middlewarePath for middleware with external dependencies.");
45
+ middlewareCode = `export default [${options.middleware.map((fn) => fn.toString()).join(",")}]`;
46
+ } else {
47
+ middlewareCode = "export default []";
48
+ }
49
+ config.virtual["#internal/grafserv/middleware"] = middlewareCode;
50
+ config.externals = config.externals || {};
51
+ config.externals.inline = config.externals.inline || [];
52
+ config.externals.inline.push(
53
+ "grafast",
54
+ "grafserv",
55
+ "grafserv/h3/v1",
56
+ "graphile-config",
57
+ "@graphql-tools/schema",
58
+ "@graphql-tools/load",
59
+ "@graphql-tools/graphql-file-loader"
60
+ );
61
+ });
62
+ nuxt.hook("nitro:config", (config) => {
63
+ config.handlers = config.handlers || [];
64
+ config.handlers.push({
65
+ route: options.url || "/graphql/",
66
+ handler: resolve("./runtime/handler")
67
+ });
68
+ config.handlers.push({
69
+ route: "/graphql/cache",
70
+ handler: resolve("./runtime/cache")
71
+ });
72
+ config.handlers.push({
73
+ route: "/ruru-static/**",
74
+ handler: resolve("./runtime/handler")
75
+ });
76
+ });
77
+ if (options.url) {
78
+ nuxt.hook("devtools:customTabs", (tabs) => {
79
+ tabs.push({
80
+ name: "nuxt-grafserv",
81
+ title: "GraphQL (Grafserv)",
82
+ icon: "simple-icons:graphql",
83
+ view: {
84
+ type: "iframe",
85
+ src: options.url
86
+ }
87
+ });
88
+ });
89
+ }
90
+ if (nuxt.options.dev) {
91
+ let cacheClearing = false;
92
+ nuxt.hook("builder:watch", async (event, path) => {
93
+ const isSchemaFile = path.endsWith(".graphql");
94
+ const isResolverFile = options.resolvers && path.includes(options.resolvers.replace("./", ""));
95
+ if (isSchemaFile || isResolverFile) {
96
+ logger.info(`${path} changed`);
97
+ if (!cacheClearing) {
98
+ cacheClearing = true;
99
+ try {
100
+ logger.info("Clearing Grafserv cache...");
101
+ const { clearGrafservCache } = await import(resolve("./runtime/handler"));
102
+ await clearGrafservCache();
103
+ logger.success("Cache cleared, schema reloaded");
104
+ } catch (error) {
105
+ logger.error("Failed to clear cache:", error);
106
+ } finally {
107
+ cacheClearing = false;
108
+ }
109
+ }
110
+ }
111
+ });
112
+ }
113
+ logger.success("[@stonecrop/nuxt-grafserv] Module initialized");
114
+ }
115
+ });
116
+
117
+ export { module$1 as default };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Cache management endpoint for the Grafserv module.
3
+ *
4
+ * Actions:
5
+ * - clear: Clear the Grafserv instance cache
6
+ * - status: Get cache status information
7
+ */
8
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<{
9
+ success: boolean;
10
+ message: string;
11
+ data?: undefined;
12
+ availableActions?: undefined;
13
+ } | {
14
+ success: boolean;
15
+ data: {
16
+ message: string;
17
+ };
18
+ message?: undefined;
19
+ availableActions?: undefined;
20
+ } | {
21
+ success: boolean;
22
+ message: string;
23
+ availableActions: string[];
24
+ data?: undefined;
25
+ }>>;
26
+ export default _default;
@@ -0,0 +1,31 @@
1
+ import { defineEventHandler, getQuery, createError } from "h3";
2
+ import { clearGrafservCache } from "./handler.js";
3
+ export default defineEventHandler(async (event) => {
4
+ const allowCacheApi = process.env.NODE_ENV === "development";
5
+ if (!allowCacheApi) {
6
+ throw createError({
7
+ statusCode: 403,
8
+ statusMessage: "Cache API is disabled in production"
9
+ });
10
+ }
11
+ const query = getQuery(event);
12
+ const action = query.action;
13
+ switch (action) {
14
+ case "clear":
15
+ await clearGrafservCache();
16
+ return { success: true, message: "Grafserv cache cleared" };
17
+ case "status":
18
+ return {
19
+ success: true,
20
+ data: {
21
+ message: "Grafserv cache status - schema and server instance cached in memory"
22
+ }
23
+ };
24
+ default:
25
+ return {
26
+ success: false,
27
+ message: "Invalid action",
28
+ availableActions: ["clear", "status"]
29
+ };
30
+ }
31
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Clear the cached instances (useful for development hot reload)
3
+ */
4
+ export declare function clearGrafservCache(): Promise<void>;
5
+ /**
6
+ * Main H3 event handler for GraphQL requests
7
+ */
8
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<Buffer<ArrayBufferLike> | import("grafserv").JSONValue | undefined>>;
9
+ export default _default;
@@ -0,0 +1,133 @@
1
+ import { grafserv } from "grafserv/h3/v1";
2
+ import { makeGrafastSchema } from "grafast";
3
+ import { GraphQLFileLoader } from "@graphql-tools/graphql-file-loader";
4
+ import { loadTypedefs } from "@graphql-tools/load";
5
+ import { defineEventHandler } from "h3";
6
+ import { useRuntimeConfig } from "nitropack/runtime";
7
+ let middlewareFunctions = null;
8
+ async function getMiddleware() {
9
+ if (middlewareFunctions !== null) {
10
+ return middlewareFunctions;
11
+ }
12
+ try {
13
+ const mod = await import("#internal/grafserv/middleware");
14
+ middlewareFunctions = mod.default || [];
15
+ } catch {
16
+ middlewareFunctions = [];
17
+ }
18
+ return middlewareFunctions;
19
+ }
20
+ let grafservInstance = null;
21
+ let cachedSchema = null;
22
+ async function loadTypeDefsFromFiles(schemaPath) {
23
+ const paths = Array.isArray(schemaPath) ? schemaPath : [schemaPath];
24
+ const sources = await loadTypedefs(paths, {
25
+ loaders: [new GraphQLFileLoader()]
26
+ });
27
+ return sources.map((source) => source.document).filter(Boolean);
28
+ }
29
+ async function getSchema(options) {
30
+ if (cachedSchema) {
31
+ return cachedSchema;
32
+ }
33
+ let schema;
34
+ if (typeof options.schema === "function") {
35
+ schema = await options.schema();
36
+ } else if (options.schema) {
37
+ const typeDefDocs = await loadTypeDefsFromFiles(options.schema);
38
+ let plans = {};
39
+ if (options.resolvers) {
40
+ try {
41
+ const resolverModule = await import("#internal/grafserv/resolvers");
42
+ const resolvers = resolverModule.default || resolverModule;
43
+ console.log("[@stonecrop/nuxt-grafserv] Resolvers loaded:", Object.keys(resolvers));
44
+ for (const typeName of Object.keys(resolvers)) {
45
+ plans[typeName] = {};
46
+ const typeResolvers = resolvers[typeName];
47
+ for (const fieldName of Object.keys(typeResolvers)) {
48
+ const resolver = typeResolvers[fieldName];
49
+ if (typeof resolver === "function") {
50
+ plans[typeName][fieldName] = { resolve: resolver };
51
+ } else {
52
+ plans[typeName][fieldName] = resolver;
53
+ }
54
+ }
55
+ }
56
+ } catch (e) {
57
+ console.warn("[@stonecrop/nuxt-grafserv] Could not load resolvers:", e);
58
+ }
59
+ }
60
+ schema = makeGrafastSchema({
61
+ typeDefs: typeDefDocs,
62
+ plans
63
+ });
64
+ } else {
65
+ throw new Error("[@stonecrop/nuxt-grafserv] No schema provided. Configure schema path or provider function.");
66
+ }
67
+ cachedSchema = schema;
68
+ return schema;
69
+ }
70
+ async function getGrafservInstance(options) {
71
+ if (grafservInstance) {
72
+ return grafservInstance;
73
+ }
74
+ const schema = await getSchema(options);
75
+ const isDev = process.env.NODE_ENV === "development";
76
+ grafservInstance = grafserv({
77
+ schema,
78
+ graphiql: options.graphiql ?? isDev,
79
+ websockets: options.grafserv?.websockets ?? false
80
+ });
81
+ console.log("[@stonecrop/nuxt-grafserv] Grafserv instance created");
82
+ return grafservInstance;
83
+ }
84
+ export async function clearGrafservCache() {
85
+ grafservInstance = null;
86
+ cachedSchema = null;
87
+ console.log("[@stonecrop/nuxt-grafserv] Cache cleared");
88
+ }
89
+ async function applyMiddleware(context, middleware) {
90
+ if (!middleware || middleware.length === 0) {
91
+ return context;
92
+ }
93
+ const applyNext = async (index) => {
94
+ if (index >= middleware.length) {
95
+ return context;
96
+ }
97
+ return middleware[index](context, () => applyNext(index + 1));
98
+ };
99
+ return applyNext(0);
100
+ }
101
+ export default defineEventHandler(async (event) => {
102
+ const config = useRuntimeConfig();
103
+ const options = config.grafserv;
104
+ try {
105
+ if (event.node.req.url?.includes("/__grafserv_cache_clear") && process.env.NODE_ENV === "development") {
106
+ await clearGrafservCache();
107
+ return { success: true, message: "Cache cleared" };
108
+ }
109
+ const { req } = event.node;
110
+ const context = {
111
+ req: new Request(new URL(req.url || "/", `http://${req.headers.host || "localhost"}`), {
112
+ method: req.method,
113
+ headers: req.headers
114
+ }),
115
+ params: event.context.params || {}
116
+ };
117
+ const middleware = await getMiddleware();
118
+ await applyMiddleware(context, middleware);
119
+ const serv = await getGrafservInstance(options);
120
+ const url = event.node.req.url || "";
121
+ const method = event.node.req.method || "GET";
122
+ if (url.includes("/ruru-static/")) {
123
+ return serv.handleGraphiqlStaticEvent(event);
124
+ }
125
+ if (method === "GET" && url.match(/\/graphql\/?(\?.*)?$/)) {
126
+ return serv.handleGraphiqlEvent(event);
127
+ }
128
+ return serv.handleGraphQLEvent(event);
129
+ } catch (error) {
130
+ console.error("[@stonecrop/nuxt-grafserv] Error in GraphQL handler:", error);
131
+ throw error;
132
+ }
133
+ });
@@ -0,0 +1,7 @@
1
+ import type { NuxtModule } from '@nuxt/schema'
2
+
3
+ import type { default as Module } from './module.mjs'
4
+
5
+ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
+
7
+ export { default } from './module.mjs'
package/package.json ADDED
@@ -0,0 +1,99 @@
1
+ {
2
+ "name": "@stonecrop/nuxt-grafserv",
3
+ "version": "0.7.0",
4
+ "description": "Pluggable Grafserv GraphQL server as Nuxt Module",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "author": {
8
+ "name": "Tyler Matteson",
9
+ "email": "tyler@agritheory.com"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/agritheory/stonecrop",
14
+ "directory": "nuxt_grafserv"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/agritheory/stonecrop/issues"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "import": "./dist/module.mjs",
22
+ "types": "./dist/types.d.mts"
23
+ },
24
+ "./runtime/*": "./dist/runtime/*"
25
+ },
26
+ "main": "./dist/module.mjs",
27
+ "types": "./dist/types.d.mts",
28
+ "typesVersions": {
29
+ "*": {
30
+ ".": [
31
+ "./dist/types.d.mts"
32
+ ]
33
+ }
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "dependencies": {
39
+ "@graphql-tools/graphql-file-loader": "^8.1.9",
40
+ "@graphql-tools/load": "^8.1.8",
41
+ "@graphql-tools/stitch": "^10.1.8",
42
+ "@graphql-tools/wrap": "^11.1.4",
43
+ "grafast": "^1.0.0-rc.3",
44
+ "grafserv": "^1.0.0-rc.3",
45
+ "graphile-config": "^1.0.0-rc.2",
46
+ "graphql": "^16.12.0",
47
+ "@stonecrop/graphql-middleware": "0.7.0"
48
+ },
49
+ "devDependencies": {
50
+ "@casl/ability": "^6.7.5",
51
+ "@eslint/js": "^9.39.2",
52
+ "@nuxt/devtools": "^3.1.1",
53
+ "@nuxt/eslint-config": "^1.12.1",
54
+ "@nuxt/kit": "^4.2.2",
55
+ "@nuxt/module-builder": "^1.0.2",
56
+ "@nuxt/schema": "^4.2.2",
57
+ "@nuxt/test-utils": "^3.23.0",
58
+ "@vitest/coverage-istanbul": "^4.0.17",
59
+ "@types/node": "^22.19.5",
60
+ "zod": "^3.25.76",
61
+ "h3": "^1.15.4",
62
+ "nitropack": "^2.13.0",
63
+ "changelogen": "^0.6.2",
64
+ "eslint": "^9.39.2",
65
+ "jsdom": "^27.4.0",
66
+ "nuxt": "^4.2.2",
67
+ "typescript": "^5.9.3",
68
+ "vite": "^7.3.1",
69
+ "vitest": "^4.0.17",
70
+ "vue-tsc": "^3.2.2",
71
+ "@stonecrop/casl-middleware": "0.7.0",
72
+ "@stonecrop/rockfoil": "0.7.0"
73
+ },
74
+ "peerDependencies": {
75
+ "@stonecrop/casl-middleware": "0.7.0",
76
+ "@stonecrop/rockfoil": "0.7.0"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "@stonecrop/casl-middleware": {
80
+ "optional": true
81
+ },
82
+ "@stonecrop/rockfoil": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "scripts": {
87
+ "_phase:build": "rushx dev:prepare && rushx prepack",
88
+ "build": "rushx dev:prepare && rushx prepack",
89
+ "build:module": "rushx dev:prepare && rushx prepack",
90
+ "dev": "nuxi dev playground",
91
+ "dev:build": "nuxi build playground",
92
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
93
+ "lint": "eslint .",
94
+ "test": "vitest run",
95
+ "test:ci": "vitest run --run",
96
+ "test:watch": "vitest watch",
97
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
98
+ }
99
+ }