@graphql-yoga/plugin-persisted-operations
Version:
Persisted Operations plugin for GraphQL Yoga.
88 lines (87 loc) • 4.06 kB
JavaScript
import { createGraphQLError, } from 'graphql-yoga';
import { handleMaybePromise } from '@whatwg-node/promise-helpers';
export const defaultExtractPersistedOperationId = (params) => {
if (params.extensions != null &&
typeof params.extensions === 'object' &&
params.extensions?.['persistedQuery'] != null &&
typeof params.extensions?.['persistedQuery'] === 'object' &&
params.extensions?.['persistedQuery']?.['version'] === 1 &&
typeof params.extensions?.['persistedQuery']?.['sha256Hash'] === 'string') {
return params.extensions?.['persistedQuery']?.['sha256Hash'];
}
return null;
};
export function usePersistedOperations({ allowArbitraryOperations = false, extractPersistedOperationId = defaultExtractPersistedOperationId, getPersistedOperation, skipDocumentValidation = false, customErrors, }) {
const operationASTByRequest = new WeakMap();
const persistedOperationRequest = new WeakSet();
const notFoundErrorFactory = createErrorFactory('PersistedQueryNotFound', customErrors?.notFound);
const keyNotFoundErrorFactory = createErrorFactory('PersistedQueryKeyNotFound', customErrors?.keyNotFound);
const persistentQueryOnlyErrorFactory = createErrorFactory('PersistedQueryOnly', customErrors?.persistedQueryOnly);
return {
onParams(payload) {
const { request, params, setParams } = payload;
if (params.query) {
if (allowArbitraryOperations === false) {
throw persistentQueryOnlyErrorFactory(payload);
}
if (typeof allowArbitraryOperations === 'function') {
return handleMaybePromise(() => allowArbitraryOperations(request), result => {
if (!result) {
throw persistentQueryOnlyErrorFactory(payload);
}
});
}
return;
}
const persistedOperationKey = extractPersistedOperationId(params, request, payload.context);
if (persistedOperationKey == null) {
throw keyNotFoundErrorFactory(payload);
}
return handleMaybePromise(() => getPersistedOperation(persistedOperationKey, request, payload.context), persistedQuery => {
if (persistedQuery == null) {
throw notFoundErrorFactory(payload);
}
if (typeof persistedQuery === 'object') {
setParams({
query: `__PERSISTED_OPERATION_${persistedOperationKey}__`,
operationName: params.operationName,
variables: params.variables,
extensions: params.extensions,
});
operationASTByRequest.set(request, persistedQuery);
}
else {
setParams({
query: persistedQuery,
operationName: params.operationName,
variables: params.variables,
extensions: params.extensions,
});
}
persistedOperationRequest.add(request);
});
},
onValidate({ setResult, context: { request } }) {
if (skipDocumentValidation && persistedOperationRequest.has(request)) {
setResult([]); // skip validation
}
},
onParse({ setParsedDocument, context: { request } }) {
const ast = operationASTByRequest.get(request);
if (ast) {
setParsedDocument(ast);
}
},
};
}
function createErrorFactory(defaultMessage, options) {
if (typeof options === 'string') {
return () => createGraphQLError(options);
}
if (typeof options === 'function') {
return options;
}
return () => {
return createGraphQLError(options?.message ?? defaultMessage, options);
};
}