UNPKG

@graphql-yoga/plugin-apq

Version:
77 lines (76 loc) 2.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useAPQ = exports.createInMemoryAPQStore = exports.hashSHA256 = void 0; const graphql_yoga_1 = require("graphql-yoga"); const tiny_lru_1 = require("tiny-lru"); async function hashSHA256(str, api = globalThis) { const { crypto, TextEncoder } = api; const textEncoder = new TextEncoder(); const utf8 = textEncoder.encode(str); const hashBuffer = await crypto.subtle.digest('SHA-256', utf8); let hashHex = ''; for (const bytes of new Uint8Array(hashBuffer)) { hashHex += bytes.toString(16).padStart(2, '0'); } return hashHex; } exports.hashSHA256 = hashSHA256; function createInMemoryAPQStore(options = {}) { return (0, tiny_lru_1.lru)(options.max ?? 1000, options.ttl ?? 36000); } exports.createInMemoryAPQStore = createInMemoryAPQStore; function isAPQExtension(input) { return (input != null && typeof input === 'object' && 'version' in input && input?.version === 1 && 'sha256Hash' in input && typeof input?.sha256Hash === 'string'); } function decodeAPQExtension(input) { if (isAPQExtension(input)) { return input; } return null; } function useAPQ(options = {}) { const { store = createInMemoryAPQStore(), hash = hashSHA256 } = options; return { async onParams({ params, setParams, fetchAPI }) { const persistedQueryData = decodeAPQExtension(params.extensions?.persistedQuery); if (persistedQueryData === null) { return; } if (params.query == null) { const persistedQuery = await store.get(persistedQueryData.sha256Hash); if (persistedQuery == null) { throw (0, graphql_yoga_1.createGraphQLError)('PersistedQueryNotFound', { extensions: { http: { status: 404, }, }, }); } setParams({ ...params, query: persistedQuery, }); } else { const expectedHash = await hash(params.query, fetchAPI); if (persistedQueryData.sha256Hash !== expectedHash) { throw (0, graphql_yoga_1.createGraphQLError)('PersistedQueryMismatch', { extensions: { http: { status: 400, }, }, }); } await store.set(persistedQueryData.sha256Hash, params.query); } }, }; } exports.useAPQ = useAPQ;