This commit is contained in:
2024-03-22 03:47:51 +05:30
parent 8bcf3d211e
commit 89819f6fe2
28440 changed files with 3211033 additions and 2 deletions

22
node_modules/algoliasearch-helper/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Algolia
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.

1331
node_modules/algoliasearch-helper/README.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1462
node_modules/algoliasearch-helper/index.d.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

71
node_modules/algoliasearch-helper/index.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
'use strict';
var AlgoliaSearchHelper = require('./src/algoliasearch.helper');
var SearchParameters = require('./src/SearchParameters');
var SearchResults = require('./src/SearchResults');
/**
* The algoliasearchHelper module is the function that will let its
* contains everything needed to use the Algoliasearch
* Helper. It is a also a function that instanciate the helper.
* To use the helper, you also need the Algolia JS client v3.
* @example
* //using the UMD build
* var client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76');
* var helper = algoliasearchHelper(client, 'bestbuy', {
* facets: ['shipping'],
* disjunctiveFacets: ['category']
* });
* helper.on('result', function(event) {
* console.log(event.results);
* });
* helper
* .toggleFacetRefinement('category', 'Movies & TV Shows')
* .toggleFacetRefinement('shipping', 'Free shipping')
* .search();
* @example
* // The helper is an event emitter using the node API
* helper.on('result', updateTheResults);
* helper.once('result', updateTheResults);
* helper.removeListener('result', updateTheResults);
* helper.removeAllListeners('result');
* @module algoliasearchHelper
* @param {AlgoliaSearch} client an AlgoliaSearch client
* @param {string} index the name of the index to query
* @param {SearchParameters|object} opts an object defining the initial config of the search. It doesn't have to be a {SearchParameters}, just an object containing the properties you need from it.
* @param {SearchResultsOptions|object} searchResultsOptions an object defining the options to use when creating the search results.
* @return {AlgoliaSearchHelper} The helper instance
*/
function algoliasearchHelper(client, index, opts, searchResultsOptions) {
return new AlgoliaSearchHelper(client, index, opts, searchResultsOptions);
}
/**
* The version currently used
* @member module:algoliasearchHelper.version
* @type {number}
*/
algoliasearchHelper.version = require('./src/version');
/**
* Constructor for the Helper.
* @member module:algoliasearchHelper.AlgoliaSearchHelper
* @type {AlgoliaSearchHelper}
*/
algoliasearchHelper.AlgoliaSearchHelper = AlgoliaSearchHelper;
/**
* Constructor for the object containing all the parameters of the search.
* @member module:algoliasearchHelper.SearchParameters
* @type {SearchParameters}
*/
algoliasearchHelper.SearchParameters = SearchParameters;
/**
* Constructor for the object containing the results of the search.
* @member module:algoliasearchHelper.SearchResults
* @type {SearchResults}
*/
algoliasearchHelper.SearchResults = SearchResults;
module.exports = algoliasearchHelper;

60
node_modules/algoliasearch-helper/package.json generated vendored Normal file
View File

@@ -0,0 +1,60 @@
{
"name": "algoliasearch-helper",
"version": "3.16.3",
"description": "Helper for implementing advanced search features with algolia",
"main": "index.js",
"types": "index.d.ts",
"homepage": "https://community.algolia.com/algoliasearch-helper-js/",
"scripts": {
"build": "./scripts/build.sh",
"lint": "eslint .",
"doc": "node documentation-src/metalsmith.js",
"test": "../../scripts/retry.sh 3 'scripts/test.sh'",
"test:unit": "jest",
"test:watch": "jest --watch",
"test:v3": "yarn run test",
"version": "./scripts/update-version.js",
"prepare": "patch-package"
},
"author": {
"name": "Algolia Inc.",
"url": "https://www.algolia.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/algolia/instantsearch/tree/master/packages/algoliasearch-helper"
},
"files": [
"dist",
"src",
"index.js",
"index.d.ts",
"types/algoliasearch.d.ts",
"types/algoliasearch.js"
],
"devDependencies": {
"@metalsmith/sass": "1.4.0",
"@types/algoliasearch": "3.34.11",
"browserify": "14.5.0",
"exorcist": "1.0.1",
"handlebars": "4.1.0",
"jest-watch-typeahead": "0.3.0",
"jsdoc-to-markdown": "8.0.0",
"metalsmith": "2.5.1",
"metalsmith-in-place": "1.4.4",
"metalsmith-layouts": "1.8.1",
"metalsmith-markdown": "1.3.0",
"metalsmith-metallic": "1.0.0",
"pretty-bytes-cli": "2.0.0",
"pug": "2.0.3",
"uglify-js": "2.8.29"
},
"dependencies": {
"@algolia/events": "^4.0.1"
},
"peerDependencies": {
"algoliasearch": ">= 3.1 < 6"
},
"gitHead": "358f849cba15cbbb415da05feb582b47358aa239"
}

View File

@@ -0,0 +1,41 @@
'use strict';
var EventEmitter = require('@algolia/events');
var inherits = require('../functions/inherits');
/**
* A DerivedHelper is a way to create sub requests to
* Algolia from a main helper.
* @class
* @classdesc The DerivedHelper provides an event based interface for search callbacks:
* - search: when a search is triggered using the `search()` method.
* - result: when the response is retrieved from Algolia and is processed.
* This event contains a {@link SearchResults} object and the
* {@link SearchParameters} corresponding to this answer.
* @param {AlgoliaSearchHelper} mainHelper the main helper
* @param {function} fn the function to create the derived state
*/
function DerivedHelper(mainHelper, fn) {
this.main = mainHelper;
this.fn = fn;
this.lastResults = null;
}
inherits(DerivedHelper, EventEmitter);
/**
* Detach this helper from the main helper
* @return {undefined}
* @throws Error if the derived helper is already detached
*/
DerivedHelper.prototype.detach = function () {
this.removeAllListeners();
this.main.detachDerivedHelper(this);
};
DerivedHelper.prototype.getModifiedState = function (parameters) {
return this.fn(parameters);
};
module.exports = DerivedHelper;

View File

@@ -0,0 +1,172 @@
'use strict';
/**
* Functions to manipulate refinement lists
*
* The RefinementList is not formally defined through a prototype but is based
* on a specific structure.
*
* @module SearchParameters.refinementList
*
* @typedef {string[]} SearchParameters.refinementList.Refinements
* @typedef {Object.<string, SearchParameters.refinementList.Refinements>} SearchParameters.refinementList.RefinementList
*/
var defaultsPure = require('../functions/defaultsPure');
var objectHasKeys = require('../functions/objectHasKeys');
var omit = require('../functions/omit');
var lib = {
/**
* Adds a refinement to a RefinementList
* @param {RefinementList} refinementList the initial list
* @param {string} attribute the attribute to refine
* @param {string} value the value of the refinement, if the value is not a string it will be converted
* @return {RefinementList} a new and updated refinement list
*/
addRefinement: function addRefinement(refinementList, attribute, value) {
if (lib.isRefined(refinementList, attribute, value)) {
return refinementList;
}
var valueAsString = '' + value;
var facetRefinement = !refinementList[attribute]
? [valueAsString]
: refinementList[attribute].concat(valueAsString);
var mod = {};
mod[attribute] = facetRefinement;
return defaultsPure({}, mod, refinementList);
},
/**
* Removes refinement(s) for an attribute:
* - if the value is specified removes the refinement for the value on the attribute
* - if no value is specified removes all the refinements for this attribute
* @param {RefinementList} refinementList the initial list
* @param {string} attribute the attribute to refine
* @param {string} [value] the value of the refinement
* @return {RefinementList} a new and updated refinement lst
*/
removeRefinement: function removeRefinement(
refinementList,
attribute,
value
) {
if (value === undefined) {
// we use the "filter" form of clearRefinement, since it leaves empty values as-is
// the form with a string will remove the attribute completely
return lib.clearRefinement(refinementList, function (v, f) {
return attribute === f;
});
}
var valueAsString = '' + value;
return lib.clearRefinement(refinementList, function (v, f) {
return attribute === f && valueAsString === v;
});
},
/**
* Toggles the refinement value for an attribute.
* @param {RefinementList} refinementList the initial list
* @param {string} attribute the attribute to refine
* @param {string} value the value of the refinement
* @return {RefinementList} a new and updated list
*/
toggleRefinement: function toggleRefinement(
refinementList,
attribute,
value
) {
if (value === undefined)
throw new Error('toggleRefinement should be used with a value');
if (lib.isRefined(refinementList, attribute, value)) {
return lib.removeRefinement(refinementList, attribute, value);
}
return lib.addRefinement(refinementList, attribute, value);
},
/**
* Clear all or parts of a RefinementList. Depending on the arguments, three
* kinds of behavior can happen:
* - if no attribute is provided: clears the whole list
* - if an attribute is provided as a string: clears the list for the specific attribute
* - if an attribute is provided as a function: discards the elements for which the function returns true
* @param {RefinementList} refinementList the initial list
* @param {string} [attribute] the attribute or function to discard
* @param {string} [refinementType] optional parameter to give more context to the attribute function
* @return {RefinementList} a new and updated refinement list
*/
clearRefinement: function clearRefinement(
refinementList,
attribute,
refinementType
) {
if (attribute === undefined) {
// return the same object if the list is already empty
// this is mainly for tests, as it doesn't have much impact on performance
if (!objectHasKeys(refinementList)) {
return refinementList;
}
return {};
} else if (typeof attribute === 'string') {
return omit(refinementList, [attribute]);
} else if (typeof attribute === 'function') {
var hasChanged = false;
var newRefinementList = Object.keys(refinementList).reduce(function (
memo,
key
) {
var values = refinementList[key] || [];
var facetList = values.filter(function (value) {
return !attribute(value, key, refinementType);
});
if (facetList.length !== values.length) {
hasChanged = true;
}
memo[key] = facetList;
return memo;
},
{});
if (hasChanged) return newRefinementList;
return refinementList;
}
// We return nothing if the attribute is not undefined, a string or a function,
// as it is not a valid value for a refinement
return undefined;
},
/**
* Test if the refinement value is used for the attribute. If no refinement value
* is provided, test if the refinementList contains any refinement for the
* given attribute.
* @param {RefinementList} refinementList the list of refinement
* @param {string} attribute name of the attribute
* @param {string} [refinementValue] value of the filter/refinement
* @return {boolean} true if the attribute is refined, false otherwise
*/
isRefined: function isRefined(refinementList, attribute, refinementValue) {
var containsRefinements =
Boolean(refinementList[attribute]) &&
refinementList[attribute].length > 0;
if (refinementValue === undefined || !containsRefinements) {
return containsRefinements;
}
var refinementValueAsString = '' + refinementValue;
return refinementList[attribute].indexOf(refinementValueAsString) !== -1;
},
};
module.exports = lib;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,202 @@
'use strict';
module.exports = generateTrees;
var fv = require('../functions/escapeFacetValue');
var find = require('../functions/find');
var prepareHierarchicalFacetSortBy = require('../functions/formatSort');
var orderBy = require('../functions/orderBy');
var escapeFacetValue = fv.escapeFacetValue;
var unescapeFacetValue = fv.unescapeFacetValue;
function generateTrees(state) {
return function generate(hierarchicalFacetResult, hierarchicalFacetIndex) {
var hierarchicalFacet = state.hierarchicalFacets[hierarchicalFacetIndex];
var hierarchicalFacetRefinement =
(state.hierarchicalFacetsRefinements[hierarchicalFacet.name] &&
state.hierarchicalFacetsRefinements[hierarchicalFacet.name][0]) ||
'';
var hierarchicalSeparator =
state._getHierarchicalFacetSeparator(hierarchicalFacet);
var hierarchicalRootPath =
state._getHierarchicalRootPath(hierarchicalFacet);
var hierarchicalShowParentLevel =
state._getHierarchicalShowParentLevel(hierarchicalFacet);
var sortBy = prepareHierarchicalFacetSortBy(
state._getHierarchicalFacetSortBy(hierarchicalFacet)
);
var rootExhaustive = hierarchicalFacetResult.every(function (facetResult) {
return facetResult.exhaustive;
});
var generateTreeFn = generateHierarchicalTree(
sortBy,
hierarchicalSeparator,
hierarchicalRootPath,
hierarchicalShowParentLevel,
hierarchicalFacetRefinement
);
var results = hierarchicalFacetResult;
if (hierarchicalRootPath) {
results = hierarchicalFacetResult.slice(
hierarchicalRootPath.split(hierarchicalSeparator).length
);
}
return results.reduce(generateTreeFn, {
name: state.hierarchicalFacets[hierarchicalFacetIndex].name,
count: null, // root level, no count
isRefined: true, // root level, always refined
path: null, // root level, no path
escapedValue: null,
exhaustive: rootExhaustive,
data: null,
});
};
}
function generateHierarchicalTree(
sortBy,
hierarchicalSeparator,
hierarchicalRootPath,
hierarchicalShowParentLevel,
currentRefinement
) {
return function generateTree(
hierarchicalTree,
hierarchicalFacetResult,
currentHierarchicalLevel
) {
var parent = hierarchicalTree;
if (currentHierarchicalLevel > 0) {
var level = 0;
parent = hierarchicalTree;
while (level < currentHierarchicalLevel) {
/**
* @type {object[]]} hierarchical data
*/
var data = parent && Array.isArray(parent.data) ? parent.data : [];
parent = find(data, function (subtree) {
return subtree.isRefined;
});
level++;
}
}
// we found a refined parent, let's add current level data under it
if (parent) {
// filter values in case an object has multiple categories:
// {
// categories: {
// level0: ['beers', 'bières'],
// level1: ['beers > IPA', 'bières > Belges']
// }
// }
//
// If parent refinement is `beers`, then we do not want to have `bières > Belges`
// showing up
var picked = Object.keys(hierarchicalFacetResult.data)
.map(function (facetValue) {
return [facetValue, hierarchicalFacetResult.data[facetValue]];
})
.filter(function (tuple) {
var facetValue = tuple[0];
return onlyMatchingTree(
facetValue,
parent.path || hierarchicalRootPath,
currentRefinement,
hierarchicalSeparator,
hierarchicalRootPath,
hierarchicalShowParentLevel
);
});
parent.data = orderBy(
picked.map(function (tuple) {
var facetValue = tuple[0];
var facetCount = tuple[1];
return format(
facetCount,
facetValue,
hierarchicalSeparator,
unescapeFacetValue(currentRefinement),
hierarchicalFacetResult.exhaustive
);
}),
sortBy[0],
sortBy[1]
);
}
return hierarchicalTree;
};
}
// eslint-disable-next-line max-params
function onlyMatchingTree(
facetValue,
parentPath,
currentRefinement,
hierarchicalSeparator,
hierarchicalRootPath,
hierarchicalShowParentLevel
) {
// we want the facetValue is a child of hierarchicalRootPath
if (
hierarchicalRootPath &&
(facetValue.indexOf(hierarchicalRootPath) !== 0 ||
hierarchicalRootPath === facetValue)
) {
return false;
}
// we always want root levels (only when there is no prefix path)
return (
(!hierarchicalRootPath &&
facetValue.indexOf(hierarchicalSeparator) === -1) ||
// if there is a rootPath, being root level mean 1 level under rootPath
(hierarchicalRootPath &&
facetValue.split(hierarchicalSeparator).length -
hierarchicalRootPath.split(hierarchicalSeparator).length ===
1) ||
// if current refinement is a root level and current facetValue is a root level,
// keep the facetValue
(facetValue.indexOf(hierarchicalSeparator) === -1 &&
currentRefinement.indexOf(hierarchicalSeparator) === -1) ||
// currentRefinement is a child of the facet value
currentRefinement.indexOf(facetValue) === 0 ||
// facetValue is a child of the current parent, add it
(facetValue.indexOf(parentPath + hierarchicalSeparator) === 0 &&
(hierarchicalShowParentLevel ||
facetValue.indexOf(currentRefinement) === 0))
);
}
function format(
facetCount,
facetValue,
hierarchicalSeparator,
currentRefinement,
exhaustive
) {
var parts = facetValue.split(hierarchicalSeparator);
return {
name: parts[parts.length - 1].trim(),
path: facetValue,
escapedValue: escapeFacetValue(facetValue),
count: facetCount,
isRefined:
currentRefinement === facetValue ||
currentRefinement.indexOf(facetValue + hierarchicalSeparator) === 0,
exhaustive: exhaustive,
data: null,
};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
'use strict';
module.exports = function compact(array) {
if (!Array.isArray(array)) {
return [];
}
return array.filter(Boolean);
};

View File

@@ -0,0 +1,21 @@
'use strict';
// NOTE: this behaves like lodash/defaults, but doesn't mutate the target
// it also preserve keys order
module.exports = function defaultsPure() {
var sources = Array.prototype.slice.call(arguments);
return sources.reduceRight(function (acc, source) {
Object.keys(Object(source)).forEach(function (key) {
if (source[key] === undefined) {
return;
}
if (acc[key] !== undefined) {
// remove if already added, so that we can add it in correct order
delete acc[key];
}
acc[key] = source[key];
});
return acc;
}, {});
};

View File

@@ -0,0 +1,30 @@
'use strict';
/**
* Replaces a leading - with \-
* @private
* @param {any} value the facet value to replace
* @returns {any} the escaped facet value or the value if it was not a string
*/
function escapeFacetValue(value) {
if (typeof value !== 'string') return value;
return String(value).replace(/^-/, '\\-');
}
/**
* Replaces a leading \- with -
* @private
* @param {any} value the escaped facet value
* @returns {any} the unescaped facet value or the value if it was not a string
*/
function unescapeFacetValue(value) {
if (typeof value !== 'string') return value;
return value.replace(/^\\-/, '-');
}
module.exports = {
escapeFacetValue: escapeFacetValue,
unescapeFacetValue: unescapeFacetValue,
};

View File

@@ -0,0 +1,16 @@
'use strict';
// @MAJOR can be replaced by native Array#find when we change support
module.exports = function find(array, comparator) {
if (!Array.isArray(array)) {
return undefined;
}
for (var i = 0; i < array.length; i++) {
if (comparator(array[i])) {
return array[i];
}
}
return undefined;
};

View File

@@ -0,0 +1,15 @@
'use strict';
// @MAJOR can be replaced by native Array#findIndex when we change support
module.exports = function find(array, comparator) {
if (!Array.isArray(array)) {
return -1;
}
for (var i = 0; i < array.length; i++) {
if (comparator(array[i])) {
return i;
}
}
return -1;
};

View File

@@ -0,0 +1,39 @@
'use strict';
var find = require('./find');
/**
* Transform sort format from user friendly notation to lodash format
* @param {string[]} sortBy array of predicate of the form "attribute:order"
* @param {string[]} [defaults] array of predicate of the form "attribute:order"
* @return {array.<string[]>} array containing 2 elements : attributes, orders
*/
module.exports = function formatSort(sortBy, defaults) {
var defaultInstructions = (defaults || []).map(function (sort) {
return sort.split(':');
});
return sortBy.reduce(
function preparePredicate(out, sort) {
var sortInstruction = sort.split(':');
var matchingDefault = find(
defaultInstructions,
function (defaultInstruction) {
return defaultInstruction[0] === sortInstruction[0];
}
);
if (sortInstruction.length > 1 || !matchingDefault) {
out[0].push(sortInstruction[0]);
out[1].push(sortInstruction[1]);
return out;
}
out[0].push(matchingDefault[0]);
out[1].push(matchingDefault[1]);
return out;
},
[[], []]
);
};

View File

@@ -0,0 +1,14 @@
'use strict';
function inherits(ctor, superCtor) {
ctor.prototype = Object.create(superCtor.prototype, {
constructor: {
value: ctor,
enumerable: false,
writable: true,
configurable: true,
},
});
}
module.exports = inherits;

View File

@@ -0,0 +1,12 @@
'use strict';
function intersection(arr1, arr2) {
return arr1.filter(function (value, index) {
return (
arr2.indexOf(value) > -1 &&
arr1.indexOf(value) === index /* skips duplicates */
);
});
}
module.exports = intersection;

View File

@@ -0,0 +1,84 @@
'use strict';
function clone(value) {
if (typeof value === 'object' && value !== null) {
return _merge(Array.isArray(value) ? [] : {}, value);
}
return value;
}
function isObjectOrArrayOrFunction(value) {
return (
typeof value === 'function' ||
Array.isArray(value) ||
Object.prototype.toString.call(value) === '[object Object]'
);
}
function _merge(target, source) {
if (target === source) {
return target;
}
// eslint-disable-next-line no-restricted-syntax
for (var key in source) {
if (
!Object.prototype.hasOwnProperty.call(source, key) ||
key === '__proto__' ||
key === 'constructor'
) {
// eslint-disable-next-line no-continue
continue;
}
var sourceVal = source[key];
var targetVal = target[key];
if (typeof targetVal !== 'undefined' && typeof sourceVal === 'undefined') {
// eslint-disable-next-line no-continue
continue;
}
if (
isObjectOrArrayOrFunction(targetVal) &&
isObjectOrArrayOrFunction(sourceVal)
) {
target[key] = _merge(targetVal, sourceVal);
} else {
target[key] = clone(sourceVal);
}
}
return target;
}
/**
* This method is like Object.assign, but recursively merges own and inherited
* enumerable keyed properties of source objects into the destination object.
*
* NOTE: this behaves like lodash/merge, but:
* - does mutate functions if they are a source
* - treats non-plain objects as plain
* - does not work for circular objects
* - treats sparse arrays as sparse
* - does not convert Array-like objects (Arguments, NodeLists, etc.) to arrays
*
* @param {Object} target The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
*/
function merge(target) {
if (!isObjectOrArrayOrFunction(target)) {
target = {};
}
for (var i = 1, l = arguments.length; i < l; i++) {
var source = arguments[i];
if (isObjectOrArrayOrFunction(source)) {
_merge(target, source);
}
}
return target;
}
module.exports = merge;

View File

@@ -0,0 +1,7 @@
'use strict';
function objectHasKeys(obj) {
return obj && Object.keys(obj).length > 0;
}
module.exports = objectHasKeys;

View File

@@ -0,0 +1,19 @@
'use strict';
// https://github.com/babel/babel/blob/3aaafae053fa75febb3aa45d45b6f00646e30ba4/packages/babel-helpers/src/helpers.js#L604-L620
function _objectWithoutPropertiesLoose(source, excluded) {
if (source === null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key;
var i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
// eslint-disable-next-line no-continue
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
module.exports = _objectWithoutPropertiesLoose;

View File

@@ -0,0 +1,80 @@
'use strict';
function compareAscending(value, other) {
if (value !== other) {
var valIsDefined = value !== undefined;
var valIsNull = value === null;
var othIsDefined = other !== undefined;
var othIsNull = other === null;
if (
(!othIsNull && value > other) ||
(valIsNull && othIsDefined) ||
!valIsDefined
) {
return 1;
}
if (
(!valIsNull && value < other) ||
(othIsNull && valIsDefined) ||
!othIsDefined
) {
return -1;
}
}
return 0;
}
/**
* @param {Array<object>} collection object with keys in attributes
* @param {Array<string>} iteratees attributes
* @param {Array<string>} orders asc | desc
* @return {Array<object>} sorted collection
*/
function orderBy(collection, iteratees, orders) {
if (!Array.isArray(collection)) {
return [];
}
if (!Array.isArray(orders)) {
orders = [];
}
var result = collection.map(function (value, index) {
return {
criteria: iteratees.map(function (iteratee) {
return value[iteratee];
}),
index: index,
value: value,
};
});
result.sort(function comparer(object, other) {
var index = -1;
while (++index < object.criteria.length) {
var res = compareAscending(object.criteria[index], other.criteria[index]);
if (res) {
if (index >= orders.length) {
return res;
}
if (orders[index] === 'desc') {
return -res;
}
return res;
}
}
// This ensures a stable sort in V8 and other engines.
// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.
return object.index - other.index;
});
return result.map(function (res) {
return res.value;
});
}
module.exports = orderBy;

View File

@@ -0,0 +1,17 @@
'use strict';
function valToNumber(v) {
if (typeof v === 'number') {
return v;
} else if (typeof v === 'string') {
return parseFloat(v);
} else if (Array.isArray(v)) {
return v.map(valToNumber);
}
throw new Error(
'The value should be a number, a parsable string or an array of those.'
);
}
module.exports = valToNumber;

448
node_modules/algoliasearch-helper/src/requestBuilder.js generated vendored Normal file
View File

@@ -0,0 +1,448 @@
'use strict';
var merge = require('./functions/merge');
function sortObject(obj) {
return Object.keys(obj)
.sort()
.reduce(function (acc, curr) {
acc[curr] = obj[curr];
return acc;
}, {});
}
var requestBuilder = {
/**
* Get all the queries to send to the client, those queries can used directly
* with the Algolia client.
* @private
* @param {string} index The name of the index
* @param {SearchParameters} state The state from which to get the queries
* @return {object[]} The queries
*/
_getQueries: function getQueries(index, state) {
var queries = [];
// One query for the hits
queries.push({
indexName: index,
params: requestBuilder._getHitsSearchParams(state),
});
// One for each disjunctive facets
state.getRefinedDisjunctiveFacets().forEach(function (refinedFacet) {
queries.push({
indexName: index,
params: requestBuilder._getDisjunctiveFacetSearchParams(
state,
refinedFacet
),
});
});
// More to get the parent levels of the hierarchical facets when refined
state.getRefinedHierarchicalFacets().forEach(function (refinedFacet) {
var hierarchicalFacet = state.getHierarchicalFacetByName(refinedFacet);
var currentRefinement = state.getHierarchicalRefinement(refinedFacet);
var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);
// If we are deeper than level 0 (starting from `beer > IPA`)
// we want to get all parent values
if (
currentRefinement.length > 0 &&
currentRefinement[0].split(separator).length > 1
) {
// We generate a map of the filters we will use for our facet values queries
var filtersMap = currentRefinement[0]
.split(separator)
.slice(0, -1)
.reduce(function createFiltersMap(map, segment, level) {
return map.concat({
attribute: hierarchicalFacet.attributes[level],
value:
level === 0
? segment
: [map[map.length - 1].value, segment].join(separator),
});
}, []);
filtersMap.forEach(function (filter, level) {
var params = requestBuilder._getDisjunctiveFacetSearchParams(
state,
filter.attribute,
level === 0
);
// Keep facet filters unrelated to current hierarchical attributes
function hasHierarchicalFacetFilter(value) {
return hierarchicalFacet.attributes.some(function (attribute) {
return attribute === value.split(':')[0];
});
}
var filteredFacetFilters = (params.facetFilters || []).reduce(
function (acc, facetFilter) {
if (Array.isArray(facetFilter)) {
var filtered = facetFilter.filter(function (filterValue) {
return !hasHierarchicalFacetFilter(filterValue);
});
if (filtered.length > 0) {
acc.push(filtered);
}
}
if (
typeof facetFilter === 'string' &&
!hasHierarchicalFacetFilter(facetFilter)
) {
acc.push(facetFilter);
}
return acc;
},
[]
);
var parent = filtersMap[level - 1];
if (level > 0) {
params.facetFilters = filteredFacetFilters.concat(
parent.attribute + ':' + parent.value
);
} else {
params.facetFilters =
filteredFacetFilters.length > 0
? filteredFacetFilters
: undefined;
}
queries.push({ indexName: index, params: params });
});
}
});
return queries;
},
/**
* Build search parameters used to fetch hits
* @private
* @param {SearchParameters} state The state from which to get the queries
* @return {object.<string, any>} The search parameters for hits
*/
_getHitsSearchParams: function (state) {
var facets = state.facets
.concat(state.disjunctiveFacets)
.concat(requestBuilder._getHitsHierarchicalFacetsAttributes(state))
.sort();
var facetFilters = requestBuilder._getFacetFilters(state);
var numericFilters = requestBuilder._getNumericFilters(state);
var tagFilters = requestBuilder._getTagFilters(state);
var additionalParams = {
facets: facets.indexOf('*') > -1 ? ['*'] : facets,
tagFilters: tagFilters,
};
if (facetFilters.length > 0) {
additionalParams.facetFilters = facetFilters;
}
if (numericFilters.length > 0) {
additionalParams.numericFilters = numericFilters;
}
return sortObject(merge({}, state.getQueryParams(), additionalParams));
},
/**
* Build search parameters used to fetch a disjunctive facet
* @private
* @param {SearchParameters} state The state from which to get the queries
* @param {string} facet the associated facet name
* @param {boolean} hierarchicalRootLevel ?? FIXME
* @return {object} The search parameters for a disjunctive facet
*/
_getDisjunctiveFacetSearchParams: function (
state,
facet,
hierarchicalRootLevel
) {
var facetFilters = requestBuilder._getFacetFilters(
state,
facet,
hierarchicalRootLevel
);
var numericFilters = requestBuilder._getNumericFilters(state, facet);
var tagFilters = requestBuilder._getTagFilters(state);
var additionalParams = {
hitsPerPage: 0,
page: 0,
analytics: false,
clickAnalytics: false,
};
if (tagFilters.length > 0) {
additionalParams.tagFilters = tagFilters;
}
var hierarchicalFacet = state.getHierarchicalFacetByName(facet);
if (hierarchicalFacet) {
additionalParams.facets =
requestBuilder._getDisjunctiveHierarchicalFacetAttribute(
state,
hierarchicalFacet,
hierarchicalRootLevel
);
} else {
additionalParams.facets = facet;
}
if (numericFilters.length > 0) {
additionalParams.numericFilters = numericFilters;
}
if (facetFilters.length > 0) {
additionalParams.facetFilters = facetFilters;
}
return sortObject(merge({}, state.getQueryParams(), additionalParams));
},
/**
* Return the numeric filters in an algolia request fashion
* @private
* @param {SearchParameters} state the state from which to get the filters
* @param {string} [facetName] the name of the attribute for which the filters should be excluded
* @return {string[]} the numeric filters in the algolia format
*/
_getNumericFilters: function (state, facetName) {
if (state.numericFilters) {
return state.numericFilters;
}
var numericFilters = [];
Object.keys(state.numericRefinements).forEach(function (attribute) {
var operators = state.numericRefinements[attribute] || {};
Object.keys(operators).forEach(function (operator) {
var values = operators[operator] || [];
if (facetName !== attribute) {
values.forEach(function (value) {
if (Array.isArray(value)) {
var vs = value.map(function (v) {
return attribute + operator + v;
});
numericFilters.push(vs);
} else {
numericFilters.push(attribute + operator + value);
}
});
}
});
});
return numericFilters;
},
/**
* Return the tags filters depending on which format is used, either tagFilters or tagRefinements
* @private
* @param {SearchParameters} state the state from which to get the filters
* @return {string} Tag filters in a single string
*/
_getTagFilters: function (state) {
if (state.tagFilters) {
return state.tagFilters;
}
return state.tagRefinements.join(',');
},
/**
* Build facetFilters parameter based on current refinements. The array returned
* contains strings representing the facet filters in the algolia format.
* @private
* @param {SearchParameters} state The state from which to get the queries
* @param {string} [facet] if set, the current disjunctive facet
* @param {boolean} [hierarchicalRootLevel] ?? FIXME
* @return {array.<string>} The facet filters in the algolia format
*/
_getFacetFilters: function (state, facet, hierarchicalRootLevel) {
var facetFilters = [];
var facetsRefinements = state.facetsRefinements || {};
Object.keys(facetsRefinements)
.sort()
.forEach(function (facetName) {
var facetValues = facetsRefinements[facetName] || [];
facetValues
.slice()
.sort()
.forEach(function (facetValue) {
facetFilters.push(facetName + ':' + facetValue);
});
});
var facetsExcludes = state.facetsExcludes || {};
Object.keys(facetsExcludes)
.sort()
.forEach(function (facetName) {
var facetValues = facetsExcludes[facetName] || [];
facetValues.sort().forEach(function (facetValue) {
facetFilters.push(facetName + ':-' + facetValue);
});
});
var disjunctiveFacetsRefinements = state.disjunctiveFacetsRefinements || {};
Object.keys(disjunctiveFacetsRefinements)
.sort()
.forEach(function (facetName) {
var facetValues = disjunctiveFacetsRefinements[facetName] || [];
if (facetName === facet || !facetValues || facetValues.length === 0) {
return;
}
var orFilters = [];
facetValues
.slice()
.sort()
.forEach(function (facetValue) {
orFilters.push(facetName + ':' + facetValue);
});
facetFilters.push(orFilters);
});
var hierarchicalFacetsRefinements =
state.hierarchicalFacetsRefinements || {};
Object.keys(hierarchicalFacetsRefinements)
.sort()
.forEach(function (facetName) {
var facetValues = hierarchicalFacetsRefinements[facetName] || [];
var facetValue = facetValues[0];
if (facetValue === undefined) {
return;
}
var hierarchicalFacet = state.getHierarchicalFacetByName(facetName);
var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);
var rootPath = state._getHierarchicalRootPath(hierarchicalFacet);
var attributeToRefine;
var attributesIndex;
// we ask for parent facet values only when the `facet` is the current hierarchical facet
if (facet === facetName) {
// if we are at the root level already, no need to ask for facet values, we get them from
// the hits query
if (
facetValue.indexOf(separator) === -1 ||
(!rootPath && hierarchicalRootLevel === true) ||
(rootPath &&
rootPath.split(separator).length ===
facetValue.split(separator).length)
) {
return;
}
if (!rootPath) {
attributesIndex = facetValue.split(separator).length - 2;
facetValue = facetValue.slice(0, facetValue.lastIndexOf(separator));
} else {
attributesIndex = rootPath.split(separator).length - 1;
facetValue = rootPath;
}
attributeToRefine = hierarchicalFacet.attributes[attributesIndex];
} else {
attributesIndex = facetValue.split(separator).length - 1;
attributeToRefine = hierarchicalFacet.attributes[attributesIndex];
}
if (attributeToRefine) {
facetFilters.push([attributeToRefine + ':' + facetValue]);
}
});
return facetFilters;
},
_getHitsHierarchicalFacetsAttributes: function (state) {
var out = [];
return state.hierarchicalFacets.reduce(
// ask for as much levels as there's hierarchical refinements
function getHitsAttributesForHierarchicalFacet(
allAttributes,
hierarchicalFacet
) {
var hierarchicalRefinement = state.getHierarchicalRefinement(
hierarchicalFacet.name
)[0];
// if no refinement, ask for root level
if (!hierarchicalRefinement) {
allAttributes.push(hierarchicalFacet.attributes[0]);
return allAttributes;
}
var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);
var level = hierarchicalRefinement.split(separator).length;
var newAttributes = hierarchicalFacet.attributes.slice(0, level + 1);
return allAttributes.concat(newAttributes);
},
out
);
},
_getDisjunctiveHierarchicalFacetAttribute: function (
state,
hierarchicalFacet,
rootLevel
) {
var separator = state._getHierarchicalFacetSeparator(hierarchicalFacet);
if (rootLevel === true) {
var rootPath = state._getHierarchicalRootPath(hierarchicalFacet);
var attributeIndex = 0;
if (rootPath) {
attributeIndex = rootPath.split(separator).length;
}
return [hierarchicalFacet.attributes[attributeIndex]];
}
var hierarchicalRefinement =
state.getHierarchicalRefinement(hierarchicalFacet.name)[0] || '';
// if refinement is 'beers > IPA > Flying dog',
// then we want `facets: ['beers > IPA']` as disjunctive facet (parent level values)
var parentLevel = hierarchicalRefinement.split(separator).length - 1;
return hierarchicalFacet.attributes.slice(0, parentLevel + 1);
},
getSearchForFacetQuery: function (facetName, query, maxFacetHits, state) {
var stateForSearchForFacetValues = state.isDisjunctiveFacet(facetName)
? state.clearRefinements(facetName)
: state;
var searchForFacetSearchParameters = {
facetQuery: query,
facetName: facetName,
};
if (typeof maxFacetHits === 'number') {
searchForFacetSearchParameters.maxFacetHits = maxFacetHits;
}
return sortObject(
merge(
{},
requestBuilder._getHitsSearchParams(stateForSearchForFacetValues),
searchForFacetSearchParameters
)
);
},
};
module.exports = requestBuilder;

View File

@@ -0,0 +1,8 @@
'use strict';
module.exports = function isValidUserToken(userToken) {
if (userToken === null) {
return false;
}
return /^[a-zA-Z0-9_-]{1,64}$/.test(userToken);
};

3
node_modules/algoliasearch-helper/src/version.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
'use strict';
module.exports = '3.16.3';

View File

@@ -0,0 +1,175 @@
// Note: Below, we will be importing all algoliasearch v3,4,5 types.
// The goal is being able to export the algoliasearch-helper types using
// the version of the client installed by the developer.
// @ts-ignore
import type * as ClientSearch from '@algolia/client-search';
// @ts-ignore
import type * as AlgoliaSearch from 'algoliasearch';
// @ts-ignore
import type algoliasearch from 'algoliasearch/lite';
// @ts-ignore
import type * as AlgoliaSearchLite from 'algoliasearch/lite';
// turns any to unknown, so it can be used as a conditional
// more info in https://stackoverflow.com/a/49928360/3185307
type AnyToUnknown<T> = (0 extends 1 & T ? true : false) extends true
? unknown
: T;
type SearchClientV4Shape = {
transporter: unknown;
};
type SearchClientShape = {
search: unknown;
};
// @ts-ignore
type ClientV3_4 = ReturnType<typeof algoliasearch>;
type ClientLiteV5 = AnyToUnknown<
// @ts-ignore
ReturnType<typeof AlgoliaSearchLite.liteClient>
>;
type ClientFullV5 = AnyToUnknown<
// @ts-ignore
ReturnType<typeof AlgoliaSearch.algoliasearch>
>;
type ClientSearchV5 = AnyToUnknown<
// @ts-ignore
ReturnType<typeof ClientSearch.searchClient>
>;
type ClientV5 = ClientLiteV5 extends SearchClientShape
? ClientLiteV5
: ClientSearchV5 extends SearchClientShape
? ClientSearchV5
: ClientFullV5 extends SearchClientShape
? ClientFullV5
: unknown;
type PickForClient<
T extends {
v3: unknown;
v4: unknown;
v5: unknown;
}
> = ClientV5 extends SearchClientShape
? T['v5']
: // @ts-ignore
ClientV3_4 extends SearchClientV4Shape
? T['v4']
: T['v3'];
type DefaultSearchClient = PickForClient<{
v3: ClientV3_4;
v4: ClientV3_4;
v5: ClientV5;
}>;
export type HighlightResult<T> = PickForClient<{
// @ts-ignore this doesn't exist as an exact type in v3
v3: any;
// @ts-ignore
v4: ClientSearch.HighlightResult<T>;
// @ts-ignore the type in the v5 library is not yet correct https://github.com/algolia/api-clients-automation/issues/853
v5: any;
}>;
export type SnippetResult<T> = PickForClient<{
// @ts-ignore this doesn't exist as an exact type in v3
v3: any;
// @ts-ignore
v4: ClientSearch.SnippetResult<T>;
// @ts-ignore the type in the v5 library is not yet correct https://github.com/algolia/api-clients-automation/issues/853
v5: any;
}>;
export type RankingInfo = PickForClient<{
v3: Record<string, unknown>;
// @ts-ignore
v4: ClientSearch.RankingInfo;
// @ts-ignore
v5: AlgoliaSearch.RankingInfo;
}>;
export type SearchOptions = PickForClient<{
// @ts-ignore
v3: AlgoliaSearch.QueryParameters;
// @ts-ignore
v4: ClientSearch.SearchOptions;
v5: NonNullable<
// @ts-ignore
AlgoliaSearch.LegacySearchMethodProps[number]['params']
>;
}>;
export type SearchResponse<T> = PickForClient<{
// @ts-ignore
v3: AlgoliaSearch.Response<T> & {
appliedRelevancyStrictness?: number;
nbSortedHits?: number;
renderingContent?: {
facetOrdering?: {
facets?: {
order?: string[];
};
values?: {
[facet: string]: {
order?: string[];
sortRemainingBy?: 'count' | 'alpha' | 'hidden';
};
};
};
};
};
// @ts-ignore
v4: ClientSearch.SearchResponse<T>;
// @ts-ignore
v5: AlgoliaSearch.SearchResponse; // TODO: should be generic https://github.com/algolia/api-clients-automation/issues/853
}>;
export type SearchResponses<T> = PickForClient<{
// @ts-ignore
v3: AlgoliaSearch.MultiResponse<T>;
// @ts-ignore
v4: ClientSearch.MultipleQueriesResponse<T>;
// @ts-ignore
v5: AlgoliaSearch.SearchResponses; // TODO: should be generic https://github.com/algolia/api-clients-automation/issues/853
}>;
export type SearchForFacetValuesResponse = PickForClient<{
// @ts-ignore
v3: AlgoliaSearch.SearchForFacetValues.Response;
// @ts-ignore
v4: ClientSearch.SearchForFacetValuesResponse;
// @ts-ignore
v5: AlgoliaSearch.SearchForFacetValuesResponse;
}>;
export type FindAnswersOptions = PickForClient<{
v3: any; // answers only exists in v4
// @ts-ignore
v4: ClientSearch.FindAnswersOptions;
v5: any; // answers only exists in v4
}>;
export type FindAnswersResponse<T> = PickForClient<{
v3: any; // answers only exists in v4
// @ts-ignore
v4: ClientSearch.FindAnswersResponse<T>;
v5: any; // answers only exists in v4
}>;
export interface SearchClient {
search: DefaultSearchClient['search'];
searchForFacetValues?: DefaultSearchClient extends {
searchForFacetValues: unknown;
}
? DefaultSearchClient['searchForFacetValues']
: never;
initIndex?: DefaultSearchClient extends { initIndex: unknown }
? DefaultSearchClient['initIndex']
: never;
addAlgoliaAgent?: DefaultSearchClient['addAlgoliaAgent'];
}

View File

@@ -0,0 +1 @@
// fake file to allow `export * from 'algoliasearch-helper/types/algoliasearch'`