meilisearch 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6309d55fa663d9fd8126c1bbf290313ddab29e0e8e72ee690b0abe49887d6097
4
- data.tar.gz: 2386993d60f7fa52c38e10d58e191a0f0797a3672de31a36b5c1013440285584
3
+ metadata.gz: c9f1a9263f33fa8d970a5e29e89ce13b213deaaa187c557e6122e2960973e22b
4
+ data.tar.gz: 5aeed7da3ed485ee621db8ea182574e50681cd1efe8a5d58430cce271c17e304
5
5
  SHA512:
6
- metadata.gz: d50aa62ffebcd4d707fc55471e8738d9dd53433c77af3f1bb08e3681395ee19eb35513bc14a1e769bf223a9e16622805dc1010d06b4b84c2252237d1eb5a8b97
7
- data.tar.gz: fff2a910e52b6c137037c3b011ddba3b0d11d28fd2427c1b4d45e925e2b28711c4e0fca269309de9b97dd99df980e4ed067b322c7148c0fde68a14ce4fe7d388
6
+ metadata.gz: 976733a7fa10473cc9cc2a972d70b50e70c4911fcf210d256f8407042040ef2314d3ae180d9946d6b7e68fb2ea24a219b3748bb9f4b88f0e8a725951a5718e92
7
+ data.tar.gz: ca1bbd991097e90eebfcc0aa08ecb71e7234453dfb9ab4d67dd6d30036af39992e769674e9fe2f98758cc77e7597f4637071170811ea4b9bb1ba9db5e68871fa
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019-2021 Meili
3
+ Copyright (c) 2019-2022 Meili SAS
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -187,8 +187,7 @@ JSON output:
187
187
  ]
188
188
  }
189
189
  ],
190
- "nbHits": 1,
191
- "exhaustiveNbHits": false,
190
+ "estimatedTotalHits": 1,
192
191
  "query": "wonder",
193
192
  "limit": 20,
194
193
  "offset": 0,
@@ -198,7 +197,7 @@ JSON output:
198
197
 
199
198
  ## 🤖 Compatibility with Meilisearch
200
199
 
201
- This package only guarantees the compatibility with the [version v0.25.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.25.0).
200
+ This package only guarantees the compatibility with the [version v0.28.0 of Meilisearch](https://github.com/meilisearch/meilisearch/releases/tag/v0.28.0).
202
201
 
203
202
  ## 💡 Learn More
204
203
 
@@ -1,19 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'meilisearch/http_request'
4
-
5
3
  module MeiliSearch
6
4
  class Client < HTTPRequest
5
+ include MeiliSearch::TenantToken
6
+
7
7
  ### INDEXES
8
8
 
9
- def raw_indexes
10
- http_get('/indexes')
9
+ def raw_indexes(options = {})
10
+ body = Utils.transform_attributes(options.transform_keys(&:to_sym).slice(:limit, :offset))
11
+
12
+ http_get('/indexes', body)
11
13
  end
12
14
 
13
- def indexes
14
- raw_indexes.map do |index_hash|
15
+ def indexes(options = {})
16
+ response = raw_indexes(options)
17
+
18
+ response['results'].map! do |index_hash|
15
19
  index_object(index_hash['uid'], index_hash['primaryKey'])
16
20
  end
21
+
22
+ response
17
23
  end
18
24
 
19
25
  # Usage:
@@ -29,7 +35,7 @@ module MeiliSearch
29
35
  # Waits for the task to be achieved, be careful when using it.
30
36
  def create_index!(index_uid, options = {})
31
37
  task = create_index(index_uid, options)
32
- wait_for_task(task['uid'])
38
+ wait_for_task(task['taskUid'])
33
39
  end
34
40
 
35
41
  def delete_index(index_uid)
@@ -52,12 +58,14 @@ module MeiliSearch
52
58
 
53
59
  ### KEYS
54
60
 
55
- def keys
56
- http_get '/keys'
61
+ def keys(limit: nil, offset: nil)
62
+ body = { limit: limit, offset: offset }.compact
63
+
64
+ http_get '/keys', body
57
65
  end
58
66
 
59
- def key(key_uid)
60
- http_get "/keys/#{key_uid}"
67
+ def key(uid_or_key)
68
+ http_get "/keys/#{uid_or_key}"
61
69
  end
62
70
 
63
71
  def create_key(key_options)
@@ -66,14 +74,15 @@ module MeiliSearch
66
74
  http_post '/keys', body
67
75
  end
68
76
 
69
- def update_key(key_uid, key_options)
77
+ def update_key(uid_or_key, key_options)
70
78
  body = Utils.transform_attributes(key_options)
79
+ body = body.slice('description', 'name')
71
80
 
72
- http_patch "/keys/#{key_uid}", body
81
+ http_patch "/keys/#{uid_or_key}", body
73
82
  end
74
83
 
75
- def delete_key(key_uid)
76
- http_delete "/keys/#{key_uid}"
84
+ def delete_key(uid_or_key)
85
+ http_delete "/keys/#{uid_or_key}"
77
86
  end
78
87
 
79
88
  ### HEALTH
@@ -105,15 +114,10 @@ module MeiliSearch
105
114
  http_post '/dumps'
106
115
  end
107
116
 
108
- def dump_status(dump_uid)
109
- http_get "/dumps/#{dump_uid}/status"
110
- end
111
- alias get_dump_status dump_status
112
-
113
117
  ### TASKS
114
118
 
115
- def tasks
116
- task_endpoint.task_list
119
+ def tasks(options = {})
120
+ task_endpoint.task_list(options)
117
121
  end
118
122
 
119
123
  def task(task_uid)
@@ -57,9 +57,15 @@ module MeiliSearch
57
57
  class TimeoutError < StandardError
58
58
  attr_reader :message
59
59
 
60
- def initialize
61
- @message = 'The update was not processed in the expected time'
60
+ def initialize(message = nil)
61
+ @message = "The request was not processed in the expected time. #{message}"
62
62
  super(@message)
63
63
  end
64
64
  end
65
+
66
+ module TenantToken
67
+ class ExpireOrInvalidSignature < StandardError; end
68
+ class InvalidApiKey < StandardError; end
69
+ class InvalidSearchRules < StandardError; end
70
+ end
65
71
  end
@@ -103,8 +103,10 @@ module MeiliSearch
103
103
 
104
104
  begin
105
105
  response = http_method.call(@base_url + relative_path, config)
106
- rescue Errno::ECONNREFUSED => e
106
+ rescue Errno::ECONNREFUSED, Errno::EPIPE => e
107
107
  raise CommunicationError, e.message
108
+ rescue Net::ReadTimeout, Net::OpenTimeout => e
109
+ raise TimeoutError, e.message
108
110
  end
109
111
 
110
112
  validate(response)
@@ -30,7 +30,7 @@ module MeiliSearch
30
30
  end
31
31
 
32
32
  def update(body)
33
- http_put indexes_path(id: @uid), Utils.transform_attributes(body)
33
+ http_patch indexes_path(id: @uid), Utils.transform_attributes(body)
34
34
  end
35
35
 
36
36
  alias update_index update
@@ -54,15 +54,20 @@ module MeiliSearch
54
54
 
55
55
  ### DOCUMENTS
56
56
 
57
- def document(document_id)
57
+ def document(document_id, fields: nil)
58
58
  encode_document = URI.encode_www_form_component(document_id)
59
- http_get "/indexes/#{@uid}/documents/#{encode_document}"
59
+ body = { fields: fields&.join(',') }.compact
60
+
61
+ http_get("/indexes/#{@uid}/documents/#{encode_document}", body)
60
62
  end
61
63
  alias get_document document
62
64
  alias get_one_document document
63
65
 
64
66
  def documents(options = {})
65
- http_get "/indexes/#{@uid}/documents", Utils.transform_attributes(options)
67
+ body = Utils.transform_attributes(options.transform_keys(&:to_sym).slice(:limit, :offset, :fields))
68
+ body = body.transform_values { |v| v.respond_to?(:join) ? v.join(',') : v }
69
+
70
+ http_get "/indexes/#{@uid}/documents", body
66
71
  end
67
72
  alias get_documents documents
68
73
 
@@ -75,7 +80,7 @@ module MeiliSearch
75
80
 
76
81
  def add_documents!(documents, primary_key = nil)
77
82
  task = add_documents(documents, primary_key)
78
- wait_for_task(task['uid'])
83
+ wait_for_task(task['taskUid'])
79
84
  end
80
85
  alias replace_documents! add_documents!
81
86
  alias add_or_replace_documents! add_documents!
@@ -109,7 +114,7 @@ module MeiliSearch
109
114
 
110
115
  def update_documents!(documents, primary_key = nil)
111
116
  task = update_documents(documents, primary_key)
112
- wait_for_task(task['uid'])
117
+ wait_for_task(task['taskUid'])
113
118
  end
114
119
  alias add_or_update_documents! update_documents!
115
120
 
@@ -125,7 +130,7 @@ module MeiliSearch
125
130
  tasks = add_documents_in_batches(documents, batch_size, primary_key)
126
131
  responses = []
127
132
  tasks.each do |task_obj|
128
- responses.append(wait_for_task(task_obj['uid']))
133
+ responses.append(wait_for_task(task_obj['taskUid']))
129
134
  end
130
135
  responses
131
136
  end
@@ -142,7 +147,7 @@ module MeiliSearch
142
147
  tasks = update_documents_in_batches(documents, batch_size, primary_key)
143
148
  responses = []
144
149
  tasks.each do |task_obj|
145
- responses.append(wait_for_task(task_obj['uid']))
150
+ responses.append(wait_for_task(task_obj['taskUid']))
146
151
  end
147
152
  responses
148
153
  end
@@ -158,7 +163,7 @@ module MeiliSearch
158
163
 
159
164
  def delete_documents!(documents_ids)
160
165
  task = delete_documents(documents_ids)
161
- wait_for_task(task['uid'])
166
+ wait_for_task(task['taskUid'])
162
167
  end
163
168
  alias delete_multiple_documents! delete_documents!
164
169
 
@@ -170,7 +175,7 @@ module MeiliSearch
170
175
 
171
176
  def delete_document!(document_id)
172
177
  task = delete_document(document_id)
173
- wait_for_task(task['uid'])
178
+ wait_for_task(task['taskUid'])
174
179
  end
175
180
  alias delete_one_document! delete_document!
176
181
 
@@ -180,7 +185,7 @@ module MeiliSearch
180
185
 
181
186
  def delete_all_documents!
182
187
  task = delete_all_documents
183
- wait_for_task(task['uid'])
188
+ wait_for_task(task['taskUid'])
184
189
  end
185
190
 
186
191
  ### SEARCH
@@ -199,7 +204,7 @@ module MeiliSearch
199
204
  private :task_endpoint
200
205
 
201
206
  def task(task_uid)
202
- task_endpoint.index_task(@uid, task_uid)
207
+ task_endpoint.index_task(task_uid)
203
208
  end
204
209
 
205
210
  def tasks
@@ -236,7 +241,7 @@ module MeiliSearch
236
241
  alias get_settings settings
237
242
 
238
243
  def update_settings(settings)
239
- http_post "/indexes/#{@uid}/settings", Utils.transform_attributes(settings)
244
+ http_patch "/indexes/#{@uid}/settings", Utils.transform_attributes(settings)
240
245
  end
241
246
  alias settings= update_settings
242
247
 
@@ -252,7 +257,7 @@ module MeiliSearch
252
257
  alias get_ranking_rules ranking_rules
253
258
 
254
259
  def update_ranking_rules(ranking_rules)
255
- http_post "/indexes/#{@uid}/settings/ranking-rules", ranking_rules
260
+ http_put "/indexes/#{@uid}/settings/ranking-rules", ranking_rules
256
261
  end
257
262
  alias ranking_rules= update_ranking_rules
258
263
 
@@ -268,7 +273,7 @@ module MeiliSearch
268
273
  alias get_synonyms synonyms
269
274
 
270
275
  def update_synonyms(synonyms)
271
- http_post "/indexes/#{@uid}/settings/synonyms", synonyms
276
+ http_put "/indexes/#{@uid}/settings/synonyms", synonyms
272
277
  end
273
278
  alias synonyms= update_synonyms
274
279
 
@@ -285,7 +290,7 @@ module MeiliSearch
285
290
 
286
291
  def update_stop_words(stop_words)
287
292
  body = stop_words.nil? || stop_words.is_a?(Array) ? stop_words : [stop_words]
288
- http_post "/indexes/#{@uid}/settings/stop-words", body
293
+ http_put "/indexes/#{@uid}/settings/stop-words", body
289
294
  end
290
295
  alias stop_words= update_stop_words
291
296
 
@@ -301,7 +306,7 @@ module MeiliSearch
301
306
  alias get_distinct_attribute distinct_attribute
302
307
 
303
308
  def update_distinct_attribute(distinct_attribute)
304
- http_post "/indexes/#{@uid}/settings/distinct-attribute", distinct_attribute
309
+ http_put "/indexes/#{@uid}/settings/distinct-attribute", distinct_attribute
305
310
  end
306
311
  alias distinct_attribute= update_distinct_attribute
307
312
 
@@ -317,7 +322,7 @@ module MeiliSearch
317
322
  alias get_searchable_attributes searchable_attributes
318
323
 
319
324
  def update_searchable_attributes(searchable_attributes)
320
- http_post "/indexes/#{@uid}/settings/searchable-attributes", searchable_attributes
325
+ http_put "/indexes/#{@uid}/settings/searchable-attributes", searchable_attributes
321
326
  end
322
327
  alias searchable_attributes= update_searchable_attributes
323
328
 
@@ -333,7 +338,7 @@ module MeiliSearch
333
338
  alias get_displayed_attributes displayed_attributes
334
339
 
335
340
  def update_displayed_attributes(displayed_attributes)
336
- http_post "/indexes/#{@uid}/settings/displayed-attributes", displayed_attributes
341
+ http_put "/indexes/#{@uid}/settings/displayed-attributes", displayed_attributes
337
342
  end
338
343
  alias displayed_attributes= update_displayed_attributes
339
344
 
@@ -349,7 +354,7 @@ module MeiliSearch
349
354
  alias get_filterable_attributes filterable_attributes
350
355
 
351
356
  def update_filterable_attributes(filterable_attributes)
352
- http_post "/indexes/#{@uid}/settings/filterable-attributes", filterable_attributes
357
+ http_put "/indexes/#{@uid}/settings/filterable-attributes", filterable_attributes
353
358
  end
354
359
  alias filterable_attributes= update_filterable_attributes
355
360
 
@@ -365,7 +370,7 @@ module MeiliSearch
365
370
  alias get_sortable_attributes sortable_attributes
366
371
 
367
372
  def update_sortable_attributes(sortable_attributes)
368
- http_post "/indexes/#{@uid}/settings/sortable-attributes", sortable_attributes
373
+ http_put "/indexes/#{@uid}/settings/sortable-attributes", sortable_attributes
369
374
  end
370
375
  alias sortable_attributes= update_sortable_attributes
371
376
 
@@ -5,8 +5,13 @@ require 'timeout'
5
5
 
6
6
  module MeiliSearch
7
7
  class Task < HTTPRequest
8
- def task_list
9
- http_get '/tasks/'
8
+ ALLOWED_PARAMS = [:limit, :from, :index_uid, :type, :status].freeze
9
+
10
+ def task_list(options = {})
11
+ body = Utils.transform_attributes(options.transform_keys(&:to_sym).slice(*ALLOWED_PARAMS))
12
+ body = body.transform_values { |v| v.respond_to?(:join) ? v.join(',') : v }
13
+
14
+ http_get '/tasks/', body
10
15
  end
11
16
 
12
17
  def task(task_uid)
@@ -14,11 +19,11 @@ module MeiliSearch
14
19
  end
15
20
 
16
21
  def index_tasks(index_uid)
17
- http_get "/indexes/#{index_uid}/tasks"
22
+ http_get '/tasks', { indexUid: [index_uid].flatten.join(',') }
18
23
  end
19
24
 
20
- def index_task(index_uid, task_uid)
21
- http_get "/indexes/#{index_uid}/tasks/#{task_uid}"
25
+ def index_task(task_uid)
26
+ http_get "/tasks/#{task_uid}"
22
27
  end
23
28
 
24
29
  def wait_for_task(task_uid, timeout_in_ms = 5000, interval_in_ms = 50)
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MeiliSearch
4
+ module TenantToken
5
+ HEADER = {
6
+ typ: 'JWT',
7
+ alg: 'HS256'
8
+ }.freeze
9
+
10
+ def generate_tenant_token(api_key_uid, search_rules, api_key: nil, expires_at: nil)
11
+ signature = retrieve_valid_key!(api_key, @api_key)
12
+ expiration = validate_expires_at!(expires_at)
13
+ rules = validate_search_rules!(search_rules)
14
+ unsigned_data = build_payload(expiration, rules, api_key_uid)
15
+
16
+ combine(unsigned_data, to_base64(sign_data(signature, unsigned_data)))
17
+ end
18
+
19
+ private
20
+
21
+ def build_payload(expiration, rules, api_key_uid)
22
+ payload = {
23
+ searchRules: rules,
24
+ apiKeyUid: api_key_uid,
25
+ exp: expiration
26
+ }
27
+
28
+ combine(encode(HEADER), encode(payload))
29
+ end
30
+
31
+ def validate_expires_at!(expires_at)
32
+ return unless expires_at
33
+ return expires_at.to_i if expires_at.utc? && expires_at > Time.now.utc
34
+
35
+ raise
36
+ rescue StandardError
37
+ raise ExpireOrInvalidSignature
38
+ end
39
+
40
+ def validate_search_rules!(data)
41
+ return data if data
42
+
43
+ raise InvalidSearchRules
44
+ end
45
+
46
+ def retrieve_valid_key!(*keys)
47
+ key = keys.compact.find { |k| !k.empty? }
48
+
49
+ raise InvalidApiKey if key.nil?
50
+
51
+ key
52
+ end
53
+
54
+ def sign_data(key, msg)
55
+ OpenSSL::HMAC.digest('SHA256', key, msg)
56
+ end
57
+
58
+ def to_base64(data)
59
+ Base64.urlsafe_encode64(data, padding: false)
60
+ end
61
+
62
+ def encode(data)
63
+ to_base64(JSON.generate(data))
64
+ end
65
+
66
+ def combine(*parts)
67
+ parts.join('.')
68
+ end
69
+ end
70
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MeiliSearch
4
- VERSION = '0.18.1'
4
+ VERSION = '0.19.0'
5
5
 
6
6
  def self.qualified_version
7
7
  "Meilisearch Ruby (v#{VERSION})"
data/lib/meilisearch.rb CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'meilisearch/version'
4
4
  require 'meilisearch/utils'
5
+ require 'meilisearch/http_request'
6
+ require 'meilisearch/tenant_token'
5
7
  require 'meilisearch/task'
6
8
  require 'meilisearch/client'
7
9
  require 'meilisearch/index'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meilisearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Meili
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-01 00:00:00.000000000 Z
11
+ date: 2022-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -44,6 +44,7 @@ files:
44
44
  - lib/meilisearch/http_request.rb
45
45
  - lib/meilisearch/index.rb
46
46
  - lib/meilisearch/task.rb
47
+ - lib/meilisearch/tenant_token.rb
47
48
  - lib/meilisearch/utils.rb
48
49
  - lib/meilisearch/version.rb
49
50
  homepage: https://github.com/meilisearch/meilisearch-ruby