castle-rb 8.0.0 → 9.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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +317 -0
  3. data/LICENSE +21 -0
  4. data/README.md +290 -112
  5. data/lib/castle/api/filter.rb +3 -1
  6. data/lib/castle/api/list_items/archive.rb +23 -0
  7. data/lib/castle/api/list_items/count.rb +22 -0
  8. data/lib/castle/api/list_items/create.rb +22 -0
  9. data/lib/castle/api/list_items/create_batch.rb +22 -0
  10. data/lib/castle/api/list_items/get.rb +22 -0
  11. data/lib/castle/api/list_items/query.rb +22 -0
  12. data/lib/castle/api/list_items/unarchive.rb +22 -0
  13. data/lib/castle/api/list_items/update.rb +22 -0
  14. data/lib/castle/api/lists/create.rb +23 -0
  15. data/lib/castle/api/lists/delete.rb +22 -0
  16. data/lib/castle/api/lists/get.rb +22 -0
  17. data/lib/castle/api/lists/get_all.rb +22 -0
  18. data/lib/castle/api/lists/query.rb +22 -0
  19. data/lib/castle/api/lists/update.rb +22 -0
  20. data/lib/castle/api/log.rb +2 -1
  21. data/lib/castle/api/privacy/delete_data.rb +23 -0
  22. data/lib/castle/api/privacy/request_data.rb +23 -0
  23. data/lib/castle/api/risk.rb +2 -1
  24. data/lib/castle/client.rb +15 -52
  25. data/lib/castle/client_actions/list_items.rb +49 -0
  26. data/lib/castle/client_actions/lists.rb +39 -0
  27. data/lib/castle/client_actions/privacy.rb +20 -0
  28. data/lib/castle/commands/list_items/archive.rb +24 -0
  29. data/lib/castle/commands/list_items/count.rb +23 -0
  30. data/lib/castle/commands/list_items/create.rb +22 -0
  31. data/lib/castle/commands/list_items/create_batch.rb +22 -0
  32. data/lib/castle/commands/list_items/get.rb +23 -0
  33. data/lib/castle/commands/list_items/query.rb +24 -0
  34. data/lib/castle/commands/list_items/unarchive.rb +23 -0
  35. data/lib/castle/commands/list_items/update.rb +22 -0
  36. data/lib/castle/commands/lists/create.rb +21 -0
  37. data/lib/castle/commands/lists/delete.rb +20 -0
  38. data/lib/castle/commands/lists/get.rb +20 -0
  39. data/lib/castle/commands/lists/get_all.rb +17 -0
  40. data/lib/castle/commands/lists/query.rb +21 -0
  41. data/lib/castle/commands/lists/update.rb +22 -0
  42. data/lib/castle/commands/privacy/delete_data.rb +20 -0
  43. data/lib/castle/commands/privacy/request_data.rb +20 -0
  44. data/lib/castle/core/get_connection.rb +5 -1
  45. data/lib/castle/core/process_response.rb +1 -0
  46. data/lib/castle/core/process_webhook.rb +1 -1
  47. data/lib/castle/core/send_request.rb +2 -1
  48. data/lib/castle/errors.rb +1 -5
  49. data/lib/castle/headers/filter.rb +1 -1
  50. data/lib/castle/version.rb +1 -1
  51. data/lib/castle.rb +36 -17
  52. metadata +62 -162
  53. data/lib/castle/api/approve_device.rb +0 -20
  54. data/lib/castle/api/authenticate.rb +0 -28
  55. data/lib/castle/api/end_impersonation.rb +0 -22
  56. data/lib/castle/api/get_device.rb +0 -20
  57. data/lib/castle/api/get_devices_for_user.rb +0 -20
  58. data/lib/castle/api/report_device.rb +0 -20
  59. data/lib/castle/api/start_impersonation.rb +0 -22
  60. data/lib/castle/api/track.rb +0 -19
  61. data/lib/castle/commands/approve_device.rb +0 -17
  62. data/lib/castle/commands/authenticate.rb +0 -23
  63. data/lib/castle/commands/end_impersonation.rb +0 -25
  64. data/lib/castle/commands/get_device.rb +0 -17
  65. data/lib/castle/commands/get_devices_for_user.rb +0 -17
  66. data/lib/castle/commands/report_device.rb +0 -17
  67. data/lib/castle/commands/start_impersonation.rb +0 -25
  68. data/lib/castle/commands/track.rb +0 -22
  69. data/lib/castle/support/hanami.rb +0 -15
  70. data/lib/castle/support/padrino.rb +0 -19
  71. data/spec/integration/rails/rails_spec.rb +0 -95
  72. data/spec/integration/rails/support/all.rb +0 -6
  73. data/spec/integration/rails/support/application.rb +0 -17
  74. data/spec/integration/rails/support/home_controller.rb +0 -39
  75. data/spec/lib/castle/api/approve_device_spec.rb +0 -17
  76. data/spec/lib/castle/api/authenticate_spec.rb +0 -133
  77. data/spec/lib/castle/api/end_impersonation_spec.rb +0 -59
  78. data/spec/lib/castle/api/filter_spec.rb +0 -5
  79. data/spec/lib/castle/api/get_device_spec.rb +0 -17
  80. data/spec/lib/castle/api/get_devices_for_user_spec.rb +0 -17
  81. data/spec/lib/castle/api/log_spec.rb +0 -5
  82. data/spec/lib/castle/api/report_device_spec.rb +0 -17
  83. data/spec/lib/castle/api/risk_spec.rb +0 -5
  84. data/spec/lib/castle/api/start_impersonation_spec.rb +0 -59
  85. data/spec/lib/castle/api/track_spec.rb +0 -65
  86. data/spec/lib/castle/api_spec.rb +0 -36
  87. data/spec/lib/castle/client_id/extract_spec.rb +0 -47
  88. data/spec/lib/castle/client_spec.rb +0 -337
  89. data/spec/lib/castle/command_spec.rb +0 -9
  90. data/spec/lib/castle/commands/approve_device_spec.rb +0 -24
  91. data/spec/lib/castle/commands/authenticate_spec.rb +0 -86
  92. data/spec/lib/castle/commands/end_impersonation_spec.rb +0 -72
  93. data/spec/lib/castle/commands/filter_spec.rb +0 -72
  94. data/spec/lib/castle/commands/get_device_spec.rb +0 -24
  95. data/spec/lib/castle/commands/get_devices_for_user_spec.rb +0 -24
  96. data/spec/lib/castle/commands/log_spec.rb +0 -73
  97. data/spec/lib/castle/commands/report_device_spec.rb +0 -24
  98. data/spec/lib/castle/commands/risk_spec.rb +0 -73
  99. data/spec/lib/castle/commands/start_impersonation_spec.rb +0 -72
  100. data/spec/lib/castle/commands/track_spec.rb +0 -89
  101. data/spec/lib/castle/configuration_spec.rb +0 -14
  102. data/spec/lib/castle/context/get_default_spec.rb +0 -41
  103. data/spec/lib/castle/context/merge_spec.rb +0 -23
  104. data/spec/lib/castle/context/prepare_spec.rb +0 -42
  105. data/spec/lib/castle/context/sanitize_spec.rb +0 -27
  106. data/spec/lib/castle/core/get_connection_spec.rb +0 -43
  107. data/spec/lib/castle/core/process_response_spec.rb +0 -103
  108. data/spec/lib/castle/core/process_webhook_spec.rb +0 -52
  109. data/spec/lib/castle/core/send_request_spec.rb +0 -97
  110. data/spec/lib/castle/failover/strategy_spec.rb +0 -12
  111. data/spec/lib/castle/headers/extract_spec.rb +0 -103
  112. data/spec/lib/castle/headers/filter_spec.rb +0 -42
  113. data/spec/lib/castle/headers/format_spec.rb +0 -25
  114. data/spec/lib/castle/ips/extract_spec.rb +0 -91
  115. data/spec/lib/castle/logger_spec.rb +0 -39
  116. data/spec/lib/castle/payload/prepare_spec.rb +0 -52
  117. data/spec/lib/castle/secure_mode_spec.rb +0 -7
  118. data/spec/lib/castle/session_spec.rb +0 -61
  119. data/spec/lib/castle/singleton_configuration_spec.rb +0 -14
  120. data/spec/lib/castle/utils/clean_invalid_chars_spec.rb +0 -69
  121. data/spec/lib/castle/utils/clone_spec.rb +0 -19
  122. data/spec/lib/castle/utils/deep_symbolize_keys_spec.rb +0 -50
  123. data/spec/lib/castle/utils/get_timestamp_spec.rb +0 -16
  124. data/spec/lib/castle/utils/merge_spec.rb +0 -13
  125. data/spec/lib/castle/validators/not_supported_spec.rb +0 -19
  126. data/spec/lib/castle/validators/present_spec.rb +0 -25
  127. data/spec/lib/castle/verdict_spec.rb +0 -9
  128. data/spec/lib/castle/version_spec.rb +0 -5
  129. data/spec/lib/castle/webhooks/verify_spec.rb +0 -59
  130. data/spec/lib/castle_spec.rb +0 -58
  131. data/spec/spec_helper.rb +0 -24
  132. data/spec/support/shared_examples/action_request.rb +0 -167
  133. data/spec/support/shared_examples/configuration.rb +0 -99
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ # Namespace for the lists API endpoints
6
+ module Lists
7
+ # Sends POST /lists request
8
+ module Create
9
+ class << self
10
+ # @param options [Hash]
11
+ # @return [Hash]
12
+ def call(options = {})
13
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
14
+ http = options.delete(:http)
15
+ config = options.delete(:config) || Castle.config
16
+
17
+ Castle::API.call(Castle::Commands::Lists::Create.build(options), {}, http, config)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Lists
6
+ # Sends DELETE /lists/:list_id request
7
+ module Delete
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Hash]
11
+ def call(options = {})
12
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
13
+ http = options.delete(:http)
14
+ config = options.delete(:config) || Castle.config
15
+
16
+ Castle::API.call(Castle::Commands::Lists::Delete.build(options), {}, http, config)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Lists
6
+ # Sends GET /lists/:list_id request
7
+ module Get
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Hash]
11
+ def call(options = {})
12
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
13
+ http = options.delete(:http)
14
+ config = options.delete(:config) || Castle.config
15
+
16
+ Castle::API.call(Castle::Commands::Lists::Get.build(options), {}, http, config)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Lists
6
+ # Sends GET /lists request
7
+ module GetAll
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Hash]
11
+ def call(options = {})
12
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
13
+ http = options.delete(:http)
14
+ config = options.delete(:config) || Castle.config
15
+
16
+ Castle::API.call(Castle::Commands::Lists::GetAll.build, {}, http, config)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Lists
6
+ # Sends POST /lists/query request
7
+ module Query
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Hash]
11
+ def call(options = {})
12
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
13
+ http = options.delete(:http)
14
+ config = options.delete(:config) || Castle.config
15
+
16
+ Castle::API.call(Castle::Commands::Lists::Query.build(options), {}, http, config)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Lists
6
+ # Sends PUT /lists/:list_id request
7
+ module Update
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Hash]
11
+ def call(options = {})
12
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
13
+ http = options.delete(:http)
14
+ config = options.delete(:config) || Castle.config
15
+
16
+ Castle::API.call(Castle::Commands::Lists::Update.build(options), {}, http, config)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -18,7 +18,8 @@ module Castle
18
18
  rescue Castle::RequestError, Castle::InternalServerError => e
19
19
  unless config.failover_strategy == :throw
20
20
  strategy = (config || Castle.config).failover_strategy
21
- return(Castle::Failover::PrepareResponse.new(options[:user][:id], reason: e.to_s, strategy: strategy).call)
21
+ user_id = options.dig(:user, :id)
22
+ return Castle::Failover::PrepareResponse.new(user_id, reason: e.to_s, strategy: strategy).call
22
23
  end
23
24
 
24
25
  raise e
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Privacy
6
+ # Sends DELETE /v1/privacy/users — permanently purges a user's data from Castle.
7
+ # Closes #261 (GDPR Article 17).
8
+ module DeleteData
9
+ class << self
10
+ # @param options [Hash]
11
+ # @return [Hash]
12
+ def call(options = {})
13
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
14
+ http = options.delete(:http)
15
+ config = options.delete(:config) || Castle.config
16
+
17
+ Castle::API.call(Castle::Commands::Privacy::DeleteData.build(options), {}, http, config)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module API
5
+ module Privacy
6
+ # Sends POST /v1/privacy/users — Castle compiles the user's data and emails it
7
+ # to the configured privacy mailbox. Closes #261 (GDPR Article 15).
8
+ module RequestData
9
+ class << self
10
+ # @param options [Hash]
11
+ # @return [Hash]
12
+ def call(options = {})
13
+ options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
14
+ http = options.delete(:http)
15
+ config = options.delete(:config) || Castle.config
16
+
17
+ Castle::API.call(Castle::Commands::Privacy::RequestData.build(options), {}, http, config)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -18,7 +18,8 @@ module Castle
18
18
  rescue Castle::RequestError, Castle::InternalServerError => e
19
19
  unless config.failover_strategy == :throw
20
20
  strategy = (config || Castle.config).failover_strategy
21
- return(Castle::Failover::PrepareResponse.new(options[:user][:id], reason: e.to_s, strategy: strategy).call)
21
+ user_id = options.dig(:user, :id)
22
+ return Castle::Failover::PrepareResponse.new(user_id, reason: e.to_s, strategy: strategy).call
22
23
  end
23
24
 
24
25
  raise e
data/lib/castle/client.rb CHANGED
@@ -3,6 +3,10 @@
3
3
  module Castle
4
4
  # Castle's client.
5
5
  class Client
6
+ include Castle::ClientActions::ListItems
7
+ include Castle::ClientActions::Lists
8
+ include Castle::ClientActions::Privacy
9
+
6
10
  class << self
7
11
  def from_request(request, options = {})
8
12
  new(options.merge(context: Castle::Context::Prepare.call(request, options)))
@@ -19,37 +23,11 @@ module Castle
19
23
  @context = options.fetch(:context) { {} }
20
24
  end
21
25
 
22
- # @param options [Hash]
23
- def authenticate(options = {})
24
- options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
25
-
26
- return generate_do_not_track_response(options[:user_id]) unless tracked?
27
-
28
- add_timestamp_if_necessary(options)
29
-
30
- new_context = Castle::Context::Merge.call(@context, options[:context])
31
-
32
- Castle::API::Authenticate.call(options.merge(context: new_context, no_symbolize: true))
33
- end
34
-
35
- # @param options [Hash]
36
- def track(options = {})
37
- options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
38
-
39
- return unless tracked?
40
-
41
- add_timestamp_if_necessary(options)
42
-
43
- new_context = Castle::Context::Merge.call(@context, options[:context])
44
-
45
- Castle::API::Track.call(options.merge(context: new_context, no_symbolize: true))
46
- end
47
-
48
26
  # @param options [Hash]
49
27
  def filter(options = {})
50
28
  options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
51
29
 
52
- return generate_do_not_track_response(options[:user][:id]) unless tracked?
30
+ return generate_do_not_track_response(failover_user_id(options)) unless tracked?
53
31
 
54
32
  add_timestamp_if_necessary(options)
55
33
 
@@ -62,7 +40,7 @@ module Castle
62
40
  def risk(options = {})
63
41
  options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
64
42
 
65
- return generate_do_not_track_response(options[:user][:id]) unless tracked?
43
+ return generate_do_not_track_response(failover_user_id(options)) unless tracked?
66
44
 
67
45
  add_timestamp_if_necessary(options)
68
46
 
@@ -75,7 +53,7 @@ module Castle
75
53
  def log(options = {})
76
54
  options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
77
55
 
78
- return generate_do_not_track_response(options[:user][:id]) unless tracked?
56
+ return generate_do_not_track_response(failover_user_id(options)) unless tracked?
79
57
 
80
58
  add_timestamp_if_necessary(options)
81
59
 
@@ -84,28 +62,6 @@ module Castle
84
62
  Castle::API::Log.call(options.merge(context: new_context, no_symbolize: true))
85
63
  end
86
64
 
87
- # @param options [Hash]
88
- def start_impersonation(options = {})
89
- options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
90
-
91
- add_timestamp_if_necessary(options)
92
-
93
- new_context = Castle::Context::Merge.call(@context, options[:context])
94
-
95
- Castle::API::StartImpersonation.call(options.merge(context: new_context, no_symbolize: true))
96
- end
97
-
98
- # @param options [Hash]
99
- def end_impersonation(options = {})
100
- options = Castle::Utils::DeepSymbolizeKeys.call(options || {})
101
-
102
- add_timestamp_if_necessary(options)
103
-
104
- new_context = Castle::Context::Merge.call(@context, options[:context])
105
-
106
- Castle::API::EndImpersonation.call(options.merge(context: new_context, no_symbolize: true))
107
- end
108
-
109
65
  def disable_tracking
110
66
  @do_not_track = true
111
67
  end
@@ -121,11 +77,18 @@ module Castle
121
77
 
122
78
  private
123
79
 
124
- # @param user_id [String, Boolean]
80
+ # @param user_id [String, Boolean, nil]
125
81
  def generate_do_not_track_response(user_id)
126
82
  Castle::Failover::PrepareResponse.new(user_id, strategy: :allow, reason: 'Castle is set to do not track.').call
127
83
  end
128
84
 
85
+ # Safely pull the user identifier for a failover/do-not-track response.
86
+ # `user` is optional on /v1/filter (#279) and may be omitted entirely on
87
+ # /v1/log; fall back to `matching_user_id` then nil.
88
+ def failover_user_id(options)
89
+ options.dig(:user, :id) || options[:matching_user_id]
90
+ end
91
+
129
92
  # @param options [Hash]
130
93
  def add_timestamp_if_necessary(options)
131
94
  options[:timestamp] ||= @timestamp if @timestamp
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ # Namespace for client actions
5
+ module ClientActions
6
+ # Client actions for list items
7
+ module ListItems
8
+ # @param options [Hash]
9
+ def archive_list_item(options = {})
10
+ Castle::API::ListItems::Archive.call(options)
11
+ end
12
+
13
+ # @param options [Hash]
14
+ def count_list_items(options = {})
15
+ Castle::API::ListItems::Count.call(options)
16
+ end
17
+
18
+ # @param options [Hash]
19
+ def create_list_item(options = {})
20
+ Castle::API::ListItems::Create.call(options)
21
+ end
22
+
23
+ # @param options [Hash]
24
+ def create_batch_list_items(options = {})
25
+ Castle::API::ListItems::CreateBatch.call(options)
26
+ end
27
+
28
+ # @param options [Hash]
29
+ def get_list_item(options = {})
30
+ Castle::API::ListItems::Get.call(options)
31
+ end
32
+
33
+ # @param options [Hash]
34
+ def query_list_items(options = {})
35
+ Castle::API::ListItems::Query.call(options)
36
+ end
37
+
38
+ # @param options [Hash]
39
+ def unarchive_list_item(options = {})
40
+ Castle::API::ListItems::Unarchive.call(options)
41
+ end
42
+
43
+ # @param options [Hash]
44
+ def update_list_item(options = {})
45
+ Castle::API::ListItems::Update.call(options)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ # Namespace for client actions
5
+ module ClientActions
6
+ # Client actions for lists
7
+ module Lists
8
+ # @param options [Hash]
9
+ def create_list(options = {})
10
+ Castle::API::Lists::Create.call(options)
11
+ end
12
+
13
+ # @param options [Hash]
14
+ def delete_list(options = {})
15
+ Castle::API::Lists::Delete.call(options)
16
+ end
17
+
18
+ # @param options [Hash]
19
+ def get_all_lists(options = {})
20
+ Castle::API::Lists::GetAll.call(options)
21
+ end
22
+
23
+ # @param options [Hash]
24
+ def get_list(options = {})
25
+ Castle::API::Lists::Get.call(options)
26
+ end
27
+
28
+ # @param options [Hash]
29
+ def query_lists(options = {})
30
+ Castle::API::Lists::Query.call(options)
31
+ end
32
+
33
+ # @param options [Hash]
34
+ def update_list(options = {})
35
+ Castle::API::Lists::Update.call(options)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module ClientActions
5
+ # Client actions for the Privacy API (GDPR Articles 15 & 17).
6
+ module Privacy
7
+ # Triggers a "right of access" data export.
8
+ # @param options [Hash] must include :identifier and :identifier_type ($id or $email)
9
+ def request_user_data(options = {})
10
+ Castle::API::Privacy::RequestData.call(options)
11
+ end
12
+
13
+ # Triggers a "right to be forgotten" data purge.
14
+ # @param options [Hash] must include :identifier and :identifier_type ($id or $email)
15
+ def delete_user_data(options = {})
16
+ Castle::API::Privacy::DeleteData.call(options)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ # Commands for list items endpoints
6
+ module ListItems
7
+ # Generates the payload for the DELETE /lists/:list_id/items/:item_id/archive request
8
+ class Archive
9
+ class << self
10
+ # @param options [Hash]
11
+ # @return [Castle::Command]
12
+ def build(options = {})
13
+ Castle::Validators::Present.call(options, %i[list_id list_item_id])
14
+
15
+ list_id = options.delete(:list_id)
16
+ list_item_id = options.delete(:list_item_id)
17
+
18
+ Castle::Command.new("lists/#{list_id}/items/#{list_item_id}/archive", nil, :delete)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Generates the payload for the POST /lists/:list_id/items/count request
7
+ class Count
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id])
13
+ options[:filters]&.each { |f| Castle::Validators::Present.call(f, %i[field op value]) }
14
+
15
+ list_id = options.delete(:list_id)
16
+
17
+ Castle::Command.new("lists/#{list_id}/items/count", options, :post)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Builds the command to create a list item
7
+ class Create
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id author primary_value])
13
+
14
+ list_id = options.delete(:list_id)
15
+
16
+ Castle::Command.new("lists/#{list_id}/items", options, :post)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Builds the command to create or update multiple list items in a single call
7
+ class CreateBatch
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id items])
13
+
14
+ list_id = options.delete(:list_id)
15
+
16
+ Castle::Command.new("lists/#{list_id}/items/batch", options, :post)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Builds the command to get a list item
7
+ class Get
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id list_item_id])
13
+
14
+ list_id = options.delete(:list_id)
15
+ list_item_id = options.delete(:list_item_id)
16
+
17
+ Castle::Command.new("lists/#{list_id}/items/#{list_item_id}", nil, :get)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Builds the command to query list items
7
+ class Query
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id])
13
+ options[:filters]&.each { |f| Castle::Validators::Present.call(f, %i[field op value]) }
14
+ Castle::Validators::Present.call(options[:sort], %i[field order]) if options[:sort]
15
+
16
+ list_id = options.delete(:list_id)
17
+
18
+ Castle::Command.new("lists/#{list_id}/items/query", options, :post)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Builds the command to unarchive a list item
7
+ class Unarchive
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id list_item_id])
13
+
14
+ list_id = options.delete(:list_id)
15
+ list_item_id = options.delete(:list_item_id)
16
+
17
+ Castle::Command.new("lists/#{list_id}/items/#{list_item_id}/unarchive", nil, :put)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module ListItems
6
+ # Builds the command to update a list item
7
+ class Update
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id list_item_id comment])
13
+ list_id = options.delete(:list_id)
14
+ list_item_id = options.delete(:list_item_id)
15
+
16
+ Castle::Command.new("lists/#{list_id}/items/#{list_item_id}", options, :put)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ # Commands for lists endpoints
6
+ module Lists
7
+ # Builds the command to create a list
8
+ class Create
9
+ class << self
10
+ # @param options [Hash]
11
+ # @return [Castle::Command]
12
+ def build(options = {})
13
+ Castle::Validators::Present.call(options, %i[name color primary_field])
14
+
15
+ Castle::Command.new('lists', options, :post)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Castle
4
+ module Commands
5
+ module Lists
6
+ # Builds the command to delete a list
7
+ class Delete
8
+ class << self
9
+ # @param options [Hash]
10
+ # @return [Castle::Command]
11
+ def build(options = {})
12
+ Castle::Validators::Present.call(options, %i[list_id])
13
+
14
+ Castle::Command.new("lists/#{options[:list_id]}", nil, :delete)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end