diff --git a/.nvmrc b/.nvmrc
new file mode 100644
index 00000000..e1fcd1ea
--- /dev/null
+++ b/.nvmrc
@@ -0,0 +1 @@
+lts/erbium
diff --git a/assets/banner-1544x500.png b/.wordpress-org/banner-1544x500.png
similarity index 100%
rename from assets/banner-1544x500.png
rename to .wordpress-org/banner-1544x500.png
diff --git a/assets/banner-772x250.png b/.wordpress-org/banner-772x250.png
similarity index 100%
rename from assets/banner-772x250.png
rename to .wordpress-org/banner-772x250.png
diff --git a/assets/icon-128x128.png b/.wordpress-org/icon-128x128.png
similarity index 100%
rename from assets/icon-128x128.png
rename to .wordpress-org/icon-128x128.png
diff --git a/assets/icon-256x256.png b/.wordpress-org/icon-256x256.png
similarity index 100%
rename from assets/icon-256x256.png
rename to .wordpress-org/icon-256x256.png
diff --git a/assets/screenshot-1.png b/.wordpress-org/screenshot-1.png
similarity index 100%
rename from assets/screenshot-1.png
rename to .wordpress-org/screenshot-1.png
diff --git a/assets/screenshot-2.png b/.wordpress-org/screenshot-2.png
similarity index 100%
rename from assets/screenshot-2.png
rename to .wordpress-org/screenshot-2.png
diff --git a/assets/screenshot-3.png b/.wordpress-org/screenshot-3.png
similarity index 100%
rename from assets/screenshot-3.png
rename to .wordpress-org/screenshot-3.png
diff --git a/assets/screenshot-4.png b/.wordpress-org/screenshot-4.png
similarity index 100%
rename from assets/screenshot-4.png
rename to .wordpress-org/screenshot-4.png
diff --git a/assets/screenshot-5.png b/.wordpress-org/screenshot-5.png
similarity index 100%
rename from assets/screenshot-5.png
rename to .wordpress-org/screenshot-5.png
diff --git a/README.txt b/README.txt
index e7250821..1ddffd60 100644
--- a/README.txt
+++ b/README.txt
@@ -2,9 +2,9 @@
Contributors: WebDevStudios, williamsba1, gregrickaby, tw2113, richaber, mrasharirfan
Tags: Search, Algolia, Autocomplete, instant-search, relevant search, search highlight, faceted search, find-as-you-type search, suggest, search by category, ajax search, better search, custom search
Requires at least: 5.0
-Tested up to: 5.7
+Tested up to: 5.8
Requires PHP: 7.2
-Stable tag: 1.8.0
+Stable tag: 2.0.0
License: GNU General Public License v2.0, MIT License
Improve search on your site. Autocomplete is included, along with full control over look, feel and relevance.
@@ -106,6 +106,14 @@ WebDevStudios provides end-to-end WordPress opportunities from strategy and plan
Follow along with the changelog on [Github](https://github.com/WebDevStudios/wp-search-with-algolia/releases).
+= 2.0.0 =
+* Breaking changes for users with customized autocomplete.php / instantsearch.php template in their theme.
+* Update autocomplete.php and instantsearch.php templates for compatibility with new JS libs.
+* Update Algolia JavaScript API Client to 4.10.3
+* Update Algolia InstantSearch.js to 4.25.2
+* Update Algolia Autocomplete.js to 0.38.0
+* Update Algolia PHP API Client to 3.0.2
+
= 1.8.0 =
* Focus on template versioning and update messaging
* Add Algolia_Template_Utils class
diff --git a/algolia.php b/algolia.php
index 7cfe1b49..935be952 100644
--- a/algolia.php
+++ b/algolia.php
@@ -3,7 +3,7 @@
* Plugin Name: WP Search with Algolia
* Plugin URI: https://github.com/WebDevStudios/wp-search-with-algolia
* Description: Integrate the powerful Algolia search service with WordPress
- * Version: 1.8.0
+ * Version: 2.0.0
* Requires at least: 5.0
* Requires PHP: 7.2
* Author: WebDevStudios
@@ -26,7 +26,7 @@
}
// The Algolia Search plugin version.
-define( 'ALGOLIA_VERSION', '1.8.0' );
+define( 'ALGOLIA_VERSION', '2.0.0' );
// The minmum required PHP version.
define( 'ALGOLIA_MIN_PHP_VERSION', '7.2' );
diff --git a/composer.json b/composer.json
index 5c6f7eda..a8ce937f 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "webdevstudios/wp-search-with-algolia",
- "version": "1.6.0",
+ "version": "2.0.0",
"description": "Integrate the powerful Algolia search service with WordPress.",
"authors": [
{
@@ -21,17 +21,17 @@
"composer/installers": "~1.0"
},
"require-dev": {
- "algolia/algoliasearch-client-php": "~2.7.0",
- "psr/http-message": "~1.0.0",
- "psr/log": "~1.0.0",
- "psr/simple-cache": "~1.0.0",
- "webdevstudios/php-coding-standards": "^1.0.0",
- "phpcompatibility/phpcompatibility-wp": "^2.0.0",
- "slowprog/composer-copy-file": "^0.3.2"
+ "algolia/algoliasearch-client-php": "^3.0.2",
+ "psr/http-message": "~1.0.1",
+ "psr/log": "~1.0.2",
+ "psr/simple-cache": "~1.0.1",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1",
+ "phpcompatibility/phpcompatibility-wp": "^2.1.2",
+ "wp-coding-standards/wpcs": "^2.3.0",
+ "slowprog/composer-copy-file": "^0.3.3"
},
"extra": {
"installer-name": "wp-search-with-algolia",
- "phpcodesniffer-search-depth": 5,
"copy-file": {
"vendor/algolia": "includes/libraries"
},
@@ -42,7 +42,7 @@
},
"scripts": {
"lint": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs --standard=phpcs.xml --extensions=php .",
- "lint:fix": "vendor/bin/phpcbf",
+ "lint:fix": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcbf --standard=phpcs.xml --extensions=php .",
"post-install-cmd": [
"SlowProg\\CopyFile\\ScriptHandler::copy"
],
diff --git a/composer.lock b/composer.lock
index 57cab201..4438ed97 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "65814a969601baa2f5152e0a79a022c7",
+ "content-hash": "65c9239fafa762ea79239cf5d665ef61",
"packages": [
{
"name": "composer/installers",
@@ -131,29 +131,39 @@
"zend",
"zikula"
],
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
"time": "2020-04-07T06:57:05+00:00"
}
],
"packages-dev": [
{
"name": "algolia/algoliasearch-client-php",
- "version": "2.7.3",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/algolia/algoliasearch-client-php.git",
- "reference": "142a382e4649db0cb64d9eb8893872f1a4ba8dd3"
+ "reference": "421abbfb085c8ae74d298a6f259ebfd69897e625"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/algolia/algoliasearch-client-php/zipball/142a382e4649db0cb64d9eb8893872f1a4ba8dd3",
- "reference": "142a382e4649db0cb64d9eb8893872f1a4ba8dd3",
+ "url": "https://api.github.com/repos/algolia/algoliasearch-client-php/zipball/421abbfb085c8ae74d298a6f259ebfd69897e625",
+ "reference": "421abbfb085c8ae74d298a6f259ebfd69897e625",
"shasum": ""
},
"require": {
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
- "php": "^5.3 || ^7.0 || ^8.0",
+ "php": "^7.2 || ^8.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0",
"psr/simple-cache": "^1.0"
@@ -161,7 +171,7 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"fzaninotto/faker": "^1.8",
- "julienbourdeau/phpunit": "4.8.37",
+ "phpunit/phpunit": "^8.0 || ^9.0",
"symfony/yaml": "^2.0 || ^4.0"
},
"suggest": {
@@ -203,7 +213,7 @@
"php",
"search"
],
- "time": "2020-12-22T11:27:03+00:00"
+ "time": "2021-05-04T09:15:35+00:00"
},
{
"name": "dealerdirect/phpcodesniffer-composer-installer",
@@ -717,6 +727,7 @@
],
"description": "In-house PHP linting and coding standards for WebDevStudios",
"homepage": "https://github.com/WebDevStudios/php-coding-standards",
+ "abandoned": "wp-coding-standards/wpcs",
"time": "2020-10-16T20:49:05+00:00"
},
{
diff --git a/css/algolia-instantsearch.css b/css/algolia-instantsearch.css
index 99dec19a..bf87b6dc 100644
--- a/css/algolia-instantsearch.css
+++ b/css/algolia-instantsearch.css
@@ -14,14 +14,35 @@
.ais-facets {
margin-bottom: 2rem;
+ padding: 0;
+}
+
+.ais-facets ul {
+ list-style: none;
+ padding-left: 0;
+ margin-left: 0;
+}
+
+.ais-facets li {
+ margin-left: 0;
}
.ais-clearfix {
clear: both;
}
-#algolia-search-box {
+.algolia-search-box-wrapper {
position: relative;
+}
+
+.algolia-search-box-wrapper .search-icon {
+ position: absolute;
+ left: 0px;
+ top: 14px;
+ fill: #21A4D7;
+}
+
+#algolia-search-box {
margin-bottom: 3rem;
}
@@ -43,14 +64,18 @@
-ms-appearance:none;
}
-#algolia-search-box .search-icon {
- position: absolute;
- left: 0px;
- top: 14px;
- fill: #21A4D7;
+.ais-SearchBox-form {
+ display: block;
+ position: relative;
+}
+
+.ais-SearchBox-submit[hidden],
+.ais-SearchBox-reset[hidden],
+.ais-SearchBox-loadingIndicator[hidden] {
+ display: none;
}
-.ais-search-box--powered-by {
+#algolia-powered-by {
position: absolute;
top: 60px;
right: 0;
@@ -58,35 +83,28 @@
text-align: right;
}
-.ais-search-box--powered-by-link {
- display: inline-block;
- width: 64px;
- height: 21px;
- text-indent: 101%;
- overflow: hidden;
- white-space: nowrap;
- background-image: url('algolia-logo.svg');
- background-repeat: no-repeat;
- background-size: contain;
- vertical-align: middle;
-}
-
-.ais-stats {
+.ais-Stats {
position: absolute;
top: 60px;
font-size: 14px;
}
-.ais-hits--item {
+.ais-Hits-list {
+ list-style: none;
+ padding-left: 0;
+ margin-left: 0;
+}
+
+.ais-Hits-item {
/* hit item */
- margin-bottom: 2rem;
+ margin: 0 0 2rem 0;
}
-.ais-hits--item h2 {
+.ais-Hits-item h2 {
margin: 0;
}
-.ais-hits--item em, .ais-hits--item a em {
+.ais-Hits-item em, .ais-Hits-item a em {
font-style: normal;
background: #FFFBCC;
border-radius: 2px;
@@ -105,41 +123,51 @@
border-radius: 3px;
}
-.ais-pagination {
+.ais-Pagination {
margin: 0;
}
-.ais-pagination--item {
- /* pagination item */
+.ais-Pagination-list {
+ margin-left: 0;
+}
+
+.ais-Pagination-item {
+ /* Pagination item */
display: inline-block;
padding: 3px;
}
-.ais-pagination--item__disabled {
- /* disabled pagination item */
+.ais-Pagination-item--disabled {
+ /* disabled Pagination item */
display: none;
}
-.ais-pagination--item__active {
+.ais-Pagination-item--selected {
font-weight: bold;
}
-.ais-menu--item__active {
+.ais-Menu-item--selected {
/* active list item */
font-weight: bold;
}
-.ais-hierarchical-menu--list__lvl1 {
+.ais-Menu-count,
+.ais-HierarchicalMenu-count,
+.ais-RefinementList-count {
+ margin-left: 5px;
+}
+
+.ais-HierarchicalMenu-list--lvl1 {
/* item list level 1 */
margin-left: 10px;
}
-.ais-hierarchical-menu--list__lvl2 {
+.ais-HierarchicalMenu-list--lvl2 {
/* item list level 0 */
margin-left: 10px;
}
-.ais-range-slider--target {
+.ais-RangeSlider-target {
position: relative;
direction: ltr;
background: #F3F4F7;
@@ -148,7 +176,7 @@
margin-bottom: 2em;
}
-.ais-range-slider--base {
+.ais-RangeSlider-base {
height: 100%;
position: relative;
z-index: 1;
@@ -158,7 +186,7 @@
border-right: 2px solid #DDD;
}
-.ais-range-slider--origin {
+.ais-RangeSlider-origin {
position: absolute;
right: 0;
top: 0;
@@ -166,15 +194,15 @@
bottom: 0;
}
-.ais-range-slider--connect {
+.ais-RangeSlider-connect {
background: #46AEDA;
}
-.ais-range-slider--background {
+.ais-RangeSlider-background {
background: #F3F4F7;
}
-.ais-range-slider--handle {
+.ais-RangeSlider-handle {
width: 20px;
height: 20px;
position: relative;
@@ -185,24 +213,24 @@
cursor: pointer;
}
-.ais-range-slider--handle-lower {
+.ais-RangeSlider-handle-lower {
left: -10px;
bottom: 7px;
}
-.ais-range-slider--handle-upper {
+.ais-RangeSlider-handle-upper {
right: 10px;
bottom: 7px;
}
-.ais-range-slider--tooltip {
+.ais-RangeSlider-tooltip {
position: absolute;
background: #FFFFFF;
top: -22px;
font-size: .8em;
}
-.ais-range-slider--pips {
+.ais-RangeSlider-pips {
box-sizing: border-box;
position: absolute;
height: 3em;
@@ -211,7 +239,7 @@
width: 100%;
}
-.ais-range-slider--value {
+.ais-RangeSlider-value {
width: 40px;
position: absolute;
text-align: center;
@@ -220,12 +248,12 @@
font-size: .8em;
}
-.ais-range-slider--value-sub {
+.ais-RangeSlider-value-sub {
font-size: .8em;
padding-top: 15px;
}
-.ais-range-slider--marker {
+.ais-RangeSlider-marker {
position: absolute;
background: #DDD;
margin-left: -1px;
@@ -233,21 +261,21 @@
height: 5px;
}
-.ais-range-slider--marker-sub {
+.ais-RangeSlider-marker-sub {
background: #DDD;
width: 2px;
margin-left: -2px;
height: 13px;
}
-.ais-range-slider--marker-large {
+.ais-RangeSlider-marker-large {
background: #DDD;
width: 2px;
margin-left: -2px;
height: 12px;
}
-.ais-range-slider--marker-large:first-child {
+.ais-RangeSlider-marker-large:first-child {
margin-left: 0;
}
@@ -302,7 +330,7 @@
}
/* Hierarchical Menu: Categories */
-.ais-hierarchical-menu--item__active > div > a {
+.ais-HierarchicalMenu--item__active > div > a {
font-weight: bold;
}
diff --git a/includes/admin/class-algolia-admin-page-autocomplete.php b/includes/admin/class-algolia-admin-page-autocomplete.php
index 306687d8..a0ecbd75 100644
--- a/includes/admin/class-algolia-admin-page-autocomplete.php
+++ b/includes/admin/class-algolia-admin-page-autocomplete.php
@@ -164,9 +164,9 @@ public function autocomplete_enabled_callback() {
$indices = $this->autocomplete_config->get_form_data();
$checked = 'yes' === $value ? 'checked ' : '';
$disabled = empty( $indices ) ? 'disabled ' : '';
-?>
+ ?>
/>
-slug ) ) . '">' . esc_html__( 'Settings', 'wp-search-with-algolia' ) . '',
)
);
@@ -206,10 +207,10 @@ public function application_id_callback() {
$settings = $this->plugin->get_settings();
$setting = $settings->get_application_id();
$disabled_html = $settings->is_application_id_in_config() ? ' disabled' : '';
-?>
+ ?>
/>
-get_search_api_key();
$disabled_html = $settings->is_search_api_key_in_config() ? ' disabled' : '';
-?>
+ ?>
/>
-plugin->get_settings();
$setting = $settings->get_api_key();
$disabled_html = $settings->is_api_key_in_config() ? ' disabled' : '';
-?>
+ ?>
/>
-plugin->get_settings();
$index_name_prefix = $settings->get_index_name_prefix();
$disabled_html = $settings->is_index_name_prefix_in_config() ? ' disabled' : '';
-?>
+ ?>
/>
- $b['position'];
}
);
@@ -175,14 +176,16 @@ public function get_config() {
// Remove manually disabled indices.
$config = array_filter(
- $config, function( $item ) {
+ $config,
+ function( $item ) {
return (bool) $item['enabled'];
}
);
// Sort the indices.
usort(
- $config, function( $a, $b ):int {
+ $config,
+ function( $a, $b ):int {
return $a['position'] <=> $b['position'];
}
);
diff --git a/includes/class-algolia-plugin.php b/includes/class-algolia-plugin.php
index fd2621e1..428e76d6 100644
--- a/includes/class-algolia-plugin.php
+++ b/includes/class-algolia-plugin.php
@@ -274,7 +274,8 @@ public function load_indices() {
$searchable_post_types = get_post_types(
array(
'exclude_from_search' => false,
- ), 'names'
+ ),
+ 'names'
);
$searchable_post_types = (array) apply_filters( 'algolia_searchable_post_types', $searchable_post_types );
$this->indices[] = new Algolia_Searchable_Posts_Index( $searchable_post_types );
@@ -353,7 +354,8 @@ public function get_indices( array $args = array() ) {
if ( isset( $args['enabled'] ) && true === $args['enabled'] ) {
$indices = array_filter(
- $indices, function( $index ) {
+ $indices,
+ function( $index ) {
return $index->is_enabled();
}
);
@@ -362,7 +364,8 @@ public function get_indices( array $args = array() ) {
if ( isset( $args['contains'] ) ) {
$contains = (string) $args['contains'];
$indices = array_filter(
- $indices, function( $index ) use ( $contains ) {
+ $indices,
+ function( $index ) use ( $contains ) {
return $index->contains_only( $contains );
}
);
diff --git a/includes/class-algolia-scripts.php b/includes/class-algolia-scripts.php
index 32d5f920..85a03290 100644
--- a/includes/class-algolia-scripts.php
+++ b/includes/class-algolia-scripts.php
@@ -37,9 +37,13 @@ public function register_scripts() {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
+ $ais_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG
+ ? '.development'
+ : '.production';
+
wp_register_script(
'algolia-search',
- ALGOLIA_PLUGIN_URL . 'js/algoliasearch/dist/algoliasearch.jquery' . $suffix . '.js',
+ ALGOLIA_PLUGIN_URL . 'js/algoliasearch/dist/algoliasearch-lite.umd.js',
[
'jquery',
'underscore',
@@ -73,7 +77,7 @@ public function register_scripts() {
wp_register_script(
'algolia-instantsearch',
- ALGOLIA_PLUGIN_URL . 'js/instantsearch.js/dist/instantsearch-preact' . $suffix . '.js',
+ ALGOLIA_PLUGIN_URL . 'js/instantsearch.js/dist/instantsearch' . $ais_suffix . $suffix . '.js',
[
'jquery',
'underscore',
diff --git a/includes/class-algolia-template-loader.php b/includes/class-algolia-template-loader.php
index 3de6a53c..a12230f2 100644
--- a/includes/class-algolia-template-loader.php
+++ b/includes/class-algolia-template-loader.php
@@ -76,7 +76,7 @@ public function load_algolia_config() {
$autocomplete_config = $this->plugin->get_autocomplete_config();
$config = array(
- 'debug' => defined( 'WP_DEBUG' ) && WP_DEBUG,
+ 'debug' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG,
'application_id' => $settings->get_application_id(),
'search_api_key' => $settings->get_search_api_key(),
'powered_by_enabled' => $settings->is_powered_by_enabled(),
@@ -186,7 +186,8 @@ public function template_loader( $template ) {
*/
public function load_instantsearch_template() {
add_action(
- 'wp_enqueue_scripts', function () {
+ 'wp_enqueue_scripts',
+ function () {
// Enqueue the instantsearch.js default styles.
wp_enqueue_style( 'algolia-instantsearch' );
diff --git a/includes/factories/class-algolia-http-client-interface-factory.php b/includes/factories/class-algolia-http-client-interface-factory.php
index e183a5b2..9119dc11 100644
--- a/includes/factories/class-algolia-http-client-interface-factory.php
+++ b/includes/factories/class-algolia-http-client-interface-factory.php
@@ -8,7 +8,7 @@
use Algolia\AlgoliaSearch\Http\Guzzle6HttpClient;
use Algolia\AlgoliaSearch\Http\HttpClientInterface;
-use Algolia\AlgoliaSearch\Http\Php53HttpClient;
+use Algolia\AlgoliaSearch\Http\CurlHttpClient;
/**
* Class Algolia_Http_Client_Interface_Factory
@@ -41,38 +41,79 @@ public static function create(): HttpClientInterface {
return $http_client;
}
- $http_client = self::create_php53_http_client();
+ $http_client = self::create_http_client();
return $http_client;
}
/**
- * Create a Php53HttpClient client.
+ * Create HttpClientInterface.
+ *
+ * @author WebDevStudios
+ * @since 1.6.0
+ *
+ * @deprecated 2.0.0 Use Algolia_Http_Client_Interface_Factory::create_http_client()
+ * @see Algolia_Http_Client_Interface_Factory::create_http_client()
+ *
+ * @return HttpClientInterface
+ */
+ public static function create_php53_http_client(): HttpClientInterface {
+ _deprecated_function(
+ __METHOD__,
+ '2.0.0',
+ 'Algolia_Http_Client_Interface_Factory::create_http_client();'
+ );
+ return self::create_http_client();
+ }
+
+ /**
+ * Create HttpClientInterface.
+ *
+ * Note: Algolia PHP Client 2.x used the `Php53HttpClient` class
+ * when Guzzle was not available.
+ * Algolia PHP Client v 3.x changed that class to `CurlHttpClient`.
+ * Ideally we would implement Guzzle support at some point,
+ * but we need to explore PHP Scoper or Mozart before doing so.
*
* @author WebDevStudios
- * @since 1.6.0
+ * @since 2.0.0
*
- * @return Php53HttpClient
+ * @return HttpClientInterface
*/
- public static function create_php53_http_client(): Php53HttpClient {
+ public static function create_http_client(): HttpClientInterface {
+
+ $options = [];
+
+ /**
+ * Allow developers to override the HttpClientInterface options.
+ *
+ * @author WebDevStudios
+ * @since 1.6.0
+ * @deprecated 2.0.0 Use {@see 'algolia_http_client_options'} instead.
+ *
+ * @param array $options Options for HttpClientInterface construction.
+ */
+ $options = (array) apply_filters_deprecated(
+ 'algolia_php_53_http_client_options',
+ [ $options ],
+ '2.0.0',
+ 'algolia_http_client_options'
+ );
/**
- * Allow developers to override the Php53HttpClient cURL options.
+ * Allow developers to override the HttpClientInterface options.
*
* @link https://www.algolia.com/doc/api-client/advanced/pass-options-to-the-http-client/php/?language=php#using-the-default-php53httpclient
* @link https://www.algolia.com/doc/api-client/getting-started/upgrade-guides/php/#curl-options
* @link https://curl.haxx.se/libcurl/c/curl_easy_setopt.html
*
* @author WebDevStudios
- * @since 1.6.0
+ * @since 2.0.0
*
- * @param array $options Curl options for Php53HttpClient construction.
+ * @param array $options Options for HttpClientInterface construction.
*/
- $options = apply_filters(
- 'algolia_php_53_http_client_options',
- []
- );
+ $options = (array) apply_filters( 'algolia_http_client_options', $options );
- return new Php53HttpClient( $options );
+ return new CurlHttpClient( $options );
}
}
diff --git a/includes/indices/class-algolia-users-index.php b/includes/indices/class-algolia-users-index.php
index b9cb4198..8e678a4f 100644
--- a/includes/indices/class-algolia-users-index.php
+++ b/includes/indices/class-algolia-users-index.php
@@ -84,7 +84,8 @@ protected function get_records( $item ) {
$avatar_size = 32;
if ( function_exists( 'get_avatar_url' ) ) {
$record['avatar_url'] = get_avatar_url(
- $item->ID, array(
+ $item->ID,
+ array(
'size' => $avatar_size,
)
);
diff --git a/includes/libraries/algoliasearch-client-php/.circleci/config.yml b/includes/libraries/algoliasearch-client-php/.circleci/config.yml
index 95cf797d..e446b1d6 100644
--- a/includes/libraries/algoliasearch-client-php/.circleci/config.yml
+++ b/includes/libraries/algoliasearch-client-php/.circleci/config.yml
@@ -35,18 +35,18 @@ jobs:
- run: sudo docker-php-ext-install zip
# Download and cache dependencies
-# - restore_cache:
-# keys:
-# - composer-deps-<>-{{ checksum "composer.json" }}
-# # fallback to using the latest cache if no exact match is found
-# #- composer-deps-
+ - restore_cache:
+ keys:
+ - composer-deps-<>-{{ checksum "composer.json" }}
+ # fallback to using the latest cache if no exact match is found
+ #- composer-deps-
- run: COMPOSER_MEMORY_LIMIT=-1 composer install -n --prefer-dist
-# - save_cache:
-# key: composer-deps-<>-{{ checksum "composer.json" }}
-# paths:
-# - ./vendor
+ - save_cache:
+ key: composer-deps-<>-{{ checksum "composer.json" }}
+ paths:
+ - ./vendor
- run:
name: Install PHP Client
@@ -60,11 +60,15 @@ jobs:
- run:
name: Get API Key Dealer client
- command: wget https://alg.li/algolia-keys && chmod +x algolia-keys
+ command: |
+ if [ "${CIRCLE_PR_REPONAME}" ]
+ then
+ curl -s https://algoliasearch-client-keygen.herokuapp.com | bash >> "$BASH_ENV"
+ fi
-# - run:
-# name: Check code styles
-# command: vendor/bin/php-cs-fixer fix -v --dry-run
+ - run:
+ name: Check code styles
+ command: vendor/bin/php-cs-fixer fix -v --dry-run
# Run tests with phpunit
#
@@ -72,19 +76,29 @@ jobs:
# with the keys in the env variables
# If the PR was open from a fork (community PR)
# we get API keys from the API key dealer https://alg.li/api-key-dealer
+ # we only run the tests on dictionaries on one case to avoid concurrency problems
- run:
name: Run tests
command: |
export CI_BUILD_NUM=$CIRCLE_BUILD_NUM
if [ -z ${CIRCLE_PR_REPONAME+x} ]
then
- php vendor/bin/phpunit
+ if [ "<>" == "latest" ] && [ "<>" == "guzzlehttp/guzzle:"^7.0"" ]
+ then
+ php vendor/bin/phpunit
+ else
+ php vendor/bin/phpunit --exclude-group=dictionaries
+ fi
else
export CI_PROJ_USERNAME=$CIRCLE_PR_USERNAME
export CI_PROJ_REPONAME=$CIRCLE_PR_REPONAME
- eval $(./algolia-keys export)
- php vendor/bin/phpunit -v --testsuite Unit,Definition,Community
+ if [ "<>" == "latest" ] && [ "<>" == "guzzlehttp/guzzle:"^7.0"" ]
+ then
+ php vendor/bin/phpunit
+ else
+ php vendor/bin/phpunit --exclude-group=dictionaries
+ fi
fi
- run:
@@ -121,12 +135,8 @@ workflows:
version: "7.4"
http_client: guzzlehttp/guzzle:"^6.0"
- test:
- name: 'Guzzle 6 - PHP 7.0'
- version: "7.0"
- http_client: guzzlehttp/guzzle:"^6.0"
- - test:
- name: 'Guzzle 6 - PHP 5.6'
- version: "5.6"
+ name: 'Guzzle 6 - PHP 7.2'
+ version: "7.2"
http_client: guzzlehttp/guzzle:"^6.0"
- test:
@@ -142,10 +152,6 @@ workflows:
version: "7.4"
http_client: legacy
- test:
- name: 'Legacy client - PHP 7.0'
- version: "7.0"
- http_client: legacy
- - test:
- name: 'Legacy client - PHP 5.6'
- version: "5.6"
+ name: 'Legacy client - PHP 7.2'
+ version: "7.2"
http_client: legacy
diff --git a/includes/libraries/algoliasearch-client-php/.circleci/index-cleanup.php b/includes/libraries/algoliasearch-client-php/.circleci/index-cleanup.php
deleted file mode 100644
index 5b0add7e..00000000
--- a/includes/libraries/algoliasearch-client-php/.circleci/index-cleanup.php
+++ /dev/null
@@ -1,19 +0,0 @@
-listIndices();
-
-foreach(array_chunk($indices['items'], 100) as $chunk) {
- $ops = array();
- foreach($chunk as $index) {
- array_push($ops, [
- 'indexName' => $index['name'],
- 'action' => 'delete',
- ]);
- }
-
- $client->multipleBatch($ops);
-}
diff --git a/includes/libraries/algoliasearch-client-php/composer.json b/includes/libraries/algoliasearch-client-php/composer.json
index fd6965ef..61fbe595 100644
--- a/includes/libraries/algoliasearch-client-php/composer.json
+++ b/includes/libraries/algoliasearch-client-php/composer.json
@@ -11,7 +11,7 @@
}
],
"require": {
- "php": "^5.3 || ^7.0 || ^8.0",
+ "php": "^7.2 || ^8.0",
"ext-curl": "*",
"ext-json": "*",
"ext-mbstring": "*",
@@ -22,7 +22,7 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.0",
"fzaninotto/faker": "^1.8",
- "julienbourdeau/phpunit": "4.8.37",
+ "phpunit/phpunit": "^8.0 || ^9.0",
"symfony/yaml": "^2.0 || ^4.0"
},
"autoload": {
diff --git a/includes/libraries/algoliasearch-client-php/src/AccountClient.php b/includes/libraries/algoliasearch-client-php/src/AccountClient.php
index 06d1c99e..20d142c8 100644
--- a/includes/libraries/algoliasearch-client-php/src/AccountClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/AccountClient.php
@@ -7,7 +7,7 @@
final class AccountClient
{
- public static function copyIndex(SearchIndex $srcIndex, SearchIndex $destIndex, $requestOptions = array())
+ public static function copyIndex(SearchIndex $srcIndex, SearchIndex $destIndex, $requestOptions = [])
{
if ($srcIndex->getAppId() === $destIndex->getAppId()) {
throw new \InvalidArgumentException('If both index are on the same app, please use SearchClient::copyIndex method instead.');
@@ -21,7 +21,7 @@ public static function copyIndex(SearchIndex $srcIndex, SearchIndex $destIndex,
// All good
}
- $allResponses = array();
+ $allResponses = [];
$settings = $srcIndex->getSettings();
$allResponses[] = $destIndex->setSettings($settings);
diff --git a/includes/libraries/algoliasearch-client-php/src/Algolia.php b/includes/libraries/algoliasearch-client-php/src/Algolia.php
index 40f31a26..88f811f0 100644
--- a/includes/libraries/algoliasearch-client-php/src/Algolia.php
+++ b/includes/libraries/algoliasearch-client-php/src/Algolia.php
@@ -10,7 +10,7 @@
final class Algolia
{
- const VERSION = '2.7.3';
+ const VERSION = '3.0.2';
/**
* Holds an instance of the simple cache repository (PSR-16).
@@ -97,9 +97,9 @@ public static function getHttpClient()
if (null === self::$httpClient) {
if (class_exists('\GuzzleHttp\Client') && 6 <= $guzzleVersion) {
- self::setHttpClient(new \Algolia\AlgoliaSearch\Http\Guzzle6HttpClient());
+ self::setHttpClient(new \Algolia\AlgoliaSearch\Http\GuzzleHttpClient());
} else {
- self::setHttpClient(new \Algolia\AlgoliaSearch\Http\Php53HttpClient());
+ self::setHttpClient(new \Algolia\AlgoliaSearch\Http\CurlHttpClient());
}
}
diff --git a/includes/libraries/algoliasearch-client-php/src/AnalyticsClient.php b/includes/libraries/algoliasearch-client-php/src/AnalyticsClient.php
index 0329f600..780b18ba 100644
--- a/includes/libraries/algoliasearch-client-php/src/AnalyticsClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/AnalyticsClient.php
@@ -57,7 +57,7 @@ public static function createWithConfig(AnalyticsConfig $config)
*
* @return array
*/
- public function getABTests($requestOptions = array())
+ public function getABTests($requestOptions = [])
{
return $this->api->read('GET', api_path('/2/abtests'), $requestOptions);
}
@@ -72,7 +72,7 @@ public function getABTests($requestOptions = array())
*
* @throws \Algolia\AlgoliaSearch\Exceptions\AlgoliaException
*/
- public function getABTest($abTestID, $requestOptions = array())
+ public function getABTest($abTestID, $requestOptions = [])
{
if (!$abTestID) {
throw new AlgoliaException('Cannot retrieve ABTest because the abtestID is invalid.');
@@ -89,7 +89,7 @@ public function getABTest($abTestID, $requestOptions = array())
*
* @return array Information about the creation like TaskID and date
*/
- public function addABTest($abTest, $requestOptions = array())
+ public function addABTest($abTest, $requestOptions = [])
{
return $this->api->write('POST', api_path('/2/abtests'), $abTest, $requestOptions);
}
@@ -104,13 +104,13 @@ public function addABTest($abTest, $requestOptions = array())
*
* @throws \Algolia\AlgoliaSearch\Exceptions\AlgoliaException
*/
- public function stopABTest($abTestID, $requestOptions = array())
+ public function stopABTest($abTestID, $requestOptions = [])
{
if (!$abTestID) {
throw new AlgoliaException('Cannot retrieve ABTest because the abtestID is invalid.');
}
- return $this->api->write('POST', api_path('/2/abtests/%s', $abTestID), array(), $requestOptions);
+ return $this->api->write('POST', api_path('/2/abtests/%s/stop', $abTestID), [], $requestOptions);
}
/**
@@ -123,16 +123,16 @@ public function stopABTest($abTestID, $requestOptions = array())
*
* @throws \Algolia\AlgoliaSearch\Exceptions\AlgoliaException
*/
- public function deleteABTest($abTestID, $requestOptions = array())
+ public function deleteABTest($abTestID, $requestOptions = [])
{
if (!$abTestID) {
throw new AlgoliaException('Cannot retrieve ABTest because the abtestID is invalid.');
}
- return $this->api->write('DELETE', api_path('/2/abtests/%s', $abTestID), array(), $requestOptions);
+ return $this->api->write('DELETE', api_path('/2/abtests/%s', $abTestID), [], $requestOptions);
}
- public function custom($method, $path, $requestOptions = array(), $hosts = null)
+ public function custom($method, $path, $requestOptions = [], $hosts = null)
{
return $this->api->send($method, $path, $requestOptions, $hosts);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Cache/FileCacheDriver.php b/includes/libraries/algoliasearch-client-php/src/Cache/FileCacheDriver.php
index 0c509849..4e4173f1 100644
--- a/includes/libraries/algoliasearch-client-php/src/Cache/FileCacheDriver.php
+++ b/includes/libraries/algoliasearch-client-php/src/Cache/FileCacheDriver.php
@@ -61,7 +61,7 @@ public function clear()
*/
public function getMultiple($keys, $default = null)
{
- $result = array();
+ $result = [];
foreach ($keys as $key) {
$result[$key] = $this->get($key, $default);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Cache/NullCacheDriver.php b/includes/libraries/algoliasearch-client-php/src/Cache/NullCacheDriver.php
index b947ae9c..0eb1d6d3 100644
--- a/includes/libraries/algoliasearch-client-php/src/Cache/NullCacheDriver.php
+++ b/includes/libraries/algoliasearch-client-php/src/Cache/NullCacheDriver.php
@@ -43,7 +43,7 @@ public function clear()
*/
public function getMultiple($keys, $default = null)
{
- $return = array();
+ $return = [];
foreach ($keys as $key) {
$return[$key] = $default;
diff --git a/includes/libraries/algoliasearch-client-php/src/Config/AbstractConfig.php b/includes/libraries/algoliasearch-client-php/src/Config/AbstractConfig.php
index 60ee1597..9effe4f5 100644
--- a/includes/libraries/algoliasearch-client-php/src/Config/AbstractConfig.php
+++ b/includes/libraries/algoliasearch-client-php/src/Config/AbstractConfig.php
@@ -12,7 +12,7 @@ abstract class AbstractConfig
protected $defaultConnectTimeout = 2;
- public function __construct(array $config = array())
+ public function __construct(array $config = [])
{
$config += $this->getDefaultConfig();
@@ -21,15 +21,15 @@ public function __construct(array $config = array())
public function getDefaultConfig()
{
- return array(
+ return [
'appId' => '',
'apiKey' => '',
'hosts' => null,
'readTimeout' => $this->defaultReadTimeout,
'writeTimeout' => $this->defaultWriteTimeout,
'connectTimeout' => $this->defaultConnectTimeout,
- 'defaultHeaders' => array(),
- );
+ 'defaultHeaders' => [],
+ ];
}
public function getAppId()
diff --git a/includes/libraries/algoliasearch-client-php/src/Config/AnalyticsConfig.php b/includes/libraries/algoliasearch-client-php/src/Config/AnalyticsConfig.php
index 73a4ea0c..ece77648 100644
--- a/includes/libraries/algoliasearch-client-php/src/Config/AnalyticsConfig.php
+++ b/includes/libraries/algoliasearch-client-php/src/Config/AnalyticsConfig.php
@@ -6,11 +6,11 @@ final class AnalyticsConfig extends AbstractConfig
{
public static function create($appId = null, $apiKey = null, $region = null)
{
- $config = array(
+ $config = [
'appId' => null !== $appId ? $appId : getenv('ALGOLIA_APP_ID'),
'apiKey' => null !== $apiKey ? $apiKey : getenv('ALGOLIA_API_KEY'),
'region' => null !== $region ? $region : 'us',
- );
+ ];
return new static($config);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Config/InsightsConfig.php b/includes/libraries/algoliasearch-client-php/src/Config/InsightsConfig.php
index 59c805cc..feb15b89 100644
--- a/includes/libraries/algoliasearch-client-php/src/Config/InsightsConfig.php
+++ b/includes/libraries/algoliasearch-client-php/src/Config/InsightsConfig.php
@@ -6,11 +6,11 @@ final class InsightsConfig extends AbstractConfig
{
public static function create($appId = null, $apiKey = null, $region = null)
{
- $config = array(
+ $config = [
'appId' => null !== $appId ? $appId : getenv('ALGOLIA_APP_ID'),
'apiKey' => null !== $apiKey ? $apiKey : getenv('ALGOLIA_API_KEY'),
'region' => null !== $region ? $region : 'us',
- );
+ ];
return new static($config);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Config/PlacesConfig.php b/includes/libraries/algoliasearch-client-php/src/Config/PlacesConfig.php
index 8bf0384b..e2a8aabb 100644
--- a/includes/libraries/algoliasearch-client-php/src/Config/PlacesConfig.php
+++ b/includes/libraries/algoliasearch-client-php/src/Config/PlacesConfig.php
@@ -6,10 +6,10 @@ final class PlacesConfig extends AbstractConfig
{
public static function create($appId, $apiKey)
{
- $config = array(
+ $config = [
'appId' => $appId,
'apiKey' => $apiKey,
- );
+ ];
return new static($config);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Config/RecommendationConfig.php b/includes/libraries/algoliasearch-client-php/src/Config/RecommendationConfig.php
index fe36399a..b451e777 100644
--- a/includes/libraries/algoliasearch-client-php/src/Config/RecommendationConfig.php
+++ b/includes/libraries/algoliasearch-client-php/src/Config/RecommendationConfig.php
@@ -13,11 +13,11 @@ final class RecommendationConfig extends AbstractConfig
*/
public static function create($appId = null, $apiKey = null, $region = null)
{
- $config = array(
+ $config = [
'appId' => null !== $appId ? $appId : getenv('ALGOLIA_APP_ID'),
'apiKey' => null !== $apiKey ? $apiKey : getenv('ALGOLIA_API_KEY'),
'region' => null !== $region ? $region : 'us',
- );
+ ];
return new self($config);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Config/SearchConfig.php b/includes/libraries/algoliasearch-client-php/src/Config/SearchConfig.php
index 516cec58..8e2ed0e3 100644
--- a/includes/libraries/algoliasearch-client-php/src/Config/SearchConfig.php
+++ b/includes/libraries/algoliasearch-client-php/src/Config/SearchConfig.php
@@ -8,17 +8,17 @@ class SearchConfig extends AbstractConfig
public static function create($appId = null, $apiKey = null)
{
- $config = array(
+ $config = [
'appId' => null !== $appId ? $appId : getenv('ALGOLIA_APP_ID'),
'apiKey' => null !== $apiKey ? $apiKey : getenv('ALGOLIA_API_KEY'),
- );
+ ];
return new static($config);
}
public function getDefaultConfig()
{
- return array(
+ return [
'appId' => '',
'apiKey' => '',
'hosts' => null,
@@ -26,10 +26,10 @@ public function getDefaultConfig()
'writeTimeout' => $this->defaultWriteTimeout,
'connectTimeout' => $this->defaultConnectTimeout,
'waitTaskTimeBeforeRetry' => $this->defaultWaitTaskTimeBeforeRetry,
- 'defaultHeaders' => array(),
+ 'defaultHeaders' => [],
'defaultForwardToReplicas' => null,
'batchSize' => 1000,
- );
+ ];
}
public function getWaitTaskTimeBeforeRetry()
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Php53HttpClient.php b/includes/libraries/algoliasearch-client-php/src/Http/CurlHttpClient.php
similarity index 93%
rename from includes/libraries/algoliasearch-client-php/src/Http/Php53HttpClient.php
rename to includes/libraries/algoliasearch-client-php/src/Http/CurlHttpClient.php
index c9edf3ec..24b7b1e9 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Php53HttpClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/CurlHttpClient.php
@@ -5,13 +5,13 @@
use Algolia\AlgoliaSearch\Http\Psr7\Response;
use Psr\Http\Message\RequestInterface;
-final class Php53HttpClient implements HttpClientInterface
+final class CurlHttpClient implements HttpClientInterface
{
private $curlMHandle;
private $curlOptions;
- public function __construct($curlOptions = array())
+ public function __construct($curlOptions = [])
{
$this->curlOptions = $curlOptions;
}
@@ -29,7 +29,7 @@ public function sendRequest(RequestInterface $request, $timeout, $connectTimeout
$this->invalidOptions($this->curlOptions, $e->getMessage());
}
- $curlHeaders = array();
+ $curlHeaders = [];
foreach ($request->getHeaders() as $key => $values) {
$curlHeaders[] = $key.': '.implode(',', $values);
}
@@ -106,7 +106,7 @@ public function sendRequest(RequestInterface $request, $timeout, $connectTimeout
$this->releaseMHandle($curlHandle);
curl_close($curlHandle);
- return new Response($statusCode, array(), $responseBody, '1.1', $error);
+ return new Response($statusCode, [], $responseBody, '1.1', $error);
}
private function getMHandle($curlHandle)
@@ -124,7 +124,7 @@ private function releaseMHandle($curlHandle)
curl_multi_remove_handle($this->curlMHandle, $curlHandle);
}
- private function invalidOptions(array $curlOptions = array(), $errorMsg = '')
+ private function invalidOptions(array $curlOptions = [], $errorMsg = '')
{
throw new \OutOfBoundsException(sprintf('AlgoliaSearch curloptions options keys are invalid. %s given. error message : %s', json_encode($curlOptions), $errorMsg));
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Guzzle6HttpClient.php b/includes/libraries/algoliasearch-client-php/src/Http/GuzzleHttpClient.php
similarity index 64%
rename from includes/libraries/algoliasearch-client-php/src/Http/Guzzle6HttpClient.php
rename to includes/libraries/algoliasearch-client-php/src/Http/GuzzleHttpClient.php
index 377f9221..5bdaafd1 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Guzzle6HttpClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/GuzzleHttpClient.php
@@ -4,12 +4,13 @@
use Algolia\AlgoliaSearch\Http\Psr7\Response;
use GuzzleHttp\Client as GuzzleClient;
-use GuzzleHttp\Exception\RequestException as GuzzleRequestException;
+use GuzzleHttp\Exception\ConnectException;
+use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
-final class Guzzle6HttpClient implements HttpClientInterface
+final class GuzzleHttpClient implements HttpClientInterface
{
private $client;
@@ -21,32 +22,40 @@ public function __construct(GuzzleClient $client = null)
public function sendRequest(RequestInterface $request, $timeout, $connectTimeout)
{
try {
- $response = $this->client->send($request, array(
+ $response = $this->client->send($request, [
'timeout' => $timeout,
'connect_timeout' => $connectTimeout,
- ));
- } catch (GuzzleRequestException $e) {
+ ]);
+ } catch (RequestException $e) {
if ($e->hasResponse()) {
return $e->getResponse();
} else {
return new Response(
0,
- array(),
+ [],
null,
'1.1',
$e->getMessage()
);
}
+ } catch (ConnectException $e) {
+ return new Response(
+ 0,
+ [],
+ null,
+ '1.1',
+ $e->getMessage()
+ );
}
return $response;
}
- private static function buildClient(array $config = array())
+ private static function buildClient(array $config = [])
{
$handlerStack = new HandlerStack(\GuzzleHttp\choose_handler());
$handlerStack->push(Middleware::prepareBody(), 'prepare_body');
- $config = array_merge(array('handler' => $handlerStack), $config);
+ $config = array_merge(['handler' => $handlerStack], $config);
return new GuzzleClient($config);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/BufferStream.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/BufferStream.php
index 419726b6..61124faf 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/BufferStream.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/BufferStream.php
@@ -136,6 +136,6 @@ public function getMetadata($key = null)
return $this->hwm;
}
- return $key ? null : array();
+ return $key ? null : [];
}
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/PumpStream.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/PumpStream.php
index 30f2298a..e1194648 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/PumpStream.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/PumpStream.php
@@ -43,11 +43,11 @@ class PumpStream implements StreamInterface
* - metadata: Hash of metadata to use with stream.
* - size: Size of the stream, if known
*/
- public function __construct(callable $source, array $options = array())
+ public function __construct(callable $source, array $options = [])
{
$this->source = $source;
$this->size = isset($options['size']) ? $options['size'] : null;
- $this->metadata = isset($options['metadata']) ? $options['metadata'] : array();
+ $this->metadata = isset($options['metadata']) ? $options['metadata'] : [];
$this->buffer = new BufferStream();
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Request.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Request.php
index d7d1db71..b4cbc16d 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Request.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Request.php
@@ -24,10 +24,10 @@ class Request implements RequestInterface
private $uri;
/** @var array Map of all registered headers, as original name => array of values */
- private $headers = array();
+ private $headers = [];
/** @var array Map of lowercase header name => original name at registration */
- private $headerNames = array();
+ private $headerNames = [];
/** @var string */
private $protocol = '1.1';
@@ -45,7 +45,7 @@ class Request implements RequestInterface
public function __construct(
$method,
$uri,
- array $headers = array(),
+ array $headers = [],
$body = null,
$version = '1.1'
) {
@@ -150,7 +150,7 @@ private function updateHostFromUri()
}
// Ensure Host is the first header.
// See: http://tools.ietf.org/html/rfc7230#section-5.4
- $this->headers = array($header => array($host)) + $this->headers;
+ $this->headers = [$header => [$host]] + $this->headers;
}
public function getProtocolVersion()
@@ -183,7 +183,7 @@ public function getHeader($header)
{
$header = strtolower($header);
if (!isset($this->headerNames[$header])) {
- return array();
+ return [];
}
$header = $this->headerNames[$header];
@@ -198,7 +198,7 @@ public function getHeaderLine($header)
public function withHeader($header, $value)
{
if (!is_array($value)) {
- $value = array($value);
+ $value = [$value];
}
$value = $this->trimHeaderValues($value);
$normalized = strtolower($header);
@@ -215,7 +215,7 @@ public function withHeader($header, $value)
public function withAddedHeader($header, $value)
{
if (!is_array($value)) {
- $value = array($value);
+ $value = [$value];
}
$value = $this->trimHeaderValues($value);
$normalized = strtolower($header);
@@ -266,10 +266,10 @@ public function withBody(StreamInterface $body)
private function setHeaders(array $headers)
{
- $this->headerNames = $this->headers = array();
+ $this->headerNames = $this->headers = [];
foreach ($headers as $header => $value) {
if (!is_array($value)) {
- $value = array($value);
+ $value = [$value];
}
$value = $this->trimHeaderValues($value);
$normalized = strtolower($header);
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Response.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Response.php
index e44aea91..b16f702f 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Response.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Response.php
@@ -16,10 +16,10 @@
class Response implements ResponseInterface
{
/** @var array Map of all registered headers, as original name => array of values */
- private $headers = array();
+ private $headers = [];
/** @var array Map of lowercase header name => original name at registration */
- private $headerNames = array();
+ private $headerNames = [];
/** @var string */
private $protocol = '1.1';
@@ -28,7 +28,7 @@ class Response implements ResponseInterface
private $stream;
/** @var array Map of standard HTTP status code/reason phrases */
- private static $phrases = array(
+ private static $phrases = [
100 => 'Continue',
101 => 'Switching Protocols',
102 => 'Processing',
@@ -87,7 +87,7 @@ class Response implements ResponseInterface
507 => 'Insufficient Storage',
508 => 'Loop Detected',
511 => 'Network Authentication Required',
- );
+ ];
/** @var string */
private $reasonPhrase = '';
@@ -104,7 +104,7 @@ class Response implements ResponseInterface
*/
public function __construct(
$status = 200,
- array $headers = array(),
+ array $headers = [],
$body = null,
$version = '1.1',
$reason = null
@@ -179,7 +179,7 @@ public function getHeader($header)
$header = strtolower($header);
if (!isset($this->headerNames[$header])) {
- return array();
+ return [];
}
$header = $this->headerNames[$header];
@@ -195,7 +195,7 @@ public function getHeaderLine($header)
public function withHeader($header, $value)
{
if (!is_array($value)) {
- $value = array($value);
+ $value = [$value];
}
$value = $this->trimHeaderValues($value);
@@ -214,7 +214,7 @@ public function withHeader($header, $value)
public function withAddedHeader($header, $value)
{
if (!is_array($value)) {
- $value = array($value);
+ $value = [$value];
}
$value = $this->trimHeaderValues($value);
@@ -271,10 +271,10 @@ public function withBody(StreamInterface $body)
private function setHeaders(array $headers)
{
- $this->headerNames = $this->headers = array();
+ $this->headerNames = $this->headers = [];
foreach ($headers as $header => $value) {
if (!is_array($value)) {
- $value = array($value);
+ $value = [$value];
}
$value = $this->trimHeaderValues($value);
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Stream.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Stream.php
index 27f0b6eb..818864e0 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Stream.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Stream.php
@@ -26,20 +26,20 @@ class Stream implements StreamInterface
private $customMetadata;
/** @var array Hash of readable and writable stream types */
- private static $readWriteHash = array(
- 'read' => array(
+ private static $readWriteHash = [
+ 'read' => [
'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
'x+t' => true, 'c+t' => true, 'a+' => true,
- ),
- 'write' => array(
+ ],
+ 'write' => [
'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
- ),
- );
+ ],
+ ];
/**
* This constructor accepts an associative array of options.
@@ -55,7 +55,7 @@ class Stream implements StreamInterface
*
* @throws \InvalidArgumentException if the stream is not a stream resource
*/
- public function __construct($stream, $options = array())
+ public function __construct($stream, $options = [])
{
if (!is_resource($stream)) {
throw new \InvalidArgumentException('Stream must be a resource');
@@ -67,7 +67,7 @@ public function __construct($stream, $options = array())
$this->customMetadata = isset($options['metadata'])
? $options['metadata']
- : array();
+ : [];
$this->stream = $stream;
$meta = stream_get_meta_data($this->stream);
@@ -264,7 +264,7 @@ public function write($string)
public function getMetadata($key = null)
{
if (!isset($this->stream)) {
- return $key ? null : array();
+ return $key ? null : [];
} elseif (!$key) {
return $this->customMetadata + stream_get_meta_data($this->stream);
} elseif (isset($this->customMetadata[$key])) {
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Uri.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Uri.php
index 63b14cc7..10ac02a8 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Uri.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/Uri.php
@@ -25,7 +25,7 @@ class Uri implements UriInterface
*/
const HTTP_DEFAULT_HOST = 'localhost';
- private static $defaultPorts = array(
+ private static $defaultPorts = [
'http' => 80,
'https' => 443,
'ftp' => 21,
@@ -37,13 +37,13 @@ class Uri implements UriInterface
'imap' => 143,
'pop' => 110,
'ldap' => 389,
- );
+ ];
private static $charUnreserved = 'a-zA-Z0-9_\-\.~';
private static $charSubDelims = '!\$&\'\(\)\*\+,;=';
- private static $replaceQuery = array('=' => '%3D', '&' => '%26');
+ private static $replaceQuery = ['=' => '%3D', '&' => '%26'];
/** @var string Uri scheme. */
private $scheme = '';
@@ -342,7 +342,7 @@ public static function withQueryValue(UriInterface $uri, $key, $value)
$current = $uri->getQuery();
if ('' === $current) {
- $result = array();
+ $result = [];
} else {
$decodedKey = rawurldecode($key);
$result = array_filter(explode('&', $current), function ($part) use ($decodedKey) {
@@ -651,7 +651,7 @@ private function filterPath($path)
return preg_replace_callback(
'/(?:[^'.self::$charUnreserved.self::$charSubDelims.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/',
- array($this, 'rawurlencodeMatchZero'),
+ [$this, 'rawurlencodeMatchZero'],
$path
);
}
@@ -673,7 +673,7 @@ private function filterQueryAndFragment($str)
return preg_replace_callback(
'/(?:[^'.self::$charUnreserved.self::$charSubDelims.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/',
- array($this, 'rawurlencodeMatchZero'),
+ [$this, 'rawurlencodeMatchZero'],
$str
);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/UriResolver.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/UriResolver.php
index 46b228e9..4d65c9c9 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/UriResolver.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/UriResolver.php
@@ -30,7 +30,7 @@ public static function removeDotSegments($path)
return $path;
}
- $results = array();
+ $results = [];
$segments = explode('/', $path);
$segment = null;
foreach ($segments as $segment) {
diff --git a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/functions.php b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/functions.php
index 05c50f3d..37fd9927 100644
--- a/includes/libraries/algoliasearch-client-php/src/Http/Psr7/functions.php
+++ b/includes/libraries/algoliasearch-client-php/src/Http/Psr7/functions.php
@@ -7,7 +7,7 @@
/**
* @internal
*/
-function stream_for($resource = '', array $options = array())
+function stream_for($resource = '', array $options = [])
{
if (is_scalar($resource)) {
$stream = fopen('php://temp', 'r+');
diff --git a/includes/libraries/algoliasearch-client-php/src/Insights/UserInsightsClient.php b/includes/libraries/algoliasearch-client-php/src/Insights/UserInsightsClient.php
index 62c53302..cc3fc8d4 100644
--- a/includes/libraries/algoliasearch-client-php/src/Insights/UserInsightsClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/Insights/UserInsightsClient.php
@@ -19,99 +19,99 @@ public function __construct(InsightsClient $client, $userToken)
$this->userToken = $userToken;
}
- public function clickedFilters($eventName, $indexName, $filters, $requestOptions = array())
+ public function clickedFilters($eventName, $indexName, $filters, $requestOptions = [])
{
- return $this->clicked(array('filters' => $filters), $eventName, $indexName, $requestOptions);
+ return $this->clicked(['filters' => $filters], $eventName, $indexName, $requestOptions);
}
- public function clickedObjectIDs($eventName, $indexName, $objectIDs, $requestOptions = array())
+ public function clickedObjectIDs($eventName, $indexName, $objectIDs, $requestOptions = [])
{
- return $this->clicked(array('objectIDs' => $objectIDs), $eventName, $indexName, $requestOptions);
+ return $this->clicked(['objectIDs' => $objectIDs], $eventName, $indexName, $requestOptions);
}
- public function clickedObjectIDsAfterSearch($eventName, $indexName, $objectIDs, $positions, $queryID, $requestOptions = array())
+ public function clickedObjectIDsAfterSearch($eventName, $indexName, $objectIDs, $positions, $queryID, $requestOptions = [])
{
- $event = array(
+ $event = [
'objectIDs' => $objectIDs,
'positions' => $positions,
'queryID' => $queryID,
- );
+ ];
return $this->clicked($event, $eventName, $indexName, $requestOptions);
}
private function clicked($event, $eventName, $indexName, $requestOptions)
{
- $event = array_merge($event, array(
+ $event = array_merge($event, [
'eventType' => 'click',
'eventName' => $eventName,
'index' => $indexName,
- ));
+ ]);
return $this->sendEvent($event, $requestOptions);
}
- public function convertedFilters($eventName, $indexName, $filters, $requestOptions = array())
+ public function convertedFilters($eventName, $indexName, $filters, $requestOptions = [])
{
- return $this->converted(array('filters' => $filters), $eventName, $indexName, $requestOptions);
+ return $this->converted(['filters' => $filters], $eventName, $indexName, $requestOptions);
}
- public function convertedObjectIDs($eventName, $indexName, $objectIDs, $requestOptions = array())
+ public function convertedObjectIDs($eventName, $indexName, $objectIDs, $requestOptions = [])
{
- return $this->converted(array('objectIDs' => $objectIDs), $eventName, $indexName, $requestOptions);
+ return $this->converted(['objectIDs' => $objectIDs], $eventName, $indexName, $requestOptions);
}
- public function convertedObjectIDsAfterSearch($eventName, $indexName, $objectIDs, $queryID, $requestOptions = array())
+ public function convertedObjectIDsAfterSearch($eventName, $indexName, $objectIDs, $queryID, $requestOptions = [])
{
- $event = array(
+ $event = [
'objectIDs' => $objectIDs,
'queryID' => $queryID,
- );
+ ];
return $this->converted($event, $eventName, $indexName, $requestOptions);
}
private function converted($event, $eventName, $indexName, $requestOptions)
{
- $event = array_merge($event, array(
+ $event = array_merge($event, [
'eventType' => 'conversion',
'eventName' => $eventName,
'index' => $indexName,
- ));
+ ]);
return $this->sendEvent($event, $requestOptions);
}
- public function viewedFilters($eventName, $indexName, $filters, $requestOptions = array())
+ public function viewedFilters($eventName, $indexName, $filters, $requestOptions = [])
{
- $event = array(
+ $event = [
'filters' => $filters,
- );
+ ];
return $this->viewed($event, $eventName, $indexName, $requestOptions);
}
- public function viewedObjectIDs($eventName, $indexName, $objectIDs, $requestOptions = array())
+ public function viewedObjectIDs($eventName, $indexName, $objectIDs, $requestOptions = [])
{
- $event = array(
+ $event = [
'objectIDs' => $objectIDs,
- );
+ ];
return $this->viewed($event, $eventName, $indexName, $requestOptions);
}
private function viewed($event, $eventName, $indexName, $requestOptions)
{
- $event = array_merge($event, array(
+ $event = array_merge($event, [
'eventType' => 'view',
'eventName' => $eventName,
'index' => $indexName,
- ));
+ ]);
return $this->sendEvent($event, $requestOptions);
}
- private function sendEvent($event, $requestOptions = array())
+ private function sendEvent($event, $requestOptions = [])
{
return $this->client->sendEvent($this->reformatEvent($event), $requestOptions);
}
@@ -119,15 +119,15 @@ private function sendEvent($event, $requestOptions = array())
private function reformatEvent($e)
{
if (isset($e['objectIDs']) && !is_array($e['objectIDs'])) {
- $e['objectIDs'] = array($e['objectIDs']);
+ $e['objectIDs'] = [$e['objectIDs']];
}
if (isset($e['filters']) && !is_array($e['filters'])) {
- $e['filters'] = array($e['filters']);
+ $e['filters'] = [$e['filters']];
}
if (isset($e['positions']) && !is_array($e['positions'])) {
- $e['positions'] = array($e['positions']);
+ $e['positions'] = [$e['positions']];
}
$e['userToken'] = $this->userToken;
diff --git a/includes/libraries/algoliasearch-client-php/src/InsightsClient.php b/includes/libraries/algoliasearch-client-php/src/InsightsClient.php
index db53a50e..237f2e97 100644
--- a/includes/libraries/algoliasearch-client-php/src/InsightsClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/InsightsClient.php
@@ -57,14 +57,14 @@ public function user($userToken)
return new UserInsightsClient($this, $userToken);
}
- public function sendEvent($event, $requestOptions = array())
+ public function sendEvent($event, $requestOptions = [])
{
- return $this->sendEvents(array($event), $requestOptions);
+ return $this->sendEvents([$event], $requestOptions);
}
- public function sendEvents($events, $requestOptions = array())
+ public function sendEvents($events, $requestOptions = [])
{
- $payload = array('events' => $events);
+ $payload = ['events' => $events];
return $this->api->write('POST', api_path('/1/events'), $payload, $requestOptions);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Iterators/AbstractAlgoliaIterator.php b/includes/libraries/algoliasearch-client-php/src/Iterators/AbstractAlgoliaIterator.php
index 07828494..ad11dff2 100644
--- a/includes/libraries/algoliasearch-client-php/src/Iterators/AbstractAlgoliaIterator.php
+++ b/includes/libraries/algoliasearch-client-php/src/Iterators/AbstractAlgoliaIterator.php
@@ -52,13 +52,13 @@ abstract protected function fetchNextPage();
*/
abstract protected function formatHit(array $hit);
- public function __construct($indexName, ApiWrapper $api, $requestOptions = array())
+ public function __construct($indexName, ApiWrapper $api, $requestOptions = [])
{
$this->indexName = $indexName;
$this->api = $api;
- $this->requestOptions = $requestOptions + array(
+ $this->requestOptions = $requestOptions + [
'hitsPerPage' => 1000,
- );
+ ];
$this->fetchNextPage();
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Iterators/ObjectIterator.php b/includes/libraries/algoliasearch-client-php/src/Iterators/ObjectIterator.php
index 3d22525f..d7a3f3da 100644
--- a/includes/libraries/algoliasearch-client-php/src/Iterators/ObjectIterator.php
+++ b/includes/libraries/algoliasearch-client-php/src/Iterators/ObjectIterator.php
@@ -28,7 +28,7 @@ protected function fetchNextPage()
return;
}
- $cursor = array();
+ $cursor = [];
if (isset($this->response['cursor'])) {
$cursor['cursor'] = $this->response['cursor'];
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Iterators/RuleIterator.php b/includes/libraries/algoliasearch-client-php/src/Iterators/RuleIterator.php
index 361b801d..1317697b 100644
--- a/includes/libraries/algoliasearch-client-php/src/Iterators/RuleIterator.php
+++ b/includes/libraries/algoliasearch-client-php/src/Iterators/RuleIterator.php
@@ -24,7 +24,7 @@ protected function fetchNextPage()
Helpers::apiPath('/1/indexes/%s/rules/search', $this->indexName),
array_merge(
$this->requestOptions,
- array('page' => $this->page)
+ ['page' => $this->page]
)
);
diff --git a/includes/libraries/algoliasearch-client-php/src/Iterators/SynonymIterator.php b/includes/libraries/algoliasearch-client-php/src/Iterators/SynonymIterator.php
index acb8268a..d1681108 100644
--- a/includes/libraries/algoliasearch-client-php/src/Iterators/SynonymIterator.php
+++ b/includes/libraries/algoliasearch-client-php/src/Iterators/SynonymIterator.php
@@ -24,7 +24,7 @@ protected function fetchNextPage()
Helpers::apiPath('/1/indexes/%s/synonyms/search', $this->indexName),
array_merge(
$this->requestOptions,
- array('page' => $this->page)
+ ['page' => $this->page]
)
);
diff --git a/includes/libraries/algoliasearch-client-php/src/Log/DebugLogger.php b/includes/libraries/algoliasearch-client-php/src/Log/DebugLogger.php
index 27db1d0e..0c765407 100644
--- a/includes/libraries/algoliasearch-client-php/src/Log/DebugLogger.php
+++ b/includes/libraries/algoliasearch-client-php/src/Log/DebugLogger.php
@@ -38,14 +38,14 @@ public static function enable()
/**
* {@inheritdoc}
*/
- public function log($level, $message, array $context = array())
+ public function log($level, $message, array $context = [])
{
if (self::$isEnabled) {
- $logMessage = array(
+ $logMessage = [
'level' => $level,
'message' => $message,
'context' => $context,
- );
+ ];
if (function_exists('dump')) {
dump($logMessage);
diff --git a/includes/libraries/algoliasearch-client-php/src/PlacesClient.php b/includes/libraries/algoliasearch-client-php/src/PlacesClient.php
index 2047dda9..47522504 100644
--- a/includes/libraries/algoliasearch-client-php/src/PlacesClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/PlacesClient.php
@@ -58,7 +58,7 @@ public static function createWithConfig(PlacesConfig $config)
return new static($apiWrapper, $config);
}
- public function search($query, $requestOptions = array())
+ public function search($query, $requestOptions = [])
{
$query = (string) $query;
@@ -71,12 +71,12 @@ public function search($query, $requestOptions = array())
return $this->api->read('POST', api_path('/1/places/query'), $requestOptions);
}
- public function getObject($objectID, $requestOptions = array())
+ public function getObject($objectID, $requestOptions = [])
{
return $this->api->read('GET', api_path('/1/places/%s', $objectID), $requestOptions);
}
- public function custom($method, $path, $requestOptions = array(), $hosts = null)
+ public function custom($method, $path, $requestOptions = [], $hosts = null)
{
return $this->api->send($method, $path, $requestOptions, $hosts);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/RecommendationClient.php b/includes/libraries/algoliasearch-client-php/src/RecommendationClient.php
index 4d82dadc..ac57630e 100644
--- a/includes/libraries/algoliasearch-client-php/src/RecommendationClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/RecommendationClient.php
@@ -70,7 +70,7 @@ public static function createWithConfig(RecommendationConfig $config)
*
* @return array
*/
- public function getPersonalizationStrategy($requestOptions = array())
+ public function getPersonalizationStrategy($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/strategies/personalization'), $requestOptions);
}
@@ -81,7 +81,7 @@ public function getPersonalizationStrategy($requestOptions = array())
*
* @return array
*/
- public function setPersonalizationStrategy($strategy, $requestOptions = array())
+ public function setPersonalizationStrategy($strategy, $requestOptions = [])
{
return $this->api->write('POST', api_path('/1/strategies/personalization'), $strategy, $requestOptions);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptions.php b/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptions.php
index 16500f0b..45b17622 100644
--- a/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptions.php
+++ b/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptions.php
@@ -6,11 +6,11 @@
final class RequestOptions
{
- private $headers = array();
+ private $headers = [];
- private $query = array();
+ private $query = [];
- private $body = array();
+ private $body = [];
private $readTimeout;
@@ -18,9 +18,9 @@ final class RequestOptions
private $connectTimeout;
- public function __construct(array $options = array())
+ public function __construct(array $options = [])
{
- foreach (array('headers', 'query', 'body') as $name) {
+ foreach (['headers', 'query', 'body'] as $name) {
if (isset($options[$name]) && !empty($options[$name])) {
$this->{$name} = $options[$name];
}
diff --git a/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptionsFactory.php b/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptionsFactory.php
index 575eee47..1c43c592 100644
--- a/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptionsFactory.php
+++ b/includes/libraries/algoliasearch-client-php/src/RequestOptions/RequestOptionsFactory.php
@@ -9,18 +9,18 @@ final class RequestOptionsFactory
{
private $config;
- private $validQueryParameters = array(
+ private $validQueryParameters = [
'forwardToReplicas',
'replaceExistingSynonyms',
'clearExistingRules',
'getVersion',
- );
+ ];
- private $validHeaders = array(
+ private $validHeaders = [
'Content-type',
'User-Agent',
'createIfNotExists',
- );
+ ];
public function __construct(AbstractConfig $config)
{
@@ -33,7 +33,7 @@ public function __construct(AbstractConfig $config)
*
* @return \Algolia\AlgoliaSearch\RequestOptions\RequestOptions
*/
- public function create($options, $defaults = array())
+ public function create($options, $defaults = [])
{
if (is_array($options)) {
$options += $defaults;
@@ -53,35 +53,35 @@ public function create($options, $defaults = array())
return $options->addDefaultHeaders($this->config->getDefaultHeaders());
}
- public function createBodyLess($options, $defaults = array())
+ public function createBodyLess($options, $defaults = [])
{
$options = $this->create($options, $defaults);
return $options
->addQueryParameters($options->getBody())
- ->setBody(array());
+ ->setBody([]);
}
private function normalize($options)
{
- $normalized = array(
- 'headers' => array(
+ $normalized = [
+ 'headers' => [
'X-Algolia-Application-Id' => $this->config->getAppId(),
'X-Algolia-API-Key' => $this->config->getApiKey(),
'User-Agent' => UserAgent::get(),
'Content-Type' => 'application/json',
- ),
- 'query' => array(),
- 'body' => array(),
+ ],
+ 'query' => [],
+ 'body' => [],
'readTimeout' => $this->config->getReadTimeout(),
'writeTimeout' => $this->config->getWriteTimeout(),
'connectTimeout' => $this->config->getConnectTimeout(),
- );
+ ];
foreach ($options as $optionName => $value) {
$type = $this->getOptionType($optionName);
- if (in_array($type, array('readTimeout', 'writeTimeout', 'connectTimeout'))) {
+ if (in_array($type, ['readTimeout', 'writeTimeout', 'connectTimeout'])) {
$normalized[$type] = $value;
} else {
$normalized[$type][$optionName] = $value;
@@ -94,7 +94,7 @@ private function normalize($options)
private function format($options)
{
foreach ($options as $name => $value) {
- if (in_array($name, array('attributesToRetrieve', 'type'), true)) {
+ if (in_array($name, ['attributesToRetrieve', 'type'], true)) {
if (is_array($value)) {
$options[$name] = implode(',', $value);
}
@@ -110,7 +110,7 @@ private function getOptionType($optionName)
return 'headers';
} elseif (in_array($optionName, $this->validQueryParameters, true)) {
return 'query';
- } elseif (in_array($optionName, array('connectTimeout', 'readTimeout', 'writeTimeout'), true)) {
+ } elseif (in_array($optionName, ['connectTimeout', 'readTimeout', 'writeTimeout'], true)) {
return $optionName;
} else {
return 'body';
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/AbstractResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/AbstractResponse.php
index 3150a76d..4103c70c 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/AbstractResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/AbstractResponse.php
@@ -9,7 +9,7 @@ abstract class AbstractResponse implements \ArrayAccess
*/
protected $apiResponse;
- abstract public function wait($requestOptions = array());
+ abstract public function wait($requestOptions = []);
/**
* @return array The actual response from Algolia API
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/AddApiKeyResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/AddApiKeyResponse.php
index d90c876b..535d0ad4 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/AddApiKeyResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/AddApiKeyResponse.php
@@ -25,7 +25,7 @@ public function __construct(array $apiResponse, SearchClient $client, SearchConf
$this->config = $config;
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (!isset($this->client)) {
return $this;
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/BatchIndexingResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/BatchIndexingResponse.php
index e741b44f..5fdde6e5 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/BatchIndexingResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/BatchIndexingResponse.php
@@ -22,7 +22,7 @@ public function __construct(array $apiResponse, SearchIndex $index)
$this->index = $index;
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (isset($this->index)) {
foreach ($this->apiResponse as $response) {
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/DeleteApiKeyResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/DeleteApiKeyResponse.php
index 0ea45b1d..b5a26200 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/DeleteApiKeyResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/DeleteApiKeyResponse.php
@@ -31,7 +31,7 @@ public function __construct(array $apiResponse, SearchClient $client, SearchConf
$this->key = $key;
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (!isset($this->client)) {
return $this;
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/DictionaryResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/DictionaryResponse.php
new file mode 100644
index 00000000..c80d92bc
--- /dev/null
+++ b/includes/libraries/algoliasearch-client-php/src/Response/DictionaryResponse.php
@@ -0,0 +1,78 @@
+apiResponse = $apiResponse;
+ $this->client = $client;
+ $this->config = $config;
+ }
+
+ /**
+ * Wait for the task from this response to finish.
+ *
+ * @param array|RequestOptions $requestOptions
+ *
+ * @return $this
+ */
+ public function wait($requestOptions = [])
+ {
+ $retryCount = 1;
+ $time = $this->config->getWaitTaskTimeBeforeRetry();
+
+ while (!$this->done) {
+ $res = $this->getTask($this->apiResponse['taskID'], $requestOptions);
+
+ if ('published' === $res['status']) {
+ $this->done = true;
+ break;
+ }
+
+ $retryCount++;
+ $factor = ceil($retryCount / 10);
+ usleep($factor * $time); // 0.1 second
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get the task details.
+ *
+ * @param int|string $taskId
+ * @param array|RequestOptions $requestOptions
+ *
+ * @return mixed
+ */
+ private function getTask($taskId, $requestOptions = [])
+ {
+ if (!$taskId) {
+ throw new \InvalidArgumentException('taskID cannot be empty');
+ }
+
+ return $this->client->custom(
+ 'GET',
+ \Algolia\AlgoliaSearch\api_path('/1/task/%s', $taskId),
+ $requestOptions
+ );
+ }
+}
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/IndexingResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/IndexingResponse.php
index dcf3b697..b12ec352 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/IndexingResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/IndexingResponse.php
@@ -17,7 +17,7 @@ public function __construct(array $apiResponse, SearchIndex $index)
$this->index = $index;
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (isset($this->index)) {
$this->index->waitTask($this->apiResponse['taskID'], $requestOptions);
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/MultiResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/MultiResponse.php
index fc42c0aa..cfeb79f0 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/MultiResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/MultiResponse.php
@@ -11,7 +11,7 @@ public function __construct($responses)
$this->apiResponse = $responses;
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
foreach ($this->apiResponse as $response) {
$response->wait();
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/MultipleIndexBatchIndexingResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/MultipleIndexBatchIndexingResponse.php
index 1e44d88c..ebd35fb1 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/MultipleIndexBatchIndexingResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/MultipleIndexBatchIndexingResponse.php
@@ -17,7 +17,7 @@ public function __construct(array $apiResponse, SearchClient $client)
$this->client = $client;
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (!isset($this->client)) {
return $this;
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/NullResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/NullResponse.php
index 2fc75db0..cd16d8bd 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/NullResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/NullResponse.php
@@ -6,10 +6,10 @@ final class NullResponse extends AbstractResponse
{
public function __construct()
{
- $this->apiResponse = array();
+ $this->apiResponse = [];
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
return $this;
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/RestoreApiKeyResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/RestoreApiKeyResponse.php
index dfe02baf..917fe057 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/RestoreApiKeyResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/RestoreApiKeyResponse.php
@@ -39,7 +39,7 @@ public function __construct(array $apiResponse, SearchClient $client, SearchConf
/**
* {@inheritdoc}
*/
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (!isset($this->client)) {
return $this;
diff --git a/includes/libraries/algoliasearch-client-php/src/Response/UpdateApiKeyResponse.php b/includes/libraries/algoliasearch-client-php/src/Response/UpdateApiKeyResponse.php
index 15d667cf..e17bec9b 100644
--- a/includes/libraries/algoliasearch-client-php/src/Response/UpdateApiKeyResponse.php
+++ b/includes/libraries/algoliasearch-client-php/src/Response/UpdateApiKeyResponse.php
@@ -32,7 +32,7 @@ public function __construct(
$this->keyParams = $this->filterOnlyKeyParams($requestOptions);
}
- public function wait($requestOptions = array())
+ public function wait($requestOptions = [])
{
if (!isset($this->client)) {
return $this;
@@ -75,11 +75,11 @@ private function isKeyUpdated($key, $keyParams)
private function filterOnlyKeyParams($requestOptions)
{
- $validKeyParams = array(
+ $validKeyParams = [
'acl', 'indexes', 'referers',
'restrictSources', 'queryParameters', 'description',
'validity', 'maxQueriesPerIPPerHour', 'maxHitsPerQuery',
- );
+ ];
return array_intersect_key($requestOptions, array_flip($validKeyParams));
}
diff --git a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapper.php b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapper.php
index 6c8f1a0a..3409641e 100644
--- a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapper.php
+++ b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapper.php
@@ -71,7 +71,7 @@ public function __construct(
}
}
- public function read($method, $path, $requestOptions = array(), $defaultRequestOptions = array())
+ public function read($method, $path, $requestOptions = [], $defaultRequestOptions = [])
{
if ('GET' === strtoupper($method)) {
$requestOptions = $this->requestOptionsFactory->createBodyLess($requestOptions, $defaultRequestOptions);
@@ -88,11 +88,11 @@ public function read($method, $path, $requestOptions = array(), $defaultRequestO
);
}
- public function write($method, $path, $data = array(), $requestOptions = array(), $defaultRequestOptions = array())
+ public function write($method, $path, $data = [], $requestOptions = [], $defaultRequestOptions = [])
{
if ('DELETE' === strtoupper($method)) {
$requestOptions = $this->requestOptionsFactory->createBodyLess($requestOptions, $defaultRequestOptions);
- $data = array();
+ $data = [];
} else {
$requestOptions = $this->requestOptionsFactory->create($requestOptions, $defaultRequestOptions);
}
@@ -107,14 +107,14 @@ public function write($method, $path, $data = array(), $requestOptions = array()
);
}
- public function send($method, $path, $requestOptions = array(), $hosts = null)
+ public function send($method, $path, $requestOptions = [], $hosts = null)
{
$requestOptions = $this->requestOptionsFactory->create($requestOptions);
if (null === $hosts) {
$hosts = $this->clusterHosts->write();
} elseif (!is_array($hosts)) {
- $hosts = array($hosts);
+ $hosts = [$hosts];
}
return $this->request(
@@ -126,7 +126,7 @@ public function send($method, $path, $requestOptions = array(), $hosts = null)
);
}
- private function request($method, $path, RequestOptions $requestOptions, $hosts, $timeout, $data = array())
+ private function request($method, $path, RequestOptions $requestOptions, $hosts, $timeout, $data = [])
{
$uri = $this->createUri($path)
->withQuery($requestOptions->getBuiltQueryParameters())
@@ -134,12 +134,12 @@ private function request($method, $path, RequestOptions $requestOptions, $hosts,
$body = array_merge($data, $requestOptions->getBody());
- $logParams = array(
+ $logParams = [
'body' => $body,
'headers' => $requestOptions->getHeaders(),
'method' => $method,
'query' => $requestOptions->getQueryParameters(),
- );
+ ];
$retry = 1;
foreach ($hosts as $host) {
@@ -171,9 +171,9 @@ private function request($method, $path, RequestOptions $requestOptions, $hosts,
return $responseBody;
} catch (RetriableException $e) {
- $this->log(LogLevel::DEBUG, 'Host failed.', array_merge($logParams, array(
+ $this->log(LogLevel::DEBUG, 'Host failed.', array_merge($logParams, [
'description' => $e->getMessage(),
- )));
+ ]));
$this->clusterHosts->failed($host);
} catch (BadRequestException $e) {
@@ -238,7 +238,7 @@ private function createUri($uri)
private function createRequest(
$method,
$uri,
- array $headers = array(),
+ array $headers = [],
$body = null,
$protocolVersion = '1.1'
) {
@@ -262,7 +262,7 @@ private function createRequest(
* @param string $level
* @param string $message
*/
- private function log($level, $message, array $context = array())
+ private function log($level, $message, array $context = [])
{
$this->logger->log($level, 'Algolia API client: '.$message, $context);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapperInterface.php b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapperInterface.php
index 7e93f803..9d2ba6f8 100644
--- a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapperInterface.php
+++ b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ApiWrapperInterface.php
@@ -4,9 +4,9 @@
interface ApiWrapperInterface
{
- public function read($method, $path, $requestOptions = array(), $defaultRequestOptions = array());
+ public function read($method, $path, $requestOptions = [], $defaultRequestOptions = []);
- public function write($method, $path, $data = array(), $requestOptions = array(), $defaultRequestOptions = array());
+ public function write($method, $path, $data = [], $requestOptions = [], $defaultRequestOptions = []);
- public function send($method, $path, $requestOptions = array(), $hosts = null);
+ public function send($method, $path, $requestOptions = [], $hosts = null);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ClusterHosts.php b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ClusterHosts.php
index 7873b6d0..8c5a423e 100644
--- a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ClusterHosts.php
+++ b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/ClusterHosts.php
@@ -32,11 +32,11 @@ public static function create($read, $write = null)
}
if (is_string($read)) {
- $read = array($read => 0);
+ $read = [$read => 0];
}
if (is_string($write)) {
- $write = array($write => 0);
+ $write = [$write => 0];
}
if (array_values($read) === $read) {
@@ -52,11 +52,11 @@ public static function create($read, $write = null)
public static function createFromAppId($applicationId)
{
- $read = $write = array(
+ $read = $write = [
$applicationId.'-1.algolianet.com' => 0,
$applicationId.'-2.algolianet.com' => 0,
$applicationId.'-3.algolianet.com' => 0,
- );
+ ];
$read[$applicationId.'-dsn.algolia.net'] = 10;
$write[$applicationId.'.algolia.net'] = 10;
@@ -66,11 +66,11 @@ public static function createFromAppId($applicationId)
public static function createForPlaces()
{
- $read = $write = array(
+ $read = $write = [
'places-1.algolianet.com' => 0,
'places-2.algolianet.com' => 0,
'places-3.algolianet.com' => 0,
- );
+ ];
$read['places-dsn.algolia.net'] = 10;
$write['places.algolia.net'] = 10;
diff --git a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/HostCollection.php b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/HostCollection.php
index a8191484..77dc1c4d 100644
--- a/includes/libraries/algoliasearch-client-php/src/RetryStrategy/HostCollection.php
+++ b/includes/libraries/algoliasearch-client-php/src/RetryStrategy/HostCollection.php
@@ -18,7 +18,7 @@ public function __construct(array $hosts)
public static function create(array $urlsWithPriority)
{
- $hosts = array();
+ $hosts = [];
foreach ($urlsWithPriority as $url => $priority) {
$hosts[] = new Host($url, $priority);
}
diff --git a/includes/libraries/algoliasearch-client-php/src/SearchClient.php b/includes/libraries/algoliasearch-client-php/src/SearchClient.php
index 20a08a00..c5aee7ec 100644
--- a/includes/libraries/algoliasearch-client-php/src/SearchClient.php
+++ b/includes/libraries/algoliasearch-client-php/src/SearchClient.php
@@ -7,6 +7,7 @@
use Algolia\AlgoliaSearch\RequestOptions\RequestOptions;
use Algolia\AlgoliaSearch\Response\AddApiKeyResponse;
use Algolia\AlgoliaSearch\Response\DeleteApiKeyResponse;
+use Algolia\AlgoliaSearch\Response\DictionaryResponse;
use Algolia\AlgoliaSearch\Response\IndexingResponse;
use Algolia\AlgoliaSearch\Response\MultipleIndexBatchIndexingResponse;
use Algolia\AlgoliaSearch\Response\RestoreApiKeyResponse;
@@ -85,76 +86,84 @@ public function getAppId()
return $this->config->getAppId();
}
- public function moveIndex($srcIndexName, $newIndexName, $requestOptions = array())
+ public function moveIndex($srcIndexName, $newIndexName, $requestOptions = [])
{
$response = $this->api->write(
'POST',
api_path('/1/indexes/%s/operation', $srcIndexName),
- array(
+ [
'operation' => 'move',
'destination' => $newIndexName,
- ),
+ ],
$requestOptions
);
return new IndexingResponse($response, $this->initIndex($srcIndexName));
}
- public function copyIndex($srcIndexName, $destIndexName, $requestOptions = array())
+ public function copyIndex($srcIndexName, $destIndexName, $requestOptions = [])
{
$response = $this->api->write(
'POST',
api_path('/1/indexes/%s/operation', $srcIndexName),
- array(
+ [
'operation' => 'copy',
'destination' => $destIndexName,
- ),
+ ],
$requestOptions
);
return new IndexingResponse($response, $this->initIndex($srcIndexName));
}
- public function copySettings($srcIndexName, $destIndexName, $requestOptions = array())
+ public function copySettings($srcIndexName, $destIndexName, $requestOptions = [])
{
if (is_array($requestOptions)) {
- $requestOptions['scope'] = array('settings');
+ $requestOptions['scope'] = ['settings'];
} elseif ($requestOptions instanceof RequestOptions) {
- $requestOptions->addBodyParameter('scope', array('settings'));
+ $requestOptions->addBodyParameter('scope', ['settings']);
}
return $this->copyIndex($srcIndexName, $destIndexName, $requestOptions);
}
- public function copySynonyms($srcIndexName, $destIndexName, $requestOptions = array())
+ public function copySynonyms($srcIndexName, $destIndexName, $requestOptions = [])
{
if (is_array($requestOptions)) {
- $requestOptions['scope'] = array('synonyms');
+ $requestOptions['scope'] = ['synonyms'];
} elseif ($requestOptions instanceof RequestOptions) {
- $requestOptions->addBodyParameter('scope', array('synonyms'));
+ $requestOptions->addBodyParameter('scope', ['synonyms']);
}
return $this->copyIndex($srcIndexName, $destIndexName, $requestOptions);
}
- public function copyRules($srcIndexName, $destIndexName, $requestOptions = array())
+ public function copyRules($srcIndexName, $destIndexName, $requestOptions = [])
{
if (is_array($requestOptions)) {
- $requestOptions['scope'] = array('rules');
+ $requestOptions['scope'] = ['rules'];
} elseif ($requestOptions instanceof RequestOptions) {
- $requestOptions->addBodyParameter('scope', array('rules'));
+ $requestOptions->addBodyParameter('scope', ['rules']);
}
return $this->copyIndex($srcIndexName, $destIndexName, $requestOptions);
}
- public function isAlive($requestOptions = array())
+ public function isAlive($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/isalive'), $requestOptions);
}
- public function multipleQueries($queries, $requestOptions = array())
+ public function multipleQueries($queries, $requestOptions = [])
{
+ $queries = array_map(function ($query) {
+ $query['params'] = isset($query['params']) ?
+ Helpers::serializeQueryParameters($query['params']) :
+ Helpers::serializeQueryParameters([]);
+
+ return $query;
+ }, $queries);
+
if (is_array($requestOptions)) {
$requestOptions['requests'] = $queries;
} elseif ($requestOptions instanceof RequestOptions) {
@@ -168,19 +177,19 @@ public function multipleQueries($queries, $requestOptions = array())
);
}
- public function multipleBatch($operations, $requestOptions = array())
+ public function multipleBatch($operations, $requestOptions = [])
{
$response = $this->api->write(
'POST',
api_path('/1/indexes/*/batch'),
- array('requests' => $operations),
+ ['requests' => $operations],
$requestOptions
);
return new MultipleIndexBatchIndexingResponse($response, $this);
}
- public function multipleGetObjects($requests, $requestOptions = array())
+ public function multipleGetObjects($requests, $requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['requests'] = $requests;
@@ -195,47 +204,47 @@ public function multipleGetObjects($requests, $requestOptions = array())
);
}
- public function listIndices($requestOptions = array())
+ public function listIndices($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/indexes/'), $requestOptions);
}
- public function listApiKeys($requestOptions = array())
+ public function listApiKeys($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/keys'), $requestOptions);
}
- public function getApiKey($key, $requestOptions = array())
+ public function getApiKey($key, $requestOptions = [])
{
return $this->api->read('GET', api_path('/1/keys/%s', $key), $requestOptions);
}
- public function addApiKey($acl, $requestOptions = array())
+ public function addApiKey($acl, $requestOptions = [])
{
- $acl = array('acl' => $acl);
+ $acl = ['acl' => $acl];
$response = $this->api->write('POST', api_path('/1/keys'), $acl, $requestOptions);
return new AddApiKeyResponse($response, $this, $this->config);
}
- public function updateApiKey($key, $requestOptions = array())
+ public function updateApiKey($key, $requestOptions = [])
{
- $response = $this->api->write('PUT', api_path('/1/keys/%s', $key), array(), $requestOptions);
+ $response = $this->api->write('PUT', api_path('/1/keys/%s', $key), [], $requestOptions);
return new UpdateApiKeyResponse($response, $this, $this->config, $requestOptions);
}
- public function deleteApiKey($key, $requestOptions = array())
+ public function deleteApiKey($key, $requestOptions = [])
{
- $response = $this->api->write('DELETE', api_path('/1/keys/%s', $key), array(), $requestOptions);
+ $response = $this->api->write('DELETE', api_path('/1/keys/%s', $key), [], $requestOptions);
return new DeleteApiKeyResponse($response, $this, $this->config, $key);
}
- public function restoreApiKey($key, $requestOptions = array())
+ public function restoreApiKey($key, $requestOptions = [])
{
- $response = $this->api->write('POST', api_path('/1/keys/%s/restore', $key), array(), $requestOptions);
+ $response = $this->api->write('POST', api_path('/1/keys/%s/restore', $key), [], $requestOptions);
return new RestoreApiKeyResponse($response, $this, $this->config, $key);
}
@@ -253,7 +262,7 @@ public static function generateSecuredApiKey($parentApiKey, $restrictions)
* @deprecated endpoint will be deprecated
* @see RecommendationClient
*/
- public function getPersonalizationStrategy($requestOptions = array())
+ public function getPersonalizationStrategy($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/recommendation/personalization/strategy'), $requestOptions);
}
@@ -262,7 +271,7 @@ public function getPersonalizationStrategy($requestOptions = array())
* @deprecated endpoint will be deprecated
* @see RecommendationClient
*/
- public function setPersonalizationStrategy($strategy, $requestOptions = array())
+ public function setPersonalizationStrategy($strategy, $requestOptions = [])
{
$apiResponse = $this->api->write(
'POST',
@@ -274,7 +283,7 @@ public function setPersonalizationStrategy($strategy, $requestOptions = array())
return $apiResponse;
}
- public function searchUserIds($query, $requestOptions = array())
+ public function searchUserIds($query, $requestOptions = [])
{
$query = (string) $query;
@@ -287,17 +296,17 @@ public function searchUserIds($query, $requestOptions = array())
return $this->api->read('POST', api_path('/1/clusters/mapping/search'), $requestOptions);
}
- public function listClusters($requestOptions = array())
+ public function listClusters($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/clusters'), $requestOptions);
}
- public function listUserIds($requestOptions = array())
+ public function listUserIds($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/clusters/mapping'), $requestOptions);
}
- public function getUserId($userId, $requestOptions = array())
+ public function getUserId($userId, $requestOptions = [])
{
return $this->api->read('GET', api_path('/1/clusters/mapping/%s', $userId), $requestOptions);
}
@@ -305,7 +314,7 @@ public function getUserId($userId, $requestOptions = array())
/**
* @deprecated since 2.6.1, use getTopUserIds instead.
*/
- public function getTopUserId($requestOptions = array())
+ public function getTopUserId($requestOptions = [])
{
return $this->getTopUserIds($requestOptions);
}
@@ -317,12 +326,12 @@ public function getTopUserId($requestOptions = array())
*
* @return array
*/
- public function getTopUserIds($requestOptions = array())
+ public function getTopUserIds($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/clusters/mapping/top'), $requestOptions);
}
- public function assignUserId($userId, $clusterName, $requestOptions = array())
+ public function assignUserId($userId, $clusterName, $requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['X-Algolia-User-ID'] = $userId;
@@ -333,9 +342,9 @@ public function assignUserId($userId, $clusterName, $requestOptions = array())
return $this->api->write(
'POST',
api_path('/1/clusters/mapping'),
- array(
+ [
'cluster' => $clusterName,
- ),
+ ],
$requestOptions
);
}
@@ -349,20 +358,20 @@ public function assignUserId($userId, $clusterName, $requestOptions = array())
*
* @return array
*/
- public function assignUserIds($userIds, $clusterName, $requestOptions = array())
+ public function assignUserIds($userIds, $clusterName, $requestOptions = [])
{
return $this->api->write(
'POST',
api_path('/1/clusters/mapping/batch'),
- array(
+ [
'users' => $userIds,
'cluster' => $clusterName,
- ),
+ ],
$requestOptions
);
}
- public function removeUserId($userId, $requestOptions = array())
+ public function removeUserId($userId, $requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['X-Algolia-User-ID'] = $userId;
@@ -373,31 +382,31 @@ public function removeUserId($userId, $requestOptions = array())
return $this->api->write(
'DELETE',
api_path('/1/clusters/mapping'),
- array(),
+ [],
$requestOptions
);
}
- public function getLogs($requestOptions = array())
+ public function getLogs($requestOptions = [])
{
return $this->api->read('GET', api_path('/1/logs'), $requestOptions);
}
- public function getTask($indexName, $taskId, $requestOptions = array())
+ public function getTask($indexName, $taskId, $requestOptions = [])
{
$index = $this->initIndex($indexName);
return $index->getTask($taskId, $requestOptions);
}
- public function waitTask($indexName, $taskId, $requestOptions = array())
+ public function waitTask($indexName, $taskId, $requestOptions = [])
{
$index = $this->initIndex($indexName);
$index->waitTask($taskId, $requestOptions);
}
- public function custom($method, $path, $requestOptions = array(), $hosts = null)
+ public function custom($method, $path, $requestOptions = [], $hosts = null)
{
return $this->api->send($method, $path, $requestOptions, $hosts);
}
@@ -433,7 +442,7 @@ public static function getSecuredApiKeyRemainingValidity($securedAPIKey)
*
* @return array
*/
- public function hasPendingMappings($requestOptions = array())
+ public function hasPendingMappings($requestOptions = [])
{
if (isset($requestOptions['retrieveMappings'])
&& true === $requestOptions['retrieveMappings']) {
@@ -450,4 +459,149 @@ public function hasPendingMappings($requestOptions = array())
$requestOptions
);
}
+
+ /**
+ * Save entries to the given dictionary.
+ *
+ * @param string $dictionary
+ * @param array> $entries
+ * @param array|RequestOptions $requestOptions
+ *
+ * @return DictionaryResponse
+ */
+ public function saveDictionaryEntries($dictionary, $entries, $requestOptions = [])
+ {
+ $response = $this->api->write(
+ 'POST',
+ api_path('/1/dictionaries/%s/batch', $dictionary),
+ [
+ 'clearExistingDictionaryEntries' => false,
+ 'requests' => Helpers::buildBatch($entries, 'addEntry'),
+ ],
+ $requestOptions
+ );
+
+ return new DictionaryResponse($response, $this, $this->config);
+ }
+
+ /**
+ * Replace all dictionary entries.
+ *
+ * @param string $dictionary
+ * @param array> $entries
+ * @param array $requestOptions
+ *
+ * @return DictionaryResponse
+ */
+ public function replaceDictionaryEntries($dictionary, $entries, $requestOptions = [])
+ {
+ $response = $this->api->write(
+ 'POST',
+ api_path('/1/dictionaries/%s/batch', $dictionary),
+ [
+ 'clearExistingDictionaryEntries' => true,
+ 'requests' => Helpers::buildBatch($entries, 'addEntry'),
+ ],
+ $requestOptions
+ );
+
+ return new DictionaryResponse($response, $this, $this->config);
+ }
+
+ /**
+ * Delete dictionary entries by their objectID.
+ *
+ * @param string $dictionary
+ * @param array $objectIDs
+ * @param array $requestOptions
+ *
+ * @return DictionaryResponse
+ */
+ public function deleteDictionaryEntries($dictionary, $objectIDs, $requestOptions = [])
+ {
+ $entries = array_map(function ($objectID) {
+ return ['objectID' => $objectID];
+ }, $objectIDs);
+
+ $response = $this->api->write(
+ 'POST',
+ api_path('/1/dictionaries/%s/batch', $dictionary),
+ [
+ 'clearExistingDictionaryEntries' => false,
+ 'requests' => Helpers::buildBatch($entries, 'deleteEntry'),
+ ],
+ $requestOptions
+ );
+
+ return new DictionaryResponse($response, $this, $this->config);
+ }
+
+ /**
+ * Clear all entries in the given dictionary.
+ *
+ * @param string $dictionary
+ * @param array|RequestOptions $requestOptions
+ *
+ * @return DictionaryResponse
+ */
+ public function clearDictionaryEntries($dictionary, $requestOptions = [])
+ {
+ return $this->replaceDictionaryEntries($dictionary, [], $requestOptions);
+ }
+
+ /**
+ * Search the dictionary for entries.
+ *
+ * @param string $dictionary
+ * @param string $query
+ * @param array|RequestOptions $requestOptions
+ *
+ * @return mixed
+ */
+ public function searchDictionaryEntries($dictionary, $query, $requestOptions = [])
+ {
+ return $this->api->read(
+ 'POST',
+ api_path('/1/dictionaries/%s/search', $dictionary),
+ ['query' => $query],
+ $requestOptions
+ );
+ }
+
+ /**
+ * Update the settings for all dictionaries.
+ *
+ * @param array $dictionarySettings
+ * @param array $requestOptions
+ *
+ * @return DictionaryResponse
+ */
+ public function setDictionarySettings($dictionarySettings, $requestOptions = [])
+ {
+ $response = $this->api->write(
+ 'PUT',
+ api_path('/1/dictionaries/*/settings'),
+ $dictionarySettings,
+ $requestOptions
+ );
+
+ return new DictionaryResponse($response, $this, $this->config);
+ }
+
+ /**
+ * Get the settings for all dictionaries.
+ *
+ * @param array|RequestOptions $requestOptions
+ *
+ * @return mixed
+ */
+ public function getDictionarySettings($requestOptions = [])
+ {
+ return $this->api->read(
+ 'GET',
+ api_path('/1/dictionaries/*/settings'),
+ [],
+ $requestOptions
+ );
+ }
}
diff --git a/includes/libraries/algoliasearch-client-php/src/SearchIndex.php b/includes/libraries/algoliasearch-client-php/src/SearchIndex.php
index 07f65a53..656e9e36 100644
--- a/includes/libraries/algoliasearch-client-php/src/SearchIndex.php
+++ b/includes/libraries/algoliasearch-client-php/src/SearchIndex.php
@@ -49,7 +49,7 @@ public function getAppId()
return $this->config->getAppId();
}
- public function search($query, $requestOptions = array())
+ public function search($query, $requestOptions = [])
{
$query = (string) $query;
@@ -65,12 +65,12 @@ public function search($query, $requestOptions = array())
/**
* @deprecated Please use searchForFacetValues instead
*/
- public function searchForFacetValue($facetName, $facetQuery, $requestOptions = array())
+ public function searchForFacetValue($facetName, $facetQuery, $requestOptions = [])
{
return $this->searchForFacetValues($facetName, $facetQuery, $requestOptions);
}
- public function searchForFacetValues($facetName, $facetQuery, $requestOptions = array())
+ public function searchForFacetValues($facetName, $facetQuery, $requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['facetQuery'] = $facetQuery;
@@ -85,7 +85,7 @@ public function searchForFacetValues($facetName, $facetQuery, $requestOptions =
);
}
- public function getSettings($requestOptions = array())
+ public function getSettings($requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['getVersion'] = 2;
@@ -100,9 +100,9 @@ public function getSettings($requestOptions = array())
);
}
- public function setSettings($settings, $requestOptions = array())
+ public function setSettings($settings, $requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
@@ -118,7 +118,7 @@ public function setSettings($settings, $requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function getObject($objectId, $requestOptions = array())
+ public function getObject($objectId, $requestOptions = [])
{
return $this->api->read(
'GET',
@@ -127,7 +127,7 @@ public function getObject($objectId, $requestOptions = array())
);
}
- public function getObjects($objectIds, $requestOptions = array())
+ public function getObjects($objectIds, $requestOptions = [])
{
if (is_array($requestOptions)) {
$attributesToRetrieve = '';
@@ -136,12 +136,12 @@ public function getObjects($objectIds, $requestOptions = array())
unset($requestOptions['attributesToRetrieve']);
}
- $request = array();
+ $request = [];
foreach ($objectIds as $id) {
- $req = array(
+ $req = [
'indexName' => $this->indexName,
'objectID' => (string) $id,
- );
+ ];
if ($attributesToRetrieve) {
$req['attributesToRetrieve'] = $attributesToRetrieve;
@@ -160,12 +160,12 @@ public function getObjects($objectIds, $requestOptions = array())
);
}
- public function saveObject($object, $requestOptions = array())
+ public function saveObject($object, $requestOptions = [])
{
- return $this->saveObjects(array($object), $requestOptions);
+ return $this->saveObjects([$object], $requestOptions);
}
- public function saveObjects($objects, $requestOptions = array())
+ public function saveObjects($objects, $requestOptions = [])
{
if (isset($requestOptions['autoGenerateObjectIDIfNotExist'])
&& $requestOptions['autoGenerateObjectIDIfNotExist']) {
@@ -192,17 +192,17 @@ public function saveObjects($objects, $requestOptions = array())
}
}
- protected function addObjects($objects, $requestOptions = array())
+ protected function addObjects($objects, $requestOptions = [])
{
return $this->splitIntoBatches('addObject', $objects, $requestOptions);
}
- public function partialUpdateObject($object, $requestOptions = array())
+ public function partialUpdateObject($object, $requestOptions = [])
{
- return $this->partialUpdateObjects(array($object), $requestOptions);
+ return $this->partialUpdateObjects([$object], $requestOptions);
}
- public function partialUpdateObjects($objects, $requestOptions = array())
+ public function partialUpdateObjects($objects, $requestOptions = [])
{
$action = 'partialUpdateObjectNoCreate';
@@ -214,7 +214,7 @@ public function partialUpdateObjects($objects, $requestOptions = array())
return $this->splitIntoBatches($action, $objects, $requestOptions);
}
- public function replaceAllObjects($objects, $requestOptions = array())
+ public function replaceAllObjects($objects, $requestOptions = [])
{
$safe = isset($requestOptions['safe']) && $requestOptions['safe'];
unset($requestOptions['safe']);
@@ -223,9 +223,9 @@ public function replaceAllObjects($objects, $requestOptions = array())
$tmpIndex = new static($tmpName, $this->api, $this->config);
// Copy all index resources from production index
- $copyResponse = $this->copyTo($tmpIndex->getIndexName(), array(
- 'scope' => array('settings', 'synonyms', 'rules'),
- ));
+ $copyResponse = $this->copyTo($tmpIndex->getIndexName(), [
+ 'scope' => ['settings', 'synonyms', 'rules'],
+ ]);
if ($safe) {
$copyResponse->wait();
@@ -245,24 +245,24 @@ public function replaceAllObjects($objects, $requestOptions = array())
$moveResponse->wait();
}
- return new MultiResponse(array($copyResponse, $batchResponse, $moveResponse));
+ return new MultiResponse([$copyResponse, $batchResponse, $moveResponse]);
}
- public function deleteObject($objectId, $requestOptions = array())
+ public function deleteObject($objectId, $requestOptions = [])
{
- return $this->deleteObjects(array($objectId), $requestOptions);
+ return $this->deleteObjects([$objectId], $requestOptions);
}
- public function deleteObjects($objectIds, $requestOptions = array())
+ public function deleteObjects($objectIds, $requestOptions = [])
{
$objects = array_map(function ($id) {
- return array('objectID' => $id);
+ return ['objectID' => $id];
}, $objectIds);
return $this->splitIntoBatches('deleteObject', $objects, $requestOptions);
}
- public function deleteBy($filters, $requestOptions = array())
+ public function deleteBy($filters, $requestOptions = [])
{
$response = $this->api->write(
'POST',
@@ -274,39 +274,39 @@ public function deleteBy($filters, $requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function clearObjects($requestOptions = array())
+ public function clearObjects($requestOptions = [])
{
$response = $this->api->write(
'POST',
api_path('/1/indexes/%s/clear', $this->indexName),
- array(),
+ [],
$requestOptions
);
return new IndexingResponse($response, $this);
}
- public function batch($requests, $requestOptions = array())
+ public function batch($requests, $requestOptions = [])
{
$response = $this->rawBatch($requests, $requestOptions);
return new IndexingResponse($response, $this);
}
- protected function rawBatch($requests, $requestOptions = array())
+ protected function rawBatch($requests, $requestOptions = [])
{
return $this->api->write(
'POST',
api_path('/1/indexes/%s/batch', $this->indexName),
- array('requests' => $requests),
+ ['requests' => $requests],
$requestOptions
);
}
- protected function splitIntoBatches($action, $objects, $requestOptions = array())
+ protected function splitIntoBatches($action, $objects, $requestOptions = [])
{
- $allResponses = array();
- $batch = array();
+ $allResponses = [];
+ $batch = [];
$batchSize = $this->config->getBatchSize();
$count = 0;
@@ -319,7 +319,7 @@ protected function splitIntoBatches($action, $objects, $requestOptions = array()
Helpers::ensureObjectID($batch, 'All objects must have an unique objectID (like a primary key) to be valid.');
}
$allResponses[] = $this->rawBatch(Helpers::buildBatch($batch, $action), $requestOptions);
- $batch = array();
+ $batch = [];
$count = 0;
}
}
@@ -341,12 +341,12 @@ protected function splitIntoBatches($action, $objects, $requestOptions = array()
return new BatchIndexingResponse($allResponses, $this);
}
- public function browseObjects($requestOptions = array())
+ public function browseObjects($requestOptions = [])
{
return new ObjectIterator($this->indexName, $this->api, $requestOptions);
}
- public function searchSynonyms($query, $requestOptions = array())
+ public function searchSynonyms($query, $requestOptions = [])
{
$query = (string) $query;
@@ -363,7 +363,7 @@ public function searchSynonyms($query, $requestOptions = array())
);
}
- public function getSynonym($objectId, $requestOptions = array())
+ public function getSynonym($objectId, $requestOptions = [])
{
return $this->api->read(
'GET',
@@ -372,20 +372,20 @@ public function getSynonym($objectId, $requestOptions = array())
);
}
- public function saveSynonym($synonym, $requestOptions = array())
+ public function saveSynonym($synonym, $requestOptions = [])
{
- return $this->saveSynonyms(array($synonym), $requestOptions);
+ return $this->saveSynonyms([$synonym], $requestOptions);
}
- public function saveSynonyms($synonyms, $requestOptions = array())
+ public function saveSynonyms($synonyms, $requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
if ($synonyms instanceof \Iterator) {
- $iteratedOver = array();
+ $iteratedOver = [];
foreach ($synonyms as $r) {
$iteratedOver[] = $r;
}
@@ -409,7 +409,7 @@ public function saveSynonyms($synonyms, $requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function replaceAllSynonyms($synonyms, $requestOptions = array())
+ public function replaceAllSynonyms($synonyms, $requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['replaceExistingSynonyms'] = true;
@@ -420,9 +420,9 @@ public function replaceAllSynonyms($synonyms, $requestOptions = array())
return $this->saveSynonyms($synonyms, $requestOptions);
}
- public function deleteSynonym($objectId, $requestOptions = array())
+ public function deleteSynonym($objectId, $requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
@@ -430,7 +430,7 @@ public function deleteSynonym($objectId, $requestOptions = array())
$response = $this->api->write(
'DELETE',
api_path('/1/indexes/%s/synonyms/%s', $this->indexName, $objectId),
- array(),
+ [],
$requestOptions,
$default
);
@@ -438,9 +438,9 @@ public function deleteSynonym($objectId, $requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function clearSynonyms($requestOptions = array())
+ public function clearSynonyms($requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
@@ -448,7 +448,7 @@ public function clearSynonyms($requestOptions = array())
$response = $this->api->write(
'POST',
api_path('/1/indexes/%s/synonyms/clear', $this->indexName),
- array(),
+ [],
$requestOptions,
$default
);
@@ -456,12 +456,12 @@ public function clearSynonyms($requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function browseSynonyms($requestOptions = array())
+ public function browseSynonyms($requestOptions = [])
{
return new SynonymIterator($this->indexName, $this->api, $requestOptions);
}
- public function searchRules($query, $requestOptions = array())
+ public function searchRules($query, $requestOptions = [])
{
$query = (string) $query;
@@ -478,7 +478,7 @@ public function searchRules($query, $requestOptions = array())
);
}
- public function getRule($objectId, $requestOptions = array())
+ public function getRule($objectId, $requestOptions = [])
{
return $this->api->read(
'GET',
@@ -487,20 +487,20 @@ public function getRule($objectId, $requestOptions = array())
);
}
- public function saveRule($rule, $requestOptions = array())
+ public function saveRule($rule, $requestOptions = [])
{
- return $this->saveRules(array($rule), $requestOptions);
+ return $this->saveRules([$rule], $requestOptions);
}
- public function saveRules($rules, $requestOptions = array())
+ public function saveRules($rules, $requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
if ($rules instanceof \Iterator) {
- $iteratedOver = array();
+ $iteratedOver = [];
foreach ($rules as $r) {
$iteratedOver[] = $r;
}
@@ -536,7 +536,7 @@ public function saveRules($rules, $requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function replaceAllRules($rules, $requestOptions = array())
+ public function replaceAllRules($rules, $requestOptions = [])
{
if (is_array($requestOptions)) {
$requestOptions['clearExistingRules'] = true;
@@ -547,9 +547,9 @@ public function replaceAllRules($rules, $requestOptions = array())
return $this->saveRules($rules, $requestOptions);
}
- public function deleteRule($objectId, $requestOptions = array())
+ public function deleteRule($objectId, $requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
@@ -557,7 +557,7 @@ public function deleteRule($objectId, $requestOptions = array())
$response = $this->api->write(
'DELETE',
api_path('/1/indexes/%s/rules/%s', $this->indexName, $objectId),
- array(),
+ [],
$requestOptions,
$default
);
@@ -565,9 +565,9 @@ public function deleteRule($objectId, $requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function clearRules($requestOptions = array())
+ public function clearRules($requestOptions = [])
{
- $default = array();
+ $default = [];
if (is_bool($fwd = $this->config->getDefaultForwardToReplicas())) {
$default['forwardToReplicas'] = $fwd;
}
@@ -575,7 +575,7 @@ public function clearRules($requestOptions = array())
$response = $this->api->write(
'POST',
api_path('/1/indexes/%s/rules/clear', $this->indexName),
- array(),
+ [],
$requestOptions,
$default
);
@@ -583,12 +583,12 @@ public function clearRules($requestOptions = array())
return new IndexingResponse($response, $this);
}
- public function browseRules($requestOptions = array())
+ public function browseRules($requestOptions = [])
{
return new RuleIterator($this->indexName, $this->api, $requestOptions);
}
- public function getTask($taskId, $requestOptions = array())
+ public function getTask($taskId, $requestOptions = [])
{
if (!$taskId) {
throw new \InvalidArgumentException('taskID cannot be empty');
@@ -601,7 +601,7 @@ public function getTask($taskId, $requestOptions = array())
);
}
- public function waitTask($taskId, $requestOptions = array())
+ public function waitTask($taskId, $requestOptions = [])
{
$retry = 1;
$time = $this->config->getWaitTaskTimeBeforeRetry();
@@ -619,17 +619,17 @@ public function waitTask($taskId, $requestOptions = array())
} while (true);
}
- public function custom($method, $path, $requestOptions = array(), $hosts = null)
+ public function custom($method, $path, $requestOptions = [], $hosts = null)
{
return $this->api->send($method, $path, $requestOptions, $hosts);
}
- public function delete($requestOptions = array())
+ public function delete($requestOptions = [])
{
$response = $this->api->write(
'DELETE',
api_path('/1/indexes/%s', $this->indexName),
- array(),
+ [],
$requestOptions
);
@@ -643,7 +643,7 @@ public function delete($requestOptions = array())
*
* @return bool
*/
- public function exists($requestOptions = array())
+ public function exists($requestOptions = [])
{
try {
$this->getSettings($requestOptions);
@@ -680,7 +680,7 @@ public function exists($requestOptions = array())
*
* @throws ObjectNotFoundException
*/
- public function findObject($callback, $requestOptions = array())
+ public function findObject($callback, $requestOptions = [])
{
$query = '';
$paginate = true;
@@ -707,11 +707,11 @@ public function findObject($callback, $requestOptions = array())
$result = $this->search($query, $requestOptions);
foreach ($result['hits'] as $key => $hit) {
if ($callback($hit)) {
- return array(
+ return [
'object' => $hit,
'position' => $key,
'page' => $page,
- );
+ ];
}
}
@@ -743,30 +743,30 @@ public static function getObjectPosition($result, $objectID)
return -1;
}
- private function copyTo($tmpIndexName, $requestOptions = array())
+ private function copyTo($tmpIndexName, $requestOptions = [])
{
$apiResponse = $this->api->write(
'POST',
api_path('/1/indexes/%s/operation', $this->indexName),
- array(
+ [
'operation' => 'copy',
'destination' => $tmpIndexName,
- ),
+ ],
$requestOptions
);
return new IndexingResponse($apiResponse, $this);
}
- private function moveFrom($tmpIndexName, $requestOptions = array())
+ private function moveFrom($tmpIndexName, $requestOptions = [])
{
$apiResponse = $this->api->write(
'POST',
api_path('/1/indexes/%s/operation', $tmpIndexName),
- array(
+ [
'operation' => 'move',
'destination' => $this->indexName,
- ),
+ ],
$requestOptions
);
diff --git a/includes/libraries/algoliasearch-client-php/src/Support/Helpers.php b/includes/libraries/algoliasearch-client-php/src/Support/Helpers.php
index 39abc53a..971393a9 100644
--- a/includes/libraries/algoliasearch-client-php/src/Support/Helpers.php
+++ b/includes/libraries/algoliasearch-client-php/src/Support/Helpers.php
@@ -66,10 +66,10 @@ public static function buildQuery(array $args)
public static function buildBatch($items, $action)
{
return array_map(function ($item) use ($action) {
- return array(
+ return [
'action' => $action,
'body' => $item,
- );
+ ];
}, $items);
}
@@ -126,4 +126,19 @@ public static function mapObjectIDs($objectIDKey, $objects)
return $object;
}, $objects);
}
+
+ public static function serializeQueryParameters($parameters)
+ {
+ if (is_string($parameters)) {
+ return $parameters;
+ }
+
+ foreach ($parameters as $key => $value) {
+ if (is_array($value)) {
+ $parameters[$key] = json_encode($value, JSON_THROW_ON_ERROR);
+ }
+ }
+
+ return http_build_query($parameters);
+ }
}
diff --git a/includes/libraries/algoliasearch-client-php/src/Support/UserAgent.php b/includes/libraries/algoliasearch-client-php/src/Support/UserAgent.php
index 638e5a9f..6be12e5f 100644
--- a/includes/libraries/algoliasearch-client-php/src/Support/UserAgent.php
+++ b/includes/libraries/algoliasearch-client-php/src/Support/UserAgent.php
@@ -8,7 +8,7 @@ final class UserAgent
{
private static $value;
- private static $customSegments = array();
+ private static $customSegments = [];
public static function get()
{
@@ -27,7 +27,7 @@ public static function addCustomUserAgent($segment, $version)
private static function getComputedValue()
{
- $ua = array();
+ $ua = [];
$segments = array_merge(self::getDefaultSegments(), self::$customSegments);
foreach ($segments as $segment => $version) {
@@ -39,7 +39,7 @@ private static function getComputedValue()
private static function getDefaultSegments()
{
- $segments = array();
+ $segments = [];
$segments['Algolia for PHP'] = Algolia::VERSION;
$segments['PHP'] = rtrim(str_replace(PHP_EXTRA_VERSION, '', PHP_VERSION), '-');
diff --git a/includes/libraries/algoliasearch-client-php/src/functions.php b/includes/libraries/algoliasearch-client-php/src/functions.php
index 1190a7b8..c852c575 100644
--- a/includes/libraries/algoliasearch-client-php/src/functions.php
+++ b/includes/libraries/algoliasearch-client-php/src/functions.php
@@ -2,7 +2,9 @@
namespace Algolia\AlgoliaSearch;
+use Algolia\AlgoliaSearch\Support\Helpers;
+
function api_path($pathFormat, $args = null, $_ = null)
{
- return call_user_func_array(array('\Algolia\AlgoliaSearch\Support\Helpers', 'apiPath'), func_get_args());
+ return call_user_func_array([Helpers::class, 'apiPath'], func_get_args());
}
diff --git a/includes/watchers/class-algolia-user-changes-watcher.php b/includes/watchers/class-algolia-user-changes-watcher.php
index 79534618..be716d8f 100644
--- a/includes/watchers/class-algolia-user-changes-watcher.php
+++ b/includes/watchers/class-algolia-user-changes-watcher.php
@@ -153,7 +153,8 @@ public function on_delete_post( $post_id ) {
// Todo: this is not optimal given it would be triggered for every future triggered hook.
// Todo: needs to be changed.
add_action(
- 'after_delete_post', function() use ( $watcher, $author_id ) {
+ 'after_delete_post',
+ function() use ( $watcher, $author_id ) {
$watcher->sync_item( $author_id );
}
);
diff --git a/js/algoliasearch/CHANGELOG.md b/js/algoliasearch/CHANGELOG.md
deleted file mode 100644
index 346a0dfa..00000000
--- a/js/algoliasearch/CHANGELOG.md
+++ /dev/null
@@ -1,1228 +0,0 @@
-# CHANGELOG
-
-## 3.35.1
->2019-10-08
-
-* FIX: extra comma on node v8 engine (#790)
-
-## 3.35.0
->2019-09-26
-
-* FEAT(remaining-validity): adds remaining valitity method (#778)
- * `client.getSecuredApiKeyRemainingValidity('securedAPIKey')`: Gets remaining validity seconds of an secured API Key
-* FEAT(unit-testing-relevance): adds unit testing relevance methods (#777)
- * `index.findObject(hit => hit.firstname == 'Jimmie')`: Find an object by the given condition
- * `index.getObjectPosition(results, 'a-unique-identifier')`: Retrieve the given object position in the given results set
-* FEAT(adds-assign-user-ids): adds assignUserIDs method and tests (#783)
- * `client.assignUserIDs({ cluster: 'c1-test', userIDs: ['some-user-1', 'some-user-2'] })`: Assign a array of userIDs to a cluster
-
-## 3.34.0
->2019-08-29
-
-* FEAT(index-exists): adds exists method into index (#773)
- * `index.exist()`: returns whether an index exists or not
-
-## 3.33.0
->2019-05-09
-
-* FEAT(api-keys): add restore api key method (#754)
- * `client.restoreApiKey('APIKEY')`: restore a deleted API key
- * see also https://www.algolia.com/doc/api-reference/api-methods/restore-api-key
-* FIX(ua): change the User-Agent to use the new specs lib (version) (#747)
-
-## 3.32.1
->2019-03-14
-
-* FIX(errors): grammar change in error message (#737)
-* FIX(dependencies): bump debug requirement (#746)
-
-## 3.32.0
->2018-12-17
-
-* FEAT(personalization): add new methods for the strategy
- * `getPersonalizationStrategy(cb)`: retrieve the currently set strategy
- * `setPersonalizationStrategy(strategy, cb)`: set the personalization strategy
- * a `strategy` is an object containing `eventsScoring` and `facetsScoring`
- * see also https://www.algolia.com/doc/rest-api/personalization
-
-## 3.31.0
->2018-12-04
-
-* FEAT(places): add `.reverse({ aroundLatLng: '' })` to reverse geo-code
-* CHORE: deprecated `similarSearch()`, instead use `.search({ similarQuery: '' })`
-
-## 3.30.0
->2018-08-01
-
-* FIX(multi-query): property pass the `strategy` argument
- * as in [docs](https://www.algolia.com/doc/rest-api/search#method-param-strategy)
- * was originally put into url parameters instead of request body
-
-## 3.29.0
->2018-06-20
-
-* FEAT(analytics): add API methods for AB testing
- * find more info about the new feature here: https://blog.algolia.com/ab-testing-search/
- * adds a new method on client:
- import algoliasearch from 'algoliasearch';
- const client = algoliasearch('appid', 'apikey');
- const analytics = client.initAnalytics();
- analytics.getABTests().then(console.log)
- * see documentation here: https://www.algolia.com/doc/api-client/ab-test/
-* CHORE(parse): remove parse build, not needed.
- * You can just install and `require('algoliasearch');`
-
-## 3.28.0
->2018-06-13
-
-* FEAT(cache): cache the requests instead of responses (#694)
-
- If you pass `_useRequestCache: true` as an option to the client then the cache behaviour will change. If you launch two requests at the same time then only one request will be done while the two callbacks/promises will still be called/resolved.
-
- Previously, the client would have made two requests instead of one.
-
- This is implemented by filling the cache as soon as the request launches instead of waiting for the response to fill it.
-* FIX(parse): correct path to debug module (#702)
-
- fixes parse build, weirdly webpack is not throwing when importing an
- unknown module using target node
-* TESTS: Make this CI green, fix unit and integration tests on every platform
-
-## 3.27.1
->2018-05-03
-
-* FIX: `client.searchForFacetValues` in older browsers
- * we use the polyfill implementation of Promise.all now instead of the native in 3.27.0
-* FIX: `index.saveRule` throw when no objectID is given
-* FEAT: deprecate index API key methods in favor of client ones
- * these methods will be removed, since you can add index restrictions to client API keys
-
-## 3.27.0
->2018-04-16
-
-* FEAT: add client.searchForFacetValues
- * this allows to request multiple search for facet values in a single call
- * note that this will do multiple requests (one per query)
-
-## 3.26.0
->2018-03-21
-
-* FEAT: allow disabling of dsn
- * in some cases (backend search while you do have global DSN), you want to disable DSN to avoid a round-robin around the whole world if DNS can't be resolved as expected, for example on GCP. (#675)
-
-## 3.25.1
->2018-03-08
-
-* FIX: fix protocol detection introduced in 3.25.0
-
-## 3.25.0
->2018-03-07
-
-* FEAT: use https by default (#670)
- * for very old devices https can be slow
- * we defaulted to sending API requests over http on http sites
- * this is now not really a performance bottleneck anymore
- * https is now default, unless specified differently when initializing
-
-## 3.24.12
->2018-02-28
-
-* FIX: Handle Node.js network errors more precisely (#669)
-
-## 3.24.11
->2017-02-08
-
-* FIX: allow `index.getSettings` without any arguments
- * this was a regression in 3.24.10
- * added tests
-
-## 3.24.10
->2017-02-07
-
-* FIX: correct `index.exportSynonyms` and `index.exportRules`
- * they had the wrong implementation until now
- * add some tests to prevent regression
-
-## 3.24.9
->2017-12-29
-
-* FIX: make sure long API keys are sent via the POST body
- * this wasn't the case in 3.24.8 because of a typo
-
-## 3.24.8
->2017-12-13
-
-* add multi cluster management methods
- * [ Assign or Move a userID to a cluster](https://algolia.com/doc/api-reference/api-methods/assign-user-id/): `assignUserID`
- * [Get userID with highest number of records per cluster](https://algolia.com/doc/api-reference/api-methods/get-top-user-id/): `getTopUserID`
- * [Returns the userID data stored in the mapping](https://algolia.com/doc/api-reference/api-methods/get-user-id/): `getUserID`
- * [List the clusters available in a multi-clusters setup for a single appID](https://algolia.com/doc/api-reference/api-methods/list-clusters/): `listClusters`
- * [List the userIDs assigned to a multi-clusters appID](https://algolia.com/doc/api-reference/api-methods/list-user-id/): `listUserIDs`
- * [Remove a userID and associated data from the multi-clusters](https://algolia.com/doc/api-reference/api-methods/remove-user-id/): `removeUserID`
- * [Search for userIDs](https://algolia.com/doc/api-reference/api-methods/search-user-id/): `searchUserIDs`
-
-## 3.24.7
->2017-11-29
-
-* don't throw an error when `copyIndex` without scope is used
- * if no scope is given, `settings`, as the default will be chosen
-
-## 3.24.6
->2017-11-16
-
-* add `index.exportSynonyms` and `index.exportRules`
- * they will get all of the synonyms or query rules on an index
-* add a new `scope` argument to `copyIndex`
- * this is the third argument (from, to, scope)
- * it's an array with settings, synonyms or rules
- * if specified, that data will also be copied if you copy the index
-
-## 3.24.5
->2017-10-02
-
-* feat(deleteBy): add deleteBy
- * deleteByQuery is deprecated now
- * the same, but now it happens at the indexing side
- * no major changes should be seen, please report if any
- * https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated#indexdeletebyquery
-
-## 3.24.4
->2017-09-22
-
-* chore(build): provide jsDelivr the right file (#599)
-
-## 3.24.3
->2017-07-24
-
-* chore(deprecation): remove deprecation from singular/plural methods; all these methods will stay existing
- * index.addObject(obj) or index.addObjects([obj])
- * index.partialUpdateObject(obj) or partialUpdateObjects([obj])
- * index.saveObject(obj) or index.saveObjects([obj])
- * index.deleteObject(objectID) or index.deleteObjects([objectID])
- * index.getObject(objectID) or index.getObjects([objectID])
-
-## 3.24.2
->2017-07-24
-
-* chore(deprecation): add deprecation message to all methods that will be removed in v4 (#573)
- * index.addObject(obj) --> index.addObjects([obj])
- * index.ttAdapter --> autocomplete.js
- * index.partialUpdateObject(obj) --> partialUpdateObjects([obj])
- * index.saveObject(obj) --> index.saveObjects([obj])
- * index.deleteObject(objectID) --> index.deleteObjects([objectID])
- * index.getObject(objectID) --> index.getObjects([objectID])
- * see https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated for more information
-
-## 3.24.1
->2017-07-20
-
-* feat(headers): add functions to remove and get extra headers (#572)
- * client.setExtraHeader('X-cool-header','hello there');
- * client.getExtraHeader('X-cool-header'); //hello there
- * client.unsetExtraHeader('X-cool-header');
- * client.getExtraHeader('X-cool-header'); //undefined
-* feat(deprecation): use console.warn to be more visible
-* refact(rules): Adapt to latest JSON schema for Query Rules
-
-## 3.24.0
->2017-06-21
-
-* feat(rules): Add query rules beta version, you cannot use this for now
-
-## 3.23.0
->2017-06-08
-
-* feat(places): Add places.getObject(); fixes algolia/places#381
-
-## 3.22.3
->2017-05-29
-
-* fix(dependency): Do not pin debug dependency anymore
-fixes #556
-
-## 3.22.2
->2017-05-18
-
-* fix(partialUpdateObjects): allow createIfNotExists (#552)
- Much like partialUpdateObject, allow createIfNotExists
- fixes #551
-
-## 3.22.1
->2017-03-13
-
-* fix(packaging): put back envify in deps
- * browserify transforms are applied for node_modules/pkg
-
-## 3.22.0
->2017-03-13
-
-
-* feat(API): rename all *userKey[s] methods to *apiKey[s]
- * client/index.listUserKeys() => client/index.listApiKeys()
- * client/index.getUserKeyACL() => client/index.getApiKey()
- * client/index.deleteUserKey() => client/index.deleteApiKey()
- * client/index.addUserKey() => client/index.addApiKey()
- * client/index.udpateUserKey() => client/index.updateApiKey()
-* fix(packaging): remove useless files for packaging (reduce package file size)
-
-## 3.21.1
->2017-02-08
-
-
-* fix(browse*): use POST instead of GET to avoid limits (#503)
-
-## 3.21.0
->2017-02-06
-
-
-* feat(x-algolia-agent): specify x-algolia-agent at search time
-* fix(parse): check for `global` existence before erasing
-
-## 3.20.4
->2017-01-16
-
-
-* fix(retry strategy): handle cases were localStorage fails after success (#474)
-
- Before this commit we only checked for localStorage failures at:
- - page load
- - localStorage.setItem
-
- While in some situations websites could erase localStorage for the
- whole page at any moment (between requests) and we were not resilient to that.
-
-* chore(forwardToSlave): deprecate forwardToSlaves in favour or forwardToReplicas
-
-## 3.20.3
->2017-01-04
-
-
-* fix(agent): ensure algolia agent is not duplicated by successive calls
-
-## 3.20.2
->2016-12-19
-
-
-* fix(nodejs): do not use let, 0.12 does not support it
-
-## 3.20.1
->2016-12-17
-
-
-* fix(nodejs): on timeout, destroy the right response
-
-## 3.20.0
->2016-12-14
-
-
-* feat(retry strategy): adjust retry strategy for all implementations
- - Retry strategy now shares the last known host for a specific appId across the current domain (browsers)
- or the current process (browsers without localStorage, Node.js). After 2 minutes we try to target back
- the first host (Usually DSN)
- - Retry strategy now shares the last known timeout multiplier that worked and set it back to default
- after 2 minutes
- - Retry strategy on Node.js now has a connect timeout of 2s
- - Retry strategy on browsers (JavaScript, not jQuery, not Angular.js, not React Native for now) now
- has a connect timeout of 1s
- - You can now get and set timeouts per client with .setTimeouts({connect, read, write}), .getTimeouts().
- Values are in ms.
-
-## 3.19.2
->2016-11-28
-
-
-* fix(facet search): rename index.searchFacet to index.searchForFacetValues
-
-## 3.19.1
->2016-11-11
-
-
-* fix(build): use regular debug module, issue with yui compressor was fixed here:
-https://github.com/visionmedia/debug/pull/315
-
-## 3.19.0
->2016-10-26
-
-
-* feat(index.searchFacet): add method #345
-
-## 3.18.1
->2016-08-31
-
-
-* fix(client.search): accept very long API keys
- fixes #319
-
- also fix uglify-js version because it's buggy in IE8:
- https://github.com/mishoo/UglifyJS2/issues/1039
-
-## 3.18.0
->2016-07-22
-
-
-* fix(debug): only activate debug messages on NODE_ENV==='debug'
-* feat(lite): add getObjects
-
-## 3.17.0
->2016-07-06
-
-
-* feat(errors): add statusCode to errors
-* chore(shrinkwrap): completely remove shrinkwrap
-
-## 3.16.0
->2016-06-22
-
-
-* feat(index.setSettings): add forwardToSlaves option
-index.setSettings({settings}, {forwardToSlaves}, cb);
-see https://www.algolia.com/doc/rest#change-index-settings
-
-## 3.15.1
->2016-06-16
-
-
-* fix(getLogs): allow using the type parameter
- The syntax is now getLogs(params[, cb])
- fixes #232
-* fix(json): avoid throwing when late JSON response
- fixes #284
-* fix(nodejs): allow universal lite applications
- require('algoliasearch/lite') should work to
- facilitate universal applications builds using
- the lite build on frontend
-
-fixes #283
-
-## 3.15.0
->2016-06-07
-
-
-* feat(synonyms): add new synonyms API
-
-## 3.14.6
->2016-05-30
-
-
-* fix(places): allow empty credentials
-
-## 3.14.5
->2016-05-26
-
-
-* fix(window): don't assume window is here
-
-When required in a node context, we may load the browser build without
-using it. Just for testing other parts of it.
-
-## 3.14.4
->2016-05-25
-
-
-* fix(lite): lite package should have browse and browseFrom
-
-## 3.14.3
->2016-05-25
-
-
-* fix(retry): also retry on non search methods when DNS failure
-
- Before this commit, methods with no fallback support (basically every
- method) would fail at retry if the DNS error occurred before the API
- client timeout.
-
- The behavior is now:
- - when a method with a fallback errors because of DNS failure we will
- switch to JSONP right away
- - when a method with no fallback errors because of DNS failure we will
- still retry
-
- We could use the same mechanism for both (= always try all hosts
- before JSONP) but I am not confident doing this change within a patch
- or minor version. We have too litle data on how blocked XHRS are
- triggered (async, sync?).
-
- fixes #250
-
- * fix(request strategy): comply with retry spec, no early JSONP switch
-
- This commit brings more conformance with request strategy
- specification by only raising timeout when there's a timeout.
-
- It also stop trying to switch to JSONP asap and always try all hosts
- using XHRS before.
-
-## 3.14.2
->2016-05-24
-
-
-* fix(request strategy): increments hostIndex (host address) on fallback
-
- When we are switching to fallback, increment host index so that JSONP
- will use another host.
-
- This issue was caused because we cannot distinguish CORS errors from DNS
- resolution errors in the browser.
-
- And the code for incrementing the host index was moved into the part
- that switches to the fallback in
- 4ec5e6a1f8cd92924ce025d60646b3a47b7d8dca.
-
- Truth is that the current solution is not optimal as, in the browser,
- we are switching to JSONP when we can't resolve the server name.
-
- This is only done because we are not sure how CORS request can be
- blocked (synchronously, asynchronously).
-
- In a next version we would drop it and wait for real issues to show up.
-
-## 3.14.1
->2016-05-12
-
-
-* fix(retry strategy): retry on timeout was only using two hosts
-* fix(errors): provide err.debugData with necessary debugging information
-* fix(errors): force AlgoliaSearchError as default name
-fixes #241
-
-## 3.14.0
->2016-05-04
-
-
-* feat(client.search): add strategy, fixes #208
-* fix(shuffle): shuffle host array like we did
-* feat(filesize): reduce filesize by removing lodash
- All build size down 26% (20kb => 14kb)
- New search-only build "algoliasearchLite[.min].js",
- weights 9.5Kb (down 50% from normal build)
- Also available as require('algoliasearch/lite');
-* fix(parse): handle parse cloud env having process.env defined
-
-## 3.13.1
->2016-03-24
-
-
-* chore(dev): use phantomjs-prebuilt instead of phantomjs
-fixes #209
-
-## 3.13.0
->2016-02-23
-
-
-* feat(initPlaces): add a static algoliasearch.initPlaces method
-
-## 3.12.0
->2016-02-05
-
-
-* fix(apiKey): put the apiKey in the POST body when feasible and key > 500 chars
-* feat(falback): provide opts.useFallback to avoid using JSONP fallback
-
-## 3.11.0
->2016-01-28
-
-
-* feat(partialUpdateObject): add createIfNotExists option: partialUpdateObject(object, createIfNotExists) https://www.algolia.com/doc/rest#partially-update-an-object
-* chore(dev): various fixes to the dev env
-
-## 3.10.2
->2015-12-14
-
-
-* fix(request strategy): always use XHR first then switch to fallback
-
- + add fallback for client.search
-
- Context: before this commit, when a user lost connectivity (or XHR was
- blocked, we cannot distinguish those events in browsers) then we
- forced using JSONP for the whole session.
-
- This led to a bug where you were stuck in a loop of non-available
- fallback even if connectivity was restored.
-
- This commit fixes this bug by always trying XHRS and fallbacking to
- JSONP on a per request basis.
-* refactor(map): use lodash map instead of custom fn
-
-## 3.10.1
->2015-12-11
-
-* fix(nodejs): consistent timeouts between nodejs versions
- We now use basic setTimeout functionnality instead of
- req.setTimeout in nodejs to avoid inconsistencies between nodejs engines.
- In node 0.10, req.setTimeout was a socket inactivity timeout
- In node > 0.10? req.setTimeout is now a global timeout
- + Node.js timeout is now 30s global per request (then incremental)
- + Fixed an edge case where we had an uncaught exception in nodejs
- + We only support 0.10+ now, node 0.8 never worked
-
-## 3.10.0
->2015-12-08
-
-* feat(gzip): ask the API for gzipped answers (nodejs)
-
-## 3.9.4
->2015-12-04
-
-* fix(process.env): set process back to normal in node v4
-
-## 3.9.3
->2015-12-01
-
-* fix(parse): set default timeout to 7.5s (indexing purposes)
-
-## 3.9.2
->2015-11-02
-
-* feat: react native build beta
-
-## 3.9.1
->2015-11-02
-
-* fix: throw on really bad usage instead of silently failing
-* fix: make angular build cache work
-
-## 3.9.0
->2015-10-23
-
-* feat: add similarSearch beta method
-* feat: add new way to generate secured api key using query parameters
-
-## 3.8.1
->2015-09-21
-
-
-* fix: disable chunked encoding on empty body DELETE requests in Node.js
-
-## 3.8.0
->2015-09-01
-
-
-* test: node v4 is now the default testing env
-* fix: always send a unique response to the user
-* fix: use `lodash` by default, only use `lodash-compat` when building for the browser
-* feat: add client.addAlgoliaAgent() to augment the sent x-algolia-agent
-* chore: move all deps to ^version and add a shrinkwrap to allow reproducible builds
-
-## 3.7.8
->2015-09-01
-
-
-* fix: ignore $http.defaults.headers.common in angular build
-* fix: force distinct false in deleteByQuery search
-* docs: precise initialization option values
-
-## 3.7.7
->2015-08-27
-
-* fix: listen to socket errors in nodejs keepalive strategy
-
-## 3.7.6
->2015-08-24
-
-* fix: encodeURIComponent(cursor) in browseFrom()
-
-## 3.7.5
->2015-07-23
-
-* fix: withCredentials forced to false in Angular
-
-## 3.7.4
->2015-07-20
-
-* fix: JSON.stringify fix when Array.prototype.toJSON is defined (prototype.js < 1.7 bug)
-
-## 3.7.3
->2015-07-09
-
-* fix: make https over http proxy work
-
-## 3.7.2
->2015-07-08
-
-* fix: remove a git clone dependency on install (debug/ms/yui compressor issue)
-
-## 3.7.1
->2015-07-08
-
-* fix: do not call agent.destroy when there's no such method
-* fix: do not rely on any "smart" port computing
-
-## 3.7.0
->2015-06-18
-
-* feat: allow passing `httpAgent` option to the nodejs client
-allow more flexible proxy/keepAlive agents in some more complex environments
-
-## 3.6.3
->2015-06-18
-
-* fix: allow getting the debug log from the outside
- will be used by diag tool and possibly anyone aware of https://github.com/visionmedia/debug
-
-## 3.6.2
->2015-06-17
-
-* chore: add window.__algolia for easy debugging anywhere
-
-## 3.6.1
->2015-06-16
-
-* fix: parse cloud build fix
-* fix: YUI compressor fix
- fixes #113
-* test: automatic parse cloud build testing
-* fix: add application id to final error message ("Cannot connect to..")
-
-## 3.6.0
->2015-06-05
-
-* feat: easy commonJS require of plugins
- fixes #109
-* test: add dependency-check step in tests
-* refactor: use lodash-compat instead of less known/used/shared modules
-* chore: use uglifyjs instead of closure compiler
-* feat: allow passing hosts as hosts.read, hosts.write
-* feat: allow passing Algolia Agent as an option
-* fix: CORS simple request for all browser builds
- fixes #111
-
-## 3.5.0
->2015-06-03
-
-* fix: send a descriptive timeout error when it occurs
-* chore: add headers debugging
-* fix: incremental wait waitTask
- will now wait 100ms * loopTickNumber * loopTickNumber
- fixes #102
-* fix: do not use global when we know we will be in a browser
- browserify `global` is not always `window` can be
- fixes #99
-* feat: new browse()/browseFrom()/browseAll()
- - `browse(query, queryParameters)` now has the same signature than
- search(). You can use any `query` and `queryParameters`.
- - `browseFrom(cursor)` can be used as an efficient way to
- continue (next page) a previous `browse()` call. All browse responses now have a `cursor` property.
- - `browseAll(query, queryParameters)` can be used to get all
- the content of your index
- It returns an [EventEmitter](https://nodejs.org/api/events.html).
-
- Available events:
- - `result`
- - `end`
- - `error` (you should listen to it or it will throw)
-
- There's also `stop()` method on the event emitter so that you can
- stop browsing at any point.
-
- fixes #101
-* fix: support typeahead 0.11
- fixes #105
-
-## 3.4.0
->2015-05-23
-
-* FIX: Remove debugging messages from builds
- fixes #91
- fixes #86
-* FIX: Handle badly formatted JSON
- fixes #89
- fixes #90
-* FIX: Stop bytes sent/received debug on node 0.12 when socket closes
-* test: Test on only 3 browsers in travis
- fixes #61
-* test: split desktop/mobile into a travis matrix, reduces travis timeouts
-* feat: add client.batch()
-* feature: getObjects now accepts attributesToRetrieve:
- signature: getObjects(objectIDs, attributesToRetrieve, callback)
-* fix: send `x-algolia-agent` instead of `x-user-agent`
-* fix: clone cached results hits sent
- fixes #79
-* feat: New parameters for API keys
- Added description, referers, queryParameters
- ref: https://www.algolia.com/changes#released-##
- >2015-05-08
-
-* fix: IE11 xhr cache was fixed by adding cache-control: no-cache in API headers
-* test: add integration testing and rework the travis tasks
-
-## 3.3.2
->2015-05-14
-
-* FIX: more fixes to the use of $q() in the angular build, now compatible with 1.2.xx and tested
-
-## 3.3.1
->2015-05-12
-
-* FIX: Compatibility with AngularJS old promise implementation
- We now use $q.defer() instead of $q()
-
-## 3.3.0
->2015-05-12
-
-* FEATURE: expose window.algoliasearch = algoliasearch in jquery/angular plugins. So that
-you can use the original algoliasearch() implem in plugins. Otherwise you would have to load both
-
-## 3.2.4
->2015-05-11
-
-* FIX: 15s inactivity timeout for nodejs implementation, should help high latency/low connection users
-* CHORE: test on iojs2
-* CHORE: debugging messages now more focused and less verbose
-* PERF: use JSON.stringify only once per request
-
-## 3.2.3
->2015-05-09
-
-* FIX: Parse build requires a charset on requests
-
-## 3.2.2
->2015-05-06
-
-* FIX : missing require (crypto) for node.js client (#84)
-
-## 3.2.1
->2015-04-29
-
-* add dist/ to npmjs repository, so cdnjs autoupdate works
-
-## 3.2.0
->2015-04-24
-
-* FEATURE: Parse build now uses V3 implementation
-* FEATURE: Parse build now returns parse promises. https://parse.com/docs/js_guide#promises
-* FEATURE: Automatically handle HTTP_PROXY HTTPS_PROXY environment variables
-in Node.js client
-
-## 3.1.0
->2015-04-14
-
-* CHANGE: Node.js will now use http headers instead of inlining them into the api call as browsers are doing
-* CHANGE: Ensure all headers (http, querystrings) are lowercased. Both are supported by our API, reduces FUD
-* FEATURE: add index.getObjects()
-* FEATURE: add index.deleteObjects()
-* FIX: waitTask failure case when using promises, was not going through
-* FEATURE: add index.deleteByQuery()
-* FEATURE (Node.js): add client.enableRateLimitForward()
-* FEATURE (Node.js): add client.disableRateLimitForward()
-* FEATURE (Node.js): add client.useSecuredAPIKey()
-* FEATURE (Node.js): add client.disableSecuredAPIKey()
-* BREAKING CHANGE (Node.js): client.setTimeout renamed to client.setRequestTimeout
-* TEST: add test around setRequestTimeout
-* FEATURE (Node.js): add client.generateSecuredApiKey()
-* FEATURE:
- - all clients are now exposing algoliasearch.ua
- - all requests are now sending x-user-agent containing for example 'Algoliasearch for vanilla JavaScript 3.0.7'
-* FEATURE: add client.search()
- Search against multiple indices, equivalent of, multipleQueries, or
- startQueriesBatch+addQueryInBatch+sendQueriesBatch
-* BREAKING CHANGE (Node.js): removed client.multipleQueries(), use client.search(queries)
-* DEPRECIATION (browser): client.startQueriesBatch/addQueryInBatch/sendQueriesBatch
- Use client.search(queries)
-* FEATURE: new HA implementation
- We now use two different DNS to perform all requests
- Removed the tld option as it's no more needed nor compatible with having a new HA implementation with different tlds (.com/.net)
-* DEPRECIATION: client.addUserKeyWithValidity(), index.addUserKeyWithValidity()
- You can now use client.addUserKey(acls, params, cb), index.addUserKey(acls, params, cb)
-* FEATURE: client|index.updateUserKey(key, acls, params, callback)
- Update a user key, provide acls and optional params
-* BREAKING CHANGE (Node.js):
- As we now have addUserKey and updateUserKey, we removed:
- - client|index.addUserKeyWithValidityAndIndexes
- - client|index.updateUserKeyWithValidity
- - client|index.updateUserKeyWithValidityAndIndexes
- You can use client|index.addUserKey or client|index.updateUserKey to do
- deal with all you keys needs
-
-## 3.0.7
->2015-04-10
-
-* MIGRATION: throw on V2 .search() usage:
- - .search(query, cb, params)
- - .search(cb, params)
-* FEATURE: add client.destroy() in Node.js implementation
- will destroy all keepalived connections and let the process exits if needed
-
-## 3.0.6
->2015-04-03
-
-* FIX: Webpack compatibility by removing packageify
- webpack does not interprets for now node_modules/* browserify transforms
-* MISC: add release script
-
-## 3.0.5
->2015-04-02
-
-* FIX: lower the build size by requiring the good version/browser.js in browser
- builds. Previously we got the full `package.json` inlined
-
-## 3.0.4
->2015-04-02
-
-* FIX: Defaults to http when the protocol of the page is not http or
- https
-* FIX: XDomainRequests no more aborted in IE9 #76
-
-## 3.0.3
->2015-03-28
-
-
-* FIX: Handle module loaders + cdn.jsdelivr.net/algoliasearch/latest usage
- When in this situation, the module loader would prevent the code
- detecting and loading the V2 to execute.
- Now fixed by prepending the migration-layer to the browserify bundle.
- It also removes the migration-layer code from the package managers (npm, bower) builds,
- where it makes no sense to have it
-* FIX: load V2 using a DOMElement when V3 is loaded ASYNCHRONOUSLY with /latest/
- * tested on all majors browsers:
- Chrome stable
- Firefox stable
- IE 8, 9, 10, 11
- * tested on corresponding customer websites
-* FIX: better warning messages when using `latest` or trying to use V3 as V2
-
-## 3.0.2
->2015-03-26
-
-
-* temp /latest/ fix for some clients loading /latest/ in async mode
-
-## 3.0.1
->2015-03-26
-
-
-* fix npm usage, was missing a dependency
-
-## 3.0.0
->2015-03-25
-
-
-* V2 users, see the migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x
-* BREAKING CHANGES:
- * `new AlgoliaSearch()` => `algoliasearch()` #40
- - The only exported global property is now `algoliasearch`
- - `opts`:
- - `dsnHost` removed, use `hosts:[dsnHost, other hosts]`
- - `dsn` removed, use `hosts:[non-dsn-host, non-dsn-host]`
- - `requestTimeoutInMs` renamed to `timeout`
- - `method` renamed to `protocol`. Protocol should be specified as `http:` or `https:`
- - `hosts` behavior changed, when using custom hosts:
- - no shuffling
- - no dsn host is prepended to the list
- - removed `AlgoliaExplainResults`, no obvious use ATM
- - calling algoliasearch() without an applicationID or apiKey will throw
- - Helper: `new AlgoliaSearchHelper()` => `algoliasearch.helper()`, same function signature
- * no more window.ALGOLIA_VERSION
- - you can find the version in algoliasearch.version
- * all api methods now use the (err, content) convention #43
- It means that instead of doing:
- ```js
- index.search(function found(success, content) {
- if (!success) {
- console.log('Error was:', content);
- return;
- }
-
- console.log('OK!', content);
- });
- ```
- You must do:
- ```js
- index.search(function found(err, content) {
- if (err) {
- console.log('Error was:', err);
- return;
- }
-
- console.log('OK!', content);
- });
- ```
- This is in par with most asynchronous APIS accepted/de vfacto conventions.
- It helps being compatible with control flow libraries like `async` and
- helps reduce WTF moments of Node.JS developers used to cb(err, content)
- * client.getLogs(cb[, offset, length]) is now .getLogs([offset, length, cb])
- * client.listIndexes(cb[, page]) => .listIndexes([page, cb])
- * client|index.addUserKeyWithValidity(acls, validity, maxQueriesPerIPPerHour, maxHitsPerQuery, cb) => client|index.addUserKeyWithValidity(acls, params, cb) where params = {validity:, maxQueriesPerIPPerHour:, maxHitsPerQuery:}
- * client.sendQueriesBatch(cb, delay) => client.sendQueriesBatch(cb)
- * index.addObject(content[, callback, objectID]) => index.addObject(content[, objectID, callback])
- * index.getObject(objectID[, callback, attributes]) => index.getObject(objectID[, attrs, callback])
- * index.search(query, callback[, params, delay]) => index.search(query[, params callback]) or index.search(params[, cb]) with params = {query: 'some thing'}
- We removed the delay option which should really be implemented by the module consumer. It's really a throttle/debounce of the search functions
- * index.browse(page, cb[, hitsPerPage]) => index.browse(page[, hitsPerPage, cb])
- * no more opts.jsonp in algoliasearch()
- Previously used as a way to force/disable jsonp. The request strategy is now more robust and does not
- requires jsonp: param
- * JSON2.js is no more included in the main build.
- If you need to support IE7 <= or IE8 quirks, add this:
- ```html
-
- ```
- * removed AlgoliaSearchHelper
- Please see https://github.com/algolia/algoliasearch-helper-js if you need the helper
- * NEW FEATURES:
- * UMD compatibility #41
- - algoliasearch can now be used with any module loader
- - build is now done with browserify
- - no more grunt
- * All calls are now returning promises #45
- If there's a callback given to an API call, you won't get a promise.
- Here are the different promises implementations we use:
- - Native promises by default (https://github.com/jakearchibald/es6-promise/)
- - AngularJS promises for AngularJS plugin
- - jQuery promises for jQuery plugin
-* FIXES:
- * do not retry when server sends 4xx or 1xx
- * distinguish jQuery/AngularJS request timeouts from errors and thus retry when timeout
- * JSONP fallback when jQuery/AngularJS request error
-* MISC:
- * Externalize plugins and request implementations
- * some linting fixes
- * test suite, including request strategy test suite
- * IE10 should now behave as a CORS supported XMLHttpRequest browser, as it is
- * running tests on many browsers, using saucelabs
- * removed vendor/
- - vendor/json2.js
- - vendor/jquery.typeahead.js now on cdnjs (examples)
-
-## 2.9.2
->2015-02-03
-
-* Fixed calls to `.search(function() {})`, `.search(null, function() {})`, `.search(undefined, function() {})
-* Fixed shared cache amongst instances
-
-## 2.9.1
->2015-02-03
-
-* Fixed listIndexes pagination, not working if page=0
-
-## 2.9.0
->2015-01-13
-
-* Angular.js & jQuery compatibility (returning promises)
-* Helper: ability to exclude facets
-
-## 2.8.6
->2015-01-13
-
-* Search helper: ability to set default facet filters
-
-## 2.8.5
->2015-01-07
-
-* Avoid CORS preflight request
-
-## 2.8.4
->2014-12-31
-
-* Fixed a bug in JSONP fallback on multi-queries and getObject when a secured API Key was used (X-Algolia-TagFilters parameter was not set, resulting in a 403 permission denied error)
-
-## 2.8.3
->2014-12-30
-
-* Helper optimization: number of nested queries is now driven by the number of refined disjunctive facets only
-
-## 2.8.2
->2014-12-23
-
-* Increase the request timeout after each retry
-
-## 2.8.1
->2014-12-09
-
-* Enabled DSN by default (is working even if only one datacenter is selected)
-
-## 2.8.0
->2014-11-28
-
-* Move to algolia.net by default
-
-## 2.7.5
->2014-11-25
-
-* Expose one option to select the TTL (prepare migration to .net, allow to gain some milliseconds compared to .io)
-
-## 2.7.4
->2014-11-12
-
-* Expose more options (jsonp & requestTimeoutInMs)
-* Change the way the JSONP fallback works
-
-## 2.7.3
->2014-10-29
-
-* Reintroduced Algolia Custom Headers (X-Algolia-*) on queries. It was removed to try to remove the CORS OPTIONS query but this has no impact because this is a POST action.
-
-## 2.7.2
->2014-10-27
-
-* Fixed browse method (author @muertet)
-
-## 2.7.{0,1}
->2014-10-15
-
-* Refactor the AlgoliaSearch constructor to allows optional/named arguments
-
-## 2.6.6
->2014-10-07
-
-* Fixed bower integration
-
-## 2.6.5
->2014-09-26
-
-* Optimize disjunctive queries that were retrieving useless attributes
-
-## 2.6.4
->2014-09-23
-
- * Fixed CORS handling issue on IE8/IE9
-
-## 2.6.3
->2014-09-23
-
- * Fixed IE11-based AJAX calls
-
-## 2.6.2
->2014-09-20
-
- * Updated package manager description files: npm and jsdelivr
-
-## 2.6.1
->2014-09-20
-
- * Fixed JSONP call: 'X-Algolia-TagFilters' and 'X-Algolia-UserToken' were not included in the URL.
-
-## 2.6.0
->2014-09-06
-
- * Improved retry strategy with implementation of a timeout on network call.
- Upgrade to this version is highly recommended
-
-## 2.5.4
->2014-09-04
-
-* Removed the OPTIONS request for the first isalive query of for all search queries
-
-## 2.5.3
->2014-07-23
-
-* AlgoliaSearchHelper: add missing getIndex/setIndex
-* listIndexes is now paginable
-
-## 2.5.2
->2014-06-05
-
-* AlgoliaSearchHelper: add getter/setter methods
-
-## 2.5.1
->2014-05-14
-
-* Fixed listIndexes call (trailing slash not compatible with our API anymore)
-
-## 2.5.0
->2014-05-09
-
-* If CORS is not available, use JSONP
-
-## 2.4.7
->2014-04-23
-
-* Ability to instantiate multiple AlgoliaSearchHelper
-
-## 2.4.6
->2014-04-05
-
-* Fixed IE 8/9 support of secured API keys
-
-## 2.4.5
->2014-03-30
-
-* Improved AlgoliaExplainResults helper handling array-based attributes as well.
-
-## 2.4.4
->2014-03-19
-
-* Improved the `waitTask` method, ensuring it sleeps 100ms before recalling the API.
-
-## 2.4.3
->2014-03-12
-
-* Removed invalid character from source code (could cause a parse error in IE8/9)
-
-## 2.4.2
->2014-02-24
-
-* Added support of secured API Key (SecurityTags & UserToken headers)
-
-## 2.4.1
->2014-02-18
-
-* Removed dependency on jquery
-
-## 2.4.0
->2014-02-10
-
-
-* Move to official Typeahead.js release (0.10.1)
-* Remove getTypeAheadTransport* functions
-
-## 2.3.8
->2014-01-16
-
-
-* Ability to customize getTypeAheadTransport parameters once instantiated
-
-## 2.3.7
->2014-01-08
-
-
-* Remove extra encodeURI
-* Travis integration
-
-## 2.3.6
->2014-01-06
-
-
-* Missing encodeURI
-* Added "distinct" documentation
-
-## 2.3.5
->2013-12-06
-
-
-* Added browse methods
-
-## 2.3.4-1
->2013-12-04
-
-
-* Fixed IE9 bug while reading onload's event
-* Here and there typos
-
-## 2.3.0
->2013-11-07
-
-
-* Added new ACL features (maxQueriesPerIPPerHour & maxHitsPerQuery)
-
-## 2.2.0
->2013-11-07
-
-
-* Added clearIndex method
-
-## 2.1.0
->2013-11-03
-
-
-* Auto-detect protocol to used based on current location
-* Added auto-complete & instant-search examples
-
-## 2.0.1
->2013-10-15
-
-
-* Gruntification
-* Embed typeahead.js
diff --git a/js/algoliasearch/LICENSE.txt b/js/algoliasearch/LICENSE.txt
deleted file mode 100644
index 8c315f45..00000000
--- a/js/algoliasearch/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Algolia
-http://www.algolia.com/
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/js/algoliasearch/README.md b/js/algoliasearch/README.md
index d97c6dc5..9e227e85 100644
--- a/js/algoliasearch/README.md
+++ b/js/algoliasearch/README.md
@@ -6,11 +6,10 @@
The perfect starting point to integrate Algolia within your JavaScript project
-
-
+
@@ -28,28 +27,30 @@
- Thin & **minimal low-level HTTP client** to interact with Algolia's API
- Works both on the **browser** and **node.js**
- **UMD compatible**, you can use it with any module loader
-- Contains type definitions: **[@types/algoliasearch](https://www.npmjs.com/package/@types/algoliasearch)**
+- Built with TypeScript
## đź’ˇ Getting Started
First, install Algolia JavaScript API Client via the [npm](https://www.npmjs.com/get-npm) package manager:
```bash
-npm install --save algoliasearch
+npm install algoliasearch
```
Then, create objects on your index:
```js
-const algoliasearch = require('algoliasearch');
+const algoliasearch = require("algoliasearch");
-const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey');
-const index = client.initIndex('your_index_name');
+const client = algoliasearch("YourApplicationID", "YourAdminAPIKey");
+const index = client.initIndex("your_index_name");
-const objects = [{
- objectID: 1,
- name: 'Foo'
-}];
+const objects = [
+ {
+ objectID: 1,
+ name: "Foo"
+ }
+];
index
.saveObjects(objects)
@@ -65,7 +66,7 @@ Finally, let's actually search using the `search` method:
```js
index
- .search('Fo')
+ .search("Fo")
.then(({ hits }) => {
console.log(hits);
})
@@ -78,4 +79,4 @@ For full documentation, visit the **[online documentation](https://www.algolia.c
## đź“„ License
-Algolia JavaScript API Client is an open-sourced software licensed under the [MIT license](LICENSE.txt).
+Algolia JavaScript API Client is an open-sourced software licensed under the [MIT license](LICENSE.md).
diff --git a/js/algoliasearch/bower.json b/js/algoliasearch/bower.json
deleted file mode 100644
index 93111c67..00000000
--- a/js/algoliasearch/bower.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "algoliasearch",
- "version": "3.35.1",
- "homepage": "https://github.com/algolia/algoliasearch-client-js",
- "authors": [
- "Algolia Team "
- ],
- "description": "Algolia Search is a search API that provides hosted full-text, numerical and faceted search.",
- "main": "dist/algoliasearch.js",
- "keywords": [
- "js",
- "algolia",
- "search",
- "api",
- "rest"
- ],
- "license": "MIT",
- "ignore": [
- "examples",
- "node_modules",
- "bower_components",
- "test"
- ]
-}
diff --git a/js/algoliasearch/dist/algoliasearch-lite.d.ts b/js/algoliasearch/dist/algoliasearch-lite.d.ts
new file mode 100644
index 00000000..4c4b983d
--- /dev/null
+++ b/js/algoliasearch/dist/algoliasearch-lite.d.ts
@@ -0,0 +1,47 @@
+import { ClientTransporterOptions } from '@algolia/client-common';
+import { FindAnswersOptions } from '@algolia/client-search';
+import { FindAnswersResponse } from '@algolia/client-search';
+import { MultipleQueriesOptions } from '@algolia/client-search';
+import { MultipleQueriesQuery } from '@algolia/client-search';
+import { MultipleQueriesResponse } from '@algolia/client-search';
+import { RequestOptions } from '@algolia/transporter';
+import { SearchClient as SearchClient_2 } from '@algolia/client-search';
+import { SearchClientOptions } from '@algolia/client-search';
+import { SearchForFacetValuesQueryParams } from '@algolia/client-search';
+import { SearchForFacetValuesResponse } from '@algolia/client-search';
+import { SearchIndex as SearchIndex_2 } from '@algolia/client-search';
+import { SearchOptions } from '@algolia/client-search';
+import { SearchResponse } from '@algolia/client-search';
+
+declare function algoliasearch(appId: string, apiKey: string, options?: AlgoliaSearchOptions): SearchClient;
+
+declare namespace algoliasearch {
+ var version: string;
+}
+export default algoliasearch;
+
+export declare type AlgoliaSearchOptions = Partial & WithoutCredentials;
+
+declare type Credentials = {
+ readonly appId: string;
+ readonly apiKey: string;
+};
+
+export declare type SearchClient = SearchClient_2 & {
+ readonly initIndex: (indexName: string) => SearchIndex;
+ readonly search: (queries: readonly MultipleQueriesQuery[], requestOptions?: RequestOptions & MultipleQueriesOptions) => Readonly>>;
+ readonly searchForFacetValues: (queries: ReadonlyArray<{
+ readonly indexName: string;
+ readonly params: SearchForFacetValuesQueryParams & SearchOptions;
+ }>, requestOptions?: RequestOptions) => Readonly>;
+};
+
+export declare type SearchIndex = SearchIndex_2 & {
+ readonly search: (query: string, requestOptions?: RequestOptions & SearchOptions) => Readonly>>;
+ readonly searchForFacetValues: (facetName: string, facetQuery: string, requestOptions?: RequestOptions & SearchOptions) => Readonly>;
+ readonly findAnswers: (query: string, queryLanguages: readonly string[], requestOptions?: RequestOptions & FindAnswersOptions) => Readonly>>;
+};
+
+export declare type WithoutCredentials = Omit;
+
+export { }
diff --git a/js/algoliasearch/dist/algoliasearch-lite.esm.browser.js b/js/algoliasearch/dist/algoliasearch-lite.esm.browser.js
new file mode 100644
index 00000000..89c99b68
--- /dev/null
+++ b/js/algoliasearch/dist/algoliasearch-lite.esm.browser.js
@@ -0,0 +1,905 @@
+function createBrowserLocalStorageCache(options) {
+ const namespaceKey = `algoliasearch-client-js-${options.key}`;
+ // eslint-disable-next-line functional/no-let
+ let storage;
+ const getStorage = () => {
+ if (storage === undefined) {
+ storage = options.localStorage || window.localStorage;
+ }
+ return storage;
+ };
+ const getNamespace = () => {
+ return JSON.parse(getStorage().getItem(namespaceKey) || '{}');
+ };
+ return {
+ get(key, defaultValue, events = {
+ miss: () => Promise.resolve(),
+ }) {
+ return Promise.resolve()
+ .then(() => {
+ const keyAsString = JSON.stringify(key);
+ const value = getNamespace()[keyAsString];
+ return Promise.all([value || defaultValue(), value !== undefined]);
+ })
+ .then(([value, exists]) => {
+ return Promise.all([value, exists || events.miss(value)]);
+ })
+ .then(([value]) => value);
+ },
+ set(key, value) {
+ return Promise.resolve().then(() => {
+ const namespace = getNamespace();
+ // eslint-disable-next-line functional/immutable-data
+ namespace[JSON.stringify(key)] = value;
+ getStorage().setItem(namespaceKey, JSON.stringify(namespace));
+ return value;
+ });
+ },
+ delete(key) {
+ return Promise.resolve().then(() => {
+ const namespace = getNamespace();
+ // eslint-disable-next-line functional/immutable-data
+ delete namespace[JSON.stringify(key)];
+ getStorage().setItem(namespaceKey, JSON.stringify(namespace));
+ });
+ },
+ clear() {
+ return Promise.resolve().then(() => {
+ getStorage().removeItem(namespaceKey);
+ });
+ },
+ };
+}
+
+// @todo Add logger on options to debug when caches go wrong.
+function createFallbackableCache(options) {
+ const caches = [...options.caches];
+ const current = caches.shift(); // eslint-disable-line functional/immutable-data
+ if (current === undefined) {
+ return createNullCache();
+ }
+ return {
+ get(key, defaultValue, events = {
+ miss: () => Promise.resolve(),
+ }) {
+ return current.get(key, defaultValue, events).catch(() => {
+ return createFallbackableCache({ caches }).get(key, defaultValue, events);
+ });
+ },
+ set(key, value) {
+ return current.set(key, value).catch(() => {
+ return createFallbackableCache({ caches }).set(key, value);
+ });
+ },
+ delete(key) {
+ return current.delete(key).catch(() => {
+ return createFallbackableCache({ caches }).delete(key);
+ });
+ },
+ clear() {
+ return current.clear().catch(() => {
+ return createFallbackableCache({ caches }).clear();
+ });
+ },
+ };
+}
+
+function createNullCache() {
+ return {
+ get(_key, defaultValue, events = {
+ miss: () => Promise.resolve(),
+ }) {
+ const value = defaultValue();
+ return value
+ .then(result => Promise.all([result, events.miss(result)]))
+ .then(([result]) => result);
+ },
+ set(_key, value) {
+ return Promise.resolve(value);
+ },
+ delete(_key) {
+ return Promise.resolve();
+ },
+ clear() {
+ return Promise.resolve();
+ },
+ };
+}
+
+function createInMemoryCache(options = { serializable: true }) {
+ // eslint-disable-next-line functional/no-let
+ let cache = {};
+ return {
+ get(key, defaultValue, events = {
+ miss: () => Promise.resolve(),
+ }) {
+ const keyAsString = JSON.stringify(key);
+ if (keyAsString in cache) {
+ return Promise.resolve(options.serializable ? JSON.parse(cache[keyAsString]) : cache[keyAsString]);
+ }
+ const promise = defaultValue();
+ const miss = (events && events.miss) || (() => Promise.resolve());
+ return promise.then((value) => miss(value)).then(() => promise);
+ },
+ set(key, value) {
+ // eslint-disable-next-line functional/immutable-data
+ cache[JSON.stringify(key)] = options.serializable ? JSON.stringify(value) : value;
+ return Promise.resolve(value);
+ },
+ delete(key) {
+ // eslint-disable-next-line functional/immutable-data
+ delete cache[JSON.stringify(key)];
+ return Promise.resolve();
+ },
+ clear() {
+ cache = {};
+ return Promise.resolve();
+ },
+ };
+}
+
+function createAuth(authMode, appId, apiKey) {
+ const credentials = {
+ 'x-algolia-api-key': apiKey,
+ 'x-algolia-application-id': appId,
+ };
+ return {
+ headers() {
+ return authMode === AuthMode.WithinHeaders ? credentials : {};
+ },
+ queryParameters() {
+ return authMode === AuthMode.WithinQueryParameters ? credentials : {};
+ },
+ };
+}
+
+// eslint-disable-next-line functional/prefer-readonly-type
+function shuffle(array) {
+ let c = array.length - 1; // eslint-disable-line functional/no-let
+ // eslint-disable-next-line functional/no-loop-statement
+ for (c; c > 0; c--) {
+ const b = Math.floor(Math.random() * (c + 1));
+ const a = array[c];
+ array[c] = array[b]; // eslint-disable-line functional/immutable-data, no-param-reassign
+ array[b] = a; // eslint-disable-line functional/immutable-data, no-param-reassign
+ }
+ return array;
+}
+function addMethods(base, methods) {
+ if (!methods) {
+ return base;
+ }
+ Object.keys(methods).forEach(key => {
+ // eslint-disable-next-line functional/immutable-data, no-param-reassign
+ base[key] = methods[key](base);
+ });
+ return base;
+}
+function encode(format, ...args) {
+ // eslint-disable-next-line functional/no-let
+ let i = 0;
+ return format.replace(/%s/g, () => encodeURIComponent(args[i++]));
+}
+
+const version = '4.10.3';
+
+const AuthMode = {
+ /**
+ * If auth credentials should be in query parameters.
+ */
+ WithinQueryParameters: 0,
+ /**
+ * If auth credentials should be in headers.
+ */
+ WithinHeaders: 1,
+};
+
+function createMappedRequestOptions(requestOptions, timeout) {
+ const options = requestOptions || {};
+ const data = options.data || {};
+ Object.keys(options).forEach(key => {
+ if (['timeout', 'headers', 'queryParameters', 'data', 'cacheable'].indexOf(key) === -1) {
+ data[key] = options[key]; // eslint-disable-line functional/immutable-data
+ }
+ });
+ return {
+ data: Object.entries(data).length > 0 ? data : undefined,
+ timeout: options.timeout || timeout,
+ headers: options.headers || {},
+ queryParameters: options.queryParameters || {},
+ cacheable: options.cacheable,
+ };
+}
+
+const CallEnum = {
+ /**
+ * If the host is read only.
+ */
+ Read: 1,
+ /**
+ * If the host is write only.
+ */
+ Write: 2,
+ /**
+ * If the host is both read and write.
+ */
+ Any: 3,
+};
+
+const HostStatusEnum = {
+ Up: 1,
+ Down: 2,
+ Timeouted: 3,
+};
+
+// By default, API Clients at Algolia have expiration delay
+// of 5 mins. In the JavaScript client, we have 2 mins.
+const EXPIRATION_DELAY = 2 * 60 * 1000;
+function createStatefulHost(host, status = HostStatusEnum.Up) {
+ return {
+ ...host,
+ status,
+ lastUpdate: Date.now(),
+ };
+}
+function isStatefulHostUp(host) {
+ return host.status === HostStatusEnum.Up || Date.now() - host.lastUpdate > EXPIRATION_DELAY;
+}
+function isStatefulHostTimeouted(host) {
+ return (host.status === HostStatusEnum.Timeouted && Date.now() - host.lastUpdate <= EXPIRATION_DELAY);
+}
+
+function createStatelessHost(options) {
+ if (typeof options === 'string') {
+ return {
+ protocol: 'https',
+ url: options,
+ accept: CallEnum.Any,
+ };
+ }
+ return {
+ protocol: options.protocol || 'https',
+ url: options.url,
+ accept: options.accept || CallEnum.Any,
+ };
+}
+
+const MethodEnum = {
+ Delete: 'DELETE',
+ Get: 'GET',
+ Post: 'POST',
+ Put: 'PUT',
+};
+
+function createRetryableOptions(hostsCache, statelessHosts) {
+ return Promise.all(statelessHosts.map(statelessHost => {
+ return hostsCache.get(statelessHost, () => {
+ return Promise.resolve(createStatefulHost(statelessHost));
+ });
+ })).then(statefulHosts => {
+ const hostsUp = statefulHosts.filter(host => isStatefulHostUp(host));
+ const hostsTimeouted = statefulHosts.filter(host => isStatefulHostTimeouted(host));
+ /**
+ * Note, we put the hosts that previously timeouted on the end of the list.
+ */
+ const hostsAvailable = [...hostsUp, ...hostsTimeouted];
+ const statelessHostsAvailable = hostsAvailable.length > 0
+ ? hostsAvailable.map(host => createStatelessHost(host))
+ : statelessHosts;
+ return {
+ getTimeout(timeoutsCount, baseTimeout) {
+ /**
+ * Imagine that you have 4 hosts, if timeouts will increase
+ * on the following way: 1 (timeouted) > 4 (timeouted) > 5 (200)
+ *
+ * Note that, the very next request, we start from the previous timeout
+ *
+ * 5 (timeouted) > 6 (timeouted) > 7 ...
+ *
+ * This strategy may need to be reviewed, but is the strategy on the our
+ * current v3 version.
+ */
+ const timeoutMultiplier = hostsTimeouted.length === 0 && timeoutsCount === 0
+ ? 1
+ : hostsTimeouted.length + 3 + timeoutsCount;
+ return timeoutMultiplier * baseTimeout;
+ },
+ statelessHosts: statelessHostsAvailable,
+ };
+ });
+}
+
+const isNetworkError = ({ isTimedOut, status }) => {
+ return !isTimedOut && ~~status === 0;
+};
+const isRetryable = (response) => {
+ const status = response.status;
+ const isTimedOut = response.isTimedOut;
+ return (isTimedOut || isNetworkError(response) || (~~(status / 100) !== 2 && ~~(status / 100) !== 4));
+};
+const isSuccess = ({ status }) => {
+ return ~~(status / 100) === 2;
+};
+const retryDecision = (response, outcomes) => {
+ if (isRetryable(response)) {
+ return outcomes.onRetry(response);
+ }
+ if (isSuccess(response)) {
+ return outcomes.onSuccess(response);
+ }
+ return outcomes.onFail(response);
+};
+
+function retryableRequest(transporter, statelessHosts, request, requestOptions) {
+ const stackTrace = []; // eslint-disable-line functional/prefer-readonly-type
+ /**
+ * First we prepare the payload that do not depend from hosts.
+ */
+ const data = serializeData(request, requestOptions);
+ const headers = serializeHeaders(transporter, requestOptions);
+ const method = request.method;
+ // On `GET`, the data is proxied to query parameters.
+ const dataQueryParameters = request.method !== MethodEnum.Get
+ ? {}
+ : {
+ ...request.data,
+ ...requestOptions.data,
+ };
+ const queryParameters = {
+ 'x-algolia-agent': transporter.userAgent.value,
+ ...transporter.queryParameters,
+ ...dataQueryParameters,
+ ...requestOptions.queryParameters,
+ };
+ let timeoutsCount = 0; // eslint-disable-line functional/no-let
+ const retry = (hosts, // eslint-disable-line functional/prefer-readonly-type
+ getTimeout) => {
+ /**
+ * We iterate on each host, until there is no host left.
+ */
+ const host = hosts.pop(); // eslint-disable-line functional/immutable-data
+ if (host === undefined) {
+ throw createRetryError(stackTraceWithoutCredentials(stackTrace));
+ }
+ const payload = {
+ data,
+ headers,
+ method,
+ url: serializeUrl(host, request.path, queryParameters),
+ connectTimeout: getTimeout(timeoutsCount, transporter.timeouts.connect),
+ responseTimeout: getTimeout(timeoutsCount, requestOptions.timeout),
+ };
+ /**
+ * The stackFrame is pushed to the stackTrace so we
+ * can have information about onRetry and onFailure
+ * decisions.
+ */
+ const pushToStackTrace = (response) => {
+ const stackFrame = {
+ request: payload,
+ response,
+ host,
+ triesLeft: hosts.length,
+ };
+ // eslint-disable-next-line functional/immutable-data
+ stackTrace.push(stackFrame);
+ return stackFrame;
+ };
+ const decisions = {
+ onSuccess: response => deserializeSuccess(response),
+ onRetry(response) {
+ const stackFrame = pushToStackTrace(response);
+ /**
+ * If response is a timeout, we increaset the number of
+ * timeouts so we can increase the timeout later.
+ */
+ if (response.isTimedOut) {
+ timeoutsCount++;
+ }
+ return Promise.all([
+ /**
+ * Failures are individually send the logger, allowing
+ * the end user to debug / store stack frames even
+ * when a retry error does not happen.
+ */
+ transporter.logger.info('Retryable failure', stackFrameWithoutCredentials(stackFrame)),
+ /**
+ * We also store the state of the host in failure cases. If the host, is
+ * down it will remain down for the next 2 minutes. In a timeout situation,
+ * this host will be added end of the list of hosts on the next request.
+ */
+ transporter.hostsCache.set(host, createStatefulHost(host, response.isTimedOut ? HostStatusEnum.Timeouted : HostStatusEnum.Down)),
+ ]).then(() => retry(hosts, getTimeout));
+ },
+ onFail(response) {
+ pushToStackTrace(response);
+ throw deserializeFailure(response, stackTraceWithoutCredentials(stackTrace));
+ },
+ };
+ return transporter.requester.send(payload).then(response => {
+ return retryDecision(response, decisions);
+ });
+ };
+ /**
+ * Finally, for each retryable host perform request until we got a non
+ * retryable response. Some notes here:
+ *
+ * 1. The reverse here is applied so we can apply a `pop` later on => more performant.
+ * 2. We also get from the retryable options a timeout multiplier that is tailored
+ * for the current context.
+ */
+ return createRetryableOptions(transporter.hostsCache, statelessHosts).then(options => {
+ return retry([...options.statelessHosts].reverse(), options.getTimeout);
+ });
+}
+
+function createTransporter(options) {
+ const { hostsCache, logger, requester, requestsCache, responsesCache, timeouts, userAgent, hosts, queryParameters, headers, } = options;
+ const transporter = {
+ hostsCache,
+ logger,
+ requester,
+ requestsCache,
+ responsesCache,
+ timeouts,
+ userAgent,
+ headers,
+ queryParameters,
+ hosts: hosts.map(host => createStatelessHost(host)),
+ read(request, requestOptions) {
+ /**
+ * First, we compute the user request options. Now, keep in mind,
+ * that using request options the user is able to modified the intire
+ * payload of the request. Such as headers, query parameters, and others.
+ */
+ const mappedRequestOptions = createMappedRequestOptions(requestOptions, transporter.timeouts.read);
+ const createRetryableRequest = () => {
+ /**
+ * Then, we prepare a function factory that contains the construction of
+ * the retryable request. At this point, we may *not* perform the actual
+ * request. But we want to have the function factory ready.
+ */
+ return retryableRequest(transporter, transporter.hosts.filter(host => (host.accept & CallEnum.Read) !== 0), request, mappedRequestOptions);
+ };
+ /**
+ * Once we have the function factory ready, we need to determine of the
+ * request is "cacheable" - should be cached. Note that, once again,
+ * the user can force this option.
+ */
+ const cacheable = mappedRequestOptions.cacheable !== undefined
+ ? mappedRequestOptions.cacheable
+ : request.cacheable;
+ /**
+ * If is not "cacheable", we immediatly trigger the retryable request, no
+ * need to check cache implementations.
+ */
+ if (cacheable !== true) {
+ return createRetryableRequest();
+ }
+ /**
+ * If the request is "cacheable", we need to first compute the key to ask
+ * the cache implementations if this request is on progress or if the
+ * response already exists on the cache.
+ */
+ const key = {
+ request,
+ mappedRequestOptions,
+ transporter: {
+ queryParameters: transporter.queryParameters,
+ headers: transporter.headers,
+ },
+ };
+ /**
+ * With the computed key, we first ask the responses cache
+ * implemention if this request was been resolved before.
+ */
+ return transporter.responsesCache.get(key, () => {
+ /**
+ * If the request has never resolved before, we actually ask if there
+ * is a current request with the same key on progress.
+ */
+ return transporter.requestsCache.get(key, () => {
+ return (transporter.requestsCache
+ /**
+ * Finally, if there is no request in progress with the same key,
+ * this `createRetryableRequest()` will actually trigger the
+ * retryable request.
+ */
+ .set(key, createRetryableRequest())
+ .then(response => Promise.all([transporter.requestsCache.delete(key), response]), err => Promise.all([transporter.requestsCache.delete(key), Promise.reject(err)]))
+ .then(([_, response]) => response));
+ });
+ }, {
+ /**
+ * Of course, once we get this response back from the server, we
+ * tell response cache to actually store the received response
+ * to be used later.
+ */
+ miss: response => transporter.responsesCache.set(key, response),
+ });
+ },
+ write(request, requestOptions) {
+ /**
+ * On write requests, no cache mechanisms are applied, and we
+ * proxy the request immediately to the requester.
+ */
+ return retryableRequest(transporter, transporter.hosts.filter(host => (host.accept & CallEnum.Write) !== 0), request, createMappedRequestOptions(requestOptions, transporter.timeouts.write));
+ },
+ };
+ return transporter;
+}
+
+function createUserAgent(version) {
+ const userAgent = {
+ value: `Algolia for JavaScript (${version})`,
+ add(options) {
+ const addedUserAgent = `; ${options.segment}${options.version !== undefined ? ` (${options.version})` : ''}`;
+ if (userAgent.value.indexOf(addedUserAgent) === -1) {
+ // eslint-disable-next-line functional/immutable-data
+ userAgent.value = `${userAgent.value}${addedUserAgent}`;
+ }
+ return userAgent;
+ },
+ };
+ return userAgent;
+}
+
+function deserializeSuccess(response) {
+ // eslint-disable-next-line functional/no-try-statement
+ try {
+ return JSON.parse(response.content);
+ }
+ catch (e) {
+ throw createDeserializationError(e.message, response);
+ }
+}
+function deserializeFailure({ content, status }, stackFrame) {
+ // eslint-disable-next-line functional/no-let
+ let message = content;
+ // eslint-disable-next-line functional/no-try-statement
+ try {
+ message = JSON.parse(content).message;
+ }
+ catch (e) {
+ // ..
+ }
+ return createApiError(message, status, stackFrame);
+}
+
+function serializeUrl(host, path, queryParameters) {
+ const queryParametersAsString = serializeQueryParameters(queryParameters);
+ // eslint-disable-next-line functional/no-let
+ let url = `${host.protocol}://${host.url}/${path.charAt(0) === '/' ? path.substr(1) : path}`;
+ if (queryParametersAsString.length) {
+ url += `?${queryParametersAsString}`;
+ }
+ return url;
+}
+function serializeQueryParameters(parameters) {
+ const isObjectOrArray = (value) => Object.prototype.toString.call(value) === '[object Object]' ||
+ Object.prototype.toString.call(value) === '[object Array]';
+ return Object.keys(parameters)
+ .map(key => encode('%s=%s', key, isObjectOrArray(parameters[key]) ? JSON.stringify(parameters[key]) : parameters[key]))
+ .join('&');
+}
+function serializeData(request, requestOptions) {
+ if (request.method === MethodEnum.Get ||
+ (request.data === undefined && requestOptions.data === undefined)) {
+ return undefined;
+ }
+ const data = Array.isArray(request.data)
+ ? request.data
+ : { ...request.data, ...requestOptions.data };
+ return JSON.stringify(data);
+}
+function serializeHeaders(transporter, requestOptions) {
+ const headers = {
+ ...transporter.headers,
+ ...requestOptions.headers,
+ };
+ const serializedHeaders = {};
+ Object.keys(headers).forEach(header => {
+ const value = headers[header];
+ // @ts-ignore
+ // eslint-disable-next-line functional/immutable-data
+ serializedHeaders[header.toLowerCase()] = value;
+ });
+ return serializedHeaders;
+}
+
+function stackTraceWithoutCredentials(stackTrace) {
+ return stackTrace.map(stackFrame => stackFrameWithoutCredentials(stackFrame));
+}
+function stackFrameWithoutCredentials(stackFrame) {
+ const modifiedHeaders = stackFrame.request.headers['x-algolia-api-key']
+ ? { 'x-algolia-api-key': '*****' }
+ : {};
+ return {
+ ...stackFrame,
+ request: {
+ ...stackFrame.request,
+ headers: {
+ ...stackFrame.request.headers,
+ ...modifiedHeaders,
+ },
+ },
+ };
+}
+
+function createApiError(message, status, transporterStackTrace) {
+ return {
+ name: 'ApiError',
+ message,
+ status,
+ transporterStackTrace,
+ };
+}
+
+function createDeserializationError(message, response) {
+ return {
+ name: 'DeserializationError',
+ message,
+ response,
+ };
+}
+
+function createRetryError(transporterStackTrace) {
+ return {
+ name: 'RetryError',
+ message: 'Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.',
+ transporterStackTrace,
+ };
+}
+
+const createSearchClient = options => {
+ const appId = options.appId;
+ const auth = createAuth(options.authMode !== undefined ? options.authMode : AuthMode.WithinHeaders, appId, options.apiKey);
+ const transporter = createTransporter({
+ hosts: [
+ { url: `${appId}-dsn.algolia.net`, accept: CallEnum.Read },
+ { url: `${appId}.algolia.net`, accept: CallEnum.Write },
+ ].concat(shuffle([
+ { url: `${appId}-1.algolianet.com` },
+ { url: `${appId}-2.algolianet.com` },
+ { url: `${appId}-3.algolianet.com` },
+ ])),
+ ...options,
+ headers: {
+ ...auth.headers(),
+ ...{ 'content-type': 'application/x-www-form-urlencoded' },
+ ...options.headers,
+ },
+ queryParameters: {
+ ...auth.queryParameters(),
+ ...options.queryParameters,
+ },
+ });
+ const base = {
+ transporter,
+ appId,
+ addAlgoliaAgent(segment, version) {
+ transporter.userAgent.add({ segment, version });
+ },
+ clearCache() {
+ return Promise.all([
+ transporter.requestsCache.clear(),
+ transporter.responsesCache.clear(),
+ ]).then(() => undefined);
+ },
+ };
+ return addMethods(base, options.methods);
+};
+
+const initIndex = (base) => {
+ return (indexName, options = {}) => {
+ const searchIndex = {
+ transporter: base.transporter,
+ appId: base.appId,
+ indexName,
+ };
+ return addMethods(searchIndex, options.methods);
+ };
+};
+
+const multipleQueries = (base) => {
+ return (queries, requestOptions) => {
+ const requests = queries.map(query => {
+ return {
+ ...query,
+ params: serializeQueryParameters(query.params || {}),
+ };
+ });
+ return base.transporter.read({
+ method: MethodEnum.Post,
+ path: '1/indexes/*/queries',
+ data: {
+ requests,
+ },
+ cacheable: true,
+ }, requestOptions);
+ };
+};
+
+const multipleSearchForFacetValues = (base) => {
+ return (queries, requestOptions) => {
+ return Promise.all(queries.map(query => {
+ const { facetName, facetQuery, ...params } = query.params;
+ return initIndex(base)(query.indexName, {
+ methods: { searchForFacetValues },
+ }).searchForFacetValues(facetName, facetQuery, {
+ ...requestOptions,
+ ...params,
+ });
+ }));
+ };
+};
+
+const findAnswers = (base) => {
+ return (query, queryLanguages, requestOptions) => {
+ return base.transporter.read({
+ method: MethodEnum.Post,
+ path: encode('1/answers/%s/prediction', base.indexName),
+ data: {
+ query,
+ queryLanguages,
+ },
+ cacheable: true,
+ }, requestOptions);
+ };
+};
+
+const search = (base) => {
+ return (query, requestOptions) => {
+ return base.transporter.read({
+ method: MethodEnum.Post,
+ path: encode('1/indexes/%s/query', base.indexName),
+ data: {
+ query,
+ },
+ cacheable: true,
+ }, requestOptions);
+ };
+};
+
+const searchForFacetValues = (base) => {
+ return (facetName, facetQuery, requestOptions) => {
+ return base.transporter.read({
+ method: MethodEnum.Post,
+ path: encode('1/indexes/%s/facets/%s/query', base.indexName, facetName),
+ data: {
+ facetQuery,
+ },
+ cacheable: true,
+ }, requestOptions);
+ };
+};
+
+const LogLevelEnum = {
+ Debug: 1,
+ Info: 2,
+ Error: 3,
+};
+
+/* eslint no-console: 0 */
+function createConsoleLogger(logLevel) {
+ return {
+ debug(message, args) {
+ if (LogLevelEnum.Debug >= logLevel) {
+ console.debug(message, args);
+ }
+ return Promise.resolve();
+ },
+ info(message, args) {
+ if (LogLevelEnum.Info >= logLevel) {
+ console.info(message, args);
+ }
+ return Promise.resolve();
+ },
+ error(message, args) {
+ console.error(message, args);
+ return Promise.resolve();
+ },
+ };
+}
+
+function createBrowserXhrRequester() {
+ return {
+ send(request) {
+ return new Promise((resolve) => {
+ const baseRequester = new XMLHttpRequest();
+ baseRequester.open(request.method, request.url, true);
+ Object.keys(request.headers).forEach(key => baseRequester.setRequestHeader(key, request.headers[key]));
+ const createTimeout = (timeout, content) => {
+ return setTimeout(() => {
+ baseRequester.abort();
+ resolve({
+ status: 0,
+ content,
+ isTimedOut: true,
+ });
+ }, timeout * 1000);
+ };
+ const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
+ // eslint-disable-next-line functional/no-let
+ let responseTimeout;
+ // eslint-disable-next-line functional/immutable-data
+ baseRequester.onreadystatechange = () => {
+ if (baseRequester.readyState > baseRequester.OPENED && responseTimeout === undefined) {
+ clearTimeout(connectTimeout);
+ responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
+ }
+ };
+ // eslint-disable-next-line functional/immutable-data
+ baseRequester.onerror = () => {
+ // istanbul ignore next
+ if (baseRequester.status === 0) {
+ clearTimeout(connectTimeout);
+ clearTimeout(responseTimeout);
+ resolve({
+ content: baseRequester.responseText || 'Network request failed',
+ status: baseRequester.status,
+ isTimedOut: false,
+ });
+ }
+ };
+ // eslint-disable-next-line functional/immutable-data
+ baseRequester.onload = () => {
+ clearTimeout(connectTimeout);
+ clearTimeout(responseTimeout);
+ resolve({
+ content: baseRequester.responseText,
+ status: baseRequester.status,
+ isTimedOut: false,
+ });
+ };
+ baseRequester.send(request.data);
+ });
+ },
+ };
+}
+
+function algoliasearch(appId, apiKey, options) {
+ const commonOptions = {
+ appId,
+ apiKey,
+ timeouts: {
+ connect: 1,
+ read: 2,
+ write: 30,
+ },
+ requester: createBrowserXhrRequester(),
+ logger: createConsoleLogger(LogLevelEnum.Error),
+ responsesCache: createInMemoryCache(),
+ requestsCache: createInMemoryCache({ serializable: false }),
+ hostsCache: createFallbackableCache({
+ caches: [
+ createBrowserLocalStorageCache({ key: `${version}-${appId}` }),
+ createInMemoryCache(),
+ ],
+ }),
+ userAgent: createUserAgent(version).add({
+ segment: 'Browser',
+ version: 'lite',
+ }),
+ authMode: AuthMode.WithinQueryParameters,
+ };
+ return createSearchClient({
+ ...commonOptions,
+ ...options,
+ methods: {
+ search: multipleQueries,
+ searchForFacetValues: multipleSearchForFacetValues,
+ multipleQueries,
+ multipleSearchForFacetValues,
+ initIndex: base => (indexName) => {
+ return initIndex(base)(indexName, {
+ methods: { search, searchForFacetValues, findAnswers },
+ });
+ },
+ },
+ });
+}
+// eslint-disable-next-line functional/immutable-data
+algoliasearch.version = version;
+
+export default algoliasearch;
diff --git a/js/algoliasearch/dist/algoliasearch-lite.umd.js b/js/algoliasearch/dist/algoliasearch-lite.umd.js
new file mode 100644
index 00000000..b2082e12
--- /dev/null
+++ b/js/algoliasearch/dist/algoliasearch-lite.umd.js
@@ -0,0 +1,2 @@
+/*! algoliasearch-lite.umd.js | 4.10.3 | © Algolia, inc. | https://github.com/algolia/algoliasearch-client-javascript */
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).algoliasearch=t()}(this,(function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function r(r){for(var n=1;n=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(!(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)))return;var r=[],n=!0,o=!1,a=void 0;try{for(var u,i=e[Symbol.iterator]();!(n=(u=i.next()).done)&&(r.push(u.value),!t||r.length!==t);n=!0);}catch(e){o=!0,a=e}finally{try{n||null==i.return||i.return()}finally{if(o)throw a}}return r}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function a(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){var r=JSON.stringify(e),n=a()[r];return Promise.all([n||t(),void 0!==n])})).then((function(e){var t=o(e,2),n=t[0],a=t[1];return Promise.all([n,a||r.miss(n)])})).then((function(e){return o(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var o=a();return o[JSON.stringify(e)]=t,n().setItem(r,JSON.stringify(o)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=a();delete t[JSON.stringify(e)],n().setItem(r,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){n().removeItem(r)}))}}}function i(e){var t=a(e.caches),r=t.shift();return void 0===r?{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},n=t();return n.then((function(e){return Promise.all([e,r.miss(e)])})).then((function(e){return o(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return r.get(e,n,o).catch((function(){return i({caches:t}).get(e,n,o)}))},set:function(e,n){return r.set(e,n).catch((function(){return i({caches:t}).set(e,n)}))},delete:function(e){return r.delete(e).catch((function(){return i({caches:t}).delete(e)}))},clear:function(){return r.clear().catch((function(){return i({caches:t}).clear()}))}}}function s(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(r,n){var o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},a=JSON.stringify(r);if(a in t)return Promise.resolve(e.serializable?JSON.parse(t[a]):t[a]);var u=n(),i=o&&o.miss||function(){return Promise.resolve()};return u.then((function(e){return i(e)})).then((function(){return u}))},set:function(r,n){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function c(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function l(e,t){return t?(Object.keys(t).forEach((function(r){e[r]=t[r](e)})),e):e}function f(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var m={Read:1,Write:2,Any:3},p=1,v=2,y=3;function g(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;return r(r({},e),{},{status:t,lastUpdate:Date.now()})}function b(e){return"string"==typeof e?{protocol:"https",url:e,accept:m.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||m.Any}}var O="GET",P="POST";function q(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(g(t))}))}))).then((function(e){var r=e.filter((function(e){return function(e){return e.status===p||Date.now()-e.lastUpdate>12e4}(e)})),n=e.filter((function(e){return function(e){return e.status===y&&Date.now()-e.lastUpdate<=12e4}(e)})),o=[].concat(a(r),a(n));return{getTimeout:function(e,t){return(0===n.length&&0===e?1:n.length+3+e)*t},statelessHosts:o.length>0?o.map((function(e){return b(e)})):t}}))}function j(e,t,n,o){var u=[],i=function(e,t){if(e.method===O||void 0===e.data&&void 0===t.data)return;var n=Array.isArray(e.data)?e.data:r(r({},e.data),t.data);return JSON.stringify(n)}(n,o),s=function(e,t){var n=r(r({},e.headers),t.headers),o={};return Object.keys(n).forEach((function(e){var t=n[e];o[e.toLowerCase()]=t})),o}(e,o),c=n.method,l=n.method!==O?{}:r(r({},n.data),o.data),f=r(r(r({"x-algolia-agent":e.userAgent.value},e.queryParameters),l),o.queryParameters),h=0,d=function t(r,a){var l=r.pop();if(void 0===l)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, contact support@algolia.com.",transporterStackTrace:A(u)};var d={data:i,headers:s,method:c,url:S(l,n.path,f),connectTimeout:a(h,e.timeouts.connect),responseTimeout:a(h,o.timeout)},m=function(e){var t={request:d,response:e,host:l,triesLeft:r.length};return u.push(t),t},p={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(n){var o=m(n);return n.isTimedOut&&h++,Promise.all([e.logger.info("Retryable failure",x(o)),e.hostsCache.set(l,g(l,n.isTimedOut?y:v))]).then((function(){return t(r,a)}))},onFail:function(e){throw m(e),function(e,t){var r=e.content,n=e.status,o=r;try{o=JSON.parse(r).message}catch(e){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(o,n,t)}(e,A(u))}};return e.requester.send(d).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,r=e.status;return!t&&0==~~r}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,p)}))};return q(e.hostsCache,t).then((function(e){return d(a(e.statelessHosts).reverse(),e.getTimeout)}))}function w(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var r="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(r)&&(t.value="".concat(t.value).concat(r)),t}};return t}function S(e,t,r){var n=T(r),o="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return n.length&&(o+="?".concat(n)),o}function T(e){return Object.keys(e).map((function(t){return f("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function A(e){return e.map((function(e){return x(e)}))}function x(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return r(r({},e),{},{request:r(r({},e.request),{},{headers:r(r({},e.request.headers),t)})})}var N=function(e){var t=e.appId,n=function(e,t,r){var n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:function(){return e===h.WithinHeaders?n:{}},queryParameters:function(){return e===h.WithinQueryParameters?n:{}}}}(void 0!==e.authMode?e.authMode:h.WithinHeaders,t,e.apiKey),a=function(e){var t=e.hostsCache,r=e.logger,n=e.requester,a=e.requestsCache,u=e.responsesCache,i=e.timeouts,s=e.userAgent,c=e.hosts,l=e.queryParameters,f={hostsCache:t,logger:r,requester:n,requestsCache:a,responsesCache:u,timeouts:i,userAgent:s,headers:e.headers,queryParameters:l,hosts:c.map((function(e){return b(e)})),read:function(e,t){var r=d(t,f.timeouts.read),n=function(){return j(f,f.hosts.filter((function(e){return 0!=(e.accept&m.Read)})),e,r)};if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();var a={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(a,(function(){return f.requestsCache.get(a,(function(){return f.requestsCache.set(a,n()).then((function(e){return Promise.all([f.requestsCache.delete(a),e])}),(function(e){return Promise.all([f.requestsCache.delete(a),Promise.reject(e)])})).then((function(e){var t=o(e,2);t[0];return t[1]}))}))}),{miss:function(e){return f.responsesCache.set(a,e)}})},write:function(e,t){return j(f,f.hosts.filter((function(e){return 0!=(e.accept&m.Write)})),e,d(t,f.timeouts.write))}};return f}(r(r({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:m.Read},{url:"".concat(t,".algolia.net"),accept:m.Write}].concat(c([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:r(r(r({},n.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:r(r({},n.queryParameters()),e.queryParameters)}));return l({transporter:a,appId:t,addAlgoliaAgent:function(e,t){a.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([a.requestsCache.clear(),a.responsesCache.clear()]).then((function(){}))}},e.methods)},C=function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n={transporter:e.transporter,appId:e.appId,indexName:t};return l(n,r.methods)}},k=function(e){return function(t,n){var o=t.map((function(e){return r(r({},e),{},{params:T(e.params||{})})}));return e.transporter.read({method:P,path:"1/indexes/*/queries",data:{requests:o},cacheable:!0},n)}},J=function(e){return function(t,o){return Promise.all(t.map((function(t){var a=t.params,u=a.facetName,i=a.facetQuery,s=n(a,["facetName","facetQuery"]);return C(e)(t.indexName,{methods:{searchForFacetValues:F}}).searchForFacetValues(u,i,r(r({},o),s))})))}},E=function(e){return function(t,r,n){return e.transporter.read({method:P,path:f("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n)}},I=function(e){return function(t,r){return e.transporter.read({method:P,path:f("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r)}},F=function(e){return function(t,r,n){return e.transporter.read({method:P,path:f("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n)}},R=1,D=2,W=3;function H(e,t,n){var o,a={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return r.setRequestHeader(t,e.headers[t])}));var n,o=function(e,n){return setTimeout((function(){r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e)},a=o(e.connectTimeout,"Connection timeout");r.onreadystatechange=function(){r.readyState>r.OPENED&&void 0===n&&(clearTimeout(a),n=o(e.responseTimeout,"Socket timeout"))},r.onerror=function(){0===r.status&&(clearTimeout(a),clearTimeout(n),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=function(){clearTimeout(a),clearTimeout(n),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))}},logger:(o=W,{debug:function(e,t){return R>=o&&console.debug(e,t),Promise.resolve()},info:function(e,t){return D>=o&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:s(),requestsCache:s({serializable:!1}),hostsCache:i({caches:[u({key:"".concat("4.10.3","-").concat(e)}),s()]}),userAgent:w("4.10.3").add({segment:"Browser",version:"lite"}),authMode:h.WithinQueryParameters};return N(r(r(r({},a),n),{},{methods:{search:k,searchForFacetValues:J,multipleQueries:k,multipleSearchForFacetValues:J,initIndex:function(e){return function(t){return C(e)(t,{methods:{search:I,searchForFacetValues:F,findAnswers:E}})}}}}))}return H.version="4.10.3",H}));
diff --git a/js/algoliasearch/dist/algoliasearch.angular.js b/js/algoliasearch/dist/algoliasearch.angular.js
deleted file mode 100644
index 2856434f..00000000
--- a/js/algoliasearch/dist/algoliasearch.angular.js
+++ /dev/null
@@ -1,7398 +0,0 @@
-/*! algoliasearch 3.35.1 | © 2014, 2015 Algolia SAS | github.com/algolia/algoliasearch-client-js */
-(function(f){var g;if(typeof window!=='undefined'){g=window}else if(typeof self!=='undefined'){g=self}g.ALGOLIA_MIGRATION_LAYER=f()})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;owindow.ALGOLIA_SUPPORTS_DOCWRITE = true\x3C/script>');
-
- if (window.ALGOLIA_SUPPORTS_DOCWRITE === true) {
- document.write('\x3Cscript src="' + v2ScriptUrl + '">\x3C/script>');
- scriptLoaded('document.write')();
- } else {
- loadScript(v2ScriptUrl, scriptLoaded('DOMElement'));
- }
- } catch (e) {
- loadScript(v2ScriptUrl, scriptLoaded('DOMElement'));
- }
-}
-
-function scriptLoaded(method) {
- return function log() {
- var message = 'AlgoliaSearch: loaded V2 script using ' + method;
-
- if (window.console && window.console.log) {
- window.console.log(message);
- }
- };
-}
-
-},{"1":1}],4:[function(require,module,exports){
-'use strict';
-
-/* eslint no-unused-vars: [2, {"vars": "local"}] */
-
-module.exports = oldGlobals;
-
-// put old window.AlgoliaSearch.. into window. again so that
-// users upgrading to V3 without changing their code, will be warned
-function oldGlobals() {
- var message = '-- AlgoliaSearch V2 => V3 error --\n' +
- 'You are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\n' +
- 'Please read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n' +
- '-- /AlgoliaSearch V2 => V3 error --';
-
- window.AlgoliaSearch = function() {
- throw new Error(message);
- };
-
- window.AlgoliaSearchHelper = function() {
- throw new Error(message);
- };
-
- window.AlgoliaExplainResults = function() {
- throw new Error(message);
- };
-}
-
-},{}],5:[function(require,module,exports){
-'use strict';
-
-// This script will be browserified and prepended to the normal build
-// directly in window, not wrapped in any module definition
-// To avoid cases where we are loaded with /latest/ along with
-migrationLayer("algoliasearch.angular");
-
-// Now onto the V2 related code:
-// If the client is using /latest/$BUILDNAME.min.js, load V2 of the library
-//
-// Otherwise, setup a migration layer that will throw on old constructors like
-// new AlgoliaSearch().
-// So that users upgrading from v2 to v3 will have a clear information
-// message on what to do if they did not read the migration guide
-function migrationLayer(buildName) {
- var isUsingLatest = require(2);
- var loadV2 = require(3);
- var oldGlobals = require(4);
-
- if (isUsingLatest(buildName)) {
- loadV2(buildName);
- } else {
- oldGlobals();
- }
-}
-
-},{"2":2,"3":3,"4":4}]},{},[5])(5)
-});(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-
-function useColors() {
- // NB: In an Electron preload script, document will be defined but not fully
- // initialized. Since we know we're in Chrome, we'll just detect this case
- // explicitly
- if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
- return true;
- }
-
- // is webkit? http://stackoverflow.com/a/16459606/376773
- // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
- return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
- // is firebug? http://stackoverflow.com/a/398120/376773
- (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
- // is firefox >= v31?
- // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
- (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
- // double check webkit in userAgent just in case we are in a worker
- (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
-}
-
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
- try {
- return JSON.stringify(v);
- } catch (err) {
- return '[UnexpectedJSONParseError]: ' + err.message;
- }
-};
-
-
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
- var useColors = this.useColors;
-
- args[0] = (useColors ? '%c' : '')
- + this.namespace
- + (useColors ? ' %c' : ' ')
- + args[0]
- + (useColors ? '%c ' : ' ')
- + '+' + exports.humanize(this.diff);
-
- if (!useColors) return;
-
- var c = 'color: ' + this.color;
- args.splice(1, 0, c, 'color: inherit')
-
- // the final "%c" is somewhat tricky, because there could be other
- // arguments passed either before or after the %c, so we need to
- // figure out the correct index to insert the CSS into
- var index = 0;
- var lastC = 0;
- args[0].replace(/%[a-zA-Z%]/g, function(match) {
- if ('%%' === match) return;
- index++;
- if ('%c' === match) {
- // we only are interested in the *last* %c
- // (the user may have provided their own)
- lastC = index;
- }
- });
-
- args.splice(lastC, 0, c);
-}
-
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
-
-function log() {
- // this hackery is required for IE8/9, where
- // the `console.log` function doesn't have 'apply'
- return 'object' === typeof console
- && console.log
- && Function.prototype.apply.call(console.log, console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
- try {
- if (null == namespaces) {
- exports.storage.removeItem('debug');
- } else {
- exports.storage.debug = namespaces;
- }
- } catch(e) {}
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
- var r;
- try {
- r = exports.storage.debug;
- } catch(e) {}
-
- // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
- if (!r && typeof process !== 'undefined' && 'env' in process) {
- r = process.env.DEBUG;
- }
-
- return r;
-}
-
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
-
-/**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
-
-function localstorage() {
- try {
- return window.localStorage;
- } catch (e) {}
-}
-
-}).call(this,require(12))
-},{"12":12,"2":2}],2:[function(require,module,exports){
-
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require(9);
-
-/**
- * The currently active debug mode names, and names to skip.
- */
-
-exports.names = [];
-exports.skips = [];
-
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
- */
-
-exports.formatters = {};
-
-/**
- * Previous log timestamp.
- */
-
-var prevTime;
-
-/**
- * Select a color.
- * @param {String} namespace
- * @return {Number}
- * @api private
- */
-
-function selectColor(namespace) {
- var hash = 0, i;
-
- for (i in namespace) {
- hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
- hash |= 0; // Convert to 32bit integer
- }
-
- return exports.colors[Math.abs(hash) % exports.colors.length];
-}
-
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
-
-function createDebug(namespace) {
-
- function debug() {
- // disabled?
- if (!debug.enabled) return;
-
- var self = debug;
-
- // set `diff` timestamp
- var curr = +new Date();
- var ms = curr - (prevTime || curr);
- self.diff = ms;
- self.prev = prevTime;
- self.curr = curr;
- prevTime = curr;
-
- // turn the `arguments` into a proper Array
- var args = new Array(arguments.length);
- for (var i = 0; i < args.length; i++) {
- args[i] = arguments[i];
- }
-
- args[0] = exports.coerce(args[0]);
-
- if ('string' !== typeof args[0]) {
- // anything else let's inspect with %O
- args.unshift('%O');
- }
-
- // apply any `formatters` transformations
- var index = 0;
- args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
- // if we encounter an escaped % then don't increase the array index
- if (match === '%%') return match;
- index++;
- var formatter = exports.formatters[format];
- if ('function' === typeof formatter) {
- var val = args[index];
- match = formatter.call(self, val);
-
- // now we need to remove `args[index]` since it's inlined in the `format`
- args.splice(index, 1);
- index--;
- }
- return match;
- });
-
- // apply env-specific formatting (colors, etc.)
- exports.formatArgs.call(self, args);
-
- var logFn = debug.log || exports.log || console.log.bind(console);
- logFn.apply(self, args);
- }
-
- debug.namespace = namespace;
- debug.enabled = exports.enabled(namespace);
- debug.useColors = exports.useColors();
- debug.color = selectColor(namespace);
-
- // env-specific initialization logic for debug instances
- if ('function' === typeof exports.init) {
- exports.init(debug);
- }
-
- return debug;
-}
-
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
-
-function enable(namespaces) {
- exports.save(namespaces);
-
- exports.names = [];
- exports.skips = [];
-
- var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
- var len = split.length;
-
- for (var i = 0; i < len; i++) {
- if (!split[i]) continue; // ignore empty strings
- namespaces = split[i].replace(/\*/g, '.*?');
- if (namespaces[0] === '-') {
- exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
- } else {
- exports.names.push(new RegExp('^' + namespaces + '$'));
- }
- }
-}
-
-/**
- * Disable debug output.
- *
- * @api public
- */
-
-function disable() {
- exports.enable('');
-}
-
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
-
-function enabled(name) {
- var i, len;
- for (i = 0, len = exports.skips.length; i < len; i++) {
- if (exports.skips[i].test(name)) {
- return false;
- }
- }
- for (i = 0, len = exports.names.length; i < len; i++) {
- if (exports.names[i].test(name)) {
- return true;
- }
- }
- return false;
-}
-
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
-
-function coerce(val) {
- if (val instanceof Error) return val.stack || val.message;
- return val;
-}
-
-},{"9":9}],3:[function(require,module,exports){
-(function (process,global){
-/*!
- * @overview es6-promise - a tiny implementation of Promises/A+.
- * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
- * @license Licensed under MIT license
- * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
- * @version 4.1.1
- */
-
-(function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.ES6Promise = factory());
-}(this, (function () { 'use strict';
-
-function objectOrFunction(x) {
- var type = typeof x;
- return x !== null && (type === 'object' || type === 'function');
-}
-
-function isFunction(x) {
- return typeof x === 'function';
-}
-
-var _isArray = undefined;
-if (Array.isArray) {
- _isArray = Array.isArray;
-} else {
- _isArray = function (x) {
- return Object.prototype.toString.call(x) === '[object Array]';
- };
-}
-
-var isArray = _isArray;
-
-var len = 0;
-var vertxNext = undefined;
-var customSchedulerFn = undefined;
-
-var asap = function asap(callback, arg) {
- queue[len] = callback;
- queue[len + 1] = arg;
- len += 2;
- if (len === 2) {
- // If len is 2, that means that we need to schedule an async flush.
- // If additional callbacks are queued before the queue is flushed, they
- // will be processed by this flush that we are scheduling.
- if (customSchedulerFn) {
- customSchedulerFn(flush);
- } else {
- scheduleFlush();
- }
- }
-};
-
-function setScheduler(scheduleFn) {
- customSchedulerFn = scheduleFn;
-}
-
-function setAsap(asapFn) {
- asap = asapFn;
-}
-
-var browserWindow = typeof window !== 'undefined' ? window : undefined;
-var browserGlobal = browserWindow || {};
-var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
-var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';
-
-// test for web worker but not in IE10
-var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
-
-// node
-function useNextTick() {
- // node version 0.10.x displays a deprecation warning when nextTick is used recursively
- // see https://github.com/cujojs/when/issues/410 for details
- return function () {
- return process.nextTick(flush);
- };
-}
-
-// vertx
-function useVertxTimer() {
- if (typeof vertxNext !== 'undefined') {
- return function () {
- vertxNext(flush);
- };
- }
-
- return useSetTimeout();
-}
-
-function useMutationObserver() {
- var iterations = 0;
- var observer = new BrowserMutationObserver(flush);
- var node = document.createTextNode('');
- observer.observe(node, { characterData: true });
-
- return function () {
- node.data = iterations = ++iterations % 2;
- };
-}
-
-// web worker
-function useMessageChannel() {
- var channel = new MessageChannel();
- channel.port1.onmessage = flush;
- return function () {
- return channel.port2.postMessage(0);
- };
-}
-
-function useSetTimeout() {
- // Store setTimeout reference so es6-promise will be unaffected by
- // other code modifying setTimeout (like sinon.useFakeTimers())
- var globalSetTimeout = setTimeout;
- return function () {
- return globalSetTimeout(flush, 1);
- };
-}
-
-var queue = new Array(1000);
-function flush() {
- for (var i = 0; i < len; i += 2) {
- var callback = queue[i];
- var arg = queue[i + 1];
-
- callback(arg);
-
- queue[i] = undefined;
- queue[i + 1] = undefined;
- }
-
- len = 0;
-}
-
-function attemptVertx() {
- try {
- var r = require;
- var vertx = r('vertx');
- vertxNext = vertx.runOnLoop || vertx.runOnContext;
- return useVertxTimer();
- } catch (e) {
- return useSetTimeout();
- }
-}
-
-var scheduleFlush = undefined;
-// Decide what async method to use to triggering processing of queued callbacks:
-if (isNode) {
- scheduleFlush = useNextTick();
-} else if (BrowserMutationObserver) {
- scheduleFlush = useMutationObserver();
-} else if (isWorker) {
- scheduleFlush = useMessageChannel();
-} else if (browserWindow === undefined && typeof require === 'function') {
- scheduleFlush = attemptVertx();
-} else {
- scheduleFlush = useSetTimeout();
-}
-
-function then(onFulfillment, onRejection) {
- var _arguments = arguments;
-
- var parent = this;
-
- var child = new this.constructor(noop);
-
- if (child[PROMISE_ID] === undefined) {
- makePromise(child);
- }
-
- var _state = parent._state;
-
- if (_state) {
- (function () {
- var callback = _arguments[_state - 1];
- asap(function () {
- return invokeCallback(_state, child, callback, parent._result);
- });
- })();
- } else {
- subscribe(parent, child, onFulfillment, onRejection);
- }
-
- return child;
-}
-
-/**
- `Promise.resolve` returns a promise that will become resolved with the
- passed `value`. It is shorthand for the following:
-
- ```javascript
- let promise = new Promise(function(resolve, reject){
- resolve(1);
- });
-
- promise.then(function(value){
- // value === 1
- });
- ```
-
- Instead of writing the above, your code now simply becomes the following:
-
- ```javascript
- let promise = Promise.resolve(1);
-
- promise.then(function(value){
- // value === 1
- });
- ```
-
- @method resolve
- @static
- @param {Any} value value that the returned promise will be resolved with
- Useful for tooling.
- @return {Promise} a promise that will become fulfilled with the given
- `value`
-*/
-function resolve$1(object) {
- /*jshint validthis:true */
- var Constructor = this;
-
- if (object && typeof object === 'object' && object.constructor === Constructor) {
- return object;
- }
-
- var promise = new Constructor(noop);
- resolve(promise, object);
- return promise;
-}
-
-var PROMISE_ID = Math.random().toString(36).substring(16);
-
-function noop() {}
-
-var PENDING = void 0;
-var FULFILLED = 1;
-var REJECTED = 2;
-
-var GET_THEN_ERROR = new ErrorObject();
-
-function selfFulfillment() {
- return new TypeError("You cannot resolve a promise with itself");
-}
-
-function cannotReturnOwn() {
- return new TypeError('A promises callback cannot return that same promise.');
-}
-
-function getThen(promise) {
- try {
- return promise.then;
- } catch (error) {
- GET_THEN_ERROR.error = error;
- return GET_THEN_ERROR;
- }
-}
-
-function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
- try {
- then$$1.call(value, fulfillmentHandler, rejectionHandler);
- } catch (e) {
- return e;
- }
-}
-
-function handleForeignThenable(promise, thenable, then$$1) {
- asap(function (promise) {
- var sealed = false;
- var error = tryThen(then$$1, thenable, function (value) {
- if (sealed) {
- return;
- }
- sealed = true;
- if (thenable !== value) {
- resolve(promise, value);
- } else {
- fulfill(promise, value);
- }
- }, function (reason) {
- if (sealed) {
- return;
- }
- sealed = true;
-
- reject(promise, reason);
- }, 'Settle: ' + (promise._label || ' unknown promise'));
-
- if (!sealed && error) {
- sealed = true;
- reject(promise, error);
- }
- }, promise);
-}
-
-function handleOwnThenable(promise, thenable) {
- if (thenable._state === FULFILLED) {
- fulfill(promise, thenable._result);
- } else if (thenable._state === REJECTED) {
- reject(promise, thenable._result);
- } else {
- subscribe(thenable, undefined, function (value) {
- return resolve(promise, value);
- }, function (reason) {
- return reject(promise, reason);
- });
- }
-}
-
-function handleMaybeThenable(promise, maybeThenable, then$$1) {
- if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
- handleOwnThenable(promise, maybeThenable);
- } else {
- if (then$$1 === GET_THEN_ERROR) {
- reject(promise, GET_THEN_ERROR.error);
- GET_THEN_ERROR.error = null;
- } else if (then$$1 === undefined) {
- fulfill(promise, maybeThenable);
- } else if (isFunction(then$$1)) {
- handleForeignThenable(promise, maybeThenable, then$$1);
- } else {
- fulfill(promise, maybeThenable);
- }
- }
-}
-
-function resolve(promise, value) {
- if (promise === value) {
- reject(promise, selfFulfillment());
- } else if (objectOrFunction(value)) {
- handleMaybeThenable(promise, value, getThen(value));
- } else {
- fulfill(promise, value);
- }
-}
-
-function publishRejection(promise) {
- if (promise._onerror) {
- promise._onerror(promise._result);
- }
-
- publish(promise);
-}
-
-function fulfill(promise, value) {
- if (promise._state !== PENDING) {
- return;
- }
-
- promise._result = value;
- promise._state = FULFILLED;
-
- if (promise._subscribers.length !== 0) {
- asap(publish, promise);
- }
-}
-
-function reject(promise, reason) {
- if (promise._state !== PENDING) {
- return;
- }
- promise._state = REJECTED;
- promise._result = reason;
-
- asap(publishRejection, promise);
-}
-
-function subscribe(parent, child, onFulfillment, onRejection) {
- var _subscribers = parent._subscribers;
- var length = _subscribers.length;
-
- parent._onerror = null;
-
- _subscribers[length] = child;
- _subscribers[length + FULFILLED] = onFulfillment;
- _subscribers[length + REJECTED] = onRejection;
-
- if (length === 0 && parent._state) {
- asap(publish, parent);
- }
-}
-
-function publish(promise) {
- var subscribers = promise._subscribers;
- var settled = promise._state;
-
- if (subscribers.length === 0) {
- return;
- }
-
- var child = undefined,
- callback = undefined,
- detail = promise._result;
-
- for (var i = 0; i < subscribers.length; i += 3) {
- child = subscribers[i];
- callback = subscribers[i + settled];
-
- if (child) {
- invokeCallback(settled, child, callback, detail);
- } else {
- callback(detail);
- }
- }
-
- promise._subscribers.length = 0;
-}
-
-function ErrorObject() {
- this.error = null;
-}
-
-var TRY_CATCH_ERROR = new ErrorObject();
-
-function tryCatch(callback, detail) {
- try {
- return callback(detail);
- } catch (e) {
- TRY_CATCH_ERROR.error = e;
- return TRY_CATCH_ERROR;
- }
-}
-
-function invokeCallback(settled, promise, callback, detail) {
- var hasCallback = isFunction(callback),
- value = undefined,
- error = undefined,
- succeeded = undefined,
- failed = undefined;
-
- if (hasCallback) {
- value = tryCatch(callback, detail);
-
- if (value === TRY_CATCH_ERROR) {
- failed = true;
- error = value.error;
- value.error = null;
- } else {
- succeeded = true;
- }
-
- if (promise === value) {
- reject(promise, cannotReturnOwn());
- return;
- }
- } else {
- value = detail;
- succeeded = true;
- }
-
- if (promise._state !== PENDING) {
- // noop
- } else if (hasCallback && succeeded) {
- resolve(promise, value);
- } else if (failed) {
- reject(promise, error);
- } else if (settled === FULFILLED) {
- fulfill(promise, value);
- } else if (settled === REJECTED) {
- reject(promise, value);
- }
-}
-
-function initializePromise(promise, resolver) {
- try {
- resolver(function resolvePromise(value) {
- resolve(promise, value);
- }, function rejectPromise(reason) {
- reject(promise, reason);
- });
- } catch (e) {
- reject(promise, e);
- }
-}
-
-var id = 0;
-function nextId() {
- return id++;
-}
-
-function makePromise(promise) {
- promise[PROMISE_ID] = id++;
- promise._state = undefined;
- promise._result = undefined;
- promise._subscribers = [];
-}
-
-function Enumerator$1(Constructor, input) {
- this._instanceConstructor = Constructor;
- this.promise = new Constructor(noop);
-
- if (!this.promise[PROMISE_ID]) {
- makePromise(this.promise);
- }
-
- if (isArray(input)) {
- this.length = input.length;
- this._remaining = input.length;
-
- this._result = new Array(this.length);
-
- if (this.length === 0) {
- fulfill(this.promise, this._result);
- } else {
- this.length = this.length || 0;
- this._enumerate(input);
- if (this._remaining === 0) {
- fulfill(this.promise, this._result);
- }
- }
- } else {
- reject(this.promise, validationError());
- }
-}
-
-function validationError() {
- return new Error('Array Methods must be provided an Array');
-}
-
-Enumerator$1.prototype._enumerate = function (input) {
- for (var i = 0; this._state === PENDING && i < input.length; i++) {
- this._eachEntry(input[i], i);
- }
-};
-
-Enumerator$1.prototype._eachEntry = function (entry, i) {
- var c = this._instanceConstructor;
- var resolve$$1 = c.resolve;
-
- if (resolve$$1 === resolve$1) {
- var _then = getThen(entry);
-
- if (_then === then && entry._state !== PENDING) {
- this._settledAt(entry._state, i, entry._result);
- } else if (typeof _then !== 'function') {
- this._remaining--;
- this._result[i] = entry;
- } else if (c === Promise$2) {
- var promise = new c(noop);
- handleMaybeThenable(promise, entry, _then);
- this._willSettleAt(promise, i);
- } else {
- this._willSettleAt(new c(function (resolve$$1) {
- return resolve$$1(entry);
- }), i);
- }
- } else {
- this._willSettleAt(resolve$$1(entry), i);
- }
-};
-
-Enumerator$1.prototype._settledAt = function (state, i, value) {
- var promise = this.promise;
-
- if (promise._state === PENDING) {
- this._remaining--;
-
- if (state === REJECTED) {
- reject(promise, value);
- } else {
- this._result[i] = value;
- }
- }
-
- if (this._remaining === 0) {
- fulfill(promise, this._result);
- }
-};
-
-Enumerator$1.prototype._willSettleAt = function (promise, i) {
- var enumerator = this;
-
- subscribe(promise, undefined, function (value) {
- return enumerator._settledAt(FULFILLED, i, value);
- }, function (reason) {
- return enumerator._settledAt(REJECTED, i, reason);
- });
-};
-
-/**
- `Promise.all` accepts an array of promises, and returns a new promise which
- is fulfilled with an array of fulfillment values for the passed promises, or
- rejected with the reason of the first passed promise to be rejected. It casts all
- elements of the passed iterable to promises as it runs this algorithm.
-
- Example:
-
- ```javascript
- let promise1 = resolve(1);
- let promise2 = resolve(2);
- let promise3 = resolve(3);
- let promises = [ promise1, promise2, promise3 ];
-
- Promise.all(promises).then(function(array){
- // The array here would be [ 1, 2, 3 ];
- });
- ```
-
- If any of the `promises` given to `all` are rejected, the first promise
- that is rejected will be given as an argument to the returned promises's
- rejection handler. For example:
-
- Example:
-
- ```javascript
- let promise1 = resolve(1);
- let promise2 = reject(new Error("2"));
- let promise3 = reject(new Error("3"));
- let promises = [ promise1, promise2, promise3 ];
-
- Promise.all(promises).then(function(array){
- // Code here never runs because there are rejected promises!
- }, function(error) {
- // error.message === "2"
- });
- ```
-
- @method all
- @static
- @param {Array} entries array of promises
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled when all `promises` have been
- fulfilled, or rejected if any of them become rejected.
- @static
-*/
-function all$1(entries) {
- return new Enumerator$1(this, entries).promise;
-}
-
-/**
- `Promise.race` returns a new promise which is settled in the same way as the
- first passed promise to settle.
-
- Example:
-
- ```javascript
- let promise1 = new Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 1');
- }, 200);
- });
-
- let promise2 = new Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 2');
- }, 100);
- });
-
- Promise.race([promise1, promise2]).then(function(result){
- // result === 'promise 2' because it was resolved before promise1
- // was resolved.
- });
- ```
-
- `Promise.race` is deterministic in that only the state of the first
- settled promise matters. For example, even if other promises given to the
- `promises` array argument are resolved, but the first settled promise has
- become rejected before the other promises became fulfilled, the returned
- promise will become rejected:
-
- ```javascript
- let promise1 = new Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 1');
- }, 200);
- });
-
- let promise2 = new Promise(function(resolve, reject){
- setTimeout(function(){
- reject(new Error('promise 2'));
- }, 100);
- });
-
- Promise.race([promise1, promise2]).then(function(result){
- // Code here never runs
- }, function(reason){
- // reason.message === 'promise 2' because promise 2 became rejected before
- // promise 1 became fulfilled
- });
- ```
-
- An example real-world use case is implementing timeouts:
-
- ```javascript
- Promise.race([ajax('foo.json'), timeout(5000)])
- ```
-
- @method race
- @static
- @param {Array} promises array of promises to observe
- Useful for tooling.
- @return {Promise} a promise which settles in the same way as the first passed
- promise to settle.
-*/
-function race$1(entries) {
- /*jshint validthis:true */
- var Constructor = this;
-
- if (!isArray(entries)) {
- return new Constructor(function (_, reject) {
- return reject(new TypeError('You must pass an array to race.'));
- });
- } else {
- return new Constructor(function (resolve, reject) {
- var length = entries.length;
- for (var i = 0; i < length; i++) {
- Constructor.resolve(entries[i]).then(resolve, reject);
- }
- });
- }
-}
-
-/**
- `Promise.reject` returns a promise rejected with the passed `reason`.
- It is shorthand for the following:
-
- ```javascript
- let promise = new Promise(function(resolve, reject){
- reject(new Error('WHOOPS'));
- });
-
- promise.then(function(value){
- // Code here doesn't run because the promise is rejected!
- }, function(reason){
- // reason.message === 'WHOOPS'
- });
- ```
-
- Instead of writing the above, your code now simply becomes the following:
-
- ```javascript
- let promise = Promise.reject(new Error('WHOOPS'));
-
- promise.then(function(value){
- // Code here doesn't run because the promise is rejected!
- }, function(reason){
- // reason.message === 'WHOOPS'
- });
- ```
-
- @method reject
- @static
- @param {Any} reason value that the returned promise will be rejected with.
- Useful for tooling.
- @return {Promise} a promise rejected with the given `reason`.
-*/
-function reject$1(reason) {
- /*jshint validthis:true */
- var Constructor = this;
- var promise = new Constructor(noop);
- reject(promise, reason);
- return promise;
-}
-
-function needsResolver() {
- throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
-}
-
-function needsNew() {
- throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
-}
-
-/**
- Promise objects represent the eventual result of an asynchronous operation. The
- primary way of interacting with a promise is through its `then` method, which
- registers callbacks to receive either a promise's eventual value or the reason
- why the promise cannot be fulfilled.
-
- Terminology
- -----------
-
- - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- - `thenable` is an object or function that defines a `then` method.
- - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- - `exception` is a value that is thrown using the throw statement.
- - `reason` is a value that indicates why a promise was rejected.
- - `settled` the final resting state of a promise, fulfilled or rejected.
-
- A promise can be in one of three states: pending, fulfilled, or rejected.
-
- Promises that are fulfilled have a fulfillment value and are in the fulfilled
- state. Promises that are rejected have a rejection reason and are in the
- rejected state. A fulfillment value is never a thenable.
-
- Promises can also be said to *resolve* a value. If this value is also a
- promise, then the original promise's settled state will match the value's
- settled state. So a promise that *resolves* a promise that rejects will
- itself reject, and a promise that *resolves* a promise that fulfills will
- itself fulfill.
-
-
- Basic Usage:
- ------------
-
- ```js
- let promise = new Promise(function(resolve, reject) {
- // on success
- resolve(value);
-
- // on failure
- reject(reason);
- });
-
- promise.then(function(value) {
- // on fulfillment
- }, function(reason) {
- // on rejection
- });
- ```
-
- Advanced Usage:
- ---------------
-
- Promises shine when abstracting away asynchronous interactions such as
- `XMLHttpRequest`s.
-
- ```js
- function getJSON(url) {
- return new Promise(function(resolve, reject){
- let xhr = new XMLHttpRequest();
-
- xhr.open('GET', url);
- xhr.onreadystatechange = handler;
- xhr.responseType = 'json';
- xhr.setRequestHeader('Accept', 'application/json');
- xhr.send();
-
- function handler() {
- if (this.readyState === this.DONE) {
- if (this.status === 200) {
- resolve(this.response);
- } else {
- reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
- }
- }
- };
- });
- }
-
- getJSON('/posts.json').then(function(json) {
- // on fulfillment
- }, function(reason) {
- // on rejection
- });
- ```
-
- Unlike callbacks, promises are great composable primitives.
-
- ```js
- Promise.all([
- getJSON('/posts'),
- getJSON('/comments')
- ]).then(function(values){
- values[0] // => postsJSON
- values[1] // => commentsJSON
-
- return values;
- });
- ```
-
- @class Promise
- @param {function} resolver
- Useful for tooling.
- @constructor
-*/
-function Promise$2(resolver) {
- this[PROMISE_ID] = nextId();
- this._result = this._state = undefined;
- this._subscribers = [];
-
- if (noop !== resolver) {
- typeof resolver !== 'function' && needsResolver();
- this instanceof Promise$2 ? initializePromise(this, resolver) : needsNew();
- }
-}
-
-Promise$2.all = all$1;
-Promise$2.race = race$1;
-Promise$2.resolve = resolve$1;
-Promise$2.reject = reject$1;
-Promise$2._setScheduler = setScheduler;
-Promise$2._setAsap = setAsap;
-Promise$2._asap = asap;
-
-Promise$2.prototype = {
- constructor: Promise$2,
-
- /**
- The primary way of interacting with a promise is through its `then` method,
- which registers callbacks to receive either a promise's eventual value or the
- reason why the promise cannot be fulfilled.
-
- ```js
- findUser().then(function(user){
- // user is available
- }, function(reason){
- // user is unavailable, and you are given the reason why
- });
- ```
-
- Chaining
- --------
-
- The return value of `then` is itself a promise. This second, 'downstream'
- promise is resolved with the return value of the first promise's fulfillment
- or rejection handler, or rejected if the handler throws an exception.
-
- ```js
- findUser().then(function (user) {
- return user.name;
- }, function (reason) {
- return 'default name';
- }).then(function (userName) {
- // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
- // will be `'default name'`
- });
-
- findUser().then(function (user) {
- throw new Error('Found user, but still unhappy');
- }, function (reason) {
- throw new Error('`findUser` rejected and we're unhappy');
- }).then(function (value) {
- // never reached
- }, function (reason) {
- // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
- // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
- });
- ```
- If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
-
- ```js
- findUser().then(function (user) {
- throw new PedagogicalException('Upstream error');
- }).then(function (value) {
- // never reached
- }).then(function (value) {
- // never reached
- }, function (reason) {
- // The `PedgagocialException` is propagated all the way down to here
- });
- ```
-
- Assimilation
- ------------
-
- Sometimes the value you want to propagate to a downstream promise can only be
- retrieved asynchronously. This can be achieved by returning a promise in the
- fulfillment or rejection handler. The downstream promise will then be pending
- until the returned promise is settled. This is called *assimilation*.
-
- ```js
- findUser().then(function (user) {
- return findCommentsByAuthor(user);
- }).then(function (comments) {
- // The user's comments are now available
- });
- ```
-
- If the assimliated promise rejects, then the downstream promise will also reject.
-
- ```js
- findUser().then(function (user) {
- return findCommentsByAuthor(user);
- }).then(function (comments) {
- // If `findCommentsByAuthor` fulfills, we'll have the value here
- }, function (reason) {
- // If `findCommentsByAuthor` rejects, we'll have the reason here
- });
- ```
-
- Simple Example
- --------------
-
- Synchronous Example
-
- ```javascript
- let result;
-
- try {
- result = findResult();
- // success
- } catch(reason) {
- // failure
- }
- ```
-
- Errback Example
-
- ```js
- findResult(function(result, err){
- if (err) {
- // failure
- } else {
- // success
- }
- });
- ```
-
- Promise Example;
-
- ```javascript
- findResult().then(function(result){
- // success
- }, function(reason){
- // failure
- });
- ```
-
- Advanced Example
- --------------
-
- Synchronous Example
-
- ```javascript
- let author, books;
-
- try {
- author = findAuthor();
- books = findBooksByAuthor(author);
- // success
- } catch(reason) {
- // failure
- }
- ```
-
- Errback Example
-
- ```js
-
- function foundBooks(books) {
-
- }
-
- function failure(reason) {
-
- }
-
- findAuthor(function(author, err){
- if (err) {
- failure(err);
- // failure
- } else {
- try {
- findBoooksByAuthor(author, function(books, err) {
- if (err) {
- failure(err);
- } else {
- try {
- foundBooks(books);
- } catch(reason) {
- failure(reason);
- }
- }
- });
- } catch(error) {
- failure(err);
- }
- // success
- }
- });
- ```
-
- Promise Example;
-
- ```javascript
- findAuthor().
- then(findBooksByAuthor).
- then(function(books){
- // found books
- }).catch(function(reason){
- // something went wrong
- });
- ```
-
- @method then
- @param {Function} onFulfilled
- @param {Function} onRejected
- Useful for tooling.
- @return {Promise}
- */
- then: then,
-
- /**
- `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
- as the catch block of a try/catch statement.
-
- ```js
- function findAuthor(){
- throw new Error('couldn't find that author');
- }
-
- // synchronous
- try {
- findAuthor();
- } catch(reason) {
- // something went wrong
- }
-
- // async with promises
- findAuthor().catch(function(reason){
- // something went wrong
- });
- ```
-
- @method catch
- @param {Function} onRejection
- Useful for tooling.
- @return {Promise}
- */
- 'catch': function _catch(onRejection) {
- return this.then(null, onRejection);
- }
-};
-
-/*global self*/
-function polyfill$1() {
- var local = undefined;
-
- if (typeof global !== 'undefined') {
- local = global;
- } else if (typeof self !== 'undefined') {
- local = self;
- } else {
- try {
- local = Function('return this')();
- } catch (e) {
- throw new Error('polyfill failed because global object is unavailable in this environment');
- }
- }
-
- var P = local.Promise;
-
- if (P) {
- var promiseToString = null;
- try {
- promiseToString = Object.prototype.toString.call(P.resolve());
- } catch (e) {
- // silently ignored
- }
-
- if (promiseToString === '[object Promise]' && !P.cast) {
- return;
- }
- }
-
- local.Promise = Promise$2;
-}
-
-// Strange compat..
-Promise$2.polyfill = polyfill$1;
-Promise$2.Promise = Promise$2;
-
-return Promise$2;
-
-})));
-
-
-
-}).call(this,require(12),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"12":12}],4:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
- this._events = this._events || {};
- this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
- if (!isNumber(n) || n < 0 || isNaN(n))
- throw TypeError('n must be a positive number');
- this._maxListeners = n;
- return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
- var er, handler, len, args, i, listeners;
-
- if (!this._events)
- this._events = {};
-
- // If there is no 'error' event listener then throw.
- if (type === 'error') {
- if (!this._events.error ||
- (isObject(this._events.error) && !this._events.error.length)) {
- er = arguments[1];
- if (er instanceof Error) {
- throw er; // Unhandled 'error' event
- } else {
- // At least give some kind of context to the user
- var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
- err.context = er;
- throw err;
- }
- }
- }
-
- handler = this._events[type];
-
- if (isUndefined(handler))
- return false;
-
- if (isFunction(handler)) {
- switch (arguments.length) {
- // fast cases
- case 1:
- handler.call(this);
- break;
- case 2:
- handler.call(this, arguments[1]);
- break;
- case 3:
- handler.call(this, arguments[1], arguments[2]);
- break;
- // slower
- default:
- args = Array.prototype.slice.call(arguments, 1);
- handler.apply(this, args);
- }
- } else if (isObject(handler)) {
- args = Array.prototype.slice.call(arguments, 1);
- listeners = handler.slice();
- len = listeners.length;
- for (i = 0; i < len; i++)
- listeners[i].apply(this, args);
- }
-
- return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
- var m;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events)
- this._events = {};
-
- // To avoid recursion in the case that type === "newListener"! Before
- // adding it to the listeners, first emit "newListener".
- if (this._events.newListener)
- this.emit('newListener', type,
- isFunction(listener.listener) ?
- listener.listener : listener);
-
- if (!this._events[type])
- // Optimize the case of one listener. Don't need the extra array object.
- this._events[type] = listener;
- else if (isObject(this._events[type]))
- // If we've already got an array, just append.
- this._events[type].push(listener);
- else
- // Adding the second element, need to change to array.
- this._events[type] = [this._events[type], listener];
-
- // Check for listener leak
- if (isObject(this._events[type]) && !this._events[type].warned) {
- if (!isUndefined(this._maxListeners)) {
- m = this._maxListeners;
- } else {
- m = EventEmitter.defaultMaxListeners;
- }
-
- if (m && m > 0 && this._events[type].length > m) {
- this._events[type].warned = true;
- console.error('(node) warning: possible EventEmitter memory ' +
- 'leak detected. %d listeners added. ' +
- 'Use emitter.setMaxListeners() to increase limit.',
- this._events[type].length);
- if (typeof console.trace === 'function') {
- // not supported in IE 10
- console.trace();
- }
- }
- }
-
- return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- var fired = false;
-
- function g() {
- this.removeListener(type, g);
-
- if (!fired) {
- fired = true;
- listener.apply(this, arguments);
- }
- }
-
- g.listener = listener;
- this.on(type, g);
-
- return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
- var list, position, length, i;
-
- if (!isFunction(listener))
- throw TypeError('listener must be a function');
-
- if (!this._events || !this._events[type])
- return this;
-
- list = this._events[type];
- length = list.length;
- position = -1;
-
- if (list === listener ||
- (isFunction(list.listener) && list.listener === listener)) {
- delete this._events[type];
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
-
- } else if (isObject(list)) {
- for (i = length; i-- > 0;) {
- if (list[i] === listener ||
- (list[i].listener && list[i].listener === listener)) {
- position = i;
- break;
- }
- }
-
- if (position < 0)
- return this;
-
- if (list.length === 1) {
- list.length = 0;
- delete this._events[type];
- } else {
- list.splice(position, 1);
- }
-
- if (this._events.removeListener)
- this.emit('removeListener', type, listener);
- }
-
- return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
- var key, listeners;
-
- if (!this._events)
- return this;
-
- // not listening for removeListener, no need to emit
- if (!this._events.removeListener) {
- if (arguments.length === 0)
- this._events = {};
- else if (this._events[type])
- delete this._events[type];
- return this;
- }
-
- // emit removeListener for all listeners on all events
- if (arguments.length === 0) {
- for (key in this._events) {
- if (key === 'removeListener') continue;
- this.removeAllListeners(key);
- }
- this.removeAllListeners('removeListener');
- this._events = {};
- return this;
- }
-
- listeners = this._events[type];
-
- if (isFunction(listeners)) {
- this.removeListener(type, listeners);
- } else if (listeners) {
- // LIFO order
- while (listeners.length)
- this.removeListener(type, listeners[listeners.length - 1]);
- }
- delete this._events[type];
-
- return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
- var ret;
- if (!this._events || !this._events[type])
- ret = [];
- else if (isFunction(this._events[type]))
- ret = [this._events[type]];
- else
- ret = this._events[type].slice();
- return ret;
-};
-
-EventEmitter.prototype.listenerCount = function(type) {
- if (this._events) {
- var evlistener = this._events[type];
-
- if (isFunction(evlistener))
- return 1;
- else if (evlistener)
- return evlistener.length;
- }
- return 0;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
- return emitter.listenerCount(type);
-};
-
-function isFunction(arg) {
- return typeof arg === 'function';
-}
-
-function isNumber(arg) {
- return typeof arg === 'number';
-}
-
-function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
- return arg === void 0;
-}
-
-},{}],5:[function(require,module,exports){
-
-var hasOwn = Object.prototype.hasOwnProperty;
-var toString = Object.prototype.toString;
-
-module.exports = function forEach (obj, fn, ctx) {
- if (toString.call(fn) !== '[object Function]') {
- throw new TypeError('iterator must be a function');
- }
- var l = obj.length;
- if (l === +l) {
- for (var i = 0; i < l; i++) {
- fn.call(ctx, obj[i], i, obj);
- }
- } else {
- for (var k in obj) {
- if (hasOwn.call(obj, k)) {
- fn.call(ctx, obj[k], k, obj);
- }
- }
- }
-};
-
-
-},{}],6:[function(require,module,exports){
-(function (global){
-var win;
-
-if (typeof window !== "undefined") {
- win = window;
-} else if (typeof global !== "undefined") {
- win = global;
-} else if (typeof self !== "undefined"){
- win = self;
-} else {
- win = {};
-}
-
-module.exports = win;
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],7:[function(require,module,exports){
-if (typeof Object.create === 'function') {
- // implementation from standard node.js 'util' module
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- };
-} else {
- // old school shim for old browsers
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- var TempCtor = function () {}
- TempCtor.prototype = superCtor.prototype
- ctor.prototype = new TempCtor()
- ctor.prototype.constructor = ctor
- }
-}
-
-},{}],8:[function(require,module,exports){
-var toString = {}.toString;
-
-module.exports = Array.isArray || function (arr) {
- return toString.call(arr) == '[object Array]';
-};
-
-},{}],9:[function(require,module,exports){
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- * - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} [options]
- * @throws {Error} throw an error if val is not a non-empty string or a number
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options) {
- options = options || {};
- var type = typeof val;
- if (type === 'string' && val.length > 0) {
- return parse(val);
- } else if (type === 'number' && isNaN(val) === false) {
- return options.long ? fmtLong(val) : fmtShort(val);
- }
- throw new Error(
- 'val is not a non-empty string or a valid number. val=' +
- JSON.stringify(val)
- );
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
- str = String(str);
- if (str.length > 100) {
- return;
- }
- var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
- str
- );
- if (!match) {
- return;
- }
- var n = parseFloat(match[1]);
- var type = (match[2] || 'ms').toLowerCase();
- switch (type) {
- case 'years':
- case 'year':
- case 'yrs':
- case 'yr':
- case 'y':
- return n * y;
- case 'days':
- case 'day':
- case 'd':
- return n * d;
- case 'hours':
- case 'hour':
- case 'hrs':
- case 'hr':
- case 'h':
- return n * h;
- case 'minutes':
- case 'minute':
- case 'mins':
- case 'min':
- case 'm':
- return n * m;
- case 'seconds':
- case 'second':
- case 'secs':
- case 'sec':
- case 's':
- return n * s;
- case 'milliseconds':
- case 'millisecond':
- case 'msecs':
- case 'msec':
- case 'ms':
- return n;
- default:
- return undefined;
- }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtShort(ms) {
- if (ms >= d) {
- return Math.round(ms / d) + 'd';
- }
- if (ms >= h) {
- return Math.round(ms / h) + 'h';
- }
- if (ms >= m) {
- return Math.round(ms / m) + 'm';
- }
- if (ms >= s) {
- return Math.round(ms / s) + 's';
- }
- return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtLong(ms) {
- return plural(ms, d, 'day') ||
- plural(ms, h, 'hour') ||
- plural(ms, m, 'minute') ||
- plural(ms, s, 'second') ||
- ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
- if (ms < n) {
- return;
- }
- if (ms < n * 1.5) {
- return Math.floor(ms / n) + ' ' + name;
- }
- return Math.ceil(ms / n) + ' ' + name + 's';
-}
-
-},{}],10:[function(require,module,exports){
-'use strict';
-
-// modified from https://github.com/es-shims/es5-shim
-var has = Object.prototype.hasOwnProperty;
-var toStr = Object.prototype.toString;
-var slice = Array.prototype.slice;
-var isArgs = require(11);
-var isEnumerable = Object.prototype.propertyIsEnumerable;
-var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
-var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
-var dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
-];
-var equalsConstructorPrototype = function (o) {
- var ctor = o.constructor;
- return ctor && ctor.prototype === o;
-};
-var excludedKeys = {
- $console: true,
- $external: true,
- $frame: true,
- $frameElement: true,
- $frames: true,
- $innerHeight: true,
- $innerWidth: true,
- $outerHeight: true,
- $outerWidth: true,
- $pageXOffset: true,
- $pageYOffset: true,
- $parent: true,
- $scrollLeft: true,
- $scrollTop: true,
- $scrollX: true,
- $scrollY: true,
- $self: true,
- $webkitIndexedDB: true,
- $webkitStorageInfo: true,
- $window: true
-};
-var hasAutomationEqualityBug = (function () {
- /* global window */
- if (typeof window === 'undefined') { return false; }
- for (var k in window) {
- try {
- if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
- try {
- equalsConstructorPrototype(window[k]);
- } catch (e) {
- return true;
- }
- }
- } catch (e) {
- return true;
- }
- }
- return false;
-}());
-var equalsConstructorPrototypeIfNotBuggy = function (o) {
- /* global window */
- if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
- return equalsConstructorPrototype(o);
- }
- try {
- return equalsConstructorPrototype(o);
- } catch (e) {
- return false;
- }
-};
-
-var keysShim = function keys(object) {
- var isObject = object !== null && typeof object === 'object';
- var isFunction = toStr.call(object) === '[object Function]';
- var isArguments = isArgs(object);
- var isString = isObject && toStr.call(object) === '[object String]';
- var theKeys = [];
-
- if (!isObject && !isFunction && !isArguments) {
- throw new TypeError('Object.keys called on a non-object');
- }
-
- var skipProto = hasProtoEnumBug && isFunction;
- if (isString && object.length > 0 && !has.call(object, 0)) {
- for (var i = 0; i < object.length; ++i) {
- theKeys.push(String(i));
- }
- }
-
- if (isArguments && object.length > 0) {
- for (var j = 0; j < object.length; ++j) {
- theKeys.push(String(j));
- }
- } else {
- for (var name in object) {
- if (!(skipProto && name === 'prototype') && has.call(object, name)) {
- theKeys.push(String(name));
- }
- }
- }
-
- if (hasDontEnumBug) {
- var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
-
- for (var k = 0; k < dontEnums.length; ++k) {
- if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
- theKeys.push(dontEnums[k]);
- }
- }
- }
- return theKeys;
-};
-
-keysShim.shim = function shimObjectKeys() {
- if (Object.keys) {
- var keysWorksWithArguments = (function () {
- // Safari 5.0 bug
- return (Object.keys(arguments) || '').length === 2;
- }(1, 2));
- if (!keysWorksWithArguments) {
- var originalKeys = Object.keys;
- Object.keys = function keys(object) {
- if (isArgs(object)) {
- return originalKeys(slice.call(object));
- } else {
- return originalKeys(object);
- }
- };
- }
- } else {
- Object.keys = keysShim;
- }
- return Object.keys || keysShim;
-};
-
-module.exports = keysShim;
-
-},{"11":11}],11:[function(require,module,exports){
-'use strict';
-
-var toStr = Object.prototype.toString;
-
-module.exports = function isArguments(value) {
- var str = toStr.call(value);
- var isArgs = str === '[object Arguments]';
- if (!isArgs) {
- isArgs = str !== '[object Array]' &&
- value !== null &&
- typeof value === 'object' &&
- typeof value.length === 'number' &&
- value.length >= 0 &&
- toStr.call(value.callee) === '[object Function]';
- }
- return isArgs;
-};
-
-},{}],12:[function(require,module,exports){
-// shim for using process in browser
-var process = module.exports = {};
-
-// cached from whatever global is present so that test runners that stub it
-// don't break things. But we need to wrap it in a try catch in case it is
-// wrapped in strict mode code which doesn't define any globals. It's inside a
-// function because try/catches deoptimize in certain engines.
-
-var cachedSetTimeout;
-var cachedClearTimeout;
-
-function defaultSetTimout() {
- throw new Error('setTimeout has not been defined');
-}
-function defaultClearTimeout () {
- throw new Error('clearTimeout has not been defined');
-}
-(function () {
- try {
- if (typeof setTimeout === 'function') {
- cachedSetTimeout = setTimeout;
- } else {
- cachedSetTimeout = defaultSetTimout;
- }
- } catch (e) {
- cachedSetTimeout = defaultSetTimout;
- }
- try {
- if (typeof clearTimeout === 'function') {
- cachedClearTimeout = clearTimeout;
- } else {
- cachedClearTimeout = defaultClearTimeout;
- }
- } catch (e) {
- cachedClearTimeout = defaultClearTimeout;
- }
-} ())
-function runTimeout(fun) {
- if (cachedSetTimeout === setTimeout) {
- //normal enviroments in sane situations
- return setTimeout(fun, 0);
- }
- // if setTimeout wasn't available but was latter defined
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
- cachedSetTimeout = setTimeout;
- return setTimeout(fun, 0);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedSetTimeout(fun, 0);
- } catch(e){
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedSetTimeout.call(null, fun, 0);
- } catch(e){
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
- return cachedSetTimeout.call(this, fun, 0);
- }
- }
-
-
-}
-function runClearTimeout(marker) {
- if (cachedClearTimeout === clearTimeout) {
- //normal enviroments in sane situations
- return clearTimeout(marker);
- }
- // if clearTimeout wasn't available but was latter defined
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
- cachedClearTimeout = clearTimeout;
- return clearTimeout(marker);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedClearTimeout(marker);
- } catch (e){
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedClearTimeout.call(null, marker);
- } catch (e){
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
- return cachedClearTimeout.call(this, marker);
- }
- }
-
-
-
-}
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
-
-function cleanUpNextTick() {
- if (!draining || !currentQueue) {
- return;
- }
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
-}
-
-function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = runTimeout(cleanUpNextTick);
- draining = true;
-
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- if (currentQueue) {
- currentQueue[queueIndex].run();
- }
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- runClearTimeout(timeout);
-}
-
-process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- runTimeout(drainQueue);
- }
-};
-
-// v8 likes predictible objects
-function Item(fun, array) {
- this.fun = fun;
- this.array = array;
-}
-Item.prototype.run = function () {
- this.fun.apply(null, this.array);
-};
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-process.version = ''; // empty string to avoid regexp issues
-process.versions = {};
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-
-process.binding = function (name) {
- throw new Error('process.binding is not supported');
-};
-
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
-};
-process.umask = function() { return 0; };
-
-},{}],13:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'use strict';
-
-// If obj.hasOwnProperty has been overridden, then calling
-// obj.hasOwnProperty(prop) will break.
-// See: https://github.com/joyent/node/issues/1707
-function hasOwnProperty(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
-}
-
-module.exports = function(qs, sep, eq, options) {
- sep = sep || '&';
- eq = eq || '=';
- var obj = {};
-
- if (typeof qs !== 'string' || qs.length === 0) {
- return obj;
- }
-
- var regexp = /\+/g;
- qs = qs.split(sep);
-
- var maxKeys = 1000;
- if (options && typeof options.maxKeys === 'number') {
- maxKeys = options.maxKeys;
- }
-
- var len = qs.length;
- // maxKeys <= 0 means that we should not limit keys count
- if (maxKeys > 0 && len > maxKeys) {
- len = maxKeys;
- }
-
- for (var i = 0; i < len; ++i) {
- var x = qs[i].replace(regexp, '%20'),
- idx = x.indexOf(eq),
- kstr, vstr, k, v;
-
- if (idx >= 0) {
- kstr = x.substr(0, idx);
- vstr = x.substr(idx + 1);
- } else {
- kstr = x;
- vstr = '';
- }
-
- k = decodeURIComponent(kstr);
- v = decodeURIComponent(vstr);
-
- if (!hasOwnProperty(obj, k)) {
- obj[k] = v;
- } else if (isArray(obj[k])) {
- obj[k].push(v);
- } else {
- obj[k] = [obj[k], v];
- }
- }
-
- return obj;
-};
-
-var isArray = Array.isArray || function (xs) {
- return Object.prototype.toString.call(xs) === '[object Array]';
-};
-
-},{}],14:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-'use strict';
-
-var stringifyPrimitive = function(v) {
- switch (typeof v) {
- case 'string':
- return v;
-
- case 'boolean':
- return v ? 'true' : 'false';
-
- case 'number':
- return isFinite(v) ? v : '';
-
- default:
- return '';
- }
-};
-
-module.exports = function(obj, sep, eq, name) {
- sep = sep || '&';
- eq = eq || '=';
- if (obj === null) {
- obj = undefined;
- }
-
- if (typeof obj === 'object') {
- return map(objectKeys(obj), function(k) {
- var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
- if (isArray(obj[k])) {
- return map(obj[k], function(v) {
- return ks + encodeURIComponent(stringifyPrimitive(v));
- }).join(sep);
- } else {
- return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
- }
- }).join(sep);
-
- }
-
- if (!name) return '';
- return encodeURIComponent(stringifyPrimitive(name)) + eq +
- encodeURIComponent(stringifyPrimitive(obj));
-};
-
-var isArray = Array.isArray || function (xs) {
- return Object.prototype.toString.call(xs) === '[object Array]';
-};
-
-function map (xs, f) {
- if (xs.map) return xs.map(f);
- var res = [];
- for (var i = 0; i < xs.length; i++) {
- res.push(f(xs[i], i));
- }
- return res;
-}
-
-var objectKeys = Object.keys || function (obj) {
- var res = [];
- for (var key in obj) {
- if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
- }
- return res;
-};
-
-},{}],15:[function(require,module,exports){
-'use strict';
-
-exports.decode = exports.parse = require(13);
-exports.encode = exports.stringify = require(14);
-
-},{"13":13,"14":14}],16:[function(require,module,exports){
-module.exports = AlgoliaSearch;
-
-var Index = require(18);
-var deprecate = require(29);
-var deprecatedMessage = require(30);
-var AlgoliaSearchCore = require(17);
-var inherits = require(7);
-var errors = require(31);
-
-function AlgoliaSearch() {
- AlgoliaSearchCore.apply(this, arguments);
-}
-
-inherits(AlgoliaSearch, AlgoliaSearchCore);
-
-/*
- * Delete an index
- *
- * @param indexName the name of index to delete
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer that contains the task ID
- */
-AlgoliaSearch.prototype.deleteIndex = function(indexName, callback) {
- return this._jsonRequest({
- method: 'DELETE',
- url: '/1/indexes/' + encodeURIComponent(indexName),
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Move an existing index.
- * @param srcIndexName the name of index to copy.
- * @param dstIndexName the new index name that will contains a copy of
- * srcIndexName (destination will be overriten if it already exist).
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer that contains the task ID
- */
-AlgoliaSearch.prototype.moveIndex = function(srcIndexName, dstIndexName, callback) {
- var postObj = {
- operation: 'move', destination: dstIndexName
- };
- return this._jsonRequest({
- method: 'POST',
- url: '/1/indexes/' + encodeURIComponent(srcIndexName) + '/operation',
- body: postObj,
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Copy an existing index.
- * @param srcIndexName the name of index to copy.
- * @param dstIndexName the new index name that will contains a copy
- * of srcIndexName (destination will be overriten if it already exist).
- * @param scope an array of scopes to copy: ['settings', 'synonyms', 'rules']
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer that contains the task ID
- */
-AlgoliaSearch.prototype.copyIndex = function(srcIndexName, dstIndexName, scopeOrCallback, _callback) {
- var postObj = {
- operation: 'copy',
- destination: dstIndexName
- };
- var callback = _callback;
- if (typeof scopeOrCallback === 'function') {
- // oops, old behaviour of third argument being a function
- callback = scopeOrCallback;
- } else if (Array.isArray(scopeOrCallback) && scopeOrCallback.length > 0) {
- postObj.scope = scopeOrCallback;
- } else if (typeof scopeOrCallback !== 'undefined') {
- throw new Error('the scope given to `copyIndex` was not an array with settings, synonyms or rules');
- }
- return this._jsonRequest({
- method: 'POST',
- url: '/1/indexes/' + encodeURIComponent(srcIndexName) + '/operation',
- body: postObj,
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Return last log entries.
- * @param offset Specify the first entry to retrieve (0-based, 0 is the most recent log entry).
- * @param length Specify the maximum number of entries to retrieve starting
- * at offset. Maximum allowed value: 1000.
- * @param type Specify the maximum number of entries to retrieve starting
- * at offset. Maximum allowed value: 1000.
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer that contains the task ID
- */
-AlgoliaSearch.prototype.getLogs = function(offset, length, callback) {
- var clone = require(27);
- var params = {};
- if (typeof offset === 'object') {
- // getLogs(params)
- params = clone(offset);
- callback = length;
- } else if (arguments.length === 0 || typeof offset === 'function') {
- // getLogs([cb])
- callback = offset;
- } else if (arguments.length === 1 || typeof length === 'function') {
- // getLogs(1, [cb)]
- callback = length;
- params.offset = offset;
- } else {
- // getLogs(1, 2, [cb])
- params.offset = offset;
- params.length = length;
- }
-
- if (params.offset === undefined) params.offset = 0;
- if (params.length === undefined) params.length = 10;
-
- return this._jsonRequest({
- method: 'GET',
- url: '/1/logs?' + this._getSearchParams(params, ''),
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
- * List all existing indexes (paginated)
- *
- * @param page The page to retrieve, starting at 0.
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer with index list
- */
-AlgoliaSearch.prototype.listIndexes = function(page, callback) {
- var params = '';
-
- if (page === undefined || typeof page === 'function') {
- callback = page;
- } else {
- params = '?page=' + page;
- }
-
- return this._jsonRequest({
- method: 'GET',
- url: '/1/indexes' + params,
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
- * Get the index object initialized
- *
- * @param indexName the name of index
- * @param callback the result callback with one argument (the Index instance)
- */
-AlgoliaSearch.prototype.initIndex = function(indexName) {
- return new Index(this, indexName);
-};
-
-AlgoliaSearch.prototype.initAnalytics = function(opts) {
- // the actual require must be inside the function, when put outside then you have a cyclic dependency
- // not well resolved that ends up making the main "./index.js" (main module, the agloliasearch function)
- // export an object instead of a function
- // Other workarounds:
- // - rewrite the lib in ES6, cyclic dependencies may be better supported
- // - move initAnalytics to a property on the main module (algoliasearch.initAnalytics),
- // same as places.
- // The current API was made mostly to mimic the one made in PHP
- var createAnalyticsClient = require(28);
- return createAnalyticsClient(this.applicationID, this.apiKey, opts);
-};
-
-/*
- * @deprecated use client.listApiKeys
- */
-AlgoliaSearch.prototype.listUserKeys = deprecate(function(callback) {
- return this.listApiKeys(callback);
-}, deprecatedMessage('client.listUserKeys()', 'client.listApiKeys()'));
-
-/*
- * List all existing api keys with their associated ACLs
- *
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer with api keys list
- */
-AlgoliaSearch.prototype.listApiKeys = function(callback) {
- return this._jsonRequest({
- method: 'GET',
- url: '/1/keys',
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
- * @deprecated see client.getApiKey
- */
-AlgoliaSearch.prototype.getUserKeyACL = deprecate(function(key, callback) {
- return this.getApiKey(key, callback);
-}, deprecatedMessage('client.getUserKeyACL()', 'client.getApiKey()'));
-
-/*
- * Get an API key
- *
- * @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
- */
-AlgoliaSearch.prototype.getApiKey = function(key, callback) {
- return this._jsonRequest({
- method: 'GET',
- url: '/1/keys/' + key,
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
- * @deprecated see client.deleteApiKey
- */
-AlgoliaSearch.prototype.deleteUserKey = deprecate(function(key, callback) {
- return this.deleteApiKey(key, callback);
-}, deprecatedMessage('client.deleteUserKey()', 'client.deleteApiKey()'));
-
-/*
- * Delete an existing API key
- * @param key
- * @param callback the result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer with the date of deletion
- */
-AlgoliaSearch.prototype.deleteApiKey = function(key, callback) {
- return this._jsonRequest({
- method: 'DELETE',
- url: '/1/keys/' + key,
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Restore a deleted API key
- *
- * @param {String} key - The key to restore
- * @param {Function} callback - The result callback called with two arguments
- * error: null or Error('message')
- * content: the server answer with the restored API key
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.restoreApiKey('APIKEY')
- * @see {@link https://www.algolia.com/doc/rest-api/search/#restore-api-key|Algolia REST API Documentation}
- */
-AlgoliaSearch.prototype.restoreApiKey = function(key, callback) {
- return this._jsonRequest({
- method: 'POST',
- url: '/1/keys/' + key + '/restore',
- hostType: 'write',
- callback: callback
- });
-};
-
-/*
- @deprecated see client.addApiKey
- */
-AlgoliaSearch.prototype.addUserKey = deprecate(function(acls, params, callback) {
- return this.addApiKey(acls, params, callback);
-}, deprecatedMessage('client.addUserKey()', 'client.addApiKey()'));
-
-/*
- * Add a new global API key
- *
- * @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.indexes - Allowed targeted indexes for this key
- * @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
- * client.addApiKey(['search'], {
- * validity: 300,
- * maxQueriesPerIPPerHour: 2000,
- * maxHitsPerQuery: 3,
- * indexes: ['fruits'],
- * description: 'Eat three fruits',
- * referers: ['*.algolia.com'],
- * queryParameters: {
- * tagFilters: ['public'],
- * }
- * })
- * @see {@link https://www.algolia.com/doc/rest_api#AddKey|Algolia REST API Documentation}
- */
-AlgoliaSearch.prototype.addApiKey = function(acls, params, callback) {
- var isArray = require(8);
- var usage = 'Usage: client.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.indexes = params.indexes;
- postObj.description = params.description;
-
- if (params.queryParameters) {
- postObj.queryParameters = this._getSearchParams(params.queryParameters, '');
- }
-
- postObj.referers = params.referers;
- }
-
- return this._jsonRequest({
- method: 'POST',
- url: '/1/keys',
- body: postObj,
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * @deprecated Please use client.addApiKey()
- */
-AlgoliaSearch.prototype.addUserKeyWithValidity = deprecate(function(acls, params, callback) {
- return this.addApiKey(acls, params, callback);
-}, deprecatedMessage('client.addUserKeyWithValidity()', 'client.addApiKey()'));
-
-/**
- * @deprecated Please use client.updateApiKey()
- */
-AlgoliaSearch.prototype.updateUserKey = deprecate(function(key, acls, params, callback) {
- return this.updateApiKey(key, acls, params, callback);
-}, deprecatedMessage('client.updateUserKey()', 'client.updateApiKey()'));
-
-/**
- * Update an existing API key
- * @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.indexes - Allowed targeted indexes for this key
- * @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 modified API key
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.updateApiKey('APIKEY', ['search'], {
- * validity: 300,
- * maxQueriesPerIPPerHour: 2000,
- * maxHitsPerQuery: 3,
- * indexes: ['fruits'],
- * description: 'Eat three fruits',
- * referers: ['*.algolia.com'],
- * queryParameters: {
- * tagFilters: ['public'],
- * }
- * })
- * @see {@link https://www.algolia.com/doc/rest_api#UpdateIndexKey|Algolia REST API Documentation}
- */
-AlgoliaSearch.prototype.updateApiKey = function(key, acls, params, callback) {
- var isArray = require(8);
- var usage = 'Usage: client.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.indexes = params.indexes;
- putObj.description = params.description;
-
- if (params.queryParameters) {
- putObj.queryParameters = this._getSearchParams(params.queryParameters, '');
- }
-
- putObj.referers = params.referers;
- }
-
- return this._jsonRequest({
- method: 'PUT',
- url: '/1/keys/' + key,
- body: putObj,
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Initialize a new batch of search queries
- * @deprecated use client.search()
- */
-AlgoliaSearch.prototype.startQueriesBatch = deprecate(function startQueriesBatchDeprecated() {
- this._batch = [];
-}, deprecatedMessage('client.startQueriesBatch()', 'client.search()'));
-
-/**
- * Add a search query in the batch
- * @deprecated use client.search()
- */
-AlgoliaSearch.prototype.addQueryInBatch = deprecate(function addQueryInBatchDeprecated(indexName, query, args) {
- this._batch.push({
- indexName: indexName,
- query: query,
- params: args
- });
-}, deprecatedMessage('client.addQueryInBatch()', 'client.search()'));
-
-/**
- * Launch the batch of queries using XMLHttpRequest.
- * @deprecated use client.search()
- */
-AlgoliaSearch.prototype.sendQueriesBatch = deprecate(function sendQueriesBatchDeprecated(callback) {
- return this.search(this._batch, callback);
-}, deprecatedMessage('client.sendQueriesBatch()', 'client.search()'));
-
-/**
- * Perform write operations across multiple indexes.
- *
- * To reduce the amount of time spent on network round trips,
- * you can create, update, or delete several objects in one call,
- * using the batch endpoint (all operations are done in the given order).
- *
- * Available actions:
- * - addObject
- * - updateObject
- * - partialUpdateObject
- * - partialUpdateObjectNoCreate
- * - deleteObject
- *
- * https://www.algolia.com/doc/rest_api#Indexes
- * @param {Object[]} operations An array of operations to perform
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.batch([{
- * action: 'addObject',
- * indexName: 'clients',
- * body: {
- * name: 'Bill'
- * }
- * }, {
- * action: 'udpateObject',
- * indexName: 'fruits',
- * body: {
- * objectID: '29138',
- * name: 'banana'
- * }
- * }], cb)
- */
-AlgoliaSearch.prototype.batch = function(operations, callback) {
- var isArray = require(8);
- var usage = 'Usage: client.batch(operations[, callback])';
-
- if (!isArray(operations)) {
- throw new Error(usage);
- }
-
- return this._jsonRequest({
- method: 'POST',
- url: '/1/indexes/*/batch',
- body: {
- requests: operations
- },
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Assign or Move a userID to a cluster
- *
- * @param {string} data.userID The userID to assign to a new cluster
- * @param {string} data.cluster The cluster to assign the user to
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.assignUserID({ cluster: 'c1-test', userID: 'some-user' });
- */
-AlgoliaSearch.prototype.assignUserID = function(data, callback) {
- if (!data.userID || !data.cluster) {
- throw new errors.AlgoliaSearchError('You have to provide both a userID and cluster', data);
- }
- return this._jsonRequest({
- method: 'POST',
- url: '/1/clusters/mapping',
- hostType: 'write',
- body: {cluster: data.cluster},
- callback: callback,
- headers: {
- 'x-algolia-user-id': data.userID
- }
- });
-};
-
-/**
- * Assign a array of userIDs to a cluster.
- *
- * @param {Array} data.userIDs The array of userIDs to assign to a new cluster
- * @param {string} data.cluster The cluster to assign the user to
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.assignUserIDs({ cluster: 'c1-test', userIDs: ['some-user-1', 'some-user-2'] });
- */
-AlgoliaSearch.prototype.assignUserIDs = function(data, callback) {
- if (!data.userIDs || !data.cluster) {
- throw new errors.AlgoliaSearchError('You have to provide both an array of userIDs and cluster', data);
- }
- return this._jsonRequest({
- method: 'POST',
- url: '/1/clusters/mapping/batch',
- hostType: 'write',
- body: {
- cluster: data.cluster,
- users: data.userIDs
- },
- callback: callback
- });
-};
-
-/**
- * Get the top userIDs
- *
- * (the callback is the second argument)
- *
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.getTopUserID();
- */
-AlgoliaSearch.prototype.getTopUserID = function(callback) {
- return this._jsonRequest({
- method: 'GET',
- url: '/1/clusters/mapping/top',
- hostType: 'read',
- callback: callback
- });
-};
-
-/**
- * Get userID
- *
- * @param {string} data.userID The userID to get info about
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.getUserID({ userID: 'some-user' });
- */
-AlgoliaSearch.prototype.getUserID = function(data, callback) {
- if (!data.userID) {
- throw new errors.AlgoliaSearchError('You have to provide a userID', {debugData: data});
- }
- return this._jsonRequest({
- method: 'GET',
- url: '/1/clusters/mapping/' + data.userID,
- hostType: 'read',
- callback: callback
- });
-};
-
-/**
- * List all the clusters
- *
- * (the callback is the second argument)
- *
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.listClusters();
- */
-AlgoliaSearch.prototype.listClusters = function(callback) {
- return this._jsonRequest({
- method: 'GET',
- url: '/1/clusters',
- hostType: 'read',
- callback: callback
- });
-};
-
-/**
- * List the userIDs
- *
- * (the callback is the second argument)
- *
- * @param {string} data.hitsPerPage How many hits on every page
- * @param {string} data.page The page to retrieve
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.listClusters();
- * client.listClusters({ page: 3, hitsPerPage: 30});
- */
-AlgoliaSearch.prototype.listUserIDs = function(data, callback) {
- return this._jsonRequest({
- method: 'GET',
- url: '/1/clusters/mapping',
- body: data,
- hostType: 'read',
- callback: callback
- });
-};
-
-/**
- * Remove an userID
- *
- * @param {string} data.userID The userID to assign to a new cluster
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.removeUserID({ userID: 'some-user' });
- */
-AlgoliaSearch.prototype.removeUserID = function(data, callback) {
- if (!data.userID) {
- throw new errors.AlgoliaSearchError('You have to provide a userID', {debugData: data});
- }
- return this._jsonRequest({
- method: 'DELETE',
- url: '/1/clusters/mapping',
- hostType: 'write',
- callback: callback,
- headers: {
- 'x-algolia-user-id': data.userID
- }
- });
-};
-
-/**
- * Search for userIDs
- *
- * @param {string} data.cluster The cluster to target
- * @param {string} data.query The query to execute
- * @param {string} data.hitsPerPage How many hits on every page
- * @param {string} data.page The page to retrieve
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.searchUserIDs({ cluster: 'c1-test', query: 'some-user' });
- * client.searchUserIDs({
- * cluster: "c1-test",
- * query: "some-user",
- * page: 3,
- * hitsPerPage: 2
- * });
- */
-AlgoliaSearch.prototype.searchUserIDs = function(data, callback) {
- return this._jsonRequest({
- method: 'POST',
- url: '/1/clusters/mapping/search',
- body: data,
- hostType: 'read',
- callback: callback
- });
-};
-
-/**
- * Set strategy for personalization
- *
- * @param {Object} data
- * @param {Object} data.eventsScoring Associate a score to an event
- * @param {Object} data.eventsScoring. The name of the event
- * @param {Number} data.eventsScoring..score The score to associate to
- * @param {String} data.eventsScoring..type Either "click", "conversion" or "view"
- * @param {Object} data.facetsScoring Associate a score to a facet
- * @param {Object} data.facetsScoring. The name of the facet
- * @param {Number} data.facetsScoring..score The score to associate to
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.setPersonalizationStrategy({
- * eventsScoring: {
- * "Add to cart": { score: 50, type: "conversion" },
- * Purchase: { score: 100, type: "conversion" }
- * },
- * facetsScoring: {
- * brand: { score: 100 },
- * categories: { score: 10 }
- * }
- * });
- */
-AlgoliaSearch.prototype.setPersonalizationStrategy = function(data, callback) {
- return this._jsonRequest({
- method: 'POST',
- url: '/1/recommendation/personalization/strategy',
- body: data,
- hostType: 'write',
- callback: callback
- });
-};
-
-/**
- * Get strategy for personalization
- *
- * @return {Promise|undefined} Returns a promise if no callback given
- * @example
- * client.getPersonalizationStrategy();
- */
-
-AlgoliaSearch.prototype.getPersonalizationStrategy = function(callback) {
- return this._jsonRequest({
- method: 'GET',
- url: '/1/recommendation/personalization/strategy',
- hostType: 'read',
- callback: callback
- });
-};
-
-// environment specific methods
-AlgoliaSearch.prototype.destroy = notImplemented;
-AlgoliaSearch.prototype.enableRateLimitForward = notImplemented;
-AlgoliaSearch.prototype.disableRateLimitForward = notImplemented;
-AlgoliaSearch.prototype.useSecuredAPIKey = notImplemented;
-AlgoliaSearch.prototype.disableSecuredAPIKey = notImplemented;
-AlgoliaSearch.prototype.generateSecuredApiKey = notImplemented;
-AlgoliaSearch.prototype.getSecuredApiKeyRemainingValidity = notImplemented;
-
-function notImplemented() {
- var message = 'Not implemented in this environment.\n' +
- 'If you feel this is a mistake, write to support@algolia.com';
-
- throw new errors.AlgoliaSearchError(message);
-}
-
-},{"17":17,"18":18,"27":27,"28":28,"29":29,"30":30,"31":31,"7":7,"8":8}],17:[function(require,module,exports){
-(function (process){
-module.exports = AlgoliaSearchCore;
-
-var errors = require(31);
-var exitPromise = require(32);
-var IndexCore = require(20);
-var store = require(37);
-
-// We will always put the API KEY in the JSON body in case of too long API KEY,
-// to avoid query string being too long and failing in various conditions (our server limit, browser limit,
-// proxies limit)
-var MAX_API_KEY_LENGTH = 500;
-var RESET_APP_DATA_TIMER =
- process.env.RESET_APP_DATA_TIMER && parseInt(process.env.RESET_APP_DATA_TIMER, 10) ||
- 60 * 2 * 1000; // after 2 minutes reset to first host
-
-/*
- * Algolia Search library initialization
- * https://www.algolia.com/
- *
- * @param {string} applicationID - Your applicationID, found in your dashboard
- * @param {string} apiKey - Your API key, found in your dashboard
- * @param {Object} [opts]
- * @param {number} [opts.timeout=2000] - The request timeout set in milliseconds,
- * another request will be issued after this timeout
- * @param {string} [opts.protocol='https:'] - The protocol used to query Algolia Search API.
- * Set to 'http:' to force using http.
- * @param {Object|Array} [opts.hosts={
- * read: [this.applicationID + '-dsn.algolia.net'].concat([
- * this.applicationID + '-1.algolianet.com',
- * this.applicationID + '-2.algolianet.com',
- * this.applicationID + '-3.algolianet.com']
- * ]),
- * write: [this.applicationID + '.algolia.net'].concat([
- * this.applicationID + '-1.algolianet.com',
- * this.applicationID + '-2.algolianet.com',
- * this.applicationID + '-3.algolianet.com']
- * ]) - The hosts to use for Algolia Search API.
- * If you provide them, you will less benefit from our HA implementation
- */
-function AlgoliaSearchCore(applicationID, apiKey, opts) {
- var debug = require(1)('algoliasearch');
-
- var clone = require(27);
- var isArray = require(8);
- var map = require(33);
-
- var usage = 'Usage: algoliasearch(applicationID, apiKey, opts)';
-
- if (opts._allowEmptyCredentials !== true && !applicationID) {
- throw new errors.AlgoliaSearchError('Please provide an application ID. ' + usage);
- }
-
- if (opts._allowEmptyCredentials !== true && !apiKey) {
- throw new errors.AlgoliaSearchError('Please provide an API key. ' + usage);
- }
-
- this.applicationID = applicationID;
- this.apiKey = apiKey;
-
- this.hosts = {
- read: [],
- write: []
- };
-
- opts = opts || {};
-
- this._timeouts = opts.timeouts || {
- connect: 1 * 1000, // 500ms connect is GPRS latency
- read: 2 * 1000,
- write: 30 * 1000
- };
-
- // backward compat, if opts.timeout is passed, we use it to configure all timeouts like before
- if (opts.timeout) {
- this._timeouts.connect = this._timeouts.read = this._timeouts.write = opts.timeout;
- }
-
- var protocol = opts.protocol || 'https:';
- // while we advocate for colon-at-the-end values: 'http:' for `opts.protocol`
- // we also accept `http` and `https`. It's a common error.
- if (!/:$/.test(protocol)) {
- protocol = protocol + ':';
- }
-
- if (protocol !== 'http:' && protocol !== 'https:') {
- throw new errors.AlgoliaSearchError('protocol must be `http:` or `https:` (was `' + opts.protocol + '`)');
- }
-
- this._checkAppIdData();
-
- if (!opts.hosts) {
- var defaultHosts = map(this._shuffleResult, function(hostNumber) {
- return applicationID + '-' + hostNumber + '.algolianet.com';
- });
-
- // no hosts given, compute defaults
- var mainSuffix = (opts.dsn === false ? '' : '-dsn') + '.algolia.net';
- this.hosts.read = [this.applicationID + mainSuffix].concat(defaultHosts);
- this.hosts.write = [this.applicationID + '.algolia.net'].concat(defaultHosts);
- } else if (isArray(opts.hosts)) {
- // when passing custom hosts, we need to have a different host index if the number
- // of write/read hosts are different.
- this.hosts.read = clone(opts.hosts);
- this.hosts.write = clone(opts.hosts);
- } else {
- this.hosts.read = clone(opts.hosts.read);
- this.hosts.write = clone(opts.hosts.write);
- }
-
- // add protocol and lowercase hosts
- this.hosts.read = map(this.hosts.read, prepareHost(protocol));
- this.hosts.write = map(this.hosts.write, prepareHost(protocol));
-
- this.extraHeaders = {};
-
- // In some situations you might want to warm the cache
- this.cache = opts._cache || {};
-
- this._ua = opts._ua;
- this._useCache = opts._useCache === undefined || opts._cache ? true : opts._useCache;
- this._useRequestCache = this._useCache && opts._useRequestCache;
- this._useFallback = opts.useFallback === undefined ? true : opts.useFallback;
-
- this._setTimeout = opts._setTimeout;
-
- debug('init done, %j', this);
-}
-
-/*
- * Get the index object initialized
- *
- * @param indexName the name of index
- * @param callback the result callback with one argument (the Index instance)
- */
-AlgoliaSearchCore.prototype.initIndex = function(indexName) {
- return new IndexCore(this, indexName);
-};
-
-/**
-* Add an extra field to the HTTP request
-*
-* @param name the header field name
-* @param value the header field value
-*/
-AlgoliaSearchCore.prototype.setExtraHeader = function(name, value) {
- this.extraHeaders[name.toLowerCase()] = value;
-};
-
-/**
-* Get the value of an extra HTTP header
-*
-* @param name the header field name
-*/
-AlgoliaSearchCore.prototype.getExtraHeader = function(name) {
- return this.extraHeaders[name.toLowerCase()];
-};
-
-/**
-* Remove an extra field from the HTTP request
-*
-* @param name the header field name
-*/
-AlgoliaSearchCore.prototype.unsetExtraHeader = function(name) {
- delete this.extraHeaders[name.toLowerCase()];
-};
-
-/**
-* Augment sent x-algolia-agent with more data, each agent part
-* is automatically separated from the others by a semicolon;
-*
-* @param algoliaAgent the agent to add
-*/
-AlgoliaSearchCore.prototype.addAlgoliaAgent = function(algoliaAgent) {
- var algoliaAgentWithDelimiter = '; ' + algoliaAgent;
-
- if (this._ua.indexOf(algoliaAgentWithDelimiter) === -1) {
- this._ua += algoliaAgentWithDelimiter;
- }
-};
-
-/*
- * Wrapper that try all hosts to maximize the quality of service
- */
-AlgoliaSearchCore.prototype._jsonRequest = function(initialOpts) {
- this._checkAppIdData();
-
- var requestDebug = require(1)('algoliasearch:' + initialOpts.url);
-
-
- var body;
- var cacheID;
- var additionalUA = initialOpts.additionalUA || '';
- var cache = initialOpts.cache;
- var client = this;
- var tries = 0;
- var usingFallback = false;
- var hasFallback = client._useFallback && client._request.fallback && initialOpts.fallback;
- var headers;
-
- if (
- this.apiKey.length > MAX_API_KEY_LENGTH &&
- initialOpts.body !== undefined &&
- (initialOpts.body.params !== undefined || // index.search()
- initialOpts.body.requests !== undefined) // client.search()
- ) {
- initialOpts.body.apiKey = this.apiKey;
- headers = this._computeRequestHeaders({
- additionalUA: additionalUA,
- withApiKey: false,
- headers: initialOpts.headers
- });
- } else {
- headers = this._computeRequestHeaders({
- additionalUA: additionalUA,
- headers: initialOpts.headers
- });
- }
-
- if (initialOpts.body !== undefined) {
- body = safeJSONStringify(initialOpts.body);
- }
-
- requestDebug('request start');
- var debugData = [];
-
-
- function doRequest(requester, reqOpts) {
- client._checkAppIdData();
-
- var startTime = new Date();
-
- if (client._useCache && !client._useRequestCache) {
- cacheID = initialOpts.url;
- }
-
- // as we sometime use POST requests to pass parameters (like query='aa'),
- // the cacheID must also include the body to be different between calls
- if (client._useCache && !client._useRequestCache && body) {
- cacheID += '_body_' + reqOpts.body;
- }
-
- // handle cache existence
- if (isCacheValidWithCurrentID(!client._useRequestCache, cache, cacheID)) {
- requestDebug('serving response from cache');
-
- var responseText = cache[cacheID];
-
- // Cache response must match the type of the original one
- return client._promise.resolve({
- body: JSON.parse(responseText),
- responseText: responseText
- });
- }
-
- // if we reached max tries
- if (tries >= client.hosts[initialOpts.hostType].length) {
- if (!hasFallback || usingFallback) {
- requestDebug('could not get any response');
- // then stop
- return client._promise.reject(new errors.AlgoliaSearchError(
- 'Cannot connect to the AlgoliaSearch API.' +
- ' Send an email to support@algolia.com to report and resolve the issue.' +
- ' Application id was: ' + client.applicationID, {debugData: debugData}
- ));
- }
-
- requestDebug('switching to fallback');
-
- // let's try the fallback starting from here
- tries = 0;
-
- // method, url and body are fallback dependent
- reqOpts.method = initialOpts.fallback.method;
- reqOpts.url = initialOpts.fallback.url;
- reqOpts.jsonBody = initialOpts.fallback.body;
- if (reqOpts.jsonBody) {
- reqOpts.body = safeJSONStringify(reqOpts.jsonBody);
- }
- // re-compute headers, they could be omitting the API KEY
- headers = client._computeRequestHeaders({
- additionalUA: additionalUA,
- headers: initialOpts.headers
- });
-
- reqOpts.timeouts = client._getTimeoutsForRequest(initialOpts.hostType);
- client._setHostIndexByType(0, initialOpts.hostType);
- usingFallback = true; // the current request is now using fallback
- return doRequest(client._request.fallback, reqOpts);
- }
-
- var currentHost = client._getHostByType(initialOpts.hostType);
-
- var url = currentHost + reqOpts.url;
- var options = {
- body: reqOpts.body,
- jsonBody: reqOpts.jsonBody,
- method: reqOpts.method,
- headers: headers,
- timeouts: reqOpts.timeouts,
- debug: requestDebug,
- forceAuthHeaders: reqOpts.forceAuthHeaders
- };
-
- requestDebug('method: %s, url: %s, headers: %j, timeouts: %d',
- options.method, url, options.headers, options.timeouts);
-
- if (requester === client._request.fallback) {
- requestDebug('using fallback');
- }
-
- // `requester` is any of this._request or this._request.fallback
- // thus it needs to be called using the client as context
- return requester.call(client, url, options).then(success, tryFallback);
-
- function success(httpResponse) {
- // compute the status of the response,
- //
- // When in browser mode, using XDR or JSONP, we have no statusCode available
- // So we rely on our API response `status` property.
- // But `waitTask` can set a `status` property which is not the statusCode (it's the task status)
- // So we check if there's a `message` along `status` and it means it's an error
- //
- // That's the only case where we have a response.status that's not the http statusCode
- var status = httpResponse && httpResponse.body && httpResponse.body.message && httpResponse.body.status ||
-
- // this is important to check the request statusCode AFTER the body eventual
- // statusCode because some implementations (jQuery XDomainRequest transport) may
- // send statusCode 200 while we had an error
- httpResponse.statusCode ||
-
- // When in browser mode, using XDR or JSONP
- // we default to success when no error (no response.status && response.message)
- // If there was a JSON.parse() error then body is null and it fails
- httpResponse && httpResponse.body && 200;
-
- requestDebug('received response: statusCode: %s, computed statusCode: %d, headers: %j',
- httpResponse.statusCode, status, httpResponse.headers);
-
- var httpResponseOk = Math.floor(status / 100) === 2;
-
- var endTime = new Date();
- debugData.push({
- currentHost: currentHost,
- headers: removeCredentials(headers),
- content: body || null,
- contentLength: body !== undefined ? body.length : null,
- method: reqOpts.method,
- timeouts: reqOpts.timeouts,
- url: reqOpts.url,
- startTime: startTime,
- endTime: endTime,
- duration: endTime - startTime,
- statusCode: status
- });
-
- if (httpResponseOk) {
- if (client._useCache && !client._useRequestCache && cache) {
- cache[cacheID] = httpResponse.responseText;
- }
-
- return {
- responseText: httpResponse.responseText,
- body: httpResponse.body
- };
- }
-
- var shouldRetry = Math.floor(status / 100) !== 4;
-
- if (shouldRetry) {
- tries += 1;
- return retryRequest();
- }
-
- requestDebug('unrecoverable error');
-
- // no success and no retry => fail
- var unrecoverableError = new errors.AlgoliaSearchError(
- httpResponse.body && httpResponse.body.message, {debugData: debugData, statusCode: status}
- );
-
- return client._promise.reject(unrecoverableError);
- }
-
- function tryFallback(err) {
- // error cases:
- // While not in fallback mode:
- // - CORS not supported
- // - network error
- // While in fallback mode:
- // - timeout
- // - network error
- // - badly formatted JSONP (script loaded, did not call our callback)
- // In both cases:
- // - uncaught exception occurs (TypeError)
- requestDebug('error: %s, stack: %s', err.message, err.stack);
-
- var endTime = new Date();
- debugData.push({
- currentHost: currentHost,
- headers: removeCredentials(headers),
- content: body || null,
- contentLength: body !== undefined ? body.length : null,
- method: reqOpts.method,
- timeouts: reqOpts.timeouts,
- url: reqOpts.url,
- startTime: startTime,
- endTime: endTime,
- duration: endTime - startTime
- });
-
- if (!(err instanceof errors.AlgoliaSearchError)) {
- err = new errors.Unknown(err && err.message, err);
- }
-
- tries += 1;
-
- // stop the request implementation when:
- if (
- // we did not generate this error,
- // it comes from a throw in some other piece of code
- err instanceof errors.Unknown ||
-
- // server sent unparsable JSON
- err instanceof errors.UnparsableJSON ||
-
- // max tries and already using fallback or no fallback
- tries >= client.hosts[initialOpts.hostType].length &&
- (usingFallback || !hasFallback)) {
- // stop request implementation for this command
- err.debugData = debugData;
- return client._promise.reject(err);
- }
-
- // When a timeout occurred, retry by raising timeout
- if (err instanceof errors.RequestTimeout) {
- return retryRequestWithHigherTimeout();
- }
-
- return retryRequest();
- }
-
- function retryRequest() {
- requestDebug('retrying request');
- client._incrementHostIndex(initialOpts.hostType);
- return doRequest(requester, reqOpts);
- }
-
- function retryRequestWithHigherTimeout() {
- requestDebug('retrying request with higher timeout');
- client._incrementHostIndex(initialOpts.hostType);
- client._incrementTimeoutMultipler();
- reqOpts.timeouts = client._getTimeoutsForRequest(initialOpts.hostType);
- return doRequest(requester, reqOpts);
- }
- }
-
- function isCacheValidWithCurrentID(
- useRequestCache,
- currentCache,
- currentCacheID
- ) {
- return (
- client._useCache &&
- useRequestCache &&
- currentCache &&
- currentCache[currentCacheID] !== undefined
- );
- }
-
-
- function interopCallbackReturn(request, callback) {
- if (isCacheValidWithCurrentID(client._useRequestCache, cache, cacheID)) {
- request.catch(function() {
- // Release the cache on error
- delete cache[cacheID];
- });
- }
-
- if (typeof initialOpts.callback === 'function') {
- // either we have a callback
- request.then(function okCb(content) {
- exitPromise(function() {
- initialOpts.callback(null, callback(content));
- }, client._setTimeout || setTimeout);
- }, function nookCb(err) {
- exitPromise(function() {
- initialOpts.callback(err);
- }, client._setTimeout || setTimeout);
- });
- } else {
- // either we are using promises
- return request.then(callback);
- }
- }
-
- if (client._useCache && client._useRequestCache) {
- cacheID = initialOpts.url;
- }
-
- // as we sometime use POST requests to pass parameters (like query='aa'),
- // the cacheID must also include the body to be different between calls
- if (client._useCache && client._useRequestCache && body) {
- cacheID += '_body_' + body;
- }
-
- if (isCacheValidWithCurrentID(client._useRequestCache, cache, cacheID)) {
- requestDebug('serving request from cache');
-
- var maybePromiseForCache = cache[cacheID];
-
- // In case the cache is warmup with value that is not a promise
- var promiseForCache = typeof maybePromiseForCache.then !== 'function'
- ? client._promise.resolve({responseText: maybePromiseForCache})
- : maybePromiseForCache;
-
- return interopCallbackReturn(promiseForCache, function(content) {
- // In case of the cache request, return the original value
- return JSON.parse(content.responseText);
- });
- }
-
- var request = doRequest(
- client._request, {
- url: initialOpts.url,
- method: initialOpts.method,
- body: body,
- jsonBody: initialOpts.body,
- timeouts: client._getTimeoutsForRequest(initialOpts.hostType),
- forceAuthHeaders: initialOpts.forceAuthHeaders
- }
- );
-
- if (client._useCache && client._useRequestCache && cache) {
- cache[cacheID] = request;
- }
-
- return interopCallbackReturn(request, function(content) {
- // In case of the first request, return the JSON value
- return content.body;
- });
-};
-
-/*
-* Transform search param object in query string
-* @param {object} args arguments to add to the current query string
-* @param {string} params current query string
-* @return {string} the final query string
-*/
-AlgoliaSearchCore.prototype._getSearchParams = function(args, params) {
- if (args === undefined || args === null) {
- return params;
- }
- for (var key in args) {
- if (key !== null && args[key] !== undefined && args.hasOwnProperty(key)) {
- params += params === '' ? '' : '&';
- params += key + '=' + encodeURIComponent(Object.prototype.toString.call(args[key]) === '[object Array]' ? safeJSONStringify(args[key]) : args[key]);
- }
- }
- return params;
-};
-
-/**
- * Compute the headers for a request
- *
- * @param [string] options.additionalUA semi-colon separated string with other user agents to add
- * @param [boolean=true] options.withApiKey Send the api key as a header
- * @param [Object] options.headers Extra headers to send
- */
-AlgoliaSearchCore.prototype._computeRequestHeaders = function(options) {
- var forEach = require(5);
-
- var ua = options.additionalUA ?
- this._ua + '; ' + options.additionalUA :
- this._ua;
-
- var requestHeaders = {
- 'x-algolia-agent': ua,
- 'x-algolia-application-id': this.applicationID
- };
-
- // browser will inline headers in the url, node.js will use http headers
- // but in some situations, the API KEY will be too long (big secured API keys)
- // so if the request is a POST and the KEY is very long, we will be asked to not put
- // it into headers but in the JSON body
- if (options.withApiKey !== false) {
- requestHeaders['x-algolia-api-key'] = this.apiKey;
- }
-
- if (this.userToken) {
- requestHeaders['x-algolia-usertoken'] = this.userToken;
- }
-
- if (this.securityTags) {
- requestHeaders['x-algolia-tagfilters'] = this.securityTags;
- }
-
- forEach(this.extraHeaders, function addToRequestHeaders(value, key) {
- requestHeaders[key] = value;
- });
-
- if (options.headers) {
- forEach(options.headers, function addToRequestHeaders(value, key) {
- requestHeaders[key] = value;
- });
- }
-
- return requestHeaders;
-};
-
-/**
- * Search through multiple indices at the same time
- * @param {Object[]} queries An array of queries you want to run.
- * @param {string} queries[].indexName The index name you want to target
- * @param {string} [queries[].query] The query to issue on this index. Can also be passed into `params`
- * @param {Object} queries[].params Any search param like hitsPerPage, ..
- * @param {Function} callback Callback to be called
- * @return {Promise|undefined} Returns a promise if no callback given
- */
-AlgoliaSearchCore.prototype.search = function(queries, opts, callback) {
- var isArray = require(8);
- var map = require(33);
-
- var usage = 'Usage: client.search(arrayOfQueries[, callback])';
-
- if (!isArray(queries)) {
- throw new Error(usage);
- }
-
- if (typeof opts === 'function') {
- callback = opts;
- opts = {};
- } else if (opts === undefined) {
- opts = {};
- }
-
- var client = this;
-
- var postObj = {
- requests: map(queries, function prepareRequest(query) {
- var params = '';
-
- // allow query.query
- // so we are mimicing the index.search(query, params) method
- // {indexName:, query:, params:}
- if (query.query !== undefined) {
- params += 'query=' + encodeURIComponent(query.query);
- }
-
- return {
- indexName: query.indexName,
- params: client._getSearchParams(query.params, params)
- };
- })
- };
-
- var JSONPParams = map(postObj.requests, function prepareJSONPParams(request, requestId) {
- return requestId + '=' +
- encodeURIComponent(
- '/1/indexes/' + encodeURIComponent(request.indexName) + '?' +
- request.params
- );
- }).join('&');
-
- var url = '/1/indexes/*/queries';
-
- if (opts.strategy !== undefined) {
- postObj.strategy = opts.strategy;
- }
-
- return this._jsonRequest({
- cache: this.cache,
- method: 'POST',
- url: url,
- body: postObj,
- hostType: 'read',
- fallback: {
- method: 'GET',
- url: '/1/indexes/*',
- body: {
- params: JSONPParams
- }
- },
- callback: callback
- });
-};
-
-/**
-* Search for facet values
-* https://www.algolia.com/doc/rest-api/search#search-for-facet-values
-* This is the top-level API for SFFV.
-*
-* @param {object[]} queries An array of queries to run.
-* @param {string} queries[].indexName Index name, name of the index to search.
-* @param {object} queries[].params Query parameters.
-* @param {string} queries[].params.facetName Facet name, name of the attribute to search for values in.
-* Must be declared as a facet
-* @param {string} queries[].params.facetQuery Query for the facet search
-* @param {string} [queries[].params.*] Any search parameter of Algolia,
-* see https://www.algolia.com/doc/api-client/javascript/search#search-parameters
-* Pagination is not supported. The page and hitsPerPage parameters will be ignored.
-*/
-AlgoliaSearchCore.prototype.searchForFacetValues = function(queries) {
- var isArray = require(8);
- var map = require(33);
-
- var usage = 'Usage: client.searchForFacetValues([{indexName, params: {facetName, facetQuery, ...params}}, ...queries])'; // eslint-disable-line max-len
-
- if (!isArray(queries)) {
- throw new Error(usage);
- }
-
- var client = this;
-
- return client._promise.all(map(queries, function performQuery(query) {
- if (
- !query ||
- query.indexName === undefined ||
- query.params.facetName === undefined ||
- query.params.facetQuery === undefined
- ) {
- throw new Error(usage);
- }
-
- var clone = require(27);
- var omit = require(35);
-
- var indexName = query.indexName;
- var params = query.params;
-
- var facetName = params.facetName;
- var filteredParams = omit(clone(params), function(keyName) {
- return keyName === 'facetName';
- });
- var searchParameters = client._getSearchParams(filteredParams, '');
-
- return client._jsonRequest({
- cache: client.cache,
- method: 'POST',
- url:
- '/1/indexes/' +
- encodeURIComponent(indexName) +
- '/facets/' +
- encodeURIComponent(facetName) +
- '/query',
- hostType: 'read',
- body: {params: searchParameters}
- });
- }));
-};
-
-/**
- * Set the extra security tagFilters header
- * @param {string|array} tags The list of tags defining the current security filters
- */
-AlgoliaSearchCore.prototype.setSecurityTags = function(tags) {
- if (Object.prototype.toString.call(tags) === '[object Array]') {
- var strTags = [];
- for (var i = 0; i < tags.length; ++i) {
- if (Object.prototype.toString.call(tags[i]) === '[object Array]') {
- var oredTags = [];
- for (var j = 0; j < tags[i].length; ++j) {
- oredTags.push(tags[i][j]);
- }
- strTags.push('(' + oredTags.join(',') + ')');
- } else {
- strTags.push(tags[i]);
- }
- }
- tags = strTags.join(',');
- }
-
- this.securityTags = tags;
-};
-
-/**
- * Set the extra user token header
- * @param {string} userToken The token identifying a uniq user (used to apply rate limits)
- */
-AlgoliaSearchCore.prototype.setUserToken = function(userToken) {
- this.userToken = userToken;
-};
-
-/**
- * Clear all queries in client's cache
- * @return undefined
- */
-AlgoliaSearchCore.prototype.clearCache = function() {
- this.cache = {};
-};
-
-/**
-* Set the number of milliseconds a request can take before automatically being terminated.
-* @deprecated
-* @param {Number} milliseconds
-*/
-AlgoliaSearchCore.prototype.setRequestTimeout = function(milliseconds) {
- if (milliseconds) {
- this._timeouts.connect = this._timeouts.read = this._timeouts.write = milliseconds;
- }
-};
-
-/**
-* Set the three different (connect, read, write) timeouts to be used when requesting
-* @param {Object} timeouts
-*/
-AlgoliaSearchCore.prototype.setTimeouts = function(timeouts) {
- this._timeouts = timeouts;
-};
-
-/**
-* Get the three different (connect, read, write) timeouts to be used when requesting
-* @param {Object} timeouts
-*/
-AlgoliaSearchCore.prototype.getTimeouts = function() {
- return this._timeouts;
-};
-
-AlgoliaSearchCore.prototype._getAppIdData = function() {
- var data = store.get(this.applicationID);
- if (data !== null) this._cacheAppIdData(data);
- return data;
-};
-
-AlgoliaSearchCore.prototype._setAppIdData = function(data) {
- data.lastChange = (new Date()).getTime();
- this._cacheAppIdData(data);
- return store.set(this.applicationID, data);
-};
-
-AlgoliaSearchCore.prototype._checkAppIdData = function() {
- var data = this._getAppIdData();
- var now = (new Date()).getTime();
- if (data === null || now - data.lastChange > RESET_APP_DATA_TIMER) {
- return this._resetInitialAppIdData(data);
- }
-
- return data;
-};
-
-AlgoliaSearchCore.prototype._resetInitialAppIdData = function(data) {
- var newData = data || {};
- newData.hostIndexes = {read: 0, write: 0};
- newData.timeoutMultiplier = 1;
- newData.shuffleResult = newData.shuffleResult || shuffle([1, 2, 3]);
- return this._setAppIdData(newData);
-};
-
-AlgoliaSearchCore.prototype._cacheAppIdData = function(data) {
- this._hostIndexes = data.hostIndexes;
- this._timeoutMultiplier = data.timeoutMultiplier;
- this._shuffleResult = data.shuffleResult;
-};
-
-AlgoliaSearchCore.prototype._partialAppIdDataUpdate = function(newData) {
- var foreach = require(5);
- var currentData = this._getAppIdData();
- foreach(newData, function(value, key) {
- currentData[key] = value;
- });
-
- return this._setAppIdData(currentData);
-};
-
-AlgoliaSearchCore.prototype._getHostByType = function(hostType) {
- return this.hosts[hostType][this._getHostIndexByType(hostType)];
-};
-
-AlgoliaSearchCore.prototype._getTimeoutMultiplier = function() {
- return this._timeoutMultiplier;
-};
-
-AlgoliaSearchCore.prototype._getHostIndexByType = function(hostType) {
- return this._hostIndexes[hostType];
-};
-
-AlgoliaSearchCore.prototype._setHostIndexByType = function(hostIndex, hostType) {
- var clone = require(27);
- var newHostIndexes = clone(this._hostIndexes);
- newHostIndexes[hostType] = hostIndex;
- this._partialAppIdDataUpdate({hostIndexes: newHostIndexes});
- return hostIndex;
-};
-
-AlgoliaSearchCore.prototype._incrementHostIndex = function(hostType) {
- return this._setHostIndexByType(
- (this._getHostIndexByType(hostType) + 1) % this.hosts[hostType].length, hostType
- );
-};
-
-AlgoliaSearchCore.prototype._incrementTimeoutMultipler = function() {
- var timeoutMultiplier = Math.max(this._timeoutMultiplier + 1, 4);
- return this._partialAppIdDataUpdate({timeoutMultiplier: timeoutMultiplier});
-};
-
-AlgoliaSearchCore.prototype._getTimeoutsForRequest = function(hostType) {
- return {
- connect: this._timeouts.connect * this._timeoutMultiplier,
- complete: this._timeouts[hostType] * this._timeoutMultiplier
- };
-};
-
-function prepareHost(protocol) {
- return function prepare(host) {
- return protocol + '//' + host.toLowerCase();
- };
-}
-
-// Prototype.js < 1.7, a widely used library, defines a weird
-// Array.prototype.toJSON function that will fail to stringify our content
-// appropriately
-// refs:
-// - https://groups.google.com/forum/#!topic/prototype-core/E-SAVvV_V9Q
-// - https://github.com/sstephenson/prototype/commit/038a2985a70593c1a86c230fadbdfe2e4898a48c
-// - http://stackoverflow.com/a/3148441/147079
-function safeJSONStringify(obj) {
- /* eslint no-extend-native:0 */
-
- if (Array.prototype.toJSON === undefined) {
- return JSON.stringify(obj);
- }
-
- var toJSON = Array.prototype.toJSON;
- delete Array.prototype.toJSON;
- var out = JSON.stringify(obj);
- Array.prototype.toJSON = toJSON;
-
- return out;
-}
-
-function shuffle(array) {
- var currentIndex = array.length;
- var temporaryValue;
- var randomIndex;
-
- // While there remain elements to shuffle...
- while (currentIndex !== 0) {
- // Pick a remaining element...
- randomIndex = Math.floor(Math.random() * currentIndex);
- currentIndex -= 1;
-
- // And swap it with the current element.
- temporaryValue = array[currentIndex];
- array[currentIndex] = array[randomIndex];
- array[randomIndex] = temporaryValue;
- }
-
- return array;
-}
-
-function removeCredentials(headers) {
- var newHeaders = {};
-
- for (var headerName in headers) {
- if (Object.prototype.hasOwnProperty.call(headers, headerName)) {
- var value;
-
- if (headerName === 'x-algolia-api-key' || headerName === 'x-algolia-application-id') {
- value = '**hidden for security purposes**';
- } else {
- value = headers[headerName];
- }
-
- newHeaders[headerName] = value;
- }
- }
-
- return newHeaders;
-}
-
-}).call(this,require(12))
-},{"1":1,"12":12,"20":20,"27":27,"31":31,"32":32,"33":33,"35":35,"37":37,"5":5,"8":8}],18:[function(require,module,exports){
-var inherits = require(7);
-var IndexCore = require(20);
-var deprecate = require(29);
-var deprecatedMessage = require(30);
-var exitPromise = require(32);
-var errors = require(31);
-
-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(8);
- 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(8);
- 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(8);
- 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(8);
- var map = require(33);
-
- 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(27);
- var map = require(33);
-
- 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(34);
-
- var IndexBrowser = require(19);
-
- 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 occurred
-*/
-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
- });
-};
-
-Index.prototype.exists = function(callback) {
- var result = this.getSettings().then(function() {
- return true;
- }).catch(function(err) {
- if (err instanceof errors.AlgoliaSearchError && err.statusCode === 404) {
- return false;
- }
-
- throw err;
- });
-
- if (typeof callback !== 'function') {
- return result;
- }
-
- result.then(function(res) {
- callback(null, res);
- }).catch(function(err) {
- callback(err);
- });
-};
-
-Index.prototype.findObject = function(findCallback, requestOptions, callback) {
- requestOptions = requestOptions === undefined ? {} : requestOptions;
- var paginate = requestOptions.paginate !== undefined ? requestOptions.paginate : true;
- var query = requestOptions.query !== undefined ? requestOptions.query : '';
-
- var that = this;
- var page = 0;
-
- var paginateLoop = function() {
- requestOptions.page = page;
-
- return that.search(query, requestOptions).then(function(result) {
- var hits = result.hits;
-
- for (var position = 0; position < hits.length; position++) {
- var hit = hits[position];
- if (findCallback(hit)) {
- return {
- object: hit,
- position: position,
- page: page
- };
- }
- }
-
- page += 1;
-
- // paginate if option was set and has next page
- if (!paginate || page >= result.nbPages) {
- throw new errors.ObjectNotFound('Object not found');
- }
-
- return paginateLoop();
- });
- };
-
- var promise = paginateLoop(page);
-
- if (callback === undefined) {
- return promise;
- }
-
- promise
- .then(function(res) {
- callback(null, res);
- })
- .catch(function(err) {
- callback(err);
- });
-};
-
-Index.prototype.getObjectPosition = function(result, objectID) {
- var hits = result.hits;
-
- for (var position = 0; position < hits.length; position++) {
- if (hits[position].objectID === objectID) {
- return position;
- }
- }
-
- return -1;
-};
-
-/*
-* Set settings for this index
-*
-* @param settings 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 "").
-* - highlightPostTag: (string) Specify the string that is inserted after
-* the highlighted parts in the query result (default to "").
-* - 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 occurred
-*/
-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(8);
- 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(8);
- 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()'));
-
-},{"19":19,"20":20,"27":27,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"7":7,"8":8}],19:[function(require,module,exports){
-'use strict';
-
-// This is the object returned by the `index.browseAll()` method
-
-module.exports = IndexBrowser;
-
-var inherits = require(7);
-var EventEmitter = require(4).EventEmitter;
-
-function IndexBrowser() {
-}
-
-inherits(IndexBrowser, EventEmitter);
-
-IndexBrowser.prototype.stop = function() {
- this._stopped = true;
- this._clean();
-};
-
-IndexBrowser.prototype._end = function() {
- this.emit('end');
- this._clean();
-};
-
-IndexBrowser.prototype._error = function(err) {
- this.emit('error', err);
- this._clean();
-};
-
-IndexBrowser.prototype._result = function(content) {
- this.emit('result', content);
-};
-
-IndexBrowser.prototype._clean = function() {
- this.removeAllListeners('stop');
- this.removeAllListeners('end');
- this.removeAllListeners('error');
- this.removeAllListeners('result');
-};
-
-},{"4":4,"7":7}],20:[function(require,module,exports){
-var buildSearchMethod = require(26);
-var deprecate = require(29);
-var deprecatedMessage = require(30);
-
-module.exports = IndexCore;
-
-/*
-* Index class constructor.
-* You should not use this method directly but use initIndex() function
-*/
-function IndexCore(algoliasearch, indexName) {
- this.indexName = indexName;
- this.as = algoliasearch;
- this.typeAheadArgs = null;
- this.typeAheadValueOption = null;
-
- // make sure every index instance has it's own cache
- this.cache = {};
-}
-
-/*
-* Clear all queries in cache
-*/
-IndexCore.prototype.clearCache = function() {
- this.cache = {};
-};
-
-/*
-* Search inside the index using XMLHttpRequest request (Using a POST query to
-* minimize number of OPTIONS queries: Cross-Origin Resource Sharing).
-*
-* @param {string} [query] the full text query
-* @param {object} [args] (optional) if set, contains an object with query parameters:
-* - page: (integer) Pagination parameter used to select the page to retrieve.
-* Page is zero-based and defaults to 0. Thus,
-* to retrieve the 10th page you need to set page=9
-* - hitsPerPage: (integer) Pagination parameter used to select the number of hits per page. Defaults to 20.
-* - attributesToRetrieve: a string that contains the list of object attributes
-* you want to retrieve (let you minimize the answer size).
-* Attributes are separated with a comma (for example "name,address").
-* You can also use an array (for example ["name","address"]).
-* By default, all attributes are retrieved. You can also use '*' to retrieve all
-* values when an attributesToRetrieve setting is specified for your index.
-* - attributesToHighlight: a string that contains the list of attributes you
-* want to highlight according to the query.
-* Attributes are separated by a comma. You can also use an array (for example ["name","address"]).
-* If an attribute has no match for the query, the raw value is returned.
-* By default all indexed text attributes are highlighted.
-* You can use `*` if you want to highlight all textual attributes.
-* Numerical attributes are not highlighted.
-* A matchLevel is returned for each highlighted attribute and can contain:
-* - full: if all the query terms were found in the attribute,
-* - partial: if only some of the query terms were found,
-* - none: if none of the query terms were found.
-* - attributesToSnippet: a string that contains the list of attributes to snippet alongside
-* the number of words to return (syntax is `attributeName:nbWords`).
-* Attributes are separated by a comma (Example: attributesToSnippet=name:10,content:10).
-* You can also use an array (Example: attributesToSnippet: ['name:10','content:10']).
-* By default no snippet is computed.
-* - minWordSizefor1Typo: the minimum number of characters in a query word to accept one typo in this word.
-* Defaults to 3.
-* - minWordSizefor2Typos: the minimum number of characters in a query word
-* to accept two typos in this word. Defaults to 7.
-* - getRankingInfo: if set to 1, the result hits will contain ranking
-* information in _rankingInfo attribute.
-* - aroundLatLng: search for entries around a given
-* latitude/longitude (specified as two floats separated by a comma).
-* For example aroundLatLng=47.316669,5.016670).
-* You can specify the maximum distance in meters with the aroundRadius parameter (in meters)
-* and the precision for ranking with aroundPrecision
-* (for example if you set aroundPrecision=100, two objects that are distant of
-* less than 100m will be considered as identical for "geo" ranking parameter).
-* At indexing, you should specify geoloc of an object with the _geoloc attribute
-* (in the form {"_geoloc":{"lat":48.853409, "lng":2.348800}})
-* - insideBoundingBox: search entries inside a given area defined by the two extreme points
-* of a rectangle (defined by 4 floats: p1Lat,p1Lng,p2Lat,p2Lng).
-* For example insideBoundingBox=47.3165,4.9665,47.3424,5.0201).
-* At indexing, you should specify geoloc of an object with the _geoloc attribute
-* (in the form {"_geoloc":{"lat":48.853409, "lng":2.348800}})
-* - numericFilters: a string that contains the list of numeric filters you want to
-* apply separated by a comma.
-* The syntax of one filter is `attributeName` followed by `operand` followed by `value`.
-* Supported operands are `<`, `<=`, `=`, `>` and `>=`.
-* You can have multiple conditions on one attribute like for example numericFilters=price>100,price<1000.
-* You can also use an array (for example numericFilters: ["price>100","price<1000"]).
-* - tagFilters: filter the query by a set of tags. You can AND tags by separating them by commas.
-* To OR tags, you must add parentheses. For example, tags=tag1,(tag2,tag3) means tag1 AND (tag2 OR tag3).
-* You can also use an array, for example tagFilters: ["tag1",["tag2","tag3"]]
-* means tag1 AND (tag2 OR tag3).
-* At indexing, tags should be added in the _tags** attribute
-* of objects (for example {"_tags":["tag1","tag2"]}).
-* - facetFilters: filter the query by a list of facets.
-* Facets are separated by commas and each facet is encoded as `attributeName:value`.
-* For example: `facetFilters=category:Book,author:John%20Doe`.
-* You can also use an array (for example `["category:Book","author:John%20Doe"]`).
-* - facets: List of object attributes that you want to use for faceting.
-* Comma separated list: `"category,author"` or array `['category','author']`
-* Only attributes that have been added in **attributesForFaceting** index setting
-* can be used in this parameter.
-* You can also use `*` to perform faceting on all attributes specified in **attributesForFaceting**.
-* - 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.
-* - optionalWords: a string that contains the list of words that should
-* be considered as optional when found in the query.
-* Comma separated and array are accepted.
-* - distinct: If set to 1, enable the distinct feature (disabled by default)
-* if the attributeForDistinct index setting is set.
-* This feature is similar to the SQL "distinct" keyword: when enabled
-* in a query with the distinct=1 parameter,
-* all hits containing a duplicate value for the attributeForDistinct 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.
-* - restrictSearchableAttributes: List of attributes you want to use for
-* textual search (must be a subset of the attributesToIndex index setting)
-* either comma separated or as an array
-* @param {function} [callback] the result callback called with two arguments:
-* error: null or Error('message'). If false, the content contains the error.
-* content: the server answer that contains the list of results.
-*/
-IndexCore.prototype.search = buildSearchMethod('query');
-
-/*
-* -- BETA --
-* Search a record similar to the query inside the index using XMLHttpRequest request (Using a POST query to
-* minimize number of OPTIONS queries: Cross-Origin Resource Sharing).
-*
-* @param {string} [query] the similar query
-* @param {object} [args] (optional) if set, contains an object with query parameters.
-* All search parameters are supported (see search function), restrictSearchableAttributes and facetFilters
-* are the two most useful to restrict the similar results and get more relevant content
-*/
-IndexCore.prototype.similarSearch = deprecate(
- buildSearchMethod('similarQuery'),
- deprecatedMessage(
- 'index.similarSearch(query[, callback])',
- 'index.search({ similarQuery: query }[, callback])'
- )
-);
-
-/*
-* Browse index content. The response content will have a `cursor` property that you can use
-* to browse subsequent pages for this query. Use `index.browseFrom(cursor)` when you want.
-*
-* @param {string} query - The full text query
-* @param {Object} [queryParameters] - Any search query parameter
-* @param {Function} [callback] - The result callback called with two arguments
-* error: null or Error('message')
-* content: the server answer with the browse result
-* @return {Promise|undefined} Returns a promise if no callback given
-* @example
-* index.browse('cool songs', {
-* tagFilters: 'public,comments',
-* hitsPerPage: 500
-* }, callback);
-* @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
-*/
-IndexCore.prototype.browse = function(query, queryParameters, callback) {
- var merge = require(34);
-
- var indexObj = this;
-
- var page;
- var hitsPerPage;
-
- // we check variadic calls that are not the one defined
- // .browse()/.browse(fn)
- // => page = 0
- if (arguments.length === 0 || arguments.length === 1 && typeof arguments[0] === 'function') {
- page = 0;
- callback = arguments[0];
- query = undefined;
- } else if (typeof arguments[0] === 'number') {
- // .browse(2)/.browse(2, 10)/.browse(2, fn)/.browse(2, 10, fn)
- page = arguments[0];
- if (typeof arguments[1] === 'number') {
- hitsPerPage = arguments[1];
- } else if (typeof arguments[1] === 'function') {
- callback = arguments[1];
- hitsPerPage = undefined;
- }
- query = undefined;
- queryParameters = undefined;
- } else if (typeof arguments[0] === 'object') {
- // .browse(queryParameters)/.browse(queryParameters, cb)
- if (typeof arguments[1] === 'function') {
- callback = arguments[1];
- }
- queryParameters = arguments[0];
- query = undefined;
- } else if (typeof arguments[0] === 'string' && typeof arguments[1] === 'function') {
- // .browse(query, cb)
- callback = arguments[1];
- queryParameters = undefined;
- }
-
- // otherwise it's a .browse(query)/.browse(query, queryParameters)/.browse(query, queryParameters, cb)
-
- // get search query parameters combining various possible calls
- // to .browse();
- queryParameters = merge({}, queryParameters || {}, {
- page: page,
- hitsPerPage: hitsPerPage,
- query: query
- });
-
- var params = this.as._getSearchParams(queryParameters, '');
-
- return this.as._jsonRequest({
- method: 'POST',
- url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/browse',
- body: {params: params},
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
-* Continue browsing from a previous position (cursor), obtained via a call to `.browse()`.
-*
-* @param {string} query - The full text query
-* @param {Object} [queryParameters] - Any search query parameter
-* @param {Function} [callback] - The result callback called with two arguments
-* error: null or Error('message')
-* content: the server answer with the browse result
-* @return {Promise|undefined} Returns a promise if no callback given
-* @example
-* index.browseFrom('14lkfsakl32', callback);
-* @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation}
-*/
-IndexCore.prototype.browseFrom = function(cursor, callback) {
- return this.as._jsonRequest({
- method: 'POST',
- url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/browse',
- body: {cursor: cursor},
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
-* Search for facet values
-* https://www.algolia.com/doc/rest-api/search#search-for-facet-values
-*
-* @param {string} params.facetName Facet name, name of the attribute to search for values in.
-* Must be declared as a facet
-* @param {string} params.facetQuery Query for the facet search
-* @param {string} [params.*] Any search parameter of Algolia,
-* see https://www.algolia.com/doc/api-client/javascript/search#search-parameters
-* Pagination is not supported. The page and hitsPerPage parameters will be ignored.
-* @param callback (optional)
-*/
-IndexCore.prototype.searchForFacetValues = function(params, callback) {
- var clone = require(27);
- var omit = require(35);
- var usage = 'Usage: index.searchForFacetValues({facetName, facetQuery, ...params}[, callback])';
-
- if (params.facetName === undefined || params.facetQuery === undefined) {
- throw new Error(usage);
- }
-
- var facetName = params.facetName;
- var filteredParams = omit(clone(params), function(keyName) {
- return keyName === 'facetName';
- });
- var searchParameters = this.as._getSearchParams(filteredParams, '');
-
- return this.as._jsonRequest({
- method: 'POST',
- url: '/1/indexes/' +
- encodeURIComponent(this.indexName) + '/facets/' + encodeURIComponent(facetName) + '/query',
- hostType: 'read',
- body: {params: searchParameters},
- callback: callback
- });
-};
-
-IndexCore.prototype.searchFacet = deprecate(function(params, callback) {
- return this.searchForFacetValues(params, callback);
-}, deprecatedMessage(
- 'index.searchFacet(params[, callback])',
- 'index.searchForFacetValues(params[, callback])'
-));
-
-IndexCore.prototype._search = function(params, url, callback, additionalUA) {
- return this.as._jsonRequest({
- cache: this.cache,
- method: 'POST',
- url: url || '/1/indexes/' + encodeURIComponent(this.indexName) + '/query',
- body: {params: params},
- hostType: 'read',
- fallback: {
- method: 'GET',
- url: '/1/indexes/' + encodeURIComponent(this.indexName),
- body: {params: params}
- },
- callback: callback,
- additionalUA: additionalUA
- });
-};
-
-/*
-* Get an object from this index
-*
-* @param objectID the unique identifier of the object to retrieve
-* @param attrs (optional) if set, contains the array of attribute names to retrieve
-* @param callback (optional) the result callback called with two arguments
-* error: null or Error('message')
-* content: the object to retrieve or the error message if a failure occurred
-*/
-IndexCore.prototype.getObject = function(objectID, attrs, callback) {
- var indexObj = this;
-
- if (arguments.length === 1 || typeof attrs === 'function') {
- callback = attrs;
- attrs = undefined;
- }
-
- var params = '';
- if (attrs !== undefined) {
- params = '?attributes=';
- for (var i = 0; i < attrs.length; ++i) {
- if (i !== 0) {
- params += ',';
- }
- params += attrs[i];
- }
- }
-
- return this.as._jsonRequest({
- method: 'GET',
- url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/' + encodeURIComponent(objectID) + params,
- hostType: 'read',
- callback: callback
- });
-};
-
-/*
-* Get several objects from this index
-*
-* @param objectIDs the array of unique identifier of objects to retrieve
-*/
-IndexCore.prototype.getObjects = function(objectIDs, attributesToRetrieve, callback) {
- var isArray = require(8);
- var map = require(33);
-
- var usage = 'Usage: index.getObjects(arrayOfObjectIDs[, callback])';
-
- if (!isArray(objectIDs)) {
- throw new Error(usage);
- }
-
- var indexObj = this;
-
- if (arguments.length === 1 || typeof attributesToRetrieve === 'function') {
- callback = attributesToRetrieve;
- attributesToRetrieve = undefined;
- }
-
- var body = {
- requests: map(objectIDs, function prepareRequest(objectID) {
- var request = {
- indexName: indexObj.indexName,
- objectID: objectID
- };
-
- if (attributesToRetrieve) {
- request.attributesToRetrieve = attributesToRetrieve.join(',');
- }
-
- return request;
- })
- };
-
- return this.as._jsonRequest({
- method: 'POST',
- url: '/1/indexes/*/objects',
- hostType: 'read',
- body: body,
- callback: callback
- });
-};
-
-IndexCore.prototype.as = null;
-IndexCore.prototype.indexName = null;
-IndexCore.prototype.typeAheadArgs = null;
-IndexCore.prototype.typeAheadValueOption = null;
-
-},{"26":26,"27":27,"29":29,"30":30,"33":33,"34":34,"35":35,"8":8}],21:[function(require,module,exports){
-(function (process){
-'use strict';
-
-// This is the AngularJS Algolia Search module
-// It's using $http to do requests with a JSONP fallback
-// $q promises are returned
-
-var inherits = require(7);
-
-var forEach = require(5);
-
-var AlgoliaSearch = require(16);
-var errors = require(31);
-var inlineHeaders = require(24);
-var jsonpRequest = require(25);
-var places = require(36);
-
-// expose original algoliasearch fn in window
-window.algoliasearch = require(22);
-
-if (process.env.NODE_ENV === 'debug') {
- require(1).enable('algoliasearch*');
-}
-
-window.angular.module('algoliasearch', [])
- .service('algolia', ['$http', '$q', '$timeout', function algoliaSearchService($http, $q, $timeout) {
- function algoliasearch(applicationID, apiKey, opts) {
- var cloneDeep = require(27);
-
- opts = cloneDeep(opts || {});
-
- opts._ua = opts._ua || algoliasearch.ua;
-
- return new AlgoliaSearchAngular(applicationID, apiKey, opts);
- }
-
- algoliasearch.version = require(38);
-
- algoliasearch.ua =
- 'Algolia for JavaScript (' + algoliasearch.version + '); ' +
- 'AngularJS (' + window.angular.version.full + ')';
-
- algoliasearch.initPlaces = places(algoliasearch);
-
- // we expose into window no matter how we are used, this will allow
- // us to easily debug any website running algolia
- window.__algolia = {
- debug: require(1),
- algoliasearch: algoliasearch
- };
-
- function AlgoliaSearchAngular() {
- // call AlgoliaSearch constructor
- AlgoliaSearch.apply(this, arguments);
- }
-
- inherits(AlgoliaSearchAngular, AlgoliaSearch);
-
- AlgoliaSearchAngular.prototype._request = function request(url, opts) {
- // Support most Angular.js versions by using $q.defer() instead
- // of the new $q() constructor everywhere we need a promise
- var deferred = $q.defer();
- var resolve = deferred.resolve;
- var reject = deferred.reject;
-
- var timedOut;
- var body = opts.body;
-
- url = inlineHeaders(url, opts.headers);
-
- var timeoutDeferred = $q.defer();
- var timeoutPromise = timeoutDeferred.promise;
-
- $timeout(function timedout() {
- timedOut = true;
- // will cancel the xhr
- timeoutDeferred.resolve('test');
- reject(new errors.RequestTimeout());
- }, opts.timeouts.complete);
-
- var requestHeaders = {};
-
- // "remove" (set to undefined) possible globally set headers
- // in $httpProvider.defaults.headers.common
- // otherwise we might fail sometimes
- // ref: https://github.com/algolia/algoliasearch-client-js/issues/135
- forEach(
- $http.defaults.headers.common,
- function removeIt(headerValue, headerName) {
- requestHeaders[headerName] = undefined;
- }
- );
-
- requestHeaders.accept = 'application/json';
-
- if (body) {
- if (opts.method === 'POST') {
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests
- requestHeaders['content-type'] = 'application/x-www-form-urlencoded';
- } else {
- requestHeaders['content-type'] = 'application/json';
- }
- }
-
- $http({
- url: url,
- method: opts.method,
- data: body,
- cache: false,
- timeout: timeoutPromise,
- headers: requestHeaders,
- transformResponse: transformResponse,
- // if client uses $httpProvider.defaults.withCredentials = true,
- // we revert it to false to avoid CORS failure
- withCredentials: false
- }).then(success, error);
-
- function success(response) {
- resolve({
- statusCode: response.status,
- headers: response.headers,
- body: JSON.parse(response.data),
- responseText: response.data
- });
- }
-
- // we force getting the raw data because we need it so
- // for cache keys
- function transformResponse(data) {
- return data;
- }
-
- function error(response) {
- if (timedOut) {
- return;
- }
-
- // network error
- if (response.status === 0) {
- reject(
- new errors.Network({
- more: response
- })
- );
- return;
- }
-
- resolve({
- body: JSON.parse(response.data),
- statusCode: response.status
- });
- }
-
- return deferred.promise;
- };
-
- // using IE8 or IE9 we will always end up here
- // AngularJS does not fallback to XDomainRequest
- AlgoliaSearchAngular.prototype._request.fallback = function requestFallback(url, opts) {
- url = inlineHeaders(url, opts.headers);
-
- var deferred = $q.defer();
- var resolve = deferred.resolve;
- var reject = deferred.reject;
-
- jsonpRequest(url, opts, function jsonpRequestDone(err, content) {
- if (err) {
- reject(err);
- return;
- }
-
- resolve(content);
- });
-
- return deferred.promise;
- };
-
- AlgoliaSearchAngular.prototype._promise = {
- reject: function(val) {
- return $q.reject(val);
- },
- resolve: function(val) {
- // http://www.bennadel.com/blog/2735-q-when-is-the-missing-q-resolve-method-in-angularjs.htm
- return $q.when(val);
- },
- delay: function(ms) {
- var deferred = $q.defer();
- var resolve = deferred.resolve;
-
- $timeout(resolve, ms);
-
- return deferred.promise;
- },
- all: function(promises) {
- return $q.all(promises);
- }
- };
-
- return {
- Client: function(applicationID, apiKey, options) {
- return algoliasearch(applicationID, apiKey, options);
- },
- ua: algoliasearch.ua,
- version: algoliasearch.version
- };
- }]);
-
-}).call(this,require(12))
-},{"1":1,"12":12,"16":16,"22":22,"24":24,"25":25,"27":27,"31":31,"36":36,"38":38,"5":5,"7":7}],22:[function(require,module,exports){
-'use strict';
-
-var AlgoliaSearch = require(16);
-var createAlgoliasearch = require(23);
-
-module.exports = createAlgoliasearch(AlgoliaSearch, 'Browser');
-
-},{"16":16,"23":23}],23:[function(require,module,exports){
-(function (process){
-'use strict';
-
-var global = require(6);
-var Promise = global.Promise || require(3).Promise;
-
-// This is the standalone browser build entry point
-// Browser implementation of the Algolia Search JavaScript client,
-// using XMLHttpRequest, XDomainRequest and JSONP as fallback
-module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) {
- var inherits = require(7);
- var errors = require(31);
- var inlineHeaders = require(24);
- var jsonpRequest = require(25);
- var places = require(36);
- uaSuffix = uaSuffix || '';
-
- if (process.env.NODE_ENV === 'debug') {
- require(1).enable('algoliasearch*');
- }
-
- function algoliasearch(applicationID, apiKey, opts) {
- var cloneDeep = require(27);
-
- opts = cloneDeep(opts || {});
-
- opts._ua = opts._ua || algoliasearch.ua;
-
- return new AlgoliaSearchBrowser(applicationID, apiKey, opts);
- }
-
- algoliasearch.version = require(38);
-
- algoliasearch.ua =
- 'Algolia for JavaScript (' + algoliasearch.version + '); ' + uaSuffix;
-
- algoliasearch.initPlaces = places(algoliasearch);
-
- // we expose into window no matter how we are used, this will allow
- // us to easily debug any website running algolia
- global.__algolia = {
- debug: require(1),
- algoliasearch: algoliasearch
- };
-
- var support = {
- hasXMLHttpRequest: 'XMLHttpRequest' in global,
- hasXDomainRequest: 'XDomainRequest' in global
- };
-
- if (support.hasXMLHttpRequest) {
- support.cors = 'withCredentials' in new XMLHttpRequest();
- }
-
- function AlgoliaSearchBrowser() {
- // call AlgoliaSearch constructor
- AlgoliaSearch.apply(this, arguments);
- }
-
- inherits(AlgoliaSearchBrowser, AlgoliaSearch);
-
- AlgoliaSearchBrowser.prototype._request = function request(url, opts) {
- return new Promise(function wrapRequest(resolve, reject) {
- // no cors or XDomainRequest, no request
- if (!support.cors && !support.hasXDomainRequest) {
- // very old browser, not supported
- reject(new errors.Network('CORS not supported'));
- return;
- }
-
- url = inlineHeaders(url, opts.headers);
-
- var body = opts.body;
- var req = support.cors ? new XMLHttpRequest() : new XDomainRequest();
- var reqTimeout;
- var timedOut;
- var connected = false;
-
- reqTimeout = setTimeout(onTimeout, opts.timeouts.connect);
- // we set an empty onprogress listener
- // so that XDomainRequest on IE9 is not aborted
- // refs:
- // - https://github.com/algolia/algoliasearch-client-js/issues/76
- // - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment
- req.onprogress = onProgress;
- if ('onreadystatechange' in req) req.onreadystatechange = onReadyStateChange;
- req.onload = onLoad;
- req.onerror = onError;
-
- // do not rely on default XHR async flag, as some analytics code like hotjar
- // breaks it and set it to false by default
- if (req instanceof XMLHttpRequest) {
- req.open(opts.method, url, true);
-
- // The Analytics API never accepts Auth headers as query string
- // this option exists specifically for them.
- if (opts.forceAuthHeaders) {
- req.setRequestHeader(
- 'x-algolia-application-id',
- opts.headers['x-algolia-application-id']
- );
- req.setRequestHeader(
- 'x-algolia-api-key',
- opts.headers['x-algolia-api-key']
- );
- }
- } else {
- req.open(opts.method, url);
- }
-
- // headers are meant to be sent after open
- if (support.cors) {
- if (body) {
- if (opts.method === 'POST') {
- // https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests
- req.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
- } else {
- req.setRequestHeader('content-type', 'application/json');
- }
- }
- req.setRequestHeader('accept', 'application/json');
- }
-
- if (body) {
- req.send(body);
- } else {
- req.send();
- }
-
- // event object not received in IE8, at least
- // but we do not use it, still important to note
- function onLoad(/* event */) {
- // When browser does not supports req.timeout, we can
- // have both a load and timeout event, since handled by a dumb setTimeout
- if (timedOut) {
- return;
- }
-
- clearTimeout(reqTimeout);
-
- var out;
-
- try {
- out = {
- body: JSON.parse(req.responseText),
- responseText: req.responseText,
- statusCode: req.status,
- // XDomainRequest does not have any response headers
- headers: req.getAllResponseHeaders && req.getAllResponseHeaders() || {}
- };
- } catch (e) {
- out = new errors.UnparsableJSON({
- more: req.responseText
- });
- }
-
- if (out instanceof errors.UnparsableJSON) {
- reject(out);
- } else {
- resolve(out);
- }
- }
-
- function onError(event) {
- if (timedOut) {
- return;
- }
-
- clearTimeout(reqTimeout);
-
- // error event is trigerred both with XDR/XHR on:
- // - DNS error
- // - unallowed cross domain request
- reject(
- new errors.Network({
- more: event
- })
- );
- }
-
- function onTimeout() {
- timedOut = true;
- req.abort();
-
- reject(new errors.RequestTimeout());
- }
-
- function onConnect() {
- connected = true;
- clearTimeout(reqTimeout);
- reqTimeout = setTimeout(onTimeout, opts.timeouts.complete);
- }
-
- function onProgress() {
- if (!connected) onConnect();
- }
-
- function onReadyStateChange() {
- if (!connected && req.readyState > 1) onConnect();
- }
- });
- };
-
- AlgoliaSearchBrowser.prototype._request.fallback = function requestFallback(url, opts) {
- url = inlineHeaders(url, opts.headers);
-
- return new Promise(function wrapJsonpRequest(resolve, reject) {
- jsonpRequest(url, opts, function jsonpRequestDone(err, content) {
- if (err) {
- reject(err);
- return;
- }
-
- resolve(content);
- });
- });
- };
-
- AlgoliaSearchBrowser.prototype._promise = {
- reject: function rejectPromise(val) {
- return Promise.reject(val);
- },
- resolve: function resolvePromise(val) {
- return Promise.resolve(val);
- },
- delay: function delayPromise(ms) {
- return new Promise(function resolveOnTimeout(resolve/* , reject*/) {
- setTimeout(resolve, ms);
- });
- },
- all: function all(promises) {
- return Promise.all(promises);
- }
- };
-
- return algoliasearch;
-};
-
-}).call(this,require(12))
-},{"1":1,"12":12,"24":24,"25":25,"27":27,"3":3,"31":31,"36":36,"38":38,"6":6,"7":7}],24:[function(require,module,exports){
-'use strict';
-
-module.exports = inlineHeaders;
-
-var encode = require(14);
-
-function inlineHeaders(url, headers) {
- if (/\?/.test(url)) {
- url += '&';
- } else {
- url += '?';
- }
-
- return url + encode(headers);
-}
-
-},{"14":14}],25:[function(require,module,exports){
-'use strict';
-
-module.exports = jsonpRequest;
-
-var errors = require(31);
-
-var JSONPCounter = 0;
-
-function jsonpRequest(url, opts, cb) {
- if (opts.method !== 'GET') {
- cb(new Error('Method ' + opts.method + ' ' + url + ' is not supported by JSONP.'));
- return;
- }
-
- opts.debug('JSONP: start');
-
- var cbCalled = false;
- var timedOut = false;
-
- JSONPCounter += 1;
- var head = document.getElementsByTagName('head')[0];
- var script = document.createElement('script');
- var cbName = 'algoliaJSONP_' + JSONPCounter;
- var done = false;
-
- window[cbName] = function(data) {
- removeGlobals();
-
- if (timedOut) {
- opts.debug('JSONP: Late answer, ignoring');
- return;
- }
-
- cbCalled = true;
-
- clean();
-
- cb(null, {
- body: data,
- responseText: JSON.stringify(data)/* ,
- // We do not send the statusCode, there's no statusCode in JSONP, it will be
- // computed using data.status && data.message like with XDR
- statusCode*/
- });
- };
-
- // add callback by hand
- url += '&callback=' + cbName;
-
- // add body params manually
- if (opts.jsonBody && opts.jsonBody.params) {
- url += '&' + opts.jsonBody.params;
- }
-
- var ontimeout = setTimeout(timeout, opts.timeouts.complete);
-
- // script onreadystatechange needed only for
- // <= IE8
- // https://github.com/angular/angular.js/issues/4523
- script.onreadystatechange = readystatechange;
- script.onload = success;
- script.onerror = error;
-
- script.async = true;
- script.defer = true;
- script.src = url;
- head.appendChild(script);
-
- function success() {
- opts.debug('JSONP: success');
-
- if (done || timedOut) {
- return;
- }
-
- done = true;
-
- // script loaded but did not call the fn => script loading error
- if (!cbCalled) {
- opts.debug('JSONP: Fail. Script loaded but did not call the callback');
- clean();
- cb(new errors.JSONPScriptFail());
- }
- }
-
- function readystatechange() {
- if (this.readyState === 'loaded' || this.readyState === 'complete') {
- success();
- }
- }
-
- function clean() {
- clearTimeout(ontimeout);
- script.onload = null;
- script.onreadystatechange = null;
- script.onerror = null;
- head.removeChild(script);
- }
-
- function removeGlobals() {
- try {
- delete window[cbName];
- delete window[cbName + '_loaded'];
- } catch (e) {
- window[cbName] = window[cbName + '_loaded'] = undefined;
- }
- }
-
- function timeout() {
- opts.debug('JSONP: Script timeout');
- timedOut = true;
- clean();
- cb(new errors.RequestTimeout());
- }
-
- function error() {
- opts.debug('JSONP: Script error');
-
- if (done || timedOut) {
- return;
- }
-
- clean();
- cb(new errors.JSONPScriptError());
- }
-}
-
-},{"31":31}],26:[function(require,module,exports){
-module.exports = buildSearchMethod;
-
-var errors = require(31);
-
-/**
- * Creates a search method to be used in clients
- * @param {string} queryParam the name of the attribute used for the query
- * @param {string} url the url
- * @return {function} the search method
- */
-function buildSearchMethod(queryParam, url) {
- /**
- * The search method. Prepares the data and send the query to Algolia.
- * @param {string} query the string used for query search
- * @param {object} args additional parameters to send with the search
- * @param {function} [callback] the callback to be called with the client gets the answer
- * @return {undefined|Promise} If the callback is not provided then this methods returns a Promise
- */
- return function search(query, args, callback) {
- // warn V2 users on how to search
- if (typeof query === 'function' && typeof args === 'object' ||
- typeof callback === 'object') {
- // .search(query, params, cb)
- // .search(cb, params)
- throw new errors.AlgoliaSearchError('index.search usage is index.search(query, params, cb)');
- }
-
- // Normalizing the function signature
- if (arguments.length === 0 || typeof query === 'function') {
- // Usage : .search(), .search(cb)
- callback = query;
- query = '';
- } else if (arguments.length === 1 || typeof args === 'function') {
- // Usage : .search(query/args), .search(query, cb)
- callback = args;
- args = undefined;
- }
- // At this point we have 3 arguments with values
-
- // Usage : .search(args) // careful: typeof null === 'object'
- if (typeof query === 'object' && query !== null) {
- args = query;
- query = undefined;
- } else if (query === undefined || query === null) { // .search(undefined/null)
- query = '';
- }
-
- var params = '';
-
- if (query !== undefined) {
- params += queryParam + '=' + encodeURIComponent(query);
- }
-
- var additionalUA;
- if (args !== undefined) {
- if (args.additionalUA) {
- additionalUA = args.additionalUA;
- delete args.additionalUA;
- }
- // `_getSearchParams` will augment params, do not be fooled by the = versus += from previous if
- params = this.as._getSearchParams(args, params);
- }
-
-
- return this._search(params, url, callback, additionalUA);
- };
-}
-
-},{"31":31}],27:[function(require,module,exports){
-module.exports = function clone(obj) {
- return JSON.parse(JSON.stringify(obj));
-};
-
-},{}],28:[function(require,module,exports){
-module.exports = createAnalyticsClient;
-
-var algoliasearch = require(22);
-
-function createAnalyticsClient(appId, apiKey, opts) {
- var analytics = {};
-
- opts = opts || {};
- // there need to be 4 hosts, like on the client, since if requests fail,
- // the counter goes up by 1, so we need to have the same amount of hosts
- // 4 because: -dsn, -1, -2, -3
- // This is done because the APPID used for search will be the same for the analytics client created,
- // and since the state of available hosts is shared by APPID globally for the module, we had issues
- // where the hostIndex would be 1 while the array was only one entry (you got an empty host)
- opts.hosts = opts.hosts || [
- 'analytics.algolia.com',
- 'analytics.algolia.com',
- 'analytics.algolia.com',
- 'analytics.algolia.com'
- ];
- opts.protocol = opts.protocol || 'https:';
-
- analytics.as = algoliasearch(appId, apiKey, opts);
-
- analytics.getABTests = function(_params, callback) {
- var params = params || {};
- var offset = params.offset || 0;
- var limit = params.limit || 10;
-
- return this.as._jsonRequest({
- method: 'GET',
- url: '/2/abtests?offset=' + encodeURIComponent(offset) + '&limit=' + encodeURIComponent(limit),
- hostType: 'read',
- forceAuthHeaders: true,
- callback: callback
- });
- };
-
- analytics.getABTest = function(abTestID, callback) {
- return this.as._jsonRequest({
- method: 'GET',
- url: '/2/abtests/' + encodeURIComponent(abTestID),
- hostType: 'read',
- forceAuthHeaders: true,
- callback: callback
- });
- };
-
- analytics.addABTest = function(abTest, callback) {
- return this.as._jsonRequest({
- method: 'POST',
- url: '/2/abtests',
- body: abTest,
- hostType: 'read',
- forceAuthHeaders: true,
- callback: callback
- });
- };
-
- analytics.stopABTest = function(abTestID, callback) {
- return this.as._jsonRequest({
- method: 'POST',
- url: '/2/abtests/' + encodeURIComponent(abTestID) + '/stop',
- hostType: 'read',
- forceAuthHeaders: true,
- callback: callback
- });
- };
-
- analytics.deleteABTest = function(abTestID, callback) {
- return this.as._jsonRequest({
- method: 'DELETE',
- url: '/2/abtests/' + encodeURIComponent(abTestID),
- hostType: 'write',
- forceAuthHeaders: true,
- callback: callback
- });
- };
-
- analytics.waitTask = function(indexName, taskID, callback) {
- return this.as.initIndex(indexName).waitTask(taskID, callback);
- };
-
- return analytics;
-}
-
-},{"22":22}],29:[function(require,module,exports){
-module.exports = function deprecate(fn, message) {
- var warned = false;
-
- function deprecated() {
- if (!warned) {
- /* eslint no-console:0 */
- console.warn(message);
- warned = true;
- }
-
- return fn.apply(this, arguments);
- }
-
- return deprecated;
-};
-
-},{}],30:[function(require,module,exports){
-module.exports = function deprecatedMessage(previousUsage, newUsage) {
- var githubAnchorLink = previousUsage.toLowerCase()
- .replace(/[\.\(\)]/g, '');
-
- return 'algoliasearch: `' + previousUsage + '` was replaced by `' + newUsage +
- '`. Please see https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated#' + githubAnchorLink;
-};
-
-},{}],31:[function(require,module,exports){
-'use strict';
-
-// This file hosts our error definitions
-// We use custom error "types" so that we can act on them when we need it
-// e.g.: if error instanceof errors.UnparsableJSON then..
-
-var inherits = require(7);
-
-function AlgoliaSearchError(message, extraProperties) {
- var forEach = require(5);
-
- var error = this;
-
- // try to get a stacktrace
- if (typeof Error.captureStackTrace === 'function') {
- Error.captureStackTrace(this, this.constructor);
- } else {
- error.stack = (new Error()).stack || 'Cannot get a stacktrace, browser is too old';
- }
-
- this.name = 'AlgoliaSearchError';
- this.message = message || 'Unknown error';
-
- if (extraProperties) {
- forEach(extraProperties, function addToErrorObject(value, key) {
- error[key] = value;
- });
- }
-}
-
-inherits(AlgoliaSearchError, Error);
-
-function createCustomError(name, message) {
- function AlgoliaSearchCustomError() {
- var args = Array.prototype.slice.call(arguments, 0);
-
- // custom message not set, use default
- if (typeof args[0] !== 'string') {
- args.unshift(message);
- }
-
- AlgoliaSearchError.apply(this, args);
- this.name = 'AlgoliaSearch' + name + 'Error';
- }
-
- inherits(AlgoliaSearchCustomError, AlgoliaSearchError);
-
- return AlgoliaSearchCustomError;
-}
-
-// late exports to let various fn defs and inherits take place
-module.exports = {
- AlgoliaSearchError: AlgoliaSearchError,
- UnparsableJSON: createCustomError(
- 'UnparsableJSON',
- 'Could not parse the incoming response as JSON, see err.more for details'
- ),
- RequestTimeout: createCustomError(
- 'RequestTimeout',
- 'Request timed out before getting a response'
- ),
- Network: createCustomError(
- 'Network',
- 'Network issue, see err.more for details'
- ),
- JSONPScriptFail: createCustomError(
- 'JSONPScriptFail',
- '"),window.ALGOLIA_SUPPORTS_DOCWRITE===!0?(document.write(''),n("document.write")()):r(o,n("DOMElement"))}catch(s){r(o,n("DOMElement"))}}function n(e){return function(){var t="AlgoliaSearch: loaded V2 script using "+e;window.console&&window.console.log&&window.console.log(t)}}t.exports=o},{1:1}],4:[function(e,t,r){"use strict";function o(){var e="-- AlgoliaSearch V2 => V3 error --\nYou are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\nPlease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch V2 => V3 error --";window.AlgoliaSearch=function(){throw new Error(e)},window.AlgoliaSearchHelper=function(){throw new Error(e)},window.AlgoliaExplainResults=function(){throw new Error(e)}}t.exports=o},{}],5:[function(e,t,r){"use strict";function o(t){var r=e(2),o=e(3),n=e(4);r(t)?o(t):n()}o("algoliasearch.angular")},{2:2,3:3,4:4}]},{},[5])(5)}),function e(t,r,o){function n(s,a){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var l=r[s]={exports:{}};t[s][0].call(l.exports,function(e){var r=t[s][1][e];return n(r?r:e)},l,l.exports,e,t,r,o)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;s=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(e){var t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+r.humanize(this.diff),t){var o="color: "+this.color;e.splice(1,0,o,"color: inherit");var n=0,i=0;e[0].replace(/%[a-zA-Z%]/g,function(e){"%%"!==e&&(n++,"%c"===e&&(i=n))}),e.splice(i,0,o)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(e){try{null==e?r.storage.removeItem("debug"):r.storage.debug=e}catch(t){}}function c(){var e;try{e=r.storage.debug}catch(t){}return!e&&"undefined"!=typeof o&&"env"in o&&(e=o.env.DEBUG),e}function u(){try{return window.localStorage}catch(e){}}r=t.exports=e(2),r.log=s,r.formatArgs=i,r.save=a,r.load=c,r.useColors=n,r.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),r.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],r.formatters.j=function(e){try{return JSON.stringify(e)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}},r.enable(c())}).call(this,e(12))},{12:12,2:2}],2:[function(e,t,r){function o(e){var t,o=0;for(t in e)o=(o<<5)-o+e.charCodeAt(t),o|=0;return r.colors[Math.abs(o)%r.colors.length]}function n(e){function t(){if(t.enabled){var e=t,o=+new Date,n=o-(u||o);e.diff=n,e.prev=u,e.curr=o,u=o;for(var i=new Array(arguments.length),s=0;s0&&this._events[e].length>r&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},o.prototype.on=o.prototype.addListener,o.prototype.once=function(e,t){function r(){this.removeListener(e,r),o||(o=!0,t.apply(this,arguments))}if(!n(t))throw TypeError("listener must be a function");var o=!1;return r.listener=t,this.on(e,r),this},o.prototype.removeListener=function(e,t){var r,o,i,a;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(r=this._events[e],i=r.length,o=-1,r===t||n(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(r)){for(a=i;a-- >0;)if(r[a]===t||r[a].listener&&r[a].listener===t){o=a;break}if(o<0)return this;1===r.length?(r.length=0,delete this._events[e]):r.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},o.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r=this._events[e],n(r))this.removeListener(e,r);else if(r)for(;r.length;)this.removeListener(e,r[r.length-1]);return delete this._events[e],this},o.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?n(this._events[e])?[this._events[e]]:this._events[e].slice():[]},o.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(n(t))return 1;if(t)return t.length}return 0},o.listenerCount=function(e,t){return e.listenerCount(t)}},{}],5:[function(e,t,r){var o=Object.prototype.hasOwnProperty,n=Object.prototype.toString;t.exports=function(e,t,r){if("[object Function]"!==n.call(t))throw new TypeError("iterator must be a function");var i=e.length;if(i===+i)for(var s=0;s100)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var r=parseFloat(t[1]),o=(t[2]||"ms").toLowerCase();switch(o){case"years":case"year":case"yrs":case"yr":case"y":return r*p;case"days":case"day":case"d":return r*l;case"hours":case"hour":case"hrs":case"hr":case"h":return r*u;case"minutes":case"minute":case"mins":case"min":case"m":return r*c;case"seconds":case"second":case"secs":case"sec":case"s":return r*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}}}function n(e){return e>=l?Math.round(e/l)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function i(e){return s(e,l,"day")||s(e,u,"hour")||s(e,c,"minute")||s(e,a,"second")||e+" ms"}function s(e,t,r){if(!(e0)return o(e);if("number"===r&&isNaN(e)===!1)return t["long"]?i(e):n(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},{}],10:[function(e,t,r){"use strict";var o=Object.prototype.hasOwnProperty,n=Object.prototype.toString,i=Array.prototype.slice,s=e(11),a=Object.prototype.propertyIsEnumerable,c=!a.call({toString:null},"toString"),u=a.call(function(){},"prototype"),l=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],p=function(e){var t=e.constructor;return t&&t.prototype===e},d={$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},h=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!d["$"+e]&&o.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{p(window[e])}catch(t){return!0}}catch(t){return!0}return!1}(),f=function(e){if("undefined"==typeof window||!h)return p(e);try{return p(e)}catch(t){return!1}},y=function(e){var t=null!==e&&"object"==typeof e,r="[object Function]"===n.call(e),i=s(e),a=t&&"[object String]"===n.call(e),p=[];if(!t&&!r&&!i)throw new TypeError("Object.keys called on a non-object");var d=u&&r;if(a&&e.length>0&&!o.call(e,0))for(var h=0;h0)for(var y=0;y=0&&"[object Function]"===o.call(e.callee)),r}},{}],12:[function(e,t,r){function o(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function i(e){if(p===setTimeout)return setTimeout(e,0);if((p===o||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function s(e){if(d===clearTimeout)return clearTimeout(e);if((d===n||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(e);try{return d(e)}catch(t){try{return d.call(null,e)}catch(t){return d.call(this,e)}}}function a(){m&&f&&(m=!1,f.length?y=f.concat(y):v=-1,y.length&&c())}function c(){if(!m){var e=i(a);m=!0;for(var t=y.length;t;){for(f=y,y=[];++v1)for(var r=1;r0&&u>c&&(u=c);for(var l=0;l=0?(p=y.substr(0,m),d=y.substr(m+1)):(p=y,d=""),h=decodeURIComponent(p),f=decodeURIComponent(d),o(s,h)?n(s[h])?s[h].push(f):s[h]=[s[h],f]:s[h]=f}return s};var n=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},{}],14:[function(e,t,r){"use strict";function o(e,t){if(e.map)return e.map(t);for(var r=[],o=0;o0)n.scope=r;else if("undefined"!=typeof r)throw new Error("the scope given to `copyIndex` was not an array with settings, synonyms or rules");return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:n,hostType:"write",callback:i})},o.prototype.getLogs=function(t,r,o){var n=e(27),i={};return"object"==typeof t?(i=n(t),o=r):0===arguments.length||"function"==typeof t?o=t:1===arguments.length||"function"==typeof r?(o=r,i.offset=t):(i.offset=t,i.length=r),void 0===i.offset&&(i.offset=0),void 0===i.length&&(i.length=10),this._jsonRequest({method:"GET",url:"/1/logs?"+this._getSearchParams(i,""),hostType:"read",callback:o})},o.prototype.listIndexes=function(e,t){var r="";return void 0===e||"function"==typeof e?t=e:r="?page="+e,this._jsonRequest({method:"GET",url:"/1/indexes"+r,hostType:"read",callback:t})},o.prototype.initIndex=function(e){return new i(this,e)},o.prototype.initAnalytics=function(t){var r=e(28);return r(this.applicationID,this.apiKey,t)},o.prototype.listUserKeys=s(function(e){return this.listApiKeys(e)},a("client.listUserKeys()","client.listApiKeys()")),o.prototype.listApiKeys=function(e){return this._jsonRequest({method:"GET",url:"/1/keys",hostType:"read",callback:e})},o.prototype.getUserKeyACL=s(function(e,t){return this.getApiKey(e,t)},a("client.getUserKeyACL()","client.getApiKey()")),o.prototype.getApiKey=function(e,t){return this._jsonRequest({method:"GET",url:"/1/keys/"+e,hostType:"read",callback:t})},o.prototype.deleteUserKey=s(function(e,t){return this.deleteApiKey(e,t)},a("client.deleteUserKey()","client.deleteApiKey()")),o.prototype.deleteApiKey=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/keys/"+e,hostType:"write",callback:t})},o.prototype.restoreApiKey=function(e,t){return this._jsonRequest({method:"POST",url:"/1/keys/"+e+"/restore",hostType:"write",callback:t})},o.prototype.addUserKey=s(function(e,t,r){return this.addApiKey(e,t,r)},a("client.addUserKey()","client.addApiKey()")),o.prototype.addApiKey=function(t,r,o){var n=e(8),i="Usage: client.addApiKey(arrayOfAcls[, params, callback])";if(!n(t))throw new Error(i);1!==arguments.length&&"function"!=typeof r||(o=r,r=null);var s={acl:t};return r&&(s.validity=r.validity,s.maxQueriesPerIPPerHour=r.maxQueriesPerIPPerHour,s.maxHitsPerQuery=r.maxHitsPerQuery,s.indexes=r.indexes,s.description=r.description,r.queryParameters&&(s.queryParameters=this._getSearchParams(r.queryParameters,"")),s.referers=r.referers),this._jsonRequest({method:"POST",url:"/1/keys",body:s,hostType:"write",callback:o})},o.prototype.addUserKeyWithValidity=s(function(e,t,r){return this.addApiKey(e,t,r)},a("client.addUserKeyWithValidity()","client.addApiKey()")),o.prototype.updateUserKey=s(function(e,t,r,o){return this.updateApiKey(e,t,r,o)},a("client.updateUserKey()","client.updateApiKey()")),o.prototype.updateApiKey=function(t,r,o,n){var i=e(8),s="Usage: client.updateApiKey(key, arrayOfAcls[, params, callback])";if(!i(r))throw new Error(s);2!==arguments.length&&"function"!=typeof o||(n=o,o=null);var a={acl:r};return o&&(a.validity=o.validity,a.maxQueriesPerIPPerHour=o.maxQueriesPerIPPerHour,a.maxHitsPerQuery=o.maxHitsPerQuery,a.indexes=o.indexes,a.description=o.description,o.queryParameters&&(a.queryParameters=this._getSearchParams(o.queryParameters,"")),a.referers=o.referers),this._jsonRequest({method:"PUT",url:"/1/keys/"+t,body:a,hostType:"write",callback:n})},o.prototype.startQueriesBatch=s(function(){this._batch=[]},a("client.startQueriesBatch()","client.search()")),o.prototype.addQueryInBatch=s(function(e,t,r){this._batch.push({indexName:e,query:t,params:r})},a("client.addQueryInBatch()","client.search()")),o.prototype.sendQueriesBatch=s(function(e){return this.search(this._batch,e)},a("client.sendQueriesBatch()","client.search()")),o.prototype.batch=function(t,r){var o=e(8),n="Usage: client.batch(operations[, callback])";if(!o(t))throw new Error(n);return this._jsonRequest({method:"POST",url:"/1/indexes/*/batch",body:{requests:t},hostType:"write",callback:r})},o.prototype.assignUserID=function(e,t){if(!e.userID||!e.cluster)throw new l.AlgoliaSearchError("You have to provide both a userID and cluster",e);return this._jsonRequest({method:"POST",url:"/1/clusters/mapping",hostType:"write",body:{cluster:e.cluster},callback:t,headers:{"x-algolia-user-id":e.userID}})},o.prototype.assignUserIDs=function(e,t){if(!e.userIDs||!e.cluster)throw new l.AlgoliaSearchError("You have to provide both an array of userIDs and cluster",e);return this._jsonRequest({method:"POST",url:"/1/clusters/mapping/batch",hostType:"write",body:{cluster:e.cluster,users:e.userIDs},callback:t})},o.prototype.getTopUserID=function(e){return this._jsonRequest({method:"GET",url:"/1/clusters/mapping/top",hostType:"read",callback:e})},o.prototype.getUserID=function(e,t){if(!e.userID)throw new l.AlgoliaSearchError("You have to provide a userID",{debugData:e});return this._jsonRequest({method:"GET",url:"/1/clusters/mapping/"+e.userID,hostType:"read",callback:t})},o.prototype.listClusters=function(e){return this._jsonRequest({method:"GET",url:"/1/clusters",hostType:"read",callback:e})},o.prototype.listUserIDs=function(e,t){return this._jsonRequest({method:"GET",url:"/1/clusters/mapping",body:e,hostType:"read",callback:t})},o.prototype.removeUserID=function(e,t){if(!e.userID)throw new l.AlgoliaSearchError("You have to provide a userID",{debugData:e});return this._jsonRequest({method:"DELETE",url:"/1/clusters/mapping",hostType:"write",callback:t,headers:{"x-algolia-user-id":e.userID}})},o.prototype.searchUserIDs=function(e,t){return this._jsonRequest({method:"POST",url:"/1/clusters/mapping/search",body:e,hostType:"read",callback:t})},o.prototype.setPersonalizationStrategy=function(e,t){return this._jsonRequest({method:"POST",url:"/1/recommendation/personalization/strategy",body:e,hostType:"write",callback:t})},o.prototype.getPersonalizationStrategy=function(e){return this._jsonRequest({method:"GET",url:"/1/recommendation/personalization/strategy",hostType:"read",callback:e})},o.prototype.destroy=n,o.prototype.enableRateLimitForward=n,o.prototype.disableRateLimitForward=n,o.prototype.useSecuredAPIKey=n,o.prototype.disableSecuredAPIKey=n,o.prototype.generateSecuredApiKey=n,o.prototype.getSecuredApiKeyRemainingValidity=n},{17:17,18:18,27:27,28:28,29:29,30:30,31:31,7:7,8:8}],17:[function(e,t,r){(function(r){function o(t,r,o){var i=e(1)("algoliasearch"),s=e(27),a=e(8),u=e(33),l="Usage: algoliasearch(applicationID, apiKey, opts)";if(o._allowEmptyCredentials!==!0&&!t)throw new c.AlgoliaSearchError("Please provide an application ID. "+l);if(o._allowEmptyCredentials!==!0&&!r)throw new c.AlgoliaSearchError("Please provide an API key. "+l);
-this.applicationID=t,this.apiKey=r,this.hosts={read:[],write:[]},o=o||{},this._timeouts=o.timeouts||{connect:1e3,read:2e3,write:3e4},o.timeout&&(this._timeouts.connect=this._timeouts.read=this._timeouts.write=o.timeout);var p=o.protocol||"https:";if(/:$/.test(p)||(p+=":"),"http:"!==p&&"https:"!==p)throw new c.AlgoliaSearchError("protocol must be `http:` or `https:` (was `"+o.protocol+"`)");if(this._checkAppIdData(),o.hosts)a(o.hosts)?(this.hosts.read=s(o.hosts),this.hosts.write=s(o.hosts)):(this.hosts.read=s(o.hosts.read),this.hosts.write=s(o.hosts.write));else{var d=u(this._shuffleResult,function(e){return t+"-"+e+".algolianet.com"}),h=(o.dsn===!1?"":"-dsn")+".algolia.net";this.hosts.read=[this.applicationID+h].concat(d),this.hosts.write=[this.applicationID+".algolia.net"].concat(d)}this.hosts.read=u(this.hosts.read,n(p)),this.hosts.write=u(this.hosts.write,n(p)),this.extraHeaders={},this.cache=o._cache||{},this._ua=o._ua,this._useCache=!(void 0!==o._useCache&&!o._cache)||o._useCache,this._useRequestCache=this._useCache&&o._useRequestCache,this._useFallback=void 0===o.useFallback||o.useFallback,this._setTimeout=o._setTimeout,i("init done, %j",this)}function n(e){return function(t){return e+"//"+t.toLowerCase()}}function i(e){if(void 0===Array.prototype.toJSON)return JSON.stringify(e);var t=Array.prototype.toJSON;delete Array.prototype.toJSON;var r=JSON.stringify(e);return Array.prototype.toJSON=t,r}function s(e){for(var t,r,o=e.length;0!==o;)r=Math.floor(Math.random()*o),o-=1,t=e[o],e[o]=e[r],e[r]=t;return e}function a(e){var t={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){var o;o="x-algolia-api-key"===r||"x-algolia-application-id"===r?"**hidden for security purposes**":e[r],t[r]=o}return t}t.exports=o;var c=e(31),u=e(32),l=e(20),p=e(37),d=500,h=r.env.RESET_APP_DATA_TIMER&&parseInt(r.env.RESET_APP_DATA_TIMER,10)||12e4;o.prototype.initIndex=function(e){return new l(this,e)},o.prototype.setExtraHeader=function(e,t){this.extraHeaders[e.toLowerCase()]=t},o.prototype.getExtraHeader=function(e){return this.extraHeaders[e.toLowerCase()]},o.prototype.unsetExtraHeader=function(e){delete this.extraHeaders[e.toLowerCase()]},o.prototype.addAlgoliaAgent=function(e){var t="; "+e;this._ua.indexOf(t)===-1&&(this._ua+=t)},o.prototype._jsonRequest=function(t){function r(e,n){function u(e){var t=e&&e.body&&e.body.message&&e.body.status||e.statusCode||e&&e.body&&200;h("received response: statusCode: %s, computed statusCode: %d, headers: %j",e.statusCode,t,e.headers);var r=2===Math.floor(t/100),o=new Date;if(w.push({currentHost:A,headers:a(p),content:s||null,contentLength:void 0!==s?s.length:null,method:n.method,timeouts:n.timeouts,url:n.url,startTime:x,endTime:o,duration:o-x,statusCode:t}),r)return m._useCache&&!m._useRequestCache&&y&&(y[l]=e.responseText),{responseText:e.responseText,body:e.body};var i=4!==Math.floor(t/100);if(i)return v+=1,_();h("unrecoverable error");var u=new c.AlgoliaSearchError(e.body&&e.body.message,{debugData:w,statusCode:t});return m._promise.reject(u)}function d(e){h("error: %s, stack: %s",e.message,e.stack);var r=new Date;return w.push({currentHost:A,headers:a(p),content:s||null,contentLength:void 0!==s?s.length:null,method:n.method,timeouts:n.timeouts,url:n.url,startTime:x,endTime:r,duration:r-x}),e instanceof c.AlgoliaSearchError||(e=new c.Unknown(e&&e.message,e)),v+=1,e instanceof c.Unknown||e instanceof c.UnparsableJSON||v>=m.hosts[t.hostType].length&&(g||!b)?(e.debugData=w,m._promise.reject(e)):e instanceof c.RequestTimeout?T():_()}function _(){return h("retrying request"),m._incrementHostIndex(t.hostType),r(e,n)}function T(){return h("retrying request with higher timeout"),m._incrementHostIndex(t.hostType),m._incrementTimeoutMultipler(),n.timeouts=m._getTimeoutsForRequest(t.hostType),r(e,n)}m._checkAppIdData();var x=new Date;if(m._useCache&&!m._useRequestCache&&(l=t.url),m._useCache&&!m._useRequestCache&&s&&(l+="_body_"+n.body),o(!m._useRequestCache,y,l)){h("serving response from cache");var R=y[l];return m._promise.resolve({body:JSON.parse(R),responseText:R})}if(v>=m.hosts[t.hostType].length)return!b||g?(h("could not get any response"),m._promise.reject(new c.AlgoliaSearchError("Cannot connect to the AlgoliaSearch API. Send an email to support@algolia.com to report and resolve the issue. Application id was: "+m.applicationID,{debugData:w}))):(h("switching to fallback"),v=0,n.method=t.fallback.method,n.url=t.fallback.url,n.jsonBody=t.fallback.body,n.jsonBody&&(n.body=i(n.jsonBody)),p=m._computeRequestHeaders({additionalUA:f,headers:t.headers}),n.timeouts=m._getTimeoutsForRequest(t.hostType),m._setHostIndexByType(0,t.hostType),g=!0,r(m._request.fallback,n));var A=m._getHostByType(t.hostType),j=A+n.url,S={body:n.body,jsonBody:n.jsonBody,method:n.method,headers:p,timeouts:n.timeouts,debug:h,forceAuthHeaders:n.forceAuthHeaders};return h("method: %s, url: %s, headers: %j, timeouts: %d",S.method,j,S.headers,S.timeouts),e===m._request.fallback&&h("using fallback"),e.call(m,j,S).then(u,d)}function o(e,t,r){return m._useCache&&e&&t&&void 0!==t[r]}function n(e,r){return o(m._useRequestCache,y,l)&&e["catch"](function(){delete y[l]}),"function"!=typeof t.callback?e.then(r):void e.then(function(e){u(function(){t.callback(null,r(e))},m._setTimeout||setTimeout)},function(e){u(function(){t.callback(e)},m._setTimeout||setTimeout)})}this._checkAppIdData();var s,l,p,h=e(1)("algoliasearch:"+t.url),f=t.additionalUA||"",y=t.cache,m=this,v=0,g=!1,b=m._useFallback&&m._request.fallback&&t.fallback;this.apiKey.length>d&&void 0!==t.body&&(void 0!==t.body.params||void 0!==t.body.requests)?(t.body.apiKey=this.apiKey,p=this._computeRequestHeaders({additionalUA:f,withApiKey:!1,headers:t.headers})):p=this._computeRequestHeaders({additionalUA:f,headers:t.headers}),void 0!==t.body&&(s=i(t.body)),h("request start");var w=[];if(m._useCache&&m._useRequestCache&&(l=t.url),m._useCache&&m._useRequestCache&&s&&(l+="_body_"+s),o(m._useRequestCache,y,l)){h("serving request from cache");var _=y[l],T="function"!=typeof _.then?m._promise.resolve({responseText:_}):_;return n(T,function(e){return JSON.parse(e.responseText)})}var x=r(m._request,{url:t.url,method:t.method,body:s,jsonBody:t.body,timeouts:m._getTimeoutsForRequest(t.hostType),forceAuthHeaders:t.forceAuthHeaders});return m._useCache&&m._useRequestCache&&y&&(y[l]=x),n(x,function(e){return e.body})},o.prototype._getSearchParams=function(e,t){if(void 0===e||null===e)return t;for(var r in e)null!==r&&void 0!==e[r]&&e.hasOwnProperty(r)&&(t+=""===t?"":"&",t+=r+"="+encodeURIComponent("[object Array]"===Object.prototype.toString.call(e[r])?i(e[r]):e[r]));return t},o.prototype._computeRequestHeaders=function(t){var r=e(5),o=t.additionalUA?this._ua+"; "+t.additionalUA:this._ua,n={"x-algolia-agent":o,"x-algolia-application-id":this.applicationID};return t.withApiKey!==!1&&(n["x-algolia-api-key"]=this.apiKey),this.userToken&&(n["x-algolia-usertoken"]=this.userToken),this.securityTags&&(n["x-algolia-tagfilters"]=this.securityTags),r(this.extraHeaders,function(e,t){n[t]=e}),t.headers&&r(t.headers,function(e,t){n[t]=e}),n},o.prototype.search=function(t,r,o){var n=e(8),i=e(33),s="Usage: client.search(arrayOfQueries[, callback])";if(!n(t))throw new Error(s);"function"==typeof r?(o=r,r={}):void 0===r&&(r={});var a=this,c={requests:i(t,function(e){var t="";return void 0!==e.query&&(t+="query="+encodeURIComponent(e.query)),{indexName:e.indexName,params:a._getSearchParams(e.params,t)}})},u=i(c.requests,function(e,t){return t+"="+encodeURIComponent("/1/indexes/"+encodeURIComponent(e.indexName)+"?"+e.params)}).join("&"),l="/1/indexes/*/queries";return void 0!==r.strategy&&(c.strategy=r.strategy),this._jsonRequest({cache:this.cache,method:"POST",url:l,body:c,hostType:"read",fallback:{method:"GET",url:"/1/indexes/*",body:{params:u}},callback:o})},o.prototype.searchForFacetValues=function(t){var r=e(8),o=e(33),n="Usage: client.searchForFacetValues([{indexName, params: {facetName, facetQuery, ...params}}, ...queries])";if(!r(t))throw new Error(n);var i=this;return i._promise.all(o(t,function(t){if(!t||void 0===t.indexName||void 0===t.params.facetName||void 0===t.params.facetQuery)throw new Error(n);var r=e(27),o=e(35),s=t.indexName,a=t.params,c=a.facetName,u=o(r(a),function(e){return"facetName"===e}),l=i._getSearchParams(u,"");return i._jsonRequest({cache:i.cache,method:"POST",url:"/1/indexes/"+encodeURIComponent(s)+"/facets/"+encodeURIComponent(c)+"/query",hostType:"read",body:{params:l}})}))},o.prototype.setSecurityTags=function(e){if("[object Array]"===Object.prototype.toString.call(e)){for(var t=[],r=0;rh?this._resetInitialAppIdData(e):e},o.prototype._resetInitialAppIdData=function(e){var t=e||{};return t.hostIndexes={read:0,write:0},t.timeoutMultiplier=1,t.shuffleResult=t.shuffleResult||s([1,2,3]),this._setAppIdData(t)},o.prototype._cacheAppIdData=function(e){this._hostIndexes=e.hostIndexes,this._timeoutMultiplier=e.timeoutMultiplier,this._shuffleResult=e.shuffleResult},o.prototype._partialAppIdDataUpdate=function(t){var r=e(5),o=this._getAppIdData();return r(t,function(e,t){o[t]=e}),this._setAppIdData(o)},o.prototype._getHostByType=function(e){return this.hosts[e][this._getHostIndexByType(e)]},o.prototype._getTimeoutMultiplier=function(){return this._timeoutMultiplier},o.prototype._getHostIndexByType=function(e){return this._hostIndexes[e]},o.prototype._setHostIndexByType=function(t,r){var o=e(27),n=o(this._hostIndexes);return n[r]=t,this._partialAppIdDataUpdate({hostIndexes:n}),t},o.prototype._incrementHostIndex=function(e){return this._setHostIndexByType((this._getHostIndexByType(e)+1)%this.hosts[e].length,e)},o.prototype._incrementTimeoutMultipler=function(){var e=Math.max(this._timeoutMultiplier+1,4);return this._partialAppIdDataUpdate({timeoutMultiplier:e})},o.prototype._getTimeoutsForRequest=function(e){return{connect:this._timeouts.connect*this._timeoutMultiplier,complete:this._timeouts[e]*this._timeoutMultiplier}}}).call(this,e(12))},{1:1,12:12,20:20,27:27,31:31,32:32,33:33,35:35,37:37,5:5,8:8}],18:[function(e,t,r){function o(){s.apply(this,arguments)}function n(e,t,r){function o(r,n){var i={page:r||0,hitsPerPage:t||100},s=n||[];return e(i).then(function(e){var t=e.hits,r=e.nbHits,n=t.map(function(e){return delete e._highlightResult,e}),a=s.concat(n);return a.lengths&&(t=s),"published"!==e.status?l._promise.delay(t).then(r):e})}function o(e){u(function(){t(null,e)},l._setTimeout||setTimeout)}function n(e){u(function(){t(e)},l._setTimeout||setTimeout)}var i=100,s=5e3,a=0,c=this,l=c.as,p=r();return t?void p.then(o,n):p},o.prototype.clearIndex=function(e){var t=this;return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(t.indexName)+"/clear",hostType:"write",callback:e})},o.prototype.getSettings=function(e,t){1===arguments.length&&"function"==typeof e&&(t=e,e={}),e=e||{};var r=encodeURIComponent(this.indexName);return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+r+"/settings?getVersion=2"+(e.advanced?"&advanced="+e.advanced:""),hostType:"read",callback:t})},o.prototype.searchSynonyms=function(e,t){return"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/search",body:e,hostType:"read",callback:t})},o.prototype.exportSynonyms=function(e,t){return n(this.searchSynonyms.bind(this),e,t)},o.prototype.saveSynonym=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"PUT",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e.objectID)+"?forwardToReplicas="+o,body:e,hostType:"write",callback:r})},o.prototype.getSynonym=function(e,t){return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e),hostType:"read",callback:t})},o.prototype.deleteSynonym=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e)+"?forwardToReplicas="+o,hostType:"write",callback:r})},o.prototype.clearSynonyms=function(e,t){"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),void 0!==e.forwardToSlaves&&p();var r=e.forwardToSlaves||e.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/clear?forwardToReplicas="+r,hostType:"write",callback:t})},o.prototype.batchSynonyms=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/batch?forwardToReplicas="+o+"&replaceExistingSynonyms="+(t.replaceExistingSynonyms?"true":"false"),hostType:"write",body:e,callback:r})},o.prototype.searchRules=function(e,t){return"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/search",body:e,hostType:"read",callback:t})},o.prototype.exportRules=function(e,t){return n(this.searchRules.bind(this),e,t)},o.prototype.saveRule=function(e,t,r){if("function"==typeof t?(r=t,t={}):void 0===t&&(t={}),!e.objectID)throw new l.AlgoliaSearchError("Missing or empty objectID field for rule");var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"PUT",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e.objectID)+"?forwardToReplicas="+o,body:e,hostType:"write",callback:r})},o.prototype.getRule=function(e,t){return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e),hostType:"read",callback:t})},o.prototype.deleteRule=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={});var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e)+"?forwardToReplicas="+o,hostType:"write",callback:r})},o.prototype.clearRules=function(e,t){"function"==typeof e?(t=e,e={}):void 0===e&&(e={});var r=e.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/clear?forwardToReplicas="+r,hostType:"write",callback:t})},o.prototype.batchRules=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={});var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/batch?forwardToReplicas="+o+"&clearExistingRules="+(t.clearExistingRules===!0?"true":"false"),hostType:"write",body:e,callback:r})},o.prototype.exists=function(e){var t=this.getSettings().then(function(){return!0})["catch"](function(e){if(e instanceof l.AlgoliaSearchError&&404===e.statusCode)return!1;throw e});return"function"!=typeof e?t:void t.then(function(t){e(null,t)})["catch"](function(t){e(t)})},o.prototype.findObject=function(e,t,r){t=void 0===t?{}:t;var o=void 0===t.paginate||t.paginate,n=void 0!==t.query?t.query:"",i=this,s=0,a=function(){return t.page=s,i.search(n,t).then(function(t){for(var r=t.hits,n=0;n=t.nbPages)throw new l.ObjectNotFound("Object not found");return a()})},c=a(s);return void 0===r?c:void c.then(function(e){r(null,e)})["catch"](function(e){r(e)})},o.prototype.getObjectPosition=function(e,t){for(var r=e.hits,o=0;o1&&a()}if(!h.cors&&!h.hasXDomainRequest)return void o(new u.Network("CORS not supported"));e=l(e,t.headers);var d,f,y=t.body,m=h.cors?new XMLHttpRequest:new XDomainRequest,v=!1;d=setTimeout(s,t.timeouts.connect),m.onprogress=c,"onreadystatechange"in m&&(m.onreadystatechange=p),m.onload=n,m.onerror=i,m instanceof XMLHttpRequest?(m.open(t.method,e,!0),t.forceAuthHeaders&&(m.setRequestHeader("x-algolia-application-id",t.headers["x-algolia-application-id"]),m.setRequestHeader("x-algolia-api-key",t.headers["x-algolia-api-key"]))):m.open(t.method,e),h.cors&&(y&&("POST"===t.method?m.setRequestHeader("content-type","application/x-www-form-urlencoded"):m.setRequestHeader("content-type","application/json")),m.setRequestHeader("accept","application/json")),y?m.send(y):m.send()})},a.prototype._request.fallback=function(e,t){return e=l(e,t.headers),new n(function(r,o){p(e,t,function(e,t){return e?void o(e):void r(t)})})},a.prototype._promise={reject:function(e){return n.reject(e)},resolve:function(e){return n.resolve(e)},delay:function(e){return new n(function(t){setTimeout(t,e)})},all:function(e){return n.all(e)}},s}}).call(this,e(12))},{1:1,12:12,24:24,25:25,27:27,3:3,31:31,36:36,38:38,6:6,7:7}],24:[function(e,t,r){"use strict";function o(e,t){return e+=/\?/.test(e)?"&":"?",e+n(t)}t.exports=o;var n=e(14)},{14:14}],25:[function(e,t,r){"use strict";function o(e,t,r){function o(){t.debug("JSONP: success"),m||d||(m=!0,p||(t.debug("JSONP: Fail. Script loaded but did not call the callback"),a(),r(new n.JSONPScriptFail)))}function s(){"loaded"!==this.readyState&&"complete"!==this.readyState||o()}function a(){clearTimeout(v),f.onload=null,f.onreadystatechange=null,f.onerror=null,h.removeChild(f)}function c(){try{delete window[y],delete window[y+"_loaded"]}catch(e){window[y]=window[y+"_loaded"]=void 0}}function u(){t.debug("JSONP: Script timeout"),d=!0,a(),r(new n.RequestTimeout)}function l(){t.debug("JSONP: Script error"),m||d||(a(),r(new n.JSONPScriptError))}if("GET"!==t.method)return void r(new Error("Method "+t.method+" "+e+" is not supported by JSONP."));t.debug("JSONP: start");var p=!1,d=!1;i+=1;var h=document.getElementsByTagName("head")[0],f=document.createElement("script"),y="algoliaJSONP_"+i,m=!1;window[y]=function(e){return c(),d?void t.debug("JSONP: Late answer, ignoring"):(p=!0,a(),void r(null,{body:e,responseText:JSON.stringify(e)}))},e+="&callback="+y,t.jsonBody&&t.jsonBody.params&&(e+="&"+t.jsonBody.params);var v=setTimeout(u,t.timeouts.complete);f.onreadystatechange=s,f.onload=o,f.onerror=l,f.async=!0,f.defer=!0,f.src=e,h.appendChild(f)}t.exports=o;var n=e(31),i=0},{31:31}],26:[function(e,t,r){function o(e,t){return function(r,o,i){if("function"==typeof r&&"object"==typeof o||"object"==typeof i)throw new n.AlgoliaSearchError("index.search usage is index.search(query, params, cb)");0===arguments.length||"function"==typeof r?(i=r,r=""):1!==arguments.length&&"function"!=typeof o||(i=o,o=void 0),"object"==typeof r&&null!==r?(o=r,r=void 0):void 0!==r&&null!==r||(r="");var s="";void 0!==r&&(s+=e+"="+encodeURIComponent(r));var a;return void 0!==o&&(o.additionalUA&&(a=o.additionalUA,delete o.additionalUA),s=this.as._getSearchParams(o,s)),this._search(s,t,i,a)}}t.exports=o;var n=e(31)},{31:31}],27:[function(e,t,r){t.exports=function(e){return JSON.parse(JSON.stringify(e))}},{}],28:[function(e,t,r){function o(e,t,r){var o={};return r=r||{},r.hosts=r.hosts||["analytics.algolia.com","analytics.algolia.com","analytics.algolia.com","analytics.algolia.com"],r.protocol=r.protocol||"https:",o.as=n(e,t,r),o.getABTests=function(e,t){var r=r||{},o=r.offset||0,n=r.limit||10;return this.as._jsonRequest({method:"GET",url:"/2/abtests?offset="+encodeURIComponent(o)+"&limit="+encodeURIComponent(n),hostType:"read",forceAuthHeaders:!0,callback:t})},o.getABTest=function(e,t){return this.as._jsonRequest({method:"GET",url:"/2/abtests/"+encodeURIComponent(e),hostType:"read",forceAuthHeaders:!0,callback:t})},o.addABTest=function(e,t){return this.as._jsonRequest({method:"POST",url:"/2/abtests",body:e,hostType:"read",forceAuthHeaders:!0,callback:t})},o.stopABTest=function(e,t){return this.as._jsonRequest({method:"POST",url:"/2/abtests/"+encodeURIComponent(e)+"/stop",hostType:"read",forceAuthHeaders:!0,callback:t})},o.deleteABTest=function(e,t){return this.as._jsonRequest({method:"DELETE",url:"/2/abtests/"+encodeURIComponent(e),hostType:"write",forceAuthHeaders:!0,callback:t})},o.waitTask=function(e,t,r){return this.as.initIndex(e).waitTask(t,r)},o}t.exports=o;var n=e(22)},{22:22}],29:[function(e,t,r){t.exports=function(e,t){function r(){return o||(console.warn(t),o=!0),e.apply(this,arguments)}var o=!1;return r}},{}],30:[function(e,t,r){t.exports=function(e,t){var r=e.toLowerCase().replace(/[\.\(\)]/g,"");return"algoliasearch: `"+e+"` was replaced by `"+t+"`. Please see https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated#"+r}},{}],31:[function(e,t,r){"use strict";function o(t,r){var o=e(5),n=this;"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):n.stack=(new Error).stack||"Cannot get a stacktrace, browser is too old",this.name="AlgoliaSearchError",this.message=t||"Unknown error",r&&o(r,function(e,t){n[t]=e})}function n(e,t){function r(){var r=Array.prototype.slice.call(arguments,0);"string"!=typeof r[0]&&r.unshift(t),o.apply(this,r),this.name="AlgoliaSearch"+e+"Error"}return i(r,o),r}var i=e(7);i(o,Error),t.exports={AlgoliaSearchError:o,UnparsableJSON:n("UnparsableJSON","Could not parse the incoming response as JSON, see err.more for details"),RequestTimeout:n("RequestTimeout","Request timed out before getting a response"),Network:n("Network","Network issue, see err.more for details"),JSONPScriptFail:n("JSONPScriptFail",""),window.ALGOLIA_SUPPORTS_DOCWRITE===!0?(document.write(''),n("document.write")()):r(o,n("DOMElement"))}catch(s){r(o,n("DOMElement"))}}function n(e){return function(){var t="AlgoliaSearch: loaded V2 script using "+e;window.console&&window.console.log&&window.console.log(t)}}t.exports=o},{1:1}],4:[function(e,t,r){"use strict";function o(){var e="-- AlgoliaSearch V2 => V3 error --\nYou are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\nPlease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch V2 => V3 error --";window.AlgoliaSearch=function(){throw new Error(e)},window.AlgoliaSearchHelper=function(){throw new Error(e)},window.AlgoliaExplainResults=function(){throw new Error(e)}}t.exports=o},{}],5:[function(e,t,r){"use strict";function o(t){var r=e(2),o=e(3),n=e(4);r(t)?o(t):n()}o("algoliasearch.jquery")},{2:2,3:3,4:4}]},{},[5])(5)}),function e(t,r,o){function n(s,a){if(!r[s]){if(!t[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var l=r[s]={exports:{}};t[s][0].call(l.exports,function(e){var r=t[s][1][e];return n(r?r:e)},l,l.exports,e,t,r,o)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;s=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(e){var t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+r.humanize(this.diff),t){var o="color: "+this.color;e.splice(1,0,o,"color: inherit");var n=0,i=0;e[0].replace(/%[a-zA-Z%]/g,function(e){"%%"!==e&&(n++,"%c"===e&&(i=n))}),e.splice(i,0,o)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(e){try{null==e?r.storage.removeItem("debug"):r.storage.debug=e}catch(t){}}function c(){var e;try{e=r.storage.debug}catch(t){}return!e&&"undefined"!=typeof o&&"env"in o&&(e=o.env.DEBUG),e}function u(){try{return window.localStorage}catch(e){}}r=t.exports=e(2),r.log=s,r.formatArgs=i,r.save=a,r.load=c,r.useColors=n,r.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),r.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],r.formatters.j=function(e){try{return JSON.stringify(e)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}},r.enable(c())}).call(this,e(12))},{12:12,2:2}],2:[function(e,t,r){function o(e){var t,o=0;for(t in e)o=(o<<5)-o+e.charCodeAt(t),o|=0;return r.colors[Math.abs(o)%r.colors.length]}function n(e){function t(){if(t.enabled){var e=t,o=+new Date,n=o-(u||o);e.diff=n,e.prev=u,e.curr=o,u=o;for(var i=new Array(arguments.length),s=0;s0&&this._events[e].length>r&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},o.prototype.on=o.prototype.addListener,o.prototype.once=function(e,t){function r(){this.removeListener(e,r),o||(o=!0,t.apply(this,arguments))}if(!n(t))throw TypeError("listener must be a function");var o=!1;return r.listener=t,this.on(e,r),this},o.prototype.removeListener=function(e,t){var r,o,i,a;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(r=this._events[e],i=r.length,o=-1,r===t||n(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(r)){for(a=i;a-- >0;)if(r[a]===t||r[a].listener&&r[a].listener===t){o=a;break}if(o<0)return this;1===r.length?(r.length=0,delete this._events[e]):r.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},o.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r=this._events[e],n(r))this.removeListener(e,r);else if(r)for(;r.length;)this.removeListener(e,r[r.length-1]);return delete this._events[e],this},o.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?n(this._events[e])?[this._events[e]]:this._events[e].slice():[]},o.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(n(t))return 1;if(t)return t.length}return 0},o.listenerCount=function(e,t){return e.listenerCount(t)}},{}],5:[function(e,t,r){var o=Object.prototype.hasOwnProperty,n=Object.prototype.toString;t.exports=function(e,t,r){if("[object Function]"!==n.call(t))throw new TypeError("iterator must be a function");var i=e.length;if(i===+i)for(var s=0;s100)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var r=parseFloat(t[1]),o=(t[2]||"ms").toLowerCase();switch(o){case"years":case"year":case"yrs":case"yr":case"y":return r*p;case"days":case"day":case"d":return r*l;case"hours":case"hour":case"hrs":case"hr":case"h":return r*u;case"minutes":case"minute":case"mins":case"min":case"m":return r*c;case"seconds":case"second":case"secs":case"sec":case"s":return r*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}}}function n(e){return e>=l?Math.round(e/l)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function i(e){return s(e,l,"day")||s(e,u,"hour")||s(e,c,"minute")||s(e,a,"second")||e+" ms"}function s(e,t,r){if(!(e0)return o(e);if("number"===r&&isNaN(e)===!1)return t["long"]?i(e):n(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},{}],10:[function(e,t,r){"use strict";var o=Object.prototype.hasOwnProperty,n=Object.prototype.toString,i=Array.prototype.slice,s=e(11),a=Object.prototype.propertyIsEnumerable,c=!a.call({toString:null},"toString"),u=a.call(function(){},"prototype"),l=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],p=function(e){var t=e.constructor;return t&&t.prototype===e},d={$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},h=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!d["$"+e]&&o.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{p(window[e])}catch(t){return!0}}catch(t){return!0}return!1}(),f=function(e){if("undefined"==typeof window||!h)return p(e);try{return p(e)}catch(t){return!1}},y=function(e){var t=null!==e&&"object"==typeof e,r="[object Function]"===n.call(e),i=s(e),a=t&&"[object String]"===n.call(e),p=[];if(!t&&!r&&!i)throw new TypeError("Object.keys called on a non-object");var d=u&&r;if(a&&e.length>0&&!o.call(e,0))for(var h=0;h0)for(var y=0;y=0&&"[object Function]"===o.call(e.callee)),r}},{}],12:[function(e,t,r){function o(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function i(e){if(p===setTimeout)return setTimeout(e,0);if((p===o||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function s(e){if(d===clearTimeout)return clearTimeout(e);if((d===n||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(e);try{return d(e)}catch(t){try{return d.call(null,e)}catch(t){return d.call(this,e)}}}function a(){m&&f&&(m=!1,f.length?y=f.concat(y):v=-1,y.length&&c())}function c(){if(!m){var e=i(a);m=!0;for(var t=y.length;t;){for(f=y,y=[];++v1)for(var r=1;r0&&u>c&&(u=c);for(var l=0;l=0?(p=y.substr(0,m),d=y.substr(m+1)):(p=y,d=""),h=decodeURIComponent(p),f=decodeURIComponent(d),o(s,h)?n(s[h])?s[h].push(f):s[h]=[s[h],f]:s[h]=f}return s};var n=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},{}],14:[function(e,t,r){"use strict";function o(e,t){if(e.map)return e.map(t);for(var r=[],o=0;o0)n.scope=r;else if("undefined"!=typeof r)throw new Error("the scope given to `copyIndex` was not an array with settings, synonyms or rules");return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:n,hostType:"write",callback:i})},o.prototype.getLogs=function(t,r,o){var n=e(27),i={};return"object"==typeof t?(i=n(t),o=r):0===arguments.length||"function"==typeof t?o=t:1===arguments.length||"function"==typeof r?(o=r,i.offset=t):(i.offset=t,i.length=r),void 0===i.offset&&(i.offset=0),void 0===i.length&&(i.length=10),this._jsonRequest({method:"GET",url:"/1/logs?"+this._getSearchParams(i,""),hostType:"read",callback:o})},o.prototype.listIndexes=function(e,t){var r="";return void 0===e||"function"==typeof e?t=e:r="?page="+e,this._jsonRequest({method:"GET",url:"/1/indexes"+r,hostType:"read",callback:t})},o.prototype.initIndex=function(e){return new i(this,e)},o.prototype.initAnalytics=function(t){var r=e(28);return r(this.applicationID,this.apiKey,t)},o.prototype.listUserKeys=s(function(e){return this.listApiKeys(e)},a("client.listUserKeys()","client.listApiKeys()")),o.prototype.listApiKeys=function(e){return this._jsonRequest({method:"GET",url:"/1/keys",hostType:"read",callback:e})},o.prototype.getUserKeyACL=s(function(e,t){return this.getApiKey(e,t)},a("client.getUserKeyACL()","client.getApiKey()")),o.prototype.getApiKey=function(e,t){return this._jsonRequest({method:"GET",url:"/1/keys/"+e,hostType:"read",callback:t})},o.prototype.deleteUserKey=s(function(e,t){return this.deleteApiKey(e,t)},a("client.deleteUserKey()","client.deleteApiKey()")),o.prototype.deleteApiKey=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/keys/"+e,hostType:"write",callback:t})},o.prototype.restoreApiKey=function(e,t){return this._jsonRequest({method:"POST",url:"/1/keys/"+e+"/restore",hostType:"write",callback:t})},o.prototype.addUserKey=s(function(e,t,r){return this.addApiKey(e,t,r)},a("client.addUserKey()","client.addApiKey()")),o.prototype.addApiKey=function(t,r,o){var n=e(8),i="Usage: client.addApiKey(arrayOfAcls[, params, callback])";if(!n(t))throw new Error(i);1!==arguments.length&&"function"!=typeof r||(o=r,r=null);var s={acl:t};return r&&(s.validity=r.validity,s.maxQueriesPerIPPerHour=r.maxQueriesPerIPPerHour,s.maxHitsPerQuery=r.maxHitsPerQuery,s.indexes=r.indexes,s.description=r.description,r.queryParameters&&(s.queryParameters=this._getSearchParams(r.queryParameters,"")),s.referers=r.referers),this._jsonRequest({method:"POST",url:"/1/keys",body:s,hostType:"write",callback:o})},o.prototype.addUserKeyWithValidity=s(function(e,t,r){return this.addApiKey(e,t,r)},a("client.addUserKeyWithValidity()","client.addApiKey()")),o.prototype.updateUserKey=s(function(e,t,r,o){return this.updateApiKey(e,t,r,o)},a("client.updateUserKey()","client.updateApiKey()")),o.prototype.updateApiKey=function(t,r,o,n){var i=e(8),s="Usage: client.updateApiKey(key, arrayOfAcls[, params, callback])";if(!i(r))throw new Error(s);2!==arguments.length&&"function"!=typeof o||(n=o,o=null);var a={acl:r};return o&&(a.validity=o.validity,a.maxQueriesPerIPPerHour=o.maxQueriesPerIPPerHour,a.maxHitsPerQuery=o.maxHitsPerQuery,a.indexes=o.indexes,a.description=o.description,o.queryParameters&&(a.queryParameters=this._getSearchParams(o.queryParameters,"")),a.referers=o.referers),this._jsonRequest({method:"PUT",url:"/1/keys/"+t,body:a,hostType:"write",callback:n})},o.prototype.startQueriesBatch=s(function(){this._batch=[]},a("client.startQueriesBatch()","client.search()")),o.prototype.addQueryInBatch=s(function(e,t,r){this._batch.push({indexName:e,query:t,params:r})},a("client.addQueryInBatch()","client.search()")),o.prototype.sendQueriesBatch=s(function(e){return this.search(this._batch,e)},a("client.sendQueriesBatch()","client.search()")),o.prototype.batch=function(t,r){var o=e(8),n="Usage: client.batch(operations[, callback])";if(!o(t))throw new Error(n);return this._jsonRequest({method:"POST",url:"/1/indexes/*/batch",body:{requests:t},hostType:"write",callback:r})},o.prototype.assignUserID=function(e,t){if(!e.userID||!e.cluster)throw new l.AlgoliaSearchError("You have to provide both a userID and cluster",e);return this._jsonRequest({method:"POST",url:"/1/clusters/mapping",hostType:"write",body:{cluster:e.cluster},callback:t,headers:{"x-algolia-user-id":e.userID}})},o.prototype.assignUserIDs=function(e,t){if(!e.userIDs||!e.cluster)throw new l.AlgoliaSearchError("You have to provide both an array of userIDs and cluster",e);return this._jsonRequest({method:"POST",url:"/1/clusters/mapping/batch",hostType:"write",body:{cluster:e.cluster,users:e.userIDs},callback:t})},o.prototype.getTopUserID=function(e){return this._jsonRequest({method:"GET",url:"/1/clusters/mapping/top",hostType:"read",callback:e})},o.prototype.getUserID=function(e,t){if(!e.userID)throw new l.AlgoliaSearchError("You have to provide a userID",{debugData:e});return this._jsonRequest({method:"GET",url:"/1/clusters/mapping/"+e.userID,hostType:"read",callback:t})},o.prototype.listClusters=function(e){return this._jsonRequest({method:"GET",url:"/1/clusters",hostType:"read",callback:e})},o.prototype.listUserIDs=function(e,t){return this._jsonRequest({method:"GET",url:"/1/clusters/mapping",body:e,hostType:"read",callback:t})},o.prototype.removeUserID=function(e,t){if(!e.userID)throw new l.AlgoliaSearchError("You have to provide a userID",{debugData:e});return this._jsonRequest({method:"DELETE",url:"/1/clusters/mapping",hostType:"write",callback:t,headers:{"x-algolia-user-id":e.userID}})},o.prototype.searchUserIDs=function(e,t){return this._jsonRequest({method:"POST",url:"/1/clusters/mapping/search",body:e,hostType:"read",callback:t})},o.prototype.setPersonalizationStrategy=function(e,t){return this._jsonRequest({method:"POST",url:"/1/recommendation/personalization/strategy",body:e,hostType:"write",callback:t})},o.prototype.getPersonalizationStrategy=function(e){return this._jsonRequest({method:"GET",url:"/1/recommendation/personalization/strategy",hostType:"read",callback:e})},o.prototype.destroy=n,o.prototype.enableRateLimitForward=n,o.prototype.disableRateLimitForward=n,o.prototype.useSecuredAPIKey=n,o.prototype.disableSecuredAPIKey=n,o.prototype.generateSecuredApiKey=n,o.prototype.getSecuredApiKeyRemainingValidity=n},{17:17,18:18,27:27,28:28,29:29,30:30,31:31,7:7,8:8}],17:[function(e,t,r){(function(r){function o(t,r,o){var i=e(1)("algoliasearch"),s=e(27),a=e(8),u=e(33),l="Usage: algoliasearch(applicationID, apiKey, opts)";if(o._allowEmptyCredentials!==!0&&!t)throw new c.AlgoliaSearchError("Please provide an application ID. "+l);if(o._allowEmptyCredentials!==!0&&!r)throw new c.AlgoliaSearchError("Please provide an API key. "+l);
-this.applicationID=t,this.apiKey=r,this.hosts={read:[],write:[]},o=o||{},this._timeouts=o.timeouts||{connect:1e3,read:2e3,write:3e4},o.timeout&&(this._timeouts.connect=this._timeouts.read=this._timeouts.write=o.timeout);var p=o.protocol||"https:";if(/:$/.test(p)||(p+=":"),"http:"!==p&&"https:"!==p)throw new c.AlgoliaSearchError("protocol must be `http:` or `https:` (was `"+o.protocol+"`)");if(this._checkAppIdData(),o.hosts)a(o.hosts)?(this.hosts.read=s(o.hosts),this.hosts.write=s(o.hosts)):(this.hosts.read=s(o.hosts.read),this.hosts.write=s(o.hosts.write));else{var d=u(this._shuffleResult,function(e){return t+"-"+e+".algolianet.com"}),h=(o.dsn===!1?"":"-dsn")+".algolia.net";this.hosts.read=[this.applicationID+h].concat(d),this.hosts.write=[this.applicationID+".algolia.net"].concat(d)}this.hosts.read=u(this.hosts.read,n(p)),this.hosts.write=u(this.hosts.write,n(p)),this.extraHeaders={},this.cache=o._cache||{},this._ua=o._ua,this._useCache=!(void 0!==o._useCache&&!o._cache)||o._useCache,this._useRequestCache=this._useCache&&o._useRequestCache,this._useFallback=void 0===o.useFallback||o.useFallback,this._setTimeout=o._setTimeout,i("init done, %j",this)}function n(e){return function(t){return e+"//"+t.toLowerCase()}}function i(e){if(void 0===Array.prototype.toJSON)return JSON.stringify(e);var t=Array.prototype.toJSON;delete Array.prototype.toJSON;var r=JSON.stringify(e);return Array.prototype.toJSON=t,r}function s(e){for(var t,r,o=e.length;0!==o;)r=Math.floor(Math.random()*o),o-=1,t=e[o],e[o]=e[r],e[r]=t;return e}function a(e){var t={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){var o;o="x-algolia-api-key"===r||"x-algolia-application-id"===r?"**hidden for security purposes**":e[r],t[r]=o}return t}t.exports=o;var c=e(31),u=e(32),l=e(20),p=e(37),d=500,h=r.env.RESET_APP_DATA_TIMER&&parseInt(r.env.RESET_APP_DATA_TIMER,10)||12e4;o.prototype.initIndex=function(e){return new l(this,e)},o.prototype.setExtraHeader=function(e,t){this.extraHeaders[e.toLowerCase()]=t},o.prototype.getExtraHeader=function(e){return this.extraHeaders[e.toLowerCase()]},o.prototype.unsetExtraHeader=function(e){delete this.extraHeaders[e.toLowerCase()]},o.prototype.addAlgoliaAgent=function(e){var t="; "+e;this._ua.indexOf(t)===-1&&(this._ua+=t)},o.prototype._jsonRequest=function(t){function r(e,n){function u(e){var t=e&&e.body&&e.body.message&&e.body.status||e.statusCode||e&&e.body&&200;h("received response: statusCode: %s, computed statusCode: %d, headers: %j",e.statusCode,t,e.headers);var r=2===Math.floor(t/100),o=new Date;if(w.push({currentHost:R,headers:a(p),content:s||null,contentLength:void 0!==s?s.length:null,method:n.method,timeouts:n.timeouts,url:n.url,startTime:x,endTime:o,duration:o-x,statusCode:t}),r)return m._useCache&&!m._useRequestCache&&y&&(y[l]=e.responseText),{responseText:e.responseText,body:e.body};var i=4!==Math.floor(t/100);if(i)return v+=1,_();h("unrecoverable error");var u=new c.AlgoliaSearchError(e.body&&e.body.message,{debugData:w,statusCode:t});return m._promise.reject(u)}function d(e){h("error: %s, stack: %s",e.message,e.stack);var r=new Date;return w.push({currentHost:R,headers:a(p),content:s||null,contentLength:void 0!==s?s.length:null,method:n.method,timeouts:n.timeouts,url:n.url,startTime:x,endTime:r,duration:r-x}),e instanceof c.AlgoliaSearchError||(e=new c.Unknown(e&&e.message,e)),v+=1,e instanceof c.Unknown||e instanceof c.UnparsableJSON||v>=m.hosts[t.hostType].length&&(g||!b)?(e.debugData=w,m._promise.reject(e)):e instanceof c.RequestTimeout?T():_()}function _(){return h("retrying request"),m._incrementHostIndex(t.hostType),r(e,n)}function T(){return h("retrying request with higher timeout"),m._incrementHostIndex(t.hostType),m._incrementTimeoutMultipler(),n.timeouts=m._getTimeoutsForRequest(t.hostType),r(e,n)}m._checkAppIdData();var x=new Date;if(m._useCache&&!m._useRequestCache&&(l=t.url),m._useCache&&!m._useRequestCache&&s&&(l+="_body_"+n.body),o(!m._useRequestCache,y,l)){h("serving response from cache");var j=y[l];return m._promise.resolve({body:JSON.parse(j),responseText:j})}if(v>=m.hosts[t.hostType].length)return!b||g?(h("could not get any response"),m._promise.reject(new c.AlgoliaSearchError("Cannot connect to the AlgoliaSearch API. Send an email to support@algolia.com to report and resolve the issue. Application id was: "+m.applicationID,{debugData:w}))):(h("switching to fallback"),v=0,n.method=t.fallback.method,n.url=t.fallback.url,n.jsonBody=t.fallback.body,n.jsonBody&&(n.body=i(n.jsonBody)),p=m._computeRequestHeaders({additionalUA:f,headers:t.headers}),n.timeouts=m._getTimeoutsForRequest(t.hostType),m._setHostIndexByType(0,t.hostType),g=!0,r(m._request.fallback,n));var R=m._getHostByType(t.hostType),A=R+n.url,S={body:n.body,jsonBody:n.jsonBody,method:n.method,headers:p,timeouts:n.timeouts,debug:h,forceAuthHeaders:n.forceAuthHeaders};return h("method: %s, url: %s, headers: %j, timeouts: %d",S.method,A,S.headers,S.timeouts),e===m._request.fallback&&h("using fallback"),e.call(m,A,S).then(u,d)}function o(e,t,r){return m._useCache&&e&&t&&void 0!==t[r]}function n(e,r){return o(m._useRequestCache,y,l)&&e["catch"](function(){delete y[l]}),"function"!=typeof t.callback?e.then(r):void e.then(function(e){u(function(){t.callback(null,r(e))},m._setTimeout||setTimeout)},function(e){u(function(){t.callback(e)},m._setTimeout||setTimeout)})}this._checkAppIdData();var s,l,p,h=e(1)("algoliasearch:"+t.url),f=t.additionalUA||"",y=t.cache,m=this,v=0,g=!1,b=m._useFallback&&m._request.fallback&&t.fallback;this.apiKey.length>d&&void 0!==t.body&&(void 0!==t.body.params||void 0!==t.body.requests)?(t.body.apiKey=this.apiKey,p=this._computeRequestHeaders({additionalUA:f,withApiKey:!1,headers:t.headers})):p=this._computeRequestHeaders({additionalUA:f,headers:t.headers}),void 0!==t.body&&(s=i(t.body)),h("request start");var w=[];if(m._useCache&&m._useRequestCache&&(l=t.url),m._useCache&&m._useRequestCache&&s&&(l+="_body_"+s),o(m._useRequestCache,y,l)){h("serving request from cache");var _=y[l],T="function"!=typeof _.then?m._promise.resolve({responseText:_}):_;return n(T,function(e){return JSON.parse(e.responseText)})}var x=r(m._request,{url:t.url,method:t.method,body:s,jsonBody:t.body,timeouts:m._getTimeoutsForRequest(t.hostType),forceAuthHeaders:t.forceAuthHeaders});return m._useCache&&m._useRequestCache&&y&&(y[l]=x),n(x,function(e){return e.body})},o.prototype._getSearchParams=function(e,t){if(void 0===e||null===e)return t;for(var r in e)null!==r&&void 0!==e[r]&&e.hasOwnProperty(r)&&(t+=""===t?"":"&",t+=r+"="+encodeURIComponent("[object Array]"===Object.prototype.toString.call(e[r])?i(e[r]):e[r]));return t},o.prototype._computeRequestHeaders=function(t){var r=e(5),o=t.additionalUA?this._ua+"; "+t.additionalUA:this._ua,n={"x-algolia-agent":o,"x-algolia-application-id":this.applicationID};return t.withApiKey!==!1&&(n["x-algolia-api-key"]=this.apiKey),this.userToken&&(n["x-algolia-usertoken"]=this.userToken),this.securityTags&&(n["x-algolia-tagfilters"]=this.securityTags),r(this.extraHeaders,function(e,t){n[t]=e}),t.headers&&r(t.headers,function(e,t){n[t]=e}),n},o.prototype.search=function(t,r,o){var n=e(8),i=e(33),s="Usage: client.search(arrayOfQueries[, callback])";if(!n(t))throw new Error(s);"function"==typeof r?(o=r,r={}):void 0===r&&(r={});var a=this,c={requests:i(t,function(e){var t="";return void 0!==e.query&&(t+="query="+encodeURIComponent(e.query)),{indexName:e.indexName,params:a._getSearchParams(e.params,t)}})},u=i(c.requests,function(e,t){return t+"="+encodeURIComponent("/1/indexes/"+encodeURIComponent(e.indexName)+"?"+e.params)}).join("&"),l="/1/indexes/*/queries";return void 0!==r.strategy&&(c.strategy=r.strategy),this._jsonRequest({cache:this.cache,method:"POST",url:l,body:c,hostType:"read",fallback:{method:"GET",url:"/1/indexes/*",body:{params:u}},callback:o})},o.prototype.searchForFacetValues=function(t){var r=e(8),o=e(33),n="Usage: client.searchForFacetValues([{indexName, params: {facetName, facetQuery, ...params}}, ...queries])";if(!r(t))throw new Error(n);var i=this;return i._promise.all(o(t,function(t){if(!t||void 0===t.indexName||void 0===t.params.facetName||void 0===t.params.facetQuery)throw new Error(n);var r=e(27),o=e(35),s=t.indexName,a=t.params,c=a.facetName,u=o(r(a),function(e){return"facetName"===e}),l=i._getSearchParams(u,"");return i._jsonRequest({cache:i.cache,method:"POST",url:"/1/indexes/"+encodeURIComponent(s)+"/facets/"+encodeURIComponent(c)+"/query",hostType:"read",body:{params:l}})}))},o.prototype.setSecurityTags=function(e){if("[object Array]"===Object.prototype.toString.call(e)){for(var t=[],r=0;rh?this._resetInitialAppIdData(e):e},o.prototype._resetInitialAppIdData=function(e){var t=e||{};return t.hostIndexes={read:0,write:0},t.timeoutMultiplier=1,t.shuffleResult=t.shuffleResult||s([1,2,3]),this._setAppIdData(t)},o.prototype._cacheAppIdData=function(e){this._hostIndexes=e.hostIndexes,this._timeoutMultiplier=e.timeoutMultiplier,this._shuffleResult=e.shuffleResult},o.prototype._partialAppIdDataUpdate=function(t){var r=e(5),o=this._getAppIdData();return r(t,function(e,t){o[t]=e}),this._setAppIdData(o)},o.prototype._getHostByType=function(e){return this.hosts[e][this._getHostIndexByType(e)]},o.prototype._getTimeoutMultiplier=function(){return this._timeoutMultiplier},o.prototype._getHostIndexByType=function(e){return this._hostIndexes[e]},o.prototype._setHostIndexByType=function(t,r){var o=e(27),n=o(this._hostIndexes);return n[r]=t,this._partialAppIdDataUpdate({hostIndexes:n}),t},o.prototype._incrementHostIndex=function(e){return this._setHostIndexByType((this._getHostIndexByType(e)+1)%this.hosts[e].length,e)},o.prototype._incrementTimeoutMultipler=function(){var e=Math.max(this._timeoutMultiplier+1,4);return this._partialAppIdDataUpdate({timeoutMultiplier:e})},o.prototype._getTimeoutsForRequest=function(e){return{connect:this._timeouts.connect*this._timeoutMultiplier,complete:this._timeouts[e]*this._timeoutMultiplier}}}).call(this,e(12))},{1:1,12:12,20:20,27:27,31:31,32:32,33:33,35:35,37:37,5:5,8:8}],18:[function(e,t,r){function o(){s.apply(this,arguments)}function n(e,t,r){function o(r,n){var i={page:r||0,hitsPerPage:t||100},s=n||[];return e(i).then(function(e){var t=e.hits,r=e.nbHits,n=t.map(function(e){return delete e._highlightResult,e}),a=s.concat(n);return a.lengths&&(t=s),"published"!==e.status?l._promise.delay(t).then(r):e})}function o(e){u(function(){t(null,e)},l._setTimeout||setTimeout)}function n(e){u(function(){t(e)},l._setTimeout||setTimeout)}var i=100,s=5e3,a=0,c=this,l=c.as,p=r();return t?void p.then(o,n):p},o.prototype.clearIndex=function(e){var t=this;return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(t.indexName)+"/clear",hostType:"write",callback:e})},o.prototype.getSettings=function(e,t){1===arguments.length&&"function"==typeof e&&(t=e,e={}),e=e||{};var r=encodeURIComponent(this.indexName);return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+r+"/settings?getVersion=2"+(e.advanced?"&advanced="+e.advanced:""),hostType:"read",callback:t})},o.prototype.searchSynonyms=function(e,t){return"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/search",body:e,hostType:"read",callback:t})},o.prototype.exportSynonyms=function(e,t){return n(this.searchSynonyms.bind(this),e,t)},o.prototype.saveSynonym=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"PUT",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e.objectID)+"?forwardToReplicas="+o,body:e,hostType:"write",callback:r})},o.prototype.getSynonym=function(e,t){return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e),hostType:"read",callback:t})},o.prototype.deleteSynonym=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e)+"?forwardToReplicas="+o,hostType:"write",callback:r})},o.prototype.clearSynonyms=function(e,t){"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),void 0!==e.forwardToSlaves&&p();var r=e.forwardToSlaves||e.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/clear?forwardToReplicas="+r,hostType:"write",callback:t})},o.prototype.batchSynonyms=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/batch?forwardToReplicas="+o+"&replaceExistingSynonyms="+(t.replaceExistingSynonyms?"true":"false"),hostType:"write",body:e,callback:r})},o.prototype.searchRules=function(e,t){return"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/search",body:e,hostType:"read",callback:t})},o.prototype.exportRules=function(e,t){return n(this.searchRules.bind(this),e,t)},o.prototype.saveRule=function(e,t,r){if("function"==typeof t?(r=t,t={}):void 0===t&&(t={}),!e.objectID)throw new l.AlgoliaSearchError("Missing or empty objectID field for rule");var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"PUT",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e.objectID)+"?forwardToReplicas="+o,body:e,hostType:"write",callback:r})},o.prototype.getRule=function(e,t){return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e),hostType:"read",callback:t})},o.prototype.deleteRule=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={});var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e)+"?forwardToReplicas="+o,hostType:"write",callback:r})},o.prototype.clearRules=function(e,t){"function"==typeof e?(t=e,e={}):void 0===e&&(e={});var r=e.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/clear?forwardToReplicas="+r,hostType:"write",callback:t})},o.prototype.batchRules=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={});var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/batch?forwardToReplicas="+o+"&clearExistingRules="+(t.clearExistingRules===!0?"true":"false"),hostType:"write",body:e,callback:r})},o.prototype.exists=function(e){var t=this.getSettings().then(function(){return!0})["catch"](function(e){if(e instanceof l.AlgoliaSearchError&&404===e.statusCode)return!1;throw e});return"function"!=typeof e?t:void t.then(function(t){e(null,t)})["catch"](function(t){e(t)})},o.prototype.findObject=function(e,t,r){t=void 0===t?{}:t;var o=void 0===t.paginate||t.paginate,n=void 0!==t.query?t.query:"",i=this,s=0,a=function(){return t.page=s,i.search(n,t).then(function(t){for(var r=t.hits,n=0;n=t.nbPages)throw new l.ObjectNotFound("Object not found");return a()})},c=a(s);return void 0===r?c:void c.then(function(e){r(null,e)})["catch"](function(e){r(e)})},o.prototype.getObjectPosition=function(e,t){for(var r=e.hits,o=0;o1&&a()}if(!h.cors&&!h.hasXDomainRequest)return void o(new u.Network("CORS not supported"));
-e=l(e,t.headers);var d,f,y=t.body,m=h.cors?new XMLHttpRequest:new XDomainRequest,v=!1;d=setTimeout(s,t.timeouts.connect),m.onprogress=c,"onreadystatechange"in m&&(m.onreadystatechange=p),m.onload=n,m.onerror=i,m instanceof XMLHttpRequest?(m.open(t.method,e,!0),t.forceAuthHeaders&&(m.setRequestHeader("x-algolia-application-id",t.headers["x-algolia-application-id"]),m.setRequestHeader("x-algolia-api-key",t.headers["x-algolia-api-key"]))):m.open(t.method,e),h.cors&&(y&&("POST"===t.method?m.setRequestHeader("content-type","application/x-www-form-urlencoded"):m.setRequestHeader("content-type","application/json")),m.setRequestHeader("accept","application/json")),y?m.send(y):m.send()})},a.prototype._request.fallback=function(e,t){return e=l(e,t.headers),new n(function(r,o){p(e,t,function(e,t){return e?void o(e):void r(t)})})},a.prototype._promise={reject:function(e){return n.reject(e)},resolve:function(e){return n.resolve(e)},delay:function(e){return new n(function(t){setTimeout(t,e)})},all:function(e){return n.all(e)}},s}}).call(this,e(12))},{1:1,12:12,24:24,25:25,27:27,3:3,31:31,36:36,38:38,6:6,7:7}],24:[function(e,t,r){"use strict";function o(e,t){return e+=/\?/.test(e)?"&":"?",e+n(t)}t.exports=o;var n=e(14)},{14:14}],25:[function(e,t,r){"use strict";function o(e,t,r){function o(){t.debug("JSONP: success"),m||d||(m=!0,p||(t.debug("JSONP: Fail. Script loaded but did not call the callback"),a(),r(new n.JSONPScriptFail)))}function s(){"loaded"!==this.readyState&&"complete"!==this.readyState||o()}function a(){clearTimeout(v),f.onload=null,f.onreadystatechange=null,f.onerror=null,h.removeChild(f)}function c(){try{delete window[y],delete window[y+"_loaded"]}catch(e){window[y]=window[y+"_loaded"]=void 0}}function u(){t.debug("JSONP: Script timeout"),d=!0,a(),r(new n.RequestTimeout)}function l(){t.debug("JSONP: Script error"),m||d||(a(),r(new n.JSONPScriptError))}if("GET"!==t.method)return void r(new Error("Method "+t.method+" "+e+" is not supported by JSONP."));t.debug("JSONP: start");var p=!1,d=!1;i+=1;var h=document.getElementsByTagName("head")[0],f=document.createElement("script"),y="algoliaJSONP_"+i,m=!1;window[y]=function(e){return c(),d?void t.debug("JSONP: Late answer, ignoring"):(p=!0,a(),void r(null,{body:e,responseText:JSON.stringify(e)}))},e+="&callback="+y,t.jsonBody&&t.jsonBody.params&&(e+="&"+t.jsonBody.params);var v=setTimeout(u,t.timeouts.complete);f.onreadystatechange=s,f.onload=o,f.onerror=l,f.async=!0,f.defer=!0,f.src=e,h.appendChild(f)}t.exports=o;var n=e(31),i=0},{31:31}],26:[function(e,t,r){function o(e,t){return function(r,o,i){if("function"==typeof r&&"object"==typeof o||"object"==typeof i)throw new n.AlgoliaSearchError("index.search usage is index.search(query, params, cb)");0===arguments.length||"function"==typeof r?(i=r,r=""):1!==arguments.length&&"function"!=typeof o||(i=o,o=void 0),"object"==typeof r&&null!==r?(o=r,r=void 0):void 0!==r&&null!==r||(r="");var s="";void 0!==r&&(s+=e+"="+encodeURIComponent(r));var a;return void 0!==o&&(o.additionalUA&&(a=o.additionalUA,delete o.additionalUA),s=this.as._getSearchParams(o,s)),this._search(s,t,i,a)}}t.exports=o;var n=e(31)},{31:31}],27:[function(e,t,r){t.exports=function(e){return JSON.parse(JSON.stringify(e))}},{}],28:[function(e,t,r){function o(e,t,r){var o={};return r=r||{},r.hosts=r.hosts||["analytics.algolia.com","analytics.algolia.com","analytics.algolia.com","analytics.algolia.com"],r.protocol=r.protocol||"https:",o.as=n(e,t,r),o.getABTests=function(e,t){var r=r||{},o=r.offset||0,n=r.limit||10;return this.as._jsonRequest({method:"GET",url:"/2/abtests?offset="+encodeURIComponent(o)+"&limit="+encodeURIComponent(n),hostType:"read",forceAuthHeaders:!0,callback:t})},o.getABTest=function(e,t){return this.as._jsonRequest({method:"GET",url:"/2/abtests/"+encodeURIComponent(e),hostType:"read",forceAuthHeaders:!0,callback:t})},o.addABTest=function(e,t){return this.as._jsonRequest({method:"POST",url:"/2/abtests",body:e,hostType:"read",forceAuthHeaders:!0,callback:t})},o.stopABTest=function(e,t){return this.as._jsonRequest({method:"POST",url:"/2/abtests/"+encodeURIComponent(e)+"/stop",hostType:"read",forceAuthHeaders:!0,callback:t})},o.deleteABTest=function(e,t){return this.as._jsonRequest({method:"DELETE",url:"/2/abtests/"+encodeURIComponent(e),hostType:"write",forceAuthHeaders:!0,callback:t})},o.waitTask=function(e,t,r){return this.as.initIndex(e).waitTask(t,r)},o}t.exports=o;var n=e(22)},{22:22}],29:[function(e,t,r){t.exports=function(e,t){function r(){return o||(console.warn(t),o=!0),e.apply(this,arguments)}var o=!1;return r}},{}],30:[function(e,t,r){t.exports=function(e,t){var r=e.toLowerCase().replace(/[\.\(\)]/g,"");return"algoliasearch: `"+e+"` was replaced by `"+t+"`. Please see https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated#"+r}},{}],31:[function(e,t,r){"use strict";function o(t,r){var o=e(5),n=this;"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):n.stack=(new Error).stack||"Cannot get a stacktrace, browser is too old",this.name="AlgoliaSearchError",this.message=t||"Unknown error",r&&o(r,function(e,t){n[t]=e})}function n(e,t){function r(){var r=Array.prototype.slice.call(arguments,0);"string"!=typeof r[0]&&r.unshift(t),o.apply(this,r),this.name="AlgoliaSearch"+e+"Error"}return i(r,o),r}var i=e(7);i(o,Error),t.exports={AlgoliaSearchError:o,UnparsableJSON:n("UnparsableJSON","Could not parse the incoming response as JSON, see err.more for details"),RequestTimeout:n("RequestTimeout","Request timed out before getting a response"),Network:n("Network","Network issue, see err.more for details"),JSONPScriptFail:n("JSONPScriptFail",""),window.ALGOLIA_SUPPORTS_DOCWRITE===!0?(document.write(''),n("document.write")()):r(o,n("DOMElement"))}catch(s){r(o,n("DOMElement"))}}function n(e){return function(){var t="AlgoliaSearch: loaded V2 script using "+e;window.console&&window.console.log&&window.console.log(t)}}t.exports=o},{1:1}],4:[function(e,t,r){"use strict";function o(){var e="-- AlgoliaSearch V2 => V3 error --\nYou are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\nPlease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch V2 => V3 error --";window.AlgoliaSearch=function(){throw new Error(e)},window.AlgoliaSearchHelper=function(){throw new Error(e)},window.AlgoliaExplainResults=function(){throw new Error(e)}}t.exports=o},{}],5:[function(e,t,r){"use strict";function o(t){var r=e(2),o=e(3),n=e(4);r(t)?o(t):n()}o("algoliasearch")},{2:2,3:3,4:4}]},{},[5])(5)}),function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.algoliasearch=e()}}(function(){var e;return function t(e,r,o){function n(s,a){if(!r[s]){if(!e[s]){var c="function"==typeof require&&require;if(!a&&c)return c(s,!0);if(i)return i(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var l=r[s]={exports:{}};e[s][0].call(l.exports,function(t){var r=e[s][1][t];return n(r?r:t)},l,l.exports,t,e,r,o)}return r[s].exports}for(var i="function"==typeof require&&require,s=0;s=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(e){var t=this.useColors;if(e[0]=(t?"%c":"")+this.namespace+(t?" %c":" ")+e[0]+(t?"%c ":" ")+"+"+r.humanize(this.diff),t){var o="color: "+this.color;e.splice(1,0,o,"color: inherit");var n=0,i=0;e[0].replace(/%[a-zA-Z%]/g,function(e){"%%"!==e&&(n++,"%c"===e&&(i=n))}),e.splice(i,0,o)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(e){try{null==e?r.storage.removeItem("debug"):r.storage.debug=e}catch(t){}}function c(){var e;try{e=r.storage.debug}catch(t){}return!e&&"undefined"!=typeof o&&"env"in o&&(e=o.env.DEBUG),e}function u(){try{return window.localStorage}catch(e){}}r=t.exports=e(2),r.log=s,r.formatArgs=i,r.save=a,r.load=c,r.useColors=n,r.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:u(),r.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],r.formatters.j=function(e){try{return JSON.stringify(e)}catch(t){return"[UnexpectedJSONParseError]: "+t.message}},r.enable(c())}).call(this,e(12))},{12:12,2:2}],2:[function(e,t,r){function o(e){var t,o=0;for(t in e)o=(o<<5)-o+e.charCodeAt(t),o|=0;return r.colors[Math.abs(o)%r.colors.length]}function n(e){function t(){if(t.enabled){var e=t,o=+new Date,n=o-(u||o);e.diff=n,e.prev=u,e.curr=o,u=o;for(var i=new Array(arguments.length),s=0;s0&&this._events[e].length>r&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace())),this},o.prototype.on=o.prototype.addListener,o.prototype.once=function(e,t){function r(){this.removeListener(e,r),o||(o=!0,t.apply(this,arguments))}if(!n(t))throw TypeError("listener must be a function");var o=!1;return r.listener=t,this.on(e,r),this},o.prototype.removeListener=function(e,t){var r,o,i,a;if(!n(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(r=this._events[e],i=r.length,o=-1,r===t||n(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(r)){for(a=i;a-- >0;)if(r[a]===t||r[a].listener&&r[a].listener===t){o=a;break}if(o<0)return this;1===r.length?(r.length=0,delete this._events[e]):r.splice(o,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},o.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r=this._events[e],n(r))this.removeListener(e,r);else if(r)for(;r.length;)this.removeListener(e,r[r.length-1]);return delete this._events[e],this},o.prototype.listeners=function(e){var t;return t=this._events&&this._events[e]?n(this._events[e])?[this._events[e]]:this._events[e].slice():[]},o.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(n(t))return 1;if(t)return t.length}return 0},o.listenerCount=function(e,t){return e.listenerCount(t)}},{}],5:[function(e,t,r){var o=Object.prototype.hasOwnProperty,n=Object.prototype.toString;t.exports=function(e,t,r){if("[object Function]"!==n.call(t))throw new TypeError("iterator must be a function");var i=e.length;if(i===+i)for(var s=0;s100)){var t=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(e);if(t){var r=parseFloat(t[1]),o=(t[2]||"ms").toLowerCase();switch(o){case"years":case"year":case"yrs":case"yr":case"y":return r*p;case"days":case"day":case"d":return r*l;case"hours":case"hour":case"hrs":case"hr":case"h":return r*u;case"minutes":case"minute":case"mins":case"min":case"m":return r*c;case"seconds":case"second":case"secs":case"sec":case"s":return r*a;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return r;default:return}}}}function n(e){return e>=l?Math.round(e/l)+"d":e>=u?Math.round(e/u)+"h":e>=c?Math.round(e/c)+"m":e>=a?Math.round(e/a)+"s":e+"ms"}function i(e){return s(e,l,"day")||s(e,u,"hour")||s(e,c,"minute")||s(e,a,"second")||e+" ms"}function s(e,t,r){if(!(e0)return o(e);if("number"===r&&isNaN(e)===!1)return t["long"]?i(e):n(e);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(e))}},{}],10:[function(e,t,r){"use strict";var o=Object.prototype.hasOwnProperty,n=Object.prototype.toString,i=Array.prototype.slice,s=e(11),a=Object.prototype.propertyIsEnumerable,c=!a.call({toString:null},"toString"),u=a.call(function(){},"prototype"),l=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],p=function(e){var t=e.constructor;return t&&t.prototype===e},d={$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},h=function(){if("undefined"==typeof window)return!1;for(var e in window)try{if(!d["$"+e]&&o.call(window,e)&&null!==window[e]&&"object"==typeof window[e])try{p(window[e])}catch(t){return!0}}catch(t){return!0}return!1}(),f=function(e){if("undefined"==typeof window||!h)return p(e);try{return p(e)}catch(t){return!1}},y=function(e){var t=null!==e&&"object"==typeof e,r="[object Function]"===n.call(e),i=s(e),a=t&&"[object String]"===n.call(e),p=[];if(!t&&!r&&!i)throw new TypeError("Object.keys called on a non-object");var d=u&&r;if(a&&e.length>0&&!o.call(e,0))for(var h=0;h0)for(var y=0;y=0&&"[object Function]"===o.call(e.callee)),r}},{}],12:[function(e,t,r){function o(){throw new Error("setTimeout has not been defined")}function n(){throw new Error("clearTimeout has not been defined")}function i(e){if(p===setTimeout)return setTimeout(e,0);if((p===o||!p)&&setTimeout)return p=setTimeout,setTimeout(e,0);try{return p(e,0)}catch(t){try{return p.call(null,e,0)}catch(t){return p.call(this,e,0)}}}function s(e){if(d===clearTimeout)return clearTimeout(e);if((d===n||!d)&&clearTimeout)return d=clearTimeout,clearTimeout(e);try{return d(e)}catch(t){try{return d.call(null,e)}catch(t){return d.call(this,e)}}}function a(){m&&f&&(m=!1,f.length?y=f.concat(y):v=-1,y.length&&c())}function c(){if(!m){var e=i(a);m=!0;for(var t=y.length;t;){for(f=y,y=[];++v1)for(var r=1;r0&&u>c&&(u=c);for(var l=0;l=0?(p=y.substr(0,m),d=y.substr(m+1)):(p=y,d=""),h=decodeURIComponent(p),f=decodeURIComponent(d),o(s,h)?n(s[h])?s[h].push(f):s[h]=[s[h],f]:s[h]=f}return s};var n=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}},{}],14:[function(e,t,r){"use strict";function o(e,t){if(e.map)return e.map(t);for(var r=[],o=0;o0)n.scope=r;else if("undefined"!=typeof r)throw new Error("the scope given to `copyIndex` was not an array with settings, synonyms or rules");return this._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(e)+"/operation",body:n,hostType:"write",callback:i})},o.prototype.getLogs=function(t,r,o){var n=e(26),i={};return"object"==typeof t?(i=n(t),o=r):0===arguments.length||"function"==typeof t?o=t:1===arguments.length||"function"==typeof r?(o=r,i.offset=t):(i.offset=t,i.length=r),void 0===i.offset&&(i.offset=0),void 0===i.length&&(i.length=10),this._jsonRequest({method:"GET",url:"/1/logs?"+this._getSearchParams(i,""),hostType:"read",callback:o})},o.prototype.listIndexes=function(e,t){var r="";return void 0===e||"function"==typeof e?t=e:r="?page="+e,this._jsonRequest({method:"GET",url:"/1/indexes"+r,hostType:"read",callback:t})},o.prototype.initIndex=function(e){return new i(this,e)},o.prototype.initAnalytics=function(t){var r=e(27);return r(this.applicationID,this.apiKey,t)},o.prototype.listUserKeys=s(function(e){return this.listApiKeys(e)},a("client.listUserKeys()","client.listApiKeys()")),o.prototype.listApiKeys=function(e){return this._jsonRequest({method:"GET",url:"/1/keys",hostType:"read",callback:e})},o.prototype.getUserKeyACL=s(function(e,t){return this.getApiKey(e,t)},a("client.getUserKeyACL()","client.getApiKey()")),o.prototype.getApiKey=function(e,t){return this._jsonRequest({method:"GET",url:"/1/keys/"+e,hostType:"read",callback:t})},o.prototype.deleteUserKey=s(function(e,t){return this.deleteApiKey(e,t)},a("client.deleteUserKey()","client.deleteApiKey()")),o.prototype.deleteApiKey=function(e,t){return this._jsonRequest({method:"DELETE",url:"/1/keys/"+e,hostType:"write",callback:t})},o.prototype.restoreApiKey=function(e,t){return this._jsonRequest({method:"POST",url:"/1/keys/"+e+"/restore",hostType:"write",callback:t})},o.prototype.addUserKey=s(function(e,t,r){return this.addApiKey(e,t,r)},a("client.addUserKey()","client.addApiKey()")),o.prototype.addApiKey=function(t,r,o){var n=e(8),i="Usage: client.addApiKey(arrayOfAcls[, params, callback])";if(!n(t))throw new Error(i);1!==arguments.length&&"function"!=typeof r||(o=r,r=null);var s={acl:t};return r&&(s.validity=r.validity,s.maxQueriesPerIPPerHour=r.maxQueriesPerIPPerHour,s.maxHitsPerQuery=r.maxHitsPerQuery,s.indexes=r.indexes,s.description=r.description,r.queryParameters&&(s.queryParameters=this._getSearchParams(r.queryParameters,"")),s.referers=r.referers),this._jsonRequest({method:"POST",url:"/1/keys",body:s,hostType:"write",callback:o})},o.prototype.addUserKeyWithValidity=s(function(e,t,r){return this.addApiKey(e,t,r)},a("client.addUserKeyWithValidity()","client.addApiKey()")),o.prototype.updateUserKey=s(function(e,t,r,o){return this.updateApiKey(e,t,r,o)},a("client.updateUserKey()","client.updateApiKey()")),o.prototype.updateApiKey=function(t,r,o,n){var i=e(8),s="Usage: client.updateApiKey(key, arrayOfAcls[, params, callback])";if(!i(r))throw new Error(s);2!==arguments.length&&"function"!=typeof o||(n=o,o=null);var a={acl:r};return o&&(a.validity=o.validity,a.maxQueriesPerIPPerHour=o.maxQueriesPerIPPerHour,a.maxHitsPerQuery=o.maxHitsPerQuery,a.indexes=o.indexes,a.description=o.description,o.queryParameters&&(a.queryParameters=this._getSearchParams(o.queryParameters,"")),a.referers=o.referers),this._jsonRequest({method:"PUT",url:"/1/keys/"+t,body:a,hostType:"write",callback:n})},o.prototype.startQueriesBatch=s(function(){this._batch=[]},a("client.startQueriesBatch()","client.search()")),o.prototype.addQueryInBatch=s(function(e,t,r){this._batch.push({indexName:e,query:t,params:r})},a("client.addQueryInBatch()","client.search()")),o.prototype.sendQueriesBatch=s(function(e){return this.search(this._batch,e)},a("client.sendQueriesBatch()","client.search()")),o.prototype.batch=function(t,r){var o=e(8),n="Usage: client.batch(operations[, callback])";if(!o(t))throw new Error(n);return this._jsonRequest({method:"POST",url:"/1/indexes/*/batch",body:{requests:t},hostType:"write",callback:r})},o.prototype.assignUserID=function(e,t){if(!e.userID||!e.cluster)throw new l.AlgoliaSearchError("You have to provide both a userID and cluster",e);return this._jsonRequest({method:"POST",url:"/1/clusters/mapping",hostType:"write",body:{cluster:e.cluster},callback:t,headers:{"x-algolia-user-id":e.userID}})},o.prototype.assignUserIDs=function(e,t){if(!e.userIDs||!e.cluster)throw new l.AlgoliaSearchError("You have to provide both an array of userIDs and cluster",e);return this._jsonRequest({method:"POST",url:"/1/clusters/mapping/batch",hostType:"write",body:{cluster:e.cluster,users:e.userIDs},callback:t})},o.prototype.getTopUserID=function(e){return this._jsonRequest({method:"GET",url:"/1/clusters/mapping/top",hostType:"read",callback:e})},o.prototype.getUserID=function(e,t){if(!e.userID)throw new l.AlgoliaSearchError("You have to provide a userID",{debugData:e});return this._jsonRequest({method:"GET",url:"/1/clusters/mapping/"+e.userID,hostType:"read",callback:t})},o.prototype.listClusters=function(e){return this._jsonRequest({method:"GET",url:"/1/clusters",hostType:"read",callback:e})},o.prototype.listUserIDs=function(e,t){return this._jsonRequest({method:"GET",url:"/1/clusters/mapping",body:e,hostType:"read",callback:t})},o.prototype.removeUserID=function(e,t){if(!e.userID)throw new l.AlgoliaSearchError("You have to provide a userID",{debugData:e});return this._jsonRequest({method:"DELETE",url:"/1/clusters/mapping",hostType:"write",callback:t,headers:{"x-algolia-user-id":e.userID}})},o.prototype.searchUserIDs=function(e,t){return this._jsonRequest({method:"POST",url:"/1/clusters/mapping/search",body:e,hostType:"read",callback:t})},o.prototype.setPersonalizationStrategy=function(e,t){return this._jsonRequest({method:"POST",url:"/1/recommendation/personalization/strategy",body:e,hostType:"write",callback:t})},o.prototype.getPersonalizationStrategy=function(e){return this._jsonRequest({method:"GET",url:"/1/recommendation/personalization/strategy",hostType:"read",callback:e})},o.prototype.destroy=n,o.prototype.enableRateLimitForward=n,o.prototype.disableRateLimitForward=n,o.prototype.useSecuredAPIKey=n,o.prototype.disableSecuredAPIKey=n,o.prototype.generateSecuredApiKey=n,o.prototype.getSecuredApiKeyRemainingValidity=n},{17:17,18:18,26:26,27:27,28:28,29:29,30:30,7:7,8:8}],17:[function(e,t,r){
-(function(r){function o(t,r,o){var i=e(1)("algoliasearch"),s=e(26),a=e(8),u=e(32),l="Usage: algoliasearch(applicationID, apiKey, opts)";if(o._allowEmptyCredentials!==!0&&!t)throw new c.AlgoliaSearchError("Please provide an application ID. "+l);if(o._allowEmptyCredentials!==!0&&!r)throw new c.AlgoliaSearchError("Please provide an API key. "+l);this.applicationID=t,this.apiKey=r,this.hosts={read:[],write:[]},o=o||{},this._timeouts=o.timeouts||{connect:1e3,read:2e3,write:3e4},o.timeout&&(this._timeouts.connect=this._timeouts.read=this._timeouts.write=o.timeout);var p=o.protocol||"https:";if(/:$/.test(p)||(p+=":"),"http:"!==p&&"https:"!==p)throw new c.AlgoliaSearchError("protocol must be `http:` or `https:` (was `"+o.protocol+"`)");if(this._checkAppIdData(),o.hosts)a(o.hosts)?(this.hosts.read=s(o.hosts),this.hosts.write=s(o.hosts)):(this.hosts.read=s(o.hosts.read),this.hosts.write=s(o.hosts.write));else{var d=u(this._shuffleResult,function(e){return t+"-"+e+".algolianet.com"}),h=(o.dsn===!1?"":"-dsn")+".algolia.net";this.hosts.read=[this.applicationID+h].concat(d),this.hosts.write=[this.applicationID+".algolia.net"].concat(d)}this.hosts.read=u(this.hosts.read,n(p)),this.hosts.write=u(this.hosts.write,n(p)),this.extraHeaders={},this.cache=o._cache||{},this._ua=o._ua,this._useCache=!(void 0!==o._useCache&&!o._cache)||o._useCache,this._useRequestCache=this._useCache&&o._useRequestCache,this._useFallback=void 0===o.useFallback||o.useFallback,this._setTimeout=o._setTimeout,i("init done, %j",this)}function n(e){return function(t){return e+"//"+t.toLowerCase()}}function i(e){if(void 0===Array.prototype.toJSON)return JSON.stringify(e);var t=Array.prototype.toJSON;delete Array.prototype.toJSON;var r=JSON.stringify(e);return Array.prototype.toJSON=t,r}function s(e){for(var t,r,o=e.length;0!==o;)r=Math.floor(Math.random()*o),o-=1,t=e[o],e[o]=e[r],e[r]=t;return e}function a(e){var t={};for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r)){var o;o="x-algolia-api-key"===r||"x-algolia-application-id"===r?"**hidden for security purposes**":e[r],t[r]=o}return t}t.exports=o;var c=e(30),u=e(31),l=e(20),p=e(36),d=500,h=r.env.RESET_APP_DATA_TIMER&&parseInt(r.env.RESET_APP_DATA_TIMER,10)||12e4;o.prototype.initIndex=function(e){return new l(this,e)},o.prototype.setExtraHeader=function(e,t){this.extraHeaders[e.toLowerCase()]=t},o.prototype.getExtraHeader=function(e){return this.extraHeaders[e.toLowerCase()]},o.prototype.unsetExtraHeader=function(e){delete this.extraHeaders[e.toLowerCase()]},o.prototype.addAlgoliaAgent=function(e){var t="; "+e;this._ua.indexOf(t)===-1&&(this._ua+=t)},o.prototype._jsonRequest=function(t){function r(e,n){function u(e){var t=e&&e.body&&e.body.message&&e.body.status||e.statusCode||e&&e.body&&200;h("received response: statusCode: %s, computed statusCode: %d, headers: %j",e.statusCode,t,e.headers);var r=2===Math.floor(t/100),o=new Date;if(w.push({currentHost:A,headers:a(p),content:s||null,contentLength:void 0!==s?s.length:null,method:n.method,timeouts:n.timeouts,url:n.url,startTime:x,endTime:o,duration:o-x,statusCode:t}),r)return m._useCache&&!m._useRequestCache&&y&&(y[l]=e.responseText),{responseText:e.responseText,body:e.body};var i=4!==Math.floor(t/100);if(i)return v+=1,_();h("unrecoverable error");var u=new c.AlgoliaSearchError(e.body&&e.body.message,{debugData:w,statusCode:t});return m._promise.reject(u)}function d(e){h("error: %s, stack: %s",e.message,e.stack);var r=new Date;return w.push({currentHost:A,headers:a(p),content:s||null,contentLength:void 0!==s?s.length:null,method:n.method,timeouts:n.timeouts,url:n.url,startTime:x,endTime:r,duration:r-x}),e instanceof c.AlgoliaSearchError||(e=new c.Unknown(e&&e.message,e)),v+=1,e instanceof c.Unknown||e instanceof c.UnparsableJSON||v>=m.hosts[t.hostType].length&&(g||!b)?(e.debugData=w,m._promise.reject(e)):e instanceof c.RequestTimeout?T():_()}function _(){return h("retrying request"),m._incrementHostIndex(t.hostType),r(e,n)}function T(){return h("retrying request with higher timeout"),m._incrementHostIndex(t.hostType),m._incrementTimeoutMultipler(),n.timeouts=m._getTimeoutsForRequest(t.hostType),r(e,n)}m._checkAppIdData();var x=new Date;if(m._useCache&&!m._useRequestCache&&(l=t.url),m._useCache&&!m._useRequestCache&&s&&(l+="_body_"+n.body),o(!m._useRequestCache,y,l)){h("serving response from cache");var R=y[l];return m._promise.resolve({body:JSON.parse(R),responseText:R})}if(v>=m.hosts[t.hostType].length)return!b||g?(h("could not get any response"),m._promise.reject(new c.AlgoliaSearchError("Cannot connect to the AlgoliaSearch API. Send an email to support@algolia.com to report and resolve the issue. Application id was: "+m.applicationID,{debugData:w}))):(h("switching to fallback"),v=0,n.method=t.fallback.method,n.url=t.fallback.url,n.jsonBody=t.fallback.body,n.jsonBody&&(n.body=i(n.jsonBody)),p=m._computeRequestHeaders({additionalUA:f,headers:t.headers}),n.timeouts=m._getTimeoutsForRequest(t.hostType),m._setHostIndexByType(0,t.hostType),g=!0,r(m._request.fallback,n));var A=m._getHostByType(t.hostType),j=A+n.url,S={body:n.body,jsonBody:n.jsonBody,method:n.method,headers:p,timeouts:n.timeouts,debug:h,forceAuthHeaders:n.forceAuthHeaders};return h("method: %s, url: %s, headers: %j, timeouts: %d",S.method,j,S.headers,S.timeouts),e===m._request.fallback&&h("using fallback"),e.call(m,j,S).then(u,d)}function o(e,t,r){return m._useCache&&e&&t&&void 0!==t[r]}function n(e,r){return o(m._useRequestCache,y,l)&&e["catch"](function(){delete y[l]}),"function"!=typeof t.callback?e.then(r):void e.then(function(e){u(function(){t.callback(null,r(e))},m._setTimeout||setTimeout)},function(e){u(function(){t.callback(e)},m._setTimeout||setTimeout)})}this._checkAppIdData();var s,l,p,h=e(1)("algoliasearch:"+t.url),f=t.additionalUA||"",y=t.cache,m=this,v=0,g=!1,b=m._useFallback&&m._request.fallback&&t.fallback;this.apiKey.length>d&&void 0!==t.body&&(void 0!==t.body.params||void 0!==t.body.requests)?(t.body.apiKey=this.apiKey,p=this._computeRequestHeaders({additionalUA:f,withApiKey:!1,headers:t.headers})):p=this._computeRequestHeaders({additionalUA:f,headers:t.headers}),void 0!==t.body&&(s=i(t.body)),h("request start");var w=[];if(m._useCache&&m._useRequestCache&&(l=t.url),m._useCache&&m._useRequestCache&&s&&(l+="_body_"+s),o(m._useRequestCache,y,l)){h("serving request from cache");var _=y[l],T="function"!=typeof _.then?m._promise.resolve({responseText:_}):_;return n(T,function(e){return JSON.parse(e.responseText)})}var x=r(m._request,{url:t.url,method:t.method,body:s,jsonBody:t.body,timeouts:m._getTimeoutsForRequest(t.hostType),forceAuthHeaders:t.forceAuthHeaders});return m._useCache&&m._useRequestCache&&y&&(y[l]=x),n(x,function(e){return e.body})},o.prototype._getSearchParams=function(e,t){if(void 0===e||null===e)return t;for(var r in e)null!==r&&void 0!==e[r]&&e.hasOwnProperty(r)&&(t+=""===t?"":"&",t+=r+"="+encodeURIComponent("[object Array]"===Object.prototype.toString.call(e[r])?i(e[r]):e[r]));return t},o.prototype._computeRequestHeaders=function(t){var r=e(5),o=t.additionalUA?this._ua+"; "+t.additionalUA:this._ua,n={"x-algolia-agent":o,"x-algolia-application-id":this.applicationID};return t.withApiKey!==!1&&(n["x-algolia-api-key"]=this.apiKey),this.userToken&&(n["x-algolia-usertoken"]=this.userToken),this.securityTags&&(n["x-algolia-tagfilters"]=this.securityTags),r(this.extraHeaders,function(e,t){n[t]=e}),t.headers&&r(t.headers,function(e,t){n[t]=e}),n},o.prototype.search=function(t,r,o){var n=e(8),i=e(32),s="Usage: client.search(arrayOfQueries[, callback])";if(!n(t))throw new Error(s);"function"==typeof r?(o=r,r={}):void 0===r&&(r={});var a=this,c={requests:i(t,function(e){var t="";return void 0!==e.query&&(t+="query="+encodeURIComponent(e.query)),{indexName:e.indexName,params:a._getSearchParams(e.params,t)}})},u=i(c.requests,function(e,t){return t+"="+encodeURIComponent("/1/indexes/"+encodeURIComponent(e.indexName)+"?"+e.params)}).join("&"),l="/1/indexes/*/queries";return void 0!==r.strategy&&(c.strategy=r.strategy),this._jsonRequest({cache:this.cache,method:"POST",url:l,body:c,hostType:"read",fallback:{method:"GET",url:"/1/indexes/*",body:{params:u}},callback:o})},o.prototype.searchForFacetValues=function(t){var r=e(8),o=e(32),n="Usage: client.searchForFacetValues([{indexName, params: {facetName, facetQuery, ...params}}, ...queries])";if(!r(t))throw new Error(n);var i=this;return i._promise.all(o(t,function(t){if(!t||void 0===t.indexName||void 0===t.params.facetName||void 0===t.params.facetQuery)throw new Error(n);var r=e(26),o=e(34),s=t.indexName,a=t.params,c=a.facetName,u=o(r(a),function(e){return"facetName"===e}),l=i._getSearchParams(u,"");return i._jsonRequest({cache:i.cache,method:"POST",url:"/1/indexes/"+encodeURIComponent(s)+"/facets/"+encodeURIComponent(c)+"/query",hostType:"read",body:{params:l}})}))},o.prototype.setSecurityTags=function(e){if("[object Array]"===Object.prototype.toString.call(e)){for(var t=[],r=0;rh?this._resetInitialAppIdData(e):e},o.prototype._resetInitialAppIdData=function(e){var t=e||{};return t.hostIndexes={read:0,write:0},t.timeoutMultiplier=1,t.shuffleResult=t.shuffleResult||s([1,2,3]),this._setAppIdData(t)},o.prototype._cacheAppIdData=function(e){this._hostIndexes=e.hostIndexes,this._timeoutMultiplier=e.timeoutMultiplier,this._shuffleResult=e.shuffleResult},o.prototype._partialAppIdDataUpdate=function(t){var r=e(5),o=this._getAppIdData();return r(t,function(e,t){o[t]=e}),this._setAppIdData(o)},o.prototype._getHostByType=function(e){return this.hosts[e][this._getHostIndexByType(e)]},o.prototype._getTimeoutMultiplier=function(){return this._timeoutMultiplier},o.prototype._getHostIndexByType=function(e){return this._hostIndexes[e]},o.prototype._setHostIndexByType=function(t,r){var o=e(26),n=o(this._hostIndexes);return n[r]=t,this._partialAppIdDataUpdate({hostIndexes:n}),t},o.prototype._incrementHostIndex=function(e){return this._setHostIndexByType((this._getHostIndexByType(e)+1)%this.hosts[e].length,e)},o.prototype._incrementTimeoutMultipler=function(){var e=Math.max(this._timeoutMultiplier+1,4);return this._partialAppIdDataUpdate({timeoutMultiplier:e})},o.prototype._getTimeoutsForRequest=function(e){return{connect:this._timeouts.connect*this._timeoutMultiplier,complete:this._timeouts[e]*this._timeoutMultiplier}}}).call(this,e(12))},{1:1,12:12,20:20,26:26,30:30,31:31,32:32,34:34,36:36,5:5,8:8}],18:[function(e,t,r){function o(){s.apply(this,arguments)}function n(e,t,r){function o(r,n){var i={page:r||0,hitsPerPage:t||100},s=n||[];return e(i).then(function(e){var t=e.hits,r=e.nbHits,n=t.map(function(e){return delete e._highlightResult,e}),a=s.concat(n);return a.lengths&&(t=s),"published"!==e.status?l._promise.delay(t).then(r):e})}function o(e){u(function(){t(null,e)},l._setTimeout||setTimeout)}function n(e){u(function(){t(e)},l._setTimeout||setTimeout)}var i=100,s=5e3,a=0,c=this,l=c.as,p=r();return t?void p.then(o,n):p},o.prototype.clearIndex=function(e){var t=this;return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(t.indexName)+"/clear",hostType:"write",callback:e})},o.prototype.getSettings=function(e,t){1===arguments.length&&"function"==typeof e&&(t=e,e={}),e=e||{};var r=encodeURIComponent(this.indexName);return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+r+"/settings?getVersion=2"+(e.advanced?"&advanced="+e.advanced:""),hostType:"read",callback:t})},o.prototype.searchSynonyms=function(e,t){return"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/search",body:e,hostType:"read",callback:t})},o.prototype.exportSynonyms=function(e,t){return n(this.searchSynonyms.bind(this),e,t)},o.prototype.saveSynonym=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"PUT",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e.objectID)+"?forwardToReplicas="+o,body:e,hostType:"write",callback:r})},o.prototype.getSynonym=function(e,t){return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e),hostType:"read",callback:t})},o.prototype.deleteSynonym=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/"+encodeURIComponent(e)+"?forwardToReplicas="+o,hostType:"write",callback:r})},o.prototype.clearSynonyms=function(e,t){"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),void 0!==e.forwardToSlaves&&p();var r=e.forwardToSlaves||e.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/clear?forwardToReplicas="+r,hostType:"write",callback:t})},o.prototype.batchSynonyms=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={}),void 0!==t.forwardToSlaves&&p();var o=t.forwardToSlaves||t.forwardToReplicas?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/synonyms/batch?forwardToReplicas="+o+"&replaceExistingSynonyms="+(t.replaceExistingSynonyms?"true":"false"),hostType:"write",body:e,callback:r})},o.prototype.searchRules=function(e,t){return"function"==typeof e?(t=e,e={}):void 0===e&&(e={}),this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/search",body:e,hostType:"read",callback:t})},o.prototype.exportRules=function(e,t){return n(this.searchRules.bind(this),e,t)},o.prototype.saveRule=function(e,t,r){if("function"==typeof t?(r=t,t={}):void 0===t&&(t={}),!e.objectID)throw new l.AlgoliaSearchError("Missing or empty objectID field for rule");var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"PUT",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e.objectID)+"?forwardToReplicas="+o,body:e,hostType:"write",callback:r})},o.prototype.getRule=function(e,t){return this.as._jsonRequest({method:"GET",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e),hostType:"read",callback:t})},o.prototype.deleteRule=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={});var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"DELETE",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/"+encodeURIComponent(e)+"?forwardToReplicas="+o,hostType:"write",callback:r})},o.prototype.clearRules=function(e,t){"function"==typeof e?(t=e,e={}):void 0===e&&(e={});var r=e.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/clear?forwardToReplicas="+r,hostType:"write",callback:t})},o.prototype.batchRules=function(e,t,r){"function"==typeof t?(r=t,t={}):void 0===t&&(t={});var o=t.forwardToReplicas===!0?"true":"false";return this.as._jsonRequest({method:"POST",url:"/1/indexes/"+encodeURIComponent(this.indexName)+"/rules/batch?forwardToReplicas="+o+"&clearExistingRules="+(t.clearExistingRules===!0?"true":"false"),hostType:"write",body:e,callback:r})},o.prototype.exists=function(e){var t=this.getSettings().then(function(){return!0})["catch"](function(e){if(e instanceof l.AlgoliaSearchError&&404===e.statusCode)return!1;throw e});return"function"!=typeof e?t:void t.then(function(t){e(null,t)})["catch"](function(t){e(t)})},o.prototype.findObject=function(e,t,r){t=void 0===t?{}:t;var o=void 0===t.paginate||t.paginate,n=void 0!==t.query?t.query:"",i=this,s=0,a=function(){return t.page=s,i.search(n,t).then(function(t){for(var r=t.hits,n=0;n=t.nbPages)throw new l.ObjectNotFound("Object not found");return a()})},c=a(s);return void 0===r?c:void c.then(function(e){r(null,e)})["catch"](function(e){r(e)})},o.prototype.getObjectPosition=function(e,t){for(var r=e.hits,o=0;o1&&a()}if(!h.cors&&!h.hasXDomainRequest)return void o(new u.Network("CORS not supported"));e=l(e,t.headers);var d,f,y=t.body,m=h.cors?new XMLHttpRequest:new XDomainRequest,v=!1;d=setTimeout(s,t.timeouts.connect),m.onprogress=c,"onreadystatechange"in m&&(m.onreadystatechange=p),m.onload=n,m.onerror=i,m instanceof XMLHttpRequest?(m.open(t.method,e,!0),t.forceAuthHeaders&&(m.setRequestHeader("x-algolia-application-id",t.headers["x-algolia-application-id"]),m.setRequestHeader("x-algolia-api-key",t.headers["x-algolia-api-key"]))):m.open(t.method,e),h.cors&&(y&&("POST"===t.method?m.setRequestHeader("content-type","application/x-www-form-urlencoded"):m.setRequestHeader("content-type","application/json")),m.setRequestHeader("accept","application/json")),y?m.send(y):m.send()})},a.prototype._request.fallback=function(e,t){return e=l(e,t.headers),new n(function(r,o){p(e,t,function(e,t){return e?void o(e):void r(t)})})},a.prototype._promise={reject:function(e){return n.reject(e)},resolve:function(e){return n.resolve(e)},delay:function(e){return new n(function(t){setTimeout(t,e)})},all:function(e){return n.all(e)}},s}}).call(this,e(12))},{1:1,12:12,23:23,24:24,26:26,3:3,30:30,35:35,37:37,6:6,7:7}],23:[function(e,t,r){"use strict";function o(e,t){return e+=/\?/.test(e)?"&":"?",e+n(t)}t.exports=o;var n=e(14)},{14:14}],24:[function(e,t,r){"use strict";function o(e,t,r){function o(){t.debug("JSONP: success"),m||d||(m=!0,p||(t.debug("JSONP: Fail. Script loaded but did not call the callback"),
-a(),r(new n.JSONPScriptFail)))}function s(){"loaded"!==this.readyState&&"complete"!==this.readyState||o()}function a(){clearTimeout(v),f.onload=null,f.onreadystatechange=null,f.onerror=null,h.removeChild(f)}function c(){try{delete window[y],delete window[y+"_loaded"]}catch(e){window[y]=window[y+"_loaded"]=void 0}}function u(){t.debug("JSONP: Script timeout"),d=!0,a(),r(new n.RequestTimeout)}function l(){t.debug("JSONP: Script error"),m||d||(a(),r(new n.JSONPScriptError))}if("GET"!==t.method)return void r(new Error("Method "+t.method+" "+e+" is not supported by JSONP."));t.debug("JSONP: start");var p=!1,d=!1;i+=1;var h=document.getElementsByTagName("head")[0],f=document.createElement("script"),y="algoliaJSONP_"+i,m=!1;window[y]=function(e){return c(),d?void t.debug("JSONP: Late answer, ignoring"):(p=!0,a(),void r(null,{body:e,responseText:JSON.stringify(e)}))},e+="&callback="+y,t.jsonBody&&t.jsonBody.params&&(e+="&"+t.jsonBody.params);var v=setTimeout(u,t.timeouts.complete);f.onreadystatechange=s,f.onload=o,f.onerror=l,f.async=!0,f.defer=!0,f.src=e,h.appendChild(f)}t.exports=o;var n=e(30),i=0},{30:30}],25:[function(e,t,r){function o(e,t){return function(r,o,i){if("function"==typeof r&&"object"==typeof o||"object"==typeof i)throw new n.AlgoliaSearchError("index.search usage is index.search(query, params, cb)");0===arguments.length||"function"==typeof r?(i=r,r=""):1!==arguments.length&&"function"!=typeof o||(i=o,o=void 0),"object"==typeof r&&null!==r?(o=r,r=void 0):void 0!==r&&null!==r||(r="");var s="";void 0!==r&&(s+=e+"="+encodeURIComponent(r));var a;return void 0!==o&&(o.additionalUA&&(a=o.additionalUA,delete o.additionalUA),s=this.as._getSearchParams(o,s)),this._search(s,t,i,a)}}t.exports=o;var n=e(30)},{30:30}],26:[function(e,t,r){t.exports=function(e){return JSON.parse(JSON.stringify(e))}},{}],27:[function(e,t,r){function o(e,t,r){var o={};return r=r||{},r.hosts=r.hosts||["analytics.algolia.com","analytics.algolia.com","analytics.algolia.com","analytics.algolia.com"],r.protocol=r.protocol||"https:",o.as=n(e,t,r),o.getABTests=function(e,t){var r=r||{},o=r.offset||0,n=r.limit||10;return this.as._jsonRequest({method:"GET",url:"/2/abtests?offset="+encodeURIComponent(o)+"&limit="+encodeURIComponent(n),hostType:"read",forceAuthHeaders:!0,callback:t})},o.getABTest=function(e,t){return this.as._jsonRequest({method:"GET",url:"/2/abtests/"+encodeURIComponent(e),hostType:"read",forceAuthHeaders:!0,callback:t})},o.addABTest=function(e,t){return this.as._jsonRequest({method:"POST",url:"/2/abtests",body:e,hostType:"read",forceAuthHeaders:!0,callback:t})},o.stopABTest=function(e,t){return this.as._jsonRequest({method:"POST",url:"/2/abtests/"+encodeURIComponent(e)+"/stop",hostType:"read",forceAuthHeaders:!0,callback:t})},o.deleteABTest=function(e,t){return this.as._jsonRequest({method:"DELETE",url:"/2/abtests/"+encodeURIComponent(e),hostType:"write",forceAuthHeaders:!0,callback:t})},o.waitTask=function(e,t,r){return this.as.initIndex(e).waitTask(t,r)},o}t.exports=o;var n=e(21)},{21:21}],28:[function(e,t,r){t.exports=function(e,t){function r(){return o||(console.warn(t),o=!0),e.apply(this,arguments)}var o=!1;return r}},{}],29:[function(e,t,r){t.exports=function(e,t){var r=e.toLowerCase().replace(/[\.\(\)]/g,"");return"algoliasearch: `"+e+"` was replaced by `"+t+"`. Please see https://github.com/algolia/algoliasearch-client-javascript/wiki/Deprecated#"+r}},{}],30:[function(e,t,r){"use strict";function o(t,r){var o=e(5),n=this;"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):n.stack=(new Error).stack||"Cannot get a stacktrace, browser is too old",this.name="AlgoliaSearchError",this.message=t||"Unknown error",r&&o(r,function(e,t){n[t]=e})}function n(e,t){function r(){var r=Array.prototype.slice.call(arguments,0);"string"!=typeof r[0]&&r.unshift(t),o.apply(this,r),this.name="AlgoliaSearch"+e+"Error"}return i(r,o),r}var i=e(7);i(o,Error),t.exports={AlgoliaSearchError:o,UnparsableJSON:n("UnparsableJSON","Could not parse the incoming response as JSON, see err.more for details"),RequestTimeout:n("RequestTimeout","Request timed out before getting a response"),Network:n("Network","Network issue, see err.more for details"),JSONPScriptFail:n("JSONPScriptFail","
+