├── algolia-write-key.png ├── .travis.yml ├── .eslintrc.yml ├── lib ├── helpers │ ├── search_config.js │ └── search_tag.js └── command.js ├── .gitignore ├── package.json ├── LICENSE ├── index.js ├── CHANGELOG.md └── README.md /algolia-write-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soxft/hexo-algolia/main/algolia-write-key.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - v12 4 | - node 5 | deploy: 6 | provider: npm 7 | email: $NPM_USER_EMAIL 8 | api_key: "$NPM_TOKEN" 9 | on: 10 | tags: true 11 | repo: oncletom/hexo-algolia 12 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | es6: true 3 | node: true 4 | extends: 'eslint:recommended' 5 | rules: 6 | indent: 7 | - error 8 | - 2 9 | linebreak-style: 10 | - error 11 | - unix 12 | quotes: 13 | - error 14 | - single 15 | semi: 16 | - error 17 | - always 18 | -------------------------------------------------------------------------------- /lib/helpers/search_config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(hexoConfig) { 4 | return function() { 5 | var algolia = hexoConfig.algolia; 6 | 7 | return ( 8 | '' 15 | ); 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /lib/helpers/search_tag.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var BASE_URLS = { 4 | CDN: 'https://cdn.jsdelivr.net/algoliasearch/3/', 5 | LOCAL: 'assets/algolia/' 6 | }; 7 | 8 | var DEFAULT_OPTIONS = { 9 | lite: true, 10 | min: true 11 | }; 12 | 13 | function generateScriptTags (hexo, baseUrl, options) { 14 | var opts = Object.assign({}, DEFAULT_OPTIONS, options); 15 | var filename = 16 | 'algoliasearch' + 17 | (opts.lite ? 'Lite' : '') + 18 | (opts.min ? '.min' : '') + 19 | '.js'; 20 | 21 | return ''; 22 | } 23 | 24 | /* used as <%- algolia_search_cdn({ ...}) %> */ 25 | module.exports.fromCDN = function(hexo, options) { 26 | return generateScriptTags(hexo, BASE_URLS.CDN, options); 27 | }; 28 | 29 | /* used as <%- algolia_search({ ... }) %> */ 30 | module.exports.fromNpmPackage = function(hexo, options) { 31 | return generateScriptTags(hexo, BASE_URLS.LOCAL, options); 32 | }; 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-search-algolia", 3 | "version": "1.0.8", 4 | "description": "Index content of your hexo website in Algolia and add search within minutes.", 5 | "main": "index", 6 | "directories": { 7 | "lib": "./lib" 8 | }, 9 | "scripts": { 10 | "test": "exit 0", 11 | "posttest": "eslint *.js ./lib" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/oncletom/hexo-algolia.git" 16 | }, 17 | "engines": { 18 | "node": ">= 4.0.0" 19 | }, 20 | "keywords": [ 21 | "hexo", 22 | "algolia", 23 | "search" 24 | ], 25 | "author": { 26 | "name": "Boris Schapira", 27 | "email": "borisschapira@gmail.com", 28 | "url": "http://borisschapira.com" 29 | }, 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/oncletom/hexo-algolia/issues" 33 | }, 34 | "homepage": "https://github.com/oncletom/hexo-algolia", 35 | "dependencies": { 36 | "algoliasearch": "^3.35.1", 37 | "p-each-series": "^1.0.0" 38 | }, 39 | "devDependencies": { 40 | "eslint": "^4.19.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Boris SCHAPIRA 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* globals hexo:false, console:false*/ 2 | 'use strict'; 3 | 4 | var fs = require('fs'); 5 | var path = require('path'); 6 | var command = require('./lib/command'); 7 | var searchTagHelper = require('./lib/helpers/search_tag.js'); 8 | var searchConfigHelper = require('./lib/helpers/search_config.js'); 9 | 10 | var KNOWN_ASSETS = [ 11 | 'algoliasearchLite.min.js', 12 | 'algoliasearchLite.js', 13 | 'algoliasearch.min.js', 14 | 'algoliasearch.js' 15 | ]; 16 | 17 | hexo.extend.console.register( 18 | 'algolia', 19 | 'Index your content in Algolia Search API', 20 | { 21 | options: [ 22 | { 23 | name: '--dry-run', 24 | desc: 'Does not push content to Algolia (default: false).' 25 | }, 26 | { 27 | name: '--flush', 28 | desc: 'Resets the Algolia index before starting the indexation (default: false).' 29 | }, 30 | { 31 | name: '--layouts', 32 | desc: 'A comma-separated list of page layouts to index (default: "page").', 33 | }, 34 | { 35 | name: '--indexing-key', 36 | desc: 'An algolia API key with add/delete records permissions.\n\t\t It should be different than the search-only API key configured in _config.yml.', 37 | } 38 | ] 39 | }, 40 | command 41 | ); 42 | 43 | hexo.extend.helper.register( 44 | 'algolia_search_cdn', 45 | searchTagHelper.fromCDN.bind(null, hexo) 46 | ); 47 | hexo.extend.helper.register( 48 | 'algolia_search', 49 | searchTagHelper.fromNpmPackage.bind(null, hexo) 50 | ); 51 | hexo.extend.helper.register( 52 | 'algolia_search_config', 53 | searchConfigHelper(hexo.config) 54 | ); 55 | 56 | hexo.extend.generator.register('algolia', function() { 57 | return KNOWN_ASSETS.map(function(assetFile) { 58 | var sourceFile = require.resolve('algoliasearch/dist/' + assetFile); 59 | 60 | return { 61 | path: path.join('assets', 'algolia', assetFile), 62 | data: function() { 63 | return fs.createReadStream(sourceFile); 64 | } 65 | }; 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # hexo-algolia changelog 2 | 3 | ## v1.3.2, 2021-02-12 4 | 5 | - update [algolia API client](https://www.algolia.com/doc/api-client/) to `v3.35.1` 6 | 7 | ## v1.3.1, 2018-12-19 8 | 9 | - display the number of records in the batch and content types to index ([eb2ef14](https://github.com/oncletom/hexo-algolia/commit/eb2ef14)) 10 | - wait for clearIndex task completion before moving to the indexing part ([a7218ab](https://github.com/oncletom/hexo-algolia/commit/a7218ab)) 11 | 12 | ## v1.3.0, 2018-12-09 13 | 14 | - trailing `index.html` are trimmed from page permalinks ([83f55a0](https://github.com/oncletom/hexo-algolia/commit/83f55a0)) 15 | - select which page layouts can be indexed ([922277c](https://github.com/oncletom/hexo-algolia/commit/922277c)) 16 | - provide an indexing API key from the command line ([fd5ae30](https://github.com/oncletom/hexo-algolia/commit/fd5ae30)) 17 | - index the `image` property ([7990bed](https://github.com/oncletom/hexo-algolia/commit/7990bed)) 18 | - restore `post.categories` and `post.tags indexing` ([830ef22](https://github.com/oncletom/hexo-algolia/commit/830ef22)) 19 | - update `algoliasearch` to `v3.31.0` ([f1f27a6](https://github.com/oncletom/hexo-algolia/commit/f1f27a6)) 20 | 21 | ## v1.2.5, 2018-04-05 22 | 23 | - index tags/categories only if they are arrays ([#33](https://github.com/oncletom/hexo-algolia/issues/33)) 24 | - update dependencies ([3b8bfce](https://github.com/oncletom/hexo-algolia/commit/3b8bfce)) 25 | 26 | ## v1.2.4, 2017-12-17 27 | 28 | - Fix `--flush` flag documentation ([#30](https://github.com/oncletom/hexo-algolia/pull/30)) 29 | 30 | ## v1.2.3, 2017-08-31 31 | 32 | - remove lodash from dependencies ([#25](https://github.com/oncletom/hexo-algolia/pull/25)) 33 | 34 | ## v1.2.2, 2017-08-31 35 | 36 | - do not index `page.content` as it causes the indexing to fail if it is bigger than 10kB ([#24](https://github.com/oncletom/hexo-algolia/pull/24), [#15](https://github.com/oncletom/hexo-algolia/issues/15)) 37 | - index `page.updated` (and its `page.updated_as_int` counterpart) [#24](https://github.com/oncletom/hexo-algolia/pull/24) 38 | 39 | ## v1.2.1, 2017-08-25 40 | 41 | - add clearer signposting for error reasons, esp no API key or Admin Key provided ([#22](https://github.com/oncletom/hexo-algolia/pull/22), [#15](https://github.com/oncletom/hexo-algolia/issues/15)) 42 | 43 | ## v1.2.0, 2017-08-25 44 | 45 | - remove chunk size from options — the default was decreased from `5000` to `50` items at a time 46 | - index pages along with publishedPosts in the index ([#21](https://github.com/oncletom/hexo-algolia/pull/21), [#18](https://github.com/oncletom/hexo-algolia/issues/18)) 47 | - fix helper name in docs ([#16](https://github.com/oncletom/hexo-algolia/pull/16)) 48 | 49 | ## v1.1.0, 2017-06-08 50 | 51 | - add `algolia_search()`, `algolia_search_cdn()` and `algolia_search_config()` hexo helpers ([#13](https://github.com/oncletom/hexo-algolia/pull/13)) 52 | 53 | ## v1.0.1, 2017-06-01 54 | 55 | - node>=4.0.0 jshint compat 56 | 57 | ## v1.0.0, 2017-06-01 58 | 59 | - rename flags, remove AdminAPIKey from config and document things a bit more 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hexo-algolia [![Build Status][]][pkg-build] ![][pkg-downloads] ![][pkg-version] 2 | 3 | > Index content of your [hexo][] website in [Algolia][] and add search within minutes. 4 | 5 | `hexo-algolia` is an [hexo][] plugin provided by the community. 6 | This is what you get when you install it: 7 | 8 | 1. a **new command**, `hexo algolia`, to index the content of your website 9 | 2. a **theme helper** to include Algolia search client 10 | 3. another **theme helper** to configure the Algolia search client 11 | 12 | 👌 The `hexo algolia` command can be run manually on your computer 13 | and on a continuous integration system like [Travis CI][-ci-node]. 14 | 15 | 📜 Browse the [CHANGELOG][] to learn what has changed between versions. 16 | ⬢ Compatible with `node>=4.0.0`. 17 | 18 | [hexo theme][] 19 | 20 | ## Install 21 | 22 | ```bash 23 | $ npm install --save hexo-algolia 24 | ``` 25 | 26 | ## Public Facing Search Options 27 | 28 | You can configure Algolia integration to your hexo website with the `_config.yml` file: 29 | 30 | ``` yaml 31 | algolia: 32 | applicationID: 'applicationID' 33 | apiKey: 'apiKey' 34 | indexName: '...' 35 | ``` 36 | 37 | | Config Key | | 38 | | --- | --- | 39 | | `applicationID` | Your Algolia Application ID | 40 | | `apiKey` | A **Search-Only** API key | 41 | | `indexName` | The name of the Algolia index to use | 42 | 43 | These configuration values are **accessible from your hexo theme**, to be used with [Algolia JavaScript client](https://www.algolia.com/doc/guides/search/auto-complete/#user-interface). 44 | 45 | ## Hexo Theme Setup 46 | 47 | Helpers are provided to make your life easier. 48 | 49 | ### Include Algolia JavaScript Client 50 | 51 | The `algolia_search` theme helper adds the 52 | [Algolia search client][js-client] to your pages. 53 | 54 | ```html 55 | <%- algolia_search() %> 56 | ``` 57 | 58 | Renders as: 59 | 60 | ```html 61 | 62 | ``` 63 | 64 | 65 | ### Configure Algolia JavaScript Client 66 | 67 | You can make your index configuration available to your page and client-side scripts by adding the `algolia_config()` hexo helper in the `` of your document. 68 | 69 | ```html 70 | <%- algolia_search_config() %> 71 | ``` 72 | 73 | Once done, you can retrieve Algolia configuration by querying the 74 | [`data attribute`](dataset) of the `algolia:search` meta tag. 75 | 76 | ```js 77 | const algoliaConfig = document.querySelector('meta[property="algolia:search"]').dataset; 78 | 79 | const client = algoliasearch(algoliaConfig.applicationId, algoliaConfig.apiKey); 80 | const index = client.initIndex(algoliaConfig.indexName); 81 | ``` 82 | 83 | ### Display Search Results 84 | 85 | It is now up to you to use the aforementioned example to trigger a search 86 | and display the results in your page. 87 | 88 | If you need some help, have a look at the [search client doc][js-client] 89 | and [the tutorials][Algolia tutorials]. 90 | 91 | ## Indexing Content 92 | 93 | Content is indexed with the help of the `hexo algolia` command. 94 | 95 | ```bash 96 | $ ./node_modules/.bin/hexo algolia 97 | ``` 98 | 99 | ### API Key 100 | 101 | A separate _API Key_ must be provided as an **environment variable** named `HEXO_ALGOLIA_INDEXING_KEY`. Create it with **these limited write access** permissions: `Add records`, `Delete records`, `List indices`, `Delete index`. 102 | 103 | ```bash 104 | $ export HEXO_ALGOLIA_INDEXING_KEY=… 105 | $ ./node_modules/.bin/hexo algolia 106 | ``` 107 | ![](algolia-write-key.png) 108 | 109 | ### Usage 110 | 111 | ``` 112 | $ ./node_modules/.bin/hexo help algolia 113 | Usage: ./node_modules/.bin/hexo algolia 114 | 115 | Description: 116 | Index your content in Algolia Search API 117 | 118 | Options: 119 | --dry-run Does not push content to Algolia (default: false). 120 | --flush Resets the Algolia index before starting the indexation (default: false). 121 | --indexing-key An algolia API key with add/delete records permissions. 122 | It should be different than the search-only API key configured in _config.yml. 123 | --layouts A comma-separated list of page layouts to index (default: "page"). 124 | ``` 125 | 126 | ### Security Concerns 127 | 128 | **Never store your _Admin API Key_** as `apiKey` in the `_config.yml` file: **it would give full control of your Algolia index to others** and [you don't want to face the consequences][daily-mirror-bonanza]. 129 | 130 | [Please read Algolia Security guide thoroughly][security] if you need some more informations about this. 131 | 132 | # License 133 | 134 | [MIT](LICENSE) 135 | 136 | [Build Status]: https://travis-ci.org/oncletom/hexo-algolia.svg?branch=master 137 | [pkg-build]: https://travis-ci.org/oncletom/hexo-algolia 138 | [pkg-downloads]: https://img.shields.io/npm/dm/hexo-algolia.svg 139 | [pkg-version]: https://img.shields.io/npm/v/hexo-algolia.svg 140 | 141 | [hexo]: https://hexo.io/ 142 | [Algolia]: https://www.algolia.com/ 143 | [hexo theme]: https://hexo.io/docs/themes.html 144 | [travis-ci-node]: https://docs.travis-ci.com/user/languages/javascript-with-nodejs/ 145 | [Algolia Tutorials]: https://www.algolia.com/doc/tutorials/ 146 | 147 | [CHANGELOG]: https://github.com/oncletom/hexo-algolia/blob/master/CHANGELOG.md 148 | 149 | [js-client]: https://www.algolia.com/doc/api-client/javascript/ 150 | [batching]: https://www.algolia.com/doc/guides/indexing/import-synchronize-data/#batching 151 | [security]: https://www.algolia.com/doc/guides/security/api-keys/ 152 | [dataset]: https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes 153 | [daily-mirror-bonanza]: http://www.mirror.co.uk/all-about/cybersecurity 154 | -------------------------------------------------------------------------------- /lib/command.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var each = require('p-each-series'); 4 | var algoliasearch = require('algoliasearch'); 5 | var crypto = require('crypto'); 6 | 7 | var INDEXED_LAYOUTS = 'page'; 8 | 9 | var CONSOLE_DEFAULTS = { 10 | dryRun: false, 11 | flush: false, 12 | chunkSize: 50, 13 | layouts: INDEXED_LAYOUTS 14 | }; 15 | 16 | var INDEXED_PROPERTIES = [ 17 | 'title', 18 | 'date', 19 | 'updated', 20 | 'slug', 21 | 'excerpt', 22 | 'permalink', 23 | 'layout', 24 | 'image' 25 | ]; 26 | 27 | function computeSha1(text) { 28 | return crypto.createHash('sha1').update(text, 'utf8').digest('hex'); 29 | } 30 | 31 | function pick(object, properties) { 32 | return properties.reduce(function(filteredObj, prop) { 33 | filteredObj[prop] = object[prop]; 34 | return filteredObj; 35 | }, {}); 36 | } 37 | 38 | function chunk(array, chunkSize) { 39 | var batches = []; 40 | 41 | while (array.length > 0) { 42 | batches.push(array.splice(0, chunkSize)); 43 | } 44 | 45 | return batches; 46 | } 47 | 48 | module.exports = function(args, callback) { 49 | var hexo = this; 50 | var config = Object.assign({}, hexo.config.algolia); 51 | var indexName = config.indexName; 52 | var applicationID = config.applicationID; 53 | var options = Object.assign({}, CONSOLE_DEFAULTS, args || {}); 54 | var pageLayouts = options.layouts.split(','); 55 | var apiKey = String(process.env.HEXO_ALGOLIA_INDEXING_KEY || options.indexingKey || ''); 56 | var client; 57 | var index; 58 | 59 | Promise.resolve(apiKey) 60 | .then(function(){ 61 | if (!apiKey) { 62 | hexo.log.error('[hexo-algolia] Please set an `HEXO_ALGOLIA_INDEXING_KEY` environment variable to enable content indexing.'); 63 | hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#api-key'); 64 | process.exit(1); 65 | } 66 | 67 | if (!indexName) { 68 | hexo.log.error('[hexo-algolia] Please provide an Algolia index name in your hexo _config.yml file.'); 69 | hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#public-facing-search-options'); 70 | process.exit(1); 71 | } 72 | 73 | client = algoliasearch(applicationID, apiKey); 74 | index = client.initIndex(indexName); 75 | }) 76 | .then(function(){ 77 | hexo.log.info('[hexo-algolia] Testing HEXO_ALGOLIA_INDEXING_KEY permissions.'); 78 | 79 | return client.getApiKey(apiKey) 80 | .catch(function(err){ 81 | hexo.log.error('[hexo-algolia] %s', err.message); 82 | hexo.log.error('>> You might have used an Admin Key or an invalid Key.'); 83 | hexo.log.error('>> Read %s for more informations.', 'https://npmjs.com/hexo-algolia#security-concerns'); 84 | process.exit(1); 85 | }); 86 | }) 87 | .then(function() { 88 | return hexo.load(); 89 | }) 90 | .then(function() { 91 | var posts = hexo.database.model('Post').find({ published: true, hidden: {$ne: true} }).sort('date', 'asc'); 92 | return posts.toArray(); 93 | }) 94 | .then(function(publishedPosts) { 95 | var pages = hexo.database.model('Page').find({ 96 | layout: { '$in': pageLayouts } 97 | }); 98 | 99 | return publishedPosts.concat(pages.toArray()); 100 | }) 101 | .then(function(publishedPagesAndPosts) { 102 | return publishedPagesAndPosts.map(function(data) { 103 | var storedPost = pick(data, INDEXED_PROPERTIES); 104 | 105 | storedPost.objectID = computeSha1(data.path); 106 | storedPost.date_as_int = Date.parse(data.date) / 1000; 107 | storedPost.updated_as_int = Date.parse(data.updated) / 1000; 108 | storedPost.permalink = storedPost.permalink.replace(/\/index.html$/, '/'); 109 | 110 | if (data.categories && (Array.isArray(data.categories) || typeof data.categories.toArray === 'function')) { 111 | storedPost.categories = (data.categories.toArray ? data.categories.toArray() : data.categories).map(function(item) { 112 | return pick(item, ['name', 'path']); 113 | }); 114 | } 115 | 116 | if (data.tags && (Array.isArray(data.tags) || typeof data.tags.toArray === 'function')) { 117 | storedPost.tags = (data.tags.toArray ? data.tags.toArray() : data.tags).map(function(item) { 118 | return pick(item, ['name', 'path']); 119 | }); 120 | } 121 | 122 | storedPost.author = data.author || config.author; 123 | 124 | return storedPost; 125 | }); 126 | }) 127 | .then(function(publishedPagesAndPosts) { 128 | hexo.log.info( 129 | '[hexo-algolia] %d records to index (%s).', 130 | publishedPagesAndPosts.length, 131 | ['post'].concat(pageLayouts).join(', ') 132 | ); 133 | 134 | return publishedPagesAndPosts.map(function toAlgoliaBatchActions(post) { 135 | return { 136 | action: 'updateObject', 137 | indexName: indexName, 138 | body: post 139 | }; 140 | }); 141 | }) 142 | .then(function(actions) { 143 | if (options.dryRun) { 144 | hexo.log.info('[hexo-algolia] Skipping due to --dry-run option'); 145 | return; 146 | } 147 | 148 | return Promise.resolve(options.flush) 149 | .then(function(flush) { 150 | if (flush) { 151 | hexo.log.info('[hexo-algolia] Clearing index...'); 152 | 153 | return new Promise(function(resolve, reject){ 154 | index.clearIndex(function(error, content){ 155 | if (error) { 156 | return reject(error); 157 | } 158 | 159 | index.waitTask(content.taskID, function(error) { 160 | if (error) { 161 | return reject(error); 162 | } 163 | 164 | return resolve(); 165 | }); 166 | }); 167 | }); 168 | } 169 | }) 170 | .then(function() { 171 | var chunks = chunk(actions, options.chunkSize); 172 | 173 | return each(chunks, function(chunk, i) { 174 | hexo.log.info( 175 | '[hexo-algolia] Indexing chunk %d of %d (%d records)', 176 | i + 1, 177 | chunks.length, 178 | chunk.length 179 | ); 180 | 181 | return client.batch(chunk) 182 | .catch(function(err){ 183 | hexo.log.error('[hexo-algolia] %s', err.message); 184 | }); 185 | }); 186 | }) 187 | 188 | .then(function() { 189 | hexo.log.info('[hexo-algolia] Indexing done.'); 190 | }); 191 | }) 192 | .catch(callback); 193 | }; 194 | --------------------------------------------------------------------------------