@graphql-box/connection-resolver 5.4.12 → 5.4.13
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/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/production.analysis.txt +56 -56
- package/dist/types/cjs/helpers/resolveConnection.d.cts +1 -3
- package/dist/types/cjs/helpers/resolveConnection.d.cts.map +1 -1
- package/dist/types/cjs/main/index.d.cts.map +1 -1
- package/dist/types/esm/helpers/resolveConnection.d.ts +1 -3
- package/dist/types/esm/helpers/resolveConnection.d.ts.map +1 -1
- package/dist/types/esm/main/index.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/helpers/resolveConnection.ts +0 -7
- package/src/main/index.ts +0 -3
package/dist/cjs/index.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";require("core-js/modules/es.set.difference.v2.js"),require("core-js/modules/es.set.intersection.v2.js"),require("core-js/modules/es.set.is-disjoint-from.v2.js"),require("core-js/modules/es.set.is-subset-of.v2.js"),require("core-js/modules/es.set.is-superset-of.v2.js"),require("core-js/modules/es.set.symmetric-difference.v2.js"),require("core-js/modules/es.set.union.v2.js");var e=require("lodash-es");require("core-js/modules/es.array.push.js");var r=require("graphql");const t=new Set(["after","before","first","last"]),a=async(e,{cursorCache:r,fieldPath:t,getters:a,groupCursor:s,makeIDCursor:o,resourceResolver:n,setCacheMetadata:u})=>{const
|
1
|
+
"use strict";require("core-js/modules/es.set.difference.v2.js"),require("core-js/modules/es.set.intersection.v2.js"),require("core-js/modules/es.set.is-disjoint-from.v2.js"),require("core-js/modules/es.set.is-subset-of.v2.js"),require("core-js/modules/es.set.is-superset-of.v2.js"),require("core-js/modules/es.set.symmetric-difference.v2.js"),require("core-js/modules/es.set.union.v2.js");var e=require("lodash-es");require("core-js/modules/es.array.push.js");var r=require("graphql");const t=new Set(["after","before","first","last"]),a=async(e,{cursorCache:r,fieldPath:t,getters:a,groupCursor:s,makeIDCursor:o,resourceResolver:n,setCacheMetadata:u})=>{const d=[],l=await Promise.all(e.map((async e=>{const{data:l,errors:c,headers:g}=await n({page:e});if(l&&u?.(t,g),l&&!c?.length){const t=(i=a.nodes(l),P=e=>o(e.id),i.map((e=>({cursor:P(e),node:e}))));return await(async(e,{edges:r,group:t,headers:a,page:s,totalPages:o,totalResults:n})=>{const u=a.get("cache-control"),d=u?{cacheHeaders:{cacheControl:u}}:void 0;await Promise.all(r.map((async({cursor:r,node:a},o)=>e.set(r,{group:t,index:o,node:a,page:s},d)))),await e.set(`${t}-metadata`,{totalPages:o,totalResults:n},d)})(r,{edges:t,group:s,headers:g,page:e,totalPages:a.totalPages(l),totalResults:a.totalResults(l)}),{edges:t,pageNumber:e}}var i,P;return c?.length&&d.push(...c),{edges:[],pageNumber:e}})));return{cachedEdges:l,errors:d}},s=e=>e.reduce(((e,r)=>[...e,...r.edges]),[]),o=e=>e.map((e=>e.node)),n=(e,{endIndex:r,resultsPerPage:t,startIndex:a})=>e.reduce(((s,o,n)=>{const u=(({pageIndex:e,startIndex:r})=>0===e?r.relative:0)({pageIndex:n,startIndex:a}),d=(({endIndex:e,pageIndex:r,resultsPerPage:t,totalCachedPages:a})=>r===a-1?e.relative:t-1)({endIndex:r,pageIndex:n,resultsPerPage:t,totalCachedPages:e.length}),l=o.edges.slice(u,d+1);return s.push({edges:l,pageNumber:o.pageNumber}),s}),[]),u=e=>e[0]?.cursor,d=e=>{const r=e.at(-1);return r?.cursor},l=e=>e?"backward":"forward",c=({page:e,totalPages:r})=>e===r,g=(r,{endIndex:t,entry:{page:a},metadata:s,resultsPerPage:o,startIndex:n})=>{const u=((e,{page:r,resultsPerPage:t,startIndex:a})=>{if("forward"===l(e.last)||a.absolute>=0)return r;const s=r-Math.ceil(Math.abs(a.absolute)/t);return Math.max(s,1)})(r,{page:a,resultsPerPage:o,startIndex:n}),d=((e,{endIndex:r,metadata:{totalPages:t},page:a,resultsPerPage:s})=>{const o=s-1;if("backward"===l(e.last)||c({page:a,totalPages:t})||r.absolute<=o)return a;const n=a+Math.ceil((r.absolute-o)/s);return Math.min(n,t)})(r,{endIndex:t,metadata:s,page:a,resultsPerPage:o});return u===d?[a]:[...e.range(u,d),d]},i=({first:e,last:r})=>e??r,P=({resultsPerPage:e,totalResults:r})=>(({resultsPerPage:e,totalResults:r})=>{const t=r%e;return 0===t?e:t})({resultsPerPage:e,totalResults:r})-1,h=({cachedEdgesByPage:r,startIndex:t})=>e.isNumber(r[0]?.pageNumber)&&1!==r[0]?.pageNumber||t.relative>0,p=({cachedEdgesByPage:r,endIndex:t,metadata:{totalPages:a,totalResults:s},resultsPerPage:o})=>e.isNumber(r.at(-1)?.pageNumber)&&r.at(-1)?.pageNumber!==a||t.relative<P({resultsPerPage:o,totalResults:s}),m=async(e,{groupCursor:r,pageNumber:t})=>{const{entries:a,metadata:s}=await e.export({filterByValue:[{comparator:t,keyChain:"page"},{comparator:r,keyChain:"group"}]});return{edges:a.reduce(((e,[r,{index:t,node:a}])=>(s[t]?.cacheability.checkTTL()&&(e[t]={cursor:r,node:a}),e)),[]),pageNumber:t}},f=({after:e,before:r})=>r??e,b=async(e,r,{cursorCache:t,resultsPerPage:a})=>{const s=f(e);if(s){const e=await t.get(s);if(e)return e}return((e,{metadata:{totalPages:r,totalResults:t},resultsPerPage:a})=>"backward"===l(e.last)?{index:P({resultsPerPage:a,totalResults:t})+1,page:r}:{index:-1,page:1})(e,{metadata:r,resultsPerPage:a})},C=async(e,{cursorCache:r,groupCursor:t,resultsPerPage:a})=>{const s=await r.get(`${t}-metadata`),o=await b(e,s,{cursorCache:r,resultsPerPage:a}),u=((e,{entry:{index:r,page:t},resultsPerPage:a})=>{const s=i(e);return"forward"===l(e.last)?{absolute:r+1,relative:r+1}:(e=>1===e)(t)&&r-s<0?{absolute:0,relative:0}:(()=>{const e=r-s;if(e>=0)return{absolute:e,relative:e};const o=Math.abs(e),n=o%a;return{absolute:e,relative:0===n||t-(o/a+1)<0?0:a-n}})()})(e,{entry:o,resultsPerPage:a}),d=((e,{entry:{index:r,page:t},metadata:{totalPages:a,totalResults:s},resultsPerPage:o})=>{const n=i(e),u=P({resultsPerPage:o,totalResults:s});return"backward"===l(e.last)?{absolute:r-1,relative:r-1}:c({page:t,totalPages:a})&&r+n>u?{absolute:u,relative:u}:(()=>{const e=r+n,s=o-1;if(e<=s)return{absolute:e,relative:e};const d=e-s,l=d%o;return{absolute:e,relative:0===l?s:t+d/o>a?u:l-1}})()})(e,{entry:o,metadata:s,resultsPerPage:a}),f=[],C=g(e,{endIndex:d,entry:o,metadata:s,resultsPerPage:a,startIndex:u});for(const e of C)f.push(m(r,{groupCursor:t,pageNumber:e}));const v=await Promise.all(f),w=(e=>e.reduce(((e,r)=>(0===r.edges.length&&e.push(r.pageNumber),e)),[]))(v);return{cachedEdges:0===w.length?n(v,{endIndex:d,resultsPerPage:a,startIndex:u}):v,hasNextPage:p({cachedEdgesByPage:v,endIndex:d,metadata:s,resultsPerPage:a}),hasPreviousPage:h({cachedEdgesByPage:v,startIndex:u}),indexes:{end:d,start:u},missingPages:w,totalResults:s.totalResults}},v=async(e,{cursorCache:r,fieldPath:t,getters:l,groupCursor:c,makeIDCursor:g,resourceResolver:i,resultsPerPage:P,setCacheMetadata:h})=>{const{cachedEdges:p,hasNextPage:m,hasPreviousPage:f,indexes:b,missingPages:v,totalResults:w}=await C(e,{cursorCache:r,groupCursor:c,resultsPerPage:P});if(0===v.length){const e=s(p);return{edges:e,errors:[],nodes:o(e),pageInfo:{endCursor:d(e),hasNextPage:m,hasPreviousPage:f,startCursor:u(e)},totalCount:w}}const{cachedEdges:x,errors:I}=await a(v,{cursorCache:r,fieldPath:t,getters:l,groupCursor:c,makeIDCursor:g,resourceResolver:i,setCacheMetadata:h}),y=n(((e,r)=>e.reduce(((e,t)=>{if(0===t.edges.length){const a=r.find((e=>e.pageNumber===t.pageNumber));if(a)return[...e,a]}return[...e,t]}),[]))(p,x),{endIndex:b.end,resultsPerPage:P,startIndex:b.start}),R=s(y);return{edges:R,errors:I,nodes:o(R),pageInfo:{endCursor:d(R),hasNextPage:m,hasPreviousPage:f,startCursor:u(R)},totalCount:w}},w=async({after:e,before:t,first:a,last:s},{fieldNodes:o},{cursorCache:n,groupCursor:u,resultsPerPage:d})=>{if(e&&!a&&!s)return new r.GraphQLError("Invalid connection argument combination. `after` must be used in combination with `first`.",{nodes:o});if(e&&s)return new r.GraphQLError("Invalid connection argument combination. `after` cannot be used in combination with `last`.",{nodes:o});if(t&&!s&&!a)return new r.GraphQLError("Invalid connection argument combination. `before` must be used in combination with `last`.",{nodes:o});if(t&&a)return new r.GraphQLError("Invalid connection argument combination. `before` cannot be used in combination with `first`.",{nodes:o});const c=await n.get(`${u}-metadata`);if(!c)return new r.GraphQLError("Curser cannot be supplied without previously being provided.",{nodes:o});const g=f({after:e,before:t});if(!g)return new r.GraphQLError("The cursor could not be found.",{nodes:o});const i=await n.get(g);if(!i)return new r.GraphQLError(`The cursor ${g} could not be found.`,{nodes:o});const h=l(s);return(({direction:e,entry:{index:r,page:t},resultsPerPage:a,totalPages:s,totalResults:o})=>"forward"===e&&t===s&&r===P({resultsPerPage:a,totalResults:o}))({direction:h,entry:i,resultsPerPage:d,...c})?new r.GraphQLError(`The cursor ${g} is the last, you cannot go forward any further.`,{nodes:o}):(({direction:e,entry:{index:r,page:t}})=>"backward"===e&&1===t&&0===r)({direction:h,entry:i})?new r.GraphQLError(`The cursor ${g} is the first, you cannot go backward any further.`,{nodes:o}):void 0};exports.makeConnectionResolver=({createMakeCursors:e,createResourceResolver:r,cursorCache:t,getters:s,resolver:o=(e=>e),resultsPerPage:n})=>async(u,d,l,c)=>{const{makeGroupCursor:g,makeIDCursor:i}=e(u,d,l,c),P=g(),{logger:h,setCacheMetadata:p}=l,{fieldName:m}=c,f={...l,data:{...l.data,args:d,fieldPath:m,groupCursor:P}},b=r(u,d,f,c),C=h?.child(f.data);if(C?.info(`Resolving ${m}`,{logEntryName:"RESOLVER_START"}),(({after:e,before:r})=>!!(e??r))(d)){const e=await w(d,c,{cursorCache:t,groupCursor:P,resultsPerPage:n});return e?(C?.error(`Failed to resolve ${m}, validation cursor error`,{errors:[e],logEntryName:"RESOLVER_FAILED"}),o({edges:[],errors:[e],nodes:[],pageInfo:{hasNextPage:!1,hasPreviousPage:!1},totalCount:0})):o(await v(d,{cursorCache:t,fieldPath:m,getters:s,groupCursor:P,makeIDCursor:i,resourceResolver:b,resultsPerPage:n,setCacheMetadata:p}))}return await t.has(`${P}-metadata`)||await a([1],{cursorCache:t,fieldPath:m,getters:s,groupCursor:P,makeIDCursor:i,resourceResolver:b,setCacheMetadata:p}),o(await v(d,{cursorCache:t,fieldPath:m,getters:s,groupCursor:P,makeIDCursor:i,resourceResolver:b,resultsPerPage:n,setCacheMetadata:p}))},exports.removeConnectionInputOptions=r=>e.pickBy(r,((e,r)=>!t.has(r)));
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/cjs/index.cjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../connection-resolver/src//helpers/removeConnectionInputOptions.ts","../connection-resolver/src//helpers/requestAndCachePages.ts","../connection-resolver/src//helpers/makeEdges.ts","../connection-resolver/src//helpers/cacheCursors.ts","../connection-resolver/src//helpers/extractEdges.ts","../connection-resolver/src//helpers/extractNodes.ts","../connection-resolver/src//helpers/getInRangeCachedEdges.ts","../connection-resolver/src//helpers/getCurrentPageStartAndEndIndexes.ts","../connection-resolver/src//helpers/getStartAndEndCursors.ts","../connection-resolver/src//helpers/getDirection.ts","../connection-resolver/src//helpers/isLastPage.ts","../connection-resolver/src//helpers/getPageNumbersToRequest.ts","../connection-resolver/src//helpers/getStartAndEndPageNumbers.ts","../connection-resolver/src//helpers/getCount.ts","../connection-resolver/src//helpers/getIndexesOnLastPage.ts","../connection-resolver/src//helpers/getResultsOnLastPage.ts","../connection-resolver/src//helpers/hasPreviousNextPage.ts","../connection-resolver/src//helpers/retrieveCachedEdgesByPage.ts","../connection-resolver/src//helpers/getCursor.ts","../connection-resolver/src//helpers/retrieveEntry.ts","../connection-resolver/src//helpers/makeEntry.ts","../connection-resolver/src//helpers/retrieveCachedConnection.ts","../connection-resolver/src//helpers/getStartAndEndIndexes.ts","../connection-resolver/src//helpers/isFirstPage.ts","../connection-resolver/src//helpers/getPagesMissingFromCache.ts","../connection-resolver/src//helpers/resolveConnection.ts","../connection-resolver/src//helpers/mergeCachedEdges.ts","../connection-resolver/src//helpers/validateCursor.ts","../connection-resolver/src//helpers/isCursorLast.ts","../connection-resolver/src//helpers/isCursorFirst.ts","../connection-resolver/src//main/index.ts","../connection-resolver/src//helpers/isCursorSupplied.ts"],"sourcesContent":["import { pickBy } from 'lodash-es';\n\nconst connectionInputOptions = new Set(['after', 'before', 'first', 'last']);\n\nexport const removeConnectionInputOptions = <O extends object>(args: O) =>\n pickBy(args, (_value, key) => !connectionInputOptions.has(key));\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport { type Getters, type Node, type ResourceResolver, type SetCacheMetadata } from '../types.ts';\nimport { cacheCursors } from './cacheCursors.ts';\nimport { makeEdges } from './makeEdges.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const requestAndCachePages = async <Resource extends PlainObject, ResourceNode extends Node>(\n pages: number[],\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const errors: Error[] = [];\n\n const cachedEdges = await Promise.all(\n pages.map(async page => {\n const {\n data: pageResultData,\n errors: pageResultErrors,\n headers: pageResultHeaders,\n } = await resourceResolver({\n page,\n });\n\n if (pageResultData) {\n setCacheMetadata?.(fieldPath, pageResultHeaders);\n }\n\n if (pageResultData && !pageResultErrors?.length) {\n const edges = makeEdges(getters.nodes(pageResultData), node => makeIDCursor(node.id));\n\n await cacheCursors(cursorCache, {\n edges,\n group: groupCursor,\n headers: pageResultHeaders,\n page,\n totalPages: getters.totalPages(pageResultData),\n totalResults: getters.totalResults(pageResultData),\n });\n\n return { edges, pageNumber: page };\n }\n\n if (pageResultErrors?.length) {\n errors.push(...pageResultErrors);\n }\n\n return { edges: [], pageNumber: page };\n }),\n );\n\n return { cachedEdges, errors };\n};\n","import { type Node } from '../types.ts';\n\nexport const makeEdges = (nodes: Node[], makeCursor: (node: Node) => string) =>\n nodes.map(node => ({ cursor: makeCursor(node), node }));\n","import { type Core } from '@cachemap/core';\nimport { type Edge } from '../types.ts';\n\nexport type Params = {\n edges: Edge[];\n group: string;\n headers: Headers;\n page: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const cacheCursors = async (\n cursorCache: Core,\n { edges, group, headers, page, totalPages, totalResults }: Params,\n) => {\n const cacheControl = headers.get('cache-control');\n const options = cacheControl ? { cacheHeaders: { cacheControl } } : undefined;\n\n await Promise.all(\n edges.map(async ({ cursor, node }, index) => cursorCache.set(cursor, { group, index, node, page }, options)),\n );\n\n await cursorCache.set(`${group}-metadata`, { totalPages, totalResults }, options);\n};\n","import { type CachedEdges, type Edge } from '../types.ts';\n\nexport const extractEdges = (cachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<Edge[]>((edges, cachedEdge) => [...edges, ...cachedEdge.edges], []);\n","import { type Edge } from '../types.ts';\n\nexport const extractNodes = (edges: Edge[]) => edges.map(edge => edge.node);\n","import { type CachedEdges, type Indexes } from '../types.ts';\nimport { getCurrentPageEndIndex, getCurrentPageStartIndex } from './getCurrentPageStartAndEndIndexes.ts';\n\nexport type Context = {\n endIndex: Indexes;\n resultsPerPage: number;\n startIndex: Indexes;\n};\n\nexport const getInRangeCachedEdges = (\n cachedEdgesByPage: CachedEdges[],\n { endIndex, resultsPerPage, startIndex }: Context,\n) => {\n return cachedEdgesByPage.reduce<CachedEdges[]>((inRange, cachedEdgesPage, index) => {\n const currentPageStartIndex = getCurrentPageStartIndex({ pageIndex: index, startIndex });\n\n const currentPageEndIndex = getCurrentPageEndIndex({\n endIndex,\n pageIndex: index,\n resultsPerPage,\n totalCachedPages: cachedEdgesByPage.length,\n });\n\n const cachedEdges = cachedEdgesPage.edges.slice(currentPageStartIndex, currentPageEndIndex + 1);\n inRange.push({ edges: cachedEdges, pageNumber: cachedEdgesPage.pageNumber });\n return inRange;\n }, []);\n};\n","import { type Indexes } from '../types.ts';\n\nexport type StartIndexContext = {\n pageIndex: number;\n startIndex: Indexes;\n};\n\nexport const getCurrentPageStartIndex = ({ pageIndex, startIndex }: StartIndexContext) =>\n pageIndex === 0 ? startIndex.relative : 0;\n\nexport type EndIndexContext = {\n endIndex: Indexes;\n pageIndex: number;\n resultsPerPage: number;\n totalCachedPages: number;\n};\n\nexport const getCurrentPageEndIndex = ({ endIndex, pageIndex, resultsPerPage, totalCachedPages }: EndIndexContext) =>\n pageIndex === totalCachedPages - 1 ? endIndex.relative : resultsPerPage - 1;\n","import { type Edge } from '../types.ts';\n\nexport const getStartCursor = (edges: Edge[]) => edges[0]?.cursor;\n\nexport const getEndCursor = (edges: Edge[]) => {\n const lastEdge = edges.at(-1);\n return lastEdge?.cursor;\n};\n","import { type Direction } from '../types.ts';\n\nexport const getDirection = (last?: number): Direction => (last ? 'backward' : 'forward');\n","export type Params = {\n page: number;\n totalPages: number;\n};\n\nexport const isLastPage = ({ page, totalPages }: Params) => page === totalPages;\n","import { range } from 'lodash-es';\nimport {\n type ConnectionInputOptions,\n type CursorGroupMetadata,\n type Indexes,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getEndPageNumber, getStartPageNumber } from './getStartAndEndPageNumbers.ts';\n\nexport type GetPageNumbersToRequestContext = {\n endIndex: Indexes;\n startIndex: Indexes;\n};\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getPageNumbersToRequest = (\n args: ConnectionInputOptions,\n { endIndex, entry: { page }, metadata, resultsPerPage, startIndex }: GetPageNumbersToRequestContext & Context,\n) => {\n const startPageNumber = getStartPageNumber(args, { page, resultsPerPage, startIndex });\n const endPageNumber = getEndPageNumber(args, { endIndex, metadata, page, resultsPerPage });\n\n if (startPageNumber === endPageNumber) {\n return [page];\n }\n\n return [...range(startPageNumber, endPageNumber), endPageNumber];\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type PageNumberContext = {\n endIndex: Indexes;\n page: number;\n startIndex: Indexes;\n};\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartPageNumber = (\n args: ConnectionInputOptions,\n { page, resultsPerPage, startIndex }: Omit<PageNumberContext, 'endIndex'> & Omit<Context, 'metadata'>,\n) => {\n if (getDirection(args.last) === 'forward' || startIndex.absolute >= 0) {\n return page;\n }\n\n const startPageNumber = page - Math.ceil(Math.abs(startIndex.absolute) / resultsPerPage);\n return Math.max(startPageNumber, 1);\n};\n\nexport const getEndPageNumber = (\n args: ConnectionInputOptions,\n { endIndex, metadata: { totalPages }, page, resultsPerPage }: Omit<PageNumberContext, 'startIndex'> & Context,\n) => {\n const indexesPerPage = resultsPerPage - 1;\n\n if (\n getDirection(args.last) === 'backward' ||\n isLastPage({ page, totalPages }) ||\n endIndex.absolute <= indexesPerPage\n ) {\n return page;\n }\n\n const endPageNumber = page + Math.ceil((endIndex.absolute - indexesPerPage) / resultsPerPage);\n return Math.min(endPageNumber, totalPages);\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\n// Based on how ConnectionInputOptions are generated, either first\n// or last would be set.\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nexport const getCount = ({ first, last }: ConnectionInputOptions) => first ?? last!;\n","import { type Params, getResultsOnLastPage } from './getResultsOnLastPage.ts';\n\nexport const getIndexesOnLastPage = ({ resultsPerPage, totalResults }: Params) =>\n getResultsOnLastPage({ resultsPerPage, totalResults }) - 1;\n","export type Params = {\n resultsPerPage: number;\n totalResults: number;\n};\n\nexport const getResultsOnLastPage = ({ resultsPerPage, totalResults }: Params) => {\n const remainder = totalResults % resultsPerPage;\n return remainder === 0 ? resultsPerPage : remainder;\n};\n","import { isNumber } from 'lodash-es';\nimport { type CachedEdges, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type HasPreviousPageParams = {\n cachedEdgesByPage: CachedEdges[];\n startIndex: Indexes;\n};\n\nexport type HasNextPageParams = {\n cachedEdgesByPage: CachedEdges[];\n endIndex: Indexes;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const hasPreviousPage = ({ cachedEdgesByPage, startIndex }: HasPreviousPageParams) =>\n (isNumber(cachedEdgesByPage[0]?.pageNumber) && cachedEdgesByPage[0]?.pageNumber !== 1) || startIndex.relative > 0;\n\nexport const hasNextPage = ({\n cachedEdgesByPage,\n endIndex,\n metadata: { totalPages, totalResults },\n resultsPerPage,\n}: HasNextPageParams) =>\n (isNumber(cachedEdgesByPage.at(-1)?.pageNumber) && cachedEdgesByPage.at(-1)?.pageNumber !== totalPages) ||\n endIndex.relative < getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type Core } from '@cachemap/core';\nimport { type CursorCacheEntry, type Edge } from '../types.ts';\n\nexport type Context = {\n groupCursor: string;\n pageNumber: number;\n};\n\nexport const retrieveCachedEdgesByPage = async (cursorCache: Core, { groupCursor, pageNumber }: Context) => {\n const { entries, metadata } = await cursorCache.export<CursorCacheEntry>({\n filterByValue: [\n { comparator: pageNumber, keyChain: 'page' },\n { comparator: groupCursor, keyChain: 'group' },\n ],\n });\n\n return {\n edges: entries.reduce<Edge[]>((cached, [key, { index, node }]) => {\n if (metadata[index]?.cacheability.checkTTL()) {\n cached[index] = { cursor: key, node };\n }\n\n return cached;\n }, []),\n pageNumber,\n };\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\nexport const getCursor = ({ after, before }: ConnectionInputOptions) => before ?? after;\n","import { type Core } from '@cachemap/core';\nimport {\n type ConnectionInputOptions,\n type CursorCacheEntry,\n type CursorGroupMetadata,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { makeEntry } from './makeEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n resultsPerPage: number;\n};\n\nexport const retrieveEntry = async (\n args: ConnectionInputOptions,\n metadata: CursorGroupMetadata,\n { cursorCache, resultsPerPage }: Context,\n): Promise<PartialCursorCacheEntry> => {\n const cursor = getCursor(args);\n\n if (cursor) {\n const cursorCacheEntry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (cursorCacheEntry) {\n return cursorCacheEntry;\n }\n }\n\n return makeEntry(args, { metadata, resultsPerPage });\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const makeEntry = (\n args: ConnectionInputOptions,\n { metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n if (getDirection(args.last) === 'backward') {\n return { index: getIndexesOnLastPage({ resultsPerPage, totalResults }) + 1, page: totalPages };\n }\n\n return { index: -1, page: 1 };\n};\n","import { type Core } from '@cachemap/core';\nimport { type CachedEdges, type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getPageNumbersToRequest } from './getPageNumbersToRequest.ts';\nimport { getPagesMissingFromCache } from './getPagesMissingFromCache.ts';\nimport { getEndIndex, getStartIndex } from './getStartAndEndIndexes.ts';\nimport { hasNextPage, hasPreviousPage } from './hasPreviousNextPage.ts';\nimport { retrieveCachedEdgesByPage } from './retrieveCachedEdgesByPage.ts';\nimport { retrieveEntry } from './retrieveEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const retrieveCachedConnection = async (\n args: ConnectionInputOptions,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n // At this point the cache will always have metadata because `retrieveCachedConnection`\n // is called from `resolveConnection` and is only called if there is a cursor, either\n // after a direct check or after calling `validateCursor` or `requestAndCachePages`,\n // which check and set the metadata respectively.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const metadata = (await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`))!;\n const entry = await retrieveEntry(args, metadata, { cursorCache, resultsPerPage });\n const startIndex = getStartIndex(args, { entry, resultsPerPage });\n const endIndex = getEndIndex(args, { entry, metadata, resultsPerPage });\n const promises: Promise<CachedEdges>[] = [];\n const pageNumbersToRequest = getPageNumbersToRequest(args, { endIndex, entry, metadata, resultsPerPage, startIndex });\n\n for (const pageNumber of pageNumbersToRequest) {\n promises.push(retrieveCachedEdgesByPage(cursorCache, { groupCursor, pageNumber }));\n }\n\n const cachedEdgesByPage = await Promise.all(promises);\n const missingPages = getPagesMissingFromCache(cachedEdgesByPage);\n\n return {\n cachedEdges:\n missingPages.length === 0\n ? getInRangeCachedEdges(cachedEdgesByPage, { endIndex, resultsPerPage, startIndex })\n : cachedEdgesByPage,\n hasNextPage: hasNextPage({\n cachedEdgesByPage,\n endIndex,\n metadata,\n resultsPerPage,\n }),\n hasPreviousPage: hasPreviousPage({ cachedEdgesByPage, startIndex }),\n indexes: { end: endIndex, start: startIndex },\n missingPages,\n totalResults: metadata.totalResults,\n };\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type PartialCursorCacheEntry } from '../types.ts';\nimport { getCount } from './getCount.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\nimport { isFirstPage } from './isFirstPage.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, resultsPerPage }: Pick<Context, 'entry' | 'resultsPerPage'>,\n) => {\n const count = getCount(args);\n\n return getDirection(args.last) === 'forward'\n ? { absolute: index + 1, relative: index + 1 }\n : isFirstPage(page) && index - count < 0\n ? { absolute: 0, relative: 0 }\n : (() => {\n const absoluteStartIndex = index - count;\n\n if (absoluteStartIndex >= 0) {\n return { absolute: absoluteStartIndex, relative: absoluteStartIndex };\n }\n\n const indexesRemainingAfterLastPage = Math.abs(absoluteStartIndex);\n const pagesRemaining = indexesRemainingAfterLastPage / resultsPerPage + 1;\n const remainder = indexesRemainingAfterLastPage % resultsPerPage;\n const relativeStartIndex = remainder === 0 ? 0 : page - pagesRemaining < 0 ? 0 : resultsPerPage - remainder;\n return { absolute: absoluteStartIndex, relative: relativeStartIndex };\n })();\n};\n\nexport const getEndIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n const count = getCount(args);\n const indexesOnLastPage = getIndexesOnLastPage({ resultsPerPage, totalResults });\n\n return getDirection(args.last) === 'backward'\n ? { absolute: index - 1, relative: index - 1 }\n : isLastPage({ page, totalPages }) && index + count > indexesOnLastPage\n ? { absolute: indexesOnLastPage, relative: indexesOnLastPage }\n : (() => {\n const absoluteEndIndex = index + count;\n const indexesPerPage = resultsPerPage - 1;\n\n if (absoluteEndIndex <= indexesPerPage) {\n return { absolute: absoluteEndIndex, relative: absoluteEndIndex };\n }\n\n const indexesRemainingAfterFirstPage = absoluteEndIndex - indexesPerPage;\n const pagesRemaining = indexesRemainingAfterFirstPage / resultsPerPage;\n const remainder = indexesRemainingAfterFirstPage % resultsPerPage;\n\n const relativeEndIndex =\n remainder === 0 ? indexesPerPage : page + pagesRemaining > totalPages ? indexesOnLastPage : remainder - 1;\n\n return { absolute: absoluteEndIndex, relative: relativeEndIndex };\n })();\n};\n","export const isFirstPage = (page: number) => page === 1;\n","import { type CachedEdges } from '../types.ts';\n\nexport const getPagesMissingFromCache = (cachedEdgesByPage: CachedEdges[]) => {\n return cachedEdgesByPage.reduce<number[]>((missing, cachedEdgesPage) => {\n if (cachedEdgesPage.edges.length === 0) {\n missing.push(cachedEdgesPage.pageNumber);\n }\n\n return missing;\n }, []);\n};\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport { type Logger } from 'winston';\nimport {\n type ConnectionInputOptions,\n type Getters,\n type Node,\n type ResourceResolver,\n type SetCacheMetadata,\n} from '../types.ts';\nimport { extractEdges } from './extractEdges.ts';\nimport { extractNodes } from './extractNodes.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getEndCursor, getStartCursor } from './getStartAndEndCursors.ts';\nimport { mergeCachedEdges } from './mergeCachedEdges.ts';\nimport { requestAndCachePages } from './requestAndCachePages.ts';\nimport { retrieveCachedConnection } from './retrieveCachedConnection.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n logger: Logger | undefined;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n resultsPerPage: number;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const resolveConnection = async <Resource extends PlainObject, ResourceNode extends Node>(\n args: PlainObject & ConnectionInputOptions,\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const { cachedEdges, hasNextPage, hasPreviousPage, indexes, missingPages, totalResults } =\n await retrieveCachedConnection(args, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (missingPages.length === 0) {\n const edges = extractEdges(cachedEdges);\n\n logger?.info(`CACHE HIT: Connection resolver cache has data to resolve ${fieldPath}`, {\n logEntryName: 'RESOLVER_RESPONSE_FROM_CACHE',\n });\n\n return {\n edges,\n errors: [],\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n }\n\n const { cachedEdges: missingCachedEdges, errors } = await requestAndCachePages<Resource, ResourceNode>(missingPages, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n const mergedCachedEdges = getInRangeCachedEdges(mergeCachedEdges(cachedEdges, missingCachedEdges), {\n endIndex: indexes.end,\n resultsPerPage,\n startIndex: indexes.start,\n });\n\n const edges = extractEdges(mergedCachedEdges);\n\n return {\n edges,\n errors,\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n};\n","import { type CachedEdges } from '../types.ts';\n\nexport const mergeCachedEdges = (cachedEdges: CachedEdges[], missingCachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<CachedEdges[]>((mergedCachedEdges, cachedEdge) => {\n if (cachedEdge.edges.length === 0) {\n const missingCachedEdge = missingCachedEdges.find(missing => missing.pageNumber === cachedEdge.pageNumber);\n\n if (missingCachedEdge) {\n return [...mergedCachedEdges, missingCachedEdge];\n }\n }\n\n return [...mergedCachedEdges, cachedEdge];\n }, []);\n","import { type Core } from '@cachemap/core';\nimport { GraphQLError, type GraphQLResolveInfo } from 'graphql';\nimport { type ConnectionInputOptions, type CursorCacheEntry, type CursorGroupMetadata } from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isCursorFirst } from './isCursorFirst.ts';\nimport { isCursorLast } from './isCursorLast.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const validateCursor = async (\n { after, before, first, last }: ConnectionInputOptions,\n { fieldNodes }: GraphQLResolveInfo,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n if (after && !first && !last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` must be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n if (after && last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` cannot be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && !last && !first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` must be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` cannot be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n const metadata = await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`);\n\n if (!metadata) {\n return new GraphQLError('Curser cannot be supplied without previously being provided.', { nodes: fieldNodes });\n }\n\n const cursor = getCursor({ after, before });\n\n if (!cursor) {\n return new GraphQLError(`The cursor could not be found.`, { nodes: fieldNodes });\n }\n\n const entry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (!entry) {\n return new GraphQLError(`The cursor ${cursor} could not be found.`, { nodes: fieldNodes });\n }\n\n const direction = getDirection(last);\n\n if (isCursorLast({ direction, entry, resultsPerPage, ...metadata })) {\n return new GraphQLError(`The cursor ${cursor} is the last, you cannot go forward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n if (isCursorFirst({ direction, entry })) {\n return new GraphQLError(`The cursor ${cursor} is the first, you cannot go backward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n return;\n};\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n resultsPerPage: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const isCursorLast = ({ direction, entry: { index, page }, resultsPerPage, totalPages, totalResults }: Params) =>\n direction === 'forward' && page === totalPages && index === getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n};\n\nexport const isCursorFirst = ({ direction, entry: { index, page } }: Params) =>\n direction === 'backward' && page === 1 && index === 0;\n","import { type PlainObject } from '@graphql-box/core';\nimport { type GraphQLResolveInfo } from 'graphql';\nimport { isCursorSupplied } from '../helpers/isCursorSupplied.ts';\nimport { requestAndCachePages } from '../helpers/requestAndCachePages.ts';\nimport { resolveConnection } from '../helpers/resolveConnection.ts';\nimport { validateCursor } from '../helpers/validateCursor.ts';\nimport {\n type Connection,\n type ConnectionInputOptions,\n type ConnectionResolverUserOptions,\n type Context,\n type Node,\n} from '../types.ts';\n\nexport const makeConnectionResolver =\n <\n Source extends PlainObject | undefined,\n Args extends PlainObject,\n Ctx extends Context,\n Resource extends PlainObject,\n ResourceNode extends Node,\n >({\n createMakeCursors,\n createResourceResolver,\n cursorCache,\n getters,\n resolver = result => result,\n resultsPerPage,\n }: ConnectionResolverUserOptions<Source, Args, Ctx, Resource, ResourceNode>) =>\n async (\n source: Source,\n args: Args & ConnectionInputOptions,\n context: Ctx,\n info: GraphQLResolveInfo,\n ): Promise<Connection> => {\n const { makeGroupCursor, makeIDCursor } = createMakeCursors(source, args, context, info);\n const groupCursor = makeGroupCursor();\n const { logger, setCacheMetadata } = context;\n const { fieldName: fieldPath } = info;\n\n const newCtx = {\n ...context,\n data: {\n ...context.data,\n args,\n fieldPath,\n groupCursor,\n },\n };\n\n const resourceResolver = createResourceResolver(source, args, newCtx, info);\n const childLogger = logger?.child(newCtx.data);\n childLogger?.info(`Resolving ${fieldPath}`, { logEntryName: 'RESOLVER_START' });\n\n if (isCursorSupplied(args)) {\n const cursorError = await validateCursor(args, info, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (cursorError) {\n childLogger?.error(`Failed to resolve ${fieldPath}, validation cursor error`, {\n errors: [cursorError],\n logEntryName: 'RESOLVER_FAILED',\n });\n\n return resolver({\n edges: [],\n errors: [cursorError],\n nodes: [],\n pageInfo: {\n hasNextPage: false,\n hasPreviousPage: false,\n },\n totalCount: 0,\n });\n }\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger: childLogger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n if (await cursorCache.has(`${groupCursor}-metadata`)) {\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger: childLogger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n await requestAndCachePages<Resource, ResourceNode>([1], {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger: childLogger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n };\n","import { type PlainObject } from '@graphql-box/core';\nimport { type ConnectionInputOptions } from '../types.ts';\n\nexport const isCursorSupplied = ({ after, before }: PlainObject & ConnectionInputOptions) => !!(after ?? before);\n"],"names":["connectionInputOptions","Set","requestAndCachePages","async","pages","cursorCache","fieldPath","getters","groupCursor","makeIDCursor","resourceResolver","setCacheMetadata","errors","cachedEdges","Promise","all","map","page","data","pageResultData","pageResultErrors","headers","pageResultHeaders","length","edges","nodes","makeCursor","node","id","cursor","group","totalPages","totalResults","cacheControl","get","options","cacheHeaders","undefined","index","set","cacheCursors","pageNumber","push","extractEdges","reduce","cachedEdge","extractNodes","edge","getInRangeCachedEdges","cachedEdgesByPage","endIndex","resultsPerPage","startIndex","inRange","cachedEdgesPage","currentPageStartIndex","pageIndex","relative","getCurrentPageStartIndex","currentPageEndIndex","totalCachedPages","getCurrentPageEndIndex","slice","getStartCursor","getEndCursor","lastEdge","at","getDirection","last","isLastPage","getPageNumbersToRequest","args","entry","metadata","startPageNumber","absolute","Math","ceil","abs","max","getStartPageNumber","endPageNumber","indexesPerPage","min","getEndPageNumber","range","getCount","first","getIndexesOnLastPage","remainder","getResultsOnLastPage","hasPreviousPage","isNumber","hasNextPage","retrieveCachedEdgesByPage","entries","export","filterByValue","comparator","keyChain","cached","key","cacheability","checkTTL","getCursor","after","before","retrieveEntry","cursorCacheEntry","makeEntry","retrieveCachedConnection","count","isFirstPage","absoluteStartIndex","indexesRemainingAfterLastPage","getStartIndex","indexesOnLastPage","absoluteEndIndex","indexesRemainingAfterFirstPage","getEndIndex","promises","pageNumbersToRequest","missingPages","missing","getPagesMissingFromCache","indexes","end","start","resolveConnection","logger","info","logEntryName","pageInfo","endCursor","startCursor","totalCount","missingCachedEdges","mergedCachedEdges","missingCachedEdge","find","mergeCachedEdges","validateCursor","fieldNodes","GraphQLError","direction","isCursorLast","isCursorFirst","createMakeCursors","createResourceResolver","resolver","result","source","context","makeGroupCursor","fieldName","newCtx","childLogger","child","isCursorSupplied","cursorError","error","has","pickBy","_value"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../connection-resolver/src//helpers/removeConnectionInputOptions.ts","../connection-resolver/src//helpers/requestAndCachePages.ts","../connection-resolver/src//helpers/makeEdges.ts","../connection-resolver/src//helpers/cacheCursors.ts","../connection-resolver/src//helpers/extractEdges.ts","../connection-resolver/src//helpers/extractNodes.ts","../connection-resolver/src//helpers/getInRangeCachedEdges.ts","../connection-resolver/src//helpers/getCurrentPageStartAndEndIndexes.ts","../connection-resolver/src//helpers/getStartAndEndCursors.ts","../connection-resolver/src//helpers/getDirection.ts","../connection-resolver/src//helpers/isLastPage.ts","../connection-resolver/src//helpers/getPageNumbersToRequest.ts","../connection-resolver/src//helpers/getStartAndEndPageNumbers.ts","../connection-resolver/src//helpers/getCount.ts","../connection-resolver/src//helpers/getIndexesOnLastPage.ts","../connection-resolver/src//helpers/getResultsOnLastPage.ts","../connection-resolver/src//helpers/hasPreviousNextPage.ts","../connection-resolver/src//helpers/retrieveCachedEdgesByPage.ts","../connection-resolver/src//helpers/getCursor.ts","../connection-resolver/src//helpers/retrieveEntry.ts","../connection-resolver/src//helpers/makeEntry.ts","../connection-resolver/src//helpers/retrieveCachedConnection.ts","../connection-resolver/src//helpers/getStartAndEndIndexes.ts","../connection-resolver/src//helpers/isFirstPage.ts","../connection-resolver/src//helpers/getPagesMissingFromCache.ts","../connection-resolver/src//helpers/resolveConnection.ts","../connection-resolver/src//helpers/mergeCachedEdges.ts","../connection-resolver/src//helpers/validateCursor.ts","../connection-resolver/src//helpers/isCursorLast.ts","../connection-resolver/src//helpers/isCursorFirst.ts","../connection-resolver/src//main/index.ts","../connection-resolver/src//helpers/isCursorSupplied.ts"],"sourcesContent":["import { pickBy } from 'lodash-es';\n\nconst connectionInputOptions = new Set(['after', 'before', 'first', 'last']);\n\nexport const removeConnectionInputOptions = <O extends object>(args: O) =>\n pickBy(args, (_value, key) => !connectionInputOptions.has(key));\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport { type Getters, type Node, type ResourceResolver, type SetCacheMetadata } from '../types.ts';\nimport { cacheCursors } from './cacheCursors.ts';\nimport { makeEdges } from './makeEdges.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const requestAndCachePages = async <Resource extends PlainObject, ResourceNode extends Node>(\n pages: number[],\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const errors: Error[] = [];\n\n const cachedEdges = await Promise.all(\n pages.map(async page => {\n const {\n data: pageResultData,\n errors: pageResultErrors,\n headers: pageResultHeaders,\n } = await resourceResolver({\n page,\n });\n\n if (pageResultData) {\n setCacheMetadata?.(fieldPath, pageResultHeaders);\n }\n\n if (pageResultData && !pageResultErrors?.length) {\n const edges = makeEdges(getters.nodes(pageResultData), node => makeIDCursor(node.id));\n\n await cacheCursors(cursorCache, {\n edges,\n group: groupCursor,\n headers: pageResultHeaders,\n page,\n totalPages: getters.totalPages(pageResultData),\n totalResults: getters.totalResults(pageResultData),\n });\n\n return { edges, pageNumber: page };\n }\n\n if (pageResultErrors?.length) {\n errors.push(...pageResultErrors);\n }\n\n return { edges: [], pageNumber: page };\n }),\n );\n\n return { cachedEdges, errors };\n};\n","import { type Node } from '../types.ts';\n\nexport const makeEdges = (nodes: Node[], makeCursor: (node: Node) => string) =>\n nodes.map(node => ({ cursor: makeCursor(node), node }));\n","import { type Core } from '@cachemap/core';\nimport { type Edge } from '../types.ts';\n\nexport type Params = {\n edges: Edge[];\n group: string;\n headers: Headers;\n page: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const cacheCursors = async (\n cursorCache: Core,\n { edges, group, headers, page, totalPages, totalResults }: Params,\n) => {\n const cacheControl = headers.get('cache-control');\n const options = cacheControl ? { cacheHeaders: { cacheControl } } : undefined;\n\n await Promise.all(\n edges.map(async ({ cursor, node }, index) => cursorCache.set(cursor, { group, index, node, page }, options)),\n );\n\n await cursorCache.set(`${group}-metadata`, { totalPages, totalResults }, options);\n};\n","import { type CachedEdges, type Edge } from '../types.ts';\n\nexport const extractEdges = (cachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<Edge[]>((edges, cachedEdge) => [...edges, ...cachedEdge.edges], []);\n","import { type Edge } from '../types.ts';\n\nexport const extractNodes = (edges: Edge[]) => edges.map(edge => edge.node);\n","import { type CachedEdges, type Indexes } from '../types.ts';\nimport { getCurrentPageEndIndex, getCurrentPageStartIndex } from './getCurrentPageStartAndEndIndexes.ts';\n\nexport type Context = {\n endIndex: Indexes;\n resultsPerPage: number;\n startIndex: Indexes;\n};\n\nexport const getInRangeCachedEdges = (\n cachedEdgesByPage: CachedEdges[],\n { endIndex, resultsPerPage, startIndex }: Context,\n) => {\n return cachedEdgesByPage.reduce<CachedEdges[]>((inRange, cachedEdgesPage, index) => {\n const currentPageStartIndex = getCurrentPageStartIndex({ pageIndex: index, startIndex });\n\n const currentPageEndIndex = getCurrentPageEndIndex({\n endIndex,\n pageIndex: index,\n resultsPerPage,\n totalCachedPages: cachedEdgesByPage.length,\n });\n\n const cachedEdges = cachedEdgesPage.edges.slice(currentPageStartIndex, currentPageEndIndex + 1);\n inRange.push({ edges: cachedEdges, pageNumber: cachedEdgesPage.pageNumber });\n return inRange;\n }, []);\n};\n","import { type Indexes } from '../types.ts';\n\nexport type StartIndexContext = {\n pageIndex: number;\n startIndex: Indexes;\n};\n\nexport const getCurrentPageStartIndex = ({ pageIndex, startIndex }: StartIndexContext) =>\n pageIndex === 0 ? startIndex.relative : 0;\n\nexport type EndIndexContext = {\n endIndex: Indexes;\n pageIndex: number;\n resultsPerPage: number;\n totalCachedPages: number;\n};\n\nexport const getCurrentPageEndIndex = ({ endIndex, pageIndex, resultsPerPage, totalCachedPages }: EndIndexContext) =>\n pageIndex === totalCachedPages - 1 ? endIndex.relative : resultsPerPage - 1;\n","import { type Edge } from '../types.ts';\n\nexport const getStartCursor = (edges: Edge[]) => edges[0]?.cursor;\n\nexport const getEndCursor = (edges: Edge[]) => {\n const lastEdge = edges.at(-1);\n return lastEdge?.cursor;\n};\n","import { type Direction } from '../types.ts';\n\nexport const getDirection = (last?: number): Direction => (last ? 'backward' : 'forward');\n","export type Params = {\n page: number;\n totalPages: number;\n};\n\nexport const isLastPage = ({ page, totalPages }: Params) => page === totalPages;\n","import { range } from 'lodash-es';\nimport {\n type ConnectionInputOptions,\n type CursorGroupMetadata,\n type Indexes,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getEndPageNumber, getStartPageNumber } from './getStartAndEndPageNumbers.ts';\n\nexport type GetPageNumbersToRequestContext = {\n endIndex: Indexes;\n startIndex: Indexes;\n};\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getPageNumbersToRequest = (\n args: ConnectionInputOptions,\n { endIndex, entry: { page }, metadata, resultsPerPage, startIndex }: GetPageNumbersToRequestContext & Context,\n) => {\n const startPageNumber = getStartPageNumber(args, { page, resultsPerPage, startIndex });\n const endPageNumber = getEndPageNumber(args, { endIndex, metadata, page, resultsPerPage });\n\n if (startPageNumber === endPageNumber) {\n return [page];\n }\n\n return [...range(startPageNumber, endPageNumber), endPageNumber];\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type PageNumberContext = {\n endIndex: Indexes;\n page: number;\n startIndex: Indexes;\n};\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartPageNumber = (\n args: ConnectionInputOptions,\n { page, resultsPerPage, startIndex }: Omit<PageNumberContext, 'endIndex'> & Omit<Context, 'metadata'>,\n) => {\n if (getDirection(args.last) === 'forward' || startIndex.absolute >= 0) {\n return page;\n }\n\n const startPageNumber = page - Math.ceil(Math.abs(startIndex.absolute) / resultsPerPage);\n return Math.max(startPageNumber, 1);\n};\n\nexport const getEndPageNumber = (\n args: ConnectionInputOptions,\n { endIndex, metadata: { totalPages }, page, resultsPerPage }: Omit<PageNumberContext, 'startIndex'> & Context,\n) => {\n const indexesPerPage = resultsPerPage - 1;\n\n if (\n getDirection(args.last) === 'backward' ||\n isLastPage({ page, totalPages }) ||\n endIndex.absolute <= indexesPerPage\n ) {\n return page;\n }\n\n const endPageNumber = page + Math.ceil((endIndex.absolute - indexesPerPage) / resultsPerPage);\n return Math.min(endPageNumber, totalPages);\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\n// Based on how ConnectionInputOptions are generated, either first\n// or last would be set.\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nexport const getCount = ({ first, last }: ConnectionInputOptions) => first ?? last!;\n","import { type Params, getResultsOnLastPage } from './getResultsOnLastPage.ts';\n\nexport const getIndexesOnLastPage = ({ resultsPerPage, totalResults }: Params) =>\n getResultsOnLastPage({ resultsPerPage, totalResults }) - 1;\n","export type Params = {\n resultsPerPage: number;\n totalResults: number;\n};\n\nexport const getResultsOnLastPage = ({ resultsPerPage, totalResults }: Params) => {\n const remainder = totalResults % resultsPerPage;\n return remainder === 0 ? resultsPerPage : remainder;\n};\n","import { isNumber } from 'lodash-es';\nimport { type CachedEdges, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type HasPreviousPageParams = {\n cachedEdgesByPage: CachedEdges[];\n startIndex: Indexes;\n};\n\nexport type HasNextPageParams = {\n cachedEdgesByPage: CachedEdges[];\n endIndex: Indexes;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const hasPreviousPage = ({ cachedEdgesByPage, startIndex }: HasPreviousPageParams) =>\n (isNumber(cachedEdgesByPage[0]?.pageNumber) && cachedEdgesByPage[0]?.pageNumber !== 1) || startIndex.relative > 0;\n\nexport const hasNextPage = ({\n cachedEdgesByPage,\n endIndex,\n metadata: { totalPages, totalResults },\n resultsPerPage,\n}: HasNextPageParams) =>\n (isNumber(cachedEdgesByPage.at(-1)?.pageNumber) && cachedEdgesByPage.at(-1)?.pageNumber !== totalPages) ||\n endIndex.relative < getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type Core } from '@cachemap/core';\nimport { type CursorCacheEntry, type Edge } from '../types.ts';\n\nexport type Context = {\n groupCursor: string;\n pageNumber: number;\n};\n\nexport const retrieveCachedEdgesByPage = async (cursorCache: Core, { groupCursor, pageNumber }: Context) => {\n const { entries, metadata } = await cursorCache.export<CursorCacheEntry>({\n filterByValue: [\n { comparator: pageNumber, keyChain: 'page' },\n { comparator: groupCursor, keyChain: 'group' },\n ],\n });\n\n return {\n edges: entries.reduce<Edge[]>((cached, [key, { index, node }]) => {\n if (metadata[index]?.cacheability.checkTTL()) {\n cached[index] = { cursor: key, node };\n }\n\n return cached;\n }, []),\n pageNumber,\n };\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\nexport const getCursor = ({ after, before }: ConnectionInputOptions) => before ?? after;\n","import { type Core } from '@cachemap/core';\nimport {\n type ConnectionInputOptions,\n type CursorCacheEntry,\n type CursorGroupMetadata,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { makeEntry } from './makeEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n resultsPerPage: number;\n};\n\nexport const retrieveEntry = async (\n args: ConnectionInputOptions,\n metadata: CursorGroupMetadata,\n { cursorCache, resultsPerPage }: Context,\n): Promise<PartialCursorCacheEntry> => {\n const cursor = getCursor(args);\n\n if (cursor) {\n const cursorCacheEntry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (cursorCacheEntry) {\n return cursorCacheEntry;\n }\n }\n\n return makeEntry(args, { metadata, resultsPerPage });\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const makeEntry = (\n args: ConnectionInputOptions,\n { metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n if (getDirection(args.last) === 'backward') {\n return { index: getIndexesOnLastPage({ resultsPerPage, totalResults }) + 1, page: totalPages };\n }\n\n return { index: -1, page: 1 };\n};\n","import { type Core } from '@cachemap/core';\nimport { type CachedEdges, type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getPageNumbersToRequest } from './getPageNumbersToRequest.ts';\nimport { getPagesMissingFromCache } from './getPagesMissingFromCache.ts';\nimport { getEndIndex, getStartIndex } from './getStartAndEndIndexes.ts';\nimport { hasNextPage, hasPreviousPage } from './hasPreviousNextPage.ts';\nimport { retrieveCachedEdgesByPage } from './retrieveCachedEdgesByPage.ts';\nimport { retrieveEntry } from './retrieveEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const retrieveCachedConnection = async (\n args: ConnectionInputOptions,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n // At this point the cache will always have metadata because `retrieveCachedConnection`\n // is called from `resolveConnection` and is only called if there is a cursor, either\n // after a direct check or after calling `validateCursor` or `requestAndCachePages`,\n // which check and set the metadata respectively.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const metadata = (await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`))!;\n const entry = await retrieveEntry(args, metadata, { cursorCache, resultsPerPage });\n const startIndex = getStartIndex(args, { entry, resultsPerPage });\n const endIndex = getEndIndex(args, { entry, metadata, resultsPerPage });\n const promises: Promise<CachedEdges>[] = [];\n const pageNumbersToRequest = getPageNumbersToRequest(args, { endIndex, entry, metadata, resultsPerPage, startIndex });\n\n for (const pageNumber of pageNumbersToRequest) {\n promises.push(retrieveCachedEdgesByPage(cursorCache, { groupCursor, pageNumber }));\n }\n\n const cachedEdgesByPage = await Promise.all(promises);\n const missingPages = getPagesMissingFromCache(cachedEdgesByPage);\n\n return {\n cachedEdges:\n missingPages.length === 0\n ? getInRangeCachedEdges(cachedEdgesByPage, { endIndex, resultsPerPage, startIndex })\n : cachedEdgesByPage,\n hasNextPage: hasNextPage({\n cachedEdgesByPage,\n endIndex,\n metadata,\n resultsPerPage,\n }),\n hasPreviousPage: hasPreviousPage({ cachedEdgesByPage, startIndex }),\n indexes: { end: endIndex, start: startIndex },\n missingPages,\n totalResults: metadata.totalResults,\n };\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type PartialCursorCacheEntry } from '../types.ts';\nimport { getCount } from './getCount.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\nimport { isFirstPage } from './isFirstPage.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, resultsPerPage }: Pick<Context, 'entry' | 'resultsPerPage'>,\n) => {\n const count = getCount(args);\n\n return getDirection(args.last) === 'forward'\n ? { absolute: index + 1, relative: index + 1 }\n : isFirstPage(page) && index - count < 0\n ? { absolute: 0, relative: 0 }\n : (() => {\n const absoluteStartIndex = index - count;\n\n if (absoluteStartIndex >= 0) {\n return { absolute: absoluteStartIndex, relative: absoluteStartIndex };\n }\n\n const indexesRemainingAfterLastPage = Math.abs(absoluteStartIndex);\n const pagesRemaining = indexesRemainingAfterLastPage / resultsPerPage + 1;\n const remainder = indexesRemainingAfterLastPage % resultsPerPage;\n const relativeStartIndex = remainder === 0 ? 0 : page - pagesRemaining < 0 ? 0 : resultsPerPage - remainder;\n return { absolute: absoluteStartIndex, relative: relativeStartIndex };\n })();\n};\n\nexport const getEndIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n const count = getCount(args);\n const indexesOnLastPage = getIndexesOnLastPage({ resultsPerPage, totalResults });\n\n return getDirection(args.last) === 'backward'\n ? { absolute: index - 1, relative: index - 1 }\n : isLastPage({ page, totalPages }) && index + count > indexesOnLastPage\n ? { absolute: indexesOnLastPage, relative: indexesOnLastPage }\n : (() => {\n const absoluteEndIndex = index + count;\n const indexesPerPage = resultsPerPage - 1;\n\n if (absoluteEndIndex <= indexesPerPage) {\n return { absolute: absoluteEndIndex, relative: absoluteEndIndex };\n }\n\n const indexesRemainingAfterFirstPage = absoluteEndIndex - indexesPerPage;\n const pagesRemaining = indexesRemainingAfterFirstPage / resultsPerPage;\n const remainder = indexesRemainingAfterFirstPage % resultsPerPage;\n\n const relativeEndIndex =\n remainder === 0 ? indexesPerPage : page + pagesRemaining > totalPages ? indexesOnLastPage : remainder - 1;\n\n return { absolute: absoluteEndIndex, relative: relativeEndIndex };\n })();\n};\n","export const isFirstPage = (page: number) => page === 1;\n","import { type CachedEdges } from '../types.ts';\n\nexport const getPagesMissingFromCache = (cachedEdgesByPage: CachedEdges[]) => {\n return cachedEdgesByPage.reduce<number[]>((missing, cachedEdgesPage) => {\n if (cachedEdgesPage.edges.length === 0) {\n missing.push(cachedEdgesPage.pageNumber);\n }\n\n return missing;\n }, []);\n};\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport {\n type ConnectionInputOptions,\n type Getters,\n type Node,\n type ResourceResolver,\n type SetCacheMetadata,\n} from '../types.ts';\nimport { extractEdges } from './extractEdges.ts';\nimport { extractNodes } from './extractNodes.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getEndCursor, getStartCursor } from './getStartAndEndCursors.ts';\nimport { mergeCachedEdges } from './mergeCachedEdges.ts';\nimport { requestAndCachePages } from './requestAndCachePages.ts';\nimport { retrieveCachedConnection } from './retrieveCachedConnection.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n resultsPerPage: number;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const resolveConnection = async <Resource extends PlainObject, ResourceNode extends Node>(\n args: PlainObject & ConnectionInputOptions,\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const { cachedEdges, hasNextPage, hasPreviousPage, indexes, missingPages, totalResults } =\n await retrieveCachedConnection(args, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (missingPages.length === 0) {\n const edges = extractEdges(cachedEdges);\n\n return {\n edges,\n errors: [],\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n }\n\n const { cachedEdges: missingCachedEdges, errors } = await requestAndCachePages<Resource, ResourceNode>(missingPages, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n const mergedCachedEdges = getInRangeCachedEdges(mergeCachedEdges(cachedEdges, missingCachedEdges), {\n endIndex: indexes.end,\n resultsPerPage,\n startIndex: indexes.start,\n });\n\n const edges = extractEdges(mergedCachedEdges);\n\n return {\n edges,\n errors,\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n};\n","import { type CachedEdges } from '../types.ts';\n\nexport const mergeCachedEdges = (cachedEdges: CachedEdges[], missingCachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<CachedEdges[]>((mergedCachedEdges, cachedEdge) => {\n if (cachedEdge.edges.length === 0) {\n const missingCachedEdge = missingCachedEdges.find(missing => missing.pageNumber === cachedEdge.pageNumber);\n\n if (missingCachedEdge) {\n return [...mergedCachedEdges, missingCachedEdge];\n }\n }\n\n return [...mergedCachedEdges, cachedEdge];\n }, []);\n","import { type Core } from '@cachemap/core';\nimport { GraphQLError, type GraphQLResolveInfo } from 'graphql';\nimport { type ConnectionInputOptions, type CursorCacheEntry, type CursorGroupMetadata } from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isCursorFirst } from './isCursorFirst.ts';\nimport { isCursorLast } from './isCursorLast.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const validateCursor = async (\n { after, before, first, last }: ConnectionInputOptions,\n { fieldNodes }: GraphQLResolveInfo,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n if (after && !first && !last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` must be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n if (after && last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` cannot be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && !last && !first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` must be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` cannot be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n const metadata = await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`);\n\n if (!metadata) {\n return new GraphQLError('Curser cannot be supplied without previously being provided.', { nodes: fieldNodes });\n }\n\n const cursor = getCursor({ after, before });\n\n if (!cursor) {\n return new GraphQLError(`The cursor could not be found.`, { nodes: fieldNodes });\n }\n\n const entry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (!entry) {\n return new GraphQLError(`The cursor ${cursor} could not be found.`, { nodes: fieldNodes });\n }\n\n const direction = getDirection(last);\n\n if (isCursorLast({ direction, entry, resultsPerPage, ...metadata })) {\n return new GraphQLError(`The cursor ${cursor} is the last, you cannot go forward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n if (isCursorFirst({ direction, entry })) {\n return new GraphQLError(`The cursor ${cursor} is the first, you cannot go backward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n return;\n};\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n resultsPerPage: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const isCursorLast = ({ direction, entry: { index, page }, resultsPerPage, totalPages, totalResults }: Params) =>\n direction === 'forward' && page === totalPages && index === getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n};\n\nexport const isCursorFirst = ({ direction, entry: { index, page } }: Params) =>\n direction === 'backward' && page === 1 && index === 0;\n","import { type PlainObject } from '@graphql-box/core';\nimport { type GraphQLResolveInfo } from 'graphql';\nimport { isCursorSupplied } from '../helpers/isCursorSupplied.ts';\nimport { requestAndCachePages } from '../helpers/requestAndCachePages.ts';\nimport { resolveConnection } from '../helpers/resolveConnection.ts';\nimport { validateCursor } from '../helpers/validateCursor.ts';\nimport {\n type Connection,\n type ConnectionInputOptions,\n type ConnectionResolverUserOptions,\n type Context,\n type Node,\n} from '../types.ts';\n\nexport const makeConnectionResolver =\n <\n Source extends PlainObject | undefined,\n Args extends PlainObject,\n Ctx extends Context,\n Resource extends PlainObject,\n ResourceNode extends Node,\n >({\n createMakeCursors,\n createResourceResolver,\n cursorCache,\n getters,\n resolver = result => result,\n resultsPerPage,\n }: ConnectionResolverUserOptions<Source, Args, Ctx, Resource, ResourceNode>) =>\n async (\n source: Source,\n args: Args & ConnectionInputOptions,\n context: Ctx,\n info: GraphQLResolveInfo,\n ): Promise<Connection> => {\n const { makeGroupCursor, makeIDCursor } = createMakeCursors(source, args, context, info);\n const groupCursor = makeGroupCursor();\n const { logger, setCacheMetadata } = context;\n const { fieldName: fieldPath } = info;\n\n const newCtx = {\n ...context,\n data: {\n ...context.data,\n args,\n fieldPath,\n groupCursor,\n },\n };\n\n const resourceResolver = createResourceResolver(source, args, newCtx, info);\n const childLogger = logger?.child(newCtx.data);\n childLogger?.info(`Resolving ${fieldPath}`, { logEntryName: 'RESOLVER_START' });\n\n if (isCursorSupplied(args)) {\n const cursorError = await validateCursor(args, info, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (cursorError) {\n childLogger?.error(`Failed to resolve ${fieldPath}, validation cursor error`, {\n errors: [cursorError],\n logEntryName: 'RESOLVER_FAILED',\n });\n\n return resolver({\n edges: [],\n errors: [cursorError],\n nodes: [],\n pageInfo: {\n hasNextPage: false,\n hasPreviousPage: false,\n },\n totalCount: 0,\n });\n }\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n if (await cursorCache.has(`${groupCursor}-metadata`)) {\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n await requestAndCachePages<Resource, ResourceNode>([1], {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n };\n","import { type PlainObject } from '@graphql-box/core';\nimport { type ConnectionInputOptions } from '../types.ts';\n\nexport const isCursorSupplied = ({ after, before }: PlainObject & ConnectionInputOptions) => !!(after ?? before);\n"],"names":["connectionInputOptions","Set","requestAndCachePages","async","pages","cursorCache","fieldPath","getters","groupCursor","makeIDCursor","resourceResolver","setCacheMetadata","errors","cachedEdges","Promise","all","map","page","data","pageResultData","pageResultErrors","headers","pageResultHeaders","length","edges","nodes","makeCursor","node","id","cursor","group","totalPages","totalResults","cacheControl","get","options","cacheHeaders","undefined","index","set","cacheCursors","pageNumber","push","extractEdges","reduce","cachedEdge","extractNodes","edge","getInRangeCachedEdges","cachedEdgesByPage","endIndex","resultsPerPage","startIndex","inRange","cachedEdgesPage","currentPageStartIndex","pageIndex","relative","getCurrentPageStartIndex","currentPageEndIndex","totalCachedPages","getCurrentPageEndIndex","slice","getStartCursor","getEndCursor","lastEdge","at","getDirection","last","isLastPage","getPageNumbersToRequest","args","entry","metadata","startPageNumber","absolute","Math","ceil","abs","max","getStartPageNumber","endPageNumber","indexesPerPage","min","getEndPageNumber","range","getCount","first","getIndexesOnLastPage","remainder","getResultsOnLastPage","hasPreviousPage","isNumber","hasNextPage","retrieveCachedEdgesByPage","entries","export","filterByValue","comparator","keyChain","cached","key","cacheability","checkTTL","getCursor","after","before","retrieveEntry","cursorCacheEntry","makeEntry","retrieveCachedConnection","count","isFirstPage","absoluteStartIndex","indexesRemainingAfterLastPage","getStartIndex","indexesOnLastPage","absoluteEndIndex","indexesRemainingAfterFirstPage","getEndIndex","promises","pageNumbersToRequest","missingPages","missing","getPagesMissingFromCache","indexes","end","start","resolveConnection","pageInfo","endCursor","startCursor","totalCount","missingCachedEdges","mergedCachedEdges","missingCachedEdge","find","mergeCachedEdges","validateCursor","fieldNodes","GraphQLError","direction","isCursorLast","isCursorFirst","createMakeCursors","createResourceResolver","resolver","result","source","context","info","makeGroupCursor","logger","fieldName","newCtx","childLogger","child","logEntryName","isCursorSupplied","cursorError","error","has","pickBy","_value"],"mappings":"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"}
|
package/dist/esm/index.mjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import"core-js/modules/es.set.difference.v2.js";import"core-js/modules/es.set.intersection.v2.js";import"core-js/modules/es.set.is-disjoint-from.v2.js";import"core-js/modules/es.set.is-subset-of.v2.js";import"core-js/modules/es.set.is-superset-of.v2.js";import"core-js/modules/es.set.symmetric-difference.v2.js";import"core-js/modules/es.set.union.v2.js";import{pickBy as e,range as
|
1
|
+
import"core-js/modules/es.set.difference.v2.js";import"core-js/modules/es.set.intersection.v2.js";import"core-js/modules/es.set.is-disjoint-from.v2.js";import"core-js/modules/es.set.is-subset-of.v2.js";import"core-js/modules/es.set.is-superset-of.v2.js";import"core-js/modules/es.set.symmetric-difference.v2.js";import"core-js/modules/es.set.union.v2.js";import{pickBy as e,range as t,isNumber as r}from"lodash-es";import"core-js/modules/es.array.push.js";import{GraphQLError as a}from"graphql";const s=new Set(["after","before","first","last"]),o=t=>e(t,((e,t)=>!s.has(t))),n=async(e,{cursorCache:t,fieldPath:r,getters:a,groupCursor:s,makeIDCursor:o,resourceResolver:n,setCacheMetadata:u})=>{const d=[],l=await Promise.all(e.map((async e=>{const{data:l,errors:c,headers:g}=await n({page:e});if(l&&u?.(r,g),l&&!c?.length){const r=(i=a.nodes(l),P=e=>o(e.id),i.map((e=>({cursor:P(e),node:e}))));return await(async(e,{edges:t,group:r,headers:a,page:s,totalPages:o,totalResults:n})=>{const u=a.get("cache-control"),d=u?{cacheHeaders:{cacheControl:u}}:void 0;await Promise.all(t.map((async({cursor:t,node:a},o)=>e.set(t,{group:r,index:o,node:a,page:s},d)))),await e.set(`${r}-metadata`,{totalPages:o,totalResults:n},d)})(t,{edges:r,group:s,headers:g,page:e,totalPages:a.totalPages(l),totalResults:a.totalResults(l)}),{edges:r,pageNumber:e}}var i,P;return c?.length&&d.push(...c),{edges:[],pageNumber:e}})));return{cachedEdges:l,errors:d}},u=e=>e.reduce(((e,t)=>[...e,...t.edges]),[]),d=e=>e.map((e=>e.node)),l=(e,{endIndex:t,resultsPerPage:r,startIndex:a})=>e.reduce(((s,o,n)=>{const u=(({pageIndex:e,startIndex:t})=>0===e?t.relative:0)({pageIndex:n,startIndex:a}),d=(({endIndex:e,pageIndex:t,resultsPerPage:r,totalCachedPages:a})=>t===a-1?e.relative:r-1)({endIndex:t,pageIndex:n,resultsPerPage:r,totalCachedPages:e.length}),l=o.edges.slice(u,d+1);return s.push({edges:l,pageNumber:o.pageNumber}),s}),[]),c=e=>e[0]?.cursor,g=e=>{const t=e.at(-1);return t?.cursor},i=e=>e?"backward":"forward",P=({page:e,totalPages:t})=>e===t,h=(e,{endIndex:r,entry:{page:a},metadata:s,resultsPerPage:o,startIndex:n})=>{const u=((e,{page:t,resultsPerPage:r,startIndex:a})=>{if("forward"===i(e.last)||a.absolute>=0)return t;const s=t-Math.ceil(Math.abs(a.absolute)/r);return Math.max(s,1)})(e,{page:a,resultsPerPage:o,startIndex:n}),d=((e,{endIndex:t,metadata:{totalPages:r},page:a,resultsPerPage:s})=>{const o=s-1;if("backward"===i(e.last)||P({page:a,totalPages:r})||t.absolute<=o)return a;const n=a+Math.ceil((t.absolute-o)/s);return Math.min(n,r)})(e,{endIndex:r,metadata:s,page:a,resultsPerPage:o});return u===d?[a]:[...t(u,d),d]},m=({first:e,last:t})=>e??t,p=({resultsPerPage:e,totalResults:t})=>(({resultsPerPage:e,totalResults:t})=>{const r=t%e;return 0===r?e:r})({resultsPerPage:e,totalResults:t})-1,f=({cachedEdgesByPage:e,startIndex:t})=>r(e[0]?.pageNumber)&&1!==e[0]?.pageNumber||t.relative>0,b=({cachedEdgesByPage:e,endIndex:t,metadata:{totalPages:a,totalResults:s},resultsPerPage:o})=>r(e.at(-1)?.pageNumber)&&e.at(-1)?.pageNumber!==a||t.relative<p({resultsPerPage:o,totalResults:s}),C=async(e,{groupCursor:t,pageNumber:r})=>{const{entries:a,metadata:s}=await e.export({filterByValue:[{comparator:r,keyChain:"page"},{comparator:t,keyChain:"group"}]});return{edges:a.reduce(((e,[t,{index:r,node:a}])=>(s[r]?.cacheability.checkTTL()&&(e[r]={cursor:t,node:a}),e)),[]),pageNumber:r}},w=({after:e,before:t})=>t??e,v=async(e,t,{cursorCache:r,resultsPerPage:a})=>{const s=w(e);if(s){const e=await r.get(s);if(e)return e}return((e,{metadata:{totalPages:t,totalResults:r},resultsPerPage:a})=>"backward"===i(e.last)?{index:p({resultsPerPage:a,totalResults:r})+1,page:t}:{index:-1,page:1})(e,{metadata:t,resultsPerPage:a})},x=async(e,{cursorCache:t,groupCursor:r,resultsPerPage:a})=>{const s=await t.get(`${r}-metadata`),o=await v(e,s,{cursorCache:t,resultsPerPage:a}),n=((e,{entry:{index:t,page:r},resultsPerPage:a})=>{const s=m(e);return"forward"===i(e.last)?{absolute:t+1,relative:t+1}:(e=>1===e)(r)&&t-s<0?{absolute:0,relative:0}:(()=>{const e=t-s;if(e>=0)return{absolute:e,relative:e};const o=Math.abs(e),n=o%a;return{absolute:e,relative:0===n||r-(o/a+1)<0?0:a-n}})()})(e,{entry:o,resultsPerPage:a}),u=((e,{entry:{index:t,page:r},metadata:{totalPages:a,totalResults:s},resultsPerPage:o})=>{const n=m(e),u=p({resultsPerPage:o,totalResults:s});return"backward"===i(e.last)?{absolute:t-1,relative:t-1}:P({page:r,totalPages:a})&&t+n>u?{absolute:u,relative:u}:(()=>{const e=t+n,s=o-1;if(e<=s)return{absolute:e,relative:e};const d=e-s,l=d%o;return{absolute:e,relative:0===l?s:r+d/o>a?u:l-1}})()})(e,{entry:o,metadata:s,resultsPerPage:a}),d=[],c=h(e,{endIndex:u,entry:o,metadata:s,resultsPerPage:a,startIndex:n});for(const e of c)d.push(C(t,{groupCursor:r,pageNumber:e}));const g=await Promise.all(d),w=(e=>e.reduce(((e,t)=>(0===t.edges.length&&e.push(t.pageNumber),e)),[]))(g);return{cachedEdges:0===w.length?l(g,{endIndex:u,resultsPerPage:a,startIndex:n}):g,hasNextPage:b({cachedEdgesByPage:g,endIndex:u,metadata:s,resultsPerPage:a}),hasPreviousPage:f({cachedEdgesByPage:g,startIndex:n}),indexes:{end:u,start:n},missingPages:w,totalResults:s.totalResults}},I=async(e,{cursorCache:t,fieldPath:r,getters:a,groupCursor:s,makeIDCursor:o,resourceResolver:i,resultsPerPage:P,setCacheMetadata:h})=>{const{cachedEdges:m,hasNextPage:p,hasPreviousPage:f,indexes:b,missingPages:C,totalResults:w}=await x(e,{cursorCache:t,groupCursor:s,resultsPerPage:P});if(0===C.length){const e=u(m);return{edges:e,errors:[],nodes:d(e),pageInfo:{endCursor:g(e),hasNextPage:p,hasPreviousPage:f,startCursor:c(e)},totalCount:w}}const{cachedEdges:v,errors:I}=await n(C,{cursorCache:t,fieldPath:r,getters:a,groupCursor:s,makeIDCursor:o,resourceResolver:i,setCacheMetadata:h}),y=l(((e,t)=>e.reduce(((e,r)=>{if(0===r.edges.length){const a=t.find((e=>e.pageNumber===r.pageNumber));if(a)return[...e,a]}return[...e,r]}),[]))(m,v),{endIndex:b.end,resultsPerPage:P,startIndex:b.start}),R=u(y);return{edges:R,errors:I,nodes:d(R),pageInfo:{endCursor:g(R),hasNextPage:p,hasPreviousPage:f,startCursor:c(R)},totalCount:w}},y=async({after:e,before:t,first:r,last:s},{fieldNodes:o},{cursorCache:n,groupCursor:u,resultsPerPage:d})=>{if(e&&!r&&!s)return new a("Invalid connection argument combination. `after` must be used in combination with `first`.",{nodes:o});if(e&&s)return new a("Invalid connection argument combination. `after` cannot be used in combination with `last`.",{nodes:o});if(t&&!s&&!r)return new a("Invalid connection argument combination. `before` must be used in combination with `last`.",{nodes:o});if(t&&r)return new a("Invalid connection argument combination. `before` cannot be used in combination with `first`.",{nodes:o});const l=await n.get(`${u}-metadata`);if(!l)return new a("Curser cannot be supplied without previously being provided.",{nodes:o});const c=w({after:e,before:t});if(!c)return new a("The cursor could not be found.",{nodes:o});const g=await n.get(c);if(!g)return new a(`The cursor ${c} could not be found.`,{nodes:o});const P=i(s);return(({direction:e,entry:{index:t,page:r},resultsPerPage:a,totalPages:s,totalResults:o})=>"forward"===e&&r===s&&t===p({resultsPerPage:a,totalResults:o}))({direction:P,entry:g,resultsPerPage:d,...l})?new a(`The cursor ${c} is the last, you cannot go forward any further.`,{nodes:o}):(({direction:e,entry:{index:t,page:r}})=>"backward"===e&&1===r&&0===t)({direction:P,entry:g})?new a(`The cursor ${c} is the first, you cannot go backward any further.`,{nodes:o}):void 0},R=({createMakeCursors:e,createResourceResolver:t,cursorCache:r,getters:a,resolver:s=(e=>e),resultsPerPage:o})=>async(u,d,l,c)=>{const{makeGroupCursor:g,makeIDCursor:i}=e(u,d,l,c),P=g(),{logger:h,setCacheMetadata:m}=l,{fieldName:p}=c,f={...l,data:{...l.data,args:d,fieldPath:p,groupCursor:P}},b=t(u,d,f,c),C=h?.child(f.data);if(C?.info(`Resolving ${p}`,{logEntryName:"RESOLVER_START"}),(({after:e,before:t})=>!!(e??t))(d)){const e=await y(d,c,{cursorCache:r,groupCursor:P,resultsPerPage:o});return e?(C?.error(`Failed to resolve ${p}, validation cursor error`,{errors:[e],logEntryName:"RESOLVER_FAILED"}),s({edges:[],errors:[e],nodes:[],pageInfo:{hasNextPage:!1,hasPreviousPage:!1},totalCount:0})):s(await I(d,{cursorCache:r,fieldPath:p,getters:a,groupCursor:P,makeIDCursor:i,resourceResolver:b,resultsPerPage:o,setCacheMetadata:m}))}return await r.has(`${P}-metadata`)||await n([1],{cursorCache:r,fieldPath:p,getters:a,groupCursor:P,makeIDCursor:i,resourceResolver:b,setCacheMetadata:m}),s(await I(d,{cursorCache:r,fieldPath:p,getters:a,groupCursor:P,makeIDCursor:i,resourceResolver:b,resultsPerPage:o,setCacheMetadata:m}))};export{R as makeConnectionResolver,o as removeConnectionInputOptions};
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../connection-resolver/src//helpers/removeConnectionInputOptions.ts","../connection-resolver/src//helpers/requestAndCachePages.ts","../connection-resolver/src//helpers/makeEdges.ts","../connection-resolver/src//helpers/cacheCursors.ts","../connection-resolver/src//helpers/extractEdges.ts","../connection-resolver/src//helpers/extractNodes.ts","../connection-resolver/src//helpers/getInRangeCachedEdges.ts","../connection-resolver/src//helpers/getCurrentPageStartAndEndIndexes.ts","../connection-resolver/src//helpers/getStartAndEndCursors.ts","../connection-resolver/src//helpers/getDirection.ts","../connection-resolver/src//helpers/isLastPage.ts","../connection-resolver/src//helpers/getPageNumbersToRequest.ts","../connection-resolver/src//helpers/getStartAndEndPageNumbers.ts","../connection-resolver/src//helpers/getCount.ts","../connection-resolver/src//helpers/getIndexesOnLastPage.ts","../connection-resolver/src//helpers/getResultsOnLastPage.ts","../connection-resolver/src//helpers/hasPreviousNextPage.ts","../connection-resolver/src//helpers/retrieveCachedEdgesByPage.ts","../connection-resolver/src//helpers/getCursor.ts","../connection-resolver/src//helpers/retrieveEntry.ts","../connection-resolver/src//helpers/makeEntry.ts","../connection-resolver/src//helpers/retrieveCachedConnection.ts","../connection-resolver/src//helpers/getStartAndEndIndexes.ts","../connection-resolver/src//helpers/isFirstPage.ts","../connection-resolver/src//helpers/getPagesMissingFromCache.ts","../connection-resolver/src//helpers/resolveConnection.ts","../connection-resolver/src//helpers/mergeCachedEdges.ts","../connection-resolver/src//helpers/validateCursor.ts","../connection-resolver/src//helpers/isCursorLast.ts","../connection-resolver/src//helpers/isCursorFirst.ts","../connection-resolver/src//main/index.ts","../connection-resolver/src//helpers/isCursorSupplied.ts"],"sourcesContent":["import { pickBy } from 'lodash-es';\n\nconst connectionInputOptions = new Set(['after', 'before', 'first', 'last']);\n\nexport const removeConnectionInputOptions = <O extends object>(args: O) =>\n pickBy(args, (_value, key) => !connectionInputOptions.has(key));\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport { type Getters, type Node, type ResourceResolver, type SetCacheMetadata } from '../types.ts';\nimport { cacheCursors } from './cacheCursors.ts';\nimport { makeEdges } from './makeEdges.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const requestAndCachePages = async <Resource extends PlainObject, ResourceNode extends Node>(\n pages: number[],\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const errors: Error[] = [];\n\n const cachedEdges = await Promise.all(\n pages.map(async page => {\n const {\n data: pageResultData,\n errors: pageResultErrors,\n headers: pageResultHeaders,\n } = await resourceResolver({\n page,\n });\n\n if (pageResultData) {\n setCacheMetadata?.(fieldPath, pageResultHeaders);\n }\n\n if (pageResultData && !pageResultErrors?.length) {\n const edges = makeEdges(getters.nodes(pageResultData), node => makeIDCursor(node.id));\n\n await cacheCursors(cursorCache, {\n edges,\n group: groupCursor,\n headers: pageResultHeaders,\n page,\n totalPages: getters.totalPages(pageResultData),\n totalResults: getters.totalResults(pageResultData),\n });\n\n return { edges, pageNumber: page };\n }\n\n if (pageResultErrors?.length) {\n errors.push(...pageResultErrors);\n }\n\n return { edges: [], pageNumber: page };\n }),\n );\n\n return { cachedEdges, errors };\n};\n","import { type Node } from '../types.ts';\n\nexport const makeEdges = (nodes: Node[], makeCursor: (node: Node) => string) =>\n nodes.map(node => ({ cursor: makeCursor(node), node }));\n","import { type Core } from '@cachemap/core';\nimport { type Edge } from '../types.ts';\n\nexport type Params = {\n edges: Edge[];\n group: string;\n headers: Headers;\n page: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const cacheCursors = async (\n cursorCache: Core,\n { edges, group, headers, page, totalPages, totalResults }: Params,\n) => {\n const cacheControl = headers.get('cache-control');\n const options = cacheControl ? { cacheHeaders: { cacheControl } } : undefined;\n\n await Promise.all(\n edges.map(async ({ cursor, node }, index) => cursorCache.set(cursor, { group, index, node, page }, options)),\n );\n\n await cursorCache.set(`${group}-metadata`, { totalPages, totalResults }, options);\n};\n","import { type CachedEdges, type Edge } from '../types.ts';\n\nexport const extractEdges = (cachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<Edge[]>((edges, cachedEdge) => [...edges, ...cachedEdge.edges], []);\n","import { type Edge } from '../types.ts';\n\nexport const extractNodes = (edges: Edge[]) => edges.map(edge => edge.node);\n","import { type CachedEdges, type Indexes } from '../types.ts';\nimport { getCurrentPageEndIndex, getCurrentPageStartIndex } from './getCurrentPageStartAndEndIndexes.ts';\n\nexport type Context = {\n endIndex: Indexes;\n resultsPerPage: number;\n startIndex: Indexes;\n};\n\nexport const getInRangeCachedEdges = (\n cachedEdgesByPage: CachedEdges[],\n { endIndex, resultsPerPage, startIndex }: Context,\n) => {\n return cachedEdgesByPage.reduce<CachedEdges[]>((inRange, cachedEdgesPage, index) => {\n const currentPageStartIndex = getCurrentPageStartIndex({ pageIndex: index, startIndex });\n\n const currentPageEndIndex = getCurrentPageEndIndex({\n endIndex,\n pageIndex: index,\n resultsPerPage,\n totalCachedPages: cachedEdgesByPage.length,\n });\n\n const cachedEdges = cachedEdgesPage.edges.slice(currentPageStartIndex, currentPageEndIndex + 1);\n inRange.push({ edges: cachedEdges, pageNumber: cachedEdgesPage.pageNumber });\n return inRange;\n }, []);\n};\n","import { type Indexes } from '../types.ts';\n\nexport type StartIndexContext = {\n pageIndex: number;\n startIndex: Indexes;\n};\n\nexport const getCurrentPageStartIndex = ({ pageIndex, startIndex }: StartIndexContext) =>\n pageIndex === 0 ? startIndex.relative : 0;\n\nexport type EndIndexContext = {\n endIndex: Indexes;\n pageIndex: number;\n resultsPerPage: number;\n totalCachedPages: number;\n};\n\nexport const getCurrentPageEndIndex = ({ endIndex, pageIndex, resultsPerPage, totalCachedPages }: EndIndexContext) =>\n pageIndex === totalCachedPages - 1 ? endIndex.relative : resultsPerPage - 1;\n","import { type Edge } from '../types.ts';\n\nexport const getStartCursor = (edges: Edge[]) => edges[0]?.cursor;\n\nexport const getEndCursor = (edges: Edge[]) => {\n const lastEdge = edges.at(-1);\n return lastEdge?.cursor;\n};\n","import { type Direction } from '../types.ts';\n\nexport const getDirection = (last?: number): Direction => (last ? 'backward' : 'forward');\n","export type Params = {\n page: number;\n totalPages: number;\n};\n\nexport const isLastPage = ({ page, totalPages }: Params) => page === totalPages;\n","import { range } from 'lodash-es';\nimport {\n type ConnectionInputOptions,\n type CursorGroupMetadata,\n type Indexes,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getEndPageNumber, getStartPageNumber } from './getStartAndEndPageNumbers.ts';\n\nexport type GetPageNumbersToRequestContext = {\n endIndex: Indexes;\n startIndex: Indexes;\n};\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getPageNumbersToRequest = (\n args: ConnectionInputOptions,\n { endIndex, entry: { page }, metadata, resultsPerPage, startIndex }: GetPageNumbersToRequestContext & Context,\n) => {\n const startPageNumber = getStartPageNumber(args, { page, resultsPerPage, startIndex });\n const endPageNumber = getEndPageNumber(args, { endIndex, metadata, page, resultsPerPage });\n\n if (startPageNumber === endPageNumber) {\n return [page];\n }\n\n return [...range(startPageNumber, endPageNumber), endPageNumber];\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type PageNumberContext = {\n endIndex: Indexes;\n page: number;\n startIndex: Indexes;\n};\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartPageNumber = (\n args: ConnectionInputOptions,\n { page, resultsPerPage, startIndex }: Omit<PageNumberContext, 'endIndex'> & Omit<Context, 'metadata'>,\n) => {\n if (getDirection(args.last) === 'forward' || startIndex.absolute >= 0) {\n return page;\n }\n\n const startPageNumber = page - Math.ceil(Math.abs(startIndex.absolute) / resultsPerPage);\n return Math.max(startPageNumber, 1);\n};\n\nexport const getEndPageNumber = (\n args: ConnectionInputOptions,\n { endIndex, metadata: { totalPages }, page, resultsPerPage }: Omit<PageNumberContext, 'startIndex'> & Context,\n) => {\n const indexesPerPage = resultsPerPage - 1;\n\n if (\n getDirection(args.last) === 'backward' ||\n isLastPage({ page, totalPages }) ||\n endIndex.absolute <= indexesPerPage\n ) {\n return page;\n }\n\n const endPageNumber = page + Math.ceil((endIndex.absolute - indexesPerPage) / resultsPerPage);\n return Math.min(endPageNumber, totalPages);\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\n// Based on how ConnectionInputOptions are generated, either first\n// or last would be set.\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nexport const getCount = ({ first, last }: ConnectionInputOptions) => first ?? last!;\n","import { type Params, getResultsOnLastPage } from './getResultsOnLastPage.ts';\n\nexport const getIndexesOnLastPage = ({ resultsPerPage, totalResults }: Params) =>\n getResultsOnLastPage({ resultsPerPage, totalResults }) - 1;\n","export type Params = {\n resultsPerPage: number;\n totalResults: number;\n};\n\nexport const getResultsOnLastPage = ({ resultsPerPage, totalResults }: Params) => {\n const remainder = totalResults % resultsPerPage;\n return remainder === 0 ? resultsPerPage : remainder;\n};\n","import { isNumber } from 'lodash-es';\nimport { type CachedEdges, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type HasPreviousPageParams = {\n cachedEdgesByPage: CachedEdges[];\n startIndex: Indexes;\n};\n\nexport type HasNextPageParams = {\n cachedEdgesByPage: CachedEdges[];\n endIndex: Indexes;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const hasPreviousPage = ({ cachedEdgesByPage, startIndex }: HasPreviousPageParams) =>\n (isNumber(cachedEdgesByPage[0]?.pageNumber) && cachedEdgesByPage[0]?.pageNumber !== 1) || startIndex.relative > 0;\n\nexport const hasNextPage = ({\n cachedEdgesByPage,\n endIndex,\n metadata: { totalPages, totalResults },\n resultsPerPage,\n}: HasNextPageParams) =>\n (isNumber(cachedEdgesByPage.at(-1)?.pageNumber) && cachedEdgesByPage.at(-1)?.pageNumber !== totalPages) ||\n endIndex.relative < getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type Core } from '@cachemap/core';\nimport { type CursorCacheEntry, type Edge } from '../types.ts';\n\nexport type Context = {\n groupCursor: string;\n pageNumber: number;\n};\n\nexport const retrieveCachedEdgesByPage = async (cursorCache: Core, { groupCursor, pageNumber }: Context) => {\n const { entries, metadata } = await cursorCache.export<CursorCacheEntry>({\n filterByValue: [\n { comparator: pageNumber, keyChain: 'page' },\n { comparator: groupCursor, keyChain: 'group' },\n ],\n });\n\n return {\n edges: entries.reduce<Edge[]>((cached, [key, { index, node }]) => {\n if (metadata[index]?.cacheability.checkTTL()) {\n cached[index] = { cursor: key, node };\n }\n\n return cached;\n }, []),\n pageNumber,\n };\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\nexport const getCursor = ({ after, before }: ConnectionInputOptions) => before ?? after;\n","import { type Core } from '@cachemap/core';\nimport {\n type ConnectionInputOptions,\n type CursorCacheEntry,\n type CursorGroupMetadata,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { makeEntry } from './makeEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n resultsPerPage: number;\n};\n\nexport const retrieveEntry = async (\n args: ConnectionInputOptions,\n metadata: CursorGroupMetadata,\n { cursorCache, resultsPerPage }: Context,\n): Promise<PartialCursorCacheEntry> => {\n const cursor = getCursor(args);\n\n if (cursor) {\n const cursorCacheEntry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (cursorCacheEntry) {\n return cursorCacheEntry;\n }\n }\n\n return makeEntry(args, { metadata, resultsPerPage });\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const makeEntry = (\n args: ConnectionInputOptions,\n { metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n if (getDirection(args.last) === 'backward') {\n return { index: getIndexesOnLastPage({ resultsPerPage, totalResults }) + 1, page: totalPages };\n }\n\n return { index: -1, page: 1 };\n};\n","import { type Core } from '@cachemap/core';\nimport { type CachedEdges, type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getPageNumbersToRequest } from './getPageNumbersToRequest.ts';\nimport { getPagesMissingFromCache } from './getPagesMissingFromCache.ts';\nimport { getEndIndex, getStartIndex } from './getStartAndEndIndexes.ts';\nimport { hasNextPage, hasPreviousPage } from './hasPreviousNextPage.ts';\nimport { retrieveCachedEdgesByPage } from './retrieveCachedEdgesByPage.ts';\nimport { retrieveEntry } from './retrieveEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const retrieveCachedConnection = async (\n args: ConnectionInputOptions,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n // At this point the cache will always have metadata because `retrieveCachedConnection`\n // is called from `resolveConnection` and is only called if there is a cursor, either\n // after a direct check or after calling `validateCursor` or `requestAndCachePages`,\n // which check and set the metadata respectively.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const metadata = (await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`))!;\n const entry = await retrieveEntry(args, metadata, { cursorCache, resultsPerPage });\n const startIndex = getStartIndex(args, { entry, resultsPerPage });\n const endIndex = getEndIndex(args, { entry, metadata, resultsPerPage });\n const promises: Promise<CachedEdges>[] = [];\n const pageNumbersToRequest = getPageNumbersToRequest(args, { endIndex, entry, metadata, resultsPerPage, startIndex });\n\n for (const pageNumber of pageNumbersToRequest) {\n promises.push(retrieveCachedEdgesByPage(cursorCache, { groupCursor, pageNumber }));\n }\n\n const cachedEdgesByPage = await Promise.all(promises);\n const missingPages = getPagesMissingFromCache(cachedEdgesByPage);\n\n return {\n cachedEdges:\n missingPages.length === 0\n ? getInRangeCachedEdges(cachedEdgesByPage, { endIndex, resultsPerPage, startIndex })\n : cachedEdgesByPage,\n hasNextPage: hasNextPage({\n cachedEdgesByPage,\n endIndex,\n metadata,\n resultsPerPage,\n }),\n hasPreviousPage: hasPreviousPage({ cachedEdgesByPage, startIndex }),\n indexes: { end: endIndex, start: startIndex },\n missingPages,\n totalResults: metadata.totalResults,\n };\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type PartialCursorCacheEntry } from '../types.ts';\nimport { getCount } from './getCount.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\nimport { isFirstPage } from './isFirstPage.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, resultsPerPage }: Pick<Context, 'entry' | 'resultsPerPage'>,\n) => {\n const count = getCount(args);\n\n return getDirection(args.last) === 'forward'\n ? { absolute: index + 1, relative: index + 1 }\n : isFirstPage(page) && index - count < 0\n ? { absolute: 0, relative: 0 }\n : (() => {\n const absoluteStartIndex = index - count;\n\n if (absoluteStartIndex >= 0) {\n return { absolute: absoluteStartIndex, relative: absoluteStartIndex };\n }\n\n const indexesRemainingAfterLastPage = Math.abs(absoluteStartIndex);\n const pagesRemaining = indexesRemainingAfterLastPage / resultsPerPage + 1;\n const remainder = indexesRemainingAfterLastPage % resultsPerPage;\n const relativeStartIndex = remainder === 0 ? 0 : page - pagesRemaining < 0 ? 0 : resultsPerPage - remainder;\n return { absolute: absoluteStartIndex, relative: relativeStartIndex };\n })();\n};\n\nexport const getEndIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n const count = getCount(args);\n const indexesOnLastPage = getIndexesOnLastPage({ resultsPerPage, totalResults });\n\n return getDirection(args.last) === 'backward'\n ? { absolute: index - 1, relative: index - 1 }\n : isLastPage({ page, totalPages }) && index + count > indexesOnLastPage\n ? { absolute: indexesOnLastPage, relative: indexesOnLastPage }\n : (() => {\n const absoluteEndIndex = index + count;\n const indexesPerPage = resultsPerPage - 1;\n\n if (absoluteEndIndex <= indexesPerPage) {\n return { absolute: absoluteEndIndex, relative: absoluteEndIndex };\n }\n\n const indexesRemainingAfterFirstPage = absoluteEndIndex - indexesPerPage;\n const pagesRemaining = indexesRemainingAfterFirstPage / resultsPerPage;\n const remainder = indexesRemainingAfterFirstPage % resultsPerPage;\n\n const relativeEndIndex =\n remainder === 0 ? indexesPerPage : page + pagesRemaining > totalPages ? indexesOnLastPage : remainder - 1;\n\n return { absolute: absoluteEndIndex, relative: relativeEndIndex };\n })();\n};\n","export const isFirstPage = (page: number) => page === 1;\n","import { type CachedEdges } from '../types.ts';\n\nexport const getPagesMissingFromCache = (cachedEdgesByPage: CachedEdges[]) => {\n return cachedEdgesByPage.reduce<number[]>((missing, cachedEdgesPage) => {\n if (cachedEdgesPage.edges.length === 0) {\n missing.push(cachedEdgesPage.pageNumber);\n }\n\n return missing;\n }, []);\n};\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport { type Logger } from 'winston';\nimport {\n type ConnectionInputOptions,\n type Getters,\n type Node,\n type ResourceResolver,\n type SetCacheMetadata,\n} from '../types.ts';\nimport { extractEdges } from './extractEdges.ts';\nimport { extractNodes } from './extractNodes.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getEndCursor, getStartCursor } from './getStartAndEndCursors.ts';\nimport { mergeCachedEdges } from './mergeCachedEdges.ts';\nimport { requestAndCachePages } from './requestAndCachePages.ts';\nimport { retrieveCachedConnection } from './retrieveCachedConnection.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n logger: Logger | undefined;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n resultsPerPage: number;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const resolveConnection = async <Resource extends PlainObject, ResourceNode extends Node>(\n args: PlainObject & ConnectionInputOptions,\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const { cachedEdges, hasNextPage, hasPreviousPage, indexes, missingPages, totalResults } =\n await retrieveCachedConnection(args, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (missingPages.length === 0) {\n const edges = extractEdges(cachedEdges);\n\n logger?.info(`CACHE HIT: Connection resolver cache has data to resolve ${fieldPath}`, {\n logEntryName: 'RESOLVER_RESPONSE_FROM_CACHE',\n });\n\n return {\n edges,\n errors: [],\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n }\n\n const { cachedEdges: missingCachedEdges, errors } = await requestAndCachePages<Resource, ResourceNode>(missingPages, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n const mergedCachedEdges = getInRangeCachedEdges(mergeCachedEdges(cachedEdges, missingCachedEdges), {\n endIndex: indexes.end,\n resultsPerPage,\n startIndex: indexes.start,\n });\n\n const edges = extractEdges(mergedCachedEdges);\n\n return {\n edges,\n errors,\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n};\n","import { type CachedEdges } from '../types.ts';\n\nexport const mergeCachedEdges = (cachedEdges: CachedEdges[], missingCachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<CachedEdges[]>((mergedCachedEdges, cachedEdge) => {\n if (cachedEdge.edges.length === 0) {\n const missingCachedEdge = missingCachedEdges.find(missing => missing.pageNumber === cachedEdge.pageNumber);\n\n if (missingCachedEdge) {\n return [...mergedCachedEdges, missingCachedEdge];\n }\n }\n\n return [...mergedCachedEdges, cachedEdge];\n }, []);\n","import { type Core } from '@cachemap/core';\nimport { GraphQLError, type GraphQLResolveInfo } from 'graphql';\nimport { type ConnectionInputOptions, type CursorCacheEntry, type CursorGroupMetadata } from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isCursorFirst } from './isCursorFirst.ts';\nimport { isCursorLast } from './isCursorLast.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const validateCursor = async (\n { after, before, first, last }: ConnectionInputOptions,\n { fieldNodes }: GraphQLResolveInfo,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n if (after && !first && !last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` must be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n if (after && last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` cannot be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && !last && !first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` must be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` cannot be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n const metadata = await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`);\n\n if (!metadata) {\n return new GraphQLError('Curser cannot be supplied without previously being provided.', { nodes: fieldNodes });\n }\n\n const cursor = getCursor({ after, before });\n\n if (!cursor) {\n return new GraphQLError(`The cursor could not be found.`, { nodes: fieldNodes });\n }\n\n const entry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (!entry) {\n return new GraphQLError(`The cursor ${cursor} could not be found.`, { nodes: fieldNodes });\n }\n\n const direction = getDirection(last);\n\n if (isCursorLast({ direction, entry, resultsPerPage, ...metadata })) {\n return new GraphQLError(`The cursor ${cursor} is the last, you cannot go forward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n if (isCursorFirst({ direction, entry })) {\n return new GraphQLError(`The cursor ${cursor} is the first, you cannot go backward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n return;\n};\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n resultsPerPage: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const isCursorLast = ({ direction, entry: { index, page }, resultsPerPage, totalPages, totalResults }: Params) =>\n direction === 'forward' && page === totalPages && index === getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n};\n\nexport const isCursorFirst = ({ direction, entry: { index, page } }: Params) =>\n direction === 'backward' && page === 1 && index === 0;\n","import { type PlainObject } from '@graphql-box/core';\nimport { type GraphQLResolveInfo } from 'graphql';\nimport { isCursorSupplied } from '../helpers/isCursorSupplied.ts';\nimport { requestAndCachePages } from '../helpers/requestAndCachePages.ts';\nimport { resolveConnection } from '../helpers/resolveConnection.ts';\nimport { validateCursor } from '../helpers/validateCursor.ts';\nimport {\n type Connection,\n type ConnectionInputOptions,\n type ConnectionResolverUserOptions,\n type Context,\n type Node,\n} from '../types.ts';\n\nexport const makeConnectionResolver =\n <\n Source extends PlainObject | undefined,\n Args extends PlainObject,\n Ctx extends Context,\n Resource extends PlainObject,\n ResourceNode extends Node,\n >({\n createMakeCursors,\n createResourceResolver,\n cursorCache,\n getters,\n resolver = result => result,\n resultsPerPage,\n }: ConnectionResolverUserOptions<Source, Args, Ctx, Resource, ResourceNode>) =>\n async (\n source: Source,\n args: Args & ConnectionInputOptions,\n context: Ctx,\n info: GraphQLResolveInfo,\n ): Promise<Connection> => {\n const { makeGroupCursor, makeIDCursor } = createMakeCursors(source, args, context, info);\n const groupCursor = makeGroupCursor();\n const { logger, setCacheMetadata } = context;\n const { fieldName: fieldPath } = info;\n\n const newCtx = {\n ...context,\n data: {\n ...context.data,\n args,\n fieldPath,\n groupCursor,\n },\n };\n\n const resourceResolver = createResourceResolver(source, args, newCtx, info);\n const childLogger = logger?.child(newCtx.data);\n childLogger?.info(`Resolving ${fieldPath}`, { logEntryName: 'RESOLVER_START' });\n\n if (isCursorSupplied(args)) {\n const cursorError = await validateCursor(args, info, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (cursorError) {\n childLogger?.error(`Failed to resolve ${fieldPath}, validation cursor error`, {\n errors: [cursorError],\n logEntryName: 'RESOLVER_FAILED',\n });\n\n return resolver({\n edges: [],\n errors: [cursorError],\n nodes: [],\n pageInfo: {\n hasNextPage: false,\n hasPreviousPage: false,\n },\n totalCount: 0,\n });\n }\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger: childLogger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n if (await cursorCache.has(`${groupCursor}-metadata`)) {\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger: childLogger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n await requestAndCachePages<Resource, ResourceNode>([1], {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n logger: childLogger,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n };\n","import { type PlainObject } from '@graphql-box/core';\nimport { type ConnectionInputOptions } from '../types.ts';\n\nexport const isCursorSupplied = ({ after, before }: PlainObject & ConnectionInputOptions) => !!(after ?? before);\n"],"names":["connectionInputOptions","Set","removeConnectionInputOptions","args","pickBy","_value","key","has","requestAndCachePages","async","pages","cursorCache","fieldPath","getters","groupCursor","makeIDCursor","resourceResolver","setCacheMetadata","errors","cachedEdges","Promise","all","map","page","data","pageResultData","pageResultErrors","headers","pageResultHeaders","length","edges","nodes","makeCursor","node","id","cursor","group","totalPages","totalResults","cacheControl","get","options","cacheHeaders","undefined","index","set","cacheCursors","pageNumber","push","extractEdges","reduce","cachedEdge","extractNodes","edge","getInRangeCachedEdges","cachedEdgesByPage","endIndex","resultsPerPage","startIndex","inRange","cachedEdgesPage","currentPageStartIndex","pageIndex","relative","getCurrentPageStartIndex","currentPageEndIndex","totalCachedPages","getCurrentPageEndIndex","slice","getStartCursor","getEndCursor","lastEdge","at","getDirection","last","isLastPage","getPageNumbersToRequest","entry","metadata","startPageNumber","absolute","Math","ceil","abs","max","getStartPageNumber","endPageNumber","indexesPerPage","min","getEndPageNumber","range","getCount","first","getIndexesOnLastPage","remainder","getResultsOnLastPage","hasPreviousPage","isNumber","hasNextPage","retrieveCachedEdgesByPage","entries","export","filterByValue","comparator","keyChain","cached","cacheability","checkTTL","getCursor","after","before","retrieveEntry","cursorCacheEntry","makeEntry","retrieveCachedConnection","count","isFirstPage","absoluteStartIndex","indexesRemainingAfterLastPage","getStartIndex","indexesOnLastPage","absoluteEndIndex","indexesRemainingAfterFirstPage","getEndIndex","promises","pageNumbersToRequest","missingPages","missing","getPagesMissingFromCache","indexes","end","start","resolveConnection","logger","info","logEntryName","pageInfo","endCursor","startCursor","totalCount","missingCachedEdges","mergedCachedEdges","missingCachedEdge","find","mergeCachedEdges","validateCursor","fieldNodes","GraphQLError","direction","isCursorLast","isCursorFirst","makeConnectionResolver","createMakeCursors","createResourceResolver","resolver","result","source","context","makeGroupCursor","fieldName","newCtx","childLogger","child","isCursorSupplied","cursorError","error"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../connection-resolver/src//helpers/removeConnectionInputOptions.ts","../connection-resolver/src//helpers/requestAndCachePages.ts","../connection-resolver/src//helpers/makeEdges.ts","../connection-resolver/src//helpers/cacheCursors.ts","../connection-resolver/src//helpers/extractEdges.ts","../connection-resolver/src//helpers/extractNodes.ts","../connection-resolver/src//helpers/getInRangeCachedEdges.ts","../connection-resolver/src//helpers/getCurrentPageStartAndEndIndexes.ts","../connection-resolver/src//helpers/getStartAndEndCursors.ts","../connection-resolver/src//helpers/getDirection.ts","../connection-resolver/src//helpers/isLastPage.ts","../connection-resolver/src//helpers/getPageNumbersToRequest.ts","../connection-resolver/src//helpers/getStartAndEndPageNumbers.ts","../connection-resolver/src//helpers/getCount.ts","../connection-resolver/src//helpers/getIndexesOnLastPage.ts","../connection-resolver/src//helpers/getResultsOnLastPage.ts","../connection-resolver/src//helpers/hasPreviousNextPage.ts","../connection-resolver/src//helpers/retrieveCachedEdgesByPage.ts","../connection-resolver/src//helpers/getCursor.ts","../connection-resolver/src//helpers/retrieveEntry.ts","../connection-resolver/src//helpers/makeEntry.ts","../connection-resolver/src//helpers/retrieveCachedConnection.ts","../connection-resolver/src//helpers/getStartAndEndIndexes.ts","../connection-resolver/src//helpers/isFirstPage.ts","../connection-resolver/src//helpers/getPagesMissingFromCache.ts","../connection-resolver/src//helpers/resolveConnection.ts","../connection-resolver/src//helpers/mergeCachedEdges.ts","../connection-resolver/src//helpers/validateCursor.ts","../connection-resolver/src//helpers/isCursorLast.ts","../connection-resolver/src//helpers/isCursorFirst.ts","../connection-resolver/src//main/index.ts","../connection-resolver/src//helpers/isCursorSupplied.ts"],"sourcesContent":["import { pickBy } from 'lodash-es';\n\nconst connectionInputOptions = new Set(['after', 'before', 'first', 'last']);\n\nexport const removeConnectionInputOptions = <O extends object>(args: O) =>\n pickBy(args, (_value, key) => !connectionInputOptions.has(key));\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport { type Getters, type Node, type ResourceResolver, type SetCacheMetadata } from '../types.ts';\nimport { cacheCursors } from './cacheCursors.ts';\nimport { makeEdges } from './makeEdges.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const requestAndCachePages = async <Resource extends PlainObject, ResourceNode extends Node>(\n pages: number[],\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const errors: Error[] = [];\n\n const cachedEdges = await Promise.all(\n pages.map(async page => {\n const {\n data: pageResultData,\n errors: pageResultErrors,\n headers: pageResultHeaders,\n } = await resourceResolver({\n page,\n });\n\n if (pageResultData) {\n setCacheMetadata?.(fieldPath, pageResultHeaders);\n }\n\n if (pageResultData && !pageResultErrors?.length) {\n const edges = makeEdges(getters.nodes(pageResultData), node => makeIDCursor(node.id));\n\n await cacheCursors(cursorCache, {\n edges,\n group: groupCursor,\n headers: pageResultHeaders,\n page,\n totalPages: getters.totalPages(pageResultData),\n totalResults: getters.totalResults(pageResultData),\n });\n\n return { edges, pageNumber: page };\n }\n\n if (pageResultErrors?.length) {\n errors.push(...pageResultErrors);\n }\n\n return { edges: [], pageNumber: page };\n }),\n );\n\n return { cachedEdges, errors };\n};\n","import { type Node } from '../types.ts';\n\nexport const makeEdges = (nodes: Node[], makeCursor: (node: Node) => string) =>\n nodes.map(node => ({ cursor: makeCursor(node), node }));\n","import { type Core } from '@cachemap/core';\nimport { type Edge } from '../types.ts';\n\nexport type Params = {\n edges: Edge[];\n group: string;\n headers: Headers;\n page: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const cacheCursors = async (\n cursorCache: Core,\n { edges, group, headers, page, totalPages, totalResults }: Params,\n) => {\n const cacheControl = headers.get('cache-control');\n const options = cacheControl ? { cacheHeaders: { cacheControl } } : undefined;\n\n await Promise.all(\n edges.map(async ({ cursor, node }, index) => cursorCache.set(cursor, { group, index, node, page }, options)),\n );\n\n await cursorCache.set(`${group}-metadata`, { totalPages, totalResults }, options);\n};\n","import { type CachedEdges, type Edge } from '../types.ts';\n\nexport const extractEdges = (cachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<Edge[]>((edges, cachedEdge) => [...edges, ...cachedEdge.edges], []);\n","import { type Edge } from '../types.ts';\n\nexport const extractNodes = (edges: Edge[]) => edges.map(edge => edge.node);\n","import { type CachedEdges, type Indexes } from '../types.ts';\nimport { getCurrentPageEndIndex, getCurrentPageStartIndex } from './getCurrentPageStartAndEndIndexes.ts';\n\nexport type Context = {\n endIndex: Indexes;\n resultsPerPage: number;\n startIndex: Indexes;\n};\n\nexport const getInRangeCachedEdges = (\n cachedEdgesByPage: CachedEdges[],\n { endIndex, resultsPerPage, startIndex }: Context,\n) => {\n return cachedEdgesByPage.reduce<CachedEdges[]>((inRange, cachedEdgesPage, index) => {\n const currentPageStartIndex = getCurrentPageStartIndex({ pageIndex: index, startIndex });\n\n const currentPageEndIndex = getCurrentPageEndIndex({\n endIndex,\n pageIndex: index,\n resultsPerPage,\n totalCachedPages: cachedEdgesByPage.length,\n });\n\n const cachedEdges = cachedEdgesPage.edges.slice(currentPageStartIndex, currentPageEndIndex + 1);\n inRange.push({ edges: cachedEdges, pageNumber: cachedEdgesPage.pageNumber });\n return inRange;\n }, []);\n};\n","import { type Indexes } from '../types.ts';\n\nexport type StartIndexContext = {\n pageIndex: number;\n startIndex: Indexes;\n};\n\nexport const getCurrentPageStartIndex = ({ pageIndex, startIndex }: StartIndexContext) =>\n pageIndex === 0 ? startIndex.relative : 0;\n\nexport type EndIndexContext = {\n endIndex: Indexes;\n pageIndex: number;\n resultsPerPage: number;\n totalCachedPages: number;\n};\n\nexport const getCurrentPageEndIndex = ({ endIndex, pageIndex, resultsPerPage, totalCachedPages }: EndIndexContext) =>\n pageIndex === totalCachedPages - 1 ? endIndex.relative : resultsPerPage - 1;\n","import { type Edge } from '../types.ts';\n\nexport const getStartCursor = (edges: Edge[]) => edges[0]?.cursor;\n\nexport const getEndCursor = (edges: Edge[]) => {\n const lastEdge = edges.at(-1);\n return lastEdge?.cursor;\n};\n","import { type Direction } from '../types.ts';\n\nexport const getDirection = (last?: number): Direction => (last ? 'backward' : 'forward');\n","export type Params = {\n page: number;\n totalPages: number;\n};\n\nexport const isLastPage = ({ page, totalPages }: Params) => page === totalPages;\n","import { range } from 'lodash-es';\nimport {\n type ConnectionInputOptions,\n type CursorGroupMetadata,\n type Indexes,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getEndPageNumber, getStartPageNumber } from './getStartAndEndPageNumbers.ts';\n\nexport type GetPageNumbersToRequestContext = {\n endIndex: Indexes;\n startIndex: Indexes;\n};\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getPageNumbersToRequest = (\n args: ConnectionInputOptions,\n { endIndex, entry: { page }, metadata, resultsPerPage, startIndex }: GetPageNumbersToRequestContext & Context,\n) => {\n const startPageNumber = getStartPageNumber(args, { page, resultsPerPage, startIndex });\n const endPageNumber = getEndPageNumber(args, { endIndex, metadata, page, resultsPerPage });\n\n if (startPageNumber === endPageNumber) {\n return [page];\n }\n\n return [...range(startPageNumber, endPageNumber), endPageNumber];\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type PageNumberContext = {\n endIndex: Indexes;\n page: number;\n startIndex: Indexes;\n};\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartPageNumber = (\n args: ConnectionInputOptions,\n { page, resultsPerPage, startIndex }: Omit<PageNumberContext, 'endIndex'> & Omit<Context, 'metadata'>,\n) => {\n if (getDirection(args.last) === 'forward' || startIndex.absolute >= 0) {\n return page;\n }\n\n const startPageNumber = page - Math.ceil(Math.abs(startIndex.absolute) / resultsPerPage);\n return Math.max(startPageNumber, 1);\n};\n\nexport const getEndPageNumber = (\n args: ConnectionInputOptions,\n { endIndex, metadata: { totalPages }, page, resultsPerPage }: Omit<PageNumberContext, 'startIndex'> & Context,\n) => {\n const indexesPerPage = resultsPerPage - 1;\n\n if (\n getDirection(args.last) === 'backward' ||\n isLastPage({ page, totalPages }) ||\n endIndex.absolute <= indexesPerPage\n ) {\n return page;\n }\n\n const endPageNumber = page + Math.ceil((endIndex.absolute - indexesPerPage) / resultsPerPage);\n return Math.min(endPageNumber, totalPages);\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\n// Based on how ConnectionInputOptions are generated, either first\n// or last would be set.\n// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\nexport const getCount = ({ first, last }: ConnectionInputOptions) => first ?? last!;\n","import { type Params, getResultsOnLastPage } from './getResultsOnLastPage.ts';\n\nexport const getIndexesOnLastPage = ({ resultsPerPage, totalResults }: Params) =>\n getResultsOnLastPage({ resultsPerPage, totalResults }) - 1;\n","export type Params = {\n resultsPerPage: number;\n totalResults: number;\n};\n\nexport const getResultsOnLastPage = ({ resultsPerPage, totalResults }: Params) => {\n const remainder = totalResults % resultsPerPage;\n return remainder === 0 ? resultsPerPage : remainder;\n};\n","import { isNumber } from 'lodash-es';\nimport { type CachedEdges, type CursorGroupMetadata, type Indexes } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type HasPreviousPageParams = {\n cachedEdgesByPage: CachedEdges[];\n startIndex: Indexes;\n};\n\nexport type HasNextPageParams = {\n cachedEdgesByPage: CachedEdges[];\n endIndex: Indexes;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const hasPreviousPage = ({ cachedEdgesByPage, startIndex }: HasPreviousPageParams) =>\n (isNumber(cachedEdgesByPage[0]?.pageNumber) && cachedEdgesByPage[0]?.pageNumber !== 1) || startIndex.relative > 0;\n\nexport const hasNextPage = ({\n cachedEdgesByPage,\n endIndex,\n metadata: { totalPages, totalResults },\n resultsPerPage,\n}: HasNextPageParams) =>\n (isNumber(cachedEdgesByPage.at(-1)?.pageNumber) && cachedEdgesByPage.at(-1)?.pageNumber !== totalPages) ||\n endIndex.relative < getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type Core } from '@cachemap/core';\nimport { type CursorCacheEntry, type Edge } from '../types.ts';\n\nexport type Context = {\n groupCursor: string;\n pageNumber: number;\n};\n\nexport const retrieveCachedEdgesByPage = async (cursorCache: Core, { groupCursor, pageNumber }: Context) => {\n const { entries, metadata } = await cursorCache.export<CursorCacheEntry>({\n filterByValue: [\n { comparator: pageNumber, keyChain: 'page' },\n { comparator: groupCursor, keyChain: 'group' },\n ],\n });\n\n return {\n edges: entries.reduce<Edge[]>((cached, [key, { index, node }]) => {\n if (metadata[index]?.cacheability.checkTTL()) {\n cached[index] = { cursor: key, node };\n }\n\n return cached;\n }, []),\n pageNumber,\n };\n};\n","import { type ConnectionInputOptions } from '../types.ts';\n\nexport const getCursor = ({ after, before }: ConnectionInputOptions) => before ?? after;\n","import { type Core } from '@cachemap/core';\nimport {\n type ConnectionInputOptions,\n type CursorCacheEntry,\n type CursorGroupMetadata,\n type PartialCursorCacheEntry,\n} from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { makeEntry } from './makeEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n resultsPerPage: number;\n};\n\nexport const retrieveEntry = async (\n args: ConnectionInputOptions,\n metadata: CursorGroupMetadata,\n { cursorCache, resultsPerPage }: Context,\n): Promise<PartialCursorCacheEntry> => {\n const cursor = getCursor(args);\n\n if (cursor) {\n const cursorCacheEntry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (cursorCacheEntry) {\n return cursorCacheEntry;\n }\n }\n\n return makeEntry(args, { metadata, resultsPerPage });\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Context = {\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const makeEntry = (\n args: ConnectionInputOptions,\n { metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n if (getDirection(args.last) === 'backward') {\n return { index: getIndexesOnLastPage({ resultsPerPage, totalResults }) + 1, page: totalPages };\n }\n\n return { index: -1, page: 1 };\n};\n","import { type Core } from '@cachemap/core';\nimport { type CachedEdges, type ConnectionInputOptions, type CursorGroupMetadata } from '../types.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getPageNumbersToRequest } from './getPageNumbersToRequest.ts';\nimport { getPagesMissingFromCache } from './getPagesMissingFromCache.ts';\nimport { getEndIndex, getStartIndex } from './getStartAndEndIndexes.ts';\nimport { hasNextPage, hasPreviousPage } from './hasPreviousNextPage.ts';\nimport { retrieveCachedEdgesByPage } from './retrieveCachedEdgesByPage.ts';\nimport { retrieveEntry } from './retrieveEntry.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const retrieveCachedConnection = async (\n args: ConnectionInputOptions,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n // At this point the cache will always have metadata because `retrieveCachedConnection`\n // is called from `resolveConnection` and is only called if there is a cursor, either\n // after a direct check or after calling `validateCursor` or `requestAndCachePages`,\n // which check and set the metadata respectively.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const metadata = (await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`))!;\n const entry = await retrieveEntry(args, metadata, { cursorCache, resultsPerPage });\n const startIndex = getStartIndex(args, { entry, resultsPerPage });\n const endIndex = getEndIndex(args, { entry, metadata, resultsPerPage });\n const promises: Promise<CachedEdges>[] = [];\n const pageNumbersToRequest = getPageNumbersToRequest(args, { endIndex, entry, metadata, resultsPerPage, startIndex });\n\n for (const pageNumber of pageNumbersToRequest) {\n promises.push(retrieveCachedEdgesByPage(cursorCache, { groupCursor, pageNumber }));\n }\n\n const cachedEdgesByPage = await Promise.all(promises);\n const missingPages = getPagesMissingFromCache(cachedEdgesByPage);\n\n return {\n cachedEdges:\n missingPages.length === 0\n ? getInRangeCachedEdges(cachedEdgesByPage, { endIndex, resultsPerPage, startIndex })\n : cachedEdgesByPage,\n hasNextPage: hasNextPage({\n cachedEdgesByPage,\n endIndex,\n metadata,\n resultsPerPage,\n }),\n hasPreviousPage: hasPreviousPage({ cachedEdgesByPage, startIndex }),\n indexes: { end: endIndex, start: startIndex },\n missingPages,\n totalResults: metadata.totalResults,\n };\n};\n","import { type ConnectionInputOptions, type CursorGroupMetadata, type PartialCursorCacheEntry } from '../types.ts';\nimport { getCount } from './getCount.ts';\nimport { getDirection } from './getDirection.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\nimport { isFirstPage } from './isFirstPage.ts';\nimport { isLastPage } from './isLastPage.ts';\n\nexport type Context = {\n entry: PartialCursorCacheEntry;\n metadata: CursorGroupMetadata;\n resultsPerPage: number;\n};\n\nexport const getStartIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, resultsPerPage }: Pick<Context, 'entry' | 'resultsPerPage'>,\n) => {\n const count = getCount(args);\n\n return getDirection(args.last) === 'forward'\n ? { absolute: index + 1, relative: index + 1 }\n : isFirstPage(page) && index - count < 0\n ? { absolute: 0, relative: 0 }\n : (() => {\n const absoluteStartIndex = index - count;\n\n if (absoluteStartIndex >= 0) {\n return { absolute: absoluteStartIndex, relative: absoluteStartIndex };\n }\n\n const indexesRemainingAfterLastPage = Math.abs(absoluteStartIndex);\n const pagesRemaining = indexesRemainingAfterLastPage / resultsPerPage + 1;\n const remainder = indexesRemainingAfterLastPage % resultsPerPage;\n const relativeStartIndex = remainder === 0 ? 0 : page - pagesRemaining < 0 ? 0 : resultsPerPage - remainder;\n return { absolute: absoluteStartIndex, relative: relativeStartIndex };\n })();\n};\n\nexport const getEndIndex = (\n args: ConnectionInputOptions,\n { entry: { index, page }, metadata: { totalPages, totalResults }, resultsPerPage }: Context,\n) => {\n const count = getCount(args);\n const indexesOnLastPage = getIndexesOnLastPage({ resultsPerPage, totalResults });\n\n return getDirection(args.last) === 'backward'\n ? { absolute: index - 1, relative: index - 1 }\n : isLastPage({ page, totalPages }) && index + count > indexesOnLastPage\n ? { absolute: indexesOnLastPage, relative: indexesOnLastPage }\n : (() => {\n const absoluteEndIndex = index + count;\n const indexesPerPage = resultsPerPage - 1;\n\n if (absoluteEndIndex <= indexesPerPage) {\n return { absolute: absoluteEndIndex, relative: absoluteEndIndex };\n }\n\n const indexesRemainingAfterFirstPage = absoluteEndIndex - indexesPerPage;\n const pagesRemaining = indexesRemainingAfterFirstPage / resultsPerPage;\n const remainder = indexesRemainingAfterFirstPage % resultsPerPage;\n\n const relativeEndIndex =\n remainder === 0 ? indexesPerPage : page + pagesRemaining > totalPages ? indexesOnLastPage : remainder - 1;\n\n return { absolute: absoluteEndIndex, relative: relativeEndIndex };\n })();\n};\n","export const isFirstPage = (page: number) => page === 1;\n","import { type CachedEdges } from '../types.ts';\n\nexport const getPagesMissingFromCache = (cachedEdgesByPage: CachedEdges[]) => {\n return cachedEdgesByPage.reduce<number[]>((missing, cachedEdgesPage) => {\n if (cachedEdgesPage.edges.length === 0) {\n missing.push(cachedEdgesPage.pageNumber);\n }\n\n return missing;\n }, []);\n};\n","import { type Core } from '@cachemap/core';\nimport { type PlainObject } from '@graphql-box/core';\nimport {\n type ConnectionInputOptions,\n type Getters,\n type Node,\n type ResourceResolver,\n type SetCacheMetadata,\n} from '../types.ts';\nimport { extractEdges } from './extractEdges.ts';\nimport { extractNodes } from './extractNodes.ts';\nimport { getInRangeCachedEdges } from './getInRangeCachedEdges.ts';\nimport { getEndCursor, getStartCursor } from './getStartAndEndCursors.ts';\nimport { mergeCachedEdges } from './mergeCachedEdges.ts';\nimport { requestAndCachePages } from './requestAndCachePages.ts';\nimport { retrieveCachedConnection } from './retrieveCachedConnection.ts';\n\nexport type Context<Resource extends PlainObject, ResourceNode extends Node> = {\n cursorCache: Core;\n fieldPath: string;\n getters: Getters<Resource, ResourceNode>;\n groupCursor: string;\n makeIDCursor: (id: string | number) => string;\n resourceResolver: ResourceResolver<Resource>;\n resultsPerPage: number;\n setCacheMetadata: SetCacheMetadata | undefined;\n};\n\nexport const resolveConnection = async <Resource extends PlainObject, ResourceNode extends Node>(\n args: PlainObject & ConnectionInputOptions,\n {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }: Context<Resource, ResourceNode>,\n) => {\n const { cachedEdges, hasNextPage, hasPreviousPage, indexes, missingPages, totalResults } =\n await retrieveCachedConnection(args, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (missingPages.length === 0) {\n const edges = extractEdges(cachedEdges);\n\n return {\n edges,\n errors: [],\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n }\n\n const { cachedEdges: missingCachedEdges, errors } = await requestAndCachePages<Resource, ResourceNode>(missingPages, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n const mergedCachedEdges = getInRangeCachedEdges(mergeCachedEdges(cachedEdges, missingCachedEdges), {\n endIndex: indexes.end,\n resultsPerPage,\n startIndex: indexes.start,\n });\n\n const edges = extractEdges(mergedCachedEdges);\n\n return {\n edges,\n errors,\n nodes: extractNodes(edges),\n pageInfo: {\n endCursor: getEndCursor(edges),\n hasNextPage,\n hasPreviousPage,\n startCursor: getStartCursor(edges),\n },\n totalCount: totalResults,\n };\n};\n","import { type CachedEdges } from '../types.ts';\n\nexport const mergeCachedEdges = (cachedEdges: CachedEdges[], missingCachedEdges: CachedEdges[]) =>\n cachedEdges.reduce<CachedEdges[]>((mergedCachedEdges, cachedEdge) => {\n if (cachedEdge.edges.length === 0) {\n const missingCachedEdge = missingCachedEdges.find(missing => missing.pageNumber === cachedEdge.pageNumber);\n\n if (missingCachedEdge) {\n return [...mergedCachedEdges, missingCachedEdge];\n }\n }\n\n return [...mergedCachedEdges, cachedEdge];\n }, []);\n","import { type Core } from '@cachemap/core';\nimport { GraphQLError, type GraphQLResolveInfo } from 'graphql';\nimport { type ConnectionInputOptions, type CursorCacheEntry, type CursorGroupMetadata } from '../types.ts';\nimport { getCursor } from './getCursor.ts';\nimport { getDirection } from './getDirection.ts';\nimport { isCursorFirst } from './isCursorFirst.ts';\nimport { isCursorLast } from './isCursorLast.ts';\n\nexport type Context = {\n cursorCache: Core;\n groupCursor: string;\n resultsPerPage: number;\n};\n\nexport const validateCursor = async (\n { after, before, first, last }: ConnectionInputOptions,\n { fieldNodes }: GraphQLResolveInfo,\n { cursorCache, groupCursor, resultsPerPage }: Context,\n) => {\n if (after && !first && !last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` must be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n if (after && last) {\n return new GraphQLError(\n 'Invalid connection argument combination. `after` cannot be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && !last && !first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` must be used in combination with `last`.',\n { nodes: fieldNodes },\n );\n }\n\n if (before && first) {\n return new GraphQLError(\n 'Invalid connection argument combination. `before` cannot be used in combination with `first`.',\n { nodes: fieldNodes },\n );\n }\n\n const metadata = await cursorCache.get<CursorGroupMetadata>(`${groupCursor}-metadata`);\n\n if (!metadata) {\n return new GraphQLError('Curser cannot be supplied without previously being provided.', { nodes: fieldNodes });\n }\n\n const cursor = getCursor({ after, before });\n\n if (!cursor) {\n return new GraphQLError(`The cursor could not be found.`, { nodes: fieldNodes });\n }\n\n const entry = await cursorCache.get<CursorCacheEntry>(cursor);\n\n if (!entry) {\n return new GraphQLError(`The cursor ${cursor} could not be found.`, { nodes: fieldNodes });\n }\n\n const direction = getDirection(last);\n\n if (isCursorLast({ direction, entry, resultsPerPage, ...metadata })) {\n return new GraphQLError(`The cursor ${cursor} is the last, you cannot go forward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n if (isCursorFirst({ direction, entry })) {\n return new GraphQLError(`The cursor ${cursor} is the first, you cannot go backward any further.`, {\n nodes: fieldNodes,\n });\n }\n\n return;\n};\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\nimport { getIndexesOnLastPage } from './getIndexesOnLastPage.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n resultsPerPage: number;\n totalPages: number;\n totalResults: number;\n};\n\nexport const isCursorLast = ({ direction, entry: { index, page }, resultsPerPage, totalPages, totalResults }: Params) =>\n direction === 'forward' && page === totalPages && index === getIndexesOnLastPage({ resultsPerPage, totalResults });\n","import { type CursorCacheEntry, type Direction } from '../types.ts';\n\nexport type Params = {\n direction: Direction;\n entry: CursorCacheEntry;\n};\n\nexport const isCursorFirst = ({ direction, entry: { index, page } }: Params) =>\n direction === 'backward' && page === 1 && index === 0;\n","import { type PlainObject } from '@graphql-box/core';\nimport { type GraphQLResolveInfo } from 'graphql';\nimport { isCursorSupplied } from '../helpers/isCursorSupplied.ts';\nimport { requestAndCachePages } from '../helpers/requestAndCachePages.ts';\nimport { resolveConnection } from '../helpers/resolveConnection.ts';\nimport { validateCursor } from '../helpers/validateCursor.ts';\nimport {\n type Connection,\n type ConnectionInputOptions,\n type ConnectionResolverUserOptions,\n type Context,\n type Node,\n} from '../types.ts';\n\nexport const makeConnectionResolver =\n <\n Source extends PlainObject | undefined,\n Args extends PlainObject,\n Ctx extends Context,\n Resource extends PlainObject,\n ResourceNode extends Node,\n >({\n createMakeCursors,\n createResourceResolver,\n cursorCache,\n getters,\n resolver = result => result,\n resultsPerPage,\n }: ConnectionResolverUserOptions<Source, Args, Ctx, Resource, ResourceNode>) =>\n async (\n source: Source,\n args: Args & ConnectionInputOptions,\n context: Ctx,\n info: GraphQLResolveInfo,\n ): Promise<Connection> => {\n const { makeGroupCursor, makeIDCursor } = createMakeCursors(source, args, context, info);\n const groupCursor = makeGroupCursor();\n const { logger, setCacheMetadata } = context;\n const { fieldName: fieldPath } = info;\n\n const newCtx = {\n ...context,\n data: {\n ...context.data,\n args,\n fieldPath,\n groupCursor,\n },\n };\n\n const resourceResolver = createResourceResolver(source, args, newCtx, info);\n const childLogger = logger?.child(newCtx.data);\n childLogger?.info(`Resolving ${fieldPath}`, { logEntryName: 'RESOLVER_START' });\n\n if (isCursorSupplied(args)) {\n const cursorError = await validateCursor(args, info, {\n cursorCache,\n groupCursor,\n resultsPerPage,\n });\n\n if (cursorError) {\n childLogger?.error(`Failed to resolve ${fieldPath}, validation cursor error`, {\n errors: [cursorError],\n logEntryName: 'RESOLVER_FAILED',\n });\n\n return resolver({\n edges: [],\n errors: [cursorError],\n nodes: [],\n pageInfo: {\n hasNextPage: false,\n hasPreviousPage: false,\n },\n totalCount: 0,\n });\n }\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n if (await cursorCache.has(`${groupCursor}-metadata`)) {\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n }\n\n await requestAndCachePages<Resource, ResourceNode>([1], {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n setCacheMetadata,\n });\n\n return resolver(\n await resolveConnection(args, {\n cursorCache,\n fieldPath,\n getters,\n groupCursor,\n makeIDCursor,\n resourceResolver,\n resultsPerPage,\n setCacheMetadata,\n }),\n );\n };\n","import { type PlainObject } from '@graphql-box/core';\nimport { type ConnectionInputOptions } from '../types.ts';\n\nexport const isCursorSupplied = ({ after, before }: PlainObject & ConnectionInputOptions) => !!(after ?? before);\n"],"names":["connectionInputOptions","Set","removeConnectionInputOptions","args","pickBy","_value","key","has","requestAndCachePages","async","pages","cursorCache","fieldPath","getters","groupCursor","makeIDCursor","resourceResolver","setCacheMetadata","errors","cachedEdges","Promise","all","map","page","data","pageResultData","pageResultErrors","headers","pageResultHeaders","length","edges","nodes","makeCursor","node","id","cursor","group","totalPages","totalResults","cacheControl","get","options","cacheHeaders","undefined","index","set","cacheCursors","pageNumber","push","extractEdges","reduce","cachedEdge","extractNodes","edge","getInRangeCachedEdges","cachedEdgesByPage","endIndex","resultsPerPage","startIndex","inRange","cachedEdgesPage","currentPageStartIndex","pageIndex","relative","getCurrentPageStartIndex","currentPageEndIndex","totalCachedPages","getCurrentPageEndIndex","slice","getStartCursor","getEndCursor","lastEdge","at","getDirection","last","isLastPage","getPageNumbersToRequest","entry","metadata","startPageNumber","absolute","Math","ceil","abs","max","getStartPageNumber","endPageNumber","indexesPerPage","min","getEndPageNumber","range","getCount","first","getIndexesOnLastPage","remainder","getResultsOnLastPage","hasPreviousPage","isNumber","hasNextPage","retrieveCachedEdgesByPage","entries","export","filterByValue","comparator","keyChain","cached","cacheability","checkTTL","getCursor","after","before","retrieveEntry","cursorCacheEntry","makeEntry","retrieveCachedConnection","count","isFirstPage","absoluteStartIndex","indexesRemainingAfterLastPage","getStartIndex","indexesOnLastPage","absoluteEndIndex","indexesRemainingAfterFirstPage","getEndIndex","promises","pageNumbersToRequest","missingPages","missing","getPagesMissingFromCache","indexes","end","start","resolveConnection","pageInfo","endCursor","startCursor","totalCount","missingCachedEdges","mergedCachedEdges","missingCachedEdge","find","mergeCachedEdges","validateCursor","fieldNodes","GraphQLError","direction","isCursorLast","isCursorFirst","makeConnectionResolver","createMakeCursors","createResourceResolver","resolver","result","source","context","info","makeGroupCursor","logger","fieldName","newCtx","childLogger","child","logEntryName","isCursorSupplied","cursorError","error"],"mappings":"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"}
|