From ed036802e382306fab358ee84e0831e287476309 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Fri, 16 May 2025 13:16:45 +0300
Subject: [PATCH 01/13] Add script for manipulating and checking code samples,
refactor code samples
---
.code-samples.meilisearch.yaml | 1345 +++++++++++++++++------------
.gitignore | 1 +
package.json | 8 +-
scripts/code-samples.js | 17 +
scripts/code-samples/from-yaml.js | 50 ++
scripts/code-samples/shared.js | 37 +
scripts/code-samples/to-yaml.js | 73 ++
tsconfig.json | 8 +-
yarn.lock | 5 +
9 files changed, 966 insertions(+), 578 deletions(-)
create mode 100644 scripts/code-samples.js
create mode 100644 scripts/code-samples/from-yaml.js
create mode 100644 scripts/code-samples/shared.js
create mode 100644 scripts/code-samples/to-yaml.js
diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 5d4788ece..1c37ade72 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -1,514 +1,614 @@
# This code-samples file is used by the Meilisearch documentation
# Every example written here will be automatically fetched by
# the documentation on build
-# You can read more on https://github.com/meilisearch/documentation/tree/master/.vuepress/code-samples
+# You can read more at https://github.com/meilisearch/documentation
---
synonyms_guide_1: |-
- client.index('movies').updateSynonyms({
- 'great': ['fantastic'],
- 'fantastic': ['great']
- })
+ const _task = await _client
+ .index("movies")
+ .updateSynonyms({
+ great: ["fantastic"],
+ fantastic: ["great"],
+ })
+ .waitTask();
date_guide_index_1: |-
- const games = require('./games.json')
- client.index('games').addDocuments(games).then((res) => console.log(res))
+ import games from "./games.json" with { type: "json" };
+ const _task = await _client.index("games").addDocuments(games).waitTask();
date_guide_filterable_attributes_1: |-
- client.index('games').updateFilterableAttributes(['release_timestamp'])
+ const _task = await _client
+ .index("games")
+ .updateFilterableAttributes(["release_timestamp"])
+ .waitTask();
date_guide_filter_1: |-
- client.index('games').search('', {
- filter: 'release_timestamp >= 1514761200 AND release_timestamp < 1672527600'
- })
+ const _response = await _client.index("games").search("", {
+ filter: "release_timestamp >= 1514761200 AND release_timestamp < 1672527600",
+ });
date_guide_sortable_attributes_1: |-
- client.index('games').updateSortableAttributes(['release_timestamp'])
+ const _task = await _client
+ .index("games")
+ .updateSortableAttributes(["release_timestamp"])
+ .waitTask();
date_guide_sort_1: |-
- client.index('games').search('', {
- sort: ['release_timestamp:desc'],
- })
+ const _response = await _client.index("games").search("", {
+ sort: ["release_timestamp:desc"],
+ });
get_one_index_1: |-
- client.index('movies').getRawInfo()
+ const _index = await _client.index("movies").getRawInfo();
list_all_indexes_1: |-
- client.getIndexes({ limit: 3 })
+ const _indexes = await _client.getIndexes({ limit: 3 });
create_an_index_1: |-
- client.createIndex('movies', { primaryKey: 'id' })
+ const _task = await _client
+ .createIndex("movies", { primaryKey: "id" })
+ .waitTask();
update_an_index_1: |-
- client.updateIndex('movies', { primaryKey: 'id' })
+ const _task = _client.updateIndex("movies", { primaryKey: "id" }).waitTask();
delete_an_index_1: |-
- client.deleteIndex('movies')
+ const _task = await _client.deleteIndex("movies").waitTask();
swap_indexes_1: |-
- client.swapIndexes([
- { 'indexes': ['indexA', 'indexB'] },
- { 'indexes': ['indexX', 'indexY'] }
- ])
+ const _task = await _client
+ .swapIndexes([
+ { indexes: ["indexA", "indexB"] },
+ { indexes: ["indexX", "indexY"] },
+ ])
+ .waitTask();
get_one_document_1: |-
- client
- .index('movies')
- .getDocument(25684, { fields: ['id', 'title', 'poster', 'release_date'] })
+ const _documents = await _client
+ .index("movies")
+ .getDocument(25684, { fields: ["id", "title", "poster", "release_date"] });
get_documents_1: |-
- client.index('movies').getDocuments({
+ const _documents = await _client.index("movies").getDocuments({
limit: 2,
- filter: 'genres = action'
- })
+ filter: "genres = action",
+ });
get_documents_post_1: |-
- client.index('books').getDocuments({
- filter: '(rating > 3 AND (genres = Adventure OR genres = Fiction)) AND language = English',
- fields: ['title', 'genres', 'rating', 'language'],
- limit: 3
- })
+ const _documents = await _client.index("books").getDocuments({
+ filter:
+ "(rating > 3 AND (genres = Adventure OR genres = Fiction)) AND language = English",
+ fields: ["title", "genres", "rating", "language"],
+ limit: 3,
+ });
add_or_replace_documents_1: |-
- client.index('movies').addDocuments([{
- id: 287947,
- title: 'Shazam',
- poster: 'https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg',
- overview: 'A boy is given the ability to become an adult superhero in times of need with a single magic word.',
- release_date: '2019-03-23'
- }])
+ const _task = await _client
+ .index("movies")
+ .addDocuments([
+ {
+ id: 287947,
+ title: "Shazam",
+ poster:
+ "https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg",
+ overview:
+ "A boy is given the ability to become an adult superhero in times of need with a single magic word.",
+ release_date: "2019-03-23",
+ },
+ ])
+ .waitTask();
add_or_update_documents_1: |-
- client.index('movies').updateDocuments([{
- id: 287947,
- title: 'Shazam ⚡️',
- genres: 'comedy'
- }])
+ const _task = await _client
+ .index("movies")
+ .updateDocuments([
+ {
+ id: 287947,
+ title: "Shazam ⚡️",
+ genres: "comedy",
+ },
+ ])
+ .waitTask();
delete_all_documents_1: |-
- client.index('movies').deleteAllDocuments()
+ const _task = await _client.index("movies").deleteAllDocuments().waitTask();
delete_one_document_1: |-
- client.index('movies').deleteDocument(25684)
+ const _task = await _client.index("movies").deleteDocument(25684).waitTask();
delete_documents_by_batch_1: |-
- client.index('movies').deleteDocuments([23488, 153738, 437035, 363869])
+ const _task = await _client
+ .index("movies")
+ .deleteDocuments([23488, 153738, 437035, 363869])
+ .waitTask();
delete_documents_by_filter_1: |-
- client.index('movies').deleteDocuments({
- filter: 'genres = action OR genres = adventure'
- })
+ const _task = await _client
+ .index("movies")
+ .deleteDocuments({
+ filter: "genres = action OR genres = adventure",
+ })
+ .waitTask();
search_post_1: |-
- client.index('movies').search('American ninja')
+ const _response = await _client.index("movies").search("American ninja");
search_get_1: |-
- client.index('movies').searchGet('American ninja')
+ const _response = await _client.index("movies").searchGet("American ninja");
multi_search_1: |-
- client.multiSearch({ queries: [
- {
- indexUid: 'movies',
- q: 'pooh',
- limit: 5,
- },
- {
- indexUid: 'movies',
- q: 'nemo',
- limit: 5,
- },
- {
- indexUid: 'movie_ratings',
- q: 'us',
- },
- ]})
+ const _response = await _client.multiSearch({
+ queries: [
+ {
+ indexUid: "movies",
+ q: "pooh",
+ limit: 5,
+ },
+ {
+ indexUid: "movies",
+ q: "nemo",
+ limit: 5,
+ },
+ {
+ indexUid: "movie_ratings",
+ q: "us",
+ },
+ ],
+ });
get_all_tasks_1: |-
- client.getTasks()
+ const _tasks = await _client.tasks.getTasks();
get_task_1: |-
- client.getTask(1)
+ const _task = await _client.tasks.getTask(1);
async_guide_filter_by_date_1: |-
- client.getTasks({ afterEnqueuedAt: '2020-10-11T11:49:53.000Z' })
+ const _tasks = await _client.tasks.getTasks({
+ afterEnqueuedAt: "2020-10-11T11:49:53.000Z",
+ });
async_guide_multiple_filters_1: |-
- client.getTasks({
- indexUids: ['movies'],
- types: ['documentAdditionOrUpdate','documentDeletion'],
- statuses: ['processing']
- })
+ const _tasks = await _client.tasks.getTasks({
+ indexUids: ["movies"],
+ types: ["documentAdditionOrUpdate", "documentDeletion"],
+ statuses: ["processing"],
+ });
async_guide_filter_by_ids_1: |-
- client.getTasks({ uids: [5, 10, 13] })
+ const _tasks = await _client.tasks.getTasks({ uids: [5, 10, 13] });
async_guide_filter_by_statuses_1: |-
- client.getTasks({ statuses: ['failed', 'canceled'] })
+ const _tasks = await _client.tasks.getTasks({
+ statuses: ["failed", "canceled"],
+ });
async_guide_filter_by_types_1: |-
- client.getTasks({ types: ['dumpCreation', 'indexSwap'] })
+ const _tasks = await _client.tasks.getTasks({
+ types: ["dumpCreation", "indexSwap"],
+ });
async_guide_filter_by_index_uids_1: |-
- client.getTasks({ indexUids: ['movies'] })
+ const _tasks = await _client.tasks.getTasks({ indexUids: ["movies"] });
get_all_tasks_paginating_1: |-
- client.getTasks({ limit: 2, from: 10 })
+ const _tasks = await _client.tasks.getTasks({ limit: 2, from: 10 });
get_all_tasks_paginating_2: |-
- client.getTasks({ limit: 2, from: 8 })
+ const _tasks = await _client.tasks.getTasks({ limit: 2, from: 8 });
async_guide_canceled_by_1: |-
- client.getTasks({ canceledBy: [9, 15] })
+ const _tasks = await _client.tasks.getTasks({ canceledBy: [9, 15] });
delete_tasks_1: |-
- client.deleteTasks({ uids: [1, 2] })
+ const _task = await _client.tasks.deleteTasks({ uids: [1, 2] }).waitTask();
cancel_tasks_1: |-
- client.cancelTasks({ uids: [1, 2] })
+ const _task = await _client.tasks.cancelTasks({ uids: [1, 2] }).waitTask();
get_one_key_1: |-
- client.getKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d')
+ const _key = await _client.getKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d");
get_all_keys_1: |-
- client.getKeys({ limit: 3 })
+ const _keys = await _client.getKeys({ limit: 3 });
create_a_key_1: |-
- client.createKey({
- description: 'Add documents: Products API key',
- actions: ['documents.add'],
- indexes: ['products'],
- expiresAt: '2021-11-13T00:00:00Z'
- })
+ const _key = await _client.createKey({
+ description: "Add documents: Products API key",
+ actions: ["documents.add"],
+ indexes: ["products"],
+ expiresAt: new Date("2021-11-13T00:00:00Z"),
+ });
update_a_key_1: |-
- client.updateKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d', {
- name: 'Products/Reviews API key',
- description: 'Manage documents: Products/Reviews API key',
- })
+ const _key = await _client.updateKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d", {
+ name: "Products/Reviews API key",
+ description: "Manage documents: Products/Reviews API key",
+ });
delete_a_key_1: |-
- client.deleteKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d')
+ await _client.deleteKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d");
get_settings_1: |-
- client.index('movies').getSettings()
+ const _settings = await _client.index("movies").getSettings();
update_settings_1: |-
- client.index('movies').updateSettings({
+ const _task = await _client
+ .index("movies")
+ .updateSettings({
rankingRules: [
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'exactness',
- 'release_date:desc',
- 'rank:desc'
- ],
- distinctAttribute: 'movie_id',
- searchableAttributes: [
- 'title',
- 'overview',
- 'genres'
- ],
- displayedAttributes: [
- 'title',
- 'overview',
- 'genres',
- 'release_date'
- ],
- stopWords: [
- 'the',
- 'a',
- 'an'
- ],
- sortableAttributes: [
- 'title',
- 'release_date'
+ "words",
+ "typo",
+ "proximity",
+ "attribute",
+ "sort",
+ "exactness",
+ "release_date:desc",
+ "rank:desc",
],
+ distinctAttribute: "movie_id",
+ searchableAttributes: ["title", "overview", "genres"],
+ displayedAttributes: ["title", "overview", "genres", "release_date"],
+ stopWords: ["the", "a", "an"],
+ sortableAttributes: ["title", "release_date"],
synonyms: {
- 'wolverine': ['xmen', 'logan'],
- 'logan': ['wolverine']
+ wolverine: ["xmen", "logan"],
+ logan: ["wolverine"],
},
typoTolerance: {
- 'minWordSizeForTypos': {
- 'oneTypo': 8,
- 'twoTypos': 10
- },
- 'disableOnAttributes': [
- 'title'
- ]
+ minWordSizeForTypos: {
+ oneTypo: 8,
+ twoTypos: 10,
+ },
+ disableOnAttributes: ["title"],
},
pagination: {
- maxTotalHits: 5000
+ maxTotalHits: 5000,
},
faceting: {
- maxValuesPerFacet: 200
+ maxValuesPerFacet: 200,
},
- searchCutoffMs: 150
- })
+ searchCutoffMs: 150,
+ })
+ .waitTask();
reset_settings_1: |-
- client.index('movies').resetSettings()
+ const _task = await _client.index("movies").resetSettings().waitTask();
get_synonyms_1: |-
- client.index('movies').getSynonyms()
+ const _synonyms = await _client.index("movies").getSynonyms();
update_synonyms_1: |-
- client.index('movies').updateSynonyms({
- wolverine: ['xmen', 'logan'],
- logan: ['wolverine', 'xmen'],
- wow: ['world of warcraft']
- })
+ const _task = await _client
+ .index("movies")
+ .updateSynonyms({
+ wolverine: ["xmen", "logan"],
+ logan: ["wolverine", "xmen"],
+ wow: ["world of warcraft"],
+ })
+ .waitTask();
reset_synonyms_1: |-
- client.index('movies').resetSynonyms()
+ const _task = await _client.index("movies").resetSynonyms().waitTask();
get_stop_words_1: |-
- client.index('movies').getStopWords()
+ const _stopWords = await _client.index("movies").getStopWords();
update_stop_words_1: |-
- client.index('movies').updateStopWords(['of', 'the', 'to'])
+ const _task = await _client
+ .index("movies")
+ .updateStopWords(["of", "the", "to"])
+ .waitTask();
reset_stop_words_1: |-
- client.index('movies').resetStopWords()
+ const _task = await _client.index("movies").resetStopWords().waitTask();
get_ranking_rules_1: |-
- client.index('movies').getRankingRules()
+ const _rankingRules = await _client.index("movies").getRankingRules();
update_ranking_rules_1: |-
- client.index('movies').updateRankingRules([
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'exactness',
- 'release_date:asc',
- 'rank:desc'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateRankingRules([
+ "words",
+ "typo",
+ "proximity",
+ "attribute",
+ "sort",
+ "exactness",
+ "release_date:asc",
+ "rank:desc",
+ ])
+ .waitTask();
reset_ranking_rules_1: |-
- client.index('movies').resetRankingRules()
+ const _task = await _client.index("movies").resetRankingRules().waitTask();
get_distinct_attribute_1: |-
- client.index('shoes').getDistinctAttribute()
+ const _distinctAttribute = await _client.index("shoes").getDistinctAttribute();
update_distinct_attribute_1: |-
- client.index('shoes').updateDistinctAttribute('skuid')
+ const _task = await _client
+ .index("shoes")
+ .updateDistinctAttribute("skuid")
+ .waitTask();
reset_distinct_attribute_1: |-
- client.index('shoes').resetDistinctAttribute()
+ const _task = await _client.index("shoes").resetDistinctAttribute().waitTask();
get_searchable_attributes_1: |-
- client.index('movies').getSearchableAttributes()
+ const _searchableAttributes = await _client
+ .index("movies")
+ .getSearchableAttributes();
update_searchable_attributes_1: |-
- client.index('movies').updateSearchableAttributes([
- 'title',
- 'overview',
- 'genres'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateSearchableAttributes(["title", "overview", "genres"])
+ .waitTask();
reset_searchable_attributes_1: |-
- client.index('movies').resetSearchableAttributes()
+ const _task = await _client
+ .index("movies")
+ .resetSearchableAttributes()
+ .waitTask();
get_displayed_attributes_1: |-
- client.index('movies').getDisplayedAttributes()
+ const _displayedAttributes = await _client
+ .index("movies")
+ .getDisplayedAttributes();
update_displayed_attributes_1: |-
- client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'genres',
- 'release_date'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateDisplayedAttributes(["title", "overview", "genres", "release_date"])
+ .waitTask();
reset_displayed_attributes_1: |-
- client.index('movies').resetDisplayedAttributes()
+ const _task = await _client
+ .index("movies")
+ .resetDisplayedAttributes()
+ .waitTask();
get_typo_tolerance_1: |-
- client.index('books').getTypoTolerance()
+ const _typoTolerance = await _client.index("books").getTypoTolerance();
update_typo_tolerance_1: |-
- client.index('books').updateTypoTolerance({
- minWordSizeForTypos: {
+ const _task = await _client
+ .index("books")
+ .updateTypoTolerance({
+ minWordSizeForTypos: {
oneTypo: 4,
- twoTypos: 10
+ twoTypos: 10,
},
- disableOnAttributes: [
- 'title'
- ]
- })
+ disableOnAttributes: ["title"],
+ })
+ .waitTask();
reset_typo_tolerance_1: |-
- client.index('books').resetTypoTolerance()
+ const _task = await _client.index("books").resetTypoTolerance().waitTask();
get_index_stats_1: |-
- client.index('movies').getStats()
+ const _indexStats = await _client.index("movies").getStats();
get_indexes_stats_1: |-
- client.getStats()
+ const _stats = await _client.getStats();
get_health_1: |-
- client.health()
+ const _health = _client.health();
get_version_1: |-
- client.getVersion()
+ const _version = await _client.getVersion();
distinct_attribute_guide_1: |-
- client.index('jackets').updateDistinctAttribute('product_id')
+ const _task = await _client
+ .index("jackets")
+ .updateDistinctAttribute("product_id")
+ .waitTask();
field_properties_guide_searchable_1: |-
- client.index('movies').updateSearchableAttributes([
- 'title',
- 'overview',
- 'genres',
- ]
- )
+ const _task = await _client
+ .index("movies")
+ .updateSearchableAttributes(["title", "overview", "genres"])
+ .waitTask();
field_properties_guide_displayed_1: |-
- client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'genres',
- 'release_date',
- ]
- )
+ const _task = await _client
+ .index("movies")
+ .updateDisplayedAttributes(["title", "overview", "genres", "release_date"])
+ .waitTask();
filtering_guide_1: |-
- client.index('movie_ratings').search('Avengers', {
- filter: 'release_date > 795484800'
- })
+ const _response = await _client.index("movie_ratings").search("Avengers", {
+ filter: "release_date > 795484800",
+ });
filtering_guide_2: |-
- client.index('movie_ratings').search('Batman', {
- filter: 'release_date > 795484800 AND (director = "Tim Burton" OR director = "Christopher Nolan")'
- })
+ const _response = await _client.index("movie_ratings").search("Batman", {
+ filter:
+ 'release_date > 795484800 AND (director = "Tim Burton" OR director = "Christopher Nolan")',
+ });
filtering_guide_3: |-
- client.index('movie_ratings').search('Planet of the Apes', {
- filter: "release_date > 1577884550 AND (NOT director = \"Tim Burton\")"
- })
+ const _response = await _client
+ .index("movie_ratings")
+ .search("Planet of the Apes", {
+ filter: 'release_date > 1577884550 AND (NOT director = "Tim Burton")',
+ });
filtering_guide_nested_1: |-
- client.index('movie_ratings').search('thriller', {
- filter: 'rating.users >= 90'
- })
+ const _response = await _client.index("movie_ratings").search("thriller", {
+ filter: "rating.users >= 90",
+ });
search_parameter_guide_query_1: |-
- client.index('movies').search('shifu')
+ const _response = await _client.index("movies").search("shifu");
search_parameter_guide_offset_1: |-
- client.index('movies').search('shifu', {
- offset: 1
- })
+ const _response = await _client.index("movies").search("shifu", {
+ offset: 1,
+ });
search_parameter_guide_limit_1: |-
- client.index('movies').search('shifu', {
- limit: 2
- })
+ const _response = await _client.index("movies").search("shifu", {
+ limit: 2,
+ });
search_parameter_guide_retrieve_1: |-
- client.index('movies').search('shifu', {
- attributesToRetrieve: ['overview', 'title']
- })
+ const _response = await _client.index("movies").search("shifu", {
+ attributesToRetrieve: ["overview", "title"],
+ });
search_parameter_guide_crop_1: |-
- client.index('movies').search('shifu', {
- attributesToCrop: ['overview'],
- cropLength: 5
- })
+ const _response = await _client.index("movies").search("shifu", {
+ attributesToCrop: ["overview"],
+ cropLength: 5,
+ });
search_parameter_guide_crop_marker_1: |-
- client.index('movies').search('shifu', {
- attributesToCrop: ['overview'],
- cropMarker: '[…]'
- })
+ const _response = await _client.index("movies").search("shifu", {
+ attributesToCrop: ["overview"],
+ cropMarker: "[…]",
+ });
search_parameter_guide_highlight_1: |-
- client.index('movies').search('winter feast', {
- attributesToHighlight: ['overview']
- })
+ const _response = await _client.index("movies").search("winter feast", {
+ attributesToHighlight: ["overview"],
+ });
search_parameter_guide_highlight_tag_1: |-
- client.index('movies').search('winter feast', {
- attributesToHighlight: ['overview'],
+ const _response = await _client.index("movies").search("winter feast", {
+ attributesToHighlight: ["overview"],
highlightPreTag: '',
- highlightPostTag: ''
- })
+ highlightPostTag: "",
+ });
search_parameter_guide_show_matches_position_1: |-
- client.index('movies').search('winter feast', {
- showMatchesPosition: true
- })
+ const _response = await _client.index("movies").search("winter feast", {
+ showMatchesPosition: true,
+ });
search_parameter_guide_matching_strategy_1: |-
- client.index('movies').search('big fat liar', {
- matchingStrategy: 'last'
- })
+ const _response = await _client.index("movies").search("big fat liar", {
+ matchingStrategy: "last",
+ });
search_parameter_guide_matching_strategy_2: |-
- client.index('movies').search('big fat liar', {
- matchingStrategy: 'all'
- })
+ const _response = await _client.index("movies").search("big fat liar", {
+ matchingStrategy: "all",
+ });
search_parameter_guide_hitsperpage_1: |-
- client.index('movies').search('', {
- hitsPerPage: 15
- })
+ const _response = await _client.index("movies").search("", {
+ hitsPerPage: 15,
+ });
search_parameter_guide_page_1: |-
- client.index('movies').search('', {
- page: 2
- })
+ const _response = await _client.index("movies").search("", {
+ page: 2,
+ });
search_parameter_guide_show_ranking_score_1: |-
- client.index('movies').search('dragon', {
- showRankingScore: true
- })
+ const _response = await _client.index("movies").search("dragon", {
+ showRankingScore: true,
+ });
search_parameter_guide_attributes_to_search_on_1: |-
- client.index('movies').search('adventure', {
- attributesToSearchOn: ['overview']
- })
+ const _response = await _client.index("movies").search("adventure", {
+ attributesToSearchOn: ["overview"],
+ });
typo_tolerance_guide_1: |-
- client.index('movies').updateTypoTolerance({
- enabled: false
- })
+ const _task = await _client
+ .index("movies")
+ .updateTypoTolerance({
+ enabled: false,
+ })
+ .waitTask();
typo_tolerance_guide_2: |-
- client.index('movies').updateTypoTolerance({
- disableOnAttributes: ['title']
- })
+ const _task = await _client
+ .index("movies")
+ .updateTypoTolerance({
+ disableOnAttributes: ["title"],
+ })
+ .waitTask();
typo_tolerance_guide_3: |-
- client.index('movies').updateTypoTolerance({
- disableOnWords: ['shrek']
- })
+ const _task = await _client
+ .index("movies")
+ .updateTypoTolerance({
+ disableOnWords: ["shrek"],
+ })
+ .waitTask();
typo_tolerance_guide_4: |-
- client.index('movies').updateTypoTolerance({
- minWordSizeForTypos: {
- oneTypo: 4,
- twoTypos: 10
- }
- })
+ const _task = await _client
+ .index("movies")
+ .updateTypoTolerance({
+ minWordSizeForTypos: {
+ oneTypo: 4,
+ twoTypos: 10,
+ },
+ })
+ .waitTask();
add_movies_json_1: |-
- const movies = require('./movies.json')
- client.index('movies').addDocuments(movies).then((res) => console.log(res))
+ import movies from "./movies.json" with { type: "json" };
+ const task = await _client.index("movies").addDocuments(movies).waitTask();
+ console.log(task);
primary_field_guide_update_document_primary_key: |-
- client.updateIndex('books', {
- primaryKey: 'title'
- })
+ const _task = await _client
+ .updateIndex("books", { primaryKey: "title" })
+ .waitTask();
primary_field_guide_create_index_primary_key: |-
- client.createIndex('books', { primaryKey: 'reference_number' })
+ const _task = await _client
+ .createIndex("books", { primaryKey: "reference_number" })
+ .waitTask();
primary_field_guide_add_document_primary_key: |-
- client.index('books').addDocuments([
- {
- reference_number: 287947,
- title: 'Diary of a Wimpy Kid',
- author: 'Jeff Kinney',
- genres: ['comedy','humor'],
- price: 5.00
- }
- ], { primaryKey: 'reference_number' })
+ const _task = await _client
+ .index("books")
+ .addDocuments(
+ [
+ {
+ reference_number: 287947,
+ title: "Diary of a Wimpy Kid",
+ author: "Jeff Kinney",
+ genres: ["comedy", "humor"],
+ price: 5.0,
+ },
+ ],
+ { primaryKey: "reference_number" },
+ )
+ .waitTask();
getting_started_add_documents: |-
// With npm:
// npm install meilisearch
-
+
// Or with yarn:
// yarn add meilisearch
-
+
// In your .js file:
+ import { MeiliSearch } from "meilisearch";
+ import movies from "./movies.json" with { type: "json" };
+
// With the `require` syntax:
- const { MeiliSearch } = require('meilisearch')
- const movies = require('./movies.json')
- // With the `import` syntax:
- import { MeiliSearch } from 'meilisearch'
- import movies from './movies.json'
-
+ // const { MeiliSearch } = require("meilisearch");
+ // const movies = require("./movies.json");
+
const client = new MeiliSearch({
- host: 'http://localhost:7700',
- apiKey: 'aSampleMasterKey'
- })
- client.index('movies').addDocuments(movies)
- .then((res) => console.log(res))
+ host: "http://localhost:7700",
+ apiKey: "aSampleMasterKey",
+ });
+
+ const task = await client.index("movies").addDocuments(movies).waitTask();
+ console.log(task);
getting_started_search: |-
- client.index('movies').search('botman').then((res) => console.log(res))
+ const response = await _client.index("movies").search("botman");
+
+ console.log(response);
getting_started_update_ranking_rules: |-
- client.index('movies').updateRankingRules([
- 'exactness',
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'release_date:asc',
- 'rank:desc'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateRankingRules([
+ "exactness",
+ "words",
+ "typo",
+ "proximity",
+ "attribute",
+ "sort",
+ "release_date:asc",
+ "rank:desc",
+ ])
+ .waitTask();
getting_started_update_searchable_attributes: |-
- client.index('movies').updateSearchableAttributes([
- 'title'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateSearchableAttributes(["title"])
+ .waitTask();
getting_started_update_stop_words: |-
- client.index('movies').updateStopWords(['the'])
+ const _task = await _client.index("movies").updateStopWords(["the"]).waitTask();
getting_started_check_task_status: |-
- client.getTask(0)
+ const _task = await _client.tasks.getTask(0);
getting_started_synonyms: |-
- client.index('movies').updateSynonyms({
- winnie: ['piglet'],
- piglet: ['winnie']
- })
+ const _task = await _client
+ .index("movies")
+ .updateSynonyms({
+ winnie: ["piglet"],
+ piglet: ["winnie"],
+ })
+ .waitTask();
getting_started_update_displayed_attributes: |-
- client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'poster'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateDisplayedAttributes(["title", "overview", "poster"])
+ .waitTask();
getting_started_add_meteorites: |-
- const meteorites = require('./meteorites.json')
-
- client.index('meteorites').addDocuments(meteorites)
+ import meteorites from "./meteorites.json" with { type: "json" };
+
+ const _task = await _client
+ .index("meteorites")
+ .addDocuments(meteorites)
+ .waitTask();
getting_started_configure_settings: |-
- client.index('meteorites').updateSettings({
- filterableAttributes: ['mass', '_geo'],
- sortableAttributes: ['mass', '_geo']
- })
+ const _task = await _client
+ .index("meteorites")
+ .updateSettings({
+ filterableAttributes: ["mass", "_geo"],
+ sortableAttributes: ["mass", "_geo"],
+ })
+ .waitTask();
getting_started_geo_radius: |-
- client.index('meteorites').search('', { filter: '_geoRadius(46.9480, 7.4474, 210000)' })
+ const _response = await _client
+ .index("meteorites")
+ .search("", { filter: "_geoRadius(46.9480, 7.4474, 210000)" });
getting_started_geo_point: |-
- client.index('meteorites').search('', { sort: ['_geoPoint(48.8583701, 2.2922926):asc'] })
+ const _response = await _client
+ .index("meteorites")
+ .search("", { sort: ["_geoPoint(48.8583701, 2.2922926):asc"] });
getting_started_sorting: |-
- client.index('meteorites').search('', {
- sort: ['mass:asc'],
- filter: 'mass < 200'
- })
+ const _response = await _client.index("meteorites").search("", {
+ sort: ["mass:asc"],
+ filter: "mass < 200",
+ });
getting_started_faceting: |-
- client.index('movies').updateFaceting({
- maxValuesPerFacet: 2,
- sortFacetValuesBy: {
- '*': 'count'
- }
- })
+ const _task = await _client
+ .index("movies")
+ .updateFaceting({
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {
+ "*": "count",
+ },
+ })
+ .waitTask();
getting_started_typo_tolerance: |-
- client.index('movies').updateTypoTolerance({
- minWordSizeForTypos: {
- oneTypo: 4
- }
- })
+ const _task = await _client
+ .index("movies")
+ .updateTypoTolerance({
+ minWordSizeForTypos: {
+ oneTypo: 4,
+ },
+ })
+ .waitTask();
getting_started_filtering: |-
- client.index('meteorites').search('', { filter: 'mass < 200' })
+ const _response = await _client
+ .index("meteorites")
+ .search("", { filter: "mass < 200" });
getting_started_pagination: |-
- client.index('movies').updatePagination({ maxTotalHits: 500 })
+ const _task = await _client
+ .index("movies")
+ .updatePagination({ maxTotalHits: 500 })
+ .waitTask();
get_filterable_attributes_1: |-
- client.index('movies').getFilterableAttributes()
+ const _filterableAttributes = await _client
+ .index("movies")
+ .getFilterableAttributes();
update_filterable_attributes_1: |-
- client.index('movies')
+ const _task = await _client
+ .index("movies")
.updateFilterableAttributes([
"genres",
{
@@ -517,305 +617,402 @@ update_filterable_attributes_1: |-
facetSearch: true,
filter: { equality: true, comparison: false },
},
- }
+ },
])
+ .waitTask();
reset_filterable_attributes_1: |-
- client.index('movies').resetFilterableAttributes()
+ const _task = await _client
+ .index("movies")
+ .resetFilterableAttributes()
+ .waitTask();
filtering_update_settings_1: |-
- client.index('movies')
- .updateFilterableAttributes([
- 'director',
- 'genres'
- ])
+ const _task = await _client
+ .index("movies")
+ .updateFilterableAttributes(["director", "genres"])
+ .waitTask();
faceted_search_walkthrough_filter_1: |-
- client.index('movies')
- .search('thriller', {
- filter: [['genres = Horror', 'genres = Mystery'], 'director = "Jordan Peele"']
- })
+ const _response = await _client.index("movies").search("thriller", {
+ filter: [
+ ["genres = Horror", "genres = Mystery"],
+ 'director = "Jordan Peele"',
+ ],
+ });
faceted_search_update_settings_1: |-
- client.index('movie_ratings').updateFilterableAttributes(['genres', 'rating', 'language'])
+ const _task = await _client
+ .index("movie_ratings")
+ .updateFilterableAttributes(["genres", "rating", "language"])
+ .waitTask();
faceted_search_1: |-
- client.index('books').search('classic', { facets: ['genres', 'rating', 'language'] })
+ const _response = await _client
+ .index("books")
+ .search("classic", { facets: ["genres", "rating", "language"] });
post_dump_1: |-
- client.createDump()
+ const _task = await _client.createDump().waitTask();
create_snapshot_1: |-
- client.createSnapshot()
+ const _task = await _client.createSnapshot().waitTask();
phrase_search_1: |-
- client.index('movies')
- .search('"african american" horror')
+ const _response = await _client
+ .index("movies")
+ .search('"african american" horror');
sorting_guide_update_sortable_attributes_1: |-
- client.index('books').updateSortableAttributes([
- 'author',
- 'price'
- ])
+ const _task = await _client
+ .index("books")
+ .updateSortableAttributes(["author", "price"])
+ .waitTask();
sorting_guide_update_ranking_rules_1: |-
- client.index('books').updateRankingRules([
- 'words',
- 'sort',
- 'typo',
- 'proximity',
- 'attribute',
- 'exactness'
- ])
+ const _task = await _client
+ .index("books")
+ .updateRankingRules([
+ "words",
+ "sort",
+ "typo",
+ "proximity",
+ "attribute",
+ "exactness",
+ ])
+ .waitTask();
sorting_guide_sort_parameter_1: |-
- client.index('books').search('science fiction', {
- sort: ['price:asc'],
- })
+ const _response = await _client.index("books").search("science fiction", {
+ sort: ["price:asc"],
+ });
sorting_guide_sort_parameter_2: |-
- client.index('books').search('butler', {
- sort: ['author:desc'],
- })
+ const _response = await _client.index("books").search("butler", {
+ sort: ["author:desc"],
+ });
sorting_guide_sort_nested_1: |-
- client.index('books').search('science fiction', {
- 'sort': ['rating.users:asc'],
- })
+ const _response = await _client.index("books").search("science fiction", {
+ sort: ["rating.users:asc"],
+ });
get_sortable_attributes_1: |-
- client.index('books').getSortableAttributes()
+ const _sortableAttributes = await _client
+ .index("books")
+ .getSortableAttributes();
update_sortable_attributes_1: |-
- client.index('books')
- .updateSortableAttributes([
- 'price',
- 'author'
- ])
+ const _task = await _client
+ .index("books")
+ .updateSortableAttributes(["price", "author"])
+ .waitTask();
reset_sortable_attributes_1: |-
- client.index('books').resetSortableAttributes()
+ const _task = await _client.index("books").resetSortableAttributes().waitTask();
get_pagination_settings_1: |-
- client.index('books').getPagination()
+ const _pagination = await _client.index("books").getPagination();
update_pagination_settings_1: |-
- client.index('books').updateSettings({ pagination: { maxTotalHits: 100 }})
+ const _task = await _client
+ .index("books")
+ .updateSettings({ pagination: { maxTotalHits: 100 } })
+ .waitTask();
reset_pagination_settings_1: |-
- client.index('books').resetPagination()
+ const _task = await _client.index("books").resetPagination().waitTask();
get_faceting_settings_1: |-
- client.index('books').getFaceting()
+ const _faceting = await _client.index("books").getFaceting();
update_faceting_settings_1: |-
- client.index('books').updateFaceting({
- maxValuesPerFacet: 2
- sortFacetValuesBy: {
- '*': 'alpha',
- genres: 'count'
- }
- })
+ const _task = await _client
+ .index("books")
+ .updateFaceting({
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {
+ "*": "alpha",
+ genres: "count",
+ },
+ })
+ .waitTask();
reset_faceting_settings_1: |-
- client.index('books').resetFaceting()
+ const _task = await _client.index("books").resetFaceting().waitTask();
get_dictionary_1: |-
- client.index('books').getDictionary()
+ const _dictionary = await _client.index("books").getDictionary();
update_dictionary_1: |-
- client.index('books').updateDictionary(['J. R. R.', 'W. E. B.'])
+ const _task = await _client
+ .index("books")
+ .updateDictionary(["J. R. R.", "W. E. B."])
+ .waitTask();
reset_dictionary_1: |-
- client.index('books').resetDictionary()
+ const _task = await _client.index("books").resetDictionary().waitTask();
search_parameter_guide_sort_1: |-
- client.index('books').search('science fiction', {
- sort: ['price:asc'],
- })
+ const _response = await _client.index("books").search("science fiction", {
+ sort: ["price:asc"],
+ });
get_separator_tokens_1: |-
- client.index('books').getSeparatorTokens()
+ const _separatorTokens = await _client.index("books").getSeparatorTokens();
update_separator_tokens_1: |-
- client.index('books').updateSeparatorTokens(['|', '…'])
+ const _task = await _client
+ .index("books")
+ .updateSeparatorTokens(["|", "…"])
+ .waitTask();
reset_separator_tokens_1: |-
- client.index('books').resetSeparatorTokens()
+ const _task = await _client.index("books").resetSeparatorTokens().waitTask();
get_non_separator_tokens_1: |-
- client.index('books').getNonSeparatorTokens()
+ const _nonSeparatorTokens = await _client
+ .index("books")
+ .getNonSeparatorTokens();
update_non_separator_tokens_1: |-
- client.index('books').updateNonSeparatorTokens(['@', '#'])
+ const _task = await _client
+ .index("books")
+ .updateNonSeparatorTokens(["@", "#"])
+ .waitTask();
reset_non_separator_tokens_1: |-
- client.index('books').resetNonSeparatorTokens()
+ const _task = await _client.index("books").resetNonSeparatorTokens().waitTask();
get_proximity_precision_settings_1: |-
- client.index('books').getProximityPrecision()
+ const _proximityPrecision = await _client
+ .index("books")
+ .getProximityPrecision();
update_proximity_precision_settings_1: |-
- client.index('books').updateProximityPrecision('byAttribute')
+ const _task = await _client
+ .index("books")
+ .updateProximityPrecision("byAttribute")
+ .waitTask();
reset_proximity_precision_settings_1: |-
- client.index('books').resetProximityPrecision()
+ const _task = await _client.index("books").resetProximityPrecision().waitTask();
get_search_cutoff_1: |-
- client.index('movies').getSearchCutoffMs()
+ const _searchCutoffMs = await _client.index("movies").getSearchCutoffMs();
update_search_cutoff_1: |-
- client.index('movies').updateSearchCutoffMs(150)
+ const _task = await _client
+ .index("movies")
+ .updateSearchCutoffMs(150)
+ .waitTask();
reset_search_cutoff_1: |-
- client.index('movies').resetSearchCutoffMs()
+ const _task = await _client.index("movies").resetSearchCutoffMs().waitTask();
search_parameter_guide_facet_stats_1: |-
- client.index('movie_ratings').search('Batman', { facets: ['genres', 'rating'] })
+ const _response = await _client
+ .index("movie_ratings")
+ .search("Batman", { facets: ["genres", "rating"] });
geosearch_guide_filter_settings_1: |-
- client.index('restaurants')
- .updateFilterableAttributes([
- '_geo'
- ])
+ const _task = await _client
+ .index("restaurants")
+ .updateFilterableAttributes(["_geo"])
+ .waitTask();
geosearch_guide_filter_usage_1: |-
- client.index('restaurants').search('', {
- filter: ['_geoRadius(45.472735, 9.184019, 2000)'],
- })
+ const _response = await _client.index("restaurants").search("", {
+ filter: ["_geoRadius(45.472735, 9.184019, 2000)"],
+ });
geosearch_guide_filter_usage_2: |-
- client.index('restaurants').search('', {
- filter: ['_geoRadius(45.472735, 9.184019, 2000) AND type = pizza'],
- })
+ const _response = await _client.index("restaurants").search("", {
+ filter: ["_geoRadius(45.472735, 9.184019, 2000) AND type = pizza"],
+ });
geosearch_guide_filter_usage_3: |-
- client.index('restaurants').search('', {
- filter: ['_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'],
- })
+ const _response = await _client.index("restaurants").search("", {
+ filter: ["_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])"],
+ });
geosearch_guide_sort_settings_1: |-
- client.index('restaurants').updateSortableAttributes([
- '_geo'
- ])
+ const _task = await _client
+ .index("restaurants")
+ .updateSortableAttributes(["_geo"])
+ .waitTask();
geosearch_guide_sort_usage_1: |-
- client.index('restaurants').search('', {
- sort: ['_geoPoint(48.8561446, 2.2978204):asc'],
- })
+ const _response = await _client.index("restaurants").search("", {
+ sort: ["_geoPoint(48.8561446, 2.2978204):asc"],
+ });
geosearch_guide_sort_usage_2: |-
- client.index('restaurants').search('', {
- sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc'],
- })
+ const _response = await _client.index("restaurants").search("", {
+ sort: ["_geoPoint(48.8561446, 2.2978204):asc", "rating:desc"],
+ });
security_guide_search_key_1: |-
- const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'apiKey' })
- client.index('patient_medical_records').search()
+ const client = new MeiliSearch({
+ host: "http://localhost:7700",
+ apiKey: "apiKey",
+ });
+
+ const _response = await client.index("patient_medical_records").search();
security_guide_update_key_1: |-
- const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' })
- client.updateKey('74c9c733-3368-4738-bbe5-1d18a5fecb37', {
- description: 'Default Search API Key'
- })
+ const client = new MeiliSearch({
+ host: "http://localhost:7700",
+ apiKey: "masterKey",
+ });
+
+ const _key = await client.updateKey("74c9c733-3368-4738-bbe5-1d18a5fecb37", {
+ description: "Default Search API Key",
+ });
security_guide_create_key_1: |-
- const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' })
- client.createKey({
- description: 'Search patient records key',
- actions: ['search'],
- indexes: ['patient_medical_records'],
- expiresAt: '2023-01-01T00:00:00Z'
- })
+ const client = new MeiliSearch({
+ host: "http://localhost:7700",
+ apiKey: "masterKey",
+ });
+
+ await client.createKey({
+ description: "Search patient records key",
+ actions: ["search"],
+ indexes: ["patient_medical_records"],
+ expiresAt: new Date("2023-01-01T00:00:00Z"),
+ });
security_guide_list_keys_1: |-
- const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' })
- client.getKeys()
+ const _keys = await _client.getKeys();
security_guide_delete_key_1: |-
- const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' })
- client.deleteKey('ac5cd97d-5a4b-4226-a868-2d0eb6d197ab')
+ const client = new MeiliSearch({
+ host: "http://localhost:7700",
+ apiKey: "masterKey",
+ });
+
+ await client.deleteKey("ac5cd97d-5a4b-4226-a868-2d0eb6d197ab");
authorization_header_1: |-
- const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' })
- client.getKeys()
+ const _keys = await _client.getKeys();
tenant_token_guide_generate_sdk_1: |-
- import { generateTenantToken } from 'meilisearch/token'
-
- const searchRules = {
- patient_medical_records: {
- filter: 'user_id = 1'
- }
- }
- const apiKey = 'B5KdX2MY2jV6EXfUs6scSfmC...'
- const apiKeyUid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76'
- const expiresAt = new Date('2025-12-20') // optional
-
- const token = await generateTenantToken({ apiKey, apiKeyUid, searchRules, expiresAt })
+ import { generateTenantToken } from "meilisearch/token";
+
+ const _token = await generateTenantToken({
+ apiKey: "B5KdX2MY2jV6EXfUs6scSfmC...",
+ apiKeyUid: "85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76",
+ searchRules: { patient_medical_records: { filter: "user_id = 1" } },
+ expiresAt: new Date("2025-12-20"), // optional
+ });
tenant_token_guide_search_sdk_1: |-
- const frontEndClient = new MeiliSearch({ host: 'http://localhost:7700', apiKey: token })
- frontEndClient.index('patient_medical_records').search('blood test')
+ const frontEndClient = new MeiliSearch({
+ host: "http://localhost:7700",
+ apiKey: "",
+ });
+
+ const _response = await frontEndClient
+ .index("patient_medical_records")
+ .search("blood test");
landing_getting_started_1: |-
- const client = new MeiliSearch('http://localhost:7700', 'masterKey')
-
- await client.index('movies').addDocuments([
- { 'id': 1, 'title': 'Carol' },
- { 'id': 2, 'title': 'Wonder Woman' },
- { 'id': 3, 'title': 'Life of Pi' },
- { 'id': 4, 'title': 'Mad Max: Fury Road' },
- { 'id': 5, 'title': 'Moana' },
- { 'id': 6, 'title': 'Philadelphia'}
- ])
-
+ const client = new MeiliSearch({
+ host: "http://localhost:7700",
+ apiKey: "masterKey",
+ });
+
+ await client.index("movies").addDocuments([
+ { id: 1, title: "Carol" },
+ { id: 2, title: "Wonder Woman" },
+ { id: 3, title: "Life of Pi" },
+ { id: 4, title: "Mad Max: Fury Road" },
+ { id: 5, title: "Moana" },
+ { id: 6, title: "Philadelphia" },
+ ]);
+
// be aware this client is using the masterKey, it should not be used in front end
- const search = await index.search('philodelphia')
- console.log(search)
+ const search = await client.index("movies").search("philodelphia");
+ console.log(search);
facet_search_1: |-
- client.index('books').searchForFacetValues({
- facetQuery: 'fiction',
- facetName: 'genres'
- filter: 'rating > 3'
- })
+ const _response = await _client.index("books").searchForFacetValues({
+ facetQuery: "fiction",
+ facetName: "genres",
+ filter: "rating > 3",
+ });
facet_search_2: |-
- client.index('books').updateFaceting({
- sortFacetValuesBy: {
- genres: 'count'
- }
- })
+ const _task = await _client
+ .index("books")
+ .updateFaceting({
+ sortFacetValuesBy: {
+ genres: "count",
+ },
+ })
+ .waitTask();
facet_search_3: |-
- client.index('books').searchForFacetValues({
- facetQuery: 'c',
- facetName: 'genres'
- })
+ const _response = await _client.index("books").searchForFacetValues({
+ facetQuery: "c",
+ facetName: "genres",
+ });
search_parameter_guide_show_ranking_score_details_1: |-
- client.index('movies').search('dragon', { showRankingScoreDetails: true })
+ const _response = await _client
+ .index("movies")
+ .search("dragon", { showRankingScoreDetails: true });
negative_search_1: |-
- client.index('movies').search('-escape')
+ const _response = await _client.index("movies").search("-escape");
negative_search_2: |-
- client.index('movies').search('-"escape"')
+ const _response = await _client.index("movies").search('-"escape"');
search_parameter_reference_ranking_score_threshold_1: |-
- client.index('INDEX_NAME').search('badman', { rankingScoreThreshold: 0.2 })
+ const _response = await _client
+ .index("INDEX_NAME")
+ .search("badman", { rankingScoreThreshold: 0.2 });
search_parameter_reference_retrieve_vectors_1: |-
- client.index('INDEX_NAME').search('kitchen utensils', {
+ const _response = await _client.index("INDEX_NAME").search("kitchen utensils", {
retrieveVectors: true,
hybrid: {
- embedder: 'EMBEDDER_NAME'
- }
- })
+ embedder: "EMBEDDER_NAME",
+ },
+ });
search_parameter_guide_hybrid_1: |-
- client.index('INDEX_NAME').search('kitchen utensils', {
+ const _response = await _client.index("INDEX_NAME").search("kitchen utensils", {
hybrid: {
semanticRatio: 0.9,
- embedder: 'EMBEDDER_NAME'
- }
- })
+ embedder: "EMBEDDER_NAME",
+ },
+ });
get_similar_post_1: |-
- client.index('INDEX_NAME').searchSimilarDocuments({ id: 'TARGET_DOCUMENT_ID', embedder: 'default' })
+ const _response = await _client
+ .index("INDEX_NAME")
+ .searchSimilarDocuments({ id: "TARGET_DOCUMENT_ID", embedder: "default" });
search_parameter_guide_matching_strategy_3: |-
- client.index('movies').search('white shirt', {
- matchingStrategy: 'frequency'
- })
+ const _response = await _client.index("movies").search("white shirt", {
+ matchingStrategy: "frequency",
+ });
search_parameter_reference_distinct_1: |-
- client.index('INDEX_NAME').search('QUERY TERMS', { distinct: 'ATTRIBUTE_A' })
+ const _response = await _client
+ .index("INDEX_NAME")
+ .search("QUERY TERMS", { distinct: "ATTRIBUTE_A" });
distinct_attribute_guide_filterable_1: |-
- client.index('products').updateFilterableAttributes(['product_id', 'sku', 'url'])
+ const _task = await _client
+ .index("products")
+ .updateFilterableAttributes(["product_id", "sku", "url"])
+ .waitTask();
distinct_attribute_guide_distinct_parameter_1: |-
- client.index('products').search('white shirt', { distinct: 'sku' })
+ const _response = await _client
+ .index("products")
+ .search("white shirt", { distinct: "sku" });
multi_search_federated_1: |-
- client.multiSearch({
+ const _response = await _client.multiSearch({
federation: {},
queries: [
{
- indexUid: 'movies',
- q: 'batman',
+ indexUid: "movies",
+ q: "batman",
},
{
- indexUid: 'comics',
- q: 'batman',
+ indexUid: "comics",
+ q: "batman",
},
- ]
- })
+ ],
+ });
search_parameter_reference_locales_1: |-
- client.index('INDEX_NAME').search('QUERY TEXT IN JAPANESE', { locales: ['jpn'] })
+ const _response = await _client
+ .index("INDEX_NAME")
+ .search("QUERY TEXT IN JAPANESE", { locales: ["jpn"] });
get_localized_attribute_settings_1: |-
- client.index('INDEX_NAME').getLocalizedAttributes()
+ const _localizedAttributes = await _client
+ .index("INDEX_NAME")
+ .getLocalizedAttributes();
update_localized_attribute_settings_1: |-
- client.index('INDEX_NAME').updateLocalizedAttributes([
- { attributePatterns: ['*_ja'], locales: ['jpn'] },
- ])
+ const _task = await _client
+ .index("INDEX_NAME")
+ .updateLocalizedAttributes([
+ { attributePatterns: ["*_ja"], locales: ["jpn"] },
+ ])
+ .waitTask();
reset_localized_attribute_settings_1: |-
- client.index('INDEX_NAME').resetLocalizedAttributes()
+ const _task = await _client
+ .index("INDEX_NAME")
+ .resetLocalizedAttributes()
+ .waitTask();
get_facet_search_settings_1: |-
- client.index('INDEX_NAME').getFacetSearch();
+ const _facetSearch = await _client.index("INDEX_NAME").getFacetSearch();
update_facet_search_settings_1: |-
- client.index('INDEX_NAME').updateFacetSearch(false);
+ const _task = await _client
+ .index("INDEX_NAME")
+ .updateFacetSearch(false)
+ .waitTask();
reset_facet_search_settings_1: |-
- client.index('INDEX_NAME').resetFacetSearch();
+ const _task = await _client.index("INDEX_NAME").resetFacetSearch().waitTask();
get_prefix_search_settings_1: |-
- client.index('INDEX_NAME').getPrefixSearch();
+ const _prefixSearch = await _client.index("INDEX_NAME").getPrefixSearch();
update_prefix_search_settings_1: |-
- client.index('INDEX_NAME').updatePrefixSearch('disabled');
+ const _task = await _client
+ .index("INDEX_NAME")
+ .updatePrefixSearch("disabled")
+ .waitTask();
reset_prefix_search_settings_1: |-
- client.index('INDEX_NAME').resetPrefixSearch();
+ const _task = await _client.index("INDEX_NAME").resetPrefixSearch().waitTask();
get_all_batches_1: |-
- client.getBatches();
+ const _batches = await _client.batches.getBatches();
get_batch_1: |-
- client.getBatch(BATCH_UID);
-# Vector search
+ const _batch = await _client.batches.getBatch(123);
update_embedders_1: |-
- client.index('INDEX_NAME').updateEmbedders({
- default: {
- source: 'openAi',
- apiKey: 'OPEN_AI_API_KEY',
- model: 'text-embedding-3-small',
- documentTemplate: 'A document titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}'
- }
- });
+ const _task = await _client
+ .index("INDEX_NAME")
+ .updateEmbedders({
+ default: {
+ source: "openAi",
+ apiKey: "OPEN_AI_API_KEY",
+ model: "text-embedding-3-small",
+ documentTemplate:
+ "A document titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}",
+ },
+ })
+ .waitTask();
diff --git a/.gitignore b/.gitignore
index 868fe3fb0..4ee31bb32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -133,3 +133,4 @@ package
dist_default_export_in_index
no_default_export_in_index
playgrounds/javascript/yarn.lock
+generated-code-samples
diff --git a/package.json b/package.json
index 4121006e3..5b2cc9d5d 100644
--- a/package.json
+++ b/package.json
@@ -70,22 +70,24 @@
],
"devDependencies": {
"@eslint/js": "^9.23.0",
- "@vitest/coverage-v8": "^3.1.1",
+ "@types/js-yaml": "^4.0.9",
"@types/node": "^22.15.3",
"@typescript-eslint/utils": "^8.29.0",
+ "@vitest/coverage-v8": "^3.1.1",
"@vitest/eslint-plugin": "^1.1.38",
"eslint": "^9.25.1",
"eslint-config-prettier": "^10.1.2",
"eslint-plugin-tsdoc": "^0.4.0",
- "typescript": "^5.8.3",
- "vite": "^6.3.4",
"globals": "^16.0.0",
"husky": "^9.1.7",
+ "js-yaml": "^4.1.0",
"lint-staged": "15.5.1",
"prettier": "^3.5.3",
"prettier-plugin-jsdoc": "^1.3.2",
"typedoc": "^0.28.3",
+ "typescript": "^5.8.3",
"typescript-eslint": "^8.31.1",
+ "vite": "^6.3.4",
"vitest": "^3.1.1"
},
"packageManager": "yarn@1.22.22"
diff --git a/scripts/code-samples.js b/scripts/code-samples.js
new file mode 100644
index 000000000..2eef7da3d
--- /dev/null
+++ b/scripts/code-samples.js
@@ -0,0 +1,17 @@
+import { argv } from "node:process";
+
+function throwInvalidArgs() {
+ throw new Error("expected `to-yaml` or `from-yaml` as arguments");
+}
+
+if (argv.length !== 3) {
+ throwInvalidArgs();
+}
+
+if (argv[2] === "to-yaml") {
+ await import("./code-samples/to-yaml.js");
+} else if (argv[2] === "from-yaml") {
+ await import("./code-samples/from-yaml.js");
+} else {
+ throwInvalidArgs();
+}
diff --git a/scripts/code-samples/from-yaml.js b/scripts/code-samples/from-yaml.js
new file mode 100644
index 000000000..97305c301
--- /dev/null
+++ b/scripts/code-samples/from-yaml.js
@@ -0,0 +1,50 @@
+import { writeFileSync, mkdirSync } from "node:fs";
+import {
+ generatedCodeSamplesDir,
+ iterateCodeSamples,
+ delimiter,
+} from "./shared.js";
+
+const headerImport = 'import { MeiliSearch } from "meilisearch";\n';
+const headerClientDeclaration =
+ 'const _client = new MeiliSearch({ host: "http://127.0.0.1:7700" });\n';
+const headerComment =
+ "// Code below this line will be written to code samples YAML file\n" +
+ delimiter +
+ "\n";
+
+const jsonFilesToGenerate = ["games", "movies", "meteorites"];
+
+try {
+ mkdirSync(generatedCodeSamplesDir);
+} catch (error) {
+ if (error.code !== "EEXIST") {
+ throw error;
+ }
+}
+
+for (const jsonFileToGenerate of jsonFilesToGenerate) {
+ writeFileSync(
+ new URL(jsonFileToGenerate + ".json", generatedCodeSamplesDir),
+ "[]",
+ );
+}
+
+for (const { sampleName, code } of iterateCodeSamples()) {
+ let header = "";
+
+ if (!code.includes('from "meilisearch";\n')) {
+ header += headerImport;
+ }
+
+ if (!code.includes("new MeiliSearch(")) {
+ header += headerClientDeclaration;
+ }
+
+ header += headerComment;
+
+ writeFileSync(
+ new URL(sampleName + ".ts", generatedCodeSamplesDir),
+ header + code + "\n",
+ );
+}
diff --git a/scripts/code-samples/shared.js b/scripts/code-samples/shared.js
new file mode 100644
index 000000000..dd5c0bc4a
--- /dev/null
+++ b/scripts/code-samples/shared.js
@@ -0,0 +1,37 @@
+import { readFileSync } from "node:fs";
+import { load } from "js-yaml";
+
+export const codeSamplesPath = new URL(
+ "../../.code-samples.meilisearch.yaml",
+ import.meta.url,
+);
+
+export const generatedCodeSamplesDir = new URL(
+ "../../generated-code-samples/",
+ import.meta.url,
+);
+
+export const delimiter = "// -~-~-~-~-";
+
+export function* iterateCodeSamples() {
+ const codeSamplesContents = readFileSync(codeSamplesPath);
+
+ const codeSamples = load(codeSamplesContents, {
+ filename: codeSamplesPath.href,
+ onWarning: console.warn,
+ });
+
+ if (codeSamples === null || typeof codeSamples !== "object") {
+ throw new Error("expected `codeSamples` to be an object", {
+ cause: codeSamples,
+ });
+ }
+
+ for (const [sampleName, code] of Object.entries(codeSamples)) {
+ if (typeof code !== "string") {
+ throw new Error("expected `code` to be a string", { cause: code });
+ }
+
+ yield { sampleName, code };
+ }
+}
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
new file mode 100644
index 000000000..81d0d51e8
--- /dev/null
+++ b/scripts/code-samples/to-yaml.js
@@ -0,0 +1,73 @@
+import { readFileSync, readdirSync, writeFileSync } from "node:fs";
+import { parse } from "node:path";
+import {
+ codeSamplesPath,
+ generatedCodeSamplesDir,
+ iterateCodeSamples,
+ delimiter,
+} from "./shared.js";
+
+const codeSampleNamesFromYaml = Array.from(
+ iterateCodeSamples(),
+ (v) => v.sampleName,
+);
+
+const dirEntries = readdirSync(generatedCodeSamplesDir, {
+ withFileTypes: true,
+});
+
+function throwError() {
+ throw new Error(
+ `expected generated code samples directory at ${generatedCodeSamplesDir.href} to only contain TypeScript and JSON files`,
+ { cause: dirEntries },
+ );
+}
+
+const serializedCodeSamples = dirEntries
+ .map((dirEnt) => {
+ if (!dirEnt.isFile()) {
+ throwError();
+ }
+
+ const { ext, name } = parse(dirEnt.name);
+ if (ext !== ".ts" && ext !== ".json") {
+ throwError();
+ }
+
+ if (ext === ".json") {
+ return null;
+ }
+
+ const codeSampleContent = readFileSync(dirEnt.parentPath + dirEnt.name, {
+ encoding: "utf-8",
+ });
+
+ const splitContent = codeSampleContent.split("\n");
+ const indexOfDelimiter = splitContent.findIndex((v) => v === delimiter);
+
+ const indentedContent = splitContent
+ .slice(indexOfDelimiter === -1 ? 0 : indexOfDelimiter + 1)
+ .map((v) => " " + v)
+ .join("\n")
+ .trimEnd();
+
+ return { name, indentedContent };
+ })
+ .filter((v) => v !== null)
+ .sort(({ name: nameA }, { name: nameB }) => {
+ const indexOfA = codeSampleNamesFromYaml.indexOf(nameA);
+ return indexOfA === -1
+ ? 1
+ : indexOfA - codeSampleNamesFromYaml.indexOf(nameB);
+ })
+ .map(({ name, indentedContent }) => name + ": |-\n" + indentedContent)
+ .join("\n");
+
+const header =
+ "# This code-samples file is used by the Meilisearch documentation\n" +
+ "# Every example written here will be automatically fetched by\n" +
+ "# the documentation on build\n" +
+ "# You can read more at https://github.com/meilisearch/documentation\n" +
+ "---\n";
+
+writeFileSync(codeSamplesPath, header + serializedCodeSamples + "\n");
diff --git a/tsconfig.json b/tsconfig.json
index 2c9559fc9..0bb66c7e7 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,6 +8,12 @@
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"resolveJsonModule": true,
"strict": true,
- "verbatimModuleSyntax": true
+ "verbatimModuleSyntax": true,
+ // For testing purposes
+ // TODO: Should use this for tests as well perhaps, resolve.alias
+ "paths": {
+ "meilisearch": ["./src/index.ts"],
+ "meilisearch/token": ["./src/token.ts"]
+ }
}
}
diff --git a/yarn.lock b/yarn.lock
index 827be91b8..3f010e7cc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -539,6 +539,11 @@
dependencies:
"@types/unist" "*"
+"@types/js-yaml@^4.0.9":
+ version "4.0.9"
+ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2"
+ integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==
+
"@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
From d80114794695dc402cec63114ba2776ce93bbd82 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Fri, 16 May 2025 18:50:11 +0300
Subject: [PATCH 02/13] Improvements, add workflow step
---
.../workflows/meilisearch-prototype-tests.yml | 2 +
.github/workflows/pre-release-tests.yml | 2 +
.github/workflows/tests.yml | 2 +
package.json | 2 +
scripts/code-samples.js | 14 ++-----
scripts/code-samples/from-yaml.js | 8 ++++
scripts/code-samples/to-yaml.js | 38 ++++++++++++++-----
7 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/.github/workflows/meilisearch-prototype-tests.yml b/.github/workflows/meilisearch-prototype-tests.yml
index b47e36c86..0f9558df6 100644
--- a/.github/workflows/meilisearch-prototype-tests.yml
+++ b/.github/workflows/meilisearch-prototype-tests.yml
@@ -57,6 +57,8 @@ jobs:
cache: yarn
- name: Install dependencies
run: yarn --dev
+ - name: Generate code sample files
+ run: yarn generate-code-sample-files
- name: Run tests
run: yarn test
- name: Build project
diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml
index 894b8e4c7..8249fb0a4 100644
--- a/.github/workflows/pre-release-tests.yml
+++ b/.github/workflows/pre-release-tests.yml
@@ -54,6 +54,8 @@ jobs:
cache: yarn
- name: Install dependencies
run: yarn --dev
+ - name: Generate code sample files
+ run: yarn generate-code-sample-files
- name: Run tests
run: yarn test
- name: Build project
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index a39efc546..be6ba5500 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -47,6 +47,8 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn --dev
+ - name: Generate code sample files
+ run: yarn generate-code-sample-files
- name: Run tests
run: yarn test
- name: Build project
diff --git a/package.json b/package.json
index 5b2cc9d5d..1036db879 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,8 @@
"test:env:nodejs": "yarn build && node tests/env/node/index.cjs && node tests/env/node/getting_started.cjs",
"test:env:esm": "yarn --cwd tests/env/esm && yarn --cwd tests/env/esm start",
"test:env:nitro-app": "yarn build && yarn --cwd tests/env/nitro-app test",
+ "generate-code-sample-files": "node scripts/code-samples.js from-yaml",
+ "generate-code-samples-yaml": "node scripts/code-samples.js to-yaml",
"fmt": "prettier -c ./**/*.{js,ts}",
"fmt:fix": "prettier -w ./**/*.{js,ts}",
"lint": "eslint",
diff --git a/scripts/code-samples.js b/scripts/code-samples.js
index 2eef7da3d..a1868e2bb 100644
--- a/scripts/code-samples.js
+++ b/scripts/code-samples.js
@@ -1,17 +1,11 @@
import { argv } from "node:process";
-function throwInvalidArgs() {
- throw new Error("expected `to-yaml` or `from-yaml` as arguments");
-}
-
-if (argv.length !== 3) {
- throwInvalidArgs();
-}
-
-if (argv[2] === "to-yaml") {
+if (argv[2] === "to-yaml" && argv.length === 3) {
await import("./code-samples/to-yaml.js");
} else if (argv[2] === "from-yaml") {
await import("./code-samples/from-yaml.js");
} else {
- throwInvalidArgs();
+ throw new Error(
+ "expected `to-yaml` (+ new code samples names) or `from-yaml` as arguments",
+ );
}
diff --git a/scripts/code-samples/from-yaml.js b/scripts/code-samples/from-yaml.js
index 97305c301..50bfb2056 100644
--- a/scripts/code-samples/from-yaml.js
+++ b/scripts/code-samples/from-yaml.js
@@ -1,3 +1,4 @@
+import { argv } from "node:process";
import { writeFileSync, mkdirSync } from "node:fs";
import {
generatedCodeSamplesDir,
@@ -48,3 +49,10 @@ for (const { sampleName, code } of iterateCodeSamples()) {
header + code + "\n",
);
}
+
+for (const sampleName of argv.slice(3)) {
+ writeFileSync(
+ new URL(sampleName + ".ts", generatedCodeSamplesDir),
+ headerImport + headerClientDeclaration + headerComment,
+ );
+}
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index 81d0d51e8..09418b8c4 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -1,4 +1,5 @@
-import { readFileSync, readdirSync, writeFileSync } from "node:fs";
+import { readdir } from "node:fs/promises";
+import { readFileSync, writeFileSync } from "node:fs";
import { parse } from "node:path";
import {
codeSamplesPath,
@@ -12,10 +13,24 @@ const codeSampleNamesFromYaml = Array.from(
(v) => v.sampleName,
);
-const dirEntries = readdirSync(generatedCodeSamplesDir, {
+/** @type {import("node:fs").Dirent[]} */
+const dirEntries = await readdir(generatedCodeSamplesDir, {
withFileTypes: true,
+}).catch((error) => {
+ if (error?.code !== "ENOENT") {
+ throw error;
+ }
+
+ return [];
});
+if (dirEntries.length === 0) {
+ throw new Error(
+ `there are no code sample files at ${generatedCodeSamplesDir.href}\n` +
+ "tip: first generate them from the YAML file, consult CONTRIBUTING.md on how to use this script",
+ );
+}
+
function throwError() {
throw new Error(
`expected generated code samples directory at ${generatedCodeSamplesDir.href} to only contain TypeScript and JSON files`,
@@ -23,7 +38,7 @@ function throwError() {
);
}
-const serializedCodeSamples = dirEntries
+const manipulatedCodeSamples = dirEntries
.map((dirEnt) => {
if (!dirEnt.isFile()) {
throwError();
@@ -51,15 +66,18 @@ const serializedCodeSamples = dirEntries
.join("\n")
.trimEnd();
- return { name, indentedContent };
+ const index = codeSampleNamesFromYaml.indexOf(name);
+
+ return { name, indentedContent, index };
})
.filter((v) => v !== null)
- .sort(({ name: nameA }, { name: nameB }) => {
- const indexOfA = codeSampleNamesFromYaml.indexOf(nameA);
- return indexOfA === -1
- ? 1
- : indexOfA - codeSampleNamesFromYaml.indexOf(nameB);
- })
+ .sort(({ index: indexA }, { index: indexB }) => indexA - indexB);
+
+while (manipulatedCodeSamples.at(0)?.index === -1) {
+ manipulatedCodeSamples.push(manipulatedCodeSamples.shift());
+}
+
+const serializedCodeSamples = manipulatedCodeSamples
.map(({ name, indentedContent }) => name + ": |-\n" + indentedContent)
.join("\n");
From e4dccddf1408099c10a7c56c1b685d49b7379d09 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Fri, 16 May 2025 19:00:17 +0300
Subject: [PATCH 03/13] Wrong workflows changed
---
.github/workflows/meilisearch-prototype-tests.yml | 2 --
.github/workflows/pre-release-tests.yml | 2 --
.github/workflows/tests.yml | 6 ++++--
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/meilisearch-prototype-tests.yml b/.github/workflows/meilisearch-prototype-tests.yml
index 0f9558df6..b47e36c86 100644
--- a/.github/workflows/meilisearch-prototype-tests.yml
+++ b/.github/workflows/meilisearch-prototype-tests.yml
@@ -57,8 +57,6 @@ jobs:
cache: yarn
- name: Install dependencies
run: yarn --dev
- - name: Generate code sample files
- run: yarn generate-code-sample-files
- name: Run tests
run: yarn test
- name: Build project
diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml
index 8249fb0a4..894b8e4c7 100644
--- a/.github/workflows/pre-release-tests.yml
+++ b/.github/workflows/pre-release-tests.yml
@@ -54,8 +54,6 @@ jobs:
cache: yarn
- name: Install dependencies
run: yarn --dev
- - name: Generate code sample files
- run: yarn generate-code-sample-files
- name: Run tests
run: yarn test
- name: Build project
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index be6ba5500..061fdebc0 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -47,8 +47,6 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn --dev
- - name: Generate code sample files
- run: yarn generate-code-sample-files
- name: Run tests
run: yarn test
- name: Build project
@@ -77,6 +75,8 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn --dev
+ - name: Generate code sample files
+ run: yarn generate-code-sample-files
- name: Run code style check
run: yarn style
- name: Run yaml style check
@@ -95,6 +95,8 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn --dev
+ - name: Generate code sample files
+ run: yarn generate-code-sample-files
- name: Build project
run: yarn build
- name: Run types check
From f8c398f05bd5e9ee6ca4c334c1a66dc9235c0740 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Fri, 16 May 2025 19:05:42 +0300
Subject: [PATCH 04/13] Fix trailing spaces problem
---
.code-samples.meilisearch.yaml | 30 +++++++++++++++---------------
scripts/code-samples/to-yaml.js | 2 +-
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 1c37ade72..ff64b0800 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -487,28 +487,28 @@ primary_field_guide_add_document_primary_key: |-
getting_started_add_documents: |-
// With npm:
// npm install meilisearch
-
+
// Or with yarn:
// yarn add meilisearch
-
+
// In your .js file:
import { MeiliSearch } from "meilisearch";
import movies from "./movies.json" with { type: "json" };
-
+
// With the `require` syntax:
// const { MeiliSearch } = require("meilisearch");
// const movies = require("./movies.json");
-
+
const client = new MeiliSearch({
host: "http://localhost:7700",
apiKey: "aSampleMasterKey",
});
-
+
const task = await client.index("movies").addDocuments(movies).waitTask();
console.log(task);
getting_started_search: |-
const response = await _client.index("movies").search("botman");
-
+
console.log(response);
getting_started_update_ranking_rules: |-
const _task = await _client
@@ -548,7 +548,7 @@ getting_started_update_displayed_attributes: |-
.waitTask();
getting_started_add_meteorites: |-
import meteorites from "./meteorites.json" with { type: "json" };
-
+
const _task = await _client
.index("meteorites")
.addDocuments(meteorites)
@@ -810,14 +810,14 @@ security_guide_search_key_1: |-
host: "http://localhost:7700",
apiKey: "apiKey",
});
-
+
const _response = await client.index("patient_medical_records").search();
security_guide_update_key_1: |-
const client = new MeiliSearch({
host: "http://localhost:7700",
apiKey: "masterKey",
});
-
+
const _key = await client.updateKey("74c9c733-3368-4738-bbe5-1d18a5fecb37", {
description: "Default Search API Key",
});
@@ -826,7 +826,7 @@ security_guide_create_key_1: |-
host: "http://localhost:7700",
apiKey: "masterKey",
});
-
+
await client.createKey({
description: "Search patient records key",
actions: ["search"],
@@ -840,13 +840,13 @@ security_guide_delete_key_1: |-
host: "http://localhost:7700",
apiKey: "masterKey",
});
-
+
await client.deleteKey("ac5cd97d-5a4b-4226-a868-2d0eb6d197ab");
authorization_header_1: |-
const _keys = await _client.getKeys();
tenant_token_guide_generate_sdk_1: |-
import { generateTenantToken } from "meilisearch/token";
-
+
const _token = await generateTenantToken({
apiKey: "B5KdX2MY2jV6EXfUs6scSfmC...",
apiKeyUid: "85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76",
@@ -858,7 +858,7 @@ tenant_token_guide_search_sdk_1: |-
host: "http://localhost:7700",
apiKey: "",
});
-
+
const _response = await frontEndClient
.index("patient_medical_records")
.search("blood test");
@@ -867,7 +867,7 @@ landing_getting_started_1: |-
host: "http://localhost:7700",
apiKey: "masterKey",
});
-
+
await client.index("movies").addDocuments([
{ id: 1, title: "Carol" },
{ id: 2, title: "Wonder Woman" },
@@ -876,7 +876,7 @@ landing_getting_started_1: |-
{ id: 5, title: "Moana" },
{ id: 6, title: "Philadelphia" },
]);
-
+
// be aware this client is using the masterKey, it should not be used in front end
const search = await client.index("movies").search("philodelphia");
console.log(search);
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index 09418b8c4..ad5b6bd28 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -62,7 +62,7 @@ const manipulatedCodeSamples = dirEntries
const indentedContent = splitContent
.slice(indexOfDelimiter === -1 ? 0 : indexOfDelimiter + 1)
- .map((v) => " " + v)
+ .map((v) => (v === "" ? v : " " + v))
.join("\n")
.trimEnd();
From f9a4286f37b756e6901a0743a7ffc46b79c80821 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Sat, 17 May 2025 09:53:45 +0300
Subject: [PATCH 05/13] Fix JSON formatting, add workflow format check, add
comments
---
.github/workflows/tests.yml | 3 +++
scripts/code-samples/from-yaml.js | 6 +++++-
scripts/code-samples/to-yaml.js | 4 ++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 061fdebc0..7d0571608 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -79,6 +79,9 @@ jobs:
run: yarn generate-code-sample-files
- name: Run code style check
run: yarn style
+ # https://github.com/prettier/prettier/issues/15438
+ - name: Check formatting of code samples
+ run: yarn prettier --ignore-path=.prettierignore -c generated-code-samples
- name: Run yaml style check
uses: ibiqlik/action-yamllint@v3
with:
diff --git a/scripts/code-samples/from-yaml.js b/scripts/code-samples/from-yaml.js
index 50bfb2056..e6e9c5285 100644
--- a/scripts/code-samples/from-yaml.js
+++ b/scripts/code-samples/from-yaml.js
@@ -24,20 +24,23 @@ try {
}
}
+// generate JSON files used by samples, so type check passes
for (const jsonFileToGenerate of jsonFilesToGenerate) {
writeFileSync(
new URL(jsonFileToGenerate + ".json", generatedCodeSamplesDir),
- "[]",
+ "[]\n",
);
}
for (const { sampleName, code } of iterateCodeSamples()) {
let header = "";
+ // generate import if there isn't already one
if (!code.includes('from "meilisearch";\n')) {
header += headerImport;
}
+ // generate client declaration if there isn't already one
if (!code.includes("new MeiliSearch(")) {
header += headerClientDeclaration;
}
@@ -50,6 +53,7 @@ for (const { sampleName, code } of iterateCodeSamples()) {
);
}
+// generate additional files from arguments passed
for (const sampleName of argv.slice(3)) {
writeFileSync(
new URL(sampleName + ".ts", generatedCodeSamplesDir),
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index ad5b6bd28..eee575730 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -61,11 +61,14 @@ const manipulatedCodeSamples = dirEntries
const indexOfDelimiter = splitContent.findIndex((v) => v === delimiter);
const indentedContent = splitContent
+ // get rid of code before delimiter
.slice(indexOfDelimiter === -1 ? 0 : indexOfDelimiter + 1)
+ // add padding
.map((v) => (v === "" ? v : " " + v))
.join("\n")
.trimEnd();
+ // get position in current code samples YAML file, to be able to order it the same way
const index = codeSampleNamesFromYaml.indexOf(name);
return { name, indentedContent, index };
@@ -73,6 +76,7 @@ const manipulatedCodeSamples = dirEntries
.filter((v) => v !== null)
.sort(({ index: indexA }, { index: indexB }) => indexA - indexB);
+// for every new code sample, place them at the end of the file instead of the start
while (manipulatedCodeSamples.at(0)?.index === -1) {
manipulatedCodeSamples.push(manipulatedCodeSamples.shift());
}
From ce84f373f155d6dc62be8f29c10335afa7f2a001 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Sun, 18 May 2025 21:51:04 +0300
Subject: [PATCH 06/13] Minor changes, update CONTRIBUTING.md
---
.github/workflows/tests.yml | 7 -------
CONTRIBUTING.md | 14 ++++++++++++++
package.json | 6 +++---
scripts/code-samples/from-yaml.js | 9 +++++++++
scripts/code-samples/to-yaml.js | 7 +++++--
5 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 7d0571608..a39efc546 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -75,13 +75,8 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn --dev
- - name: Generate code sample files
- run: yarn generate-code-sample-files
- name: Run code style check
run: yarn style
- # https://github.com/prettier/prettier/issues/15438
- - name: Check formatting of code samples
- run: yarn prettier --ignore-path=.prettierignore -c generated-code-samples
- name: Run yaml style check
uses: ibiqlik/action-yamllint@v3
with:
@@ -98,8 +93,6 @@ jobs:
cache: 'yarn'
- name: Install dependencies
run: yarn --dev
- - name: Generate code sample files
- run: yarn generate-code-sample-files
- name: Build project
run: yarn build
- name: Run types check
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index aea3406bf..701fd7cd4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -70,6 +70,20 @@ yarn style:fix
yarn build
```
+### Code samples
+
+In this repository code samples are linted and type checked. To achieve this we generate
+TypeScript files from `.code-samples.meilisearch.yaml`, and vice-versa.
+
+```bash
+# Generate files
+yarn generate-code-sample-files
+# Generate YAML file
+yarn generate-code-samples-yaml
+# For maintainers to generate new code samples
+yarn generate-code-sample-files new_sample_one new_sample_two
+```
+
## Git Guidelines
### Git Branches
diff --git a/package.json b/package.json
index 1036db879..03d9304e5 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
"build": "vite build && tsc -p tsconfig.build.json && vite --mode production-umd build",
"postbuild": "node scripts/build.js",
"test": "vitest run --coverage",
- "types": "tsc -p tsconfig.json --noEmit",
+ "types": "yarn generate-code-sample-files && tsc -p tsconfig.json --noEmit",
"types:watch": "yarn types --watch",
"test:env:browser": "yarn build && node scripts/copy-umd-file.js --to ./tests/env/express/public && yarn --cwd tests/env/express && yarn --cwd tests/env/express test",
"test:watch": "vitest watch",
@@ -61,8 +61,8 @@
"fmt:fix": "prettier -w ./**/*.{js,ts}",
"lint": "eslint",
"lint:fix": "eslint --fix",
- "style": "yarn fmt && yarn lint",
- "style:fix": "yarn fmt:fix && yarn lint:fix",
+ "style": "yarn generate-code-sample-files && prettier --ignore-path=.prettierignore -c generated-code-samples && yarn fmt && yarn lint",
+ "style:fix": "yarn generate-code-sample-files && prettier --ignore-path=.prettierignore -c generated-code-samples && yarn fmt:fix && yarn lint:fix",
"prepare": "husky"
},
"files": [
diff --git a/scripts/code-samples/from-yaml.js b/scripts/code-samples/from-yaml.js
index e6e9c5285..e80b53122 100644
--- a/scripts/code-samples/from-yaml.js
+++ b/scripts/code-samples/from-yaml.js
@@ -11,6 +11,7 @@ const headerClientDeclaration =
'const _client = new MeiliSearch({ host: "http://127.0.0.1:7700" });\n';
const headerComment =
"// Code below this line will be written to code samples YAML file\n" +
+ '// For more information consult CONTRIBUTING.md "Tests and Linter" section\n' +
delimiter +
"\n";
@@ -32,6 +33,8 @@ for (const jsonFileToGenerate of jsonFilesToGenerate) {
);
}
+let generatedFileTally = 0;
+
for (const { sampleName, code } of iterateCodeSamples()) {
let header = "";
@@ -51,6 +54,8 @@ for (const { sampleName, code } of iterateCodeSamples()) {
new URL(sampleName + ".ts", generatedCodeSamplesDir),
header + code + "\n",
);
+
+ generatedFileTally += 1;
}
// generate additional files from arguments passed
@@ -59,4 +64,8 @@ for (const sampleName of argv.slice(3)) {
new URL(sampleName + ".ts", generatedCodeSamplesDir),
headerImport + headerClientDeclaration + headerComment,
);
+
+ generatedFileTally += 1;
}
+
+console.log(`generated ${generatedFileTally} code sample file(s)`);
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index eee575730..c5ed957d5 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -86,10 +86,13 @@ const serializedCodeSamples = manipulatedCodeSamples
.join("\n");
const header =
- "# This code-samples file is used by the Meilisearch documentation\n" +
+ "# This code-samples file is used by the Meilisearch documentation.\n" +
"# Every example written here will be automatically fetched by\n" +
- "# the documentation on build\n" +
+ "# the documentation on build.\n" +
"# You can read more at https://github.com/meilisearch/documentation\n" +
+ '# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.' +
"---\n";
writeFileSync(codeSamplesPath, header + serializedCodeSamples + "\n");
+
+console.log(`generated ${manipulatedCodeSamples.length} code sample(s)`);
From 0e76d6d72dd784a01e0e8d513abdac3c85f51b29 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Sun, 18 May 2025 22:01:35 +0300
Subject: [PATCH 07/13] Update scripts/code-samples/to-yaml.js
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
---
scripts/code-samples/to-yaml.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index c5ed957d5..edf70281e 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -90,7 +90,7 @@ const header =
"# Every example written here will be automatically fetched by\n" +
"# the documentation on build.\n" +
"# You can read more at https://github.com/meilisearch/documentation\n" +
- '# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.' +
+ '# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.\n' +
"---\n";
writeFileSync(codeSamplesPath, header + serializedCodeSamples + "\n");
From cf9419f1d6587de29ab27fb341fb0d9cd5d158fb Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Sun, 18 May 2025 22:11:17 +0300
Subject: [PATCH 08/13] Minor changes
---
.code-samples.meilisearch.yaml | 9 ++++++---
scripts/code-samples/to-yaml.js | 5 +++--
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index ff64b0800..56769f1ac 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -1,7 +1,8 @@
-# This code-samples file is used by the Meilisearch documentation
+# This code-samples file is used by the Meilisearch documentation.
# Every example written here will be automatically fetched by
-# the documentation on build
+# the documentation on build.
# You can read more at https://github.com/meilisearch/documentation
+# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.
---
synonyms_guide_1: |-
const _task = await _client
@@ -41,7 +42,9 @@ create_an_index_1: |-
.createIndex("movies", { primaryKey: "id" })
.waitTask();
update_an_index_1: |-
- const _task = _client.updateIndex("movies", { primaryKey: "id" }).waitTask();
+ const _task = await _client
+ .updateIndex("movies", { primaryKey: "id" })
+ .waitTask();
delete_an_index_1: |-
const _task = await _client.deleteIndex("movies").waitTask();
swap_indexes_1: |-
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index c5ed957d5..b30d61218 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -90,8 +90,9 @@ const header =
"# Every example written here will be automatically fetched by\n" +
"# the documentation on build.\n" +
"# You can read more at https://github.com/meilisearch/documentation\n" +
- '# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.' +
- "---\n";
+ '# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.\n' +
+ ``;
+("---\n");
writeFileSync(codeSamplesPath, header + serializedCodeSamples + "\n");
From f303e2e8e6eddeb279613d1ea4cde952ee2ffc84 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Mon, 19 May 2025 11:14:42 +0300
Subject: [PATCH 09/13] Misc
---
scripts/code-samples/to-yaml.js | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index edf70281e..7c427c901 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -1,6 +1,6 @@
import { readdir } from "node:fs/promises";
import { readFileSync, writeFileSync } from "node:fs";
-import { parse } from "node:path";
+import { parse, join } from "node:path";
import {
codeSamplesPath,
generatedCodeSamplesDir,
@@ -53,9 +53,10 @@ const manipulatedCodeSamples = dirEntries
return null;
}
- const codeSampleContent = readFileSync(dirEnt.parentPath + dirEnt.name, {
- encoding: "utf-8",
- });
+ const codeSampleContent = readFileSync(
+ join(dirEnt.parentPath, dirEnt.name),
+ { encoding: "utf-8" },
+ );
const splitContent = codeSampleContent.split("\n");
const indexOfDelimiter = splitContent.findIndex((v) => v === delimiter);
From e147795986d641f484077dea838a6d11153f0c88 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Wed, 21 May 2025 11:16:00 +0300
Subject: [PATCH 10/13] Refactor and improve
---
.code-samples.meilisearch.yaml | 866 ++++++++++++------------------
scripts/code-samples/from-yaml.js | 25 +-
2 files changed, 359 insertions(+), 532 deletions(-)
diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 56769f1ac..70b9d81bc 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -5,119 +5,91 @@
# This file is generated, read more in CONTRIBUTING.md "Tests and Linter" section.
---
synonyms_guide_1: |-
- const _task = await _client
- .index("movies")
- .updateSynonyms({
- great: ["fantastic"],
- fantastic: ["great"],
- })
- .waitTask();
+ await client.index("movies").updateSynonyms({
+ great: ["fantastic"],
+ fantastic: ["great"],
+ });
date_guide_index_1: |-
import games from "./games.json" with { type: "json" };
- const _task = await _client.index("games").addDocuments(games).waitTask();
+ await client.index("games").addDocuments(games);
date_guide_filterable_attributes_1: |-
- const _task = await _client
- .index("games")
- .updateFilterableAttributes(["release_timestamp"])
- .waitTask();
+ await client.index("games").updateFilterableAttributes(["release_timestamp"]);
date_guide_filter_1: |-
- const _response = await _client.index("games").search("", {
+ await client.index("games").search("", {
filter: "release_timestamp >= 1514761200 AND release_timestamp < 1672527600",
});
date_guide_sortable_attributes_1: |-
- const _task = await _client
- .index("games")
- .updateSortableAttributes(["release_timestamp"])
- .waitTask();
+ await client.index("games").updateSortableAttributes(["release_timestamp"]);
date_guide_sort_1: |-
- const _response = await _client.index("games").search("", {
+ await client.index("games").search("", {
sort: ["release_timestamp:desc"],
});
get_one_index_1: |-
- const _index = await _client.index("movies").getRawInfo();
+ await client.index("movies").getRawInfo();
list_all_indexes_1: |-
- const _indexes = await _client.getIndexes({ limit: 3 });
+ await client.getIndexes({ limit: 3 });
create_an_index_1: |-
- const _task = await _client
- .createIndex("movies", { primaryKey: "id" })
- .waitTask();
+ await client.createIndex("movies", { primaryKey: "id" });
update_an_index_1: |-
- const _task = await _client
- .updateIndex("movies", { primaryKey: "id" })
- .waitTask();
+ await client.updateIndex("movies", { primaryKey: "id" });
delete_an_index_1: |-
- const _task = await _client.deleteIndex("movies").waitTask();
+ await client.deleteIndex("movies");
swap_indexes_1: |-
- const _task = await _client
- .swapIndexes([
- { indexes: ["indexA", "indexB"] },
- { indexes: ["indexX", "indexY"] },
- ])
- .waitTask();
+ await client.swapIndexes([
+ { indexes: ["indexA", "indexB"] },
+ { indexes: ["indexX", "indexY"] },
+ ]);
get_one_document_1: |-
- const _documents = await _client
+ await client
.index("movies")
.getDocument(25684, { fields: ["id", "title", "poster", "release_date"] });
get_documents_1: |-
- const _documents = await _client.index("movies").getDocuments({
+ await client.index("movies").getDocuments({
limit: 2,
filter: "genres = action",
});
get_documents_post_1: |-
- const _documents = await _client.index("books").getDocuments({
+ await client.index("books").getDocuments({
filter:
"(rating > 3 AND (genres = Adventure OR genres = Fiction)) AND language = English",
fields: ["title", "genres", "rating", "language"],
limit: 3,
});
add_or_replace_documents_1: |-
- const _task = await _client
- .index("movies")
- .addDocuments([
- {
- id: 287947,
- title: "Shazam",
- poster:
- "https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg",
- overview:
- "A boy is given the ability to become an adult superhero in times of need with a single magic word.",
- release_date: "2019-03-23",
- },
- ])
- .waitTask();
+ await client.index("movies").addDocuments([
+ {
+ id: 287947,
+ title: "Shazam",
+ poster: "https://image.tmdb.org/t/p/w1280/xnopI5Xtky18MPhK40cZAGAOVeV.jpg",
+ overview:
+ "A boy is given the ability to become an adult superhero in times of need with a single magic word.",
+ release_date: "2019-03-23",
+ },
+ ]);
add_or_update_documents_1: |-
- const _task = await _client
- .index("movies")
- .updateDocuments([
- {
- id: 287947,
- title: "Shazam ⚡️",
- genres: "comedy",
- },
- ])
- .waitTask();
+ await client.index("movies").updateDocuments([
+ {
+ id: 287947,
+ title: "Shazam ⚡️",
+ genres: "comedy",
+ },
+ ]);
delete_all_documents_1: |-
- const _task = await _client.index("movies").deleteAllDocuments().waitTask();
+ await client.index("movies").deleteAllDocuments();
delete_one_document_1: |-
- const _task = await _client.index("movies").deleteDocument(25684).waitTask();
+ await client.index("movies").deleteDocument(25684);
delete_documents_by_batch_1: |-
- const _task = await _client
- .index("movies")
- .deleteDocuments([23488, 153738, 437035, 363869])
- .waitTask();
+ await client.index("movies").deleteDocuments([23488, 153738, 437035, 363869]);
delete_documents_by_filter_1: |-
- const _task = await _client
- .index("movies")
- .deleteDocuments({
- filter: "genres = action OR genres = adventure",
- })
- .waitTask();
+ await client.index("movies").deleteDocuments({
+ filter: "genres = action OR genres = adventure",
+ });
search_post_1: |-
- const _response = await _client.index("movies").search("American ninja");
+ await client.index("movies").search("American ninja");
search_get_1: |-
- const _response = await _client.index("movies").searchGet("American ninja");
+ await client.index("movies").searchGet("American ninja");
multi_search_1: |-
- const _response = await _client.multiSearch({
+ await client.multiSearch({
queries: [
{
indexUid: "movies",
@@ -136,128 +108,119 @@ multi_search_1: |-
],
});
get_all_tasks_1: |-
- const _tasks = await _client.tasks.getTasks();
+ await client.tasks.getTasks();
get_task_1: |-
- const _task = await _client.tasks.getTask(1);
+ await client.tasks.getTask(1);
async_guide_filter_by_date_1: |-
- const _tasks = await _client.tasks.getTasks({
+ await client.tasks.getTasks({
afterEnqueuedAt: "2020-10-11T11:49:53.000Z",
});
async_guide_multiple_filters_1: |-
- const _tasks = await _client.tasks.getTasks({
+ await client.tasks.getTasks({
indexUids: ["movies"],
types: ["documentAdditionOrUpdate", "documentDeletion"],
statuses: ["processing"],
});
async_guide_filter_by_ids_1: |-
- const _tasks = await _client.tasks.getTasks({ uids: [5, 10, 13] });
+ await client.tasks.getTasks({ uids: [5, 10, 13] });
async_guide_filter_by_statuses_1: |-
- const _tasks = await _client.tasks.getTasks({
+ await client.tasks.getTasks({
statuses: ["failed", "canceled"],
});
async_guide_filter_by_types_1: |-
- const _tasks = await _client.tasks.getTasks({
+ await client.tasks.getTasks({
types: ["dumpCreation", "indexSwap"],
});
async_guide_filter_by_index_uids_1: |-
- const _tasks = await _client.tasks.getTasks({ indexUids: ["movies"] });
+ await client.tasks.getTasks({ indexUids: ["movies"] });
get_all_tasks_paginating_1: |-
- const _tasks = await _client.tasks.getTasks({ limit: 2, from: 10 });
+ await client.tasks.getTasks({ limit: 2, from: 10 });
get_all_tasks_paginating_2: |-
- const _tasks = await _client.tasks.getTasks({ limit: 2, from: 8 });
+ await client.tasks.getTasks({ limit: 2, from: 8 });
async_guide_canceled_by_1: |-
- const _tasks = await _client.tasks.getTasks({ canceledBy: [9, 15] });
+ await client.tasks.getTasks({ canceledBy: [9, 15] });
delete_tasks_1: |-
- const _task = await _client.tasks.deleteTasks({ uids: [1, 2] }).waitTask();
+ await client.tasks.deleteTasks({ uids: [1, 2] });
cancel_tasks_1: |-
- const _task = await _client.tasks.cancelTasks({ uids: [1, 2] }).waitTask();
+ await client.tasks.cancelTasks({ uids: [1, 2] });
get_one_key_1: |-
- const _key = await _client.getKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d");
+ await client.getKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d");
get_all_keys_1: |-
- const _keys = await _client.getKeys({ limit: 3 });
+ await client.getKeys({ limit: 3 });
create_a_key_1: |-
- const _key = await _client.createKey({
+ await client.createKey({
description: "Add documents: Products API key",
actions: ["documents.add"],
indexes: ["products"],
expiresAt: new Date("2021-11-13T00:00:00Z"),
});
update_a_key_1: |-
- const _key = await _client.updateKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d", {
+ await client.updateKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d", {
name: "Products/Reviews API key",
description: "Manage documents: Products/Reviews API key",
});
delete_a_key_1: |-
- await _client.deleteKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d");
+ await client.deleteKey("6062abda-a5aa-4414-ac91-ecd7944c0f8d");
get_settings_1: |-
- const _settings = await _client.index("movies").getSettings();
+ await client.index("movies").getSettings();
update_settings_1: |-
- const _task = await _client
- .index("movies")
- .updateSettings({
- rankingRules: [
- "words",
- "typo",
- "proximity",
- "attribute",
- "sort",
- "exactness",
- "release_date:desc",
- "rank:desc",
- ],
- distinctAttribute: "movie_id",
- searchableAttributes: ["title", "overview", "genres"],
- displayedAttributes: ["title", "overview", "genres", "release_date"],
- stopWords: ["the", "a", "an"],
- sortableAttributes: ["title", "release_date"],
- synonyms: {
- wolverine: ["xmen", "logan"],
- logan: ["wolverine"],
- },
- typoTolerance: {
- minWordSizeForTypos: {
- oneTypo: 8,
- twoTypos: 10,
- },
- disableOnAttributes: ["title"],
- },
- pagination: {
- maxTotalHits: 5000,
- },
- faceting: {
- maxValuesPerFacet: 200,
+ await client.index("movies").updateSettings({
+ rankingRules: [
+ "words",
+ "typo",
+ "proximity",
+ "attribute",
+ "sort",
+ "exactness",
+ "release_date:desc",
+ "rank:desc",
+ ],
+ distinctAttribute: "movie_id",
+ searchableAttributes: ["title", "overview", "genres"],
+ displayedAttributes: ["title", "overview", "genres", "release_date"],
+ stopWords: ["the", "a", "an"],
+ sortableAttributes: ["title", "release_date"],
+ synonyms: {
+ wolverine: ["xmen", "logan"],
+ logan: ["wolverine"],
+ },
+ typoTolerance: {
+ minWordSizeForTypos: {
+ oneTypo: 8,
+ twoTypos: 10,
},
- searchCutoffMs: 150,
- })
- .waitTask();
+ disableOnAttributes: ["title"],
+ },
+ pagination: {
+ maxTotalHits: 5000,
+ },
+ faceting: {
+ maxValuesPerFacet: 200,
+ },
+ searchCutoffMs: 150,
+ });
reset_settings_1: |-
- const _task = await _client.index("movies").resetSettings().waitTask();
+ await client.index("movies").resetSettings();
get_synonyms_1: |-
- const _synonyms = await _client.index("movies").getSynonyms();
+ await client.index("movies").getSynonyms();
update_synonyms_1: |-
- const _task = await _client
- .index("movies")
- .updateSynonyms({
- wolverine: ["xmen", "logan"],
- logan: ["wolverine", "xmen"],
- wow: ["world of warcraft"],
- })
- .waitTask();
+ await client.index("movies").updateSynonyms({
+ wolverine: ["xmen", "logan"],
+ logan: ["wolverine", "xmen"],
+ wow: ["world of warcraft"],
+ });
reset_synonyms_1: |-
- const _task = await _client.index("movies").resetSynonyms().waitTask();
+ await client.index("movies").resetSynonyms();
get_stop_words_1: |-
- const _stopWords = await _client.index("movies").getStopWords();
+ await client.index("movies").getStopWords();
update_stop_words_1: |-
- const _task = await _client
- .index("movies")
- .updateStopWords(["of", "the", "to"])
- .waitTask();
+ await client.index("movies").updateStopWords(["of", "the", "to"]);
reset_stop_words_1: |-
- const _task = await _client.index("movies").resetStopWords().waitTask();
+ await client.index("movies").resetStopWords();
get_ranking_rules_1: |-
- const _rankingRules = await _client.index("movies").getRankingRules();
+ await client.index("movies").getRankingRules();
update_ranking_rules_1: |-
- const _task = await _client
+ await client
.index("movies")
.updateRankingRules([
"words",
@@ -268,225 +231,180 @@ update_ranking_rules_1: |-
"exactness",
"release_date:asc",
"rank:desc",
- ])
- .waitTask();
+ ]);
reset_ranking_rules_1: |-
- const _task = await _client.index("movies").resetRankingRules().waitTask();
+ await client.index("movies").resetRankingRules();
get_distinct_attribute_1: |-
- const _distinctAttribute = await _client.index("shoes").getDistinctAttribute();
+ await client.index("shoes").getDistinctAttribute();
update_distinct_attribute_1: |-
- const _task = await _client
- .index("shoes")
- .updateDistinctAttribute("skuid")
- .waitTask();
+ await client.index("shoes").updateDistinctAttribute("skuid");
reset_distinct_attribute_1: |-
- const _task = await _client.index("shoes").resetDistinctAttribute().waitTask();
+ await client.index("shoes").resetDistinctAttribute();
get_searchable_attributes_1: |-
- const _searchableAttributes = await _client
- .index("movies")
- .getSearchableAttributes();
+ await client.index("movies").getSearchableAttributes();
update_searchable_attributes_1: |-
- const _task = await _client
+ await client
.index("movies")
- .updateSearchableAttributes(["title", "overview", "genres"])
- .waitTask();
+ .updateSearchableAttributes(["title", "overview", "genres"]);
reset_searchable_attributes_1: |-
- const _task = await _client
- .index("movies")
- .resetSearchableAttributes()
- .waitTask();
+ await client.index("movies").resetSearchableAttributes();
get_displayed_attributes_1: |-
- const _displayedAttributes = await _client
- .index("movies")
- .getDisplayedAttributes();
+ await client.index("movies").getDisplayedAttributes();
update_displayed_attributes_1: |-
- const _task = await _client
+ await client
.index("movies")
- .updateDisplayedAttributes(["title", "overview", "genres", "release_date"])
- .waitTask();
+ .updateDisplayedAttributes(["title", "overview", "genres", "release_date"]);
reset_displayed_attributes_1: |-
- const _task = await _client
- .index("movies")
- .resetDisplayedAttributes()
- .waitTask();
+ await client.index("movies").resetDisplayedAttributes();
get_typo_tolerance_1: |-
- const _typoTolerance = await _client.index("books").getTypoTolerance();
+ await client.index("books").getTypoTolerance();
update_typo_tolerance_1: |-
- const _task = await _client
- .index("books")
- .updateTypoTolerance({
- minWordSizeForTypos: {
- oneTypo: 4,
- twoTypos: 10,
- },
- disableOnAttributes: ["title"],
- })
- .waitTask();
+ await client.index("books").updateTypoTolerance({
+ minWordSizeForTypos: {
+ oneTypo: 4,
+ twoTypos: 10,
+ },
+ disableOnAttributes: ["title"],
+ });
reset_typo_tolerance_1: |-
- const _task = await _client.index("books").resetTypoTolerance().waitTask();
+ await client.index("books").resetTypoTolerance();
get_index_stats_1: |-
- const _indexStats = await _client.index("movies").getStats();
+ await client.index("movies").getStats();
get_indexes_stats_1: |-
- const _stats = await _client.getStats();
+ await client.getStats();
get_health_1: |-
- const _health = _client.health();
+ await client.health();
get_version_1: |-
- const _version = await _client.getVersion();
+ await client.getVersion();
distinct_attribute_guide_1: |-
- const _task = await _client
- .index("jackets")
- .updateDistinctAttribute("product_id")
- .waitTask();
+ await client.index("jackets").updateDistinctAttribute("product_id");
field_properties_guide_searchable_1: |-
- const _task = await _client
+ await client
.index("movies")
- .updateSearchableAttributes(["title", "overview", "genres"])
- .waitTask();
+ .updateSearchableAttributes(["title", "overview", "genres"]);
field_properties_guide_displayed_1: |-
- const _task = await _client
+ await client
.index("movies")
- .updateDisplayedAttributes(["title", "overview", "genres", "release_date"])
- .waitTask();
+ .updateDisplayedAttributes(["title", "overview", "genres", "release_date"]);
filtering_guide_1: |-
- const _response = await _client.index("movie_ratings").search("Avengers", {
+ await client.index("movie_ratings").search("Avengers", {
filter: "release_date > 795484800",
});
filtering_guide_2: |-
- const _response = await _client.index("movie_ratings").search("Batman", {
+ await client.index("movie_ratings").search("Batman", {
filter:
'release_date > 795484800 AND (director = "Tim Burton" OR director = "Christopher Nolan")',
});
filtering_guide_3: |-
- const _response = await _client
- .index("movie_ratings")
- .search("Planet of the Apes", {
- filter: 'release_date > 1577884550 AND (NOT director = "Tim Burton")',
- });
+ await client.index("movie_ratings").search("Planet of the Apes", {
+ filter: 'release_date > 1577884550 AND (NOT director = "Tim Burton")',
+ });
filtering_guide_nested_1: |-
- const _response = await _client.index("movie_ratings").search("thriller", {
+ await client.index("movie_ratings").search("thriller", {
filter: "rating.users >= 90",
});
search_parameter_guide_query_1: |-
- const _response = await _client.index("movies").search("shifu");
+ await client.index("movies").search("shifu");
search_parameter_guide_offset_1: |-
- const _response = await _client.index("movies").search("shifu", {
+ await client.index("movies").search("shifu", {
offset: 1,
});
search_parameter_guide_limit_1: |-
- const _response = await _client.index("movies").search("shifu", {
+ await client.index("movies").search("shifu", {
limit: 2,
});
search_parameter_guide_retrieve_1: |-
- const _response = await _client.index("movies").search("shifu", {
+ await client.index("movies").search("shifu", {
attributesToRetrieve: ["overview", "title"],
});
search_parameter_guide_crop_1: |-
- const _response = await _client.index("movies").search("shifu", {
+ await client.index("movies").search("shifu", {
attributesToCrop: ["overview"],
cropLength: 5,
});
search_parameter_guide_crop_marker_1: |-
- const _response = await _client.index("movies").search("shifu", {
+ await client.index("movies").search("shifu", {
attributesToCrop: ["overview"],
cropMarker: "[…]",
});
search_parameter_guide_highlight_1: |-
- const _response = await _client.index("movies").search("winter feast", {
+ await client.index("movies").search("winter feast", {
attributesToHighlight: ["overview"],
});
search_parameter_guide_highlight_tag_1: |-
- const _response = await _client.index("movies").search("winter feast", {
+ await client.index("movies").search("winter feast", {
attributesToHighlight: ["overview"],
highlightPreTag: '',
highlightPostTag: "",
});
search_parameter_guide_show_matches_position_1: |-
- const _response = await _client.index("movies").search("winter feast", {
+ await client.index("movies").search("winter feast", {
showMatchesPosition: true,
});
search_parameter_guide_matching_strategy_1: |-
- const _response = await _client.index("movies").search("big fat liar", {
+ await client.index("movies").search("big fat liar", {
matchingStrategy: "last",
});
search_parameter_guide_matching_strategy_2: |-
- const _response = await _client.index("movies").search("big fat liar", {
+ await client.index("movies").search("big fat liar", {
matchingStrategy: "all",
});
search_parameter_guide_hitsperpage_1: |-
- const _response = await _client.index("movies").search("", {
+ await client.index("movies").search("", {
hitsPerPage: 15,
});
search_parameter_guide_page_1: |-
- const _response = await _client.index("movies").search("", {
+ await client.index("movies").search("", {
page: 2,
});
search_parameter_guide_show_ranking_score_1: |-
- const _response = await _client.index("movies").search("dragon", {
+ await client.index("movies").search("dragon", {
showRankingScore: true,
});
search_parameter_guide_attributes_to_search_on_1: |-
- const _response = await _client.index("movies").search("adventure", {
+ await client.index("movies").search("adventure", {
attributesToSearchOn: ["overview"],
});
typo_tolerance_guide_1: |-
- const _task = await _client
- .index("movies")
- .updateTypoTolerance({
- enabled: false,
- })
- .waitTask();
+ await client.index("movies").updateTypoTolerance({
+ enabled: false,
+ });
typo_tolerance_guide_2: |-
- const _task = await _client
- .index("movies")
- .updateTypoTolerance({
- disableOnAttributes: ["title"],
- })
- .waitTask();
+ await client.index("movies").updateTypoTolerance({
+ disableOnAttributes: ["title"],
+ });
typo_tolerance_guide_3: |-
- const _task = await _client
- .index("movies")
- .updateTypoTolerance({
- disableOnWords: ["shrek"],
- })
- .waitTask();
+ await client.index("movies").updateTypoTolerance({
+ disableOnWords: ["shrek"],
+ });
typo_tolerance_guide_4: |-
- const _task = await _client
- .index("movies")
- .updateTypoTolerance({
- minWordSizeForTypos: {
- oneTypo: 4,
- twoTypos: 10,
- },
- })
- .waitTask();
+ await client.index("movies").updateTypoTolerance({
+ minWordSizeForTypos: {
+ oneTypo: 4,
+ twoTypos: 10,
+ },
+ });
add_movies_json_1: |-
import movies from "./movies.json" with { type: "json" };
- const task = await _client.index("movies").addDocuments(movies).waitTask();
+ const task = await client.index("movies").addDocuments(movies);
console.log(task);
primary_field_guide_update_document_primary_key: |-
- const _task = await _client
- .updateIndex("books", { primaryKey: "title" })
- .waitTask();
+ await client.updateIndex("books", { primaryKey: "title" });
primary_field_guide_create_index_primary_key: |-
- const _task = await _client
- .createIndex("books", { primaryKey: "reference_number" })
- .waitTask();
+ await client.createIndex("books", { primaryKey: "reference_number" });
primary_field_guide_add_document_primary_key: |-
- const _task = await _client
- .index("books")
- .addDocuments(
- [
- {
- reference_number: 287947,
- title: "Diary of a Wimpy Kid",
- author: "Jeff Kinney",
- genres: ["comedy", "humor"],
- price: 5.0,
- },
- ],
- { primaryKey: "reference_number" },
- )
- .waitTask();
+ await client.index("books").addDocuments(
+ [
+ {
+ reference_number: 287947,
+ title: "Diary of a Wimpy Kid",
+ author: "Jeff Kinney",
+ genres: ["comedy", "humor"],
+ price: 5.0,
+ },
+ ],
+ { primaryKey: "reference_number" },
+ );
getting_started_add_documents: |-
// With npm:
// npm install meilisearch
@@ -507,14 +425,14 @@ getting_started_add_documents: |-
apiKey: "aSampleMasterKey",
});
- const task = await client.index("movies").addDocuments(movies).waitTask();
+ const task = await client.index("movies").addDocuments(movies);
console.log(task);
getting_started_search: |-
- const response = await _client.index("movies").search("botman");
+ const response = await client.index("movies").search("botman");
console.log(response);
getting_started_update_ranking_rules: |-
- const _task = await _client
+ await client
.index("movies")
.updateRankingRules([
"exactness",
@@ -525,145 +443,103 @@ getting_started_update_ranking_rules: |-
"sort",
"release_date:asc",
"rank:desc",
- ])
- .waitTask();
+ ]);
getting_started_update_searchable_attributes: |-
- const _task = await _client
- .index("movies")
- .updateSearchableAttributes(["title"])
- .waitTask();
+ await client.index("movies").updateSearchableAttributes(["title"]);
getting_started_update_stop_words: |-
- const _task = await _client.index("movies").updateStopWords(["the"]).waitTask();
+ await client.index("movies").updateStopWords(["the"]);
getting_started_check_task_status: |-
- const _task = await _client.tasks.getTask(0);
+ await client.tasks.getTask(0);
getting_started_synonyms: |-
- const _task = await _client
- .index("movies")
- .updateSynonyms({
- winnie: ["piglet"],
- piglet: ["winnie"],
- })
- .waitTask();
+ await client.index("movies").updateSynonyms({
+ winnie: ["piglet"],
+ piglet: ["winnie"],
+ });
getting_started_update_displayed_attributes: |-
- const _task = await _client
+ await client
.index("movies")
- .updateDisplayedAttributes(["title", "overview", "poster"])
- .waitTask();
+ .updateDisplayedAttributes(["title", "overview", "poster"]);
getting_started_add_meteorites: |-
import meteorites from "./meteorites.json" with { type: "json" };
- const _task = await _client
- .index("meteorites")
- .addDocuments(meteorites)
- .waitTask();
+ await client.index("meteorites").addDocuments(meteorites);
getting_started_configure_settings: |-
- const _task = await _client
- .index("meteorites")
- .updateSettings({
- filterableAttributes: ["mass", "_geo"],
- sortableAttributes: ["mass", "_geo"],
- })
- .waitTask();
+ await client.index("meteorites").updateSettings({
+ filterableAttributes: ["mass", "_geo"],
+ sortableAttributes: ["mass", "_geo"],
+ });
getting_started_geo_radius: |-
- const _response = await _client
+ await client
.index("meteorites")
.search("", { filter: "_geoRadius(46.9480, 7.4474, 210000)" });
getting_started_geo_point: |-
- const _response = await _client
+ await client
.index("meteorites")
.search("", { sort: ["_geoPoint(48.8583701, 2.2922926):asc"] });
getting_started_sorting: |-
- const _response = await _client.index("meteorites").search("", {
+ await client.index("meteorites").search("", {
sort: ["mass:asc"],
filter: "mass < 200",
});
getting_started_faceting: |-
- const _task = await _client
- .index("movies")
- .updateFaceting({
- maxValuesPerFacet: 2,
- sortFacetValuesBy: {
- "*": "count",
- },
- })
- .waitTask();
+ await client.index("movies").updateFaceting({
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {
+ "*": "count",
+ },
+ });
getting_started_typo_tolerance: |-
- const _task = await _client
- .index("movies")
- .updateTypoTolerance({
- minWordSizeForTypos: {
- oneTypo: 4,
- },
- })
- .waitTask();
+ await client.index("movies").updateTypoTolerance({
+ minWordSizeForTypos: {
+ oneTypo: 4,
+ },
+ });
getting_started_filtering: |-
- const _response = await _client
- .index("meteorites")
- .search("", { filter: "mass < 200" });
+ await client.index("meteorites").search("", { filter: "mass < 200" });
getting_started_pagination: |-
- const _task = await _client
- .index("movies")
- .updatePagination({ maxTotalHits: 500 })
- .waitTask();
+ await client.index("movies").updatePagination({ maxTotalHits: 500 });
get_filterable_attributes_1: |-
- const _filterableAttributes = await _client
- .index("movies")
- .getFilterableAttributes();
+ await client.index("movies").getFilterableAttributes();
update_filterable_attributes_1: |-
- const _task = await _client
- .index("movies")
- .updateFilterableAttributes([
- "genres",
- {
- attributePatterns: ["genre"],
- features: {
- facetSearch: true,
- filter: { equality: true, comparison: false },
- },
+ await client.index("movies").updateFilterableAttributes([
+ "genres",
+ {
+ attributePatterns: ["genre"],
+ features: {
+ facetSearch: true,
+ filter: { equality: true, comparison: false },
},
- ])
- .waitTask();
+ },
+ ]);
reset_filterable_attributes_1: |-
- const _task = await _client
- .index("movies")
- .resetFilterableAttributes()
- .waitTask();
+ await client.index("movies").resetFilterableAttributes();
filtering_update_settings_1: |-
- const _task = await _client
- .index("movies")
- .updateFilterableAttributes(["director", "genres"])
- .waitTask();
+ await client.index("movies").updateFilterableAttributes(["director", "genres"]);
faceted_search_walkthrough_filter_1: |-
- const _response = await _client.index("movies").search("thriller", {
+ await client.index("movies").search("thriller", {
filter: [
["genres = Horror", "genres = Mystery"],
'director = "Jordan Peele"',
],
});
faceted_search_update_settings_1: |-
- const _task = await _client
+ await client
.index("movie_ratings")
- .updateFilterableAttributes(["genres", "rating", "language"])
- .waitTask();
+ .updateFilterableAttributes(["genres", "rating", "language"]);
faceted_search_1: |-
- const _response = await _client
+ await client
.index("books")
.search("classic", { facets: ["genres", "rating", "language"] });
post_dump_1: |-
- const _task = await _client.createDump().waitTask();
+ await client.createDump();
create_snapshot_1: |-
- const _task = await _client.createSnapshot().waitTask();
+ await client.createSnapshot();
phrase_search_1: |-
- const _response = await _client
- .index("movies")
- .search('"african american" horror');
+ await client.index("movies").search('"african american" horror');
sorting_guide_update_sortable_attributes_1: |-
- const _task = await _client
- .index("books")
- .updateSortableAttributes(["author", "price"])
- .waitTask();
+ await client.index("books").updateSortableAttributes(["author", "price"]);
sorting_guide_update_ranking_rules_1: |-
- const _task = await _client
+ await client
.index("books")
.updateRankingRules([
"words",
@@ -672,140 +548,105 @@ sorting_guide_update_ranking_rules_1: |-
"proximity",
"attribute",
"exactness",
- ])
- .waitTask();
+ ]);
sorting_guide_sort_parameter_1: |-
- const _response = await _client.index("books").search("science fiction", {
+ await client.index("books").search("science fiction", {
sort: ["price:asc"],
});
sorting_guide_sort_parameter_2: |-
- const _response = await _client.index("books").search("butler", {
+ await client.index("books").search("butler", {
sort: ["author:desc"],
});
sorting_guide_sort_nested_1: |-
- const _response = await _client.index("books").search("science fiction", {
+ await client.index("books").search("science fiction", {
sort: ["rating.users:asc"],
});
get_sortable_attributes_1: |-
- const _sortableAttributes = await _client
- .index("books")
- .getSortableAttributes();
+ await client.index("books").getSortableAttributes();
update_sortable_attributes_1: |-
- const _task = await _client
- .index("books")
- .updateSortableAttributes(["price", "author"])
- .waitTask();
+ await client.index("books").updateSortableAttributes(["price", "author"]);
reset_sortable_attributes_1: |-
- const _task = await _client.index("books").resetSortableAttributes().waitTask();
+ await client.index("books").resetSortableAttributes();
get_pagination_settings_1: |-
- const _pagination = await _client.index("books").getPagination();
+ await client.index("books").getPagination();
update_pagination_settings_1: |-
- const _task = await _client
+ await client
.index("books")
- .updateSettings({ pagination: { maxTotalHits: 100 } })
- .waitTask();
+ .updateSettings({ pagination: { maxTotalHits: 100 } });
reset_pagination_settings_1: |-
- const _task = await _client.index("books").resetPagination().waitTask();
+ await client.index("books").resetPagination();
get_faceting_settings_1: |-
- const _faceting = await _client.index("books").getFaceting();
+ await client.index("books").getFaceting();
update_faceting_settings_1: |-
- const _task = await _client
- .index("books")
- .updateFaceting({
- maxValuesPerFacet: 2,
- sortFacetValuesBy: {
- "*": "alpha",
- genres: "count",
- },
- })
- .waitTask();
+ await client.index("books").updateFaceting({
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {
+ "*": "alpha",
+ genres: "count",
+ },
+ });
reset_faceting_settings_1: |-
- const _task = await _client.index("books").resetFaceting().waitTask();
+ await client.index("books").resetFaceting();
get_dictionary_1: |-
- const _dictionary = await _client.index("books").getDictionary();
+ await client.index("books").getDictionary();
update_dictionary_1: |-
- const _task = await _client
- .index("books")
- .updateDictionary(["J. R. R.", "W. E. B."])
- .waitTask();
+ await client.index("books").updateDictionary(["J. R. R.", "W. E. B."]);
reset_dictionary_1: |-
- const _task = await _client.index("books").resetDictionary().waitTask();
+ await client.index("books").resetDictionary();
search_parameter_guide_sort_1: |-
- const _response = await _client.index("books").search("science fiction", {
+ await client.index("books").search("science fiction", {
sort: ["price:asc"],
});
get_separator_tokens_1: |-
- const _separatorTokens = await _client.index("books").getSeparatorTokens();
+ await client.index("books").getSeparatorTokens();
update_separator_tokens_1: |-
- const _task = await _client
- .index("books")
- .updateSeparatorTokens(["|", "…"])
- .waitTask();
+ await client.index("books").updateSeparatorTokens(["|", "…"]);
reset_separator_tokens_1: |-
- const _task = await _client.index("books").resetSeparatorTokens().waitTask();
+ await client.index("books").resetSeparatorTokens();
get_non_separator_tokens_1: |-
- const _nonSeparatorTokens = await _client
- .index("books")
- .getNonSeparatorTokens();
+ await client.index("books").getNonSeparatorTokens();
update_non_separator_tokens_1: |-
- const _task = await _client
- .index("books")
- .updateNonSeparatorTokens(["@", "#"])
- .waitTask();
+ await client.index("books").updateNonSeparatorTokens(["@", "#"]);
reset_non_separator_tokens_1: |-
- const _task = await _client.index("books").resetNonSeparatorTokens().waitTask();
+ await client.index("books").resetNonSeparatorTokens();
get_proximity_precision_settings_1: |-
- const _proximityPrecision = await _client
- .index("books")
- .getProximityPrecision();
+ await client.index("books").getProximityPrecision();
update_proximity_precision_settings_1: |-
- const _task = await _client
- .index("books")
- .updateProximityPrecision("byAttribute")
- .waitTask();
+ await client.index("books").updateProximityPrecision("byAttribute");
reset_proximity_precision_settings_1: |-
- const _task = await _client.index("books").resetProximityPrecision().waitTask();
+ await client.index("books").resetProximityPrecision();
get_search_cutoff_1: |-
- const _searchCutoffMs = await _client.index("movies").getSearchCutoffMs();
+ await client.index("movies").getSearchCutoffMs();
update_search_cutoff_1: |-
- const _task = await _client
- .index("movies")
- .updateSearchCutoffMs(150)
- .waitTask();
+ await client.index("movies").updateSearchCutoffMs(150);
reset_search_cutoff_1: |-
- const _task = await _client.index("movies").resetSearchCutoffMs().waitTask();
+ await client.index("movies").resetSearchCutoffMs();
search_parameter_guide_facet_stats_1: |-
- const _response = await _client
+ await client
.index("movie_ratings")
.search("Batman", { facets: ["genres", "rating"] });
geosearch_guide_filter_settings_1: |-
- const _task = await _client
- .index("restaurants")
- .updateFilterableAttributes(["_geo"])
- .waitTask();
+ await client.index("restaurants").updateFilterableAttributes(["_geo"]);
geosearch_guide_filter_usage_1: |-
- const _response = await _client.index("restaurants").search("", {
+ await client.index("restaurants").search("", {
filter: ["_geoRadius(45.472735, 9.184019, 2000)"],
});
geosearch_guide_filter_usage_2: |-
- const _response = await _client.index("restaurants").search("", {
+ await client.index("restaurants").search("", {
filter: ["_geoRadius(45.472735, 9.184019, 2000) AND type = pizza"],
});
geosearch_guide_filter_usage_3: |-
- const _response = await _client.index("restaurants").search("", {
+ await client.index("restaurants").search("", {
filter: ["_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])"],
});
geosearch_guide_sort_settings_1: |-
- const _task = await _client
- .index("restaurants")
- .updateSortableAttributes(["_geo"])
- .waitTask();
+ await client.index("restaurants").updateSortableAttributes(["_geo"]);
geosearch_guide_sort_usage_1: |-
- const _response = await _client.index("restaurants").search("", {
+ await client.index("restaurants").search("", {
sort: ["_geoPoint(48.8561446, 2.2978204):asc"],
});
geosearch_guide_sort_usage_2: |-
- const _response = await _client.index("restaurants").search("", {
+ await client.index("restaurants").search("", {
sort: ["_geoPoint(48.8561446, 2.2978204):asc", "rating:desc"],
});
security_guide_search_key_1: |-
@@ -814,14 +655,14 @@ security_guide_search_key_1: |-
apiKey: "apiKey",
});
- const _response = await client.index("patient_medical_records").search();
+ await client.index("patient_medical_records").search();
security_guide_update_key_1: |-
const client = new MeiliSearch({
host: "http://localhost:7700",
apiKey: "masterKey",
});
- const _key = await client.updateKey("74c9c733-3368-4738-bbe5-1d18a5fecb37", {
+ await client.updateKey("74c9c733-3368-4738-bbe5-1d18a5fecb37", {
description: "Default Search API Key",
});
security_guide_create_key_1: |-
@@ -837,7 +678,7 @@ security_guide_create_key_1: |-
expiresAt: new Date("2023-01-01T00:00:00Z"),
});
security_guide_list_keys_1: |-
- const _keys = await _client.getKeys();
+ await client.getKeys();
security_guide_delete_key_1: |-
const client = new MeiliSearch({
host: "http://localhost:7700",
@@ -846,11 +687,11 @@ security_guide_delete_key_1: |-
await client.deleteKey("ac5cd97d-5a4b-4226-a868-2d0eb6d197ab");
authorization_header_1: |-
- const _keys = await _client.getKeys();
+ await client.getKeys();
tenant_token_guide_generate_sdk_1: |-
import { generateTenantToken } from "meilisearch/token";
- const _token = await generateTenantToken({
+ await generateTenantToken({
apiKey: "B5KdX2MY2jV6EXfUs6scSfmC...",
apiKeyUid: "85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76",
searchRules: { patient_medical_records: { filter: "user_id = 1" } },
@@ -862,9 +703,7 @@ tenant_token_guide_search_sdk_1: |-
apiKey: "",
});
- const _response = await frontEndClient
- .index("patient_medical_records")
- .search("blood test");
+ await frontEndClient.index("patient_medical_records").search("blood test");
landing_getting_started_1: |-
const client = new MeiliSearch({
host: "http://localhost:7700",
@@ -884,74 +723,68 @@ landing_getting_started_1: |-
const search = await client.index("movies").search("philodelphia");
console.log(search);
facet_search_1: |-
- const _response = await _client.index("books").searchForFacetValues({
+ await client.index("books").searchForFacetValues({
facetQuery: "fiction",
facetName: "genres",
filter: "rating > 3",
});
facet_search_2: |-
- const _task = await _client
- .index("books")
- .updateFaceting({
- sortFacetValuesBy: {
- genres: "count",
- },
- })
- .waitTask();
+ await client.index("books").updateFaceting({
+ sortFacetValuesBy: {
+ genres: "count",
+ },
+ });
facet_search_3: |-
- const _response = await _client.index("books").searchForFacetValues({
+ await client.index("books").searchForFacetValues({
facetQuery: "c",
facetName: "genres",
});
search_parameter_guide_show_ranking_score_details_1: |-
- const _response = await _client
+ await client
.index("movies")
.search("dragon", { showRankingScoreDetails: true });
negative_search_1: |-
- const _response = await _client.index("movies").search("-escape");
+ await client.index("movies").search("-escape");
negative_search_2: |-
- const _response = await _client.index("movies").search('-"escape"');
+ await client.index("movies").search('-"escape"');
search_parameter_reference_ranking_score_threshold_1: |-
- const _response = await _client
+ await client
.index("INDEX_NAME")
.search("badman", { rankingScoreThreshold: 0.2 });
search_parameter_reference_retrieve_vectors_1: |-
- const _response = await _client.index("INDEX_NAME").search("kitchen utensils", {
+ await client.index("INDEX_NAME").search("kitchen utensils", {
retrieveVectors: true,
hybrid: {
embedder: "EMBEDDER_NAME",
},
});
search_parameter_guide_hybrid_1: |-
- const _response = await _client.index("INDEX_NAME").search("kitchen utensils", {
+ await client.index("INDEX_NAME").search("kitchen utensils", {
hybrid: {
semanticRatio: 0.9,
embedder: "EMBEDDER_NAME",
},
});
get_similar_post_1: |-
- const _response = await _client
+ await client
.index("INDEX_NAME")
.searchSimilarDocuments({ id: "TARGET_DOCUMENT_ID", embedder: "default" });
search_parameter_guide_matching_strategy_3: |-
- const _response = await _client.index("movies").search("white shirt", {
+ await client.index("movies").search("white shirt", {
matchingStrategy: "frequency",
});
search_parameter_reference_distinct_1: |-
- const _response = await _client
+ await client
.index("INDEX_NAME")
.search("QUERY TERMS", { distinct: "ATTRIBUTE_A" });
distinct_attribute_guide_filterable_1: |-
- const _task = await _client
+ await client
.index("products")
- .updateFilterableAttributes(["product_id", "sku", "url"])
- .waitTask();
+ .updateFilterableAttributes(["product_id", "sku", "url"]);
distinct_attribute_guide_distinct_parameter_1: |-
- const _response = await _client
- .index("products")
- .search("white shirt", { distinct: "sku" });
+ await client.index("products").search("white shirt", { distinct: "sku" });
multi_search_federated_1: |-
- const _response = await _client.multiSearch({
+ await client.multiSearch({
federation: {},
queries: [
{
@@ -965,57 +798,42 @@ multi_search_federated_1: |-
],
});
search_parameter_reference_locales_1: |-
- const _response = await _client
+ await client
.index("INDEX_NAME")
.search("QUERY TEXT IN JAPANESE", { locales: ["jpn"] });
get_localized_attribute_settings_1: |-
- const _localizedAttributes = await _client
- .index("INDEX_NAME")
- .getLocalizedAttributes();
+ await client.index("INDEX_NAME").getLocalizedAttributes();
update_localized_attribute_settings_1: |-
- const _task = await _client
+ await client
.index("INDEX_NAME")
.updateLocalizedAttributes([
{ attributePatterns: ["*_ja"], locales: ["jpn"] },
- ])
- .waitTask();
+ ]);
reset_localized_attribute_settings_1: |-
- const _task = await _client
- .index("INDEX_NAME")
- .resetLocalizedAttributes()
- .waitTask();
+ await client.index("INDEX_NAME").resetLocalizedAttributes();
get_facet_search_settings_1: |-
- const _facetSearch = await _client.index("INDEX_NAME").getFacetSearch();
+ await client.index("INDEX_NAME").getFacetSearch();
update_facet_search_settings_1: |-
- const _task = await _client
- .index("INDEX_NAME")
- .updateFacetSearch(false)
- .waitTask();
+ await client.index("INDEX_NAME").updateFacetSearch(false);
reset_facet_search_settings_1: |-
- const _task = await _client.index("INDEX_NAME").resetFacetSearch().waitTask();
+ await client.index("INDEX_NAME").resetFacetSearch();
get_prefix_search_settings_1: |-
- const _prefixSearch = await _client.index("INDEX_NAME").getPrefixSearch();
+ await client.index("INDEX_NAME").getPrefixSearch();
update_prefix_search_settings_1: |-
- const _task = await _client
- .index("INDEX_NAME")
- .updatePrefixSearch("disabled")
- .waitTask();
+ await client.index("INDEX_NAME").updatePrefixSearch("disabled");
reset_prefix_search_settings_1: |-
- const _task = await _client.index("INDEX_NAME").resetPrefixSearch().waitTask();
+ await client.index("INDEX_NAME").resetPrefixSearch();
get_all_batches_1: |-
- const _batches = await _client.batches.getBatches();
+ await client.batches.getBatches();
get_batch_1: |-
- const _batch = await _client.batches.getBatch(123);
+ await client.batches.getBatch(123);
update_embedders_1: |-
- const _task = await _client
- .index("INDEX_NAME")
- .updateEmbedders({
- default: {
- source: "openAi",
- apiKey: "OPEN_AI_API_KEY",
- model: "text-embedding-3-small",
- documentTemplate:
- "A document titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}",
- },
- })
- .waitTask();
+ await client.index("INDEX_NAME").updateEmbedders({
+ default: {
+ source: "openAi",
+ apiKey: "OPEN_AI_API_KEY",
+ model: "text-embedding-3-small",
+ documentTemplate:
+ "A document titled '{{doc.title}}' whose description starts with {{doc.overview|truncatewords: 20}}",
+ },
+ });
diff --git a/scripts/code-samples/from-yaml.js b/scripts/code-samples/from-yaml.js
index e80b53122..5adc76fa2 100644
--- a/scripts/code-samples/from-yaml.js
+++ b/scripts/code-samples/from-yaml.js
@@ -8,7 +8,7 @@ import {
const headerImport = 'import { MeiliSearch } from "meilisearch";\n';
const headerClientDeclaration =
- 'const _client = new MeiliSearch({ host: "http://127.0.0.1:7700" });\n';
+ 'const client = new MeiliSearch({ host: "http://127.0.0.1:7700" });\n';
const headerComment =
"// Code below this line will be written to code samples YAML file\n" +
'// For more information consult CONTRIBUTING.md "Tests and Linter" section\n' +
@@ -33,19 +33,28 @@ for (const jsonFileToGenerate of jsonFilesToGenerate) {
);
}
+const clientVarRegExp = /(?<=const|let ).+(?= = new MeiliSearch\()/;
+
let generatedFileTally = 0;
for (const { sampleName, code } of iterateCodeSamples()) {
let header = "";
- // generate import if there isn't already one
- if (!code.includes('from "meilisearch";\n')) {
- header += headerImport;
- }
+ const clientVarMatch = code.match(clientVarRegExp);
+ const clientVarLiteral = clientVarMatch?.[0] ?? "client";
+ const clientVarUsageRegExp = new RegExp(`${clientVarLiteral}\\s*\\.`);
+
+ // if there is client usage in the code sample
+ if (clientVarUsageRegExp.test(code)) {
+ // generate import if there isn't already one
+ if (!code.includes('from "meilisearch";\n')) {
+ header += headerImport;
+ }
- // generate client declaration if there isn't already one
- if (!code.includes("new MeiliSearch(")) {
- header += headerClientDeclaration;
+ // generate client declaration if there isn't already one
+ if (clientVarMatch === null) {
+ header += headerClientDeclaration;
+ }
}
header += headerComment;
From f44d8c055e69eadcc99b6abf23e1bd6fb5f03b0f Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Thu, 29 May 2025 14:57:53 +0300
Subject: [PATCH 11/13] Fix bugs, improve error messages and docs
---
CONTRIBUTING.md | 8 ++++++--
scripts/code-samples/shared.js | 32 +++++++++++++++++++++++++++-----
scripts/code-samples/to-yaml.js | 6 ++++--
3 files changed, 37 insertions(+), 9 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 701fd7cd4..892d62024 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,8 +72,12 @@ yarn build
### Code samples
-In this repository code samples are linted and type checked. To achieve this we generate
-TypeScript files from `.code-samples.meilisearch.yaml`, and vice-versa.
+In this repository code samples are linted and type checked. To achieve this we
+generate TypeScript files from `.code-samples.meilisearch.yaml`, and vice-versa.
+
+> [!WARNING]
+>
+> Each of these commands overwrite their target files, so use them carefully.
```bash
# Generate files
diff --git a/scripts/code-samples/shared.js b/scripts/code-samples/shared.js
index dd5c0bc4a..922e4f3bb 100644
--- a/scripts/code-samples/shared.js
+++ b/scripts/code-samples/shared.js
@@ -14,22 +14,44 @@ export const generatedCodeSamplesDir = new URL(
export const delimiter = "// -~-~-~-~-";
export function* iterateCodeSamples() {
- const codeSamplesContents = readFileSync(codeSamplesPath);
+ let codeSamplesContents;
+ try {
+ codeSamplesContents = readFileSync(codeSamplesPath, {
+ encoding: "utf-8",
+ });
+ } catch (error) {
+ if (error?.code !== "ENOENT") {
+ throw error;
+ }
+
+ return;
+ }
const codeSamples = load(codeSamplesContents, {
filename: codeSamplesPath.href,
onWarning: console.warn,
});
+ // YAML file is empty
+ if (codeSamples === undefined) {
+ return;
+ }
+
if (codeSamples === null || typeof codeSamples !== "object") {
- throw new Error("expected `codeSamples` to be an object", {
- cause: codeSamples,
- });
+ throw new Error(
+ `expected YAML contents to be of type \`Record\`; got ${String(codeSamples)}`,
+ {
+ cause: codeSamples,
+ },
+ );
}
for (const [sampleName, code] of Object.entries(codeSamples)) {
if (typeof code !== "string") {
- throw new Error("expected `code` to be a string", { cause: code });
+ throw new Error(
+ `expected YAML contents to be of type \`Record\`; at ${sampleName} got ${String(code)}`,
+ { cause: code },
+ );
}
yield { sampleName, code };
diff --git a/scripts/code-samples/to-yaml.js b/scripts/code-samples/to-yaml.js
index 7c427c901..03be665c9 100644
--- a/scripts/code-samples/to-yaml.js
+++ b/scripts/code-samples/to-yaml.js
@@ -78,8 +78,10 @@ const manipulatedCodeSamples = dirEntries
.sort(({ index: indexA }, { index: indexB }) => indexA - indexB);
// for every new code sample, place them at the end of the file instead of the start
-while (manipulatedCodeSamples.at(0)?.index === -1) {
- manipulatedCodeSamples.push(manipulatedCodeSamples.shift());
+if (manipulatedCodeSamples.some((v) => v.index !== -1)) {
+ while (manipulatedCodeSamples.at(0)?.index === -1) {
+ manipulatedCodeSamples.push(manipulatedCodeSamples.shift());
+ }
}
const serializedCodeSamples = manipulatedCodeSamples
From d7d11c842d300f44d4e9cf3d8fe70ed3e46a185e Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Thu, 29 May 2025 15:02:51 +0300
Subject: [PATCH 12/13] Misc
---
CONTRIBUTING.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 892d62024..f28f8844b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -72,8 +72,9 @@ yarn build
### Code samples
-In this repository code samples are linted and type checked. To achieve this we
-generate TypeScript files from `.code-samples.meilisearch.yaml`, and vice-versa.
+In this repository, code samples are linted and type-checked. To achieve this,
+we generate TypeScript files from `.code-samples.meilisearch.yaml` and vice
+versa.
> [!WARNING]
>
From 3f980f430892b2dc859b8ede24963ec1d00f4d90 Mon Sep 17 00:00:00 2001
From: "F. Levi" <55688616+flevi29@users.noreply.github.com>
Date: Thu, 29 May 2025 18:53:20 +0300
Subject: [PATCH 13/13] Update CONTRIBUTING.md
---
CONTRIBUTING.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f28f8844b..071853847 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -81,11 +81,11 @@ versa.
> Each of these commands overwrite their target files, so use them carefully.
```bash
-# Generate files
+# Generate all the code sample files from YAML file
yarn generate-code-sample-files
-# Generate YAML file
+# Generate YAML file from all the code sample files
yarn generate-code-samples-yaml
-# For maintainers to generate new code samples
+# Generate all + new code sample files from YAML file
yarn generate-code-sample-files new_sample_one new_sample_two
```