aboutsummaryrefslogtreecommitdiff
path: root/node_modules/algoliasearch/src/Index.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/algoliasearch/src/Index.js')
-rw-r--r--node_modules/algoliasearch/src/Index.js1249
1 files changed, 1249 insertions, 0 deletions
diff --git a/node_modules/algoliasearch/src/Index.js b/node_modules/algoliasearch/src/Index.js
new file mode 100644
index 00000000..99e5a196
--- /dev/null
+++ b/node_modules/algoliasearch/src/Index.js
@@ -0,0 +1,1249 @@
+var inherits = require('inherits');
+var IndexCore = require('./IndexCore.js');
+var deprecate = require('./deprecate.js');
+var deprecatedMessage = require('./deprecatedMessage.js');
+var exitPromise = require('./exitPromise.js');
+var errors = require('./errors');
+
+var deprecateForwardToSlaves = deprecate(
+ function() {},
+ deprecatedMessage('forwardToSlaves', 'forwardToReplicas')
+);
+
+module.exports = Index;
+
+function Index() {
+ IndexCore.apply(this, arguments);
+}
+
+inherits(Index, IndexCore);
+
+/*
+* Add an object in this index
+*
+* @param content contains the javascript object to add inside the index
+* @param objectID (optional) an objectID you want to attribute to this object
+* (if the attribute already exist the old object will be overwrite)
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that contains 3 elements: createAt, taskId and objectID
+*/
+Index.prototype.addObject = function(content, objectID, callback) {
+ var indexObj = this;
+
+ if (arguments.length === 1 || typeof objectID === 'function') {
+ callback = objectID;
+ objectID = undefined;
+ }
+
+ return this.as._jsonRequest({
+ method: objectID !== undefined ?
+ 'PUT' : // update or create
+ 'POST', // create (API generates an objectID)
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + // create
+ (objectID !== undefined ? '/' + encodeURIComponent(objectID) : ''), // update or create
+ body: content,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Add several objects
+*
+* @param objects contains an array of objects to add
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that updateAt and taskID
+*/
+Index.prototype.addObjects = function(objects, callback) {
+ var isArray = require('isarray');
+ var usage = 'Usage: index.addObjects(arrayOfObjects[, callback])';
+
+ if (!isArray(objects)) {
+ throw new Error(usage);
+ }
+
+ var indexObj = this;
+ var postObj = {
+ requests: []
+ };
+ for (var i = 0; i < objects.length; ++i) {
+ var request = {
+ action: 'addObject',
+ body: objects[i]
+ };
+ postObj.requests.push(request);
+ }
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/batch',
+ body: postObj,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Update partially an object (only update attributes passed in argument)
+*
+* @param partialObject contains the javascript attributes to override, the
+* object must contains an objectID attribute
+* @param createIfNotExists (optional) if false, avoid an automatic creation of the object
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that contains 3 elements: createAt, taskId and objectID
+*/
+Index.prototype.partialUpdateObject = function(partialObject, createIfNotExists, callback) {
+ if (arguments.length === 1 || typeof createIfNotExists === 'function') {
+ callback = createIfNotExists;
+ createIfNotExists = undefined;
+ }
+
+ var indexObj = this;
+ var url = '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/' + encodeURIComponent(partialObject.objectID) + '/partial';
+ if (createIfNotExists === false) {
+ url += '?createIfNotExists=false';
+ }
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: url,
+ body: partialObject,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Partially Override the content of several objects
+*
+* @param objects contains an array of objects to update (each object must contains a objectID attribute)
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that updateAt and taskID
+*/
+Index.prototype.partialUpdateObjects = function(objects, createIfNotExists, callback) {
+ if (arguments.length === 1 || typeof createIfNotExists === 'function') {
+ callback = createIfNotExists;
+ createIfNotExists = true;
+ }
+
+ var isArray = require('isarray');
+ var usage = 'Usage: index.partialUpdateObjects(arrayOfObjects[, callback])';
+
+ if (!isArray(objects)) {
+ throw new Error(usage);
+ }
+
+ var indexObj = this;
+ var postObj = {
+ requests: []
+ };
+ for (var i = 0; i < objects.length; ++i) {
+ var request = {
+ action: createIfNotExists === true ? 'partialUpdateObject' : 'partialUpdateObjectNoCreate',
+ objectID: objects[i].objectID,
+ body: objects[i]
+ };
+ postObj.requests.push(request);
+ }
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/batch',
+ body: postObj,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Override the content of object
+*
+* @param object contains the javascript object to save, the object must contains an objectID attribute
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that updateAt and taskID
+*/
+Index.prototype.saveObject = function(object, callback) {
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'PUT',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/' + encodeURIComponent(object.objectID),
+ body: object,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Override the content of several objects
+*
+* @param objects contains an array of objects to update (each object must contains a objectID attribute)
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that updateAt and taskID
+*/
+Index.prototype.saveObjects = function(objects, callback) {
+ var isArray = require('isarray');
+ var usage = 'Usage: index.saveObjects(arrayOfObjects[, callback])';
+
+ if (!isArray(objects)) {
+ throw new Error(usage);
+ }
+
+ var indexObj = this;
+ var postObj = {
+ requests: []
+ };
+ for (var i = 0; i < objects.length; ++i) {
+ var request = {
+ action: 'updateObject',
+ objectID: objects[i].objectID,
+ body: objects[i]
+ };
+ postObj.requests.push(request);
+ }
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/batch',
+ body: postObj,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Delete an object from the index
+*
+* @param objectID the unique identifier of object to delete
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that contains 3 elements: createAt, taskId and objectID
+*/
+Index.prototype.deleteObject = function(objectID, callback) {
+ if (typeof objectID === 'function' || typeof objectID !== 'string' && typeof objectID !== 'number') {
+ var err = new errors.AlgoliaSearchError(
+ objectID && typeof objectID !== 'function'
+ ? 'ObjectID must be a string'
+ : 'Cannot delete an object without an objectID'
+ );
+ callback = objectID;
+ if (typeof callback === 'function') {
+ return callback(err);
+ }
+
+ return this.as._promise.reject(err);
+ }
+
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'DELETE',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/' + encodeURIComponent(objectID),
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Delete several objects from an index
+*
+* @param objectIDs contains an array of objectID to delete
+* @param callback (optional) the result callback called with two arguments:
+* error: null or Error('message')
+* content: the server answer that contains 3 elements: createAt, taskId and objectID
+*/
+Index.prototype.deleteObjects = function(objectIDs, callback) {
+ var isArray = require('isarray');
+ var map = require('./map.js');
+
+ var usage = 'Usage: index.deleteObjects(arrayOfObjectIDs[, callback])';
+
+ if (!isArray(objectIDs)) {
+ throw new Error(usage);
+ }
+
+ var indexObj = this;
+ var postObj = {
+ requests: map(objectIDs, function prepareRequest(objectID) {
+ return {
+ action: 'deleteObject',
+ objectID: objectID,
+ body: {
+ objectID: objectID
+ }
+ };
+ })
+ };
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/batch',
+ body: postObj,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Delete all objects matching a query
+*
+* @param query the query string
+* @param params the optional query parameters
+* @param callback (optional) the result callback called with one argument
+* error: null or Error('message')
+* @deprecated see index.deleteBy
+*/
+Index.prototype.deleteByQuery = deprecate(function(query, params, callback) {
+ var clone = require('./clone.js');
+ var map = require('./map.js');
+
+ var indexObj = this;
+ var client = indexObj.as;
+
+ if (arguments.length === 1 || typeof params === 'function') {
+ callback = params;
+ params = {};
+ } else {
+ params = clone(params);
+ }
+
+ params.attributesToRetrieve = 'objectID';
+ params.hitsPerPage = 1000;
+ params.distinct = false;
+
+ // when deleting, we should never use cache to get the
+ // search results
+ this.clearCache();
+
+ // there's a problem in how we use the promise chain,
+ // see how waitTask is done
+ var promise = this
+ .search(query, params)
+ .then(stopOrDelete);
+
+ function stopOrDelete(searchContent) {
+ // stop here
+ if (searchContent.nbHits === 0) {
+ // return indexObj.as._request.resolve();
+ return searchContent;
+ }
+
+ // continue and do a recursive call
+ var objectIDs = map(searchContent.hits, function getObjectID(object) {
+ return object.objectID;
+ });
+
+ return indexObj
+ .deleteObjects(objectIDs)
+ .then(waitTask)
+ .then(doDeleteByQuery);
+ }
+
+ function waitTask(deleteObjectsContent) {
+ return indexObj.waitTask(deleteObjectsContent.taskID);
+ }
+
+ function doDeleteByQuery() {
+ return indexObj.deleteByQuery(query, params);
+ }
+
+ if (!callback) {
+ return promise;
+ }
+
+ promise.then(success, failure);
+
+ function success() {
+ exitPromise(function exit() {
+ callback(null);
+ }, client._setTimeout || setTimeout);
+ }
+
+ function failure(err) {
+ exitPromise(function exit() {
+ callback(err);
+ }, client._setTimeout || setTimeout);
+ }
+}, deprecatedMessage('index.deleteByQuery()', 'index.deleteBy()'));
+
+/**
+* Delete all objects matching a query
+*
+* the query parameters that can be used are:
+* - filters (numeric, facet, tag)
+* - geo
+*
+* you can not send an empty query or filters
+*
+* @param params the optional query parameters
+* @param callback (optional) the result callback called with one argument
+* error: null or Error('message')
+*/
+Index.prototype.deleteBy = function(params, callback) {
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/deleteByQuery',
+ body: {params: indexObj.as._getSearchParams(params, '')},
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Browse all content from an index using events. Basically this will do
+* .browse() -> .browseFrom -> .browseFrom -> .. until all the results are returned
+*
+* @param {string} query - The full text query
+* @param {Object} [queryParameters] - Any search query parameter
+* @return {EventEmitter}
+* @example
+* var browser = index.browseAll('cool songs', {
+* tagFilters: 'public,comments',
+* hitsPerPage: 500
+* });
+*
+* browser.on('result', function resultCallback(content) {
+* console.log(content.hits);
+* });
+*
+* // if any error occurs, you get it
+* browser.on('error', function(err) {
+* throw err;
+* });
+*
+* // when you have browsed the whole index, you get this event
+* browser.on('end', function() {
+* console.log('finished');
+* });
+*
+* // at any point if you want to stop the browsing process, you can stop it manually
+* // otherwise it will go on and on
+* browser.stop();
+*
+* @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
+*/
+Index.prototype.browseAll = function(query, queryParameters) {
+ if (typeof query === 'object') {
+ queryParameters = query;
+ query = undefined;
+ }
+
+ var merge = require('./merge.js');
+
+ var IndexBrowser = require('./IndexBrowser');
+
+ var browser = new IndexBrowser();
+ var client = this.as;
+ var index = this;
+ var params = client._getSearchParams(
+ merge({}, queryParameters || {}, {
+ query: query
+ }), ''
+ );
+
+ // start browsing
+ browseLoop();
+
+ function browseLoop(cursor) {
+ if (browser._stopped) {
+ return;
+ }
+
+ var body;
+
+ if (cursor !== undefined) {
+ body = {
+ cursor: cursor
+ };
+ } else {
+ body = {
+ params: params
+ };
+ }
+
+ client._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(index.indexName) + '/browse',
+ hostType: 'read',
+ body: body,
+ callback: browseCallback
+ });
+ }
+
+ function browseCallback(err, content) {
+ if (browser._stopped) {
+ return;
+ }
+
+ if (err) {
+ browser._error(err);
+ return;
+ }
+
+ browser._result(content);
+
+ // no cursor means we are finished browsing
+ if (content.cursor === undefined) {
+ browser._end();
+ return;
+ }
+
+ browseLoop(content.cursor);
+ }
+
+ return browser;
+};
+
+/*
+* Get a Typeahead.js adapter
+* @param searchParams contains an object with query parameters (see search for details)
+*/
+Index.prototype.ttAdapter = deprecate(function(params) {
+ var self = this;
+ return function ttAdapter(query, syncCb, asyncCb) {
+ var cb;
+
+ if (typeof asyncCb === 'function') {
+ // typeahead 0.11
+ cb = asyncCb;
+ } else {
+ // pre typeahead 0.11
+ cb = syncCb;
+ }
+
+ self.search(query, params, function searchDone(err, content) {
+ if (err) {
+ cb(err);
+ return;
+ }
+
+ cb(content.hits);
+ });
+ };
+},
+'ttAdapter is not necessary anymore and will be removed in the next version,\n' +
+'have a look at autocomplete.js (https://github.com/algolia/autocomplete.js)');
+
+/*
+* Wait the publication of a task on the server.
+* All server task are asynchronous and you can check with this method that the task is published.
+*
+* @param taskID the id of the task returned by server
+* @param callback the result callback with with two arguments:
+* error: null or Error('message')
+* content: the server answer that contains the list of results
+*/
+Index.prototype.waitTask = function(taskID, callback) {
+ // wait minimum 100ms before retrying
+ var baseDelay = 100;
+ // wait maximum 5s before retrying
+ var maxDelay = 5000;
+ var loop = 0;
+
+ // waitTask() must be handled differently from other methods,
+ // it's a recursive method using a timeout
+ var indexObj = this;
+ var client = indexObj.as;
+
+ var promise = retryLoop();
+
+ function retryLoop() {
+ return client._jsonRequest({
+ method: 'GET',
+ hostType: 'read',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/task/' + taskID
+ }).then(function success(content) {
+ loop++;
+ var delay = baseDelay * loop * loop;
+ if (delay > maxDelay) {
+ delay = maxDelay;
+ }
+
+ if (content.status !== 'published') {
+ return client._promise.delay(delay).then(retryLoop);
+ }
+
+ return content;
+ });
+ }
+
+ if (!callback) {
+ return promise;
+ }
+
+ promise.then(successCb, failureCb);
+
+ function successCb(content) {
+ exitPromise(function exit() {
+ callback(null, content);
+ }, client._setTimeout || setTimeout);
+ }
+
+ function failureCb(err) {
+ exitPromise(function exit() {
+ callback(err);
+ }, client._setTimeout || setTimeout);
+ }
+};
+
+/*
+* This function deletes the index content. Settings and index specific API keys are kept untouched.
+*
+* @param callback (optional) the result callback called with two arguments
+* error: null or Error('message')
+* content: the settings object or the error message if a failure occured
+*/
+Index.prototype.clearIndex = function(callback) {
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/clear',
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+/*
+* Get settings of this index
+*
+* @param opts an object of options to add
+* @param opts.advanced get more settings like nbShards (useful for Enterprise)
+* @param callback (optional) the result callback called with two arguments
+* error: null or Error('message')
+* content: the settings object or the error message if a failure occurred
+*/
+Index.prototype.getSettings = function(opts, callback) {
+ if (arguments.length === 1 && typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+ opts = opts || {};
+
+ var indexName = encodeURIComponent(this.indexName);
+ return this.as._jsonRequest({
+ method: 'GET',
+ url:
+ '/1/indexes/' +
+ indexName +
+ '/settings?getVersion=2' +
+ (opts.advanced ? '&advanced=' + opts.advanced : ''),
+ hostType: 'read',
+ callback: callback
+ });
+};
+
+Index.prototype.searchSynonyms = function(params, callback) {
+ if (typeof params === 'function') {
+ callback = params;
+ params = {};
+ } else if (params === undefined) {
+ params = {};
+ }
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/synonyms/search',
+ body: params,
+ hostType: 'read',
+ callback: callback
+ });
+};
+
+function exportData(method, _hitsPerPage, callback) {
+ function search(page, _previous) {
+ var options = {
+ page: page || 0,
+ hitsPerPage: _hitsPerPage || 100
+ };
+ var previous = _previous || [];
+
+ return method(options).then(function(result) {
+ var hits = result.hits;
+ var nbHits = result.nbHits;
+ var current = hits.map(function(s) {
+ delete s._highlightResult;
+ return s;
+ });
+ var synonyms = previous.concat(current);
+ if (synonyms.length < nbHits) {
+ return search(options.page + 1, synonyms);
+ }
+ return synonyms;
+ });
+ }
+ return search().then(function(data) {
+ if (typeof callback === 'function') {
+ callback(data);
+ return undefined;
+ }
+ return data;
+ });
+}
+
+/**
+ * Retrieve all the synonyms in an index
+ * @param [number=100] hitsPerPage The amount of synonyms to retrieve per batch
+ * @param [function] callback will be called after all synonyms are retrieved
+ */
+Index.prototype.exportSynonyms = function(hitsPerPage, callback) {
+ return exportData(this.searchSynonyms.bind(this), hitsPerPage, callback);
+};
+
+Index.prototype.saveSynonym = function(synonym, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ if (opts.forwardToSlaves !== undefined) deprecateForwardToSlaves();
+ var forwardToReplicas = (opts.forwardToSlaves || opts.forwardToReplicas) ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'PUT',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/synonyms/' + encodeURIComponent(synonym.objectID) +
+ '?forwardToReplicas=' + forwardToReplicas,
+ body: synonym,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+Index.prototype.getSynonym = function(objectID, callback) {
+ return this.as._jsonRequest({
+ method: 'GET',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/synonyms/' + encodeURIComponent(objectID),
+ hostType: 'read',
+ callback: callback
+ });
+};
+
+Index.prototype.deleteSynonym = function(objectID, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ if (opts.forwardToSlaves !== undefined) deprecateForwardToSlaves();
+ var forwardToReplicas = (opts.forwardToSlaves || opts.forwardToReplicas) ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'DELETE',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/synonyms/' + encodeURIComponent(objectID) +
+ '?forwardToReplicas=' + forwardToReplicas,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+Index.prototype.clearSynonyms = function(opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ if (opts.forwardToSlaves !== undefined) deprecateForwardToSlaves();
+ var forwardToReplicas = (opts.forwardToSlaves || opts.forwardToReplicas) ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/synonyms/clear' +
+ '?forwardToReplicas=' + forwardToReplicas,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+Index.prototype.batchSynonyms = function(synonyms, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ if (opts.forwardToSlaves !== undefined) deprecateForwardToSlaves();
+ var forwardToReplicas = (opts.forwardToSlaves || opts.forwardToReplicas) ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/synonyms/batch' +
+ '?forwardToReplicas=' + forwardToReplicas +
+ '&replaceExistingSynonyms=' + (opts.replaceExistingSynonyms ? 'true' : 'false'),
+ hostType: 'write',
+ body: synonyms,
+ callback: callback
+ });
+};
+
+Index.prototype.searchRules = function(params, callback) {
+ if (typeof params === 'function') {
+ callback = params;
+ params = {};
+ } else if (params === undefined) {
+ params = {};
+ }
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/rules/search',
+ body: params,
+ hostType: 'read',
+ callback: callback
+ });
+};
+/**
+ * Retrieve all the query rules in an index
+ * @param [number=100] hitsPerPage The amount of query rules to retrieve per batch
+ * @param [function] callback will be called after all query rules are retrieved
+ * error: null or Error('message')
+ */
+Index.prototype.exportRules = function(hitsPerPage, callback) {
+ return exportData(this.searchRules.bind(this), hitsPerPage, callback);
+};
+
+Index.prototype.saveRule = function(rule, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ if (!rule.objectID) {
+ throw new errors.AlgoliaSearchError('Missing or empty objectID field for rule');
+ }
+
+ var forwardToReplicas = opts.forwardToReplicas === true ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'PUT',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/rules/' + encodeURIComponent(rule.objectID) +
+ '?forwardToReplicas=' + forwardToReplicas,
+ body: rule,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+Index.prototype.getRule = function(objectID, callback) {
+ return this.as._jsonRequest({
+ method: 'GET',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/rules/' + encodeURIComponent(objectID),
+ hostType: 'read',
+ callback: callback
+ });
+};
+
+Index.prototype.deleteRule = function(objectID, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ var forwardToReplicas = opts.forwardToReplicas === true ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'DELETE',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/rules/' + encodeURIComponent(objectID) +
+ '?forwardToReplicas=' + forwardToReplicas,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+Index.prototype.clearRules = function(opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ var forwardToReplicas = opts.forwardToReplicas === true ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/rules/clear' +
+ '?forwardToReplicas=' + forwardToReplicas,
+ hostType: 'write',
+ callback: callback
+ });
+};
+
+Index.prototype.batchRules = function(rules, opts, callback) {
+ if (typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ } else if (opts === undefined) {
+ opts = {};
+ }
+
+ var forwardToReplicas = opts.forwardToReplicas === true ? 'true' : 'false';
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/rules/batch' +
+ '?forwardToReplicas=' + forwardToReplicas +
+ '&clearExistingRules=' + (opts.clearExistingRules === true ? 'true' : 'false'),
+ hostType: 'write',
+ body: rules,
+ callback: callback
+ });
+};
+
+/*
+* Set settings for this index
+*
+* @param settigns the settings object that can contains :
+* - minWordSizefor1Typo: (integer) the minimum number of characters to accept one typo (default = 3).
+* - minWordSizefor2Typos: (integer) the minimum number of characters to accept two typos (default = 7).
+* - hitsPerPage: (integer) the number of hits per page (default = 10).
+* - attributesToRetrieve: (array of strings) default list of attributes to retrieve in objects.
+* If set to null, all attributes are retrieved.
+* - attributesToHighlight: (array of strings) default list of attributes to highlight.
+* If set to null, all indexed attributes are highlighted.
+* - attributesToSnippet**: (array of strings) default list of attributes to snippet alongside the number
+* of words to return (syntax is attributeName:nbWords).
+* By default no snippet is computed. If set to null, no snippet is computed.
+* - attributesToIndex: (array of strings) the list of fields you want to index.
+* If set to null, all textual and numerical attributes of your objects are indexed,
+* but you should update it to get optimal results.
+* This parameter has two important uses:
+* - Limit the attributes to index: For example if you store a binary image in base64,
+* you want to store it and be able to
+* retrieve it but you don't want to search in the base64 string.
+* - Control part of the ranking*: (see the ranking parameter for full explanation)
+* Matches in attributes at the beginning of
+* the list will be considered more important than matches in attributes further down the list.
+* In one attribute, matching text at the beginning of the attribute will be
+* considered more important than text after, you can disable
+* this behavior if you add your attribute inside `unordered(AttributeName)`,
+* for example attributesToIndex: ["title", "unordered(text)"].
+* - attributesForFaceting: (array of strings) The list of fields you want to use for faceting.
+* All strings in the attribute selected for faceting are extracted and added as a facet.
+* If set to null, no attribute is used for faceting.
+* - attributeForDistinct: (string) The attribute name used for the Distinct feature.
+* This feature is similar to the SQL "distinct" keyword: when enabled
+* in query with the distinct=1 parameter, all hits containing a duplicate
+* value for this attribute are removed from results.
+* For example, if the chosen attribute is show_name and several hits have
+* the same value for show_name, then only the best one is kept and others are removed.
+* - ranking: (array of strings) controls the way results are sorted.
+* We have six available criteria:
+* - typo: sort according to number of typos,
+* - geo: sort according to decreassing distance when performing a geo-location based search,
+* - proximity: sort according to the proximity of query words in hits,
+* - attribute: sort according to the order of attributes defined by attributesToIndex,
+* - exact:
+* - if the user query contains one word: sort objects having an attribute
+* that is exactly the query word before others.
+* For example if you search for the "V" TV show, you want to find it
+* with the "V" query and avoid to have all popular TV
+* show starting by the v letter before it.
+* - if the user query contains multiple words: sort according to the
+* number of words that matched exactly (and not as a prefix).
+* - custom: sort according to a user defined formula set in **customRanking** attribute.
+* The standard order is ["typo", "geo", "proximity", "attribute", "exact", "custom"]
+* - customRanking: (array of strings) lets you specify part of the ranking.
+* The syntax of this condition is an array of strings containing attributes
+* prefixed by asc (ascending order) or desc (descending order) operator.
+* For example `"customRanking" => ["desc(population)", "asc(name)"]`
+* - queryType: Select how the query words are interpreted, it can be one of the following value:
+* - prefixAll: all query words are interpreted as prefixes,
+* - prefixLast: only the last word is interpreted as a prefix (default behavior),
+* - prefixNone: no query word is interpreted as a prefix. This option is not recommended.
+* - highlightPreTag: (string) Specify the string that is inserted before
+* the highlighted parts in the query result (default to "<em>").
+* - highlightPostTag: (string) Specify the string that is inserted after
+* the highlighted parts in the query result (default to "</em>").
+* - optionalWords: (array of strings) Specify a list of words that should
+* be considered as optional when found in the query.
+* @param callback (optional) the result callback called with two arguments
+* error: null or Error('message')
+* content: the server answer or the error message if a failure occured
+*/
+Index.prototype.setSettings = function(settings, opts, callback) {
+ if (arguments.length === 1 || typeof opts === 'function') {
+ callback = opts;
+ opts = {};
+ }
+
+ if (opts.forwardToSlaves !== undefined) deprecateForwardToSlaves();
+ var forwardToReplicas = (opts.forwardToSlaves || opts.forwardToReplicas) ? 'true' : 'false';
+
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'PUT',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/settings?forwardToReplicas='
+ + forwardToReplicas,
+ hostType: 'write',
+ body: settings,
+ callback: callback
+ });
+};
+
+/*
+* @deprecated see client.listApiKeys()
+*/
+Index.prototype.listUserKeys = deprecate(function(callback) {
+ return this.listApiKeys(callback);
+}, deprecatedMessage('index.listUserKeys()', 'client.listApiKeys()'));
+
+/*
+* List all existing API keys to this index
+*
+* @param callback the result callback called with two arguments
+* error: null or Error('message')
+* content: the server answer with API keys belonging to the index
+*
+* @deprecated see client.listApiKeys()
+*/
+Index.prototype.listApiKeys = deprecate(function(callback) {
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'GET',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/keys',
+ hostType: 'read',
+ callback: callback
+ });
+}, deprecatedMessage('index.listApiKeys()', 'client.listApiKeys()'));
+
+/*
+* @deprecated see client.getApiKey()
+*/
+Index.prototype.getUserKeyACL = deprecate(function(key, callback) {
+ return this.getApiKey(key, callback);
+}, deprecatedMessage('index.getUserKeyACL()', 'client.getApiKey()'));
+
+
+/*
+* Get an API key from this index
+*
+* @param key
+* @param callback the result callback called with two arguments
+* error: null or Error('message')
+* content: the server answer with the right API key
+*
+* @deprecated see client.getApiKey()
+*/
+Index.prototype.getApiKey = deprecate(function(key, callback) {
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'GET',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/keys/' + key,
+ hostType: 'read',
+ callback: callback
+ });
+}, deprecatedMessage('index.getApiKey()', 'client.getApiKey()'));
+
+/*
+* @deprecated see client.deleteApiKey()
+*/
+Index.prototype.deleteUserKey = deprecate(function(key, callback) {
+ return this.deleteApiKey(key, callback);
+}, deprecatedMessage('index.deleteUserKey()', 'client.deleteApiKey()'));
+
+/*
+* Delete an existing API key associated to this index
+*
+* @param key
+* @param callback the result callback called with two arguments
+* error: null or Error('message')
+* content: the server answer with the deletion date
+*
+* @deprecated see client.deleteApiKey()
+*/
+Index.prototype.deleteApiKey = deprecate(function(key, callback) {
+ var indexObj = this;
+ return this.as._jsonRequest({
+ method: 'DELETE',
+ url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/keys/' + key,
+ hostType: 'write',
+ callback: callback
+ });
+}, deprecatedMessage('index.deleteApiKey()', 'client.deleteApiKey()'));
+
+/*
+* @deprecated see client.addApiKey()
+*/
+Index.prototype.addUserKey = deprecate(function(acls, params, callback) {
+ return this.addApiKey(acls, params, callback);
+}, deprecatedMessage('index.addUserKey()', 'client.addApiKey()'));
+
+/*
+* Add a new API key to this index
+*
+* @param {string[]} acls - The list of ACL for this key. Defined by an array of strings that
+* can contains the following values:
+* - search: allow to search (https and http)
+* - addObject: allows to add/update an object in the index (https only)
+* - deleteObject : allows to delete an existing object (https only)
+* - deleteIndex : allows to delete index content (https only)
+* - settings : allows to get index settings (https only)
+* - editSettings : allows to change index settings (https only)
+* @param {Object} [params] - Optionnal parameters to set for the key
+* @param {number} params.validity - Number of seconds after which the key will
+* be automatically removed (0 means no time limit for this key)
+* @param {number} params.maxQueriesPerIPPerHour - Number of API calls allowed from an IP address per hour
+* @param {number} params.maxHitsPerQuery - Number of hits this API key can retrieve in one call
+* @param {string} params.description - A description for your key
+* @param {string[]} params.referers - A list of authorized referers
+* @param {Object} params.queryParameters - Force the key to use specific query parameters
+* @param {Function} callback - The result callback called with two arguments
+* error: null or Error('message')
+* content: the server answer with the added API key
+* @return {Promise|undefined} Returns a promise if no callback given
+* @example
+* index.addUserKey(['search'], {
+* validity: 300,
+* maxQueriesPerIPPerHour: 2000,
+* maxHitsPerQuery: 3,
+* description: 'Eat three fruits',
+* referers: ['*.algolia.com'],
+* queryParameters: {
+* tagFilters: ['public'],
+* }
+* })
+* @see {@link https://www.algolia.com/doc/rest_api#AddIndexKey|Algolia REST API Documentation}
+*
+* @deprecated see client.addApiKey()
+*/
+Index.prototype.addApiKey = deprecate(function(acls, params, callback) {
+ var isArray = require('isarray');
+ var usage = 'Usage: index.addApiKey(arrayOfAcls[, params, callback])';
+
+ if (!isArray(acls)) {
+ throw new Error(usage);
+ }
+
+ if (arguments.length === 1 || typeof params === 'function') {
+ callback = params;
+ params = null;
+ }
+
+ var postObj = {
+ acl: acls
+ };
+
+ if (params) {
+ postObj.validity = params.validity;
+ postObj.maxQueriesPerIPPerHour = params.maxQueriesPerIPPerHour;
+ postObj.maxHitsPerQuery = params.maxHitsPerQuery;
+ postObj.description = params.description;
+
+ if (params.queryParameters) {
+ postObj.queryParameters = this.as._getSearchParams(params.queryParameters, '');
+ }
+
+ postObj.referers = params.referers;
+ }
+
+ return this.as._jsonRequest({
+ method: 'POST',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/keys',
+ body: postObj,
+ hostType: 'write',
+ callback: callback
+ });
+}, deprecatedMessage('index.addApiKey()', 'client.addApiKey()'));
+
+/**
+* @deprecated use client.addApiKey()
+*/
+Index.prototype.addUserKeyWithValidity = deprecate(function deprecatedAddUserKeyWithValidity(acls, params, callback) {
+ return this.addApiKey(acls, params, callback);
+}, deprecatedMessage('index.addUserKeyWithValidity()', 'client.addApiKey()'));
+
+/*
+* @deprecated see client.updateApiKey()
+*/
+Index.prototype.updateUserKey = deprecate(function(key, acls, params, callback) {
+ return this.updateApiKey(key, acls, params, callback);
+}, deprecatedMessage('index.updateUserKey()', 'client.updateApiKey()'));
+
+/**
+* Update an existing API key of this index
+* @param {string} key - The key to update
+* @param {string[]} acls - The list of ACL for this key. Defined by an array of strings that
+* can contains the following values:
+* - search: allow to search (https and http)
+* - addObject: allows to add/update an object in the index (https only)
+* - deleteObject : allows to delete an existing object (https only)
+* - deleteIndex : allows to delete index content (https only)
+* - settings : allows to get index settings (https only)
+* - editSettings : allows to change index settings (https only)
+* @param {Object} [params] - Optionnal parameters to set for the key
+* @param {number} params.validity - Number of seconds after which the key will
+* be automatically removed (0 means no time limit for this key)
+* @param {number} params.maxQueriesPerIPPerHour - Number of API calls allowed from an IP address per hour
+* @param {number} params.maxHitsPerQuery - Number of hits this API key can retrieve in one call
+* @param {string} params.description - A description for your key
+* @param {string[]} params.referers - A list of authorized referers
+* @param {Object} params.queryParameters - Force the key to use specific query parameters
+* @param {Function} callback - The result callback called with two arguments
+* error: null or Error('message')
+* content: the server answer with user keys list
+* @return {Promise|undefined} Returns a promise if no callback given
+* @example
+* index.updateApiKey('APIKEY', ['search'], {
+* validity: 300,
+* maxQueriesPerIPPerHour: 2000,
+* maxHitsPerQuery: 3,
+* description: 'Eat three fruits',
+* referers: ['*.algolia.com'],
+* queryParameters: {
+* tagFilters: ['public'],
+* }
+* })
+* @see {@link https://www.algolia.com/doc/rest_api#UpdateIndexKey|Algolia REST API Documentation}
+*
+* @deprecated see client.updateApiKey()
+*/
+Index.prototype.updateApiKey = deprecate(function(key, acls, params, callback) {
+ var isArray = require('isarray');
+ var usage = 'Usage: index.updateApiKey(key, arrayOfAcls[, params, callback])';
+
+ if (!isArray(acls)) {
+ throw new Error(usage);
+ }
+
+ if (arguments.length === 2 || typeof params === 'function') {
+ callback = params;
+ params = null;
+ }
+
+ var putObj = {
+ acl: acls
+ };
+
+ if (params) {
+ putObj.validity = params.validity;
+ putObj.maxQueriesPerIPPerHour = params.maxQueriesPerIPPerHour;
+ putObj.maxHitsPerQuery = params.maxHitsPerQuery;
+ putObj.description = params.description;
+
+ if (params.queryParameters) {
+ putObj.queryParameters = this.as._getSearchParams(params.queryParameters, '');
+ }
+
+ putObj.referers = params.referers;
+ }
+
+ return this.as._jsonRequest({
+ method: 'PUT',
+ url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/keys/' + key,
+ body: putObj,
+ hostType: 'write',
+ callback: callback
+ });
+}, deprecatedMessage('index.updateApiKey()', 'client.updateApiKey()'));