workos 0.10.2 → 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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.ruby-version +1 -1
  4. data/.semaphore/semaphore.yml +8 -2
  5. data/Gemfile.lock +49 -36
  6. data/LICENSE +1 -1
  7. data/README.md +13 -230
  8. data/lib/workos.rb +5 -0
  9. data/lib/workos/client.rb +21 -4
  10. data/lib/workos/connection.rb +12 -1
  11. data/lib/workos/directory.rb +53 -0
  12. data/lib/workos/directory_group.rb +44 -0
  13. data/lib/workos/directory_sync.rb +63 -7
  14. data/lib/workos/directory_user.rb +63 -0
  15. data/lib/workos/organizations.rb +150 -0
  16. data/lib/workos/passwordless.rb +4 -0
  17. data/lib/workos/portal.rb +0 -80
  18. data/lib/workos/profile.rb +1 -2
  19. data/lib/workos/profile_and_token.rb +28 -0
  20. data/lib/workos/sso.rb +37 -104
  21. data/lib/workos/types.rb +3 -0
  22. data/lib/workos/types/connection_struct.rb +3 -0
  23. data/lib/workos/types/directory_group_struct.rb +13 -0
  24. data/lib/workos/types/directory_struct.rb +16 -0
  25. data/lib/workos/types/directory_user_struct.rb +19 -0
  26. data/lib/workos/version.rb +1 -1
  27. data/sorbet/rbi/gems/addressable.rbi +199 -0
  28. data/sorbet/rbi/gems/ast.rbi +49 -0
  29. data/sorbet/rbi/gems/codecov.rbi +37 -0
  30. data/sorbet/rbi/gems/crack.rbi +62 -0
  31. data/sorbet/rbi/gems/docile.rbi +36 -0
  32. data/sorbet/rbi/gems/hashdiff.rbi +66 -0
  33. data/sorbet/rbi/gems/parallel.rbi +83 -0
  34. data/sorbet/rbi/gems/parser.rbi +1429 -0
  35. data/sorbet/rbi/gems/public_suffix.rbi +104 -0
  36. data/sorbet/rbi/gems/rainbow.rbi +118 -0
  37. data/sorbet/rbi/gems/rake.rbi +644 -0
  38. data/sorbet/rbi/gems/regexp_parser.rbi +926 -0
  39. data/sorbet/rbi/gems/rexml.rbi +628 -0
  40. data/sorbet/rbi/gems/rspec-core.rbi +1898 -0
  41. data/sorbet/rbi/gems/rspec-expectations.rbi +1127 -0
  42. data/sorbet/rbi/gems/rspec-mocks.rbi +1099 -0
  43. data/sorbet/rbi/gems/rspec-support.rbi +280 -0
  44. data/sorbet/rbi/gems/rspec.rbi +15 -0
  45. data/sorbet/rbi/gems/rubocop-ast.rbi +1355 -0
  46. data/sorbet/rbi/gems/rubocop.rbi +7253 -0
  47. data/sorbet/rbi/gems/ruby-progressbar.rbi +304 -0
  48. data/sorbet/rbi/gems/simplecov-html.rbi +35 -0
  49. data/sorbet/rbi/gems/simplecov.rbi +406 -0
  50. data/sorbet/rbi/gems/unicode-display_width.rbi +17 -0
  51. data/sorbet/rbi/gems/vcr.rbi +572 -0
  52. data/sorbet/rbi/gems/webmock.rbi +556 -0
  53. data/sorbet/rbi/gems/yard.rbi +1165 -0
  54. data/sorbet/rbi/sorbet-typed/lib/rake/all/rake.rbi +645 -0
  55. data/sorbet/rbi/sorbet-typed/lib/rspec-core/all/rspec-core.rbi +1891 -0
  56. data/sorbet/rbi/sorbet-typed/lib/rubocop/~>0.85/rubocop.rbi +2072 -0
  57. data/sorbet/rbi/sorbet-typed/lib/yard/all/yard.rbi +1214 -0
  58. data/sorbet/rbi/todo.rbi +1 -3
  59. data/spec/lib/workos/audit_trail_spec.rb +0 -8
  60. data/spec/lib/workos/directory_sync_spec.rb +347 -40
  61. data/spec/lib/workos/organizations_spec.rb +164 -0
  62. data/spec/lib/workos/passwordless_spec.rb +0 -8
  63. data/spec/lib/workos/portal_spec.rb +0 -121
  64. data/spec/lib/workos/sso_spec.rb +141 -187
  65. data/spec/spec_helper.rb +2 -1
  66. data/spec/support/fixtures/vcr_cassettes/directory_sync/delete_directory.yml +72 -0
  67. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections.yml → directory_sync/list_directories/with_after.yml} +7 -7
  68. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_limit_param.yml → directory_sync/list_directories/with_before.yml} +8 -8
  69. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_connection_type_param.yml → directory_sync/list_directories/with_domain.yml} +11 -10
  70. data/spec/support/fixtures/vcr_cassettes/{sso/list_connections_with_after_param.yml → directory_sync/list_directories/with_limit.yml} +12 -10
  71. data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_directories.yml → list_directories/with_no_options.yml} +1 -1
  72. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories/with_search.yml +73 -0
  73. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_after.yml +76 -0
  74. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_before.yml +74 -0
  75. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_directory.yml +78 -0
  76. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_limit.yml +74 -0
  77. data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_groups.yml → list_groups/with_no_options.yml} +16 -6
  78. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups/with_user.yml +72 -0
  79. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_after.yml +86 -0
  80. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_before.yml +75 -0
  81. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_directory.yml +93 -0
  82. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_group.yml +76 -0
  83. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users/with_limit.yml +75 -0
  84. data/spec/support/fixtures/vcr_cassettes/directory_sync/{list_users.yml → list_users/with_no_options.yml} +16 -6
  85. data/spec/support/fixtures/vcr_cassettes/organization/get.yml +73 -0
  86. data/spec/support/fixtures/vcr_cassettes/organization/get_invalid.yml +72 -0
  87. data/spec/support/fixtures/vcr_cassettes/organization/update.yml +73 -0
  88. data/spec/support/fixtures/vcr_cassettes/organization/update_invalid.yml +73 -0
  89. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_after.yml +73 -0
  90. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_before.yml +73 -0
  91. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_connection_type.yml +73 -0
  92. data/spec/support/fixtures/vcr_cassettes/sso/{list_connections_with_domain_param.yml → list_connections/with_domain.yml} +6 -6
  93. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_limit.yml +74 -0
  94. data/spec/support/fixtures/vcr_cassettes/sso/list_connections/with_no_options.yml +73 -0
  95. data/spec/support/fixtures/vcr_cassettes/sso/{list_connections_with_organization_id_param.yml → list_connections/with_organization_id.yml} +6 -6
  96. data/workos.gemspec +2 -0
  97. metadata +109 -44
  98. data/sorbet/rbi/hidden-definitions/errors.txt +0 -24896
  99. data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -38411
  100. data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +0 -8684
  101. data/sorbet/rbi/sorbet-typed/lib/ruby/all/gem.rbi +0 -4222
  102. data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +0 -111
  103. data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +0 -543
  104. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_directories_with_domain_param.yml +0 -63
  105. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_groups_with_directory_param.yml +0 -62
  106. data/spec/support/fixtures/vcr_cassettes/directory_sync/list_users_with_directory_param.yml +0 -62
  107. data/spec/support/fixtures/vcr_cassettes/sso/create_connection_with_invalid_source.yml +0 -58
  108. data/spec/support/fixtures/vcr_cassettes/sso/create_connection_with_valid_source.yml +0 -63
  109. data/spec/support/fixtures/vcr_cassettes/sso/list_connections_with_before_param.yml +0 -73
data/lib/workos.rb CHANGED
@@ -32,11 +32,16 @@ module WorkOS
32
32
  autoload :AuditTrail, 'workos/audit_trail'
33
33
  autoload :Connection, 'workos/connection'
34
34
  autoload :DirectorySync, 'workos/directory_sync'
35
+ autoload :Directory, 'workos/directory'
36
+ autoload :DirectoryGroup, 'workos/directory_group'
35
37
  autoload :Organization, 'workos/organization'
38
+ autoload :Organizations, 'workos/organizations'
36
39
  autoload :Passwordless, 'workos/passwordless'
37
40
  autoload :Portal, 'workos/portal'
38
41
  autoload :Profile, 'workos/profile'
42
+ autoload :ProfileAndToken, 'workos/profile_and_token'
39
43
  autoload :SSO, 'workos/sso'
44
+ autoload :DirectoryUser, 'workos/directory_user'
40
45
 
41
46
  # Errors
42
47
  autoload :APIError, 'workos/errors'
data/lib/workos/client.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: false
3
3
 
4
4
  module WorkOS
5
5
  # A Net::HTTP based API client for interacting with the WorkOS API
@@ -19,7 +19,7 @@ module WorkOS
19
19
 
20
20
  sig do
21
21
  params(
22
- request: T.any(Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Delete),
22
+ request: T.any(Net::HTTP::Get, Net::HTTP::Post, Net::HTTP::Delete, Net::HTTP::Put),
23
23
  ).returns(::T.untyped)
24
24
  end
25
25
  def execute_request(request:)
@@ -90,6 +90,23 @@ module WorkOS
90
90
  request
91
91
  end
92
92
 
93
+ sig do
94
+ params(
95
+ path: String,
96
+ auth: T.nilable(T::Boolean),
97
+ idempotency_key: T.nilable(String),
98
+ body: T.nilable(Hash),
99
+ ).returns(Net::HTTP::Put)
100
+ end
101
+ def put_request(path:, auth: false, idempotency_key: nil, body: nil)
102
+ request = Net::HTTP::Put.new(path, 'Content-Type' => 'application/json')
103
+ request.body = body.to_json if body
104
+ request['Authorization'] = "Bearer #{WorkOS.key!}" if auth
105
+ request['Idempotency-Key'] = idempotency_key if idempotency_key
106
+ request['User-Agent'] = user_agent
107
+ request
108
+ end
109
+
93
110
  sig { returns(String) }
94
111
  def user_agent
95
112
  engine = defined?(::RUBY_ENGINE) ? ::RUBY_ENGINE : 'Ruby'
@@ -102,7 +119,7 @@ module WorkOS
102
119
  ].join('; ')
103
120
  end
104
121
 
105
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
122
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
106
123
  sig { params(response: ::T.untyped).void }
107
124
  def handle_error_response(response:)
108
125
  http_status = response.code.to_i
@@ -139,7 +156,7 @@ module WorkOS
139
156
  )
140
157
  end
141
158
  end
142
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
159
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
143
160
 
144
161
  private
145
162
 
@@ -5,10 +5,12 @@ module WorkOS
5
5
  # The Connection class provides a lightweight wrapper around
6
6
  # a WorkOS Connection resource. This class is not meant to be instantiated
7
7
  # in user space, and is instantiated internally but exposed.
8
+ # Note: status is deprecated - use state instead
8
9
  class Connection
9
10
  extend T::Sig
10
11
 
11
- attr_accessor :id, :name, :connection_type, :domains
12
+ attr_accessor :id, :name, :connection_type, :domains, :organization_id,
13
+ :state, :status
12
14
 
13
15
  sig { params(json: String).void }
14
16
  def initialize(json)
@@ -18,6 +20,9 @@ module WorkOS
18
20
  @name = T.let(raw.name, String)
19
21
  @connection_type = T.let(raw.connection_type, String)
20
22
  @domains = T.let(raw.domains, Array)
23
+ @organization_id = T.let(raw.organization_id, String)
24
+ @state = T.let(raw.state, String)
25
+ @status = T.let(raw.status, String)
21
26
  end
22
27
 
23
28
  def to_json(*)
@@ -26,6 +31,9 @@ module WorkOS
26
31
  name: name,
27
32
  connection_type: connection_type,
28
33
  domains: domains,
34
+ organization_id: organization_id,
35
+ state: state,
36
+ status: status,
29
37
  }
30
38
  end
31
39
 
@@ -40,6 +48,9 @@ module WorkOS
40
48
  name: hash[:name],
41
49
  connection_type: hash[:connection_type],
42
50
  domains: hash[:domains],
51
+ organization_id: hash[:organization_id],
52
+ state: hash[:state],
53
+ status: hash[:status],
43
54
  )
44
55
  end
45
56
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOS
5
+ # The Directory class provides a lightweight wrapper around
6
+ # a WorkOS Directory resource. This class is not meant to be instantiated
7
+ # in user space, and is instantiated internally but exposed.
8
+ class Directory
9
+ extend T::Sig
10
+
11
+ attr_accessor :id, :domain, :name, :type, :state
12
+
13
+ sig { params(json: String).void }
14
+ def initialize(json)
15
+ raw = parse_json(json)
16
+
17
+ @id = T.let(raw.id, String)
18
+ @name = T.let(raw.name, String)
19
+ @domain = T.let(raw.domain, String)
20
+ @type = T.let(raw.type, String)
21
+ @state = T.let(raw.state, String)
22
+ end
23
+
24
+ def to_json(*)
25
+ {
26
+ id: id,
27
+ name: name,
28
+ domain: domain,
29
+ type: type,
30
+ state: state,
31
+ }
32
+ end
33
+
34
+ private
35
+
36
+ sig do
37
+ params(
38
+ json_string: String,
39
+ ).returns(WorkOS::Types::DirectoryStruct)
40
+ end
41
+ def parse_json(json_string)
42
+ hash = JSON.parse(json_string, symbolize_names: true)
43
+
44
+ WorkOS::Types::DirectoryStruct.new(
45
+ id: hash[:id],
46
+ name: hash[:name],
47
+ domain: hash[:domain],
48
+ type: hash[:type],
49
+ state: hash[:state],
50
+ )
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOS
5
+ # The DirectoryGroup class provides a lightweight wrapper around
6
+ # a WorkOS DirectoryGroup resource. This class is not meant to be instantiated
7
+ # in user space, and is instantiated internally but exposed.
8
+ class DirectoryGroup
9
+ extend T::Sig
10
+
11
+ attr_accessor :id, :name
12
+
13
+ sig { params(json: String).void }
14
+ def initialize(json)
15
+ raw = parse_json(json)
16
+
17
+ @id = T.let(raw.id, String)
18
+ @name = T.let(raw.name, String)
19
+ end
20
+
21
+ def to_json(*)
22
+ {
23
+ id: id,
24
+ name: name,
25
+ }
26
+ end
27
+
28
+ private
29
+
30
+ sig do
31
+ params(
32
+ json_string: String,
33
+ ).returns(WorkOS::Types::DirectoryGroupStruct)
34
+ end
35
+ def parse_json(json_string)
36
+ hash = JSON.parse(json_string, symbolize_names: true)
37
+
38
+ WorkOS::Types::DirectoryGroupStruct.new(
39
+ id: hash[:id],
40
+ name: hash[:name],
41
+ )
42
+ end
43
+ end
44
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- # typed: true
2
+ # typed: strict
3
3
 
4
4
  require 'net/http'
5
5
 
@@ -21,12 +21,17 @@ module WorkOS
21
21
  # @option options [String] domain The domain of the directory to be
22
22
  # retrieved.
23
23
  # @option options [String] search A search term for direcory names.
24
+ # @option options [String] limit Maximum number of records to return.
25
+ # @option options [String] before Pagination cursor to receive records
26
+ # before a provided Directory ID.
27
+ # @option options [String] after Pagination cursor to receive records
28
+ # before a provided Directory ID.
24
29
  #
25
30
  # @return [Hash]
26
31
  sig do
27
32
  params(
28
33
  options: T::Hash[Symbol, String],
29
- ).returns(T::Array[T::Hash[String, T.nilable(String)]])
34
+ ).returns(WorkOS::Types::ListStruct)
30
35
  end
31
36
  def list_directories(options = {})
32
37
  response = execute_request(
@@ -37,7 +42,15 @@ module WorkOS
37
42
  ),
38
43
  )
39
44
 
40
- JSON.parse(response.body)['data']
45
+ parsed_response = JSON.parse(response.body)
46
+ directories = parsed_response['data'].map do |directory|
47
+ ::WorkOS::Directory.new(directory.to_json)
48
+ end
49
+
50
+ WorkOS::Types::ListStruct.new(
51
+ data: directories,
52
+ list_metadata: parsed_response['listMetadata'],
53
+ )
41
54
  end
42
55
 
43
56
  # Retrieve directory groups.
@@ -47,12 +60,17 @@ module WorkOS
47
60
  # directory groups will be retrieved.
48
61
  # @option options [String] user The ID of the directory user whose
49
62
  # directory groups will be retrieved.
63
+ # @option options [String] limit Maximum number of records to return.
64
+ # @option options [String] before Pagination cursor to receive records
65
+ # before a provided Directory Group ID.
66
+ # @option options [String] after Pagination cursor to receive records
67
+ # before a provided Directory Group ID.
50
68
  #
51
69
  # @return [Hash]
52
70
  sig do
53
71
  params(
54
72
  options: T::Hash[Symbol, String],
55
- ).returns(T::Array[T::Hash[String, T.nilable(String)]])
73
+ ).returns(WorkOS::Types::ListStruct)
56
74
  end
57
75
  def list_groups(options = {})
58
76
  response = execute_request(
@@ -63,7 +81,15 @@ module WorkOS
63
81
  ),
64
82
  )
65
83
 
66
- JSON.parse(response.body)['data']
84
+ parsed_response = JSON.parse(response.body)
85
+ groups = parsed_response['data'].map do |group|
86
+ ::WorkOS::DirectoryGroup.new(group.to_json)
87
+ end
88
+
89
+ WorkOS::Types::ListStruct.new(
90
+ data: groups,
91
+ list_metadata: parsed_response['listMetadata'],
92
+ )
67
93
  end
68
94
 
69
95
  # Retrieve directory users.
@@ -73,12 +99,17 @@ module WorkOS
73
99
  # directory users will be retrieved.
74
100
  # @option options [String] user The ID of the directory group whose
75
101
  # directory users will be retrieved.
102
+ # @option options [String] limit Maximum number of records to return.
103
+ # @option options [String] before Pagination cursor to receive records
104
+ # before a provided Directory User ID.
105
+ # @option options [String] after Pagination cursor to receive records
106
+ # before a provided Directory User ID.
76
107
  #
77
108
  # @return [Hash]
78
109
  sig do
79
110
  params(
80
111
  options: T::Hash[Symbol, String],
81
- ).returns(T::Array[T::Hash[String, T.untyped]])
112
+ ).returns(WorkOS::Types::ListStruct)
82
113
  end
83
114
  def list_users(options = {})
84
115
  response = execute_request(
@@ -89,7 +120,15 @@ module WorkOS
89
120
  ),
90
121
  )
91
122
 
92
- JSON.parse(response.body)['data']
123
+ parsed_response = JSON.parse(response.body)
124
+ users = parsed_response['data'].map do |user|
125
+ ::WorkOS::DirectoryUser.new(user.to_json)
126
+ end
127
+
128
+ WorkOS::Types::ListStruct.new(
129
+ data: users,
130
+ list_metadata: parsed_response['listMetadata'],
131
+ )
93
132
  end
94
133
 
95
134
  # Retrieve the directory group with the given ID.
@@ -125,6 +164,23 @@ module WorkOS
125
164
 
126
165
  JSON.parse(response.body)
127
166
  end
167
+
168
+ # Delete the directory with the given ID.
169
+ #
170
+ # @param [String] id The ID of the directory.
171
+ #
172
+ # @return Boolean
173
+ sig { params(id: String).returns(T::Boolean) }
174
+ def delete_directory(id)
175
+ request = delete_request(
176
+ auth: true,
177
+ path: "/directories/#{id}",
178
+ )
179
+
180
+ response = execute_request(request: request)
181
+
182
+ response.is_a? Net::HTTPSuccess
183
+ end
128
184
  end
129
185
  end
130
186
  end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ module WorkOS
5
+ # The DirectoryUser class provides a lightweight wrapper around
6
+ # a WorkOS DirectoryUser resource. This class is not meant to be instantiated
7
+ # in DirectoryUser space, and is instantiated internally but exposed.
8
+ class DirectoryUser
9
+ extend T::Sig
10
+
11
+ attr_accessor :id, :idp_id, :emails, :first_name, :last_name, :username, :state,
12
+ :raw_attributes
13
+
14
+ sig { params(json: String).void }
15
+ def initialize(json)
16
+ raw = parse_json(json)
17
+
18
+ @id = T.let(raw.id, String)
19
+ @idp_id = T.let(raw.idp_id, String)
20
+ @emails = T.let(raw.emails, Array)
21
+ @first_name = raw.first_name
22
+ @last_name = raw.last_name
23
+ @username = raw.username
24
+ @state = raw.state
25
+ @raw_attributes = raw.raw_attributes
26
+ end
27
+
28
+ def to_json(*)
29
+ {
30
+ id: id,
31
+ idp_id: idp_id,
32
+ emails: emails,
33
+ first_name: first_name,
34
+ last_name: last_name,
35
+ username: username,
36
+ state: state,
37
+ raw_attributes: raw_attributes,
38
+ }
39
+ end
40
+
41
+ private
42
+
43
+ sig do
44
+ params(
45
+ json_string: String,
46
+ ).returns(WorkOS::Types::DirectoryUserStruct)
47
+ end
48
+ def parse_json(json_string)
49
+ hash = JSON.parse(json_string, symbolize_names: true)
50
+
51
+ WorkOS::Types::DirectoryUserStruct.new(
52
+ id: hash[:id],
53
+ idp_id: hash[:idp_id],
54
+ emails: hash[:emails],
55
+ first_name: hash[:first_name],
56
+ last_name: hash[:last_name],
57
+ username: hash[:username],
58
+ state: hash[:state],
59
+ raw_attributes: hash[:raw_attributes],
60
+ )
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'net/http'
5
+
6
+ module WorkOS
7
+ # The Organizations module provides resource methods for working with Organizations
8
+ module Organizations
9
+ class << self
10
+ extend T::Sig
11
+ include Base
12
+ include Client
13
+
14
+ # Retrieve a list of organizations that have connections configured
15
+ # within your WorkOS dashboard.
16
+ #
17
+ # @param [Array<String>] domains Filter organizations to only return those
18
+ # that are associated with the provided domains.
19
+ # @param [String] before A pagination argument used to request
20
+ # organizations before the provided Organization ID.
21
+ # @param [String] after A pagination argument used to request
22
+ # organizations after the provided Organization ID.
23
+ # @param [Integer] limit A pagination argument used to limit the number
24
+ # of listed Organizations that are returned.
25
+ sig do
26
+ params(
27
+ options: T::Hash[Symbol, String],
28
+ ).returns(WorkOS::Types::ListStruct)
29
+ end
30
+ def list_organizations(options = {})
31
+ response = execute_request(
32
+ request: get_request(
33
+ path: '/organizations',
34
+ auth: true,
35
+ params: options,
36
+ ),
37
+ )
38
+
39
+ parsed_response = JSON.parse(response.body)
40
+
41
+ organizations = parsed_response['data'].map do |organization|
42
+ ::WorkOS::Organization.new(organization.to_json)
43
+ end
44
+
45
+ WorkOS::Types::ListStruct.new(
46
+ data: organizations,
47
+ list_metadata: parsed_response['listMetadata'],
48
+ )
49
+ end
50
+
51
+ # Get an Organization
52
+ #
53
+ # @param [String] id Organization unique identifier
54
+ #
55
+ # @example
56
+ # WorkOS::Portal.get_organization(id: 'org_02DRA1XNSJDZ19A31F183ECQW9')
57
+ # => #<WorkOS::Organization:0x00007fb6e4193d20
58
+ # @id="org_02DRA1XNSJDZ19A31F183ECQW9",
59
+ # @name="Foo Corp",
60
+ # @domains=
61
+ # [{:object=>"organization_domain",
62
+ # :id=>"org_domain_01E6PK9N3XMD8RHWF7S66380AR",
63
+ # :domain=>"foo-corp.com"}]>
64
+ #
65
+ # @return [WorkOS::Connection]
66
+ sig { params(id: String).returns(WorkOS::Organization) }
67
+ def get_organization(id:)
68
+ request = get_request(
69
+ auth: true,
70
+ path: "/organizations/#{id}",
71
+ )
72
+
73
+ response = execute_request(request: request)
74
+
75
+ WorkOS::Organization.new(response.body)
76
+ end
77
+
78
+ # Create an organization
79
+ #
80
+ # @param [Array<String>] domains List of domains that belong to the
81
+ # organization
82
+ # @param [String] name A unique, descriptive name for the organization
83
+ sig do
84
+ params(
85
+ domains: T::Array[String],
86
+ name: String,
87
+ ).returns(WorkOS::Organization)
88
+ end
89
+ def create_organization(domains:, name:)
90
+ request = post_request(
91
+ auth: true,
92
+ body: { domains: domains, name: name },
93
+ path: '/organizations',
94
+ )
95
+
96
+ response = execute_request(request: request)
97
+ check_and_raise_organization_error(response: response)
98
+
99
+ WorkOS::Organization.new(response.body)
100
+ end
101
+
102
+ # Update an organization
103
+ #
104
+ # @param [String] organization Organization unique identifier
105
+ # @param [Array<String>] domains List of domains that belong to the
106
+ # organization
107
+ # @param [String] name A unique, descriptive name for the organization
108
+ sig do
109
+ params(
110
+ organization: String,
111
+ domains: T::Array[String],
112
+ name: String,
113
+ ).returns(WorkOS::Organization)
114
+ end
115
+ def update_organization(organization:, domains:, name:)
116
+ request = put_request(
117
+ auth: true,
118
+ body: { domains: domains, name: name },
119
+ path: "/organizations/#{organization}",
120
+ )
121
+
122
+ response = execute_request(request: request)
123
+ check_and_raise_organization_error(response: response)
124
+
125
+ WorkOS::Organization.new(response.body)
126
+ end
127
+
128
+ private
129
+
130
+ sig { params(response: Net::HTTPResponse).void }
131
+ def check_and_raise_organization_error(response:)
132
+ begin
133
+ body = JSON.parse(response.body)
134
+ return unless body['message']
135
+
136
+ message = body['message']
137
+ request_id = response['x-request-id']
138
+ rescue StandardError
139
+ message = 'Something went wrong'
140
+ end
141
+
142
+ raise APIError.new(
143
+ message: message,
144
+ http_status: nil,
145
+ request_id: request_id,
146
+ )
147
+ end
148
+ end
149
+ end
150
+ end