import type { GraphQLParams } from "@benzene/core" ; import { sha256 } from "crypto-hash" ; import { ExecutionResult } from "graphql" ; import lru from "tiny-lru" ; import { HTTPError } from "./errors" ; import { KeyValueStore } from "./types" ; export function makeAPQHandler ( options ? ) { const cache = options ?. cache || lru ( 1024 ) ; return async function apq ( params ) : Promise < GraphQLParams | ExecutionResult > { if ( params . extensions ?. persistedQuery ?. version !== 1 ) { return params ; } const queryHash = params . extensions . persistedQuery . sha256Hash ; if ( ! params . query ) { const query = cache . get ( queryHash ) ; if ( ! query ) { return { errors : [ new HTTPError ( 200 , "PersistedQueryNotFound" , { code : "PERSISTED_QUERY_NOT_FOUND" , } ) , ] , } ; } return { ... params , query , } ; } const computedQueryHash = await sha256 ( params . query ) ; if ( computedQueryHash !== queryHash ) { return { errors : [ new HTTPError ( 400 , "provided sha does not match query" ) ] , } ; } cache . set ( queryHash , params . query ) ; return params ; } ; }