├── .circleci
└── config.yml
├── .codesandbox
└── ci.json
├── .eslintignore
├── .eslintrc.js
├── .git-blame-ignore-revs
├── .gitignore
├── .nvmrc
├── .prettierignore
├── .prettierrc
├── CHANGELOG
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── documentation-src
├── content
│ ├── concepts.md
│ ├── examples.md
│ ├── gettingstarted.md
│ ├── images
│ │ ├── al-helper-logo.svg
│ │ ├── algolia-mark-white.svg
│ │ ├── background_footer.svg
│ │ ├── community-badge.svg
│ │ ├── concepts
│ │ │ ├── Events.svg
│ │ │ ├── conjunctive-facets.svg
│ │ │ ├── derive-simplified.svg
│ │ │ ├── disjunctive-facets.svg
│ │ │ ├── search-cycle.svg
│ │ │ ├── search-states.svg
│ │ │ ├── setting-parameters.svg
│ │ │ └── state-is-immutable.svg
│ │ ├── icon-arrow-pipe.svg
│ │ ├── icon-github.svg
│ │ ├── icon-heart-dark.svg
│ │ ├── icon-heart-light.svg
│ │ └── icon-search-white.svg
│ ├── index.md
│ ├── js
│ │ └── main.js
│ ├── reference.md
│ └── upgrade.md
├── layouts
│ ├── common
│ │ ├── footer.pug
│ │ ├── header.pug
│ │ └── metas.pug
│ ├── documentation.pug
│ └── main.pug
├── metalsmith.js
├── partials
│ ├── event.hbs
│ ├── jsdoc.hbs
│ ├── member.hbs
│ ├── method.hbs
│ ├── typedef.hbs
│ └── types.hbs
├── plugins
│ ├── handlebars-helpers.js
│ ├── headings.js
│ └── jsdoc-data.js
└── stylesheets
│ ├── components
│ ├── _buttons.scss
│ ├── _clipboard.scss
│ ├── _code-highlight.scss
│ ├── _containers.scss
│ ├── _documentation.scss
│ ├── _examples-intro.scss
│ ├── _examples.scss
│ ├── _fonts.scss
│ ├── _footer.scss
│ ├── _home.scss
│ ├── _icons.scss
│ ├── _inputs.scss
│ ├── _media.scss
│ ├── _sidebar.scss
│ ├── _visual-helper.scss
│ └── docs
│ │ └── _method.scss
│ ├── index.scss
│ └── vendors
│ ├── _animations.scss
│ ├── _base.scss
│ ├── _communityHeader.scss
│ ├── _helpers.scss
│ ├── _mixins.scss
│ ├── _normalize.scss
│ └── _variables.scss
├── examples
└── readme.md
├── index.d.ts
├── index.html
├── index.js
├── jest.config.js
├── jest.setup.js
├── package.json
├── patches
└── metalsmith-in-place+1.4.4.patch
├── scripts
├── build.sh
├── conventional-changelog
│ └── index.js
├── lib
│ └── conventionalChangelog.js
├── release.js
├── retry.sh
├── staging-doc.sh
└── test.sh
├── src
├── DerivedHelper
│ └── index.js
├── SearchParameters
│ ├── RefinementList.js
│ └── index.js
├── SearchResults
│ ├── generate-hierarchical-tree.js
│ └── index.js
├── algoliasearch.helper.js
├── functions
│ ├── compact.js
│ ├── defaultsPure.js
│ ├── escapeFacetValue.js
│ ├── find.js
│ ├── findIndex.js
│ ├── formatSort.js
│ ├── inherits.js
│ ├── intersection.js
│ ├── merge.js
│ ├── objectHasKeys.js
│ ├── omit.js
│ ├── orderBy.js
│ └── valToNumber.js
├── requestBuilder.js
├── utils
│ └── isValidUserToken.js
└── version.js
├── test
├── datasets
│ ├── SearchParameters
│ │ └── search.dataset.js
│ └── SearchResults
│ │ ├── getFacetValues.dataset.js
│ │ └── getRefinements.dataset.js
├── integration-spec
│ ├── helper.derive.js
│ ├── helper.distinct.facet.js
│ ├── helper.filters.js
│ ├── helper.geo.js
│ ├── helper.highlight.js
│ ├── helper.insights.js
│ ├── helper.numerics.js
│ ├── helper.results.getFacetValues.js
│ ├── helper.searchForFacetValues.js
│ ├── helper.searchOnce.js
│ └── helper.tags.js
├── integration-utils.js
├── replayTools.js
├── run.js
├── spec
│ ├── SearchParameters
│ │ ├── RefinementList
│ │ │ └── clear.js
│ │ ├── _clearNumericRefinements.js
│ │ ├── _parseNumbers.js
│ │ ├── constructorFn.js
│ │ ├── getConjunctiveRefinements.js
│ │ ├── getDisjunctiveRefinements.js
│ │ ├── getExcludeRefinements.js
│ │ ├── hierarchical-facets
│ │ │ ├── add.js
│ │ │ └── remove.js
│ │ ├── isDisjunctiveFacetRefined.js
│ │ ├── isExcludeRefined.js
│ │ ├── isFacetRefined.js
│ │ ├── isHierarchicalFacetRefined.js
│ │ ├── isNumericRefined.js
│ │ ├── listAttributes.js
│ │ ├── noChanges.js
│ │ ├── numericAttributes.js
│ │ ├── numericFilters.js
│ │ ├── removeXFacet.js
│ │ ├── removeXFacetRefinement.js
│ │ ├── resetPage.js
│ │ ├── setQueryParameter.js
│ │ └── setQueryParameters.js
│ ├── SearchResults
│ │ ├── getFacet.js
│ │ ├── getFacetStats.js
│ │ ├── getFacetValues-facetOrdering.js
│ │ ├── getFacetValues.js
│ │ ├── getFacetValues
│ │ │ ├── conjunctive.json
│ │ │ ├── disjunctive.json
│ │ │ ├── hierarchical.json
│ │ │ ├── noFilters.json
│ │ │ └── sparse.json
│ │ ├── getRefinements.js
│ │ ├── getRefinements
│ │ │ ├── conjunctive-brand-apple.json
│ │ │ ├── disjunctive-type-trendcase.json
│ │ │ ├── dummy-tags.json
│ │ │ ├── exclude-apple.json
│ │ │ ├── exclude-artificial-results.json
│ │ │ ├── hierarchical-cards.json
│ │ │ ├── noFilters.json
│ │ │ └── numeric-rating-3.json
│ │ └── initialization.js
│ ├── algoliasearch.helper
│ │ ├── addFacetRefinement.js
│ │ ├── clears.js
│ │ ├── client.js
│ │ ├── constructor.js
│ │ ├── derive
│ │ │ ├── detach.js
│ │ │ ├── empty-index.js
│ │ │ ├── events.js
│ │ │ └── multiqueries.js
│ │ ├── distinct.js
│ │ ├── events.js
│ │ ├── excludes.js
│ │ ├── facetFilters.js
│ │ ├── findAnswers.js
│ │ ├── getNumericRefinement.js
│ │ ├── getQuery.js
│ │ ├── hasRefinements.js
│ │ ├── incorrectFacetDefinition.js
│ │ ├── numericFilters.js
│ │ ├── pages.js
│ │ ├── pendingSearch.js
│ │ ├── queryID.js
│ │ ├── searchForFacetValues.js
│ │ ├── searchOnce.js
│ │ ├── setQueryParameter.js
│ │ ├── state.js
│ │ └── tags.js
│ ├── functions
│ │ ├── compact.js
│ │ ├── defaultsPure.js
│ │ ├── find.js
│ │ ├── findIndex.js
│ │ ├── formatSort.js
│ │ ├── intersection.js
│ │ ├── merge.js
│ │ ├── orderBy.js
│ │ └── valToNumber.js
│ ├── hierarchical-facets
│ │ ├── add-remove.js
│ │ ├── attributes-order.js
│ │ ├── breadcrumb.js
│ │ ├── custom-prefix-path.js
│ │ ├── custom-separator.js
│ │ ├── do-not-show-parent-level.js
│ │ ├── facet-value-length.js
│ │ ├── getFacetValues.js
│ │ ├── no-refinement.js
│ │ ├── no-trim.js
│ │ ├── objects-with-multiple-categories.js
│ │ ├── one-level.js
│ │ ├── pagination.js
│ │ ├── parent-toggleRefine.js
│ │ ├── refined-no-result.js
│ │ ├── show-parent-level.js
│ │ ├── simple-usage.js
│ │ ├── sort-by.js
│ │ ├── two-facets.js
│ │ ├── unknown-facet.js
│ │ └── with-a-disjunctive-facet.js
│ ├── refinements.js
│ ├── requestBuilder.js
│ ├── search.js
│ └── utils
│ │ └── isValidUserToken.js
└── types.ts
├── tsconfig.json
├── types
├── algoliasearch.d.ts
└── algoliasearch.js
└── yarn.lock
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | aliases:
2 | - &install_yarn_version
3 | name: Install specific Yarn version
4 | command: |
5 | curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.15.2
6 | echo 'export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"' >> $BASH_ENV
7 |
8 | - &restore_yarn_cache
9 | name: Restore Yarn cache
10 | keys:
11 | - yarn-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
12 |
13 | - &save_yarn_cache
14 | name: Save Yarn cache
15 | key: yarn-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
16 | paths:
17 | - ~/.cache/yarn
18 |
19 | - &run_yarn_install
20 | name: Install dependencies
21 | command: yarn install
22 |
23 | defaults: &defaults
24 | working_directory: ~/algoliasearch-helper-js
25 | docker:
26 | - image: cimg/node:14.18.0
27 |
28 | version: 2
29 | jobs:
30 | build:
31 | <<: *defaults
32 | steps:
33 | - checkout
34 | - run: *install_yarn_version
35 | - restore_cache: *restore_yarn_cache
36 | - run: *run_yarn_install
37 | - save_cache: *save_yarn_cache
38 | - run:
39 | name: Build
40 | command: yarn build
41 |
42 | test:
43 | <<: *defaults
44 | steps:
45 | - checkout
46 | - run: *install_yarn_version
47 | - restore_cache: *restore_yarn_cache
48 | - run: *run_yarn_install
49 | - save_cache: *save_yarn_cache
50 | - run:
51 | name: Lint & Code styles
52 | command: yarn lint
53 | - run:
54 | name: Unit & Integration Tests
55 | command: yarn test --maxWorkers=4
56 | - run:
57 | name: Type checking
58 | command: yarn tsc
59 |
60 | 'test algoliasearch v3':
61 | <<: *defaults
62 | steps:
63 | - checkout
64 | - run: *install_yarn_version
65 | - restore_cache: *restore_yarn_cache
66 | - run: *run_yarn_install
67 | - save_cache: *save_yarn_cache
68 | - run:
69 | name: Install algoliasearch v3
70 | command: yarn add --dev algoliasearch@3.35.1 @types/algoliasearch@3.34.10
71 | - run:
72 | name: Unit & Integration Tests
73 | command: yarn test --maxWorkers=4
74 | - run:
75 | name: Type checking
76 | command: yarn tsc
77 |
78 | docs:
79 | <<: *defaults
80 | steps:
81 | - checkout
82 | - run: *install_yarn_version
83 | - restore_cache: *restore_yarn_cache
84 | - run: *run_yarn_install
85 | - save_cache: *save_yarn_cache
86 | - run:
87 | name: Build documentation
88 | command: yarn doc
89 | - store_artifacts:
90 | path: documentation
91 |
92 | workflows:
93 | version: 2
94 | ci:
95 | jobs:
96 | - build
97 | - test
98 | - test algoliasearch v3
99 | - docs
100 |
--------------------------------------------------------------------------------
/.codesandbox/ci.json:
--------------------------------------------------------------------------------
1 | {
2 | "sandboxes": [
3 | "github/algolia/create-instantsearch-app/tree/templates/javascript-helper",
4 | "instantsearchjs-es-template-pcw1k"
5 | ],
6 | "node": "14"
7 | }
8 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/
2 | documentation-src/
3 | documentation/
4 | scripts/rollup.esm.config.js
5 | *.ts
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @type {import('eslint').Linter.Config}
3 | */
4 | const config = {
5 | extends: [
6 | 'algolia',
7 | 'algolia/jest',
8 | 'algolia/react',
9 | 'algolia/typescript',
10 | 'plugin:react-hooks/recommended',
11 | ],
12 | overrides: [
13 | {
14 | // TODO: should be scoped to helper folder once in monorepo
15 | files: ['*.js'],
16 | rules: {
17 | // Helper uses CommonJS for now
18 | 'import/no-commonjs': 'off',
19 | strict: 'off',
20 | // Helper uses ES5 for now
21 | 'no-var': 'off',
22 | 'vars-on-top': 'off',
23 | 'object-shorthand': 'off',
24 | 'prefer-template': 'off',
25 | 'prefer-spread': 'off',
26 | 'prefer-rest-params': 'off',
27 | },
28 | },
29 | {
30 | // TODO: should be scoped to helper folder once in monorepo
31 | files: ['test/**/*.js'],
32 | rules: {
33 | 'no-console': 'off',
34 | 'jest/no-done-callback': 'off',
35 | 'jest/no-conditional-expect': 'off',
36 | },
37 | env: {
38 | jest: true,
39 | },
40 | globals: {
41 | test: true,
42 | beforeAll: true,
43 | },
44 | },
45 | ],
46 | };
47 |
48 | module.exports = config;
49 |
--------------------------------------------------------------------------------
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # Introduced prettier
2 | cc83731fc794a45d05b915e7419c59f25eb812c5
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # Compiled binary addons (http://nodejs.org/api/addons.html)
20 | build/Release
21 |
22 | # Dependency directory
23 | # Commenting this out is preferred by some people, see
24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
25 | node_modules
26 |
27 | # Users Environment Variables
28 | .lock-wscript
29 |
30 | # Built documentation folder, tracked in gh-pages
31 | documentation
32 |
33 | dist
34 | .DS_Store
35 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 14.18.0
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | documentation-src/partials
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "proseWrap": "never",
4 | "trailingComma": "es5"
5 | }
6 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | How to contribute?
2 |
3 | Basic flow:
4 |
5 | - fork this repository
6 | - setup the project: `yarn`
7 | - start dev mode `yarn dev` and open http://localhost:8090/\_\_zuul
8 | - you can also run both browser and node.js tests by using `npm test`
9 | - code, add a [test](./test/) for every fix or new feature
10 | - commit
11 | - open a pull request
12 |
13 | We will then review your pull request and makes sure your fix helps the community.
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Algolia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # algoliasearch-helper-js has a new home 👋
2 |
3 | This project has moved and is now part of the [InstantSearch monorepo](https://github.com/algolia/instantsearch)! **The library remains unchanged and is still available on npm and CDNs like jsDelivr.**
4 |
5 | You can [browse the code](https://github.com/algolia/instantsearch/tree/master/packages), find [existing issues](https://github.com/algolia/instantsearch/issues?q=is%3Aissue+is%3Aopen+label%3A%22Library%3A+AlgoliaSearch+Helper%22) and follow [new releases](https://github.com/algolia/instantsearch/releases) over there.
6 |
--------------------------------------------------------------------------------
/documentation-src/content/examples.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: documentation.pug
3 | title: Uses of the Helper
4 | ---
5 |
6 | ## Common patterns
7 |
8 | These examples showcase the main features and patterns commonly found using the Helper. They do not contain advanced UI implementations. If you want a pre-built widget library, we suggest you to have a look at [instantsearch.js](https://community.algolia.com/instantsearch.js/).
9 |
10 | ### Results
11 |
12 | This first sample shows you how to implement a search displaying results and how to make use of the highlighting provided by Algolia to display insights about the results to your users.
13 |
14 | {{{codepen "JKyQxx"}}}
15 |
16 | ### Facet list
17 |
18 | This example present you how to configure and use facets in your application.
19 |
20 | {{{codepen "LkjwLE"}}}
21 |
22 | ### Excluding facets
23 |
24 | With excluding facet the user can choose not to have certain values in the results. This very powerful feature is configure the same way the conjunctive facets are.
25 |
26 | {{{codepen "LkzEgG"}}}
27 |
28 | ### Disjunctive facet list
29 |
30 | {{{codepen "bZoVKZ"}}}
31 |
32 | ### Hierarchical facet list
33 |
34 | {{{codepen "QEBRoN"}}}
35 |
36 | ## Use with frameworks
37 |
38 | ### Angular 1
39 |
40 | {{{codepen "PzZobK"}}}
41 |
42 | ### Backbone
43 |
44 | {{{codepen "AXVLmy"}}}
45 |
--------------------------------------------------------------------------------
/documentation-src/content/images/algolia-mark-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/documentation-src/content/images/community-badge.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/documentation-src/content/images/icon-arrow-pipe.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/documentation-src/content/images/icon-github.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/documentation-src/content/images/icon-heart-dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/documentation-src/content/images/icon-heart-light.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/documentation-src/content/images/icon-search-white.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/documentation-src/content/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: main.pug
3 | title: Algolia JS Helper
4 | subtitle: A set of utilities for further customizing search behavior
5 | ---
6 |
7 | Don't sweat, the content of this file won't be read.
8 |
9 | It needs to be there so that we can render the layout.
10 |
--------------------------------------------------------------------------------
/documentation-src/layouts/common/footer.pug:
--------------------------------------------------------------------------------
1 | section.ac-footer
2 | .ac-footer-container
3 | p.ac-footer-links
4 | | Code licensed under
5 | a.ac-footer-link-item(href='https://raw.githubusercontent.com/algolia/algoliasearch-helper-js/master/LICENSE') MIT
6 | br
7 | a.ac-footer-link-item(href='https://github.com/algolia/algoliasearch-helper-js') GitHub
8 | a.ac-footer-link-item(href='https://github.com/algolia/algoliasearch-helper-js/issues') issues
9 | .ac-footer-container.ac-footer-brand
10 | p This project is part of
11 | img.ac-footer-brand-icon(src='images/community-badge.svg')
12 | figure
13 | img.ac-footer-brand-logo(src='https://res.cloudinary.com/hilnmyskv/image/upload/v1484219849/algolia-community-logo-words-darkbg.svg')
14 | figcaption Algolia Community
15 | a.ac-footer-btn.ac-footer-btn-cta(href='https://community.algolia.com/') See More
16 | span.ac-icon.ac-icon-love-dark
17 | p.ac-footer-version Latest version: #{pkg.version}
18 | .ac-footer-actions
19 | .footer-container
20 | p Build unique search experiences with Algolia
21 | a.ac-footer-btn.ac-footer-btn-ghost-grey(href='https://www.algolia.com/why?utm_medium=social-owned&utm_source=helper%20website&utm_campaign=homepage&utm_term=why')
22 | | See Why
23 | span.ac-icon-triangle
24 | a.ac-footer-btn.ac-footer-btn-ghost-pink(href='https://www.algolia.com/users/sign_up?utm_medium=social-owned&utm_source=helper%20website&utm_campaign=homepage&utm_term=get_started') Get Started For Free
25 | script(src='js/main.js')
26 |
--------------------------------------------------------------------------------
/documentation-src/layouts/common/metas.pug:
--------------------------------------------------------------------------------
1 | meta(content='The Algolia JS Helper is the toolbox to create advanced search experience ', name='description')
2 | meta(content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0', name='viewport')
3 | // / Twitter card
4 | meta(content='summary_large_image', name='twitter:card')
5 | meta(content='@Algolia', name='twitter:site')
6 | meta(content='@Algolia', name='twitter:creator')
7 | meta(content='Algolia JS Helper', name='twitter:title')
8 | meta(content='The Algolia JS Helper is the toolbox to create advanced search experience ', name='twitter:description')
9 | meta(content='Algolia Product image', name='twitter:image')
10 | // / OG meta
11 | meta(content=pkg.homepage, property='og:url')
12 | meta(content='Algolia JS Helper documentation', property='og:title')
13 | meta(content='#', property='og:image')
14 | meta(content='article', property='og:type')
15 | meta(content='The Algolia JS Helper is the toolbox to create advanced search experience ', property='og:description')
16 | meta(content='Algolia JS Helper', property='og:site_name')
17 |
--------------------------------------------------------------------------------
/documentation-src/layouts/documentation.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | meta(content='IE=edge', http-equiv='X-UA-Compatible')
5 | meta(charset='utf-8')
6 | meta(content='width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no', name='viewport')
7 | link(href='#', rel='icon', type='image/x-icon')
8 | include ./common/metas.pug
9 | // Use title if it's in the page YAML frontmatter
10 | title= title
11 | link(href='https://fonts.googleapis.com/css?family=Montserrat:500,600|Open+Sans', rel='stylesheet', type='text/css')
12 | link(rel='stylesheet', href='css/index.css')
13 | link(rel='stylesheet', href='https://yandex.st/highlightjs/8.0/styles/github.min.css')
14 | // Google Tag Manager
15 | noscript
16 | iframe(src='//www.googletagmanager.com/ns.html?id=GTM-N8JP8G', height='0', width='0', style='display:none;visibility:hidden')
17 | script.
18 | (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
19 | new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
20 | j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
21 | '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
22 | })(window,document,'script','dataLayer','GTM-N8JP8G');
23 | body(class=page_classes)
24 | include ./common/header.pug
25 | section.hero-section.shrink
26 | .container
27 | .hero-container
28 | .fl-right
29 | img(src='images/al-helper-logo.svg')
30 | .fl-left
31 | a(href='https://www.algolia.com/?utm_medium=social-owned&utm_source=algoliasearch-helper%20website&utm_campaign=homepage', title='Algolia built this')
32 | span#icon-algolia.icon.icon-algolia-small.no-mobile
33 | h1= title
34 | section.documentation-section
35 | .container
36 | nav.sidebar
37 | ul
38 | each item in headings
39 | li(class='level-' + item.tag)
40 | a(href='#' + item.id)= item.text
41 | .documentation-container
42 | | !{contents}
43 | include ./common/footer.pug
44 |
--------------------------------------------------------------------------------
/documentation-src/metalsmith.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 |
4 | var metalsmith = require('metalsmith');
5 | var inPlace = require('metalsmith-in-place');
6 | var markdown = require('metalsmith-markdown');
7 | var jsdoc = require('./plugins/jsdoc-data');
8 | var registerHandleBarHelpers = require('./plugins/handlebars-helpers');
9 | var headings = require('./plugins/headings');
10 | var layouts = require('metalsmith-layouts');
11 | var metallic = require('metalsmith-metallic');
12 | var sass = require('@metalsmith/sass');
13 | var marked = require('marked');
14 |
15 | var isDev = process.env.NODE_ENV === 'development';
16 |
17 | var projectRoot = path.join(__dirname, '..');
18 | var documentationRoot = path.join(projectRoot, 'documentation');
19 | var cssRoot = path.join(documentationRoot, 'css');
20 |
21 | var src = {
22 | stylesheets: path.join(__dirname, './stylesheets'),
23 | content: path.join(__dirname, './content'),
24 | layouts: path.join(__dirname, './layouts'),
25 | partials: path.join(__dirname, './partials'),
26 | js: path.join(__dirname, './js/'),
27 | };
28 |
29 | var customMarkedRenderer = new marked.Renderer();
30 | var oldHeadingRenderer = customMarkedRenderer.heading;
31 | customMarkedRenderer.heading = function (text, level) {
32 | // do not add id to h4+
33 | if (level > 3) {
34 | return '' + text + '';
35 | }
36 | return oldHeadingRenderer.apply(this, arguments);
37 | };
38 |
39 | var project = require('../package.json');
40 | var builder = metalsmith(projectRoot)
41 | .metadata({
42 | pkg: project,
43 | })
44 | .ignore('.*')
45 | .clean(false)
46 | .source(src.content)
47 | .destination(documentationRoot)
48 | .use(
49 | sass({
50 | style: isDev ? 'expanded' : 'compressed',
51 | sourceMap: isDev,
52 | sourceMapIncludeSources: isDev,
53 | loadPaths: ['node_modules'],
54 | entries: {
55 | [path.join(src.stylesheets, 'index.scss')]: path.join(
56 | cssRoot,
57 | 'index.css'
58 | ),
59 | },
60 | })
61 | )
62 | .use(
63 | jsdoc({
64 | src: 'src/algoliasearch.helper.js',
65 | namespace: 'helper',
66 | })
67 | )
68 | .use(
69 | jsdoc({
70 | src: 'src/SearchResults/index.js',
71 | namespace: 'results',
72 | })
73 | )
74 | .use(
75 | jsdoc({
76 | src: 'src/SearchParameters/index.js',
77 | namespace: 'state',
78 | })
79 | )
80 | .use(
81 | jsdoc({
82 | src: 'index.js',
83 | namespace: 'main',
84 | })
85 | )
86 | .use(
87 | inPlace({
88 | engine: 'handlebars',
89 | partials: 'documentation-src/partials',
90 | exposeConsolidate: registerHandleBarHelpers,
91 | })
92 | )
93 | .use(metallic())
94 | .use(
95 | markdown({
96 | gfm: true,
97 | renderer: customMarkedRenderer,
98 | })
99 | )
100 | .use(headings('h2, h3'))
101 | .use(
102 | layouts({
103 | engine: 'pug',
104 | directory: src.layouts,
105 | })
106 | );
107 |
108 | builder.build(function (err) {
109 | if (err) {
110 | throw err;
111 | }
112 | console.log('Metalsmith build finished');
113 | });
114 |
--------------------------------------------------------------------------------
/documentation-src/partials/event.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{{description}}}
6 |
7 |
8 |
21 | {{#if examples}}
22 |
23 | {{#each examples}}
24 |
25 | ```javascript
26 | {{{this}}}
27 | ```
28 |
29 | {{/each}}
30 |
31 | {{/if}}
32 |
33 |
--------------------------------------------------------------------------------
/documentation-src/partials/jsdoc.hbs:
--------------------------------------------------------------------------------
1 | {{!--
2 | The kinds "typedef", "member" and "event" have self-named partials.
3 | "function" and "module" are special cases of "kind" that are mapped to "method".
4 | --}}
5 | {{> (lookup this "kind") }}
6 | {{#*inline "function"}}{{> method this}}{{/inline}}
7 | {{#*inline "module"}}{{> method this}}{{/inline}}
8 |
--------------------------------------------------------------------------------
/documentation-src/partials/member.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{{description}}}
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/documentation-src/partials/method.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{name}}
6 | ({{{cleanParameters params}}}) ⇒ {{#each returns}}{{> types type}}{{else}}undefined{{/each}}
7 |
8 |
9 | {{#if chainable}}
10 |
chainable
11 | {{/if}}
12 | {{#each fires}}
13 |
{{this}}
14 | {{/each}}
15 |
16 |
17 |
18 | {{{description}}}
19 |
20 |
21 | {{#if params}}
22 |
23 | {{#each params as |v k|}}
24 |
25 |
{{name}}
26 |
{{> types type}}
27 |
28 |
29 | {{{description}}}
30 |
31 |
32 |
33 | {{/each}}
34 |
35 | {{/if}}
36 | {{#if chainable}}{{else}}{{#each returns}}
37 |
38 |
39 | {{> types type}}
40 |
41 |
42 | {{{description}}}
43 |
44 |
45 |
46 |
47 | {{else}}
48 |
This method does not return anything
49 | {{/each}}
50 | {{/if}}
51 | {{#if examples}}
52 |
53 | {{#each examples}}
54 |
55 | ```javascript
56 | {{{this}}}
57 | ```
58 |
59 | {{/each}}
60 |
61 | {{/if}}
62 |
63 |
64 |
--------------------------------------------------------------------------------
/documentation-src/partials/typedef.hbs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
{{name}}
4 | -
5 | {{#if properties}}
6 |
record-like object
7 | {{else}}
8 |
{{> types type}}
9 | {{/if}}
10 |
11 |
12 |
13 | {{{description}}}
14 |
15 |
16 | {{#if properties}}
17 |
18 | {{#each properties}}
19 |
20 | {{name}}
21 | {{> types type}}
22 |
23 |
24 | {{{description}}}
25 |
26 |
27 |
28 | {{/each}}
29 |
30 | {{/if}}
31 | {{#if params}}
32 |
33 | {{#each params as |v k|}}
34 |
35 |
{{name}}
36 |
{{> types type}}
37 |
38 |
39 | {{{description}}}
40 |
41 |
42 |
43 | {{/each}}
44 |
45 | {{/if}}
46 | {{#if returns}}
47 | {{#each returns}}
48 |
49 |
50 | {{> types type}}
51 |
52 |
53 | {{{description}}}
54 |
55 |
56 |
57 |
58 | {{/each}}
59 | {{/if}}
60 | {{#if examples}}
61 |
62 | {{#each examples}}
63 |
64 | ```javascript
65 | {{{this}}}
66 | ```
67 |
68 | {{/each}}
69 |
70 | {{/if}}
71 |
72 |
--------------------------------------------------------------------------------
/documentation-src/partials/types.hbs:
--------------------------------------------------------------------------------
1 | {{#each this.names}}{{#type}}{{this}}{{/type}}{{/each}}
2 |
--------------------------------------------------------------------------------
/documentation-src/plugins/handlebars-helpers.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var Handlebars = require('handlebars');
3 |
4 | module.exports = function (requires) {
5 | requires.handlebars = Handlebars;
6 |
7 | var arrayRegexp = /^Array\.<(.+?)>$/;
8 | var mapRegexp = /^Object\.$/;
9 | var unionRegexp = /([^|()]+)/gi;
10 | function formatGenerics(type) {
11 | var matchArray = arrayRegexp.exec(type);
12 | if (matchArray) return formatGenerics(matchArray[1]) + '[]';
13 | var matchMap = mapRegexp.exec(type);
14 | if (matchMap) return '{ string: ' + formatGenerics(matchMap[1]) + ' }';
15 | var union = [];
16 | var m = unionRegexp.exec(type);
17 | while (m) {
18 | union.push(m[1]);
19 | m = unionRegexp.exec(type);
20 | }
21 | if (union.length > 1)
22 | return '(' + union.map(formatGenerics).join('|') + ')';
23 | return type;
24 | }
25 | Handlebars.registerHelper('type', function (options) {
26 | return options.fn(formatGenerics(this));
27 | });
28 |
29 | Handlebars.registerHelper('event', function (options) {
30 | return options.fn(this).split(':')[1];
31 | });
32 |
33 | Handlebars.registerHelper('codepen', function (hash, height) {
34 | var h = typeof height === 'number' ? height : 790;
35 | var url =
36 | '//codepen.io/Algolia/embed/' +
37 | hash +
38 | '?height=' +
39 | h +
40 | '&theme-id=light&slug-hash=' +
41 | hash +
42 | '&default-tab=result&user=Algolia&embed-version=2';
43 | var codepenContent =
44 | '';
51 | var downloadLink =
52 | 'Download this example.';
55 | return new Handlebars.SafeString(downloadLink + codepenContent);
56 | });
57 |
58 | Handlebars.registerHelper('cleanParameters', function (parameters) {
59 | if (!parameters) return '';
60 | return new Handlebars.SafeString(
61 | parameters
62 | .map(function (p, k) {
63 | if (p.name.indexOf('.') !== -1) return '';
64 | if (p.optional)
65 | return `${p.name}`;
66 | return `${p.name}`;
67 | })
68 | .join('')
69 | );
70 | });
71 | };
72 |
--------------------------------------------------------------------------------
/documentation-src/plugins/headings.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { JSDOM } = require('jsdom');
4 |
5 | module.exports = function ({ selector = 'h2,h3' } = {}) {
6 | return function (files) {
7 | return Object.keys(files).forEach(function (file) {
8 | if (!file.endsWith('.html')) return;
9 | var data = files[file];
10 | var contents = data.contents.toString();
11 | var { window } = new JSDOM(contents);
12 | data.headings = [];
13 |
14 | window.document.querySelectorAll(selector).forEach(function (element) {
15 | data.headings.push({
16 | id: element.id,
17 | tag: element.tagName.toLowerCase(),
18 | text: element.textContent,
19 | });
20 | });
21 | });
22 | };
23 | };
24 |
--------------------------------------------------------------------------------
/documentation-src/plugins/jsdoc-data.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var jsdoc = require('jsdoc-to-markdown');
3 |
4 | /**
5 | * Same as lodash keyBy, turns an array of objects into an object keyed by the
6 | * value of the given key. When there are multiple objects with the same key,
7 | * the last one wins.
8 | */
9 | function keyBy(arr, key) {
10 | return arr.reduce(function (obj, o) {
11 | obj[o[key]] = o;
12 | return obj;
13 | }, {});
14 | }
15 |
16 | module.exports = function (opts) {
17 | if (!opts.src) throw new Error('opts.src must be defined');
18 | var namespace = opts.namespace;
19 |
20 | return function (_files, metalsmith) {
21 | var files = metalsmith.path(opts.src);
22 | return jsdoc.getTemplateData({ files: files }).then((data) => {
23 | var filteredData = data.filter(function (o) {
24 | return !o.deprecated;
25 | });
26 | var metadata = metalsmith.metadata();
27 | if (!namespace) metadata.jsdoc = keyBy(filteredData, 'longname');
28 | else {
29 | metadata.jsdoc = metadata.jsdoc || {};
30 | metadata.jsdoc[namespace] = keyBy(filteredData, 'name');
31 | // console.log(JSON.stringify(metadata.jsdoc, null, 2));
32 | }
33 | });
34 | };
35 | };
36 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_buttons.scss:
--------------------------------------------------------------------------------
1 | .btn {
2 | background: $accent-color-darkish;
3 | color: #fff;
4 | border: 1px solid $accent-color;
5 | height: 40px;
6 | max-width: 140px;
7 | line-height: 40px;
8 | padding: 0 1em;
9 | text-align: center;
10 | display: block;
11 | text-decoration: none;
12 | border-radius: 3px;
13 | text-transform: uppercase;
14 | font-weight: 600;
15 | font-size: 12px;
16 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
17 | transition: background 0.1s ease;
18 | cursor: pointer;
19 |
20 | &:hover,
21 | &:active {
22 | background: $accent-color;
23 | }
24 |
25 | &.btn-cta {
26 | max-width: 230px;
27 | margin: 32px auto;
28 | }
29 |
30 | &.btn-grey {
31 | background: $silver;
32 | border-color: $light-blue-grey;
33 | border-width: 2px;
34 | color: $grey-blue;
35 | box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1), 0 2px 4px 0 rgba(0, 0, 0, 0.1);
36 | }
37 |
38 | &.btn-black {
39 | background: $black;
40 | border-color: mix($black, #fff, 90%);
41 | }
42 |
43 | &-ghost {
44 | background: transparent;
45 | border-color: currentColor;
46 | font-weight: bold;
47 | max-width: inherit;
48 | padding: 0 32px;
49 |
50 | &-grey {
51 | color: $steel;
52 |
53 | &:hover {
54 | background: $steel;
55 | border-color: $steel;
56 | color: #fff;
57 |
58 | .ico-triangle {
59 | border-left-color: #fff;
60 | }
61 | }
62 | }
63 |
64 | &-pink {
65 | color: $accent-color;
66 |
67 | &:hover {
68 | background: $accent-color;
69 | border-color: $accent-color;
70 | color: #fff;
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_clipboard.scss:
--------------------------------------------------------------------------------
1 | .code {
2 | position: relative;
3 |
4 | .clipboard {
5 | position: absolute;
6 | top: 0;
7 | right: 0;
8 | opacity: 0;
9 | transition: opacity 150ms;
10 | }
11 |
12 | &:hover {
13 | .clipboard {
14 | opacity: 1;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_examples-intro.scss:
--------------------------------------------------------------------------------
1 | // icon - degree - colorStart - colorEnd
2 | $square-map: (
3 | (input, 135, #13c4a5, #10a4b8),
4 | (form, 138, #af84e3, #5071c7),
5 | (city, 314, #ec4918, #e25d8d),
6 | (country, 134, #fad961, #f76b1c),
7 | (map, 135, #81bf30, #00bdbd),
8 | (advanced, 135, #bfbfbf, #8a8a8a)
9 | );
10 |
11 | .examples-intro {
12 | margin-top: 4em;
13 | margin-bottom: 6em;
14 |
15 | float: left;
16 | width: 100%;
17 | display: none;
18 |
19 | @include small-mq {
20 | margin-bottom: 1.5em;
21 | }
22 |
23 | body.examples & {
24 | display: block;
25 | }
26 |
27 | .items-holder {
28 | margin: 2em auto 2em;
29 | display: block;
30 | max-width: 940px;
31 | padding: 0em;
32 | display: flex;
33 | flex-wrap: wrap;
34 | flex-direction: row;
35 |
36 | @include small-mq {
37 | align-items: center;
38 | margin-bottom: 0;
39 | }
40 |
41 | a {
42 | text-decoration: none;
43 | color: inherit;
44 | }
45 |
46 | .item {
47 | max-width: 120px;
48 | height: 120px;
49 | float: left;
50 | flex: 1 1 auto;
51 | margin: 0 22px;
52 | text-align: center;
53 |
54 | &:first-of-type {
55 | margin-left: 0;
56 | }
57 | &:last-of-type {
58 | margin-right: 0;
59 | }
60 |
61 | @include small-mq {
62 | margin: auto auto 58px;
63 | width: 50%;
64 |
65 | &:first-of-type {
66 | margin-left: auto;
67 | }
68 | &:last-of-type {
69 | margin-right: auto;
70 | }
71 | }
72 |
73 | span.square {
74 | display: block;
75 | position: relative;
76 | max-width: 120px;
77 | height: 120px;
78 | border-radius: 16px;
79 | box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
80 | transition: box-shadow 0.3s ease, transform 0.1s ease;
81 |
82 | @each $class, $degrees, $color-a, $color-b in $square-map {
83 | &.#{$class} {
84 | background: linear-gradient(
85 | #{$degrees}deg,
86 | #{$color-a} 0,
87 | #{$color-b} 100%
88 | );
89 | }
90 | }
91 |
92 | &:hover {
93 | box-shadow: none;
94 | transform: scale(1.05);
95 |
96 | & ~ .name {
97 | opacity: 1;
98 | }
99 | }
100 | }
101 |
102 | svg {
103 | position: absolute;
104 | top: 50%;
105 | left: 50%;
106 | transform: translate(-50%, -50%);
107 | }
108 |
109 | .name {
110 | font-family: 'Open Sans', Helvetica Neue, helvetica, sans-serif;
111 | opacity: 0.8;
112 | font-size: 16px;
113 | font-weight: 300;
114 | line-height: 52px;
115 | transition: opacity 0.3s ease;
116 | }
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_examples.scss:
--------------------------------------------------------------------------------
1 | .form-control {
2 | width: 100%;
3 | box-sizing: border-box;
4 | padding-left: 16px;
5 | line-height: 40px;
6 | height: 40px;
7 | border: 1px solid #cccccc;
8 | border-radius: 3px;
9 | outline: none;
10 | }
11 |
12 | .form-group {
13 | margin-bottom: 1em;
14 | clear: both;
15 |
16 | label {
17 | display: block;
18 | font-weight: bold;
19 | font-size: 0.8em;
20 | }
21 | }
22 |
23 | #map-example-container,
24 | #map-example-container-paris {
25 | // trigger zindex value otherwise
26 | // map goes hover other elements (like header)
27 | position: relative;
28 | z-index: 0;
29 | }
30 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_fonts.scss:
--------------------------------------------------------------------------------
1 | p a {
2 | color: #21a4d7;
3 | text-decoration: none;
4 | }
5 |
6 | /* heading settings
7 | =======================*/
8 | h1,
9 | h2,
10 | h3,
11 | h4 {
12 | padding: 0;
13 | margin: 0;
14 | }
15 |
16 | h1 {
17 | font-size: 46px;
18 | }
19 |
20 | h3 {
21 | font-size: 20px;
22 | }
23 |
24 | h3 {
25 | font-size: 18px;
26 | }
27 |
28 | /* Paragraphs
29 | ======================*/
30 | p {
31 | font-family: 'Open Sans', Helvetica Neue, helvetica, sans-serif;
32 | font-size: 20px;
33 | line-height: 32px;
34 | color: $charcoal-grey-75;
35 |
36 | @include small-mq {
37 | font-size: 16px;
38 | }
39 |
40 | & + ul,
41 | & + ol {
42 | font-size: 20px;
43 | line-height: 32px;
44 | color: $charcoal-grey-75;
45 | }
46 | }
47 |
48 | /* Big titles
49 | ======================*/
50 | h2.title {
51 | text-align: center;
52 | width: 100%;
53 | font-size: 1.8em;
54 | color: $charcoal-grey;
55 | display: block;
56 | position: relative;
57 | margin-top: 120px;
58 | margin-bottom: 80px;
59 |
60 | &:after {
61 | content: '';
62 | position: absolute;
63 | width: 50px;
64 | height: 3px;
65 | background: $accent-color;
66 | top: 2.8em;
67 | left: 0;
68 | right: 0;
69 | margin: auto;
70 | }
71 |
72 | ~ p {
73 | color: $charcoal-grey;
74 | font-size: 1.3em;
75 | text-align: center;
76 |
77 | @include small-mq {
78 | font-size: 16px;
79 | }
80 | }
81 |
82 | @include small-mq {
83 | margin-top: 60px;
84 | font-size: 22px;
85 | }
86 | }
87 |
88 | /* Small titles
89 | ======================*/
90 | h3.title {
91 | font-size: 1.5em;
92 | color: $greyish-brown;
93 | font-weight: bold;
94 | margin: 0;
95 | padding: 0;
96 | line-height: 1.2em;
97 |
98 | ~ p {
99 | margin: 32px 0;
100 | padding: 8px 0 0;
101 | }
102 | }
103 | h4 {
104 | font-size: 18px;
105 | }
106 |
107 | /* Anchors / links
108 | ====================*/
109 | .link {
110 | text-transform: uppercase;
111 | font-size: 16px;
112 | color: $accent-color;
113 | font-weight: 600;
114 | text-decoration: none;
115 | padding: 0 8px;
116 | }
117 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_home.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: $font-settings;
3 | }
4 |
5 | .container {
6 | width: 100%;
7 | height: 100%;
8 | margin: $navigation-height auto;
9 | }
10 |
11 | .welcome {
12 | padding: 2em 0;
13 | text-align: center;
14 | border: 1px solid rgba(black, 0.1);
15 | max-width: $max-container-width;
16 | margin: 6em auto 0;
17 | }
18 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_icons.scss:
--------------------------------------------------------------------------------
1 | .icon {
2 | text-indent: -99999px;
3 | color: transparent;
4 | transition: background 0.2s ease;
5 |
6 | &-love {
7 | background: url($icon-heart) no-repeat center center / contain;
8 | }
9 |
10 | &-love-dark {
11 | background: url($icon-heart-dark) no-repeat center center / contain;
12 | }
13 |
14 | &-mail {
15 | background: url($icon-mail) no-repeat 8px 7px / 70%;
16 | }
17 |
18 | &-algolia-small {
19 | background: url(../images/algolia-mark-white.svg) no-repeat center center /
20 | contain;
21 | }
22 | }
23 |
24 | // Small css shape
25 | .ico-triangle {
26 | width: 0;
27 | height: 0;
28 | border-top: 5px solid transparent;
29 | border-bottom: 5px solid transparent;
30 | border-left: 5px solid $steel;
31 | position: relative;
32 | display: inline-block;
33 | margin-left: 8px;
34 | }
35 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_inputs.scss:
--------------------------------------------------------------------------------
1 | input {
2 | outline: none;
3 | border-radius: 4px;
4 |
5 | @include appearance(none !important);
6 | &::-webkit-search-decoration,
7 | &::-webkit-search-cancel-button,
8 | &::-webkit-search-results-button,
9 | &::-webkit-search-results-decoration {
10 | display: none !important;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_media.scss:
--------------------------------------------------------------------------------
1 | .media-object {
2 | display: block;
3 | width: 100%;
4 | height: 100%;
5 | float: left;
6 | padding: 0;
7 | margin: 0;
8 |
9 | img {
10 | object: {
11 | fit: cover;
12 | position: center center;
13 | }
14 | display: block;
15 | padding: 4px;
16 | line-height: 1.42857143;
17 | background-color: #fff;
18 | border: 1px solid #ddd;
19 | border-radius: 4px;
20 | width: 100%;
21 | max-width: 400px;
22 |
23 | &.gif {
24 | display: block;
25 | max-width: 100%;
26 | height: auto;
27 | padding: 4px;
28 | line-height: 1.42857143;
29 | background-color: #fff;
30 | border: 1px solid #ddd;
31 | border-radius: 4px;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/components/_sidebar.scss:
--------------------------------------------------------------------------------
1 | nav.sidebar {
2 | float: left;
3 | width: 100%;
4 | height: 100%;
5 | position: absolute;
6 | max-width: $sidebar-width;
7 | border-right: 1px solid #d8d8d8;
8 | padding-top: 120px;
9 | overflow: auto;
10 |
11 | ul {
12 | list-style: none;
13 | width: 100%;
14 | max-width: $sidebar-width;
15 | padding: 0;
16 | margin: 0;
17 | float: left;
18 |
19 | &.fixed {
20 | position: fixed;
21 | top: $navigation-height;
22 | z-index: 9;
23 | max-height: calc(100vh - #{$navigation-height});
24 | overflow: auto;
25 | }
26 |
27 | li {
28 | width: 100%;
29 | line-height: 32px;
30 |
31 | &.level-h2 {
32 | }
33 | &.level-h3 {
34 | line-height: 24px;
35 | font-size: 12px;
36 | padding-left: 12px;
37 | font-family: 'Open sans';
38 | }
39 |
40 | a {
41 | text-decoration: none;
42 | display: block;
43 | width: 100%;
44 | color: $charcoal-grey-75;
45 | font-weight: 400;
46 |
47 | &:focus,
48 | &:target {
49 | @extend %active-links;
50 | }
51 | &.active {
52 | @extend %active-links;
53 | }
54 | }
55 | }
56 | }
57 |
58 | @include small-mq {
59 | width: calc(100% + 16px);
60 | max-width: calc(100% + 16px);
61 | position: absolute;
62 | max-height: 46px;
63 | left: 0;
64 | top: 16px;
65 | border: none;
66 | padding-top: 0;
67 | display: none;
68 |
69 | select {
70 | width: calc(100% - 32px);
71 | margin: 8px 8px;
72 | visibility: hidden;
73 | }
74 |
75 | &.fixed {
76 | background: $brand-primary;
77 | color: #fff;
78 | top: 50px;
79 | display: block;
80 |
81 | select {
82 | visibility: visible;
83 | }
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/index.scss:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | @import 'vendors/normalize', 'vendors/variables', 'vendors/mixins',
4 | 'vendors/base', 'vendors/helpers', 'vendors/animations',
5 | 'vendors/communityHeader';
6 |
7 | @import 'components/footer', 'components/home', 'components/code-highlight',
8 | 'components/icons', 'components/containers', 'components/buttons',
9 | 'components/media', 'components/inputs', 'components/fonts',
10 | 'components/sidebar', 'components/documentation', 'components/examples-intro',
11 | 'components/examples', 'components/footer', 'components/visual-helper',
12 | 'components/clipboard';
13 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/vendors/_animations.scss:
--------------------------------------------------------------------------------
1 | // Hero Illustration
2 | $timingFunction: 3s ease infinite;
3 |
4 | @mixin anim($name, $p1, $p2, $p3) {
5 | @keyframes #{$name} {
6 | 0%,
7 | 20%,
8 | 80%,
9 | 100% {
10 | transform: #{$p1};
11 | }
12 | 10%,
13 | 40%,
14 | 50% {
15 | transform: #{$p2};
16 | }
17 | 60% {
18 | transform: #{$p3};
19 | }
20 | }
21 | }
22 | @mixin animEllipse($name, $p1, $p2, $p3) {
23 | @keyframes #{$name} {
24 | 0%,
25 | 20%,
26 | 80%,
27 | 100% {
28 | transform: #{$p1};
29 | }
30 | 10%,
31 | 40%,
32 | 50% {
33 | transform: #{$p2};
34 | opacity: 0.6;
35 | }
36 | 60% {
37 | transform: #{$p3};
38 | opacity: 0.6;
39 | }
40 | }
41 | }
42 |
43 | #pin {
44 | animation: bounce $timingFunction;
45 | }
46 | ellipse {
47 | transform-origin: center center;
48 | -moz-transform-origin: 50% 40%;
49 | animation: bounceShadow $timingFunction;
50 | -moz-animation: mozBounceShadow $timingFunction;
51 | }
52 | // Fix svg in FF
53 | #plan-holder {
54 | -moz-transform: translateY(10px);
55 | }
56 | #plan {
57 | -moz-transform: scale(1.1);
58 | }
59 |
60 | @include anim(
61 | 'bounce',
62 | 'translateY(0)',
63 | 'translateY(-5px)',
64 | 'translateY(-5px)'
65 | );
66 | @include animEllipse(
67 | 'bounceShadow',
68 | 'scale(1) translateY(12px)',
69 | 'scale(0.75) translateY(12px) ',
70 | 'scale(0.75) translateY(12px) '
71 | );
72 | @include animEllipse(
73 | 'mozBounceShadow',
74 | 'scale(1) translateY(16px)',
75 | 'scale(0.75) translateY(16px) translateX(-8px) ',
76 | 'scale(0.75) translateY(16px) translateX(-8px) '
77 | );
78 |
79 | // Footer heartbeat
80 | @keyframes pulse {
81 | 0% {
82 | box-shadow: 0 0 0 0 rgba($red-pink, 0.4);
83 | }
84 | 70% {
85 | box-shadow: 0 0 0 30px rgba($red-pink, 0);
86 | }
87 | 100% {
88 | box-shadow: 0 0 0 0 rgba($red-pink, 0);
89 | }
90 | }
91 |
92 | @keyframes pulseHeart {
93 | 0% {
94 | transform: scale(1.3);
95 | }
96 | 70% {
97 | transform: scale(1.15);
98 | }
99 | 100% {
100 | transform: scale(1);
101 | }
102 | }
103 |
104 | .icon-love-dark {
105 | display: block;
106 | position: relative;
107 |
108 | &:before {
109 | content: '';
110 | display: block;
111 | width: 8px;
112 | height: 8px;
113 | position: absolute;
114 | top: 45%;
115 | bottom: 0;
116 | left: 50%;
117 | transform: translate(-50%, -50%);
118 | right: 0;
119 | z-index: -1;
120 | border-radius: 100%;
121 | }
122 | }
123 |
124 | .inner-bloc:hover .icon-love-dark {
125 | animation: pulseHeart 1s ease infinite;
126 |
127 | &:before {
128 | animation: pulse 1s ease infinite !important;
129 | }
130 | }
131 |
132 | // part of animate.css
133 | @keyframes fadeInDown {
134 | 0% {
135 | opacity: 0;
136 | transform: translate3d(0, -100%, 0);
137 | }
138 |
139 | 100% {
140 | opacity: 1;
141 | transform: none;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/vendors/_base.scss:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Montserrat:500,600|Open+Sans);
2 |
3 | * {
4 | box-sizing: border-box;
5 | -webkit-font-smoothing: antialiased;
6 | -moz-osx-font-smoothing: grayscale;
7 | }
8 |
9 | h1,
10 | h2,
11 | h3,
12 | h4,
13 | h5,
14 | h6 {
15 | font-family: 'Montserrat', Helvetica Neue, helvetica, sans-serif;
16 | }
17 |
18 | :root {
19 | font-family: 'Open Sans', Helvetica Neue, helvetica, sans-serif;
20 | }
21 |
22 | hr {
23 | margin: 0;
24 | }
25 |
26 | figure {
27 | figcaption {
28 | text-indent: -9999px;
29 | color: transparent;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/vendors/_helpers.scss:
--------------------------------------------------------------------------------
1 | $sizes: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
2 |
3 | [class*='bloc-'] {
4 | float: left;
5 | }
6 | @each $size in $sizes {
7 | .bloc-#{$size} {
8 | $size: $size * 10%;
9 | width: $size;
10 | }
11 | }
12 |
13 | .relative {
14 | position: relative;
15 | overflow: hidden;
16 | }
17 |
18 | .center-text {
19 | text-align: center;
20 | }
21 |
22 | .fl-left {
23 | float: left;
24 | }
25 |
26 | .fl-right {
27 | float: right;
28 | }
29 |
30 | hr {
31 | border: none;
32 | float: left;
33 | clear: both;
34 | &:before,
35 | &:after {
36 | content: '';
37 | display: table;
38 | clear: both;
39 | }
40 |
41 | width: 100%;
42 | height: 1px;
43 | background: #e5e5e5;
44 | }
45 |
46 | .pipe {
47 | width: 2px;
48 | height: 20px;
49 | background: $accent-color;
50 | display: inline-block;
51 | float: left;
52 | margin: 20px 16px 0;
53 | line-height: $navigation-height;
54 |
55 | & + span {
56 | font-weight: bold;
57 | width: 0;
58 | float: left;
59 | }
60 |
61 | body.index & {
62 | display: none;
63 |
64 | & + span {
65 | display: none !important;
66 | }
67 | }
68 | }
69 |
70 | // The following helper classes
71 | // made responsive desing easy
72 | // - no-desktop : Only display on mobile
73 | // - no-mobile : Only display on desktop
74 | // - display-on-small : only display on smallish screen ( no mobile )
75 |
76 | .no-desktop {
77 | @include hide();
78 | @include small-mq {
79 | @include hide();
80 | }
81 |
82 | @include mobile-mq {
83 | @include unhide(block);
84 | }
85 |
86 | &.community-badge {
87 | @include mobile-mq {
88 | @include unhide(inline);
89 | }
90 | }
91 |
92 | @media screen and (orientation: landscape) {
93 | @include hide();
94 | }
95 | }
96 |
97 | .no-mobile {
98 | @include unhide(block);
99 |
100 | &.nav-icon {
101 | @include unhide(inline);
102 |
103 | @include small-mq {
104 | @include hide();
105 | }
106 | }
107 |
108 | @include small-mq {
109 | @include hide();
110 | }
111 | }
112 |
113 | .display-on-small {
114 | @include hide();
115 |
116 | @media (max-width: 960px) {
117 | display: inline-block !important;
118 | visibility: visible;
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/documentation-src/stylesheets/vendors/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | @mixin placeholder {
3 | $placeholders: ':-webkit-input' ':-moz' '-moz' '-ms-input';
4 | @each $placeholder in $placeholders {
5 | &:#{$placeholder}-placeholder {
6 | @content;
7 | }
8 | }
9 | }
10 | @mixin better-fonts() {
11 | h1,
12 | h2,
13 | h3,
14 | h4,
15 | h5,
16 | h6,
17 | span,
18 | div,
19 | p,
20 | pre,
21 | code,
22 | a,
23 | strong,
24 | em,
25 | i {
26 | -webkit-font-smoothing: antialiased;
27 | -moz-osx-font-smoothing: grayscale;
28 | }
29 | }
30 |
31 | @mixin footer-text {
32 | color: #496f92;
33 | text-transform: uppercase;
34 | font-weight: bold;
35 | font-size: 12px;
36 | margin: 0;
37 | font-family: 'Open Sans', Helvetica Neue, helvetica, sans-serif;
38 | font-weight: 800;
39 | float: none;
40 | }
41 |
42 | @mixin hide() {
43 | display: none !important;
44 | visibility: hidden;
45 | }
46 |
47 | @mixin unhide($type) {
48 | display: $type !important;
49 | visibility: visible;
50 | }
51 | @mixin appearance($value) {
52 | -webkit-appearance: $value;
53 | -moz-appearance: $value;
54 | appearance: $value;
55 | }
56 |
57 | // Responsive Breakpoints
58 | @mixin big-min-mq {
59 | @media (min-width: $bp-big) {
60 | @content;
61 | }
62 | }
63 | @mixin huge-min-mq {
64 | @media (min-width: $bp-huge) {
65 | @content;
66 | }
67 | }
68 |
69 | @mixin big-mq {
70 | @media (max-width: $bp-big) {
71 | @content;
72 | }
73 | }
74 | @mixin medium-mq {
75 | @media (max-width: $bp-medium) {
76 | @content;
77 | }
78 | }
79 | @mixin small-mq {
80 | @media (max-width: $bp-medium) {
81 | @content;
82 | }
83 | }
84 | @mixin mobile-mq {
85 | @media (max-width: $bp-small) {
86 | @content;
87 | }
88 | }
89 | @mixin tablet-mq-portrait {
90 | @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) {
91 | @content;
92 | }
93 | }
94 | @mixin tablet-mq-landscape {
95 | @media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) {
96 | @content;
97 | }
98 | }
99 |
100 | // Placeholders
101 |
102 | %fadeInDown {
103 | animation-name: fadeInDown;
104 | }
105 |
106 | %animated {
107 | -webkit-animation-duration: 0.3s;
108 | animation-duration: 0.3s;
109 | -webkit-animation-fill-mode: both;
110 | animation-fill-mode: both;
111 | }
112 |
113 | %active-links {
114 | color: $accent-color;
115 | box-shadow: inset -2px 0 0 0 $accent-color;
116 |
117 | @include small-mq {
118 | font-weight: bold;
119 | box-shadow: none;
120 | color: #fff;
121 | border-bottom: 2px solid $accent-color;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/examples/readme.md:
--------------------------------------------------------------------------------
1 | The examples moved to [codepen](http://codepen.io/collection/nwWJbe/).
2 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
Getting started with the examples
21 |
33 |
Play with the examples locally
34 |
35 | To get you started with the helper examples on your machine, follow
36 | these steps:
37 |
38 |
39 | -
40 | Checkout the project with
41 | git clone
43 | https://github.com/algolia/algoliasearch-helper-js.git
45 |
46 | - In your command line, do npm install
47 | -
48 | Launch the examples with
49 | npm run examples (it will open the browser
50 | for you and show this page)
51 |
52 |
53 |
API documentation
54 |
JSDoc
55 |
More informations api Algolia API
56 |
57 | All informations related to Algolia can be found on
58 | the web documentation
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var AlgoliaSearchHelper = require('./src/algoliasearch.helper');
4 |
5 | var SearchParameters = require('./src/SearchParameters');
6 | var SearchResults = require('./src/SearchResults');
7 |
8 | /**
9 | * The algoliasearchHelper module is the function that will let its
10 | * contains everything needed to use the Algoliasearch
11 | * Helper. It is a also a function that instanciate the helper.
12 | * To use the helper, you also need the Algolia JS client v3.
13 | * @example
14 | * //using the UMD build
15 | * var client = algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76');
16 | * var helper = algoliasearchHelper(client, 'bestbuy', {
17 | * facets: ['shipping'],
18 | * disjunctiveFacets: ['category']
19 | * });
20 | * helper.on('result', function(event) {
21 | * console.log(event.results);
22 | * });
23 | * helper
24 | * .toggleFacetRefinement('category', 'Movies & TV Shows')
25 | * .toggleFacetRefinement('shipping', 'Free shipping')
26 | * .search();
27 | * @example
28 | * // The helper is an event emitter using the node API
29 | * helper.on('result', updateTheResults);
30 | * helper.once('result', updateTheResults);
31 | * helper.removeListener('result', updateTheResults);
32 | * helper.removeAllListeners('result');
33 | * @module algoliasearchHelper
34 | * @param {AlgoliaSearch} client an AlgoliaSearch client
35 | * @param {string} index the name of the index to query
36 | * @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.
37 | * @return {AlgoliaSearchHelper} The helper instance
38 | */
39 | function algoliasearchHelper(client, index, opts) {
40 | return new AlgoliaSearchHelper(client, index, opts);
41 | }
42 |
43 | /**
44 | * The version currently used
45 | * @member module:algoliasearchHelper.version
46 | * @type {number}
47 | */
48 | algoliasearchHelper.version = require('./src/version');
49 |
50 | /**
51 | * Constructor for the Helper.
52 | * @member module:algoliasearchHelper.AlgoliaSearchHelper
53 | * @type {AlgoliaSearchHelper}
54 | */
55 | algoliasearchHelper.AlgoliaSearchHelper = AlgoliaSearchHelper;
56 |
57 | /**
58 | * Constructor for the object containing all the parameters of the search.
59 | * @member module:algoliasearchHelper.SearchParameters
60 | * @type {SearchParameters}
61 | */
62 | algoliasearchHelper.SearchParameters = SearchParameters;
63 |
64 | /**
65 | * Constructor for the object containing the results of the search.
66 | * @member module:algoliasearchHelper.SearchResults
67 | * @type {SearchResults}
68 | */
69 | algoliasearchHelper.SearchResults = SearchResults;
70 |
71 | module.exports = algoliasearchHelper;
72 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | testEnvironment: 'node',
5 | testMatch: ['/test/spec/**/*.[jt]s?(x)'],
6 | watchPlugins: [
7 | 'jest-watch-typeahead/filename',
8 | 'jest-watch-typeahead/testname',
9 | ],
10 | };
11 |
--------------------------------------------------------------------------------
/jest.setup.js:
--------------------------------------------------------------------------------
1 | /* eslint-env jest */
2 |
3 | 'use strict';
4 |
5 | jest.setTimeout(20000);
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "algoliasearch-helper",
3 | "version": "3.13.3",
4 | "description": "Helper for implementing advanced search features with algolia",
5 | "main": "index.js",
6 | "types": "index.d.ts",
7 | "homepage": "https://community.algolia.com/algoliasearch-helper-js/",
8 | "scripts": {
9 | "build": "./scripts/build.sh",
10 | "lint": "eslint .",
11 | "doc": "node documentation-src/metalsmith.js",
12 | "doc:publish": "yarn run doc && gh-pages -d documentation",
13 | "doc:staging": "scripts/staging-doc.sh",
14 | "readme:toc": "doctoc --notitle README.md --maxlevel 3",
15 | "test": "scripts/retry.sh 3 'scripts/test.sh'",
16 | "test:unit": "jest",
17 | "test:watch": "jest --watch",
18 | "release": "./scripts/release.js",
19 | "changelog:view-last": "conventional-changelog -u -n scripts/conventional-changelog/",
20 | "changelog:update": "conventional-changelog -i CHANGELOG -s -u -n scripts/conventional-changelog/",
21 | "prepare": "patch-package"
22 | },
23 | "author": {
24 | "name": "Algolia Inc.",
25 | "url": "https://www.algolia.com"
26 | },
27 | "license": "MIT",
28 | "repository": {
29 | "type": "git",
30 | "url": "https://github.com/algolia/algoliasearch-helper-js.git"
31 | },
32 | "files": [
33 | "dist",
34 | "src",
35 | "index.js",
36 | "index.d.ts",
37 | "types/algoliasearch.d.ts",
38 | "types/algoliasearch.js"
39 | ],
40 | "devDependencies": {
41 | "@types/algoliasearch": "3.34.11",
42 | "algoliasearch": "4.8.3",
43 | "doctoc": "1.3.0",
44 | "patch-package": "6.2.2",
45 | "eslint": "6.8.0",
46 | "eslint-config-algolia": "16.0.0",
47 | "eslint-config-prettier": "6.15.0",
48 | "eslint-import-resolver-typescript": "2.5.0",
49 | "eslint-plugin-deprecation": "1.3.2",
50 | "eslint-plugin-eslint-comments": "3.2.0",
51 | "eslint-plugin-import": "2.24.2",
52 | "eslint-plugin-jasmine": "4.1.0",
53 | "eslint-plugin-jest": "27.0.4",
54 | "eslint-plugin-prettier": "3.4.0",
55 | "eslint-plugin-react": "7.26.0",
56 | "eslint-plugin-react-hooks": "4.3.0",
57 | "eslint-plugin-vue": "9.8.0",
58 | "eslint-plugin-wdio": "5.11.0",
59 | "@typescript-eslint/eslint-plugin": "5.38.1",
60 | "@typescript-eslint/parser": "4.31.2",
61 | "prettier": "2.4.1",
62 | "gh-pages": "1.0.0",
63 | "jest": "24.7.1",
64 | "jest-watch-typeahead": "0.3.0",
65 | "browserify": "14.5.0",
66 | "exorcist": "1.0.1",
67 | "uglify-js": "2.8.29",
68 | "colors": "1.1.2",
69 | "conventional-changelog-cli": "1.3.2",
70 | "pretty-bytes-cli": "2.0.0",
71 | "prompt": "1.0.0",
72 | "semver": "5.3.0",
73 | "shelljs": "0.7.8",
74 | "mversion": "1.13.0",
75 | "yargs": "13.2.4",
76 | "jsdoc-to-markdown": "8.0.0",
77 | "handlebars": "4.1.0",
78 | "metalsmith": "2.5.1",
79 | "metalsmith-in-place": "1.4.4",
80 | "metalsmith-layouts": "1.8.1",
81 | "metalsmith-markdown": "1.3.0",
82 | "metalsmith-metallic": "1.0.0",
83 | "@metalsmith/sass": "1.4.0",
84 | "pug": "2.0.3",
85 | "typescript": "5.1.3"
86 | },
87 | "dependencies": {
88 | "@algolia/events": "^4.0.1"
89 | },
90 | "peerDependencies": {
91 | "algoliasearch": ">= 3.1 < 6"
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/patches/metalsmith-in-place+1.4.4.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/metalsmith-in-place/lib/index.js b/node_modules/metalsmith-in-place/lib/index.js
2 | index 4c0092a..9924129 100644
3 | --- a/node_modules/metalsmith-in-place/lib/index.js
4 | +++ b/node_modules/metalsmith-in-place/lib/index.js
5 | @@ -24,7 +24,9 @@ module.exports = plugin;
6 | *
7 | * Options supported by metalsmith-in-place
8 | */
9 | -var settings = ['engine', 'partials', 'pattern', 'rename'];
10 | +// we need access to handlebars helpers (codepen etc.), so we use exposeConsolidate
11 | +// to add plugins/handlebars-helpers.js
12 | +var settings = ['engine', 'partials', 'pattern', 'rename', 'exposeConsolidate'];
13 |
14 | /**
15 | * Metalsmith plugin for in-place templating.
16 | @@ -57,6 +59,10 @@ function plugin(opts){
17 | throw new Error('Unknown template engine: "' + opts.engine + '"');
18 | }
19 |
20 | + if (typeof opts.exposeConsolidate === 'function') {
21 | + opts.exposeConsolidate(consolidate.requires);
22 | + }
23 | +
24 | // Map options to local variables
25 | var engine = opts.engine;
26 | var partials = opts.partials;
27 |
--------------------------------------------------------------------------------
/scripts/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | [ -z $CIRCLE_BUILD_NUM ] && CI='false' || CI='true'
6 |
7 | if [ $CI == 'true' ]; then
8 | set -x # debug messages
9 | fi
10 |
11 | bundle='algoliasearch.helper'
12 |
13 | echo "Build"
14 |
15 | mkdir -p dist
16 |
17 | browserify index.js \
18 | --standalone algoliasearchHelper \
19 | --debug | \
20 | exorcist dist/algoliasearch.helper.js.map > dist/algoliasearch.helper.js
21 |
22 | echo "..Minify"
23 |
24 | uglifyjs dist/algoliasearch.helper.js \
25 | --mangle \
26 | --compress=warnings=false \
27 | --in-source-map "dist/algoliasearch.helper.js.map" \
28 | --source-map "dist/algoliasearch.helper.min.js.map" \
29 | --output dist/algoliasearch.helper.min.js
30 |
31 | echo '..Gzipped file size'
32 |
33 | echo "${bundle}.min.js gzipped will weigh" $(cat dist/"${bundle}".min.js | gzip -9 | wc -c | pretty-bytes)
34 |
--------------------------------------------------------------------------------
/scripts/conventional-changelog/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var parserOpts = {
3 | // eslint-disable-next-line no-useless-escape
4 | headerPattern: /^(\w*)(?:\((.*)\))?\: (.*)$/,
5 | headerCorrespondence: ['type', 'scope', 'subject'],
6 | noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES'],
7 | revertPattern: /^revert:\s([\s\S]*?)\s*This reverts commit (\w*)\./,
8 | revertCorrespondence: ['header', 'hash'],
9 | };
10 |
11 | var writerOpts = {
12 | transform: function (commit) {
13 | return commit;
14 | },
15 | groupBy: 'type',
16 | commitGroupsSort: 'title',
17 | commitsSort: ['scope', 'subject'],
18 | noteGroupsSort: 'title',
19 | headerPartial: '{{version}} - {{date}}',
20 | mainTemplate: `{{> header}}
21 |
22 | {{#each commitGroups}}
23 | {{#each commits}}
24 | {{> commit root=@root}}
25 | {{/each}}
26 | {{/each}}
27 |
28 | {{> footer}}
29 | `,
30 | commitPartial: ` * {{header}}
31 |
32 | {{~!-- commit link --}} {{#if @root.linkReferences~}}
33 | {{~#if @root.repository}}
34 | {{~#if @root.host}}
35 | {{~@root.host}}/
36 | {{~/if}}
37 | {{~#if @root.owner}}
38 | {{~@root.owner}}/
39 | {{~/if}}
40 | {{~@root.repository}}
41 | {{~else}}
42 | {{~@root.repoUrl}}
43 | {{~/if}}/
44 | {{~@root.commit}}/{{hash}}
45 | {{~else}}
46 | {{~hash}}
47 | {{~/if}}
48 |
49 | {{~!-- commit references --}}
50 | {{~#if references~}}
51 | , closes
52 | {{~#each references}} {{#if @root.linkReferences~}}
53 | {{~#if @root.repository}}
54 | {{~#if @root.host}}
55 | {{~@root.host}}/
56 | {{~/if}}
57 | {{~#if this.repository}}
58 | {{~#if this.owner}}
59 | {{~this.owner}}/
60 | {{~/if}}
61 | {{~this.repository}}
62 | {{~else}}
63 | {{~#if @root.owner}}
64 | {{~@root.owner}}/
65 | {{~/if}}
66 | {{~@root.repository}}
67 | {{~/if}}
68 | {{~else}}
69 | {{~@root.repoUrl}}
70 | {{~/if}}/
71 | {{~@root.issue}}/{{this.issue}}
72 | {{~else}}
73 | {{~#if this.owner}}
74 | {{~this.owner}}/
75 | {{~/if}}
76 | {{~this.repository}}#{{this.issue}}
77 | {{~/if}}{{/each}}
78 | {{~/if}}
79 |
80 | `,
81 | };
82 |
83 | /*
84 | writerOpts.mainTemplate = template;
85 | writerOpts.headerPartial = header;
86 | writerOpts.commitPartial = commit;
87 | writerOpts.footerPartial = footer;
88 | */
89 |
90 | module.exports = {
91 | parserOpts: parserOpts,
92 | writerOpts: writerOpts,
93 | };
94 |
--------------------------------------------------------------------------------
/scripts/lib/conventionalChangelog.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | showChangelog,
5 | updateChangelog,
6 | getChangelog,
7 | };
8 |
9 | const colors = require('colors/safe');
10 |
11 | const baseConvChangelog =
12 | 'conventional-changelog --config scripts/conventional-changelog/';
13 |
14 | function showChangelog(shell) {
15 | shell.echo(colors.yellow.underline('\nNext version changelog:'));
16 | const changelog = shell.exec(`${baseConvChangelog} -u`, {
17 | silent: true,
18 | }).stdout;
19 | shell.echo(colors.white(changelog));
20 | }
21 |
22 | function updateChangelog(shell) {
23 | shell.echo(colors.yellow('⚠️ Updating changelog'));
24 | shell.exec(`${baseConvChangelog} --infile CHANGELOG --same-file`, {
25 | silent: true,
26 | });
27 | }
28 |
29 | function getChangelog(shell) {
30 | const changelog = shell
31 | .exec(`${baseConvChangelog} -u`, { silent: true })
32 | .trim()
33 | .split('\n');
34 | changelog.splice(1, 0, '');
35 | return changelog;
36 | }
37 |
--------------------------------------------------------------------------------
/scripts/retry.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Retry a command up to a specific number of times until it exits successfully
3 | # Usage: scripts/retry.sh
4 |
5 | retries="$1"
6 | command="$2"
7 |
8 | echo trying "$command", $retries retries left
9 |
10 | # Run the command, and save the exit code
11 | ($command)
12 | exit_code=$?
13 |
14 | # If the exit code is non-zero (i.e. command failed), and we have not
15 | # reached the maximum number of retries, run the command again
16 | if [[ $exit_code -ne 0 && $retries -gt 0 ]]; then
17 | scripts/retry.sh $(($retries - 1)) "$command"
18 | else
19 | # Return the exit code from the command
20 | exit $exit_code
21 | fi
22 |
23 |
--------------------------------------------------------------------------------
/scripts/staging-doc.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -ev # exit when error
4 |
5 | yarn
6 | yarn run doc
7 | surge documentation
8 |
--------------------------------------------------------------------------------
/scripts/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e # exit when error
4 |
5 | [ -z $CIRCLE_BUILD_NUM ] && CI='false' || CI='true'
6 |
7 | if [ $CI == 'true' ]; then
8 | set -x # debug messages
9 | fi
10 |
11 | node test/run.js
12 |
--------------------------------------------------------------------------------
/src/DerivedHelper/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var EventEmitter = require('@algolia/events');
4 | var inherits = require('../functions/inherits');
5 |
6 | /**
7 | * A DerivedHelper is a way to create sub requests to
8 | * Algolia from a main helper.
9 | * @class
10 | * @classdesc The DerivedHelper provides an event based interface for search callbacks:
11 | * - search: when a search is triggered using the `search()` method.
12 | * - result: when the response is retrieved from Algolia and is processed.
13 | * This event contains a {@link SearchResults} object and the
14 | * {@link SearchParameters} corresponding to this answer.
15 | * @param {AlgoliaSearchHelper} mainHelper the main helper
16 | * @param {function} fn the function to create the derived state
17 | */
18 | function DerivedHelper(mainHelper, fn) {
19 | this.main = mainHelper;
20 | this.fn = fn;
21 | this.lastResults = null;
22 | }
23 |
24 | inherits(DerivedHelper, EventEmitter);
25 |
26 | /**
27 | * Detach this helper from the main helper
28 | * @return {undefined}
29 | * @throws Error if the derived helper is already detached
30 | */
31 | DerivedHelper.prototype.detach = function () {
32 | this.removeAllListeners();
33 | this.main.detachDerivedHelper(this);
34 | };
35 |
36 | DerivedHelper.prototype.getModifiedState = function (parameters) {
37 | return this.fn(parameters);
38 | };
39 |
40 | module.exports = DerivedHelper;
41 |
--------------------------------------------------------------------------------
/src/functions/compact.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function compact(array) {
4 | if (!Array.isArray(array)) {
5 | return [];
6 | }
7 |
8 | return array.filter(Boolean);
9 | };
10 |
--------------------------------------------------------------------------------
/src/functions/defaultsPure.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // NOTE: this behaves like lodash/defaults, but doesn't mutate the target
4 | // it also preserve keys order
5 | module.exports = function defaultsPure() {
6 | var sources = Array.prototype.slice.call(arguments);
7 |
8 | return sources.reduceRight(function (acc, source) {
9 | Object.keys(Object(source)).forEach(function (key) {
10 | if (source[key] === undefined) {
11 | return;
12 | }
13 | if (acc[key] !== undefined) {
14 | // remove if already added, so that we can add it in correct order
15 | // eslint-disable-next-line no-param-reassign
16 | delete acc[key];
17 | }
18 | // eslint-disable-next-line no-param-reassign
19 | acc[key] = source[key];
20 | });
21 | return acc;
22 | }, {});
23 | };
24 |
--------------------------------------------------------------------------------
/src/functions/escapeFacetValue.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Replaces a leading - with \-
5 | * @private
6 | * @param {any} value the facet value to replace
7 | * @returns {any} the escaped facet value or the value if it was not a string
8 | */
9 | function escapeFacetValue(value) {
10 | if (typeof value !== 'string') return value;
11 |
12 | return String(value).replace(/^-/, '\\-');
13 | }
14 |
15 | /**
16 | * Replaces a leading \- with -
17 | * @private
18 | * @param {any} value the escaped facet value
19 | * @returns {any} the unescaped facet value or the value if it was not a string
20 | */
21 | function unescapeFacetValue(value) {
22 | if (typeof value !== 'string') return value;
23 |
24 | return value.replace(/^\\-/, '-');
25 | }
26 |
27 | module.exports = {
28 | escapeFacetValue: escapeFacetValue,
29 | unescapeFacetValue: unescapeFacetValue,
30 | };
31 |
--------------------------------------------------------------------------------
/src/functions/find.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // @MAJOR can be replaced by native Array#find when we change support
4 | module.exports = function find(array, comparator) {
5 | if (!Array.isArray(array)) {
6 | return undefined;
7 | }
8 |
9 | for (var i = 0; i < array.length; i++) {
10 | if (comparator(array[i])) {
11 | return array[i];
12 | }
13 | }
14 |
15 | return undefined;
16 | };
17 |
--------------------------------------------------------------------------------
/src/functions/findIndex.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // @MAJOR can be replaced by native Array#findIndex when we change support
4 | module.exports = function find(array, comparator) {
5 | if (!Array.isArray(array)) {
6 | return -1;
7 | }
8 |
9 | for (var i = 0; i < array.length; i++) {
10 | if (comparator(array[i])) {
11 | return i;
12 | }
13 | }
14 | return -1;
15 | };
16 |
--------------------------------------------------------------------------------
/src/functions/formatSort.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var find = require('./find');
4 |
5 | /**
6 | * Transform sort format from user friendly notation to lodash format
7 | * @param {string[]} sortBy array of predicate of the form "attribute:order"
8 | * @param {string[]} [defaults] array of predicate of the form "attribute:order"
9 | * @return {array.} array containing 2 elements : attributes, orders
10 | */
11 | module.exports = function formatSort(sortBy, defaults) {
12 | var defaultInstructions = (defaults || []).map(function (sort) {
13 | return sort.split(':');
14 | });
15 |
16 | return sortBy.reduce(
17 | function preparePredicate(out, sort) {
18 | var sortInstruction = sort.split(':');
19 |
20 | var matchingDefault = find(
21 | defaultInstructions,
22 | function (defaultInstruction) {
23 | return defaultInstruction[0] === sortInstruction[0];
24 | }
25 | );
26 |
27 | if (sortInstruction.length > 1 || !matchingDefault) {
28 | out[0].push(sortInstruction[0]);
29 | out[1].push(sortInstruction[1]);
30 | return out;
31 | }
32 |
33 | out[0].push(matchingDefault[0]);
34 | out[1].push(matchingDefault[1]);
35 | return out;
36 | },
37 | [[], []]
38 | );
39 | };
40 |
--------------------------------------------------------------------------------
/src/functions/inherits.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function inherits(ctor, superCtor) {
4 | // eslint-disable-next-line no-param-reassign
5 | ctor.prototype = Object.create(superCtor.prototype, {
6 | constructor: {
7 | value: ctor,
8 | enumerable: false,
9 | writable: true,
10 | configurable: true,
11 | },
12 | });
13 | }
14 |
15 | module.exports = inherits;
16 |
--------------------------------------------------------------------------------
/src/functions/intersection.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function intersection(arr1, arr2) {
4 | return arr1.filter(function (value, index) {
5 | return (
6 | arr2.indexOf(value) > -1 &&
7 | arr1.indexOf(value) === index /* skips duplicates */
8 | );
9 | });
10 | }
11 |
12 | module.exports = intersection;
13 |
--------------------------------------------------------------------------------
/src/functions/merge.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function clone(value) {
4 | if (typeof value === 'object' && value !== null) {
5 | return _merge(Array.isArray(value) ? [] : {}, value);
6 | }
7 | return value;
8 | }
9 |
10 | function isObjectOrArrayOrFunction(value) {
11 | return (
12 | typeof value === 'function' ||
13 | Array.isArray(value) ||
14 | Object.prototype.toString.call(value) === '[object Object]'
15 | );
16 | }
17 |
18 | function _merge(target, source) {
19 | if (target === source) {
20 | return target;
21 | }
22 |
23 | for (var key in source) {
24 | if (
25 | !Object.prototype.hasOwnProperty.call(source, key) ||
26 | key === '__proto__' ||
27 | key === 'constructor'
28 | ) {
29 | // eslint-disable-next-line no-continue
30 | continue;
31 | }
32 |
33 | var sourceVal = source[key];
34 | var targetVal = target[key];
35 |
36 | if (typeof targetVal !== 'undefined' && typeof sourceVal === 'undefined') {
37 | // eslint-disable-next-line no-continue
38 | continue;
39 | }
40 |
41 | if (
42 | isObjectOrArrayOrFunction(targetVal) &&
43 | isObjectOrArrayOrFunction(sourceVal)
44 | ) {
45 | // eslint-disable-next-line no-param-reassign
46 | target[key] = _merge(targetVal, sourceVal);
47 | } else {
48 | // eslint-disable-next-line no-param-reassign
49 | target[key] = clone(sourceVal);
50 | }
51 | }
52 | return target;
53 | }
54 |
55 | /**
56 | * This method is like Object.assign, but recursively merges own and inherited
57 | * enumerable keyed properties of source objects into the destination object.
58 | *
59 | * NOTE: this behaves like lodash/merge, but:
60 | * - does mutate functions if they are a source
61 | * - treats non-plain objects as plain
62 | * - does not work for circular objects
63 | * - treats sparse arrays as sparse
64 | * - does not convert Array-like objects (Arguments, NodeLists, etc.) to arrays
65 | *
66 | * @param {Object} target The destination object.
67 | * @param {...Object} [sources] The source objects.
68 | * @returns {Object} Returns `object`.
69 | */
70 | function merge(target) {
71 | if (!isObjectOrArrayOrFunction(target)) {
72 | // eslint-disable-next-line no-param-reassign
73 | target = {};
74 | }
75 |
76 | for (var i = 1, l = arguments.length; i < l; i++) {
77 | var source = arguments[i];
78 |
79 | if (isObjectOrArrayOrFunction(source)) {
80 | _merge(target, source);
81 | }
82 | }
83 | return target;
84 | }
85 |
86 | module.exports = merge;
87 |
--------------------------------------------------------------------------------
/src/functions/objectHasKeys.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function objectHasKeys(obj) {
4 | return obj && Object.keys(obj).length > 0;
5 | }
6 |
7 | module.exports = objectHasKeys;
8 |
--------------------------------------------------------------------------------
/src/functions/omit.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // https://github.com/babel/babel/blob/3aaafae053fa75febb3aa45d45b6f00646e30ba4/packages/babel-helpers/src/helpers.js#L604-L620
4 | function _objectWithoutPropertiesLoose(source, excluded) {
5 | if (source === null) return {};
6 | var target = {};
7 | var sourceKeys = Object.keys(source);
8 | var key;
9 | var i;
10 | for (i = 0; i < sourceKeys.length; i++) {
11 | key = sourceKeys[i];
12 | // eslint-disable-next-line no-continue
13 | if (excluded.indexOf(key) >= 0) continue;
14 | target[key] = source[key];
15 | }
16 | return target;
17 | }
18 |
19 | module.exports = _objectWithoutPropertiesLoose;
20 |
--------------------------------------------------------------------------------
/src/functions/orderBy.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function compareAscending(value, other) {
4 | if (value !== other) {
5 | var valIsDefined = value !== undefined;
6 | var valIsNull = value === null;
7 |
8 | var othIsDefined = other !== undefined;
9 | var othIsNull = other === null;
10 |
11 | if (
12 | (!othIsNull && value > other) ||
13 | (valIsNull && othIsDefined) ||
14 | !valIsDefined
15 | ) {
16 | return 1;
17 | }
18 | if (
19 | (!valIsNull && value < other) ||
20 | (othIsNull && valIsDefined) ||
21 | !othIsDefined
22 | ) {
23 | return -1;
24 | }
25 | }
26 | return 0;
27 | }
28 |
29 | /**
30 | * @param {Array