You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

208 lines
6.8 KiB

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.getFieldsWithFilters = exports.getBasicFields = exports.preparePosts = exports.splitIntoChunks = exports.upperFirst = exports.pick = void 0;
var _striptags = _interopRequireDefault(require("striptags"));
var _algoliasearch = _interopRequireDefault(require("algoliasearch"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
const FILTER_FUNCTIONS = {
strip: _striptags.default,
truncate: function truncate(post, start, end) {
return post.substr(start, end);
}
};
/**
* Pick specified attributes of a given object
*
* @param {Object} object - The object to pick the attribute from
* @param {Array} attributes - The attributes to pick from the given object
* @returns {Object}
*/
const pick = (object, attributes) => {
const newObject = {};
attributes.forEach(attribute => {
if (object.hasOwnProperty(attribute)) {
newObject[attribute] = object[attribute];
}
});
return newObject;
};
/**
* Upper case the first character of a string
*
* @param {String} string - The string to update
* @returns {string}
*/
exports.pick = pick;
const upperFirst = string => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
/**
* Split an `Array` into chunk
*
* @param {Array} array - The `Array` to split
* @param {Number} chunkSize - The size of the chunks
* @returns {Array}
*/
exports.upperFirst = upperFirst;
const splitIntoChunks = (array, chunkSize) => {
const newArrays = array.slice(0);
const chunks = [];
while (newArrays.length) {
chunks.push(newArrays.splice(0, chunkSize));
}
return chunks;
};
/**
* Pick speficied fields of posts
*
* @param {Object} posts - The posts to prepare
* @param {Array} fields - The fields of the posts to select
* @param {Array} fieldsWithFilters - The fields of the posts to select
* @returns {Object} posts - The posts ready to be indexed
*/
exports.splitIntoChunks = splitIntoChunks;
const preparePosts = (posts, fields, fieldsWithFilters) => {
const tagsAndCategoriesFields = ['tags', 'categories'].filter(field => fields.includes(field));
return posts.map(initialPost => {
const postToIndex = pick(initialPost, fields); // define a unique ID to identfy this post on Algolia
postToIndex.objectID = initialPost._id; // extract tags and categories
tagsAndCategoriesFields.forEach(field => {
postToIndex[field] = [];
initialPost[field].data.forEach(function (fieldElement) {
postToIndex[field].push(fieldElement.name);
});
}); // execute filters of fields
fieldsWithFilters.forEach(field => {
const indexedFieldName = [];
const fieldFilters = field.split(':');
const fieldName = fieldFilters.shift();
if (!initialPost.hasOwnProperty(fieldName)) {
hexo.log.warn(`"${initialPost.title}" post has no "${fieldName}" field.`);
return;
}
let fieldValue = initialPost[fieldName];
fieldFilters.forEach(function (filter) {
const filterArgs = filter.split(',');
const filterName = filterArgs.shift();
indexedFieldName.push(upperFirst(filterName));
filterArgs.unshift(fieldValue); // execute filter on field value
fieldValue = FILTER_FUNCTIONS[filterName].apply(this, filterArgs);
}); // store filter result in post object
postToIndex[fieldName + indexedFieldName.join('')] = fieldValue;
});
return postToIndex;
});
};
/**
* Get fields without filters
*
* @param {Array} fields - A list of fields. E.g: content, excerpt, categories, etc...
* @returns {Array} - A list of fields without any filters
*/
exports.preparePosts = preparePosts;
const getBasicFields = fields => fields.filter(field => !/:/.test(field));
/**
* Get fields with filters
*
* @param {Array} fields - A list of fields. E.g: content, excerpt, categories, etc...
* @returns {Array} - A list of fields with filters
*/
exports.getBasicFields = getBasicFields;
const getFieldsWithFilters = fields => fields.filter(field => /:/.test(field));
exports.getFieldsWithFilters = getFieldsWithFilters;
const algoliaCommand = /*#__PURE__*/function () {
var _ref = _asyncToGenerator(function* (hexo, args, callback) {
const algoliaConfig = hexo.config.algolia;
const fields = getBasicFields(algoliaConfig.fields);
const fieldsWithFilters = getFieldsWithFilters(algoliaConfig.fields);
const algoliaAppId = process.env.ALGOLIA_APP_ID || algoliaConfig.appId;
const algoliaAdminApiKey = process.env.ALGOLIA_ADMIN_API_KEY || algoliaConfig.adminApiKey;
const algoliaIndexName = process.env.ALGOLIA_INDEX_NAME || algoliaConfig.indexName; // Algolia recommendation: split posts into chunks of 5000 to get a good indexing/insert performance
const algoliaChunkSize = algoliaConfig.chunkSize || 5000;
yield hexo.call('generate');
yield hexo.database.load();
let posts = hexo.database.model('Post').find({
published: true
}).sort('date', 'asc').toArray();
if (!posts.length) {
hexo.log.info('There is no post to index.');
return callback();
}
posts = preparePosts(posts, fields, fieldsWithFilters);
const chunkedPosts = splitIntoChunks(posts, algoliaChunkSize);
const algoliaClient = (0, _algoliasearch.default)(algoliaAppId, algoliaAdminApiKey);
const algoliaIndex = algoliaClient.initIndex(algoliaIndexName);
if (args && !args.n) {
hexo.log.info('Clearing index on Algolia...');
try {
yield algoliaIndex.clearObjects();
} catch (error) {
hexo.log.info(`Error has occurred during clearing index : ${error}`);
return callback(error);
}
hexo.log.info('Index cleared.');
}
hexo.log.info('Indexing posts on Algolia...');
try {
yield Promise.all(chunkedPosts.map(posts => algoliaIndex.saveObjects(posts)));
} catch (error) {
hexo.log.info(`Error has occurred during indexing posts : ${error}`);
return callback(error);
}
hexo.log.info(`${posts.length} posts indexed.`);
});
return function algoliaCommand(_x, _x2, _x3) {
return _ref.apply(this, arguments);
};
}();
var _default = algoliaCommand;
exports.default = _default;