UNPKG

@graphprotocol/client-auto-pagination

Version:

`graph-client` implements automatic pagination using `first:` and `after:` filters of `graph-node`.

118 lines (117 loc) 5.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useAutoPagination = void 0; const tslib_1 = require("tslib"); const delegate_1 = require("@graphql-tools/delegate"); const graphql_1 = require("graphql"); const utils_1 = require("@graphql-tools/utils"); const lodash_1 = tslib_1.__importDefault(require("lodash")); const shared_js_1 = require("./shared.js"); const DEFAULTS = { if: true, validateSchema: true, ...shared_js_1.DEFAULT_OPTIONS, }; const validateSchema = (0, utils_1.memoize2)(function validateSchema(schema, config) { const queryType = schema.getQueryType(); if (queryType == null) { throw new Error(`Make sure you have a query type in this source before applying Block Tracking`); } const queryFields = queryType.getFields(); for (const fieldName in queryFields) { if (fieldName.startsWith('_')) { continue; } const field = queryFields[fieldName]; const nullableType = (0, graphql_1.isNonNullType)(field.type) ? field.type.ofType : field.type; if ((0, graphql_1.isListType)(nullableType)) { if (!field.args.some((arg) => arg.name === config.firstArgumentName)) { throw new Error(`Make sure you have a ${config.firstArgumentName} argument in the query field ${fieldName}`); } if (!field.args.some((arg) => arg.name === config.skipArgumentName)) { throw new Error(`Make sure you have a ${config.skipArgumentName} argument in the query field ${fieldName}`); } } } }); /* const getQueryFieldNames = memoize1(function getQueryFields(schema: GraphQLSchema) { const queryType = schema.getQueryType() if (queryType == null) { throw new Error(`Make sure you have a query type in this source before applying Block Tracking`) } return Object.keys(queryType.getFields()) }) */ class AutoPaginationTransform { constructor({ config } = {}) { this.config = { ...DEFAULTS, ...config }; if (this.config.if === false) { return {}; } } transformSchema(schema, subschemaConfig) { if (this.config.validateSchema) { validateSchema(subschemaConfig.schema, this.config); } if (schema != null) { const queryType = schema.getQueryType(); if (queryType != null) { const queryFields = queryType.getFields(); for (const fieldName in queryFields) { if (!fieldName.startsWith('_')) { const field = queryFields[fieldName]; const existingResolver = field.resolve; field.resolve = async (root, args, context, info) => { const totalRecords = args[this.config.firstArgumentName] || this.config.limitOfRecords; const initialSkipValue = args[this.config.skipArgumentName] || 0; if (totalRecords >= this.config.skipArgumentLimit * 2) { let remainingRecords = totalRecords; const records = []; while (remainingRecords > 0) { let skipValue = records.length === 0 ? initialSkipValue : 0; const lastIdValue = records.length > 0 ? records[records.length - 1].id : null; while (skipValue < this.config.skipArgumentLimit && remainingRecords > 0) { const newArgs = { ...args, }; if (lastIdValue) { lodash_1.default.set(newArgs, this.config.lastIdArgumentName, lastIdValue); } lodash_1.default.set(newArgs, this.config.skipArgumentName, skipValue); const askedRecords = Math.min(remainingRecords, this.config.skipArgumentLimit); lodash_1.default.set(newArgs, this.config.firstArgumentName, askedRecords); const result = await (0, delegate_1.delegateToSchema)({ schema, fieldName, args: newArgs, context, info, }); if (!Array.isArray(result)) { return result; } records.push(...result); skipValue += askedRecords; remainingRecords -= askedRecords; } } return records; } return existingResolver(root, args, context, info); }; } } } } return schema; } transformRequest(executionRequest, delegationContext) { return (0, shared_js_1.transformExecutionRequest)(executionRequest, this.config, delegationContext); } transformResult(originalResult) { return (0, shared_js_1.transformExecutionResponse)(originalResult); } } exports.default = AutoPaginationTransform; var plugin_js_1 = require("./plugin.js"); Object.defineProperty(exports, "useAutoPagination", { enumerable: true, get: function () { return plugin_js_1.useAutoPagination; } });