From 198801fbebf4095e05894411979faf27fb119cf5 Mon Sep 17 00:00:00 2001 From: Katie West Date: Fri, 25 Sep 2026 09:24:43 -0700 Subject: [PATCH] feat(directory-sync): Add on-demand sync (FEAT-3084) --- .oagen-manifest.json | 8 +++++ lib/workos/directory_sync.rb | 19 ++++++++++ .../directory_sync_rate_limit_error.rb | 25 +++++++++++++ .../directory_sync/directory_sync_response.rb | 18 ++++++++++ rbi/workos/directory_sync.rbi | 8 +++++ .../directory_sync_rate_limit_error.rbi | 36 +++++++++++++++++++ rbi/workos/directory_sync_response.rbi | 24 +++++++++++++ test/workos/test_directory_sync.rb | 8 +++++ .../test_directory_sync_model_round_trip.rb | 24 +++++++++++++ 9 files changed, 170 insertions(+) create mode 100644 lib/workos/directory_sync/directory_sync_rate_limit_error.rb create mode 100644 lib/workos/directory_sync/directory_sync_response.rb create mode 100644 rbi/workos/directory_sync_rate_limit_error.rbi create mode 100644 rbi/workos/directory_sync_response.rbi diff --git a/.oagen-manifest.json b/.oagen-manifest.json index ade3f514..9c092da9 100644 --- a/.oagen-manifest.json +++ b/.oagen-manifest.json @@ -137,6 +137,8 @@ "lib/workos/directory_sync/directory_group.rb", "lib/workos/directory_sync/directory_metadata.rb", "lib/workos/directory_sync/directory_metadata_user.rb", + "lib/workos/directory_sync/directory_sync_rate_limit_error.rb", + "lib/workos/directory_sync/directory_sync_response.rb", "lib/workos/directory_sync/directory_user.rb", "lib/workos/directory_sync/directory_user_email.rb", "lib/workos/directory_sync/directory_user_with_groups.rb", @@ -1101,6 +1103,8 @@ "rbi/workos/directory_metadata.rbi", "rbi/workos/directory_metadata_user.rbi", "rbi/workos/directory_sync.rbi", + "rbi/workos/directory_sync_rate_limit_error.rbi", + "rbi/workos/directory_sync_response.rbi", "rbi/workos/directory_user.rbi", "rbi/workos/directory_user_email.rbi", "rbi/workos/directory_user_with_groups.rbi", @@ -2589,6 +2593,10 @@ "GET /audit_logs/exports/{auditLogExportId}": { "sdkMethod": "get_export", "service": "audit_logs" + }, + "POST /directories/{id}/sync": { + "sdkMethod": "sync_directory", + "service": "directory_sync" } } } diff --git a/lib/workos/directory_sync.rb b/lib/workos/directory_sync.rb index 3420ba7c..efbdca66 100644 --- a/lib/workos/directory_sync.rb +++ b/lib/workos/directory_sync.rb @@ -102,6 +102,25 @@ def delete_directory( nil end + # Sync a Directory + # @param id [String] Unique identifier for the Directory. + # @param request_options [Hash] (see WorkOS::Types::RequestOptions) + # @return [WorkOS::DirectorySyncResponse] + def sync_directory( + id:, + request_options: {} + ) + response = @client.request( + method: :post, + path: "/directories/#{WorkOS::Util.encode_path(id)}/sync", + auth: true, + request_options: request_options + ) + result = WorkOS::DirectorySyncResponse.new(response.body) + result.last_response = WorkOS::Types::ApiResponse.new(http_status: response.code.to_i, http_headers: response.each_header.to_h, request_id: response["x-request-id"]) + result + end + # List Directory Groups # @param before [String, nil] An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `before="obj_123"` to fetch a new batch of objects before `"obj_123"`. # @param after [String, nil] An object ID that defines your place in the list. When the ID is not present, you are at the end of the list. For example, if you make a list request and receive 100 objects, ending with `"obj_123"`, your subsequent call can include `after="obj_123"` to fetch a new batch of objects after `"obj_123"`. diff --git a/lib/workos/directory_sync/directory_sync_rate_limit_error.rb b/lib/workos/directory_sync/directory_sync_rate_limit_error.rb new file mode 100644 index 00000000..4312daf1 --- /dev/null +++ b/lib/workos/directory_sync/directory_sync_rate_limit_error.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# This file is auto-generated by oagen. Do not edit. + +module WorkOS + class DirectorySyncRateLimitError < WorkOS::Types::BaseModel + HASH_ATTRS = { + code: :code, + message: :message, + retry_after_seconds: :retry_after_seconds + }.freeze + + attr_accessor \ + :code, + :message, + :retry_after_seconds + + def initialize(json) + hash = self.class.normalize(json) + @code = hash[:code] + @message = hash[:message] + @retry_after_seconds = hash[:retry_after_seconds] + end + end +end diff --git a/lib/workos/directory_sync/directory_sync_response.rb b/lib/workos/directory_sync/directory_sync_response.rb new file mode 100644 index 00000000..a543e217 --- /dev/null +++ b/lib/workos/directory_sync/directory_sync_response.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# This file is auto-generated by oagen. Do not edit. + +module WorkOS + class DirectorySyncResponse < WorkOS::Types::BaseModel + HASH_ATTRS = { + status: :status + }.freeze + + attr_accessor :status + + def initialize(json) + hash = self.class.normalize(json) + @status = hash[:status] + end + end +end diff --git a/rbi/workos/directory_sync.rbi b/rbi/workos/directory_sync.rbi index 376dffd2..686a8f52 100644 --- a/rbi/workos/directory_sync.rbi +++ b/rbi/workos/directory_sync.rbi @@ -39,6 +39,14 @@ module WorkOS end def delete_directory(id:, request_options:); end + sig do + params( + id: String, + request_options: T::Hash[Symbol, T.untyped] + ).returns(WorkOS::DirectorySyncResponse) + end + def sync_directory(id:, request_options:); end + sig do params( before: T.nilable(String), diff --git a/rbi/workos/directory_sync_rate_limit_error.rbi b/rbi/workos/directory_sync_rate_limit_error.rbi new file mode 100644 index 00000000..31dfbc29 --- /dev/null +++ b/rbi/workos/directory_sync_rate_limit_error.rbi @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# This file is auto-generated by oagen. Do not edit. + +# typed: strong + +module WorkOS + class DirectorySyncRateLimitError + sig { params(json: T.any(String, T::Hash[Symbol, T.untyped])).void } + def initialize(json); end + + sig { returns(String) } + def code; end + + sig { params(value: String).returns(String) } + def code=(value); end + + sig { returns(String) } + def message; end + + sig { params(value: String).returns(String) } + def message=(value); end + + sig { returns(Integer) } + def retry_after_seconds; end + + sig { params(value: Integer).returns(Integer) } + def retry_after_seconds=(value); end + + sig { returns(T::Hash[Symbol, T.untyped]) } + def to_h; end + + sig { params(args: T.untyped).returns(String) } + def to_json(*args); end + end +end diff --git a/rbi/workos/directory_sync_response.rbi b/rbi/workos/directory_sync_response.rbi new file mode 100644 index 00000000..b08085af --- /dev/null +++ b/rbi/workos/directory_sync_response.rbi @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# This file is auto-generated by oagen. Do not edit. + +# typed: strong + +module WorkOS + class DirectorySyncResponse + sig { params(json: T.any(String, T::Hash[Symbol, T.untyped])).void } + def initialize(json); end + + sig { returns(String) } + def status; end + + sig { params(value: String).returns(String) } + def status=(value); end + + sig { returns(T::Hash[Symbol, T.untyped]) } + def to_h; end + + sig { params(args: T.untyped).returns(String) } + def to_json(*args); end + end +end diff --git a/test/workos/test_directory_sync.rb b/test/workos/test_directory_sync.rb index 574ec0ee..62ac66a9 100644 --- a/test/workos/test_directory_sync.rb +++ b/test/workos/test_directory_sync.rb @@ -32,6 +32,13 @@ def test_delete_directory_returns_expected_result assert_nil result end + def test_sync_directory_returns_expected_result + stub_request(:post, %r{\Ahttps://api\.workos\.com/directories/stub/sync(\?|\z)}) + .to_return(body: "{}", status: 200) + result = @client.directory_sync.sync_directory(id: "stub") + refute_nil result + end + def test_list_groups_returns_expected_result stub_request(:get, %r{\Ahttps://api\.workos\.com/directory_groups(\?|\z)}) .to_return(body: '{"data": [], "list_metadata": {}}', status: 200) @@ -65,6 +72,7 @@ def test_get_user_returns_expected_result {name: :list_directories, verb: :get, url: %r{\Ahttps://api\.workos\.com/directories(\?|\z)}}, {name: :get_directory, verb: :get, url: %r{\Ahttps://api\.workos\.com/directories/stub(\?|\z)}, args: {id: "stub"}}, {name: :delete_directory, verb: :delete, url: %r{\Ahttps://api\.workos\.com/directories/stub(\?|\z)}, args: {id: "stub"}}, + {name: :sync_directory, verb: :post, url: %r{\Ahttps://api\.workos\.com/directories/stub/sync(\?|\z)}, args: {id: "stub"}}, {name: :list_groups, verb: :get, url: %r{\Ahttps://api\.workos\.com/directory_groups(\?|\z)}}, {name: :get_group, verb: :get, url: %r{\Ahttps://api\.workos\.com/directory_groups/stub(\?|\z)}, args: {id: "stub"}}, {name: :list_users, verb: :get, url: %r{\Ahttps://api\.workos\.com/directory_users(\?|\z)}}, diff --git a/test/workos/test_directory_sync_model_round_trip.rb b/test/workos/test_directory_sync_model_round_trip.rb index 2f2daea8..d9802f58 100644 --- a/test/workos/test_directory_sync_model_round_trip.rb +++ b/test/workos/test_directory_sync_model_round_trip.rb @@ -31,6 +31,30 @@ def test_directory_round_trip fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" } end + def test_directory_sync_response_round_trip + fixture = { + "status" => "queued" + } + model = WorkOS::DirectorySyncResponse.new(fixture.to_json) + json = model.to_h + assert_kind_of Hash, json + fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" } + end + + def test_directory_sync_rate_limit_error_round_trip + fixture = { + "code" => "directory_sync_rate_limited", + "message" => "stub", + "retry_after_seconds" => 1 + } + model = WorkOS::DirectorySyncRateLimitError.new(fixture.to_json) + json = model.to_h + assert_kind_of Hash, json + assert_equal fixture["message"], json[:message] + assert_equal fixture["retry_after_seconds"], json[:retry_after_seconds] + fixture.each_key { |k| assert json.key?(k.to_sym) || json.key?(k), "Expected to_h to include key #{k}" } + end + def test_directory_group_round_trip fixture = { "object" => "directory_group",