Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

hexo-azuresearch

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hexo-azuresearch - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

CHANGELOG.md

6

index.js
'use strict';
var azuresearch = require('./lib/azuresearch');
const AzureSearch = require('./lib/azuresearch');
hexo.extend.console.register('azuresearch', 'Index posts on Azure Search', {
options: []
}, azuresearch);
}, (options, callback) => {
AzureSearch(hexo, options, callback);
});

@@ -0,18 +1,128 @@

const HexoUtil = require('hexo-util');
const Axios = require('axios');
/**
* Index Hexo posts and upload to Azure Search
* Based on hexo-algoliasearch (https://github.com/LouisBarranqueiro/hexo-algoliasearch)
* @param args {Object}
* @param callback {Function}
* Extract a list type metadata from an Hexo post.
* @param {object} post a hexo post object
* @param {prop} prop property name e.g. tags
*/
function AzureSearch(args, callback) {
var _ = require('lodash');
var hexoUtil = require('hexo-util');
var async = require('async');
var request = require('request');
var Q = require('q');
const transformListProp = (post, prop) => {
const items = [];
Object.keys(post[prop].data).forEach(item => {
if (item.name) {
items.push(item.name);
}
});
return items;
}
var hexo = this;
var config = hexo.config.AzureSearch;
var log = hexo.log;
var fields = [
/**
* Trnasform a Hexo post to an AzureSearch document.
* @param {object} post a hexo post object
* @prarm {object} config azure search config
* @return post
*/
const transformPost = (post, config) => {
return {
postId: post.slug,
permalink: post.permalink,
path: post.path,
title: post.title,
date: post.date.format('YYYY-MM-DDTHH:mm:ss.SSSZ'),
excerpt: post.excerpt || HexoUtil.truncate(HexoUtil.stripHTML(post.content), {
length: config.excerptLimit || 200,
omission: '...',
separator: ''
}),
tags: transformListProp(post, 'tags'),
categories: transformListProp(post, 'categories'),
'@search.action': 'mergeOrUpload'
};
object.tags = getProperty(post, 'tags');
object.categories = getProperty(post, 'categories');
return object;
}
/**
* Create or update an AzureSearch index.
* @param hexo
* @param indexFields
* @param config
* @returns {Promise<*>}
*/
const putIndex = async (hexo, indexFields, config) => {
const { serviceURL, serviceUrl, indexName, apiVersion, adminKey } = config;
const url = `${serviceURL || serviceUrl}/indexes/${indexName}?api-version=${apiVersion}`;
const headers = {
'api-key': config.adminKey,
'Content-Type': 'application/json'
};
try {
const response = await Axios({
method: 'put',
url,
headers,
data: {
name: indexName,
fields: indexFields,
corsOptions: {
allowedOrigins: ['*'],
maxAgeInSeconds: 300
}
},
});
hexo.log.info('AzureSearch created index.');
if (config.verbose) {
hexo.log.info(JSON.stringify(response.data));
}
return Promise.resolve(response);
} catch (e) {
hexo.log.error('AzureSearch failed to put index.');
hexo.log.error(e);
hexo.log.error(JSON.stringify(e.response.data));
return Promise.reject(e);
}
};
/**
* Index a post to AzureSearch.
* @param hexo
* @param posts
* @param config
* @returns {Promise<void|any>}
*/
const indexDocuments = async (hexo, posts, config) => {
const { serviceURL, serviceUrl, indexName, apiVersion, adminKey } = config;
const url = `${serviceURL || serviceUrl}/indexes/${indexName}/docs/index?api-version=${apiVersion}`;
const headers = {
'api-key': config.adminKey,
'Content-Type': 'application/json'
};
try {
const response = await Axios({
method: 'post',
url,
headers,
data: {
value: posts
},
});
hexo.log.info('AzureSearch indexed documents.');
if (config.verbose) {
hexo.log.info(JSON.stringify(response.data));
}
return Promise.resolve(response);
} catch (e) {
hexo.log.error('AzureSearch failed to index documents.');
hexo.log.error(JSON.stringify(e.response.data));
return Promise.reject(e);
}
};
const AzureSearch = async (hexo, args, callback) => {
const config = {
...hexo.config.AzureSearch,
apiVersion: '2019-05-06'
};
const fields = [
{

@@ -103,172 +213,39 @@ "name": "postId",

];
var fieldList = ['title', 'date', 'excerpt', 'permalink', 'path', 'tags', 'categories'];
var posts = [];
config.apiVersion = "2015-02-28";
const fieldNames = fields.map(field => field.name);
const posts = [];
/**
* Process a post
* @param post {Object} a hexo post object
* @return post {Object} a post extracted object for algolia
*/
function processPost(post) {
var key = null;
var object = {};
hexo.extend.filter.register('after_post_render', function(post) {
if (post.published) {
posts.push(transformPost(post, config));
}
return post;
});
object = _.pick(post, fieldList);
object['@search.action'] = 'mergeOrUpload';
object.postId = post.slug;
object.tags = getProperty(post, 'tags');
object.categories = getProperty(post, 'categories');
object.date = post.date.format('YYYY-MM-DDTHH:mm:ss.SSSZ');
object.excerpt = hexoUtil.truncate(hexoUtil.stripHTML(post.content), {
length: config.excerptLimit || 200,
omission: "...",
separator: ""
});
return object;
}
const log = hexo.log;
/**
* Extract a given property from an hexo post object
* @param post {Object} a hexo post object
* @param property {String} a property name of hexo post objects
*/
function getProperty(post, property) {
var tags = [];
for (var key in post[property].data) {
if (post[property].data.hasOwnProperty(key)) {
if (post[property].data[key].hasOwnProperty('name')) {
tags.push(post[property].data[key].name);
}
}
log.info('AzureSearch is claning up posts...');
hexo.call('clean', (err) => {
if (err) {
log.info('AzureSearch failed to clean up posts : ' + err);
return callback(err);
}
return tags;
}
/**
* Delete the existing index on azure search
* no param
*/
function deleteIndex() {
var deferred = Q.defer();
var url = config.serviceURL + '/indexes/' +config.indexName+ '?api-version=' +config.apiVersion;
var headers = {
'api-key': config.adminKey,
'Content-type': 'application/json'
};
var options = {
url: url,
headers: headers,
withCredentials: false
};
request.del(options, function(error, response, body) {
log.info('delete index result: ' + response.statusCode);
log.info(body);
deferred.resolve();
});
return deferred.promise;
}
/**
* Create a new index on azure search
* no param
*/
function createIndex() {
var deferred = Q.defer();
var url = config.serviceURL + "/indexes/" +config.indexName+ "?api-version=" +config.apiVersion;
var headers = {
'api-key': config.adminKey,
'Content-Type': 'application/json'
};
var options = {
url: url,
headers: headers,
body: JSON.stringify({
"name": config.indexName,
"fields": fields,
"scoringProfiles": [],
"defaultScoringProfile": null,
"corsOptions": {
"allowedOrigins": ["*"],
"maxAgeInSeconds": 300
},
"suggesters": []
}),
withCredentials: false
};
request.put(options, function(error, response, body){
log.info("create index result: " + response.statusCode);
log.info(body);
deferred.resolve();
});
return deferred.promise;
}
/**
* Upload generated posts data to Azure Search
* no param
*/
function uploadData() {
var deferred = Q.defer();
var url = config.serviceURL + '/indexes/' +config.indexName+ "/docs/index?api-version=" +config.apiVersion;
var headers = {
'api-key': config.adminKey,
'Content-type': 'application/json'
};
var options = {
url: url,
headers: headers,
body: JSON.stringify({
"value": posts
}),
withCredentials: false
};
request.post(options, function(error, response, body) {
log.info("upload posts result: " + response.statusCode);
log.info(body);
if (response.statusCode === 200) {
log.info("Successfully uploaded index data to Azure Search.");
hexo.call('generate', {}).then(async (err) => {
if (err) {
log.info('AzureSearch failed to generate posts : ' + err);
return callback(err);
}
deferred.resolve();
});
return deferred.promise;
}
log.info(`AzureSearch collected ${posts.length} posts.`);
/**
* Initialization
* no param
*/
function init() {
hexo.extend.filter.register('after_post_render', function(post) {
if (post.published) {
posts.push(processPost(post));
try {
await putIndex(hexo, fields, config);
await indexDocuments(hexo, posts, config);
} catch (e) {
log.error('AzureSearch exit due to error');
}
return post;
});
});
};
log.info('Clearing posts ...');
hexo.call('clean', function(err) {
if (err) {
log.info('Failed to clear posts : ' + err);
return callback(err);
}
hexo.call('generate', {}).then(function(err) {
if (err) {
log.info('Failed to generate posts : ' + err);
return callback(err);
}
log.info(posts.length + ' posts collected.');
deleteIndex()
.then(createIndex)
.then(uploadData);
});
});
}
init();
}
module.exports = AzureSearch;
module.exports = AzureSearch;
{
"name": "hexo-azuresearch",
"version": "1.0.0",
"version": "1.1.0",
"description": "Azure search support for Hexo.",
"main": "index.js",
"scripts": {},
"scripts": {
"release": "standard-version"
},
"repository": {

@@ -12,5 +14,6 @@ "type": "git",

"keywords": [
"hexo",
"hexo-plugin",
"azure",
"search",
"hexo"
"search"
],

@@ -27,8 +30,8 @@ "author": {

"dependencies": {
"async": "^2.0.1",
"hexo-util": "^0.6.0",
"lodash": "^4.15.0",
"q": "^1.4.1",
"request": "^2.74.0"
"axios": "^0.19.2",
"hexo-util": "^2.1.0"
},
"devDependencies": {
"standard-version": "^8.0.0"
}
}

@@ -28,6 +28,6 @@ # hexo-azuresearch

This command will automatically first clean then re-generate your hexo site. You DON'T need to `hexo clean` first.
This command will automatically re-generate the hexo site. You don't need to `hexo clean`.
```bash
hexo azuresearch
```
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc