gitlab-customer-support-operations_gitlab 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 (35) hide show
  1. checksums.yaml +7 -0
  2. data/lib/support_ops_gitlab/gitlab/badges.rb +229 -0
  3. data/lib/support_ops_gitlab/gitlab/base.rb +552 -0
  4. data/lib/support_ops_gitlab/gitlab/client.rb +51 -0
  5. data/lib/support_ops_gitlab/gitlab/commits.rb +198 -0
  6. data/lib/support_ops_gitlab/gitlab/configuration.rb +86 -0
  7. data/lib/support_ops_gitlab/gitlab/epics.rb +325 -0
  8. data/lib/support_ops_gitlab/gitlab/events.rb +167 -0
  9. data/lib/support_ops_gitlab/gitlab/gpg_keys.rb +64 -0
  10. data/lib/support_ops_gitlab/gitlab/group_memberships.rb +33 -0
  11. data/lib/support_ops_gitlab/gitlab/groups.rb +431 -0
  12. data/lib/support_ops_gitlab/gitlab/invitations.rb +72 -0
  13. data/lib/support_ops_gitlab/gitlab/issues.rb +606 -0
  14. data/lib/support_ops_gitlab/gitlab/jobs.rb +61 -0
  15. data/lib/support_ops_gitlab/gitlab/markdown.rb +54 -0
  16. data/lib/support_ops_gitlab/gitlab/merge_requests.rb +411 -0
  17. data/lib/support_ops_gitlab/gitlab/milestones.rb +195 -0
  18. data/lib/support_ops_gitlab/gitlab/namespaces.rb +184 -0
  19. data/lib/support_ops_gitlab/gitlab/notes.rb +182 -0
  20. data/lib/support_ops_gitlab/gitlab/pipelines.rb +258 -0
  21. data/lib/support_ops_gitlab/gitlab/project_access_tokens.rb +245 -0
  22. data/lib/support_ops_gitlab/gitlab/project_memberships.rb +33 -0
  23. data/lib/support_ops_gitlab/gitlab/project_webhook_events.rb +33 -0
  24. data/lib/support_ops_gitlab/gitlab/project_webhooks.rb +218 -0
  25. data/lib/support_ops_gitlab/gitlab/projects.rb +741 -0
  26. data/lib/support_ops_gitlab/gitlab/repository_files.rb +102 -0
  27. data/lib/support_ops_gitlab/gitlab/repository_submodules.rb +78 -0
  28. data/lib/support_ops_gitlab/gitlab/ssh_keys.rb +67 -0
  29. data/lib/support_ops_gitlab/gitlab/user_emails.rb +147 -0
  30. data/lib/support_ops_gitlab/gitlab/user_memberships.rb +21 -0
  31. data/lib/support_ops_gitlab/gitlab/user_tokens.rb +344 -0
  32. data/lib/support_ops_gitlab/gitlab/users.rb +1059 -0
  33. data/lib/support_ops_gitlab/gitlab.rb +45 -0
  34. data/lib/support_ops_gitlab.rb +28 -0
  35. metadata +251 -0
@@ -0,0 +1,431 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module SupportOps.
4
+ module SupportOps
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the class Groups within the module {SupportOps::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ # @attr [Array] allowed_email_domains_list Comma-separated list of email address domains to allow group access
13
+ # @attr [Boolean] auto_ban_user_on_excessive_projects_download When enabled, users are automatically banned from the group when they download more than the maximum number of unique projects specified by unique_project_download_limit and unique_project_download_limit_interval_in_seconds
14
+ # @attr [String] avatar_url The URL of the group's avatar
15
+ # @attr [Boolean] auto_devops_enabled Default to Auto DevOps pipeline for all projects within this group
16
+ # @attr [String] created_at The timestamp the group was created at
17
+ # @attr [String] default_branch The default branch name for group’s projects
18
+ # @attr [Hash] default_branch_protection_defaults Describes the default branch protection defaults. See https://docs.gitlab.com/api/groups/#options-for-default_branch_protection_defaults for more info
19
+ # @attr [String] description The group’s description
20
+ # @attr [String] duo_availability Duo availability setting; valid values are: default_on, default_off, never_on
21
+ # @attr [Boolean] duo_features_enabled Indicates whether GitLab Duo features are enabled for this group
22
+ # @attr [Boolean] emails_enabled Enable email notifications
23
+ # @attr [String] enabled_git_access_protocol Enabled protocols for Git access; allowed values are: ssh, http, and all to allow both protocols
24
+ # @attr [Boolean] experiment_features_enabled Enable experiment features for this group
25
+ # @attr [Integer] extra_shared_runners_minutes_limit Additional compute minutes for this group
26
+ # @attr [Integer] file_template_project_id The ID of a project to load custom file templates from
27
+ # @attr [String] full_name The full name of the group
28
+ # @attr [String] full_path Full path of group
29
+ # @attr [Integer] id ID of the group
30
+ # @attr [String] ip_restriction_ranges Comma-separated list of IP addresses or subnet masks to restrict group access
31
+ # @attr [Boolean] lfs_enabled Enable/disable Large File Storage (LFS) for the projects in this group
32
+ # @attr [Boolean] lock_duo_features_enabled Indicates whether the GitLab Duo features enabled setting is enforced for all subgroups
33
+ # @attr [Boolean] lock_math_rendering_limits_enabled Indicates if math rendering limits are locked for all descendent groups
34
+ # @attr [String] marked_for_deletion_on The date the group is scheduled to be deleted
35
+ # @attr [Boolean] math_rendering_limits_enabled Indicates if math rendering limits are used for this group
36
+ # @attr [Integer] max_artifacts_size The maximum file size in megabytes for individual job artifacts
37
+ # @attr [Boolean] membership_lock Users cannot be added to projects in this group
38
+ # @attr [Boolean] mentions_disabled Disable the capability of a group from getting mentioned
39
+ # @attr [String] name The name of the group
40
+ # @attr [Integer] organization_id The organization ID for the group
41
+ # @attr [Integer] parent_id The parent group ID for creating nested group
42
+ # @attr [String] path The path of the group
43
+ # @attr [Boolean] prevent_forking_outside_group When enabled, users can not fork projects from this group to external namespaces
44
+ # @attr [Boolean] prevent_sharing_groups_outside_hierarchy When enabled, top-level group will ensure its subgroups and projects cannot invite other groups outside of the top-level group’s hierarchy
45
+ # @attr [String] project_creation_level Determine if developers can create projects in the group; can be noone, maintainer, or developer
46
+ # @attr [String] repository_storage Stroage location of repositories
47
+ # @attr [Boolean] request_access_enabled Allow users to request member access
48
+ # @attr [Boolean] require_two_factor_authentication Require all users in this group to set up two-factor authentication
49
+ # @attr [String] runners_token Token of the group's runner
50
+ # @attr [Boolean] share_with_group_lock Prevent sharing a project with another group within this group
51
+ # @attr [Integer] shared_runners_minutes_limit Maximum number of monthly compute minutes for this group; can be nil, 0, or > 0
52
+ # @attr [Array] shared_with_groups Groups this group has been shared with
53
+ # @attr [Hash] statistics Group statistics
54
+ # @attr [String] subgroup_creation_level Allowed to create subgroups; can be owner or maintainer
55
+ # @attr [Integer] two_factor_grace_period Time before Two-factor authentication is enforced (in hours)
56
+ # @attr [Integer] unique_project_download_limit Maximum number of unique projects a user can download in the specified time period before they are banned
57
+ # @attr [Array] unique_project_download_limit_allowlist List of usernames excluded from the unique project download limit
58
+ # @attr [Array] unique_project_download_limit_alertlist List of user IDs that are emailed when the unique project download limit is exceeded
59
+ # @attr [Integer] unique_project_download_limit_interval_in_seconds Time period during which a user can download a maximum amount of projects before they are banned
60
+ # @attr [String] visibility The group’s visibility; can be private, internal, or public
61
+ # @attr [String] web_url The URL of the group
62
+ # @attr [String] wiki_access_level The wiki access level; can be disabled, private, or enabled
63
+ # @todo A lot of things listed at https://docs.gitlab.com/api/groups
64
+ class Groups < SupportOps::GitLab::Base
65
+ # @!parse
66
+ # # List badges within a group
67
+ # #
68
+ # # @author Jason Colyer
69
+ # # @since 1.0.0
70
+ # # @return [Boolean]
71
+ # # @note This is inherited from {SupportOps::GitLab::Base#badges}
72
+ # # @see
73
+ # # https://docs.gitlab.com/api/group_badges/#list-all-badges-of-a-group
74
+ # # GitLab API > Groups > Badges > List all badgesof a group
75
+ # # @example
76
+ # # require 'support_ops_gitlab'
77
+ # #
78
+ # # SupportOps::GitLab::Configuration.configure do |config|
79
+ # # config.token = ENV.fetch('GL_TOKEN')
80
+ # # config.url = 'https://gitlab.com/api/v4'
81
+ # # end
82
+ # #
83
+ # # group = SupportOps::GitLab::Groups.get!(123456)
84
+ # # badges = group.badges
85
+ # # pp badges.count
86
+ # # # => 2
87
+ # def badges; end
88
+ # @!parse
89
+ # # List projects within a group
90
+ # #
91
+ # # @author Jason Colyer
92
+ # # @since 1.0.0
93
+ # # @return [Boolean]
94
+ # # @note This is inherited from {SupportOps::GitLab::Base#projects}
95
+ # # @see
96
+ # # https://docs.gitlab.com/api/groups/#list-projects
97
+ # # GitLab API > Groups > List projects
98
+ # # @example
99
+ # # require 'support_ops_gitlab'
100
+ # #
101
+ # # SupportOps::GitLab::Configuration.configure do |config|
102
+ # # config.token = ENV.fetch('GL_TOKEN')
103
+ # # config.url = 'https://gitlab.com/api/v4'
104
+ # # end
105
+ # #
106
+ # # group = SupportOps::GitLab::Groups.get!(123456)
107
+ # # projects = group.projects
108
+ # # pp projects.count
109
+ # # # => 27
110
+ # def projects; end
111
+ # @!parse
112
+ # # List milestones within a group
113
+ # #
114
+ # # @author Jason Colyer
115
+ # # @since 1.0.0
116
+ # # @return [Boolean]
117
+ # # @note This is inherited from {SupportOps::GitLab::Base#milestones}
118
+ # # @see
119
+ # # https://docs.gitlab.com/api/group_milestones/#list-group-milestones
120
+ # # GitLab API > Groups > Milestones > List group milestones
121
+ # # @example
122
+ # # require 'support_ops_gitlab'
123
+ # #
124
+ # # SupportOps::GitLab::Configuration.configure do |config|
125
+ # # config.token = ENV.fetch('GL_TOKEN')
126
+ # # config.url = 'https://gitlab.com/api/v4'
127
+ # # end
128
+ # #
129
+ # # group = SupportOps::GitLab::Groups.get!(123456)
130
+ # # milestones = group.milestones
131
+ # # pp milestones.count
132
+ # # # => 24
133
+ # def milestones; end
134
+ # @!parse
135
+ # # List merge requests within a group
136
+ # #
137
+ # # @author Jason Colyer
138
+ # # @since 1.0.0
139
+ # # @return [Boolean]
140
+ # # @note This is inherited from {SupportOps::GitLab::Base#merge_requests}
141
+ # # @see
142
+ # # https://docs.gitlab.com/api/merge_requests/#list-group-merge-requests
143
+ # # GitLab API > Merge requests > List group merge requests
144
+ # # @example
145
+ # # require 'support_ops_gitlab'
146
+ # #
147
+ # # SupportOps::GitLab::Configuration.configure do |config|
148
+ # # config.token = ENV.fetch('GL_TOKEN')
149
+ # # config.url = 'https://gitlab.com/api/v4'
150
+ # # end
151
+ # #
152
+ # # group = SupportOps::GitLab::Groups.get!(123456)
153
+ # # merge_requests = group.merge_requests
154
+ # # pp merge_requests.count
155
+ # # # => 128
156
+ # def merge_requests; end
157
+ # @!parse
158
+ # # List epics within a group
159
+ # #
160
+ # # @author Jason Colyer
161
+ # # @since 1.0.0
162
+ # # @return [Boolean]
163
+ # # @note This is inherited from {SupportOps::GitLab::Base#epics}
164
+ # # @see
165
+ # # https://docs.gitlab.com/api/epics/#list-epics-for-a-group
166
+ # # GitLab API > Epics > List epics for a group
167
+ # # @example
168
+ # # require 'support_ops_gitlab'
169
+ # #
170
+ # # SupportOps::GitLab::Configuration.configure do |config|
171
+ # # config.token = ENV.fetch('GL_TOKEN')
172
+ # # config.url = 'https://gitlab.com/api/v4'
173
+ # # end
174
+ # #
175
+ # # group = SupportOps::GitLab::Groups.get!(123456)
176
+ # # epics = group.epics
177
+ # # pp epics.count
178
+ # # # => 3
179
+ # def epics; end
180
+ # @!parse
181
+ # # List members within a group
182
+ # #
183
+ # # @author Jason Colyer
184
+ # # @since 1.0.0
185
+ # # @return [Boolean]
186
+ # # @note This is inherited from {SupportOps::GitLab::Base#members}
187
+ # # @see
188
+ # # https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project
189
+ # # GitLab API > Members > List all members of a group or project
190
+ # # @see
191
+ # # https://docs.gitlab.com/api/members/#list-all-members-of-a-group-or-project-including-inherited-and-invited-members
192
+ # # GitLab API > Members > List all members of a group or project including inherited and invited members
193
+ # # @example
194
+ # # require 'support_ops_gitlab'
195
+ # #
196
+ # # SupportOps::GitLab::Configuration.configure do |config|
197
+ # # config.token = ENV.fetch('GL_TOKEN')
198
+ # # config.url = 'https://gitlab.com/api/v4'
199
+ # # end
200
+ # #
201
+ # # group = SupportOps::GitLab::Groups.get!(123456)
202
+ # # members = group.members
203
+ # # pp members.count
204
+ # # # => 5
205
+ # # members = group.members(all: true)
206
+ # # pp members.count
207
+ # # # => 15
208
+ # def members; end
209
+ # @!parse
210
+ # # Return the encoded path for a group
211
+ # #
212
+ # # @author Jason Colyer
213
+ # # @since 1.0.0
214
+ # # @return [Boolean]
215
+ # # @note This is inherited from {SupportOps::GitLab::Base#encoded_path}
216
+ # # @example
217
+ # # require 'support_ops_gitlab'
218
+ # #
219
+ # # SupportOps::GitLab::Configuration.configure do |config|
220
+ # # config.token = ENV.fetch('GL_TOKEN')
221
+ # # config.url = 'https://gitlab.com/api/v4'
222
+ # # end
223
+ # #
224
+ # # group = SupportOps::GitLab::Groups.get!(123456)
225
+ # # pp group.encoded_path
226
+ # # # => "test%2Fgroup"
227
+ # def encoded_path; end
228
+ define_attributes :allowed_email_domains_list,
229
+ :auto_ban_user_on_excessive_projects_download,
230
+ :avatar_url, :auto_devops_enabled, :created_at,
231
+ :default_branch, :default_branch_protection_defaults,
232
+ :description, :duo_availability, :duo_features_enabled,
233
+ :emails_enabled, :enabled_git_access_protocol,
234
+ :experiment_features_enabled,
235
+ :extra_shared_runners_minutes_limit,
236
+ :file_template_project_id, :full_name, :full_path, :id,
237
+ :ip_restriction_ranges, :lfs_enabled,
238
+ :lock_duo_features_enabled,
239
+ :lock_math_rendering_limits_enabled,
240
+ :marked_for_deletion_on, :math_rendering_limits_enabled,
241
+ :max_artifacts_size, :membership_lock,
242
+ :mentions_disabled, :name, :organization_id, :parent_id,
243
+ :path, :prevent_forking_outside_group,
244
+ :prevent_sharing_groups_outside_hierarchy,
245
+ :project_creation_level, :repository_storage,
246
+ :request_access_enabled,
247
+ :require_two_factor_authentication, :runners_token,
248
+ :share_with_group_lock, :shared_runners_minutes_limit,
249
+ :shared_with_groups, :statistics,
250
+ :subgroup_creation_level, :two_factor_grace_period,
251
+ :unique_project_download_limit,
252
+ :unique_project_download_limit_allowlist,
253
+ :unique_project_download_limit_alertlist,
254
+ :unique_project_download_limit_interval_in_seconds,
255
+ :visibility, :web_url, :wiki_access_level
256
+ readonly_attributes :avatar_url, :created_at, :full_name, :id, :parent_id,
257
+ :repository_storage, :runners_token,
258
+ :shared_with_groups, :statistics, :web_url
259
+
260
+ ##
261
+ # Locates a specific group in the GitLab system
262
+ #
263
+ # @author Jason Colyer
264
+ # @since 1.0.0
265
+ # @see
266
+ # https://docs.gitlab.com/api/groups/#get-a-single-group
267
+ # GitLab API > Groups > Get a single group
268
+ # @see SupportOps::GitLab::Configuration Setting up a client
269
+ # @example
270
+ # require 'support_ops_gitlab'
271
+ #
272
+ # SupportOps::GitLab::Configuration.configure do |config|
273
+ # config.url = 'https://gitlab.com/api/v4'
274
+ # config.token = 'abc123'
275
+ # end
276
+ #
277
+ # group = SupportOps::GitLab::Groups.get(123456)
278
+ # pp group.name
279
+ # # => "My Awesome Group"
280
+ def self.get(object)
281
+ if object.is_a? Groups
282
+ Groups.new(id: id).find
283
+ else
284
+ Groups.new(id: object).find
285
+ end
286
+ end
287
+
288
+ ##
289
+ # Locates a specific group in the GitLab system
290
+ #
291
+ # @author Jason Colyer
292
+ # @since 1.0.0
293
+ # @see
294
+ # https://docs.gitlab.com/api/groups/#get-a-single-group
295
+ # GitLab API > Groups > Get a single group
296
+ # @see SupportOps::GitLab::Configuration Setting up a client
297
+ # @example
298
+ # require 'support_ops_gitlab'
299
+ #
300
+ # SupportOps::GitLab::Configuration.configure do |config|
301
+ # config.url = 'https://gitlab.com/api/v4'
302
+ # config.token = 'abc123'
303
+ # end
304
+ #
305
+ # group = SupportOps::GitLab::Groups.get!(123456)
306
+ # pp group.name
307
+ # # => "My Awesome Group"
308
+ def self.get!(object)
309
+ if object.is_a? Groups
310
+ Groups.new(id: id).find!
311
+ else
312
+ Groups.new(id: object).find!
313
+ end
314
+ end
315
+
316
+ private
317
+
318
+ ##
319
+ # @private
320
+ def get_record
321
+ response = self.client.connection.get("groups/#{self.id}?with_projects=false")
322
+ return nil if response.status != 200
323
+
324
+ Oj.load(response.body)
325
+ end
326
+
327
+ ##
328
+ # @private
329
+ def members_record(**args)
330
+ args[:all] = false unless args[:all]
331
+ args[:query] = nil unless args[:query]
332
+ args[:user_ids] = nil unless args[:user_ids]
333
+ args[:skip_users] = nil unless args[:skip_users]
334
+ args[:show_seat_info] = nil unless args[:show_seat_info]
335
+ params = ''
336
+ params += "query&" unless args[:query].nil?
337
+ params += "user_ids&" unless args[:user_ids].nil?
338
+ params += "skip_users&" unless args[:skip_users].nil?
339
+ params += "show_seat_info&" unless args[:show_seat_info].nil?
340
+ base_url = if args[:all]
341
+ "groups/#{self.id}/members/all"
342
+ else
343
+ "groups/#{self.id}/members"
344
+ end
345
+ array = []
346
+ page = 1
347
+ loop do
348
+ response = self.client.connection.get("#{base_url}?#{params}&page=#{page}&per_page=100")
349
+ pp "#{base_url}?#{params}&page=#{page}&per_page=100"
350
+ body = Oj.load(response.body)
351
+ array += body.map { |g| GroupMemberships.new(g) }
352
+ break if body.count < 100
353
+ page += 1
354
+ end
355
+ array
356
+ end
357
+
358
+ ##
359
+ # @private
360
+ def encoded_path_record
361
+ ERB::Util.url_encode(self.full_path)
362
+ end
363
+
364
+ ##
365
+ # @private
366
+ def epics_records
367
+ Epics.list(group_id: self.id)
368
+ end
369
+
370
+ ##
371
+ # @private
372
+ def issues_record
373
+ array = []
374
+ page = 1
375
+ loop do
376
+ response = self.client.connection.get("groups/#{self.id}/issues?per_page=100&page=#{page}")
377
+ body = Oj.load(response.body)
378
+ array += body.map { |i| Issues.new(i) }
379
+ break if body.count < 100
380
+
381
+ page += 1
382
+ end
383
+ array
384
+ end
385
+
386
+ ##
387
+ # @private
388
+ def milestones_record
389
+ Milestones.list(group_id: self.id)
390
+ end
391
+
392
+ ##
393
+ # @private
394
+ def projects_record
395
+ array = []
396
+ page = 1
397
+ loop do
398
+ response = self.client.connection.get("groups/#{self.id}/projects?per_page=100&page=#{page}")
399
+ body = Oj.load(response.body)
400
+ array += body.map { |p| Projects.new(p) }
401
+ break if body.count < 100
402
+
403
+ page += 1
404
+ end
405
+ array
406
+ end
407
+
408
+ ##
409
+ # @private
410
+ def badges_record
411
+ Badges.list(group_id: self.id)
412
+ end
413
+
414
+ ##
415
+ # @private
416
+ def merge_requests_record
417
+ array = []
418
+ page = 1
419
+ loop do
420
+ response = self.client.connection.get("groups/#{self.id}/merge_requests?page=#{page}&per_page=100")
421
+ body = Oj.load(response.body)
422
+ array += body.map { |m| MergeRequests.new(m) }
423
+ break if body.count < 100
424
+
425
+ page += 1
426
+ end
427
+ array
428
+ end
429
+ end
430
+ end
431
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Defines the module SupportOps.
4
+ module SupportOps
5
+ # Defines the module GitLab
6
+ module GitLab
7
+ ##
8
+ # Defines the class Invitations within the module {SupportOps::GitLab}.
9
+ #
10
+ # @author Jason Colyer
11
+ # @since 1.0.0
12
+ # @todo Add attributes
13
+ # @todo Stuff at https://docs.gitlab.com/api/invitations/
14
+ class Invitations < SupportOps::GitLab::Base
15
+ define_attributes :id
16
+ readonly_attributes :id
17
+
18
+ ##
19
+ # Create a membership invitation for a project. This will exit on error
20
+ #
21
+ # @author Jason Colyer
22
+ # @since 1.0.0
23
+ # @param item_id [Integer] The ID of the project or group
24
+ # @param type [String]
25
+ # @param project [Object] An instance of {Readiness::GitLab::Projects}
26
+ # @param data [Hash] The invite information
27
+ # @return [Array]
28
+ # @see
29
+ # https://docs.gitlab.com/ee/api/invitations.html#add-a-member-to-a-group-or-project
30
+ # GitLab API > Invitations > Add a member to a group or project
31
+ # @example
32
+ # require 'support_ops_gitlab'
33
+ #
34
+ # SupportOps::GitLab::Configuration.configure do |config|
35
+ # config.url = 'https://gitlab.com/api/v4'
36
+ # config.token = 'abc123'
37
+ # end
38
+ #
39
+ # data = {
40
+ # email: 'bob@example.com',
41
+ # access_level: 50
42
+ # }
43
+ # invite = SupportOps::GitLab::Invitations.create!('project', 1234, data)
44
+ # pp invite
45
+ # # => {"status"=>"success"}
46
+ # @example
47
+ # require 'support_ops_gitlab'
48
+ #
49
+ # SupportOps::GitLab::Configuration.configure do |config|
50
+ # config.url = 'https://gitlab.com/api/v4'
51
+ # config.token = 'abc123'
52
+ # end
53
+ #
54
+ # data = {
55
+ # user_id: 987,
56
+ # access_level: 40
57
+ # }
58
+ # invite = SupportOps::GitLab::Invitations.create!('group', 5678, data)
59
+ # pp invite
60
+ # # => {"status"=>"success"}
61
+ def self.create!(item_id, type, data)
62
+ raise "This only works for a project or group, not a #{type}" unless %w[project group].include? type.downcase.singularize
63
+ response = client.connection.post("#{type.downcase.pluralize}/#{item_id}/invitations", data.to_json)
64
+ body = Oj.load(response.body)
65
+ raise "Failed to create invites => #{body}" unless response.status == 200
66
+ body
67
+ end
68
+
69
+ private
70
+ end
71
+ end
72
+ end