warb 0.1.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -12
  3. data/README.md +9 -32
  4. data/Rakefile +3 -3
  5. data/docs/README.md +1 -4
  6. data/docs/components/README.md +1 -4
  7. data/docs/messages/README.md +1 -2
  8. data/docs/messages/interactive_call_to_action_url.md +9 -9
  9. data/docs/messages/interactive_list.md +2 -2
  10. data/docs/messages/interactive_reply_button.md +9 -9
  11. data/examples/audio.rb +10 -10
  12. data/examples/document.rb +34 -34
  13. data/examples/image.rb +22 -22
  14. data/examples/interactive_call_to_action_url.rb +46 -46
  15. data/examples/interactive_list.rb +61 -61
  16. data/examples/interactive_reply_button.rb +43 -43
  17. data/examples/location.rb +32 -32
  18. data/examples/location_request.rb +11 -11
  19. data/examples/message.rb +8 -8
  20. data/examples/sticker.rb +10 -10
  21. data/examples/video.rb +22 -22
  22. data/examples/webhook.rb +42 -44
  23. data/lib/warb/client.rb +5 -7
  24. data/lib/warb/components/action.rb +8 -12
  25. data/lib/warb/configuration.rb +1 -4
  26. data/lib/warb/connection.rb +9 -15
  27. data/lib/warb/dispatcher.rb +3 -4
  28. data/lib/warb/dispatcher_concern.rb +0 -6
  29. data/lib/warb/indicator_dispatcher.rb +4 -4
  30. data/lib/warb/media_dispatcher.rb +10 -10
  31. data/lib/warb/resources/audio.rb +1 -1
  32. data/lib/warb/resources/contact.rb +20 -22
  33. data/lib/warb/resources/document.rb +1 -1
  34. data/lib/warb/resources/flow.rb +8 -10
  35. data/lib/warb/resources/image.rb +1 -1
  36. data/lib/warb/resources/interactive_call_to_action_url.rb +8 -10
  37. data/lib/warb/resources/interactive_list.rb +5 -7
  38. data/lib/warb/resources/interactive_reply_button.rb +8 -10
  39. data/lib/warb/resources/location.rb +1 -11
  40. data/lib/warb/resources/location_request.rb +3 -5
  41. data/lib/warb/resources/reaction.rb +1 -1
  42. data/lib/warb/resources/resource.rb +4 -12
  43. data/lib/warb/resources/sticker.rb +1 -1
  44. data/lib/warb/resources/text.rb +3 -21
  45. data/lib/warb/resources/video.rb +1 -1
  46. data/lib/warb/utils.rb +1 -3
  47. data/lib/warb/version.rb +1 -1
  48. data/lib/warb.rb +31 -50
  49. metadata +3 -29
  50. data/docs/components/button.md +0 -61
  51. data/docs/components/copy_code_button.md +0 -57
  52. data/docs/components/url_button.md +0 -57
  53. data/docs/messages/template.md +0 -327
  54. data/docs/resources/currency.md +0 -22
  55. data/docs/resources/date_time.md +0 -11
  56. data/docs/resources/index.md +0 -14
  57. data/docs/resources/text.md +0 -9
  58. data/lib/warb/components/button.rb +0 -29
  59. data/lib/warb/components/component.rb +0 -19
  60. data/lib/warb/components/copy_code_button.rb +0 -30
  61. data/lib/warb/components/quick_reply_button.rb +0 -15
  62. data/lib/warb/components/url_button.rb +0 -30
  63. data/lib/warb/components/voice_call_button.rb +0 -15
  64. data/lib/warb/errors.rb +0 -27
  65. data/lib/warb/language.rb +0 -8
  66. data/lib/warb/resources/currency.rb +0 -47
  67. data/lib/warb/resources/date_time.rb +0 -34
  68. data/lib/warb/resources/template.rb +0 -167
  69. data/lib/warb/response.rb +0 -33
  70. data/lib/warb/response_error_handler.rb +0 -42
  71. data/lib/warb/template_dispatcher.rb +0 -12
@@ -8,34 +8,28 @@ module Warb
8
8
  @client = client
9
9
  end
10
10
 
11
- # rubocop:disable Metrics/ParameterLists
12
11
  def send_request(http_method:, endpoint:, url: nil, data: {}, headers: {}, multipart: false,
13
12
  endpoint_prefix: :sender_id)
14
- conn = connection(url:, multipart:)
15
- response = conn.send(http_method, handle_endpoint(endpoint:, endpoint_prefix:), data, headers)
16
- if response.success?
17
- Warb::Response.new(response.body)
18
- else
19
- Warb::ResponseErrorHandler.new(response.body, response.status).handle
20
- end
21
- rescue Faraday::Error => e
22
- msg = e.response_body || e.message
23
- raise RequestError, msg
13
+ conn = set_connection(url:, multipart:)
14
+ conn.send(http_method, handle_endpoint(endpoint:, endpoint_prefix:), data, headers)
15
+ rescue StandardError => e
16
+ @client.logger.error e.inspect
17
+ e.response
24
18
  end
25
- # rubocop:enable Metrics/ParameterLists
26
19
 
27
20
  private
28
21
 
29
- def connection(url:, multipart:)
30
- url ||= 'https://graph.facebook.com/v22.0'
22
+ def set_connection(url:, multipart:)
23
+ url ||= "https://graph.facebook.com/v22.0"
31
24
 
32
25
  Faraday.new(url) do |conn|
33
26
  conn.request(:multipart) if multipart
34
27
  conn.request(:url_encoded) if multipart
35
28
  conn.request(:json)
36
29
  conn.response(:json)
37
- conn.headers['Authorization'] = "Bearer #{@client.access_token}" unless @client.access_token.nil?
30
+ conn.headers["Authorization"] = "Bearer #{@client.access_token}" unless @client.access_token.nil?
38
31
  conn.adapter(@client.adapter)
32
+ conn.response :raise_error
39
33
  end
40
34
  end
41
35
 
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Warb
4
2
  class Dispatcher
5
3
  def initialize(klass, client)
@@ -8,10 +6,11 @@ module Warb
8
6
  end
9
7
 
10
8
  def dispatch(recipient_number, reply_to: nil, **args, &block)
11
- resource = block_given? ? @klass.new(**args).tap(&block) : @klass.new(**args)
9
+ resource = block_given? ? @klass.new.tap(&block) : @klass.new(**args)
12
10
 
13
11
  data = resource.call(recipient_number, reply_to:)
14
- @client.post('messages', data)
12
+
13
+ @client.post("messages", data)
15
14
  end
16
15
  end
17
16
  end
@@ -1,5 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Warb
4
2
  module DispatcherConcern
5
3
  def message
@@ -58,10 +56,6 @@ module Warb
58
56
  @contact ||= Dispatcher.new Resources::Contact, dispatcher
59
57
  end
60
58
 
61
- def template
62
- @template ||= TemplateDispatcher.new Resources::Template, dispatcher
63
- end
64
-
65
59
  def flow
66
60
  @flow ||= Dispatcher.new Resources::Flow, dispatcher
67
61
  end
@@ -7,15 +7,15 @@ module Warb
7
7
  end
8
8
 
9
9
  def send_typing_indicator(message_id)
10
- data = common_indicator_params(message_id).merge(typing_indicator: { type: 'text' })
10
+ data = common_indicator_params(message_id).merge(typing_indicator: { type: "text" })
11
11
 
12
- @client.post('messages', data)
12
+ @client.post("messages", data)
13
13
  end
14
14
 
15
15
  def mark_as_read(message_id)
16
16
  data = common_indicator_params(message_id)
17
17
 
18
- @client.post('messages', data)
18
+ @client.post("messages", data)
19
19
  end
20
20
 
21
21
  private
@@ -24,7 +24,7 @@ module Warb
24
24
  {
25
25
  messaging_product: Warb::MESSAGING_PRODUCT,
26
26
  message_id: message_id,
27
- status: 'read'
27
+ status: "read"
28
28
  }
29
29
  end
30
30
  end
@@ -1,21 +1,21 @@
1
- # frozen_string_literal: true
2
-
3
1
  module Warb
4
2
  class MediaDispatcher < Dispatcher
5
- def upload(file_path:, file_type: 'text/plain')
3
+ def upload(file_path:, file_type: "text/plain")
6
4
  file = Faraday::UploadIO.new(file_path, file_type)
7
5
 
8
6
  data = { file:, messaging_product: Warb::MESSAGING_PRODUCT }
9
7
 
10
- @client.post('media', data, multipart: true).body['id']
8
+ @client.post("media", data, multipart: true).body["id"]
11
9
  end
12
10
 
13
11
  def download(file_path:, media_url: nil, media_id: nil)
14
- media_url ||= retrieve(media_id)['url']
12
+ media_url ||= retrieve(media_id)["url"]
15
13
 
16
14
  resp = downloaded_media_response(media_url)
17
15
 
18
- File.binwrite(file_path, resp.body)
16
+ File.open(file_path, "wb") do |file|
17
+ file.write(resp.body)
18
+ end
19
19
  end
20
20
 
21
21
  def retrieve(media_id)
@@ -25,9 +25,9 @@ module Warb
25
25
  def delete(media_id)
26
26
  response_body = @client.delete(media_id, endpoint_prefix: nil).body
27
27
 
28
- return response_body['success'] if response_body['success']
28
+ return response_body["success"] if response_body["success"]
29
29
 
30
- response_body['error']['message']
30
+ response_body["error"]["message"]
31
31
  end
32
32
 
33
33
  private
@@ -36,9 +36,9 @@ module Warb
36
36
  uri = URI(url)
37
37
 
38
38
  request = Net::HTTP::Get.new(uri)
39
- request['Authorization'] = "Bearer #{@client.access_token}"
39
+ request["Authorization"] = "Bearer #{@client.access_token}"
40
40
 
41
- Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
41
+ Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
42
42
  http.request(request)
43
43
  end
44
44
  end
@@ -7,7 +7,7 @@ module Warb
7
7
 
8
8
  def build_payload
9
9
  {
10
- type: 'audio',
10
+ type: "audio",
11
11
  audio: {
12
12
  id: media_id || @params[:media_id],
13
13
  link: link || @params[:link]
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../components/address'
4
- require_relative '../components/name'
5
- require_relative '../components/email'
6
- require_relative '../components/org'
7
- require_relative '../components/phone'
8
- require_relative '../components/url'
3
+ require_relative "../components/address"
4
+ require_relative "../components/name"
5
+ require_relative "../components/email"
6
+ require_relative "../components/org"
7
+ require_relative "../components/phone"
8
+ require_relative "../components/url"
9
9
 
10
10
  module Warb
11
11
  module Resources
@@ -13,7 +13,7 @@ module Warb
13
13
  attr_accessor :addresses, :emails, :phones, :urls, :name, :org, :birthday
14
14
 
15
15
  def initialize(**params)
16
- super
16
+ super(**params)
17
17
 
18
18
  @org = @params[:org]
19
19
  @name = @params[:name]
@@ -24,10 +24,9 @@ module Warb
24
24
  @urls = @params.fetch(:urls, [])
25
25
  end
26
26
 
27
- # rubocop:disable Metrics/MethodLength
28
27
  def build_payload
29
28
  {
30
- type: 'contacts',
29
+ type: "contacts",
31
30
  contacts: [
32
31
  {
33
32
  birthday: birthday,
@@ -41,50 +40,49 @@ module Warb
41
40
  ]
42
41
  }
43
42
  end
44
- # rubocop:enable Metrics/MethodLength
45
43
 
46
- def add_address(**params, &)
44
+ def add_address(**params, &block)
47
45
  address = Components::Address.new(**params)
48
46
 
49
47
  @addresses << address
50
48
 
51
- block_given? ? address.tap(&) : address
49
+ block_given? ? address.tap(&block) : address
52
50
  end
53
51
 
54
- def add_email(**params, &)
52
+ def add_email(**params, &block)
55
53
  email = Components::Email.new(**params)
56
54
 
57
55
  @emails << email
58
56
 
59
- block_given? ? email.tap(&) : email
57
+ block_given? ? email.tap(&block) : email
60
58
  end
61
59
 
62
- def add_phone(**params, &)
60
+ def add_phone(**params, &block)
63
61
  phone = Components::Phone.new(**params)
64
62
 
65
63
  @phones << phone
66
64
 
67
- block_given? ? phone.tap(&) : phone
65
+ block_given? ? phone.tap(&block) : phone
68
66
  end
69
67
 
70
- def add_url(**params, &)
68
+ def add_url(**params, &block)
71
69
  url = Components::URL.new(**params)
72
70
 
73
71
  @urls << url
74
72
 
75
- block_given? ? url.tap(&) : url
73
+ block_given? ? url.tap(&block) : url
76
74
  end
77
75
 
78
- def build_name(**params, &)
76
+ def build_name(**params, &block)
79
77
  @name = Warb::Components::Name.new(**params)
80
78
 
81
- block_given? ? @name.tap(&) : @name
79
+ block_given? ? @name.tap(&block) : @name
82
80
  end
83
81
 
84
- def build_org(**params, &)
82
+ def build_org(**params, &block)
85
83
  @org = Warb::Components::Org.new(**params)
86
84
 
87
- block_given? ? @org.tap(&) : @org
85
+ block_given? ? @org.tap(&block) : @org
88
86
  end
89
87
  end
90
88
  end
@@ -19,7 +19,7 @@ module Warb
19
19
 
20
20
  def common_document_params
21
21
  {
22
- type: 'document',
22
+ type: "document",
23
23
  document: {
24
24
  id: media_id || @params[:media_id],
25
25
  filename: filename || @params[:filename],
@@ -5,23 +5,22 @@ module Warb
5
5
  class Flow < Resource
6
6
  attr_accessor :flow_id, :screen
7
7
 
8
- # rubocop:disable Metrics/MethodLength
9
8
  def build_payload
10
9
  {
11
- type: 'interactive',
10
+ type: "interactive",
12
11
  interactive: {
13
- type: 'flow',
12
+ type: "flow",
14
13
  body: {
15
- text: 'Not shown in draft mode'
14
+ text: "Not shown in draft mode"
16
15
  },
17
16
  action: {
18
- name: 'flow',
17
+ name: "flow",
19
18
  parameters: {
20
- flow_message_version: '3',
21
- flow_action: 'navigate',
19
+ flow_message_version: "3",
20
+ flow_action: "navigate",
22
21
  flow_id: flow_id || @params[:flow_id],
23
- flow_cta: 'Not shown in draft mode',
24
- mode: 'draft',
22
+ flow_cta: "Not shown in draft mode",
23
+ mode: "draft",
25
24
  flow_action_payload: {
26
25
  screen: screen || @params[:screen]
27
26
  }
@@ -30,7 +29,6 @@ module Warb
30
29
  }
31
30
  }
32
31
  end
33
- # rubocop:enable Metrics/MethodLength
34
32
  end
35
33
  end
36
34
  end
@@ -19,7 +19,7 @@ module Warb
19
19
 
20
20
  def common_image_params
21
21
  {
22
- type: 'image',
22
+ type: "image",
23
23
  image: {
24
24
  id: media_id || @params[:media_id],
25
25
  link: link || @params[:link]
@@ -5,12 +5,11 @@ module Warb
5
5
  class InteractiveCallToActionUrl < Resource
6
6
  attr_accessor :header, :body, :footer, :action
7
7
 
8
- # rubocop:disable Metrics/MethodLength
9
8
  def build_payload
10
9
  {
11
- type: 'interactive',
10
+ type: "interactive",
12
11
  interactive: {
13
- type: 'cta_url',
12
+ type: "cta_url",
14
13
  header: header || @params[:header]&.to_h,
15
14
  body: {
16
15
  text: body || @params[:body]
@@ -22,28 +21,27 @@ module Warb
22
21
  }
23
22
  }
24
23
  end
25
- # rubocop:enable Metrics/MethodLength
26
24
 
27
- def add_text_header(text)
25
+ def set_text_header(text)
28
26
  @header = Warb::Resources::Text.new(text:).build_header
29
27
  end
30
28
 
31
- def add_image_header(link: nil)
29
+ def set_image_header(link: nil)
32
30
  @header = Warb::Resources::Image.new(link:).build_header
33
31
  end
34
32
 
35
- def add_video_header(link: nil)
33
+ def set_video_header(link: nil)
36
34
  @header = Warb::Resources::Video.new(link:).build_header
37
35
  end
38
36
 
39
- def add_document_header(link: nil, filename: nil)
37
+ def set_document_header(link: nil, filename: nil)
40
38
  @header = Warb::Resources::Document.new(link:, filename:).build_header
41
39
  end
42
40
 
43
- def build_action(**params, &)
41
+ def build_action(**params, &block)
44
42
  @action = Warb::Components::CTAAction.new(**params)
45
43
 
46
- block_given? ? @action.tap(&) : @action
44
+ block_given? ? @action.tap(&block) : @action
47
45
  end
48
46
  end
49
47
  end
@@ -5,12 +5,11 @@ module Warb
5
5
  class InteractiveList < Resource
6
6
  attr_accessor :header, :body, :footer, :action
7
7
 
8
- # rubocop:disable Metrics/MethodLength
9
8
  def build_payload
10
9
  {
11
- type: 'interactive',
10
+ type: "interactive",
12
11
  interactive: {
13
- type: 'list',
12
+ type: "list",
14
13
  header: header || @params[:header]&.to_h,
15
14
  body: {
16
15
  text: body || @params[:body]
@@ -22,16 +21,15 @@ module Warb
22
21
  }
23
22
  }
24
23
  end
25
- # rubocop:enable Metrics/MethodLength
26
24
 
27
- def add_text_header(text)
25
+ def set_text_header(text)
28
26
  @header = Warb::Resources::Text.new(text:).build_header
29
27
  end
30
28
 
31
- def build_action(**params, &)
29
+ def build_action(**params, &block)
32
30
  @action = Warb::Components::ListAction.new(**params)
33
31
 
34
- block_given? ? @action.tap(&) : @action
32
+ block_given? ? @action.tap(&block) : @action
35
33
  end
36
34
  end
37
35
  end
@@ -5,12 +5,11 @@ module Warb
5
5
  class InteractiveReplyButton < Resource
6
6
  attr_accessor :header, :body, :footer, :action
7
7
 
8
- # rubocop:disable Metrics/MethodLength
9
8
  def build_payload
10
9
  {
11
- type: 'interactive',
10
+ type: "interactive",
12
11
  interactive: {
13
- type: 'button',
12
+ type: "button",
14
13
  header: header || @params[:header]&.to_h,
15
14
  body: {
16
15
  text: body || @params[:body]
@@ -22,28 +21,27 @@ module Warb
22
21
  }
23
22
  }
24
23
  end
25
- # rubocop:enable Metrics/MethodLength
26
24
 
27
- def add_text_header(text)
25
+ def set_text_header(text)
28
26
  @header = Warb::Resources::Text.new(text:).build_header
29
27
  end
30
28
 
31
- def add_image_header(media_id: nil, link: nil)
29
+ def set_image_header(media_id: nil, link: nil)
32
30
  @header = Warb::Resources::Image.new(media_id:, link:).build_header
33
31
  end
34
32
 
35
- def add_video_header(media_id: nil, link: nil)
33
+ def set_video_header(media_id: nil, link: nil)
36
34
  @header = Warb::Resources::Video.new(media_id:, link:).build_header
37
35
  end
38
36
 
39
- def add_document_header(media_id: nil, link: nil, filename: nil)
37
+ def set_document_header(media_id: nil, link: nil, filename: nil)
40
38
  @header = Warb::Resources::Document.new(media_id:, link:, filename:).build_header
41
39
  end
42
40
 
43
- def build_action(**params, &)
41
+ def build_action(**params, &block)
44
42
  @action = Warb::Components::ReplyButtonAction.new(**params)
45
43
 
46
- block_given? ? @action.tap(&) : @action
44
+ block_given? ? @action.tap(&block) : @action
47
45
  end
48
46
  end
49
47
  end
@@ -5,19 +5,9 @@ module Warb
5
5
  class Location < Resource
6
6
  attr_accessor :latitude, :longitude, :name, :address
7
7
 
8
- def build_header
9
- common_location_params
10
- end
11
-
12
8
  def build_payload
13
- common_location_params
14
- end
15
-
16
- private
17
-
18
- def common_location_params
19
9
  {
20
- type: 'location',
10
+ type: "location",
21
11
  location: {
22
12
  latitude: latitude || @params[:latitude],
23
13
  longitude: longitude || @params[:longitude],
@@ -5,22 +5,20 @@ module Warb
5
5
  class LocationRequest < Resource
6
6
  attr_accessor :body_text
7
7
 
8
- # rubocop:disable Metrics/MethodLength
9
8
  def build_payload
10
9
  {
11
- type: 'interactive',
10
+ type: "interactive",
12
11
  interactive: {
13
- type: 'location_request_message',
12
+ type: "location_request_message",
14
13
  body: {
15
14
  text: body_text || @params[:body_text]
16
15
  },
17
16
  action: {
18
- name: 'send_location'
17
+ name: "send_location"
19
18
  }
20
19
  }
21
20
  }
22
21
  end
23
- # rubocop:enable Metrics/MethodLength
24
22
  end
25
23
  end
26
24
  end
@@ -7,7 +7,7 @@ module Warb
7
7
 
8
8
  def build_payload
9
9
  {
10
- type: 'reaction',
10
+ type: "reaction",
11
11
  reaction: {
12
12
  message_id: message_id || @params[:message_id],
13
13
  emoji: emoji || @params[:emoji]
@@ -19,27 +19,19 @@ module Warb
19
19
  raise NotImplementedError
20
20
  end
21
21
 
22
- def build_template_positional_parameter
22
+ def set_text_header
23
23
  raise NotImplementedError
24
24
  end
25
25
 
26
- def build_template_named_parameter(paramater_name)
26
+ def set_image_header
27
27
  raise NotImplementedError
28
28
  end
29
29
 
30
- def add_text_header
30
+ def set_video_header
31
31
  raise NotImplementedError
32
32
  end
33
33
 
34
- def add_image_header
35
- raise NotImplementedError
36
- end
37
-
38
- def add_video_header
39
- raise NotImplementedError
40
- end
41
-
42
- def add_document_header
34
+ def set_document_header
43
35
  raise NotImplementedError
44
36
  end
45
37
 
@@ -7,7 +7,7 @@ module Warb
7
7
 
8
8
  def build_payload
9
9
  {
10
- type: 'sticker',
10
+ type: "sticker",
11
11
  sticker: {
12
12
  id: media_id || @params[:media_id],
13
13
  link: link || @params[:link]
@@ -3,18 +3,15 @@
3
3
  module Warb
4
4
  module Resources
5
5
  class Text < Resource
6
- attr_accessor :content, :text, :message, :preview_url, :parameter_name
6
+ attr_accessor :content, :text, :message, :preview_url
7
7
 
8
8
  def build_header
9
- { type: 'text', text: message_per_priority }.tap do |header|
10
- parameter_name ||= @params[:parameter_name]
11
- header[:parameter_name] = parameter_name unless parameter_name.nil?
12
- end
9
+ { type: "text", text: message_per_priority }
13
10
  end
14
11
 
15
12
  def build_payload
16
13
  {
17
- type: 'text',
14
+ type: "text",
18
15
  text: {
19
16
  preview_url: preview_url || @params[:preview_url],
20
17
  body: message_per_priority
@@ -22,21 +19,6 @@ module Warb
22
19
  }
23
20
  end
24
21
 
25
- def build_template_named_parameter(parameter_name)
26
- {
27
- type: 'text',
28
- text: message_per_priority,
29
- parameter_name: parameter_name
30
- }
31
- end
32
-
33
- def build_template_positional_parameter
34
- {
35
- type: 'text',
36
- text: message_per_priority
37
- }
38
- end
39
-
40
22
  private
41
23
 
42
24
  def message_per_priority
@@ -19,7 +19,7 @@ module Warb
19
19
 
20
20
  def common_video_params
21
21
  {
22
- type: 'video',
22
+ type: "video",
23
23
  video: {
24
24
  id: media_id || @params[:media_id],
25
25
  link: link || @params[:link]
data/lib/warb/utils.rb CHANGED
@@ -1,7 +1,5 @@
1
- # frozen_string_literal: true
2
-
3
1
  class String
4
2
  def normalize
5
- unicode_normalize(:nfd).gsub(/\p{Mn}/, '')
3
+ unicode_normalize(:nfd).gsub(/\p{Mn}/, "")
6
4
  end
7
5
  end
data/lib/warb/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Warb
4
- VERSION = '0.1.3'
4
+ VERSION = "1.0.0"
5
5
  end