UNPKG

@geekbears/gb-mongoose-keywords-plugin

Version:
108 lines 4.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeywordsMiddleware = void 0; const lodash_1 = require("lodash"); const helpers_1 = require("./helpers"); const extraction_1 = require("./helpers/extraction"); /** * Add keyword generation for a given schema * * @description * Automatically generates keywords from the specified local and virtual paths and persists * them into a new `__keywords` field. * * @usage * Pass an object with the following options to configure the behavior of keyword generation. * * Available options are: * - `paths`: a collection of the local schema paths to generate keywords from * - `virtuals`: a map of virtual paths to be populated and generate keywords from * - `omit`: a collection of words to be omitted from the resulting keywords * * @remarks * Keywords will be generated automatically when creating a new document or updating an existing * one via `findOneAndUpdate` */ const KeywordsMiddleware = function (schema, options) { const { paths, virtuals, omit } = (0, helpers_1.validateOptions)(schema, options); /** * Generate and extract keywords based on the preconfigured schema parameters * @implementation */ schema.method('__generateKeywords', async function () { try { const document = this; const leanDoc = document.toObject({ virtuals: false, getters: false }); const localKeywords = (0, lodash_1.flatten)(paths.map(path => (0, extraction_1.extractKeywordsFromField)(leanDoc[path], omit))); const populatedKeywords = (0, lodash_1.flatten)(await Promise.all((0, lodash_1.keys)(virtuals).map(async (key) => { const virtualPaths = virtuals[key]; const populatedDoc = (await document.populate(key)).toObject({ virtuals: true }); return (0, lodash_1.flatten)(virtualPaths.map(path => (0, extraction_1.extractKeywordsFromPopulatedField)(populatedDoc[key], path, omit))); }))); const keywords = (0, lodash_1.uniq)([...localKeywords, ...populatedKeywords]); if (options.logging) console.log(`Generated keywords for ${document.$model.name}:${document._id.toString()}`, keywords); return keywords; } catch (err) { console.error(`Error generating keywords`); console.error(err); } }); /** * Generate and save this documents keywords * @implementation */ schema.method('__generateAndSaveKeywords', async function () { const document = this; const keywords = await document.__generateKeywords(); document.__keywords = [...keywords]; await document.save(); }); /** * An array containing this document's generated keywords * @remarks configure a text index on the field * @implementation */ schema.add({ __keywords: { type: [String], index: 'text', }, }); /** * Pre-Save document hook * Generate keywords when a new document is created for this collection * @remarks requires `onNew` option enabled */ schema.pre('save', async function () { if (!options.onNew) return; if (!this.isNew) return; this.__keywords = await this.__generateKeywords(); }); /** * Pre-Update query hook * Generate keywords when a document in this collection updated * @remarks requires `onUpdate` option enabled */ schema.pre('findOneAndUpdate', { query: true, document: false }, async function () { if (!options.onUpdate) return; const document = await this.model.findOne(this.getQuery()); if ((0, lodash_1.isNil)(document)) return; this.set({ __keywords: await document.__generateKeywords() }); }); schema.post('findOneAndUpdate', async function (document) { if (!options.onUpdate) return; if ((0, lodash_1.isNil)(document)) return; const __keywords = await document.__generateKeywords(); await document.updateOne({ __keywords }); }); }; exports.KeywordsMiddleware = KeywordsMiddleware; //# sourceMappingURL=keywords.plugin.js.map