nuxt-graphql-middleware 5.0.0 → 5.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/dist/client/200.html +9 -9
- package/dist/client/404.html +9 -9
- package/dist/client/_nuxt/B-BZSpkz.js +25 -0
- package/dist/client/_nuxt/C6_BMIRJ.js +1 -0
- package/dist/client/_nuxt/{FTbv7CO6.js → CFKT0oF2.js} +1 -1
- package/dist/client/_nuxt/{lIgCBhS_.js → CrwW1KlQ.js} +1 -1
- package/dist/client/_nuxt/{CROlboVl.js → CyxO-88q.js} +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/bab648bf-3b57-4a37-bfa7-d3789fe7395f.json +1 -0
- package/dist/client/_nuxt/{entry.Cn9qfNGa.css → entry.BBgLZ1Jk.css} +1 -1
- package/dist/client/_nuxt/error-404.Bbd2eCoc.css +1 -0
- package/dist/client/_nuxt/error-500.Cd2cwFc3.css +1 -0
- package/dist/client/index.html +9 -9
- package/dist/module.d.mts +1 -1
- package/dist/module.json +2 -2
- package/dist/module.mjs +159 -55
- package/dist/runtime/composables/nuxtApp.d.ts +30 -2
- package/dist/runtime/composables/nuxtApp.js +66 -24
- package/dist/runtime/composables/useAsyncGraphqlQuery.js +28 -25
- package/dist/runtime/composables/useGraphqlMutation.d.ts +1 -1
- package/dist/runtime/composables/useGraphqlMutation.js +11 -16
- package/dist/runtime/composables/useGraphqlQuery.d.ts +1 -1
- package/dist/runtime/composables/useGraphqlQuery.js +7 -25
- package/dist/runtime/composables/useGraphqlUploadMutation.js +1 -1
- package/dist/runtime/helpers/ClientCache.d.ts +1 -0
- package/dist/runtime/helpers/ClientCache.js +12 -0
- package/dist/runtime/helpers/composables.d.ts +8 -0
- package/dist/runtime/helpers/composables.js +27 -0
- package/dist/runtime/helpers/index.d.ts +0 -4
- package/dist/runtime/helpers/index.js +0 -13
- package/dist/runtime/helpers/queryEncoding.d.ts +11 -0
- package/dist/runtime/helpers/queryEncoding.js +89 -0
- package/dist/runtime/plugins/devMode.js +2 -1
- package/dist/runtime/server/api/query.js +5 -7
- package/dist/runtime/server/utils/useGraphqlQuery.js +2 -2
- package/dist/runtime/settings/index.d.ts +1 -0
- package/dist/runtime/settings/index.js +1 -0
- package/dist/shared/{nuxt-graphql-middleware.cXfDI4U3.d.mts → nuxt-graphql-middleware.-BeiPV4H.d.mts} +49 -0
- package/dist/utils.d.mts +1 -1
- package/package.json +7 -7
- package/dist/client/_nuxt/BM34SYth.js +0 -1
- package/dist/client/_nuxt/D5hBL5aZ.js +0 -25
- package/dist/client/_nuxt/builds/meta/83f9fcd5-bd28-4608-b499-05e08fe0f7d0.json +0 -1
- package/dist/client/_nuxt/error-404.ehK72JOs.css +0 -1
- package/dist/client/_nuxt/error-500._g0akJim.css +0 -1
|
@@ -1,26 +1,57 @@
|
|
|
1
1
|
import { useGraphqlState } from "./useGraphqlState.js";
|
|
2
2
|
import { hash } from "ohash";
|
|
3
|
-
import { GraphqlMiddlewareCache } from "../helpers/ClientCache.js";
|
|
4
3
|
import { getEndpoint } from "#nuxt-graphql-middleware/helpers";
|
|
5
4
|
import { useNuxtApp, useAppConfig } from "#imports";
|
|
6
|
-
|
|
5
|
+
import { operationHashes } from "#nuxt-graphql-middleware/operation-hashes";
|
|
6
|
+
import {
|
|
7
|
+
clientCacheEnabledAtBuild,
|
|
8
|
+
importMetaClient
|
|
9
|
+
} from "#nuxt-graphql-middleware/config";
|
|
10
|
+
import { encodeVariables } from "../helpers/queryEncoding.js";
|
|
11
|
+
import {
|
|
12
|
+
encodeContext,
|
|
13
|
+
getOrCreateClientCache,
|
|
14
|
+
sortQueryParams
|
|
15
|
+
} from "../helpers/composables.js";
|
|
16
|
+
import { OPERATION_HASH_PREFIX } from "../settings/index.js";
|
|
17
|
+
export function performRequest(operation, operationName, variablesOrBody, overrideFetchOptions, globalClientContext, overrideClientContext, cacheOptions) {
|
|
7
18
|
const state = useGraphqlState();
|
|
8
19
|
const app = useNuxtApp();
|
|
20
|
+
const config = useAppConfig();
|
|
21
|
+
const method = operation === "query" ? "get" : "post";
|
|
22
|
+
const isQuery = operation === "query";
|
|
9
23
|
if (!state) {
|
|
10
24
|
console.error(
|
|
11
25
|
`A GraphQL composable for ${operation} "${operationName}" was called before the "nuxt-graphql-middleware-provide-state" plugin could provide the state, which might lead to unexpected behaviour. Make sure that custom plugins that perform GraphQL requests are executed after "nuxt-graphql-middleware-provide-state" by setting it as a dependency via "dependsOn".`
|
|
12
26
|
);
|
|
13
27
|
}
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
const clientContext = Object.assign(
|
|
29
|
+
{},
|
|
30
|
+
globalClientContext,
|
|
31
|
+
overrideClientContext
|
|
32
|
+
);
|
|
33
|
+
const fetchOptions = Object.assign(
|
|
34
|
+
{},
|
|
35
|
+
state?.fetchOptions,
|
|
36
|
+
overrideFetchOptions
|
|
37
|
+
);
|
|
38
|
+
const paramsRaw = Object.assign(
|
|
39
|
+
importMetaClient ? {
|
|
40
|
+
// The unique operation hash that changes whenever any operation source or
|
|
41
|
+
// fragment changes.
|
|
42
|
+
[OPERATION_HASH_PREFIX]: operationHashes[operationName]
|
|
43
|
+
} : {},
|
|
44
|
+
encodeContext(clientContext),
|
|
45
|
+
fetchOptions.params,
|
|
46
|
+
fetchOptions.query,
|
|
47
|
+
isQuery ? encodeVariables(variablesOrBody) : null
|
|
48
|
+
);
|
|
49
|
+
const params = importMetaClient && isQuery ? sortQueryParams(paramsRaw) : paramsRaw;
|
|
50
|
+
const cacheKey = importMetaClient && clientCacheEnabledAtBuild && isQuery && cacheOptions?.client && config.graphqlMiddleware.clientCacheEnabled ? `${operation}:${operationName}:${hash(params)}` : void 0;
|
|
51
|
+
if (importMetaClient && cacheKey) {
|
|
52
|
+
const cache = getOrCreateClientCache(app, config);
|
|
53
|
+
if (cache) {
|
|
54
|
+
const cached = cache.get(cacheKey);
|
|
24
55
|
if (cached) {
|
|
25
56
|
if (import.meta.dev) {
|
|
26
57
|
cached.then((response) => {
|
|
@@ -40,11 +71,23 @@ export function performRequest(operation, operationName, method, options, cacheO
|
|
|
40
71
|
}
|
|
41
72
|
const promise = $fetch(
|
|
42
73
|
getEndpoint(operation, operationName),
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
74
|
+
Object.assign(
|
|
75
|
+
{},
|
|
76
|
+
// Use the merged fetch options.
|
|
77
|
+
fetchOptions,
|
|
78
|
+
// Remove params and query from the fetch options.
|
|
79
|
+
{
|
|
80
|
+
params: void 0,
|
|
81
|
+
query: void 0
|
|
82
|
+
},
|
|
83
|
+
// Set the previously merged params. That way we only ever pass "params"
|
|
84
|
+
// as the query params.
|
|
85
|
+
{
|
|
86
|
+
params,
|
|
87
|
+
method,
|
|
88
|
+
body: operation === "mutation" ? variablesOrBody : void 0
|
|
89
|
+
}
|
|
90
|
+
)
|
|
48
91
|
).then((v) => {
|
|
49
92
|
if (import.meta.dev && v.errors?.length) {
|
|
50
93
|
app.callHook("nuxt-graphql-middleware:errors", {
|
|
@@ -54,14 +97,13 @@ export function performRequest(operation, operationName, method, options, cacheO
|
|
|
54
97
|
stack: Error().stack
|
|
55
98
|
});
|
|
56
99
|
}
|
|
57
|
-
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
};
|
|
100
|
+
return Object.assign({}, v, {
|
|
101
|
+
data: v?.data,
|
|
102
|
+
errors: v?.errors || []
|
|
103
|
+
});
|
|
62
104
|
});
|
|
63
|
-
if (
|
|
64
|
-
app.$graphqlCache.set(
|
|
105
|
+
if (importMetaClient && cacheKey && app.$graphqlCache && clientCacheEnabledAtBuild) {
|
|
106
|
+
app.$graphqlCache.set(cacheKey, promise);
|
|
65
107
|
}
|
|
66
108
|
return promise;
|
|
67
109
|
}
|
|
@@ -1,57 +1,60 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
getOrCreateClientCache
|
|
3
3
|
} from "./../helpers/composables.js";
|
|
4
4
|
import { isRef, unref } from "vue";
|
|
5
|
-
import { buildRequestParams } from "./../helpers/index.js";
|
|
6
5
|
import { performRequest } from "./nuxtApp.js";
|
|
7
6
|
import {
|
|
8
7
|
clientOptions
|
|
9
8
|
} from "#nuxt-graphql-middleware/client-options";
|
|
10
|
-
import { useAsyncData, useAppConfig, useNuxtApp } from "#imports";
|
|
9
|
+
import { useAsyncData, useAppConfig, useNuxtApp, computed } from "#imports";
|
|
11
10
|
import { hash } from "ohash";
|
|
11
|
+
import { importMetaClient } from "#nuxt-graphql-middleware/config";
|
|
12
12
|
export function useAsyncGraphqlQuery(name, ...args) {
|
|
13
13
|
const variables = args[0];
|
|
14
14
|
const asyncDataOptions = args[1] || {};
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
const asyncDataKey = computed(() => {
|
|
16
|
+
const vars = isRef(variables) ? variables.value : variables;
|
|
17
|
+
return `useAsyncGraphqlQuery:${name}:${hash(vars)}`;
|
|
18
|
+
});
|
|
17
19
|
const config = useAppConfig();
|
|
18
20
|
const app = useNuxtApp();
|
|
19
|
-
if (
|
|
21
|
+
if (importMetaClient) {
|
|
20
22
|
if (variables && isRef(variables)) {
|
|
21
23
|
if (!asyncDataOptions.watch) {
|
|
22
24
|
asyncDataOptions.watch = [];
|
|
23
25
|
}
|
|
24
26
|
asyncDataOptions.watch.push(variables);
|
|
25
27
|
}
|
|
28
|
+
if (asyncDataOptions.graphqlCaching?.client && app.isHydrating) {
|
|
29
|
+
const cache = getOrCreateClientCache(app, config);
|
|
30
|
+
if (cache) {
|
|
31
|
+
const key = asyncDataKey.value;
|
|
32
|
+
const payload = app.payload.data[asyncDataKey.value];
|
|
33
|
+
if (payload) {
|
|
34
|
+
cache.set(key, payload);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
26
38
|
if (asyncDataOptions.graphqlCaching?.client && !asyncDataOptions.getCachedData) {
|
|
27
|
-
asyncDataOptions.getCachedData = function(
|
|
28
|
-
if (
|
|
29
|
-
return;
|
|
39
|
+
asyncDataOptions.getCachedData = function(key, app2, ctx) {
|
|
40
|
+
if (ctx.cause === "initial") {
|
|
41
|
+
return app2.payload.data[key] ?? app2.$graphqlCache?.get(key);
|
|
30
42
|
}
|
|
31
|
-
return app.payload.data[key2];
|
|
32
43
|
};
|
|
33
44
|
}
|
|
34
45
|
}
|
|
35
46
|
const result = useAsyncData(
|
|
36
|
-
|
|
47
|
+
asyncDataKey,
|
|
37
48
|
() => {
|
|
38
|
-
const globalClientContext = clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
49
|
+
const globalClientContext = clientOptions && clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
39
50
|
return performRequest(
|
|
40
51
|
"query",
|
|
41
52
|
name,
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
...buildRequestParams(unref(variables)),
|
|
48
|
-
...encodeContext({
|
|
49
|
-
...globalClientContext,
|
|
50
|
-
...asyncDataOptions.clientContext || {}
|
|
51
|
-
})
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
asyncDataOptions.graphqlCaching
|
|
53
|
+
unref(variables) || {},
|
|
54
|
+
asyncDataOptions.fetchOptions || {},
|
|
55
|
+
globalClientContext,
|
|
56
|
+
asyncDataOptions.clientContext || {},
|
|
57
|
+
asyncDataOptions.graphqlCaching || {}
|
|
55
58
|
);
|
|
56
59
|
},
|
|
57
60
|
asyncDataOptions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { GetMutationArgs, MutationObjectArgs, GetMutationResult } from './../helpers/composables.js';
|
|
2
2
|
import type { GraphqlResponse } from '#nuxt-graphql-middleware/response';
|
|
3
3
|
import type { Mutation } from '#nuxt-graphql-middleware/operation-types';
|
|
4
4
|
/**
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
encodeContext
|
|
3
|
-
} from "./../helpers/composables.js";
|
|
4
1
|
import { performRequest } from "./nuxtApp.js";
|
|
5
2
|
import { clientOptions } from "#nuxt-graphql-middleware/client-options";
|
|
6
3
|
export function useGraphqlMutation(...args) {
|
|
7
|
-
const [name, body, fetchOptions
|
|
4
|
+
const [name, body, fetchOptions, overrideClientContext] = typeof args[0] === "string" ? [args[0], args[1], args[2]?.fetchOptions, args[2]?.clientContext] : [
|
|
8
5
|
args[0].name,
|
|
9
6
|
args[0].variables,
|
|
10
7
|
args[0].fetchOptions,
|
|
11
8
|
args[0].clientContext
|
|
12
9
|
];
|
|
13
|
-
const globalClientContext = clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
14
|
-
return performRequest(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
});
|
|
10
|
+
const globalClientContext = clientOptions && clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
11
|
+
return performRequest(
|
|
12
|
+
"mutation",
|
|
13
|
+
name,
|
|
14
|
+
body || {},
|
|
15
|
+
fetchOptions || {},
|
|
16
|
+
globalClientContext,
|
|
17
|
+
overrideClientContext || {},
|
|
18
|
+
{}
|
|
19
|
+
);
|
|
25
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { GetQueryArgs, QueryObjectArgs, GetQueryResult } from './../helpers/composables.js';
|
|
2
2
|
import type { GraphqlResponse } from '#nuxt-graphql-middleware/response';
|
|
3
3
|
import type { Query } from '#nuxt-graphql-middleware/operation-types';
|
|
4
4
|
/**
|
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
encodeContext
|
|
3
|
-
} from "./../helpers/composables.js";
|
|
4
|
-
import { buildRequestParams } from "./../helpers/index.js";
|
|
5
1
|
import { performRequest } from "./nuxtApp.js";
|
|
6
2
|
import { clientOptions } from "#nuxt-graphql-middleware/client-options";
|
|
7
3
|
export function useGraphqlQuery(...args) {
|
|
8
|
-
const [
|
|
9
|
-
name,
|
|
10
|
-
variables,
|
|
11
|
-
fetchOptions = {},
|
|
12
|
-
graphqlCaching = {},
|
|
13
|
-
overrideClientContext = {}
|
|
14
|
-
] = typeof args[0] === "string" ? [
|
|
4
|
+
const [name, variables, fetchOptions, graphqlCaching, overrideClientContext] = typeof args[0] === "string" ? [
|
|
15
5
|
args[0],
|
|
16
6
|
args[1],
|
|
17
7
|
args[2]?.fetchOptions,
|
|
@@ -24,22 +14,14 @@ export function useGraphqlQuery(...args) {
|
|
|
24
14
|
args[0].graphqlCaching,
|
|
25
15
|
args[0].clientContext
|
|
26
16
|
];
|
|
27
|
-
const globalClientContext = clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
17
|
+
const globalClientContext = clientOptions && clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
28
18
|
return performRequest(
|
|
29
19
|
"query",
|
|
30
20
|
name,
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
...buildRequestParams(variables),
|
|
37
|
-
...encodeContext({
|
|
38
|
-
...globalClientContext,
|
|
39
|
-
...overrideClientContext
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
graphqlCaching
|
|
21
|
+
variables || {},
|
|
22
|
+
fetchOptions || {},
|
|
23
|
+
globalClientContext || {},
|
|
24
|
+
overrideClientContext || {},
|
|
25
|
+
graphqlCaching || {}
|
|
44
26
|
);
|
|
45
27
|
}
|
|
@@ -49,7 +49,7 @@ export function useGraphqlUploadMutation(...args) {
|
|
|
49
49
|
}
|
|
50
50
|
const state = useGraphqlState();
|
|
51
51
|
const formData = createFormData(variables);
|
|
52
|
-
const globalClientContext = clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
52
|
+
const globalClientContext = clientOptions && clientOptions.buildClientContext ? clientOptions.buildClientContext() : {};
|
|
53
53
|
const clientContext = encodeContext({
|
|
54
54
|
...globalClientContext,
|
|
55
55
|
...overrideClientContext
|
|
@@ -36,5 +36,17 @@ export class GraphqlMiddlewareCache {
|
|
|
36
36
|
}
|
|
37
37
|
purge() {
|
|
38
38
|
this.cache = {};
|
|
39
|
+
this.keys = [];
|
|
40
|
+
}
|
|
41
|
+
remove(key) {
|
|
42
|
+
if (Object.prototype.hasOwnProperty.call(this.cache, key)) {
|
|
43
|
+
delete this.cache[key];
|
|
44
|
+
const index = this.keys.indexOf(key);
|
|
45
|
+
if (index > -1) {
|
|
46
|
+
this.keys.splice(index, 1);
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
39
51
|
}
|
|
40
52
|
}
|
|
@@ -2,6 +2,9 @@ import type { FetchOptions } from 'ofetch';
|
|
|
2
2
|
import type { RequestCacheOptions } from './../types.js';
|
|
3
3
|
import type { GraphqlClientContext } from '#nuxt-graphql-middleware/client-options';
|
|
4
4
|
import type { Query, Mutation } from '#nuxt-graphql-middleware/operation-types';
|
|
5
|
+
import type { NuxtApp } from '#app';
|
|
6
|
+
import type { AppConfig } from 'nuxt/schema';
|
|
7
|
+
import { GraphqlMiddlewareCache } from './ClientCache.js';
|
|
5
8
|
export type GraphqlComposableOptions = {
|
|
6
9
|
fetchOptions?: FetchOptions;
|
|
7
10
|
graphqlCaching?: RequestCacheOptions;
|
|
@@ -38,3 +41,8 @@ export type MutationObjectArgs<K extends keyof Mutation, M extends Mutation[K] =
|
|
|
38
41
|
export type PickFrom<T, K extends Array<string>> = T extends Array<any> ? T : T extends Record<string, any> ? keyof T extends K[number] ? T : K[number] extends never ? T : Pick<T, K[number]> : T;
|
|
39
42
|
export type KeysOf<T> = Array<T extends T ? (keyof T extends string ? keyof T : never) : never>;
|
|
40
43
|
export declare function encodeContext(context: Record<string, string | null | undefined>): Record<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* Sort an object defining query params alphabetically.
|
|
46
|
+
*/
|
|
47
|
+
export declare function sortQueryParams(obj: Record<string, string>): Record<string, string>;
|
|
48
|
+
export declare function getOrCreateClientCache(app: NuxtApp, config: AppConfig): GraphqlMiddlewareCache | undefined;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { CLIENT_CONTEXT_PREFIX } from "../settings/index.js";
|
|
2
|
+
import { GraphqlMiddlewareCache } from "./ClientCache.js";
|
|
3
|
+
import {
|
|
4
|
+
clientCacheEnabledAtBuild,
|
|
5
|
+
importMetaServer
|
|
6
|
+
} from "#nuxt-graphql-middleware/config";
|
|
2
7
|
export function encodeContext(context) {
|
|
3
8
|
return Object.entries(context).reduce(
|
|
4
9
|
(acc, [key, value]) => {
|
|
@@ -10,3 +15,25 @@ export function encodeContext(context) {
|
|
|
10
15
|
{}
|
|
11
16
|
);
|
|
12
17
|
}
|
|
18
|
+
export function sortQueryParams(obj) {
|
|
19
|
+
const sortedKeys = Object.keys(obj).sort();
|
|
20
|
+
const sortedObj = {};
|
|
21
|
+
for (const key of sortedKeys) {
|
|
22
|
+
sortedObj[key] = obj[key];
|
|
23
|
+
}
|
|
24
|
+
return sortedObj;
|
|
25
|
+
}
|
|
26
|
+
export function getOrCreateClientCache(app, config) {
|
|
27
|
+
if (importMetaServer || !clientCacheEnabledAtBuild) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!config.graphqlMiddleware.clientCacheEnabled) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!app.$graphqlCache) {
|
|
34
|
+
app.$graphqlCache = new GraphqlMiddlewareCache(
|
|
35
|
+
config.graphqlMiddleware.clientCacheMaxSize
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
return app.$graphqlCache;
|
|
39
|
+
}
|
|
@@ -5,7 +5,3 @@
|
|
|
5
5
|
* items.filter(falsy)
|
|
6
6
|
*/
|
|
7
7
|
export declare function falsy<T>(value: T): value is NonNullable<T>;
|
|
8
|
-
/**
|
|
9
|
-
* Get the parameters for the GraphQL middleware query.
|
|
10
|
-
*/
|
|
11
|
-
export declare function buildRequestParams(variables?: Record<string, any> | undefined | null): Record<string, any>;
|
|
@@ -1,16 +1,3 @@
|
|
|
1
1
|
export function falsy(value) {
|
|
2
2
|
return value !== null && value !== void 0;
|
|
3
3
|
}
|
|
4
|
-
export function buildRequestParams(variables) {
|
|
5
|
-
if (typeof variables !== "object" || !variables) {
|
|
6
|
-
return {};
|
|
7
|
-
}
|
|
8
|
-
for (const key in variables) {
|
|
9
|
-
if (typeof variables[key] !== "string") {
|
|
10
|
-
return {
|
|
11
|
-
__variables: JSON.stringify(variables)
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
return variables;
|
|
16
|
-
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function encodeVariables(variables?: Record<string, any> | null): Record<string, any>;
|
|
2
|
+
/**
|
|
3
|
+
* Get the variables from query parameters.
|
|
4
|
+
*
|
|
5
|
+
* For simple cases with type prefixes:
|
|
6
|
+
* ?name=Jon&n:age=20&b:isUser=false
|
|
7
|
+
*
|
|
8
|
+
* In complex cases, the entire variables are sent as a JSON encoded string:
|
|
9
|
+
* ?__variables=%7B%22foobar%22:%7B%22path%22:%22%22%7D%7D
|
|
10
|
+
*/
|
|
11
|
+
export declare function decodeVariables(query: Record<string, any>, validKeys?: string[]): any;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { experimentalQueryParamEncoding } from "#nuxt-graphql-middleware/config";
|
|
2
|
+
import { CLIENT_CONTEXT_PREFIX, OPERATION_HASH_PREFIX } from "../settings/index.js";
|
|
3
|
+
export function encodeVariables(variables) {
|
|
4
|
+
if (typeof variables !== "object" || !variables) {
|
|
5
|
+
return {};
|
|
6
|
+
}
|
|
7
|
+
if (!experimentalQueryParamEncoding) {
|
|
8
|
+
for (const key in variables) {
|
|
9
|
+
if (typeof variables[key] !== "string") {
|
|
10
|
+
return {
|
|
11
|
+
__variables: JSON.stringify(variables)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return variables;
|
|
16
|
+
}
|
|
17
|
+
const result = {};
|
|
18
|
+
let needsFallback = false;
|
|
19
|
+
for (const key in variables) {
|
|
20
|
+
const value = variables[key];
|
|
21
|
+
const type = typeof value;
|
|
22
|
+
if (type === "string") {
|
|
23
|
+
result[key] = value;
|
|
24
|
+
} else if (type === "number") {
|
|
25
|
+
result[`n:${key}`] = String(value);
|
|
26
|
+
} else if (type === "boolean") {
|
|
27
|
+
result[`b:${key}`] = String(value);
|
|
28
|
+
} else {
|
|
29
|
+
needsFallback = true;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (needsFallback) {
|
|
34
|
+
return {
|
|
35
|
+
__variables: JSON.stringify(variables)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
function filterValidKeys(validKeys, obj) {
|
|
41
|
+
return validKeys.reduce((acc, key) => {
|
|
42
|
+
const value = obj[key];
|
|
43
|
+
if (value !== void 0 && value !== null) {
|
|
44
|
+
acc[key] = value;
|
|
45
|
+
}
|
|
46
|
+
return acc;
|
|
47
|
+
}, {});
|
|
48
|
+
}
|
|
49
|
+
export function decodeVariables(query, validKeys) {
|
|
50
|
+
try {
|
|
51
|
+
if (query.__variables && typeof query.__variables === "string") {
|
|
52
|
+
return JSON.parse(query.__variables);
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
if (!experimentalQueryParamEncoding) {
|
|
57
|
+
if (validKeys) {
|
|
58
|
+
return filterValidKeys(validKeys, query);
|
|
59
|
+
}
|
|
60
|
+
return query;
|
|
61
|
+
}
|
|
62
|
+
if (validKeys && validKeys.length === 0) {
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
const result = {};
|
|
66
|
+
for (const key in query) {
|
|
67
|
+
if (key.startsWith(CLIENT_CONTEXT_PREFIX) || key.startsWith(OPERATION_HASH_PREFIX)) {
|
|
68
|
+
continue;
|
|
69
|
+
} else if (key.startsWith("n:")) {
|
|
70
|
+
const actualKey = key.substring(2);
|
|
71
|
+
if (validKeys && !validKeys.includes(actualKey)) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
result[actualKey] = Number(query[key]);
|
|
75
|
+
} else if (key.startsWith("b:")) {
|
|
76
|
+
const actualKey = key.substring(2);
|
|
77
|
+
if (validKeys && !validKeys.includes(actualKey)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
result[actualKey] = query[key] === "true";
|
|
81
|
+
} else if (key !== "__variables") {
|
|
82
|
+
if (validKeys && !validKeys.includes(key)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
result[key] = query[key];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineNuxtPlugin, useState } from "#imports";
|
|
2
2
|
import { createApp } from "vue";
|
|
3
3
|
import DevModeOverlay from "../components/DevModeOverlay.vue";
|
|
4
|
+
import { importMetaClient } from "#nuxt-graphql-middleware/config";
|
|
4
5
|
export default defineNuxtPlugin({
|
|
5
6
|
name: "nuxt-graphql-middleware:dev-mode",
|
|
6
7
|
setup(nuxtApp) {
|
|
@@ -11,7 +12,7 @@ export default defineNuxtPlugin({
|
|
|
11
12
|
nuxtApp.hook("nuxt-graphql-middleware:errors", (value) => {
|
|
12
13
|
errors.value.push(value);
|
|
13
14
|
});
|
|
14
|
-
if (
|
|
15
|
+
if (importMetaClient) {
|
|
15
16
|
nuxtApp.hook("app:mounted", () => {
|
|
16
17
|
const container = document.createElement("div");
|
|
17
18
|
document.body.appendChild(container);
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { defineEventHandler, getQuery, getRouterParam } from "h3";
|
|
2
|
-
import {
|
|
3
|
-
queryParamToVariables,
|
|
4
|
-
extractRequestContext,
|
|
5
|
-
isValidQuery,
|
|
6
|
-
throwError
|
|
7
|
-
} from "./../helpers/index.js";
|
|
2
|
+
import { extractRequestContext, isValidQuery, throwError } from "./../helpers/index.js";
|
|
8
3
|
import { GraphqlMiddlewareOperation } from "./../../settings/index.js";
|
|
9
4
|
import { documents } from "#nuxt-graphql-middleware/documents";
|
|
10
5
|
import { doGraphqlRequest } from "../utils/doGraphqlRequest.js";
|
|
6
|
+
import { decodeVariables } from "../../helpers/queryEncoding.js";
|
|
7
|
+
import { operationVariables } from "#nuxt-graphql-middleware/operation-variables";
|
|
11
8
|
export default defineEventHandler(async (event) => {
|
|
12
9
|
const operationName = getRouterParam(event, "name");
|
|
13
10
|
if (!isValidQuery(operationName)) {
|
|
@@ -16,7 +13,8 @@ export default defineEventHandler(async (event) => {
|
|
|
16
13
|
const operationDocument = documents.query[operationName];
|
|
17
14
|
const queryParams = getQuery(event);
|
|
18
15
|
const context = extractRequestContext(queryParams);
|
|
19
|
-
const
|
|
16
|
+
const validVariableKeys = operationVariables[operationName];
|
|
17
|
+
const variables = decodeVariables(queryParams, validVariableKeys);
|
|
20
18
|
return doGraphqlRequest(
|
|
21
19
|
{
|
|
22
20
|
query: operationDocument,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
encodeContext
|
|
3
3
|
} from "./../../helpers/composables.js";
|
|
4
|
-
import {
|
|
4
|
+
import { encodeVariables } from "./../../helpers/queryEncoding.js";
|
|
5
5
|
import { performRequest } from "./index.js";
|
|
6
6
|
export function useGraphqlQuery(...args) {
|
|
7
7
|
const [name, variables, fetchOptions = {}, clientContext = {}] = typeof args[0] === "string" ? [args[0], args[1], args[2]?.fetchOptions, args[2]?.clientContext] : [
|
|
@@ -14,7 +14,7 @@ export function useGraphqlQuery(...args) {
|
|
|
14
14
|
...fetchOptions,
|
|
15
15
|
params: {
|
|
16
16
|
...fetchOptions.params || {},
|
|
17
|
-
...
|
|
17
|
+
...encodeVariables(variables),
|
|
18
18
|
...encodeContext(clientContext)
|
|
19
19
|
}
|
|
20
20
|
});
|
|
@@ -169,15 +169,64 @@ interface ModuleOptions {
|
|
|
169
169
|
};
|
|
170
170
|
/**
|
|
171
171
|
* Enable Nuxt DevTools integration.
|
|
172
|
+
*
|
|
173
|
+
* @default true
|
|
172
174
|
*/
|
|
173
175
|
devtools?: boolean;
|
|
174
176
|
/**
|
|
175
177
|
* Client caching configuration.
|
|
176
178
|
*/
|
|
177
179
|
clientCache?: {
|
|
180
|
+
/**
|
|
181
|
+
* Whether client caching should be enabled.
|
|
182
|
+
*
|
|
183
|
+
* Note that if you set this to false during build, the cache will not be
|
|
184
|
+
* available at all. If you intend to enable/disable it using app config at
|
|
185
|
+
* runtime, it *must* be enabled at build!
|
|
186
|
+
*
|
|
187
|
+
* @default false
|
|
188
|
+
*/
|
|
178
189
|
enabled?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* The maximum number of cache entries.
|
|
192
|
+
*
|
|
193
|
+
* @default 100
|
|
194
|
+
*/
|
|
179
195
|
maxSize?: number;
|
|
180
196
|
};
|
|
197
|
+
/**
|
|
198
|
+
* Experimental features.
|
|
199
|
+
*/
|
|
200
|
+
experimental?: {
|
|
201
|
+
/**
|
|
202
|
+
* Enables improved encoding for GraphQL query param encoding.
|
|
203
|
+
*
|
|
204
|
+
* If enabled, query variables that are non-strings such as numbers or
|
|
205
|
+
* booleans are encoded as strings, with a prefix in their name to indicate
|
|
206
|
+
* the type.
|
|
207
|
+
*
|
|
208
|
+
* For example, given this object definining query variables:
|
|
209
|
+
*
|
|
210
|
+
* ```
|
|
211
|
+
* {
|
|
212
|
+
* name: 'John',
|
|
213
|
+
* age: 35,
|
|
214
|
+
* isUser: false
|
|
215
|
+
* }
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* This would be encoded as:
|
|
219
|
+
*
|
|
220
|
+
* ```
|
|
221
|
+
* name=John&n:age=35&b:isUser=false
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* This only works for flat primitive values. Nested objects or arrays are
|
|
225
|
+
* still encoded using the __variables fallback where all variables are
|
|
226
|
+
* JSON encoded.
|
|
227
|
+
*/
|
|
228
|
+
improvedQueryParamEncoding?: boolean;
|
|
229
|
+
};
|
|
181
230
|
}
|
|
182
231
|
|
|
183
232
|
declare const defaultOptions: ModuleOptions;
|