diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 8af0f27..db106fe 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -2,76 +2,25 @@
# Every example written here will be automatically fetched by
# the documentation and the landing page on build
---
-search_parameter_guide_show_ranking_score_1: |-
- await client.index('movies').search('dragon', SearchQuery(showRankingScore: true));
-facet_search_1: |-
- await client.index('books').facetSearch(FacetSearchQuery(
- facetQuery: 'fiction',
- facetName: 'genres',
- filter: 'rating > 3'
- ),
- );
-facet_search_2: |-
- await client.index('books').updateFaceting(Faceting(sortFacetValuesBy: {'genres': 'count'}));
-facet_search_3: |-
- await client.index('books').facetSearch(FacetSearchQuery(
- facetQuery: 'c',
- facetName: 'genres',
- ),
- );
-search_parameter_guide_attributes_to_search_on_1: |-
- await client.index('movies').search('adventure', SearchQuery(attributesToSearchOn: ['overview']));
-get_documents_post_1: |-
- await client.index('movies').getDocuments(
- params: DocumentsQuery(
- filter: '(rating > 3 AND (genres = Adventure OR genres = Fiction)) AND language = English',
- fields: ['title', 'genres', 'rating', 'language'],
- limit: 3
- )
- );
-delete_documents_by_filter_1: |-
- await client.index('movies')
- .deleteDocuments(DeleteDocumentsQuery(filter: 'genres = action OR genres = adventure'));
-get_documents_1: |-
- await client.index('movies')
- .getDocuments(params: DocumentsQuery(limit: 2, filter: 'genres = action'));
-multi_search_1: |-
- await client.multiSearch(MultiSearchQuery(queries: [
- IndexSearchQuery(
- query: 'pooh',
- indexUid: 'movies',
- limit: 5
- ),
- IndexSearchQuery(
- query: 'nemo',
- indexUid: 'movies',
- limit: 5
- ),
- IndexSearchQuery(
- query: 'us',
- indexUid: 'movies_ratings'
- ),
- ]));
-faceted_search_update_settings_1: |-
- await client.index('movie_ratings').updateFilterableAttributes(['genres', 'rating', 'language']);
-search_parameter_guide_facet_stats_1: |-
- await client.index('movie_ratings').search('Batman', SearchQuery(facets: ['genres', 'rating']));
-faceted_search_1: |-
- await client.index('books').search('', SearchQuery(facets: ['genres', 'rating', 'language']));
-filtering_guide_nested_1: |-
- await client.index('movie_ratings').search('thriller', SearchQuery(filter: 'rating.users >= 90'));
-sorting_guide_sort_nested_1: |-
- await client.index('movie_ratings').search('thriller', SearchQuery(sort: ['rating.users:asc']));
-async_guide_filter_by_date_1: |-
- await client.getTasks(params: TasksQuery(afterEnqueuedAt: DateTime(2020, 10, 11, 11, 49, 53)));
-async_guide_multiple_filters_1: |-
- await client.getTasks(params: TasksQuery(indexUids: ['movies'], types: ['documentAdditionOrUpdate','documentDeletion'], statuses: ['processing']));
-async_guide_filter_by_ids_1: |-
- await client.getTasks(params: TasksQuery(uids: [5, 10, 13]));
-async_guide_filter_by_statuses_1: |-
- await client.getTasks(params: TasksQuery(statuses: ['failed', 'canceled']));
-async_guide_filter_by_types_1: |-
- await client.getTasks(params: TasksQuery(types: ['dumpCreation', 'indexSwap']));
+search_parameter_guide_show_ranking_score_1: "await client\n .index('movies')\n .search('dragon', SearchQuery(showRankingScore: true));"
+facet_search_1: "await client.index('books').facetSearch(\n FacetSearchQuery(\n facetQuery: 'fiction',\n facetName: 'genres',\n filter: 'rating > 3',\n ),\n );"
+facet_search_2: "await client.index('books').updateFaceting(\n Faceting(\n sortFacetValuesBy: {\n 'genres': FacetingSortTypes.count,\n },\n ),\n );"
+facet_search_3: "await client.index('books').facetSearch(\n FacetSearchQuery(\n facetQuery: 'c',\n facetName: 'genres',\n ),\n );"
+search_parameter_guide_attributes_to_search_on_1: "await client.index('books').facetSearch(\n FacetSearchQuery(\n facetQuery: 'c',\n facetName: 'genres',\n ),\n );"
+get_documents_post_1: "await client.index('movies').getDocuments(\n params: DocumentsQuery(\n filterExpression: Meili.and([\n 'language'.toMeiliAttribute().eq('English'.toMeiliValue()),\n Meili.and([\n 'rating'.toMeiliAttribute().gt(3.toMeiliValue()),\n Meili.or([\n 'genres'.toMeiliAttribute().eq('Adventure'.toMeiliValue()),\n 'genres'.toMeiliAttribute().eq('Fiction'.toMeiliValue()),\n ]),\n ]),\n ]),\n fields: ['title', 'genres', 'rating', 'language'],\n limit: 3,\n ),\n );"
+delete_documents_by_filter_1: "await client.index('movies').deleteDocuments(\n DeleteDocumentsQuery(\n filterExpression: Meili.or([\n Meili.attr('genres').eq(Meili.value('action')),\n Meili.attr('genres').eq(Meili.value('adventure')),\n ]),\n ),\n );"
+get_documents_1: "await client.index('movies').getDocuments(\n params: DocumentsQuery(\n limit: 2,\n filter: Meili.attr('genres').eq('action'.toMeiliValue()),\n ),\n );"
+multi_search_1: "await client.multiSearch(MultiSearchQuery(queries: [\n IndexSearchQuery(query: 'pooh', indexUid: 'movies', limit: 5),\n IndexSearchQuery(query: 'nemo', indexUid: 'movies', limit: 5),\n IndexSearchQuery(query: 'us', indexUid: 'movies_ratings'),\n]));"
+faceted_search_update_settings_1: "await client\n .index('movie_ratings')\n .updateFilterableAttributes(['genres', 'rating', 'language']);"
+search_parameter_guide_facet_stats_1: "await client\n .index('movie_ratings')\n .search('Batman', SearchQuery(facets: ['genres', 'rating']));"
+faceted_search_1: "await client\n .index('books')\n .search('', SearchQuery(facets: ['genres', 'rating', 'language']));"
+filtering_guide_nested_1: "await client.index('movie_ratings').search(\n 'thriller',\n SearchQuery(\n filterExpression: Meili.gte(\n \/\/or Meili.attr('rating.users')\n \/\/or 'rating.users'.toMeiliAttribute()\n Meili.attrFromParts(['rating', 'users']),\n Meili.value(90),\n ),\n ),\n );"
+sorting_guide_sort_nested_1: "await client\n .index('movie_ratings')\n .search('thriller', SearchQuery(sort: ['rating.users:asc']));"
+async_guide_filter_by_date_1: "await client.getTasks(\n params: TasksQuery(\n afterEnqueuedAt: DateTime(2020, 10, 11, 11, 49, 53),\n ),\n);"
+async_guide_multiple_filters_1: "await client.getTasks(\n params: TasksQuery(\n indexUids: ['movies'],\n types: ['documentAdditionOrUpdate', 'documentDeletion'],\n statuses: ['processing'],\n ),\n);"
+async_guide_filter_by_ids_1: "await client.getTasks(\n params: TasksQuery(\n uids: [5, 10, 13],\n ),\n);"
+async_guide_filter_by_statuses_1: "await client.getTasks(\n params: TasksQuery(\n statuses: ['failed', 'canceled'],\n ),\n);"
+async_guide_filter_by_types_1: "await client.getTasks(\n params: TasksQuery(\n types: ['dumpCreation', 'indexSwap'],\n ),\n);"
async_guide_filter_by_index_uids_1: |-
await client.getTasks(params: TasksQuery(indexUids: ['movies']));
delete_tasks_1: |-
@@ -80,48 +29,27 @@ cancel_tasks_1: |-
await client.cancelTasks(params: CancelTasksQuery(uids: [1, 2]));
async_guide_canceled_by_1: |-
await client.getTasks(params: TasksQuery(canceledBy: [9, 15]));
-swap_indexes_1: |-
- await client.swapIndexes([SwapIndex(['indexA', 'indexB']), SwapIndex(['indexX', 'indexY'])]);
-search_parameter_guide_hitsperpage_1: |-
- await client.index('movies').search('', SearchQuery(hitsPerPage: 15)) as PaginatedSearchResult;
-search_parameter_guide_page_1: |-
- await client.index('movies').search('', SearchQuery(page: 2)) as PaginatedSearchResult;
-synonyms_guide_1: |-
- await client.index('movies').updateSynonyms({
- 'great': ['fantastic'],
- 'fantastic': ['great']
- });
-date_guide_index_1: |-
- import 'dart:io';
- import 'dart:convert';
-
- final json = await File('games.json').readAsString();
-
- await client.index('games').addDocumentsJson(json);
-date_guide_filterable_attributes_1: |-
- await client.index('games').updateFilterableAttributes(['release_timestamp']);
-date_guide_filter_1: |-
- await client.index('games').search('',
- SearchQuery(filter:
- 'release_timestamp >= 1514761200 AND release_timestamp < 1672527600'));
-date_guide_sortable_attributes_1: |-
- await client.index('games').updateSortableAttributes(['release_timestamp']);
-date_guide_sort_1: |-
- await client.index('games').search('', SearchQuery(sort: ['release_timestamp:desc']));
+swap_indexes_1: "await client.swapIndexes([\n SwapIndex(['indexA', 'indexB']),\n SwapIndex(['indexX', 'indexY']),\n]);"
+search_parameter_guide_hitsperpage_1: "await client\n .index('movies')\n .search('', SearchQuery(hitsPerPage: 15))\n .asPaginatedResult();"
+search_parameter_guide_page_1: "await client\n .index('movies')\n .search('', SearchQuery(page: 2))\n .asPaginatedResult();"
+synonyms_guide_1: "await client.index('movies').updateSynonyms({\n 'great': ['fantastic'],\n 'fantastic': ['great'],\n});"
+date_guide_index_1: "\/\/import 'dart:io';\n\/\/import 'dart:convert';\nfinal json = await File('games.json').readAsString();\nawait client.index('games').addDocumentsJson(json);"
+date_guide_filterable_attributes_1: "await client\n .index('games')\n .updateFilterableAttributes(['release_timestamp']);"
+date_guide_filter_1: "await client.index('games').search(\n '',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.gte(\n 'release_timestamp'.toMeiliAttribute(),\n Meili.value(DateTime(2017, 12, 31, 23, 0)),\n ),\n Meili.lt(\n 'release_timestamp'.toMeiliAttribute(),\n Meili.value(DateTime(2022, 12, 31, 23, 0)),\n ),\n ]),\n ),\n );"
+date_guide_sortable_attributes_1: "await client\n .index('games')\n .updateSortableAttributes(['release_timestamp']);"
+date_guide_sort_1: "await client\n .index('games')\n .search('', SearchQuery(sort: ['release_timestamp:desc']));"
get_all_tasks_paginating_1: |-
await client.getTasks(params: TasksQuery(limit: 2, from: 10));
get_all_tasks_paginating_2: |-
await client.getTasks(params: TasksQuery(limit: 2, from: 8));
get_pagination_settings_1: |-
await client.index('movies').getPagination();
-update_pagination_settings_1: |-
- await client.index('books').updatePagination(Pagination(maxTotalHits: 100));
+update_pagination_settings_1: "await client\n .index('books')\n .updatePagination(Pagination(maxTotalHits: 100));"
reset_pagination_settings_1: |-
await client.index('movies').resetPagination();
get_faceting_settings_1: |-
await client.index('movies').getFaceting();
-update_faceting_settings_1: |-
- await client.index('books').updateFaceting(Faceting(maxValuesPerFacet: 2, sortFacetValuesBy: {'*': 'alpha', 'genres': 'count'}));
+update_faceting_settings_1: "await client.index('books').updateFaceting(Faceting(\n maxValuesPerFacet: 2,\n sortFacetValuesBy: {\n '*': FacetingSortTypes.alpha,\n 'genres': FacetingSortTypes.count\n }));"
reset_faceting_settings_1: |-
await client.index('movies').resetFaceting();
get_one_index_1: |-
@@ -134,8 +62,7 @@ update_an_index_1: |-
await client.index('movies').update(primaryKey: 'id');
delete_an_index_1: |-
await client.index('movies').delete();
-get_one_document_1: |-
- await client.index('movies').getDocument(25684, fields: ['id', 'title', 'poster', 'release_date']);
+get_one_document_1: "await client.index('movies').getDocument(25684,\n fields: ['id', 'title', 'poster', 'release_date']);"
add_or_replace_documents_1: |-
await client.index('movies').addDocuments([
{
@@ -148,21 +75,12 @@ add_or_replace_documents_1: |-
'release_date': '2019-03-23'
}
]);
-add_or_update_documents_1: |-
- await client.index('movies').updateDocuments([
- {
- 'id': 287947,
- 'title': 'Shazam ⚡️',
- 'genres': 'comedy'
- }
- ]);
+add_or_update_documents_1: "await client.index('movies').updateDocuments([\n {\n 'id': 287947,\n 'title': 'Shazam ⚡️',\n 'genres': 'comedy',\n }\n]);"
delete_all_documents_1: |-
await client.index('movies').deleteAllDocuments();
delete_one_document_1: |-
await client.index('movies').deleteDocument(25684);
-delete_documents_by_batch_1: |-
- await client.index('movies')
- .deleteDocuments(DeleteDocumentsQuery(ids: [23488, 153738, 437035, 363869]));
+delete_documents_by_batch_1: "await client.index('movies').deleteDocuments(\n DeleteDocumentsQuery(\n ids: [23488, 153738, 437035, 363869],\n ),\n );"
search_post_1: |-
await client.index('movies').search('American ninja');
get_task_1: |-
@@ -171,40 +89,12 @@ get_all_tasks_1: |-
await client.getTasks();
get_settings_1: |-
await client.index('movies').getSettings();
-update_settings_1: |-
- await client.index('movies').updateSettings(IndexSettings(
- 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'],
- },
- ));
+update_settings_1: "await client.index('movies').updateSettings(\n IndexSettings(\n rankingRules: [\n 'words',\n 'typo',\n 'proximity',\n 'attribute',\n 'sort',\n 'exactness',\n 'release_date:desc',\n 'rank:desc'\n ],\n distinctAttribute: 'movie_id',\n searchableAttributes: ['title', 'overview', 'genres'],\n displayedAttributes: [\n 'title',\n 'overview',\n 'genres',\n 'release_date'\n ],\n stopWords: ['the', 'a', 'an'],\n sortableAttributes: ['title', 'release_date'],\n synonyms: {\n 'wolverine': ['xmen', 'logan'],\n 'logan': ['wolverine'],\n },\n ),\n );"
reset_settings_1: |-
await client.index('movies').resetSettings();
get_synonyms_1: |-
await client.index('movies').getSynonyms();
-update_synonyms_1: |-
- await client.index('movies').updateSynonyms(
- {
- 'wolverine': ['xmen', 'logan'],
- 'logan': ['wolverine', 'xmen'],
- 'wow': ['world of warcraft']
- }
- );
+update_synonyms_1: "await client.index('movies').updateSynonyms({\n 'wolverine': ['xmen', 'logan'],\n 'logan': ['wolverine', 'xmen'],\n 'wow': ['world of warcraft'],\n});"
reset_synonyms_1: |-
await client.index('movies').resetSynonyms();
get_stop_words_1: |-
@@ -215,17 +105,7 @@ reset_stop_words_1: |-
await client.index('movies').resetStopWords();
get_ranking_rules_1: |-
await client.index('movies').getRankingRules();
-update_ranking_rules_1: |-
- await client.index('movies').updateRankingRules([
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'exactness',
- 'release_date:asc',
- 'rank:desc'
- ]);
+update_ranking_rules_1: "await client.index('movies').updateRankingRules([\n 'words',\n 'typo',\n 'proximity',\n 'attribute',\n 'sort',\n 'exactness',\n 'release_date:asc',\n 'rank:desc',\n]);"
reset_ranking_rules_1: |-
await client.index('movies').resetRankingRules();
get_distinct_attribute_1: |-
@@ -236,32 +116,17 @@ reset_distinct_attribute_1: |-
await client.index('shoes').resetDistinctAttribute();
get_filterable_attributes_1: |-
await client.index('movies').getFilterableAttributes();
-update_filterable_attributes_1: |-
- await client.index('movies').updateFilterableAttributes([
- 'genres',
- 'director'
- ]);
+update_filterable_attributes_1: "await client\n .index('movies')\n .updateFilterableAttributes(['genres', 'director']);"
reset_filterable_attributes_1: |-
await client.index('movies').resetFilterableAttributes();
get_searchable_attributes_1: |-
await client.index('movies').getSearchableAttributes();
-update_searchable_attributes_1: |-
- await client.index('movies').updateSearchableAttributes([
- 'title',
- 'overview',
- 'genres'
- ]);
+update_searchable_attributes_1: "await client\n .index('movies')\n .updateSearchableAttributes(['title', 'overview', 'genres']);"
reset_searchable_attributes_1: |-
await client.index('movies').resetSearchableAttributes();
get_displayed_attributes_1: |-
await client.index('movies').getDisplayedAttributes();
-update_displayed_attributes_1: |-
- await client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'genres',
- 'release_date'
- ]);
+update_displayed_attributes_1: "await client.index('movies').updateDisplayedAttributes([\n 'title',\n 'overview',\n 'genres',\n 'release_date',\n]);"
reset_displayed_attributes_1: |-
await client.index('movies').resetDisplayedAttributes();
get_typo_tolerance_1: |-
@@ -287,54 +152,24 @@ get_version_1: |-
await client.getVersion();
distinct_attribute_guide_1: |-
await client.index('jackets').updateDistinctAttribute('product_id');
-field_properties_guide_searchable_1: |-
- await client.index('movies').updateSearchableAttributes(['title', 'overview', 'genres']);
-field_properties_guide_displayed_1: |-
- await client.index('movies').updateDisplayedAttributes(['title', 'overview', 'genres', 'release_date']);
-filtering_guide_1: |-
- await client
- .index('movie_ratings')
- .search('Avengers', SearchQuery(filter: 'release_date > 795484800'));
-filtering_guide_2: |-
- await client.index('movie_ratings')
- .search('Batman',
- SearchQuery(filter: 'release_date > 795484800 AND (director = "Tim Burton" OR director = "Christopher Nolan")'
- )
- );
-filtering_guide_3: |-
- await client.index('movie_ratings').search('Planet of the Apes',
- SearchQuery(filter: 'release_date > 1577884550 AND (NOT director = "Tim Burton")'));
+field_properties_guide_searchable_1: "await client\n .index('movies')\n .updateSearchableAttributes(['title', 'overview', 'genres']);"
+field_properties_guide_displayed_1: "await client.index('movies').updateDisplayedAttributes([\n 'title',\n 'overview',\n 'genres',\n 'release_date',\n]);"
+filtering_guide_1: "await client.index('movie_ratings').search(\n 'Avengers',\n SearchQuery(\n filterExpression: Meili.gt(\n Meili.attr('release_date'),\n DateTime.utc(1995, 3, 18).toMeiliValue(),\n ),\n ),\n );"
+filtering_guide_2: "await client.index('movie_ratings').search(\n 'Batman',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.attr('release_date')\n .gt(DateTime.utc(1995, 3, 18).toMeiliValue()),\n Meili.or([\n 'director'.toMeiliAttribute().eq('Tim Burton'.toMeiliValue()),\n 'director'\n .toMeiliAttribute()\n .eq('Christopher Nolan'.toMeiliValue()),\n ]),\n ]),\n ),\n );"
+filtering_guide_3: "await client.index('movie_ratings').search(\n 'Planet of the Apes',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.attr('release_date')\n .gt(DateTime.utc(2020, 1, 1, 13, 15, 50).toMeiliValue()),\n Meili.not(\n Meili.attr('director').eq(\"Tim Burton\".toMeiliValue()),\n ),\n ]),\n ),\n );"
search_parameter_guide_query_1: |-
await client.index('movies').search('shifu');
search_parameter_guide_offset_1: |-
await client.index('movies').search('shifu', SearchQuery(offset: 1));
search_parameter_guide_limit_1: |-
await client.index('movies').search('shifu', SearchQuery(limit: 2));
-search_parameter_guide_matching_strategy_1: |-
- await client.index('movies').search('big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.last));
-search_parameter_guide_matching_strategy_2: |-
- await client.index('movies').search('big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.all));
-search_parameter_guide_retrieve_1: |-
- await client
- .index('movies')
- .search('shifu', SearchQuery(attributesToRetrieve: ['overview', 'title']));
-search_parameter_guide_crop_1: |-
- await client
- .index('movies')
- .search('shifu', SearchQuery(attributesToCrop: ['overview'], cropLength: 5));
-search_parameter_guide_highlight_1: |-
- await client
- .index('movies')
- .search('winter feast', SearchQuery(attributesToHighlight: ['overview']));
-search_parameter_guide_show_matches_position_1: |-
- await client.index('movies').search('winter feast', SearchQuery(showMatchesPosition: true));
-add_movies_json_1: |-
- import 'dart:io';
- import 'dart:convert';
-
- final json = await File('movies.json').readAsString();
-
- await client.index('movies').addDocumentsJson(json);
+search_parameter_guide_matching_strategy_1: "await client.index('movies').search(\n 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.last));"
+search_parameter_guide_matching_strategy_2: "await client.index('movies').search(\n 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.all));"
+search_parameter_guide_retrieve_1: "await client.index('movies').search(\n 'shifu', SearchQuery(attributesToRetrieve: ['overview', 'title']));"
+search_parameter_guide_crop_1: "await client.index('movies').search(\n 'shifu', SearchQuery(attributesToCrop: ['overview'], cropLength: 5));"
+search_parameter_guide_highlight_1: "await client.index('movies').search(\n 'winter feast', SearchQuery(attributesToHighlight: ['overview']));"
+search_parameter_guide_show_matches_position_1: "await client\n .index('movies')\n .search('winter feast', SearchQuery(showMatchesPosition: true));"
+add_movies_json_1: "\/\/ import 'dart:io';\n\/\/ import 'dart:convert';\nfinal json = await File('movies.json').readAsString();\nawait client.index('movies').addDocumentsJson(json);"
primary_field_guide_create_index_primary_key: |-
await client.createIndex('books', primaryKey: 'reference_number');
primary_field_guide_update_document_primary_key: |-
@@ -370,142 +205,58 @@ typo_tolerance_guide_4: |-
),
);
await client.index('movies').updateTypoTolerance(toUpdate);
-getting_started_add_documents_md: |-
- ```bash
- dart pub add meilisearch
- ```
-
- ```dart
- import 'package:meilisearch/meilisearch.dart';
- import 'dart:io';
- import 'dart:convert';
-
- var client = MeiliSearchClient('http://localhost:7700', 'aSampleMasterKey');
-
- final json = await File('movies.json').readAsString();
-
- await client.index('movies').addDocumentsJson(json);
- ```
-
- [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
-getting_started_search_md: |-
- ```dart
- await client.index('movies').search('botman');
- ```
-
- [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
-getting_started_update_ranking_rules: |-
- await client.index('movies').updateRankingRules([
- 'exactness',
- 'words',
- 'typo',
- 'proximity',
- 'attribute',
- 'sort',
- 'release_date:asc',
- 'rank:desc'
- ]);
-getting_started_update_searchable_attributes: |-
- await client.index('movies').updateSearchableAttributes([
- 'title'
- ]);
+getting_started_add_documents_md: "```bash\ndart pub add meilisearch\n```\n```dart\nimport 'package:meilisearch\/meilisearch.dart';\nimport 'dart:io';\nimport 'dart:convert';\nvar client = MeiliSearchClient('http:\/\/localhost:7700', 'aSampleMasterKey');\nfinal json = await File('movies.json').readAsString();\nawait client.index('movies').addDocumentsJson(json);\n```\n[About this SDK](https:\/\/github.com\/meilisearch\/meilisearch-dart\/)"
+getting_started_search_md: "```dart\nawait client.index('movies').search('botman');\n```\n[About this SDK](https:\/\/github.com\/meilisearch\/meilisearch-dart\/)"
+getting_started_update_ranking_rules: "await client.index('movies').updateRankingRules([\n 'exactness',\n 'words',\n 'typo',\n 'proximity',\n 'attribute',\n 'sort',\n 'release_date:asc',\n 'rank:desc',\n]);"
+getting_started_update_searchable_attributes: "await client.index('movies').updateSearchableAttributes(['title']);"
getting_started_update_stop_words: |-
await client.index('movies').updateStopWords(['the']);
getting_started_check_task_status: |-
await client.getTask(0);
-getting_started_synonyms: |-
- await client.index('movies').updateSynonyms({
- 'winnie': ['piglet'],
- 'piglet': ['winnie']
- });
-getting_started_update_displayed_attributes: |-
- await client.index('movies').updateDisplayedAttributes([
- 'title',
- 'overview',
- 'poster'
- ]);
-getting_started_add_meteorites: |-
- final json = await File('meteorites.json').readAsString();
-
- await client.index('meteorites').addDocumentsJson(json);
-getting_started_configure_settings: |-
- await client.index('meteorites').updateSettings(IndexSettings(
- filterableAttributes: ['mass', '_geo'],
- sortableAttributes: ['mass', '_geo']
- ));
-getting_started_geo_radius: |-
- await client.index('meteorites').search('', SearchQuery(filter: '_geoRadius(46.9480, 7.4474, 210000)'));
-getting_started_geo_point: |-
- await client.index('meteorites').search('', SearchQuery(sort: ['_geoPoint(48.8583701, 2.2922926):asc']));
-getting_started_sorting: |-
- await client.index('meteorites').search('', SearchQuery(sort: ['mass:asc'], filter: 'mass < 200'));
-getting_started_filtering: |-
- await client.index('meteorites').search('', SearchQuery(filter: 'mass < 200'));
-getting_started_faceting: |-
- await client.index('books').updateFaceting(Faceting(maxValuesPerFacet: 2, sortFacetValuesBy: {'*': 'count'}));
+getting_started_synonyms: "await client.index('movies').updateSynonyms({\n 'winnie': ['piglet'],\n 'piglet': ['winnie'],\n});"
+getting_started_update_displayed_attributes: "await client\n .index('movies')\n .updateDisplayedAttributes(['title', 'overview', 'poster']);"
+getting_started_add_meteorites: "final json = await File('meteorites.json').readAsString();\nawait client.index('meteorites').addDocumentsJson(json);"
+getting_started_configure_settings: "await client.index('meteorites').updateSettings(IndexSettings(\n filterableAttributes: ['mass', '_geo'],\n sortableAttributes: ['mass', '_geo']));"
+getting_started_geo_radius: "await client.index('meteorites').search(\n '',\n SearchQuery(\n filterExpression: Meili.geoRadius(\n (lat: 46.9480, lng: 7.4474),\n 210000,\n ),\n ),\n );"
+getting_started_geo_point: "await client.index('meteorites').search(\n '', SearchQuery(sort: ['_geoPoint(48.8583701, 2.2922926):asc']));"
+getting_started_sorting: "await client.index('meteorites').search(\n '',\n SearchQuery(\n sort: ['mass:asc'],\n filterExpression: Meili.attr('mass').lt(200.toMeiliValue()),\n ),\n );"
+getting_started_filtering: "await client\n .index('meteorites')\n .search('', SearchQuery(filter: 'mass < 200'));"
+getting_started_faceting: "await client.index('books').updateFaceting(Faceting(\n maxValuesPerFacet: 2,\n sortFacetValuesBy: {'*': FacetingSortTypes.count}));"
getting_started_typo_tolerance: |-
final toUpdate = TypoTolerance(
minWordSizeForTypos: MinWordSizeForTypos(oneTypo: 4),
);
await client.index('movies').updateTypoTolerance(toUpdate);
-getting_started_pagination: |-
- await client.index('books').updatePagination(Pagination(maxTotalHits: 500));
+getting_started_pagination: "await client\n .index('books')\n .updatePagination(Pagination(maxTotalHits: 500));"
filtering_update_settings_1: |-
await client.index('movies').updateFilterableAttributes([
'director',
'genres',
]);
-faceted_search_walkthrough_filter_1: |-
- await client.index('movies').search('thriller', SearchQuery(filter: [
- ['genres = Horror', 'genres = Mystery'],
- 'director = "Jordan Peele"'
- ]));
+faceted_search_walkthrough_filter_1: "await client.index('movies').search(\n 'thriller',\n SearchQuery(filter: [\n ['genres = Horror', 'genres = Mystery'],\n 'director = \"Jordan Peele\"'\n ]));"
post_dump_1: |-
await client.createDump();
phrase_search_1: |-
await client.index('movies').search('"african american" horror');
sorting_guide_update_sortable_attributes_1: |-
await client.index('books').updateSortableAttributes(['author', 'price']);
-sorting_guide_update_ranking_rules_1: |-
- await client.index('books').updateRankingRules([
- 'words',
- 'sort',
- 'typo',
- 'proximity',
- 'attribute',
- 'exactness'
- ]);
-sorting_guide_sort_parameter_1: |-
- await client.index('books').search('science fiction', SearchQuery(sort: ['price:asc']));
-sorting_guide_sort_parameter_2: |-
- await client.index('books').search('butler', SearchQuery(sort: ['author:desc']));
+sorting_guide_update_ranking_rules_1: "await client.index('books').updateRankingRules(\n ['words', 'sort', 'typo', 'proximity', 'attribute', 'exactness']);"
+sorting_guide_sort_parameter_1: "await client\n .index('books')\n .search('science fiction', SearchQuery(sort: ['price:asc']));"
+sorting_guide_sort_parameter_2: "await client\n .index('books')\n .search('butler', SearchQuery(sort: ['author:desc']));"
get_sortable_attributes_1: |-
await client.index('books').getSortableAttributes();
-update_sortable_attributes_1: |-
- await client.index('books').updateSortableAttributes([
- 'price',
- 'author'
- ]);
+update_sortable_attributes_1: "await client.index('books').updateSortableAttributes(['price', 'author']);"
reset_sortable_attributes_1: |-
await client.index('books').resetSortableAttributes();
-search_parameter_guide_sort_1: |-
- await client.index('books').search('science fiction', SearchQuery(sort: ['price:asc']));
+search_parameter_guide_sort_1: "await client\n .index('books')\n .search('science fiction', SearchQuery(sort: ['price:asc']));"
geosearch_guide_filter_settings_1: |-
await client.index('restaurants').updateFilterableAttributes(['_geo']);
-geosearch_guide_filter_usage_1: |-
- await await client
- .index('restaurants')
- .search('', SearchQuery(filter: '_geoRadius(45.472735, 9.184019, 2000)'));
-geosearch_guide_filter_usage_2: |-
- await await client
- .index('restaurants')
- .search('', SearchQuery(filter: '_geoRadius(45.472735, 9.184019, 2000) AND type = pizza'));
+geosearch_guide_filter_usage_1: "await client.index('restaurants').search(\n '',\n SearchQuery(\n filterExpression: Meili.geoRadius(\n (lat: 45.472735, lng: 9.184019),\n 2000,\n ),\n ),\n );"
+geosearch_guide_filter_usage_2: "await client.index('restaurants').search(\n '',\n SearchQuery(\n filterExpression: Meili.and([\n Meili.geoRadius(\n (lat: 45.472735, lng: 9.184019),\n 2000,\n ),\n Meili.attr('type').eq('pizza'.toMeiliValue())\n ]),\n ),\n );"
geosearch_guide_sort_settings_1: |-
await client.index('restaurants').updateSortableAttributes(['_geo']);
-geosearch_guide_sort_usage_1: |-
- await client.index('restaurants').search('', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc']));
-geosearch_guide_sort_usage_2: |-
- await client.index('restaurants').search('', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc']));
+geosearch_guide_sort_usage_1: "await client.index('restaurants').search(\n '', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc']));"
+geosearch_guide_sort_usage_2: "await client.index('restaurants').search(\n '',\n SearchQuery(\n sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc']));"
authorization_header_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
await client.getKeys();
@@ -513,27 +264,14 @@ get_one_key_1: |-
await client.getKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
get_all_keys_1: |-
await client.getKeys(params: KeysQuery(limit: 3));
-create_a_key_1: |-
- await client.createKey(
- description: 'Add documents: Products API key',
- actions: ['documents.add'],
- indexes: ['products'],
- expiresAt: DateTime(2042, 04, 02)
- );
-update_a_key_1: |-
- await client.updateKey(
- '6062abda-a5aa-4414-ac91-ecd7944c0f8d',
- description: 'Manage documents: Products/Reviews API key',
- name: 'Products/Reviews API key'
- );
+create_a_key_1: "await client.createKey(\n description: 'Add documents: Products API key',\n actions: ['documents.add'],\n indexes: ['products'],\n expiresAt: DateTime(2042, 04, 02));"
+update_a_key_1: "await client.updateKey(\n '6062abda-a5aa-4414-ac91-ecd7944c0f8d',\n description: 'Manage documents: Products\/Reviews API key',\n name: 'Products\/Reviews API key',\n);"
delete_a_key_1: |-
await client.deleteKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
security_guide_search_key_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'apiKey');
await client.index('patient_medical_records').search('');
-security_guide_update_key_1: |-
- var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
- await client.updateKey('74c9c733-3368-4738-bbe5-1d18a5fecb37', description: 'Default Search API Key');
+security_guide_update_key_1: "var client = MeiliSearchClient('http:\/\/localhost:7700', 'masterKey');\nawait client.updateKey(\n '74c9c733-3368-4738-bbe5-1d18a5fecb37',\n description: 'Default Search API Key',\n);"
security_guide_create_key_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
await client.createKey(
@@ -548,48 +286,7 @@ security_guide_list_keys_1: |-
security_guide_delete_key_1: |-
var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
await client.deleteKey('ac5cd97d-5a4b-4226-a868-2d0eb6d197ab');
-tenant_token_guide_generate_sdk_1: |-
- final uid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76';
- final apiKey = 'B5KdX2MY2jV6EXfUs6scSfmC...';
- final expiresAt = DateTime.utc(2025, 12, 20);
- final searchRules = {
- 'patient_medical_records': {
- 'filter': 'user_id = 1'
- }
- };
-
- final token = client.generateTenantToken(
- uid,
- searchRules,
- apiKey: apiKey, // optional
- expiresAt: expiresAt // optional
- );
-tenant_token_guide_search_sdk_1: |-
- final frontEndClient = MeiliSearchClient('http://localhost:7700', token);
- await frontEndClient.index('patient_medical_records').search('blood test');
-landing_getting_started_1: |-
- var client = MeiliSearchClient('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'}
- ]);
-search_parameter_guide_crop_marker_1: |-
- await client
- .index('movies')
- .search('shifu', SearchQuery(attributesToCrop: ['overview'], cropMarker: '[…]'));
-search_parameter_guide_highlight_tag_1: |-
- await client.index('movies').search(
- 'winter feast',
- SearchQuery(
- attributesToHighlight: ['overview'],
- highlightPreTag: '',
- highlightPostTag: ''));
-geosearch_guide_filter_usage_3: |-
- await client.index('restaurants')
- .search('', SearchQuery(filter: '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])')),
- });
+search_parameter_guide_crop_marker_1: "await client.index('movies').search(\n 'shifu',\n SearchQuery(\n attributesToCrop: ['overview'],\n cropMarker: '[…]',\n ),\n );"
+search_parameter_guide_highlight_tag_1: "await client.index('movies').search(\n 'winter feast',\n SearchQuery(\n attributesToHighlight: ['overview'],\n highlightPreTag: '',\n highlightPostTag: '<\/span>',\n ),\n );"
+geosearch_guide_filter_usage_3: "await client.index('restaurants').search(\n '',\n SearchQuery(\n filter:\n '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'));\n});"
+search_get_1: await client.index('movies').search('American ninja');
diff --git a/.github/workflows/pre-release-tests.yml b/.github/workflows/pre-release-tests.yml
index a498df8..68d2419 100644
--- a/.github/workflows/pre-release-tests.yml
+++ b/.github/workflows/pre-release-tests.yml
@@ -27,4 +27,4 @@ jobs:
- name: Meilisearch (${{ env.MEILISEARCH_VERSION }}) setup with Docker
run: docker run -d -p 7700:7700 getmeili/meilisearch:${{ env.MEILISEARCH_VERSION }} meilisearch --master-key=masterKey --no-analytics
- name: Run integration tests
- run: docker run --net="host" -v $PWD:/package -w /package dart:${{ matrix.version }} /bin/sh -c 'dart pub get && dart run test'
+ run: docker run --net="host" -v $PWD:/package -w /package dart:${{ matrix.version }} /bin/sh -c 'dart pub get && dart pub get -C tool && dart run test'
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 877ff05..d944725 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -41,6 +41,7 @@ jobs:
- name: Install dependencies
run: |
dart pub get
+ dart pub get -C tool
dart pub global activate coverage
- name: Run integration tests
run: dart test --concurrency=4 --reporter=github --coverage=./coverage/reports
@@ -61,7 +62,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install dependencies
- run: dart pub get
+ run: |
+ dart pub get
+ dart pub get -C tool
- name: Run linter
run: dart analyze --fatal-infos && dart format . --set-exit-if-changed
@@ -75,6 +78,19 @@ jobs:
with:
config_file: .yamllint.yml
+ check-code-samples:
+ name: check .code-samples.meilisearch.yaml
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: dart-lang/setup-dart@v1
+ with:
+ sdk: '3.0.0'
+ - name: check if samples changed
+ run: |
+ dart pub get
+ dart pub get -C tool
+ dart run ./tool/bin/meili.dart update-samples --fail-on-change
pana:
runs-on: ubuntu-latest
timeout-minutes: 10
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c790302..eecd17b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,6 +9,7 @@ First of all, thank you for contributing to Meilisearch! The goal of this docume
- [Requirements ](#requirements-)
- [Setup ](#setup-)
- [Tests and Linter ](#tests-and-linter-)
+ - [Updating code samples](#updating-code-samples)
- [Git Guidelines](#git-guidelines)
- [Git Branches ](#git-branches-)
- [Git Commits ](#git-commits-)
@@ -76,6 +77,31 @@ dart test
dart analyze
```
+### Updating code samples
+
+Some PRs require updating the code samples (found in `.code-samples.meilisearch.yaml`), this is done automatically using code excerpts, which are actual pieces of code subject to testing and linting.
+
+A lot of them are placed in `test/code_samples.dart`.
+
+Also most of the tests in that file are skipped, since they are mostly duplicated in other test files.
+
+The process to define a new code sample is as follows:
+1. Add the piece of code in `test/code_samples.dart`
+2. surround it with `#docregion key` and `#enddocregion`, e.g.
+ ```
+ // #docregion meilisearch_contributing_1
+ final client = MeilisearchClient();
+ anything();
+ // #enddocregion
+ ```
+3. run this command to update the code samples
+ ```bash
+ dart run ./tool/bin/meili.dart update-samples
+ ```
+4. to test if the code samples are updated correctly, run:
+ ```bash
+ dart run ./tool/bin/meili.dart update-samples --fail-on-change
+ ```
## Git Guidelines
### Git Branches
diff --git a/README.md b/README.md
index c3a7afa..85e4a39 100644
--- a/README.md
+++ b/README.md
@@ -28,13 +28,7 @@
**Meilisearch** is an open-source search engine. [Learn more about Meilisearch.](https://github.com/meilisearch/meilisearch)
----
-
-### 🔥 On November 2nd, we are hosting our first-ever live demo and product updates for [Meilisearch Cloud](https://www.meilisearch.com/cloud?utm_campaign=oss&utm_source=github&utm_medium=meilisearch). Make sure to [register here](https://us06web.zoom.us/meeting/register/tZMlc-mqrjIsH912-HTRe-AaT-pp41bDe81a#/registration) and bring your questions for live Q&A!
-
----
-
-## Table of Contents
+## Table of Contents
- [📖 Documentation](#-documentation)
- [⚡ Supercharge your Meilisearch experience](#-supercharge-your-meilisearch-experience)
diff --git a/lib/src/filter_builder/values.dart b/lib/src/filter_builder/values.dart
index c1a8a19..db1f6d4 100644
--- a/lib/src/filter_builder/values.dart
+++ b/lib/src/filter_builder/values.dart
@@ -29,8 +29,10 @@ class MeiliDateTimeValueExpression extends MeiliValueExpressionBase {
"DateTime passed to Meili must be in UTC to avoid inconsistency accross multiple devices",
);
+ /// Unix epoch time is seconds since epoch
@override
- String transform() => value.millisecondsSinceEpoch.toString();
+ String transform() =>
+ (value.millisecondsSinceEpoch / 1000).floor().toString();
@override
bool operator ==(Object other) {
diff --git a/test/code_samples.dart b/test/code_samples.dart
new file mode 100644
index 0000000..3de892b
--- /dev/null
+++ b/test/code_samples.dart
@@ -0,0 +1,888 @@
+// ignore_for_file: unused_element
+
+import 'dart:io';
+
+import 'package:meilisearch/meilisearch.dart';
+import 'package:test/test.dart';
+
+import 'utils/client.dart';
+
+void main() {
+ // this file hosts some code samples referenced in
+ // .code-samples.meilisearch.yaml
+ // it's subject to tests, lint rules, deprecation notices, etc...
+ group('code samples', () {
+ setUpClient();
+
+ test('excerpts', () async {
+ void a1() async {
+ // #docregion typo_tolerance_guide_1
+ final toUpdate = TypoTolerance(enabled: false);
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a2() async {
+ // #docregion typo_tolerance_guide_2
+ final toUpdate = TypoTolerance(
+ disableOnAttributes: ['title'],
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a3() async {
+ // #docregion typo_tolerance_guide_3
+ final toUpdate = TypoTolerance(
+ disableOnWords: ['shrek'],
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a4() async {
+ // #docregion typo_tolerance_guide_4
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(
+ oneTypo: 4,
+ twoTypos: 10,
+ ),
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ void a8() async {
+ // #docregion getting_started_add_meteorites
+ final json = await File('meteorites.json').readAsString();
+
+ await client.index('meteorites').addDocumentsJson(json);
+ // #enddocregion
+ }
+
+ void a10() async {
+ // #docregion add_movies_json_1
+ // import 'dart:io';
+ // import 'dart:convert';
+ final json = await File('movies.json').readAsString();
+ await client.index('movies').addDocumentsJson(json);
+ // #enddocregion
+ }
+
+ void a11() async {
+ // #docregion security_guide_delete_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.deleteKey('ac5cd97d-5a4b-4226-a868-2d0eb6d197ab');
+ // #enddocregion
+ }
+
+ void a12() async {
+ // #docregion security_guide_list_keys_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.getKeys();
+ // #enddocregion
+ }
+
+ void a13() async {
+ // #docregion security_guide_create_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.createKey(
+ description: 'Search patient records key',
+ actions: ['search'],
+ indexes: ['patient_medical_records'],
+ expiresAt: DateTime(2023, 01, 01),
+ );
+ // #enddocregion
+ }
+
+ void a14() async {
+ // #docregion authorization_header_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.getKeys();
+ // #enddocregion
+ }
+
+ void a15() async {
+ // #docregion security_guide_search_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'apiKey');
+ await client.index('patient_medical_records').search('');
+ // #enddocregion
+ }
+
+ void a16() async {
+ // #docregion security_guide_update_key_1
+ var client = MeiliSearchClient('http://localhost:7700', 'masterKey');
+ await client.updateKey(
+ '74c9c733-3368-4738-bbe5-1d18a5fecb37',
+ description: 'Default Search API Key',
+ );
+ // #enddocregion
+ }
+
+ // #docregion date_guide_index_1
+ //import 'dart:io';
+ //import 'dart:convert';
+
+ final json = await File('games.json').readAsString();
+
+ await client.index('games').addDocumentsJson(json);
+ // #enddocregion
+
+ // #docregion date_guide_filterable_attributes_1
+ await client
+ .index('games')
+ .updateFilterableAttributes(['release_timestamp']);
+ // #enddocregion
+
+ // #docregion date_guide_filter_1
+ await client.index('games').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.gte(
+ 'release_timestamp'.toMeiliAttribute(),
+ Meili.value(DateTime(2017, 12, 31, 23, 0)),
+ ),
+ Meili.lt(
+ 'release_timestamp'.toMeiliAttribute(),
+ Meili.value(DateTime(2022, 12, 31, 23, 0)),
+ ),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion date_guide_sortable_attributes_1
+ await client
+ .index('games')
+ .updateSortableAttributes(['release_timestamp']);
+ // #enddocregion
+
+ // #docregion date_guide_sort_1
+ await client
+ .index('games')
+ .search('', SearchQuery(sort: ['release_timestamp:desc']));
+ // #enddocregion
+
+ // #docregion get_all_tasks_paginating_1
+ await client.getTasks(params: TasksQuery(limit: 2, from: 10));
+ // #enddocregion
+
+ // #docregion get_all_tasks_paginating_2
+ await client.getTasks(params: TasksQuery(limit: 2, from: 8));
+ // #enddocregion
+
+ // #docregion get_pagination_settings_1
+ await client.index('movies').getPagination();
+ // #enddocregion
+
+ // #docregion update_pagination_settings_1
+ await client
+ .index('books')
+ .updatePagination(Pagination(maxTotalHits: 100));
+ // #enddocregion
+
+ // #docregion reset_pagination_settings_1
+ await client.index('movies').resetPagination();
+ // #enddocregion
+
+ // #docregion get_faceting_settings_1
+ await client.index('movies').getFaceting();
+ // #enddocregion
+
+ // #docregion update_faceting_settings_1
+ await client.index('books').updateFaceting(Faceting(
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {
+ '*': FacetingSortTypes.alpha,
+ 'genres': FacetingSortTypes.count
+ }));
+ // #enddocregion
+
+ // #docregion reset_faceting_settings_1
+ await client.index('movies').resetFaceting();
+ // #enddocregion
+
+ // #docregion get_one_index_1
+ await client.getIndex('movies');
+ // #enddocregion
+
+ // #docregion list_all_indexes_1
+ await client.getIndexes(params: IndexesQuery(limit: 3));
+ // #enddocregion
+
+ // #docregion create_an_index_1
+ await client.createIndex('movies', primaryKey: 'id');
+ // #enddocregion
+
+ // #docregion update_an_index_1
+ await client.index('movies').update(primaryKey: 'id');
+ // #enddocregion
+
+ // #docregion delete_an_index_1
+ await client.index('movies').delete();
+ // #enddocregion
+
+ // #docregion get_one_document_1
+ await client.index('movies').getDocument(25684,
+ fields: ['id', 'title', 'poster', 'release_date']);
+ // #enddocregion
+
+ // #docregion add_or_replace_documents_1
+ 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'
+ }
+ ]);
+ // #enddocregion
+
+ // #docregion add_or_update_documents_1
+ await client.index('movies').updateDocuments([
+ {
+ 'id': 287947,
+ 'title': 'Shazam ⚡️',
+ 'genres': 'comedy',
+ }
+ ]);
+ // #enddocregion
+
+ // #docregion delete_all_documents_1
+ await client.index('movies').deleteAllDocuments();
+ // #enddocregion
+
+ // #docregion delete_one_document_1
+ await client.index('movies').deleteDocument(25684);
+ // #enddocregion
+
+ // #docregion delete_documents_by_batch_1
+ await client.index('movies').deleteDocuments(
+ DeleteDocumentsQuery(
+ ids: [23488, 153738, 437035, 363869],
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_post_1
+ await client.index('movies').search('American ninja');
+ // #enddocregion
+
+ // #docregion get_task_1
+ await client.getTask(1);
+ // #enddocregion
+
+ // #docregion get_all_tasks_1
+ await client.getTasks();
+ // #enddocregion
+
+ // #docregion get_settings_1
+ await client.index('movies').getSettings();
+ // #enddocregion
+
+ // #docregion update_settings_1
+ await client.index('movies').updateSettings(
+ IndexSettings(
+ 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'],
+ },
+ ),
+ );
+ // #enddocregion
+
+ // #docregion reset_settings_1
+ await client.index('movies').resetSettings();
+ // #enddocregion
+
+ // #docregion get_synonyms_1
+ await client.index('movies').getSynonyms();
+ // #enddocregion
+
+ // #docregion update_synonyms_1
+ await client.index('movies').updateSynonyms({
+ 'wolverine': ['xmen', 'logan'],
+ 'logan': ['wolverine', 'xmen'],
+ 'wow': ['world of warcraft'],
+ });
+ // #enddocregion
+
+ // #docregion reset_synonyms_1
+ await client.index('movies').resetSynonyms();
+ // #enddocregion
+
+ // #docregion get_stop_words_1
+ await client.index('movies').getStopWords();
+ // #enddocregion
+
+ // #docregion update_stop_words_1
+ await client.index('movies').updateStopWords(['of', 'the', 'to']);
+ // #enddocregion
+
+ // #docregion reset_stop_words_1
+ await client.index('movies').resetStopWords();
+ // #enddocregion
+
+ // #docregion get_ranking_rules_1
+ await client.index('movies').getRankingRules();
+ // #enddocregion
+
+ // #docregion update_ranking_rules_1
+ await client.index('movies').updateRankingRules([
+ 'words',
+ 'typo',
+ 'proximity',
+ 'attribute',
+ 'sort',
+ 'exactness',
+ 'release_date:asc',
+ 'rank:desc',
+ ]);
+ // #enddocregion
+
+ // #docregion reset_ranking_rules_1
+ await client.index('movies').resetRankingRules();
+ // #enddocregion
+
+ // #docregion get_distinct_attribute_1
+ await client.index('shoes').getDistinctAttribute();
+ // #enddocregion
+
+ // #docregion update_distinct_attribute_1
+ await client.index('shoes').updateDistinctAttribute('skuid');
+ // #enddocregion
+
+ // #docregion reset_distinct_attribute_1
+ await client.index('shoes').resetDistinctAttribute();
+ // #enddocregion
+
+ // #docregion get_filterable_attributes_1
+ await client.index('movies').getFilterableAttributes();
+ // #enddocregion
+
+ // #docregion update_filterable_attributes_1
+ await client
+ .index('movies')
+ .updateFilterableAttributes(['genres', 'director']);
+ // #enddocregion
+
+ // #docregion reset_filterable_attributes_1
+ await client.index('movies').resetFilterableAttributes();
+ // #enddocregion
+
+ // #docregion get_searchable_attributes_1
+ await client.index('movies').getSearchableAttributes();
+ // #enddocregion
+
+ // #docregion update_searchable_attributes_1
+ await client
+ .index('movies')
+ .updateSearchableAttributes(['title', 'overview', 'genres']);
+ // #enddocregion
+
+ // #docregion reset_searchable_attributes_1
+ await client.index('movies').resetSearchableAttributes();
+ // #enddocregion
+
+ // #docregion get_displayed_attributes_1
+ await client.index('movies').getDisplayedAttributes();
+ // #enddocregion
+
+ // #docregion update_displayed_attributes_1
+ await client.index('movies').updateDisplayedAttributes([
+ 'title',
+ 'overview',
+ 'genres',
+ 'release_date',
+ ]);
+ // #enddocregion
+
+ // #docregion reset_displayed_attributes_1
+ await client.index('movies').resetDisplayedAttributes();
+ // #enddocregion
+
+ // #docregion get_typo_tolerance_1
+ await client.index('books').getTypoTolerance();
+ // #enddocregion
+
+ // #docregion update_typo_tolerance_1
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(
+ oneTypo: 4,
+ twoTypos: 10,
+ ),
+ disableOnAttributes: ['title'],
+ );
+ await client.index('books').updateTypoTolerance(toUpdate);
+ // #enddocregion
+
+ // #docregion reset_typo_tolerance_1
+ await client.index('books').resetTypoTolerance();
+ // #enddocregion
+
+ // #docregion get_index_stats_1
+ await client.index('movies').getStats();
+ // #enddocregion
+
+ // #docregion get_indexes_stats_1
+ await client.getStats();
+ // #enddocregion
+
+ // #docregion get_health_1
+ await client.health();
+ // #enddocregion
+
+ // #docregion get_version_1
+ await client.getVersion();
+ // #enddocregion
+
+ // #docregion distinct_attribute_guide_1
+ await client.index('jackets').updateDistinctAttribute('product_id');
+ // #enddocregion
+
+ // #docregion field_properties_guide_searchable_1
+ await client
+ .index('movies')
+ .updateSearchableAttributes(['title', 'overview', 'genres']);
+ // #enddocregion
+
+ // #docregion field_properties_guide_displayed_1
+ await client.index('movies').updateDisplayedAttributes([
+ 'title',
+ 'overview',
+ 'genres',
+ 'release_date',
+ ]);
+ // #enddocregion
+
+ // #docregion filtering_guide_1
+ await client.index('movie_ratings').search(
+ 'Avengers',
+ SearchQuery(
+ filterExpression: Meili.gt(
+ Meili.attr('release_date'),
+ DateTime.utc(1995, 3, 18).toMeiliValue(),
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion filtering_guide_2
+ await client.index('movie_ratings').search(
+ 'Batman',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.attr('release_date')
+ .gt(DateTime.utc(1995, 3, 18).toMeiliValue()),
+ Meili.or([
+ 'director'.toMeiliAttribute().eq('Tim Burton'.toMeiliValue()),
+ 'director'
+ .toMeiliAttribute()
+ .eq('Christopher Nolan'.toMeiliValue()),
+ ]),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion filtering_guide_3
+ await client.index('movie_ratings').search(
+ 'Planet of the Apes',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.attr('release_date')
+ .gt(DateTime.utc(2020, 1, 1, 13, 15, 50).toMeiliValue()),
+ Meili.not(
+ Meili.attr('director').eq("Tim Burton".toMeiliValue()),
+ ),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_parameter_guide_query_1
+ await client.index('movies').search('shifu');
+ // #enddocregion
+
+ // #docregion search_parameter_guide_offset_1
+ await client.index('movies').search('shifu', SearchQuery(offset: 1));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_limit_1
+ await client.index('movies').search('shifu', SearchQuery(limit: 2));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_matching_strategy_1
+ await client.index('movies').search(
+ 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.last));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_matching_strategy_2
+ await client.index('movies').search(
+ 'big fat liar', SearchQuery(matchingStrategy: MatchingStrategy.all));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_retrieve_1
+ await client.index('movies').search(
+ 'shifu', SearchQuery(attributesToRetrieve: ['overview', 'title']));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_crop_1
+ await client.index('movies').search(
+ 'shifu', SearchQuery(attributesToCrop: ['overview'], cropLength: 5));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_highlight_1
+ await client.index('movies').search(
+ 'winter feast', SearchQuery(attributesToHighlight: ['overview']));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_show_matches_position_1
+ await client
+ .index('movies')
+ .search('winter feast', SearchQuery(showMatchesPosition: true));
+ // #enddocregion
+
+ // #docregion primary_field_guide_create_index_primary_key
+ await client.createIndex('books', primaryKey: 'reference_number');
+ // #enddocregion
+
+ // #docregion primary_field_guide_update_document_primary_key
+ await client.updateIndex('books', 'title');
+ // #enddocregion
+
+ // #docregion primary_field_guide_add_document_primary_key
+ await client.index('movies').addDocuments([
+ {
+ 'reference_number': 287947,
+ 'title': 'Diary of a Wimpy Kid',
+ 'author': 'Jeff Kinney',
+ 'genres': ['comedy', 'humor'],
+ 'price': 5.00
+ }
+ ], primaryKey: 'reference_number');
+ // #enddocregion
+
+ // #docregion getting_started_update_ranking_rules
+ await client.index('movies').updateRankingRules([
+ 'exactness',
+ 'words',
+ 'typo',
+ 'proximity',
+ 'attribute',
+ 'sort',
+ 'release_date:asc',
+ 'rank:desc',
+ ]);
+ // #enddocregion
+
+ // #docregion getting_started_update_searchable_attributes
+ await client.index('movies').updateSearchableAttributes(['title']);
+ // #enddocregion
+
+ // #docregion getting_started_update_stop_words
+ await client.index('movies').updateStopWords(['the']);
+ // #enddocregion
+
+ // #docregion getting_started_check_task_status
+ await client.getTask(0);
+ // #enddocregion
+
+ // #docregion getting_started_synonyms
+ await client.index('movies').updateSynonyms({
+ 'winnie': ['piglet'],
+ 'piglet': ['winnie'],
+ });
+ // #enddocregion
+
+ // #docregion getting_started_update_displayed_attributes
+ await client
+ .index('movies')
+ .updateDisplayedAttributes(['title', 'overview', 'poster']);
+ // #enddocregion
+
+ // #docregion getting_started_configure_settings
+ await client.index('meteorites').updateSettings(IndexSettings(
+ filterableAttributes: ['mass', '_geo'],
+ sortableAttributes: ['mass', '_geo']));
+ // #enddocregion
+
+ // #docregion getting_started_geo_radius
+ await client.index('meteorites').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.geoRadius(
+ (lat: 46.9480, lng: 7.4474),
+ 210000,
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion getting_started_geo_point
+ await client.index('meteorites').search(
+ '', SearchQuery(sort: ['_geoPoint(48.8583701, 2.2922926):asc']));
+ // #enddocregion
+
+ // #docregion getting_started_sorting
+ await client.index('meteorites').search(
+ '',
+ SearchQuery(
+ sort: ['mass:asc'],
+ filterExpression: Meili.attr('mass').lt(200.toMeiliValue()),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion getting_started_filtering
+ await client
+ .index('meteorites')
+ .search('', SearchQuery(filter: 'mass < 200'));
+ // #enddocregion
+
+ // #docregion getting_started_faceting
+ await client.index('books').updateFaceting(Faceting(
+ maxValuesPerFacet: 2,
+ sortFacetValuesBy: {'*': FacetingSortTypes.count}));
+ // #enddocregion
+
+ void a9() async {
+ // #docregion getting_started_typo_tolerance
+ final toUpdate = TypoTolerance(
+ minWordSizeForTypos: MinWordSizeForTypos(oneTypo: 4),
+ );
+ await client.index('movies').updateTypoTolerance(toUpdate);
+ // #enddocregion
+ }
+
+ // #docregion getting_started_pagination
+ await client
+ .index('books')
+ .updatePagination(Pagination(maxTotalHits: 500));
+ // #enddocregion
+
+ // #docregion filtering_update_settings_1
+ await client.index('movies').updateFilterableAttributes([
+ 'director',
+ 'genres',
+ ]);
+ // #enddocregion
+
+ // #docregion faceted_search_walkthrough_filter_1
+ await client.index('movies').search(
+ 'thriller',
+ SearchQuery(filter: [
+ ['genres = Horror', 'genres = Mystery'],
+ 'director = "Jordan Peele"'
+ ]));
+ // #enddocregion
+
+ // #docregion post_dump_1
+ await client.createDump();
+ // #enddocregion
+
+ // #docregion phrase_search_1
+ await client.index('movies').search('"african american" horror');
+ // #enddocregion
+
+ // #docregion sorting_guide_update_sortable_attributes_1
+ await client.index('books').updateSortableAttributes(['author', 'price']);
+ // #enddocregion
+
+ // #docregion sorting_guide_update_ranking_rules_1
+ await client.index('books').updateRankingRules(
+ ['words', 'sort', 'typo', 'proximity', 'attribute', 'exactness']);
+ // #enddocregion
+
+ // #docregion sorting_guide_sort_parameter_1
+ await client
+ .index('books')
+ .search('science fiction', SearchQuery(sort: ['price:asc']));
+ // #enddocregion
+
+ // #docregion sorting_guide_sort_parameter_2
+ await client
+ .index('books')
+ .search('butler', SearchQuery(sort: ['author:desc']));
+ // #enddocregion
+
+ // #docregion get_sortable_attributes_1
+ await client.index('books').getSortableAttributes();
+ // #enddocregion
+
+ // #docregion update_sortable_attributes_1
+ await client.index('books').updateSortableAttributes(['price', 'author']);
+ // #enddocregion
+
+ // #docregion reset_sortable_attributes_1
+ await client.index('books').resetSortableAttributes();
+ // #enddocregion
+
+ // #docregion search_parameter_guide_sort_1
+ await client
+ .index('books')
+ .search('science fiction', SearchQuery(sort: ['price:asc']));
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_settings_1
+ await client.index('restaurants').updateFilterableAttributes(['_geo']);
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_usage_1
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.geoRadius(
+ (lat: 45.472735, lng: 9.184019),
+ 2000,
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_usage_2
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ filterExpression: Meili.and([
+ Meili.geoRadius(
+ (lat: 45.472735, lng: 9.184019),
+ 2000,
+ ),
+ Meili.attr('type').eq('pizza'.toMeiliValue())
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion geosearch_guide_sort_settings_1
+ await client.index('restaurants').updateSortableAttributes(['_geo']);
+ // #enddocregion
+
+ // #docregion geosearch_guide_sort_usage_1
+ await client.index('restaurants').search(
+ '', SearchQuery(sort: ['_geoPoint(48.8561446, 2.2978204):asc']));
+ // #enddocregion
+
+ // #docregion geosearch_guide_sort_usage_2
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ sort: ['_geoPoint(48.8561446, 2.2978204):asc', 'rating:desc']));
+ // #enddocregion
+
+ // #docregion get_one_key_1
+ await client.getKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
+ // #enddocregion
+
+ // #docregion get_all_keys_1
+ await client.getKeys(params: KeysQuery(limit: 3));
+ // #enddocregion
+
+ // #docregion create_a_key_1
+ await client.createKey(
+ description: 'Add documents: Products API key',
+ actions: ['documents.add'],
+ indexes: ['products'],
+ expiresAt: DateTime(2042, 04, 02));
+ // #enddocregion
+
+ // #docregion update_a_key_1
+ await client.updateKey(
+ '6062abda-a5aa-4414-ac91-ecd7944c0f8d',
+ description: 'Manage documents: Products/Reviews API key',
+ name: 'Products/Reviews API key',
+ );
+ // #enddocregion
+
+ // #docregion delete_a_key_1
+ await client.deleteKey('6062abda-a5aa-4414-ac91-ecd7944c0f8d');
+ // #enddocregion
+
+ // #docregion search_parameter_guide_crop_marker_1
+ await client.index('movies').search(
+ 'shifu',
+ SearchQuery(
+ attributesToCrop: ['overview'],
+ cropMarker: '[…]',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_parameter_guide_highlight_tag_1
+ await client.index('movies').search(
+ 'winter feast',
+ SearchQuery(
+ attributesToHighlight: ['overview'],
+ highlightPreTag: '',
+ highlightPostTag: '',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion geosearch_guide_filter_usage_3
+ await client.index('restaurants').search(
+ '',
+ SearchQuery(
+ filter:
+ '_geoBoundingBox([45.494181, 9.214024], [45.449484, 9.179175])'));
+ });
+ // #enddocregion
+ // skip this test, since it's only used for generating code samples
+ }, skip: true);
+
+// unformatted examples
+/*
+ // #docregion getting_started_search_md
+ ```dart
+ await client.index('movies').search('botman');
+ ```
+
+ [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
+ // #enddocregion
+
+ // #docregion getting_started_add_documents_md
+ ```bash
+ dart pub add meilisearch
+ ```
+
+ ```dart
+ import 'package:meilisearch/meilisearch.dart';
+ import 'dart:io';
+ import 'dart:convert';
+
+ var client = MeiliSearchClient('http://localhost:7700', 'aSampleMasterKey');
+
+ final json = await File('movies.json').readAsString();
+
+ await client.index('movies').addDocumentsJson(json);
+ ```
+
+ [About this SDK](https://github.com/meilisearch/meilisearch-dart/)
+ // #enddocregion
+*/
+}
diff --git a/test/documents_test.dart b/test/documents_test.dart
index b0c7a8e..8023a8f 100644
--- a/test/documents_test.dart
+++ b/test/documents_test.dart
@@ -557,4 +557,49 @@ void main() {
});
});
});
+
+ test(
+ 'documents code samples',
+ () async {
+ // #docregion delete_documents_by_filter_1
+ await client.index('movies').deleteDocuments(
+ DeleteDocumentsQuery(
+ filterExpression: Meili.or([
+ Meili.attr('genres').eq(Meili.value('action')),
+ Meili.attr('genres').eq(Meili.value('adventure')),
+ ]),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion get_documents_1
+ await client.index('movies').getDocuments(
+ params: DocumentsQuery(
+ limit: 2,
+ filter: Meili.attr('genres').eq('action'.toMeiliValue()),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion get_documents_post_1
+ await client.index('movies').getDocuments(
+ params: DocumentsQuery(
+ filterExpression: Meili.and([
+ 'language'.toMeiliAttribute().eq('English'.toMeiliValue()),
+ Meili.and([
+ 'rating'.toMeiliAttribute().gt(3.toMeiliValue()),
+ Meili.or([
+ 'genres'.toMeiliAttribute().eq('Adventure'.toMeiliValue()),
+ 'genres'.toMeiliAttribute().eq('Fiction'.toMeiliValue()),
+ ]),
+ ]),
+ ]),
+ fields: ['title', 'genres', 'rating', 'language'],
+ limit: 3,
+ ),
+ );
+ // #enddocregion
+ },
+ skip: true,
+ );
}
diff --git a/test/exceptions_test.dart b/test/exceptions_test.dart
index 3981a7d..6975cbf 100644
--- a/test/exceptions_test.dart
+++ b/test/exceptions_test.dart
@@ -25,7 +25,7 @@ void main() {
throwsA(isA().having(
(error) => error.toString(), // Actual
'toString() method', // Description of the check
- 'MeiliSearchApiError - message: The request returned an invalid status code of 404.', // Expected
+ contains('404'), // Expected
)),
);
});
diff --git a/test/filter_builder_test.dart b/test/filter_builder_test.dart
index 86431fc..fe962c8 100644
--- a/test/filter_builder_test.dart
+++ b/test/filter_builder_test.dart
@@ -75,7 +75,7 @@ void main() {
});
test("Dates", () {
final testData = [
- [DateTime.utc(1999, 12, 14, 18, 53, 56), '945197636000'],
+ [DateTime.utc(1999, 12, 14, 18, 53, 56), '945197636'],
];
for (var element in testData) {
diff --git a/test/multi_index_search_test.dart b/test/multi_index_search_test.dart
index 7aabbc7..64abd3f 100644
--- a/test/multi_index_search_test.dart
+++ b/test/multi_index_search_test.dart
@@ -46,4 +46,14 @@ void main() {
expect(result.results.last.hits.length, 2);
});
});
+
+ test('code samples', () async {
+ // #docregion multi_search_1
+ await client.multiSearch(MultiSearchQuery(queries: [
+ IndexSearchQuery(query: 'pooh', indexUid: 'movies', limit: 5),
+ IndexSearchQuery(query: 'nemo', indexUid: 'movies', limit: 5),
+ IndexSearchQuery(query: 'us', indexUid: 'movies_ratings'),
+ ]));
+ // #enddocregion
+ }, skip: true);
}
diff --git a/test/search_test.dart b/test/search_test.dart
index 0fbb14f..45a1768 100644
--- a/test/search_test.dart
+++ b/test/search_test.dart
@@ -604,4 +604,102 @@ void main() {
);
});
});
+
+ test('search code samples', () async {
+ // #docregion search_get_1
+ await client.index('movies').search('American ninja');
+ // #enddocregion
+
+ // #docregion search_parameter_guide_show_ranking_score_1
+ await client
+ .index('movies')
+ .search('dragon', SearchQuery(showRankingScore: true));
+ // #enddocregion
+ }, skip: true);
+
+ test('facet search code samples', () async {
+ // #docregion facet_search_1
+ await client.index('books').facetSearch(
+ FacetSearchQuery(
+ facetQuery: 'fiction',
+ facetName: 'genres',
+ filter: 'rating > 3',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion facet_search_2
+ await client.index('books').updateFaceting(
+ Faceting(
+ sortFacetValuesBy: {
+ 'genres': FacetingSortTypes.count,
+ },
+ ),
+ );
+ // #enddocregion
+
+ // #docregion facet_search_3
+ await client.index('books').facetSearch(
+ FacetSearchQuery(
+ facetQuery: 'c',
+ facetName: 'genres',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_parameter_guide_attributes_to_search_on_1
+ await client.index('books').facetSearch(
+ FacetSearchQuery(
+ facetQuery: 'c',
+ facetName: 'genres',
+ ),
+ );
+ // #enddocregion
+
+ // #docregion search_parameter_guide_facet_stats_1
+ await client
+ .index('movie_ratings')
+ .search('Batman', SearchQuery(facets: ['genres', 'rating']));
+ // #enddocregion
+
+ // #docregion faceted_search_1
+ await client
+ .index('books')
+ .search('', SearchQuery(facets: ['genres', 'rating', 'language']));
+ // #enddocregion
+
+ // #docregion filtering_guide_nested_1
+ await client.index('movie_ratings').search(
+ 'thriller',
+ SearchQuery(
+ filterExpression: Meili.gte(
+ //or Meili.attr('rating.users')
+ //or 'rating.users'.toMeiliAttribute()
+ Meili.attrFromParts(['rating', 'users']),
+ Meili.value(90),
+ ),
+ ),
+ );
+ // #enddocregion
+
+ // #docregion sorting_guide_sort_nested_1
+ await client
+ .index('movie_ratings')
+ .search('thriller', SearchQuery(sort: ['rating.users:asc']));
+ // #enddocregion
+
+ // #docregion search_parameter_guide_page_1
+ await client
+ .index('movies')
+ .search('', SearchQuery(page: 2))
+ .asPaginatedResult();
+ // #enddocregion
+
+ // #docregion search_parameter_guide_hitsperpage_1
+ await client
+ .index('movies')
+ .search('', SearchQuery(hitsPerPage: 15))
+ .asPaginatedResult();
+ // #enddocregion
+ }, skip: true);
}
diff --git a/test/settings_test.dart b/test/settings_test.dart
index 0c457e4..c6d9862 100644
--- a/test/settings_test.dart
+++ b/test/settings_test.dart
@@ -400,4 +400,19 @@ void main() {
});
});
});
+
+ test('code samples', () async {
+ // #docregion faceted_search_update_settings_1
+ await client
+ .index('movie_ratings')
+ .updateFilterableAttributes(['genres', 'rating', 'language']);
+ // #enddocregion
+
+ // #docregion synonyms_guide_1
+ await client.index('movies').updateSynonyms({
+ 'great': ['fantastic'],
+ 'fantastic': ['great'],
+ });
+ // #enddocregion
+ });
}
diff --git a/test/swaps_test.dart b/test/swaps_test.dart
index f7f4cbd..58ba326 100644
--- a/test/swaps_test.dart
+++ b/test/swaps_test.dart
@@ -30,4 +30,13 @@ void main() {
]);
});
});
+
+ test('code samples', () async {
+ // #docregion swap_indexes_1
+ await client.swapIndexes([
+ SwapIndex(['indexA', 'indexB']),
+ SwapIndex(['indexX', 'indexY']),
+ ]);
+ // #enddocregion
+ }, skip: true);
}
diff --git a/test/tasks_test.dart b/test/tasks_test.dart
index 7a94e86..f521aeb 100644
--- a/test/tasks_test.dart
+++ b/test/tasks_test.dart
@@ -66,4 +66,60 @@ void main() {
);
});
});
+
+ test(
+ 'code samples',
+ () async {
+ // #docregion async_guide_filter_by_date_1
+ await client.getTasks(
+ params: TasksQuery(
+ afterEnqueuedAt: DateTime(2020, 10, 11, 11, 49, 53),
+ ),
+ );
+ // #enddocregion
+ // #docregion async_guide_multiple_filters_1
+ await client.getTasks(
+ params: TasksQuery(
+ indexUids: ['movies'],
+ types: ['documentAdditionOrUpdate', 'documentDeletion'],
+ statuses: ['processing'],
+ ),
+ );
+ // #enddocregion
+ // #docregion async_guide_filter_by_ids_1
+ await client.getTasks(
+ params: TasksQuery(
+ uids: [5, 10, 13],
+ ),
+ );
+ // #enddocregion
+ // #docregion async_guide_filter_by_statuses_1
+ await client.getTasks(
+ params: TasksQuery(
+ statuses: ['failed', 'canceled'],
+ ),
+ );
+ // #enddocregion
+ // #docregion async_guide_filter_by_types_1
+ await client.getTasks(
+ params: TasksQuery(
+ types: ['dumpCreation', 'indexSwap'],
+ ),
+ );
+ // #enddocregion
+ // #docregion async_guide_filter_by_index_uids_1
+ await client.getTasks(params: TasksQuery(indexUids: ['movies']));
+ // #enddocregion
+ // #docregion delete_tasks_1
+ await client.deleteTasks(params: DeleteTasksQuery(uids: [1, 2]));
+ // #enddocregion
+ // #docregion cancel_tasks_1
+ await client.cancelTasks(params: CancelTasksQuery(uids: [1, 2]));
+ // #enddocregion
+ // #docregion async_guide_canceled_by_1
+ await client.getTasks(params: TasksQuery(canceledBy: [9, 15]));
+ // #enddocregion
+ },
+ skip: true,
+ );
}
diff --git a/tool/.gitignore b/tool/.gitignore
new file mode 100644
index 0000000..3a85790
--- /dev/null
+++ b/tool/.gitignore
@@ -0,0 +1,3 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
diff --git a/tool/analysis_options.yaml b/tool/analysis_options.yaml
new file mode 100644
index 0000000..c0a9532
--- /dev/null
+++ b/tool/analysis_options.yaml
@@ -0,0 +1,18 @@
+# This file configures the static analysis results for your project (errors,
+# warnings, and lints).
+#
+# This enables the 'recommended' set of lints from `package:lints`.
+# This set helps identify many issues that may lead to problems when running
+# or consuming Dart code, and enforces writing Dart using a single, idiomatic
+# style and format.
+#
+# If you want a smaller set of lints you can change this to specify
+# 'package:lints/core.yaml'. These are just the most critical lints
+# (the recommended set includes the core lints).
+# The core lints are also what is used by pub.dev for scoring packages.
+
+include: package:lints/recommended.yaml
+
+linter:
+ rules:
+ avoid_print: false
diff --git a/tool/bin/meili.dart b/tool/bin/meili.dart
new file mode 100644
index 0000000..201457b
--- /dev/null
+++ b/tool/bin/meili.dart
@@ -0,0 +1 @@
+export 'package:meili_tool/src/main.dart';
diff --git a/tool/lib/src/command_base.dart b/tool/lib/src/command_base.dart
new file mode 100644
index 0000000..bd7853d
--- /dev/null
+++ b/tool/lib/src/command_base.dart
@@ -0,0 +1,37 @@
+import 'package:args/command_runner.dart';
+import 'package:file/file.dart';
+import 'package:meili_tool/src/result.dart';
+import 'package:platform/platform.dart';
+import 'package:path/path.dart' as p;
+
+abstract class MeiliCommandBase extends Command {
+ final Directory packageDirectory;
+
+ MeiliCommandBase(
+ this.packageDirectory, {
+ this.platform = const LocalPlatform(),
+ });
+
+ /// The current platform.
+ ///
+ /// This can be overridden for testing.
+ final Platform platform;
+
+ /// A context that matches the default for [platform].
+ p.Context get path => platform.isWindows ? p.windows : p.posix;
+ // Returns the relative path from [from] to [entity] in Posix style.
+ ///
+ /// This should be used when, for example, printing package-relative paths in
+ /// status or error messages.
+ String getRelativePosixPath(
+ FileSystemEntity entity, {
+ required Directory from,
+ }) =>
+ p.posix.joinAll(path.split(path.relative(entity.path, from: from.path)));
+
+ String get indentation => ' ';
+
+ bool getBoolArg(String key) {
+ return (argResults![key] as bool?) ?? false;
+ }
+}
diff --git a/tool/lib/src/core.dart b/tool/lib/src/core.dart
new file mode 100644
index 0000000..9835d0a
--- /dev/null
+++ b/tool/lib/src/core.dart
@@ -0,0 +1,16 @@
+/// Error thrown when a command needs to exit with a non-zero exit code.
+///
+/// While there is no specific definition of the meaning of different non-zero
+/// exit codes for this tool, commands should follow the general convention:
+/// 1: The command ran correctly, but found errors.
+/// 2: The command failed to run because the arguments were invalid.
+/// >2: The command failed to run correctly for some other reason. Ideally,
+/// each such failure should have a unique exit code within the context of
+/// that command.
+class ToolExit extends Error {
+ /// Creates a tool exit with the given [exitCode].
+ ToolExit(this.exitCode);
+
+ /// The code that the process should exit with.
+ final int exitCode;
+}
diff --git a/tool/lib/src/main.dart b/tool/lib/src/main.dart
new file mode 100644
index 0000000..ce3dc16
--- /dev/null
+++ b/tool/lib/src/main.dart
@@ -0,0 +1,53 @@
+import 'dart:io' as io;
+
+import 'package:args/command_runner.dart';
+import 'package:file/file.dart';
+import 'package:file/local.dart';
+import 'package:meili_tool/src/output_utils.dart';
+import 'package:meili_tool/src/result.dart';
+
+import 'core.dart';
+import 'update_samples_command.dart';
+
+void main(List arguments) {
+ const FileSystem fileSystem = LocalFileSystem();
+ final Directory scriptDir =
+ fileSystem.file(io.Platform.script.toFilePath()).parent;
+ final Directory toolsDir =
+ scriptDir.basename == 'bin' ? scriptDir.parent : scriptDir.parent.parent;
+
+ final Directory meilisearchDirectory = toolsDir.parent;
+
+ final commandRunner = CommandRunner(
+ 'dart run ./tool/bin/meili.dart', 'Productivity utils for meilisearch.')
+ ..addCommand(UpdateSamplesCommand(meilisearchDirectory));
+
+ commandRunner.run(arguments).then((value) {
+ if (value == null) {
+ print('MUST output either a success or fail.');
+ assert(false);
+ io.exit(255);
+ }
+ switch (value.state) {
+ case RunState.succeeded:
+ printSuccess('Success!');
+ break;
+ case RunState.failed:
+ printError('Failed!');
+ if (value.details.isNotEmpty) {
+ printError(value.details.join('\n'));
+ }
+ io.exit(255);
+ }
+ }).catchError((Object e) {
+ final ToolExit toolExit = e as ToolExit;
+ int exitCode = toolExit.exitCode;
+ // This should never happen; this check is here to guarantee that a ToolExit
+ // never accidentally has code 0 thus causing CI to pass.
+ if (exitCode == 0) {
+ assert(false);
+ exitCode = 255;
+ }
+ io.exit(exitCode);
+ }, test: (Object e) => e is ToolExit);
+}
diff --git a/tool/lib/src/output_utils.dart b/tool/lib/src/output_utils.dart
new file mode 100644
index 0000000..7fd39f6
--- /dev/null
+++ b/tool/lib/src/output_utils.dart
@@ -0,0 +1,44 @@
+// Copyright 2013 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:colorize/colorize.dart';
+import 'package:meta/meta.dart';
+
+export 'package:colorize/colorize.dart' show Styles;
+
+/// True if color should be applied.
+///
+/// Defaults to autodetecting stdout.
+@visibleForTesting
+bool useColorForOutput = stdout.supportsAnsiEscapes;
+
+String _colorizeIfAppropriate(String string, Styles color) {
+ if (!useColorForOutput) {
+ return string;
+ }
+ return Colorize(string).apply(color).toString();
+}
+
+/// Prints [message] in green, if the environment supports color.
+void printSuccess(String message) {
+ print(_colorizeIfAppropriate(message, Styles.GREEN));
+}
+
+/// Prints [message] in yellow, if the environment supports color.
+void printWarning(String message) {
+ print(_colorizeIfAppropriate(message, Styles.YELLOW));
+}
+
+/// Prints [message] in red, if the environment supports color.
+void printError(String message) {
+ print(_colorizeIfAppropriate(message, Styles.RED));
+}
+
+/// Returns [message] with escapes to print it in [color], if the environment
+/// supports color.
+String colorizeString(String message, Styles color) {
+ return _colorizeIfAppropriate(message, color);
+}
diff --git a/tool/lib/src/result.dart b/tool/lib/src/result.dart
new file mode 100644
index 0000000..331bf43
--- /dev/null
+++ b/tool/lib/src/result.dart
@@ -0,0 +1,34 @@
+/// Possible outcomes of a command run for a package.
+enum RunState {
+ /// The command succeeded for the package.
+ succeeded,
+
+ /// The command failed for the package.
+ failed,
+}
+
+/// The result of a [runForPackage] call.
+class PackageResult {
+ /// A successful result.
+ PackageResult.success() : this._(RunState.succeeded);
+
+ /// A run that failed.
+ ///
+ /// If [errors] are provided, they will be listed in the summary, otherwise
+ /// the summary will simply show that the package failed.
+ PackageResult.fail([List errors = const []])
+ : this._(RunState.failed, errors);
+
+ const PackageResult._(this.state, [this.details = const []]);
+
+ /// The state the package run completed with.
+ final RunState state;
+
+ /// Information about the result:
+ /// - For `succeeded`, this is empty.
+ /// - For `skipped`, it contains a single entry describing why the run was
+ /// skipped.
+ /// - For `failed`, it contains zero or more specific error details to be
+ /// shown in the summary.
+ final List details;
+}
diff --git a/tool/lib/src/update_samples_command.dart b/tool/lib/src/update_samples_command.dart
new file mode 100644
index 0000000..5462008
--- /dev/null
+++ b/tool/lib/src/update_samples_command.dart
@@ -0,0 +1,269 @@
+// Source: https://github.com/flutter/packages/blob/d0411e450a8d94fcb221e8d8eacd3b1f8ca0e2fc/script/tool/lib/src/update_excerpts_command.dart
+// but modified to accept yaml files.
+
+import 'dart:async';
+import 'package:file/file.dart';
+import 'package:http/http.dart' as http;
+import 'package:meili_tool/src/command_base.dart';
+import 'package:meili_tool/src/result.dart';
+import 'package:yaml/yaml.dart';
+import 'package:yaml_edit/yaml_edit.dart';
+
+class _SourceFile {
+ final File file;
+ final List contents;
+ Map? result;
+
+ _SourceFile({
+ required this.file,
+ required this.contents,
+ });
+}
+
+class UpdateSamplesCommand extends MeiliCommandBase {
+ static const String _failOnChangeFlag = 'fail-on-change';
+ static const String _checkRemoteRepoFlag = 'check-remote-repository';
+ static const String _generateMissingExcerpts = 'generate-missing-excerpts';
+
+ UpdateSamplesCommand(
+ super.packageDirectory, {
+ super.platform,
+ }) {
+ argParser.addFlag(
+ _failOnChangeFlag,
+ help: 'Fail if the command does anything. '
+ '(Used in CI to ensure excerpts are up to date.)',
+ );
+ argParser.addFlag(
+ _checkRemoteRepoFlag,
+ hide: true,
+ help:
+ 'Check the remote code samples to see if there are missing/useless keys',
+ );
+ argParser.addFlag(
+ _generateMissingExcerpts,
+ hide: true,
+ help: 'Generate entries that are found in code samples, but not in code',
+ );
+ }
+
+ @override
+ String get description =>
+ 'Updates .code-samples.meilisearch.yaml, based on code from code files';
+
+ @override
+ String get name => 'update-samples';
+
+ static const docregion = '#docregion';
+ static const enddocregion = '#enddocregion';
+ final startRegionRegex = RegExp(RegExp.escape(docregion) + r'\s+(?\w+)');
+
+ @override
+ Future run() async {
+ try {
+ final failOnChange = getBoolArg(_failOnChangeFlag);
+ final checkRemoteRepo = getBoolArg(_checkRemoteRepoFlag);
+ final generateMissingExcerpts = getBoolArg(_generateMissingExcerpts);
+ //read the samples yaml file
+ final changedKeys = {};
+ final File samplesFile =
+ packageDirectory.childFile('.code-samples.meilisearch.yaml');
+ final samplesContentRaw = await samplesFile.readAsString();
+ final samplesYaml = loadYaml(samplesContentRaw);
+ if (samplesYaml is! YamlMap) {
+ print(samplesYaml.runtimeType);
+ return PackageResult.fail(['samples yaml must be an YamlMap']);
+ }
+
+ final newSamplesYaml = YamlEditor(samplesContentRaw);
+ final foundCodeSamples = {};
+ final missingSamples = {};
+ final sourceFiles = await _discoverSourceFiles();
+ for (var sourceFile in sourceFiles) {
+ final newValues = _runInFile(sourceFile);
+ foundCodeSamples.addAll(newValues);
+ sourceFile.result = newValues;
+ for (var element in newValues.entries) {
+ final existingValue = samplesYaml[element.key];
+ if (existingValue != null) {
+ if (existingValue == element.value) {
+ continue;
+ } else {
+ changedKeys[element.key] = element.value;
+ }
+ } else {
+ changedKeys[element.key] = element.value;
+ }
+ }
+ if (failOnChange && changedKeys.isNotEmpty) {
+ return PackageResult.fail([
+ 'found changed keys: ${changedKeys.keys.toList()}',
+ ]);
+ }
+
+ if (!failOnChange) {
+ for (var changedEntry in changedKeys.entries) {
+ newSamplesYaml.update([changedEntry.key], changedEntry.value);
+ }
+ }
+ }
+
+ for (var entry in samplesYaml.entries) {
+ if (foundCodeSamples.containsKey(entry.key)) {
+ continue;
+ }
+ missingSamples[entry.key] = entry.value;
+ }
+ if (generateMissingExcerpts) {
+ final targetFile = packageDirectory
+ .childDirectory('test')
+ .childFile('missing_samples.dart');
+ final sb = StringBuffer();
+
+ sb.writeln(r"import 'package:meilisearch/meilisearch.dart';");
+ sb.writeln('late MeiliSearchClient client;');
+ sb.writeln('void main() async {');
+ for (var element in missingSamples.entries) {
+ sb.writeln('// #docregion ${element.key}');
+ sb.writeln(element.value);
+ sb.writeln('// #enddocregion');
+ sb.writeln();
+ }
+ sb.writeln('}');
+ await targetFile.writeAsString(sb.toString());
+ }
+
+ // for now don't check remote repository
+ if (checkRemoteRepo) {
+ final fullSamplesYaml = await getFullCorrectSamples();
+ final missingEntries = fullSamplesYaml.entries
+ .where((element) => !samplesYaml.containsKey(element.key));
+ final oldEntries = samplesYaml.entries
+ .where((element) => !fullSamplesYaml.containsKey(element.key));
+ if (failOnChange) {
+ if (missingEntries.isNotEmpty || oldEntries.isNotEmpty) {
+ return PackageResult.fail([
+ if (missingEntries.isNotEmpty)
+ 'found the following missing entries: ${missingEntries.map((e) => e.key).join('\n')}',
+ if (oldEntries.isNotEmpty)
+ 'found the following useless entries: ${oldEntries.map((e) => e.key).join('\n')}',
+ ]);
+ }
+ } else {
+ for (var element in missingEntries) {
+ newSamplesYaml.update([element.key], element.value);
+ }
+ for (var element in oldEntries) {
+ newSamplesYaml.remove([element.key]);
+ }
+ }
+ }
+
+ if (!failOnChange && !generateMissingExcerpts) {
+ await samplesFile.writeAsString(newSamplesYaml.toString());
+ }
+ return PackageResult.success();
+ } on PackageResult catch (e) {
+ return e;
+ }
+ }
+
+ Future getFullCorrectSamples() async {
+ final uri = Uri.parse(
+ 'https://raw.githubusercontent.com/meilisearch/documentation/main/.code-samples.meilisearch.yaml');
+ final data = await http.get(uri);
+ final parsed = loadYaml(data.body, sourceUrl: uri);
+ return parsed as YamlMap;
+ }
+
+ Map _runInFile(_SourceFile file) {
+ int lineNumber = 0;
+ String? currentKey;
+ final keys = [];
+ final res = {};
+ final currentKeyLines = >[];
+ for (var line in file.contents) {
+ lineNumber++;
+ if (currentKey == null) {
+ final capture = startRegionRegex.firstMatch(line);
+ if (capture == null) {
+ continue;
+ }
+ final key = capture.namedGroup('key');
+ if (key == null) {
+ throw PackageResult.fail(['found a #docregion with no key']);
+ }
+ if (keys.contains(key)) {
+ throw PackageResult.fail(['found duplicate keys $key']);
+ }
+ keys.add(key);
+ currentKey = key;
+ } else {
+ if (line.contains(enddocregion)) {
+ final sb = StringBuffer();
+ final unindentedLines =
+ unindentLines(currentKeyLines.map((e) => e.value).toList())
+ .join('\n');
+ sb.write(unindentedLines);
+ //add to results.
+ res[currentKey] = sb.toString();
+
+ currentKey = null;
+ currentKeyLines.clear();
+ } else {
+ currentKeyLines.add(MapEntry(lineNumber, line));
+ }
+ }
+ }
+ return res;
+ }
+
+ List unindentLines(List src) {
+ if (src.isEmpty) {
+ return src;
+ }
+ final ogFirst = src.first;
+ final trimmedFirst = ogFirst.trimLeft();
+ final firstIndentation = ogFirst.length - trimmedFirst.length;
+ final res = [];
+ for (var element in src) {
+ final trimmedLine = element.trimLeft();
+ if (trimmedLine.isEmpty) {
+ continue;
+ }
+ var indentation = element.length - trimmedLine.length;
+ indentation -= firstIndentation;
+ res.add('${" " * indentation}$trimmedLine');
+ }
+
+ return res;
+ }
+
+ Future> _discoverSourceFiles() async {
+ final libDir = packageDirectory.childDirectory('lib');
+ final testsDir = packageDirectory.childDirectory('test');
+ //look in dart files and generate a new yaml file based on the referenced code.
+ final allDartFiles = [
+ ...libDir.listSync(recursive: true),
+ ...testsDir.listSync(recursive: true),
+ ].where((element) => element.basename.toLowerCase().endsWith('.dart'));
+
+ final sourceFiles = <_SourceFile>[];
+ for (var dartFile in allDartFiles) {
+ if (dartFile is! File) {
+ continue;
+ }
+ final fileContents = await dartFile.readAsLines();
+ if (!fileContents.any((line) => line.contains(docregion))) {
+ continue;
+ }
+ sourceFiles.add(
+ _SourceFile(
+ file: dartFile,
+ contents: fileContents,
+ ),
+ );
+ }
+ return sourceFiles;
+ }
+}
diff --git a/tool/pubspec.yaml b/tool/pubspec.yaml
new file mode 100644
index 0000000..be5bf8b
--- /dev/null
+++ b/tool/pubspec.yaml
@@ -0,0 +1,30 @@
+name: meili_tool
+description: |
+ Productivity tools for meilisearch dart repository,
+ most of this is inspired from the flutter packages repository https://github.com/flutter/packages/.
+version: 1.0.0
+repository: https://github.com/meilisearch/meilisearch-dart
+
+environment:
+ sdk: '>=3.0.0 <4.0.0'
+
+# Add regular dependencies here.
+dependencies:
+ lints: ^2.0.0
+ test: ^1.21.0
+ args: ^2.4.2
+ cli_util: ^0.4.0
+ file: ^7.0.0
+ path: ^1.8.3
+ platform: ^3.1.2
+ collection: ^1.15.0
+ colorize: ^3.0.0
+ meta: ^1.10.0
+ yaml: ^3.1.2
+ yaml_edit: ^2.1.1
+ http: ^1.1.0
+
+dev_dependencies:
+ build_runner: ^2.0.3
+ matcher: ^0.12.10
+ mockito: '>=5.3.2 <=5.4.0'