UNPKG

@woovi/graphql-mongoose-loader

Version:
228 lines (227 loc) 8.69 kB
"use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.d = (exports1, definition)=>{ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { enumerable: true, get: definition[key] }); }; })(); (()=>{ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); })(); (()=>{ __webpack_require__.r = (exports1)=>{ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { value: 'Module' }); Object.defineProperty(exports1, '__esModule', { value: true }); }; })(); var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { connectionFromMongoCursor: ()=>ConnectionFromMongoCursor, mongooseLoader: ()=>mongooseLoader, unbase64: ()=>unbase64, calculateOffsets: ()=>calculateOffsets, offsetToCursor: ()=>offsetToCursor, getPageInfo: ()=>getPageInfo, base64: ()=>base64, connectionFromMongoAggregate: ()=>ConnectionFromMongoAggregate, getOffsetWithDefault: ()=>getOffsetWithDefault, getTotalCount: ()=>getTotalCount, cursorToOffset: ()=>cursorToOffset }); const PREFIX = 'mongo:'; const base64 = (str)=>Buffer.from(str, 'ascii').toString('base64'); const unbase64 = (b64)=>Buffer.from(b64, 'base64').toString('ascii'); const cursorToOffset = (cursor)=>parseInt(unbase64(cursor).substring(PREFIX.length), 10); const getOffsetWithDefault = (cursor, defaultOffset)=>{ if (null == cursor) return defaultOffset; const offset = cursorToOffset(cursor); return isNaN(offset) ? defaultOffset : offset; }; const offsetToCursor = (offset)=>base64(PREFIX + offset); const getTotalCount = async ({ cursor, useEstimatedCount = false, lean = true })=>{ const clonedCursor = lean ? cursor.model.find().lean().merge(cursor) : cursor.model.find().merge(cursor); return useEstimatedCount ? clonedCursor.estimatedDocumentCount() : clonedCursor.countDocuments(); }; const calculateOffsets = ({ args, totalCount })=>{ const { after, before } = args; let { first, last } = args; if (!first && !last) first = 10; if (first && first > 1000) first = 1000; if (last && last > 1000) last = 1000; const beforeOffset = getOffsetWithDefault(before || null, totalCount); const afterOffset = getOffsetWithDefault(after || null, -1); let startOffset = Math.max(-1, afterOffset) + 1; let endOffset = Math.min(totalCount, beforeOffset); if (null != first) endOffset = Math.min(endOffset, startOffset + first); if (null != last) startOffset = Math.max(startOffset, endOffset - (last || 0)); const skip = Math.max(startOffset, 0); const safeLimit = Math.max(endOffset - startOffset, 1); const limitOffset = Math.max(endOffset - startOffset, 0); return { first: first || null, last: last || null, before: before || null, after: after || null, skip, limit: safeLimit, beforeOffset, afterOffset, startOffset, endOffset, startCursorOffset: skip, endCursorOffset: limitOffset + skip }; }; function getPageInfo({ edges, totalCount, startCursorOffset, endCursorOffset }) { const firstEdge = edges[0]; const lastEdge = edges[edges.length - 1]; return { startCursor: firstEdge ? firstEdge.cursor : null, endCursor: lastEdge ? lastEdge.cursor : null, hasPreviousPage: startCursorOffset > 0, hasNextPage: endCursorOffset < totalCount }; } async function connectionFromMongoCursor({ cursor, context, args = {}, loader, raw = false, useEstimatedCount = false, lean = true }) { const clonedCursor = lean ? cursor.model.find().lean().merge(cursor) : cursor.model.find().merge(cursor); const totalCount = await getTotalCount({ cursor: clonedCursor, useEstimatedCount, lean }); const { first, last, before, after, skip, limit, beforeOffset, afterOffset, startOffset, endOffset, startCursorOffset, endCursorOffset } = calculateOffsets({ args, totalCount }); clonedCursor.skip(skip); clonedCursor.limit(limit); const slice = await clonedCursor.select(raw ? {} : { _id: 1 }).exec(); const edges = slice.map((value, index)=>({ cursor: offsetToCursor(startOffset + index), node: loader(context, raw ? value : value._id) })); return { edges, count: totalCount, endCursorOffset, startCursorOffset, pageInfo: getPageInfo({ edges, before, after, first, last, afterOffset, beforeOffset, startOffset, endOffset, totalCount, startCursorOffset, endCursorOffset }) }; } const ConnectionFromMongoCursor = connectionFromMongoCursor; const cloneAggregate = (aggregate)=>aggregate._model.aggregate(aggregate.pipeline()); async function connectionFromMongoAggregate({ aggregate, context, args = {}, loader, raw = false, allowDiskUse = false }) { const clonedAggregate = cloneAggregate(aggregate).allowDiskUse(allowDiskUse); const resultCount = await cloneAggregate(aggregate).allowDiskUse(allowDiskUse).count('total'); const totalCount = resultCount.length ? resultCount[0].total : 0; const { first, last, before, after, skip, limit, beforeOffset, afterOffset, startOffset, endOffset, startCursorOffset, endCursorOffset } = calculateOffsets({ args, totalCount }); clonedAggregate.skip(skip); clonedAggregate.limit(limit || 1); const slice = await (raw ? clonedAggregate : clonedAggregate.project({ _id: 1 })); const edges = slice.map((value, index)=>({ cursor: offsetToCursor(startOffset + index), node: loader(context, raw ? value : value._id) })); return { edges, count: totalCount, endCursorOffset, startCursorOffset, pageInfo: getPageInfo({ edges, before, after, first, last, afterOffset, beforeOffset, startOffset, endOffset, totalCount, startCursorOffset, endCursorOffset }) }; } const ConnectionFromMongoAggregate = connectionFromMongoAggregate; function indexResults(results, indexField, cacheKey = cacheKeyFn) { const indexedResults = new Map(); results.forEach((res)=>{ indexedResults.set(cacheKey(res[indexField]), res); }); return indexedResults; } function normalizeResults(keys, indexField, cacheKey = cacheKeyFn) { return (results)=>{ const indexedResults = indexResults(results, indexField, cacheKey); return keys.map((val)=>indexedResults.get(cacheKey(val)) || new Error(`Key not found : ${val}`)); }; } const cacheKeyFn = (key)=>key.toString(); async function mongooseLoader(model, keys, lean = true, keyField = '_id') { const results = lean ? await model.find({ [keyField]: { $in: keys } }).lean() : await model.find({ [keyField]: { $in: keys } }); return normalizeResults(keys, keyField, cacheKeyFn)(results); } exports.base64 = __webpack_exports__.base64; exports.calculateOffsets = __webpack_exports__.calculateOffsets; exports.connectionFromMongoAggregate = __webpack_exports__.connectionFromMongoAggregate; exports.connectionFromMongoCursor = __webpack_exports__.connectionFromMongoCursor; exports.cursorToOffset = __webpack_exports__.cursorToOffset; exports.getOffsetWithDefault = __webpack_exports__.getOffsetWithDefault; exports.getPageInfo = __webpack_exports__.getPageInfo; exports.getTotalCount = __webpack_exports__.getTotalCount; exports.mongooseLoader = __webpack_exports__.mongooseLoader; exports.offsetToCursor = __webpack_exports__.offsetToCursor; exports.unbase64 = __webpack_exports__.unbase64; for(var __webpack_i__ in __webpack_exports__)if (-1 === [ "base64", "calculateOffsets", "connectionFromMongoAggregate", "connectionFromMongoCursor", "cursorToOffset", "getOffsetWithDefault", "getPageInfo", "getTotalCount", "mongooseLoader", "offsetToCursor", "unbase64" ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; Object.defineProperty(exports, '__esModule', { value: true });