From 6eb6756ef89a7b99a3825bd5ab899bf2f0b030e2 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 13:28:56 +0000 Subject: [PATCH 01/13] chore(tests): bump steady to v0.20.1 --- scripts/mock | 6 +++--- scripts/test | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mock b/scripts/mock index 4931f304..8b82c3e5 100755 --- a/scripts/mock +++ b/scripts/mock @@ -22,9 +22,9 @@ echo "==> Starting mock server with URL ${URL}" # Run steady mock on the given spec if [ "$1" == "--daemon" ]; then # Pre-install the package so the download doesn't eat into the startup timeout - npm exec --package=@stdy/cli@0.19.7 -- steady --version + npm exec --package=@stdy/cli@0.20.1 -- steady --version - npm exec --package=@stdy/cli@0.19.7 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & + npm exec --package=@stdy/cli@0.20.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" @@ -48,5 +48,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stdy/cli@0.19.7 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" + npm exec --package=@stdy/cli@0.20.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index acff404e..da76620d 100755 --- a/scripts/test +++ b/scripts/test @@ -43,7 +43,7 @@ elif ! steady_is_running ; then echo -e "To run the server, pass in the path or url of your OpenAPI" echo -e "spec to the steady command:" echo - echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.19.7 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" + echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.20.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" echo exit 1 From 4206b20a8cd60362598da173185bbd236e659eff Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:18:31 +0000 Subject: [PATCH 02/13] chore(tests): bump steady to v0.20.2 --- scripts/mock | 6 +++--- scripts/test | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mock b/scripts/mock index 8b82c3e5..886f2ffc 100755 --- a/scripts/mock +++ b/scripts/mock @@ -22,9 +22,9 @@ echo "==> Starting mock server with URL ${URL}" # Run steady mock on the given spec if [ "$1" == "--daemon" ]; then # Pre-install the package so the download doesn't eat into the startup timeout - npm exec --package=@stdy/cli@0.20.1 -- steady --version + npm exec --package=@stdy/cli@0.20.2 -- steady --version - npm exec --package=@stdy/cli@0.20.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & + npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log & # Wait for server to come online via health endpoint (max 30s) echo -n "Waiting for server" @@ -48,5 +48,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stdy/cli@0.20.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" + npm exec --package=@stdy/cli@0.20.2 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" fi diff --git a/scripts/test b/scripts/test index da76620d..9fc2510b 100755 --- a/scripts/test +++ b/scripts/test @@ -43,7 +43,7 @@ elif ! steady_is_running ; then echo -e "To run the server, pass in the path or url of your OpenAPI" echo -e "spec to the steady command:" echo - echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.20.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" + echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.20.2 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=brackets --validator-form-array-format=brackets --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}" echo exit 1 From cde113151eb2879204409723971653616876fdee Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:31:01 +0000 Subject: [PATCH 03/13] fix: variable name typo --- lib/knockapi/internal/util.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/knockapi/internal/util.rb b/lib/knockapi/internal/util.rb index c4d54820..ce7b8933 100644 --- a/lib/knockapi/internal/util.rb +++ b/lib/knockapi/internal/util.rb @@ -157,7 +157,7 @@ def coerce_hash!(input) in Hash | nil => coerced coerced else - message = "Expected a #{Hash} or #{Knockapi::Internal::Type::BaseModel}, got #{data.inspect}" + message = "Expected a #{Hash} or #{Knockapi::Internal::Type::BaseModel}, got #{input.inspect}" raise ArgumentError.new(message) end end From 3e2268d3e0547fa66ad253e35c86da963cc36215 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 31 Mar 2026 20:46:12 +0000 Subject: [PATCH 04/13] fix: align path encoding with RFC 3986 section 3.3 --- lib/knockapi/internal/util.rb | 20 +++++++++++++++++--- rbi/knockapi/internal/util.rbi | 8 ++++++++ sig/knockapi/internal/util.rbs | 4 ++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/knockapi/internal/util.rb b/lib/knockapi/internal/util.rb index ce7b8933..7c80600d 100644 --- a/lib/knockapi/internal/util.rb +++ b/lib/knockapi/internal/util.rb @@ -237,6 +237,11 @@ def dig(data, pick, &blk) end end + # @type [Regexp] + # + # https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3 + RFC_3986_NOT_PCHARS = /[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/ + class << self # @api private # @@ -247,6 +252,15 @@ def uri_origin(uri) "#{uri.scheme}://#{uri.host}#{":#{uri.port}" unless uri.port == uri.default_port}" end + # @api private + # + # @param path [String, Integer] + # + # @return [String] + def encode_path(path) + path.to_s.gsub(Knockapi::Internal::Util::RFC_3986_NOT_PCHARS) { ERB::Util.url_encode(_1) } + end + # @api private # # @param path [String, Array] @@ -259,7 +273,7 @@ def interpolate_path(path) in [] "" in [String => p, *interpolations] - encoded = interpolations.map { ERB::Util.url_encode(_1) } + encoded = interpolations.map { encode_path(_1) } format(p, *encoded) end end @@ -576,10 +590,10 @@ def encode_query_params(query) case val in Knockapi::FilePart unless val.filename.nil? - filename = ERB::Util.url_encode(val.filename) + filename = encode_path(val.filename) y << "; filename=\"#{filename}\"" in Pathname | IO - filename = ERB::Util.url_encode(::File.basename(val.to_path)) + filename = encode_path(::File.basename(val.to_path)) y << "; filename=\"#{filename}\"" else end diff --git a/rbi/knockapi/internal/util.rbi b/rbi/knockapi/internal/util.rbi index 37d976cf..680cc9ab 100644 --- a/rbi/knockapi/internal/util.rbi +++ b/rbi/knockapi/internal/util.rbi @@ -148,12 +148,20 @@ module Knockapi end end + # https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3 + RFC_3986_NOT_PCHARS = T.let(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/, Regexp) + class << self # @api private sig { params(uri: URI::Generic).returns(String) } def uri_origin(uri) end + # @api private + sig { params(path: T.any(String, Integer)).returns(String) } + def encode_path(path) + end + # @api private sig { params(path: T.any(String, T::Array[String])).returns(String) } def interpolate_path(path) diff --git a/sig/knockapi/internal/util.rbs b/sig/knockapi/internal/util.rbs index f0ea6692..486b0dcb 100644 --- a/sig/knockapi/internal/util.rbs +++ b/sig/knockapi/internal/util.rbs @@ -45,8 +45,12 @@ module Knockapi -> top? } -> top? + RFC_3986_NOT_PCHARS: Regexp + def self?.uri_origin: (URI::Generic uri) -> String + def self?.encode_path: (String | Integer path) -> String + def self?.interpolate_path: (String | ::Array[String] path) -> String def self?.decode_query: (String? query) -> ::Hash[String, ::Array[String]] From 4ff46f6222b96590260445d0931a87113a51b246 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 1 Apr 2026 19:44:52 +0000 Subject: [PATCH 05/13] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index ac5431c0..4f3582bf 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 90 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-c4b73cfc78e9b583cae6abe7c1f73caf2b81d9d8c4338819707f7089443b9754.yml -openapi_spec_hash: 8ee18f8419b62f10276dff5d35ee5f27 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-f7658bcdf4b85c3c7b283f0dc216e7eb425d4ff258674fa79f6caa0eeb340b5e.yml +openapi_spec_hash: c80f2985521f9fc3cb931940915e6a99 config_hash: 32503026a45db991d0d102f25af40a77 From 9b272e8ced5eb194a57d79ba442fba9539a0c0ef Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:54:04 +0000 Subject: [PATCH 06/13] feat(api): added new unset preferences methods --- .stats.yml | 4 +- lib/knockapi.rb | 2 + lib/knockapi/models.rb | 4 ++ .../models/object_unset_preferences_params.rb | 32 ++++++++++++ .../models/user_unset_preferences_params.rb | 26 ++++++++++ lib/knockapi/resources/objects.rb | 24 +++++++++ lib/knockapi/resources/users.rb | 22 ++++++++ rbi/knockapi/models.rbi | 4 ++ .../object_unset_preferences_params.rbi | 51 +++++++++++++++++++ .../models/user_unset_preferences_params.rbi | 46 +++++++++++++++++ rbi/knockapi/resources/objects.rbi | 20 ++++++++ rbi/knockapi/resources/users.rbi | 17 +++++++ sig/knockapi/models.rbs | 4 ++ .../object_unset_preferences_params.rbs | 32 ++++++++++++ .../models/user_unset_preferences_params.rbs | 28 ++++++++++ sig/knockapi/resources/objects.rbs | 7 +++ sig/knockapi/resources/users.rbs | 6 +++ test/knockapi/resources/objects_test.rb | 8 +++ test/knockapi/resources/users_test.rb | 8 +++ 19 files changed, 343 insertions(+), 2 deletions(-) create mode 100644 lib/knockapi/models/object_unset_preferences_params.rb create mode 100644 lib/knockapi/models/user_unset_preferences_params.rb create mode 100644 rbi/knockapi/models/object_unset_preferences_params.rbi create mode 100644 rbi/knockapi/models/user_unset_preferences_params.rbi create mode 100644 sig/knockapi/models/object_unset_preferences_params.rbs create mode 100644 sig/knockapi/models/user_unset_preferences_params.rbs diff --git a/.stats.yml b/.stats.yml index 4f3582bf..b81442b0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 90 +configured_endpoints: 92 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-f7658bcdf4b85c3c7b283f0dc216e7eb425d4ff258674fa79f6caa0eeb340b5e.yml openapi_spec_hash: c80f2985521f9fc3cb931940915e6a99 -config_hash: 32503026a45db991d0d102f25af40a77 +config_hash: a3056fe062e62c7ca4d3931ccf3f6d06 diff --git a/lib/knockapi.rb b/lib/knockapi.rb index ea9e809e..83206a37 100644 --- a/lib/knockapi.rb +++ b/lib/knockapi.rb @@ -132,6 +132,7 @@ require_relative "knockapi/models/object_set_params" require_relative "knockapi/models/object_set_preferences_params" require_relative "knockapi/models/object_unset_channel_data_params" +require_relative "knockapi/models/object_unset_preferences_params" require_relative "knockapi/models/page_info" require_relative "knockapi/models/providers/ms_team_check_auth_params" require_relative "knockapi/models/providers/ms_team_check_auth_response" @@ -214,6 +215,7 @@ require_relative "knockapi/models/user_set_channel_data_params" require_relative "knockapi/models/user_set_preferences_params" require_relative "knockapi/models/user_unset_channel_data_params" +require_relative "knockapi/models/user_unset_preferences_params" require_relative "knockapi/models/user_update_params" require_relative "knockapi/models/workflow_cancel_params" require_relative "knockapi/models/workflow_trigger_params" diff --git a/lib/knockapi/models.rb b/lib/knockapi/models.rb index 25a828f0..bd434ea7 100644 --- a/lib/knockapi/models.rb +++ b/lib/knockapi/models.rb @@ -135,6 +135,8 @@ module Knockapi ObjectUnsetChannelDataParams = Knockapi::Models::ObjectUnsetChannelDataParams + ObjectUnsetPreferencesParams = Knockapi::Models::ObjectUnsetPreferencesParams + PageInfo = Knockapi::Models::PageInfo Providers = Knockapi::Models::Providers @@ -205,6 +207,8 @@ module Knockapi UserUnsetChannelDataParams = Knockapi::Models::UserUnsetChannelDataParams + UserUnsetPreferencesParams = Knockapi::Models::UserUnsetPreferencesParams + UserUpdateParams = Knockapi::Models::UserUpdateParams WorkflowCancelParams = Knockapi::Models::WorkflowCancelParams diff --git a/lib/knockapi/models/object_unset_preferences_params.rb b/lib/knockapi/models/object_unset_preferences_params.rb new file mode 100644 index 00000000..f07a330d --- /dev/null +++ b/lib/knockapi/models/object_unset_preferences_params.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Knockapi + module Models + # @see Knockapi::Resources::Objects#unset_preferences + class ObjectUnsetPreferencesParams < Knockapi::Internal::Type::BaseModel + extend Knockapi::Internal::Type::RequestParameters::Converter + include Knockapi::Internal::Type::RequestParameters + + # @!attribute collection + # + # @return [String] + required :collection, String + + # @!attribute object_id_ + # + # @return [String] + required :object_id_, String + + # @!attribute id + # + # @return [String] + required :id, String + + # @!method initialize(collection:, object_id_:, id:, request_options: {}) + # @param collection [String] + # @param object_id_ [String] + # @param id [String] + # @param request_options [Knockapi::RequestOptions, Hash{Symbol=>Object}] + end + end +end diff --git a/lib/knockapi/models/user_unset_preferences_params.rb b/lib/knockapi/models/user_unset_preferences_params.rb new file mode 100644 index 00000000..38ef7feb --- /dev/null +++ b/lib/knockapi/models/user_unset_preferences_params.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Knockapi + module Models + # @see Knockapi::Resources::Users#unset_preferences + class UserUnsetPreferencesParams < Knockapi::Internal::Type::BaseModel + extend Knockapi::Internal::Type::RequestParameters::Converter + include Knockapi::Internal::Type::RequestParameters + + # @!attribute user_id + # + # @return [String] + required :user_id, String + + # @!attribute id + # + # @return [String] + required :id, String + + # @!method initialize(user_id:, id:, request_options: {}) + # @param user_id [String] + # @param id [String] + # @param request_options [Knockapi::RequestOptions, Hash{Symbol=>Object}] + end + end +end diff --git a/lib/knockapi/resources/objects.rb b/lib/knockapi/resources/objects.rb index 49786d9b..b114ba53 100644 --- a/lib/knockapi/resources/objects.rb +++ b/lib/knockapi/resources/objects.rb @@ -503,6 +503,30 @@ def unset_channel_data(collection, object_id_, channel_id, params = {}) ) end + # Unsets the preference set for the object, removing it entirely. + # + # @overload unset_preferences(collection, object_id_, id, request_options: {}) + # + # @param collection [String] The collection this object belongs to. + # + # @param object_id_ [String] Unique identifier for the object. + # + # @param id [String] Unique identifier for the preference set. + # + # @param request_options [Knockapi::RequestOptions, Hash{Symbol=>Object}, nil] + # + # @return [nil] + # + # @see Knockapi::Models::ObjectUnsetPreferencesParams + def unset_preferences(collection, object_id_, id, params = {}) + @client.request( + method: :delete, + path: ["v1/objects/%1$s/%2$s/preferences/%3$s", collection, object_id_, id], + model: NilClass, + options: params[:request_options] + ) + end + # @api private # # @param client [Knockapi::Client] diff --git a/lib/knockapi/resources/users.rb b/lib/knockapi/resources/users.rb index b4df0367..18faf5cd 100644 --- a/lib/knockapi/resources/users.rb +++ b/lib/knockapi/resources/users.rb @@ -449,6 +449,28 @@ def unset_channel_data(user_id, channel_id, params = {}) ) end + # Unsets the preference set for the user, removing it entirely. + # + # @overload unset_preferences(user_id, id, request_options: {}) + # + # @param user_id [String] The unique identifier of the user. + # + # @param id [String] Unique identifier for the preference set. + # + # @param request_options [Knockapi::RequestOptions, Hash{Symbol=>Object}, nil] + # + # @return [nil] + # + # @see Knockapi::Models::UserUnsetPreferencesParams + def unset_preferences(user_id, id, params = {}) + @client.request( + method: :delete, + path: ["v1/users/%1$s/preferences/%2$s", user_id, id], + model: NilClass, + options: params[:request_options] + ) + end + # @api private # # @param client [Knockapi::Client] diff --git a/rbi/knockapi/models.rbi b/rbi/knockapi/models.rbi index c9ede6d0..d80aca8f 100644 --- a/rbi/knockapi/models.rbi +++ b/rbi/knockapi/models.rbi @@ -101,6 +101,8 @@ module Knockapi ObjectUnsetChannelDataParams = Knockapi::Models::ObjectUnsetChannelDataParams + ObjectUnsetPreferencesParams = Knockapi::Models::ObjectUnsetPreferencesParams + PageInfo = Knockapi::Models::PageInfo Providers = Knockapi::Models::Providers @@ -171,6 +173,8 @@ module Knockapi UserUnsetChannelDataParams = Knockapi::Models::UserUnsetChannelDataParams + UserUnsetPreferencesParams = Knockapi::Models::UserUnsetPreferencesParams + UserUpdateParams = Knockapi::Models::UserUpdateParams WorkflowCancelParams = Knockapi::Models::WorkflowCancelParams diff --git a/rbi/knockapi/models/object_unset_preferences_params.rbi b/rbi/knockapi/models/object_unset_preferences_params.rbi new file mode 100644 index 00000000..9badfc64 --- /dev/null +++ b/rbi/knockapi/models/object_unset_preferences_params.rbi @@ -0,0 +1,51 @@ +# typed: strong + +module Knockapi + module Models + class ObjectUnsetPreferencesParams < Knockapi::Internal::Type::BaseModel + extend Knockapi::Internal::Type::RequestParameters::Converter + include Knockapi::Internal::Type::RequestParameters + + OrHash = + T.type_alias do + T.any( + Knockapi::ObjectUnsetPreferencesParams, + Knockapi::Internal::AnyHash + ) + end + + sig { returns(String) } + attr_accessor :collection + + sig { returns(String) } + attr_accessor :object_id_ + + sig { returns(String) } + attr_accessor :id + + sig do + params( + collection: String, + object_id_: String, + id: String, + request_options: Knockapi::RequestOptions::OrHash + ).returns(T.attached_class) + end + def self.new(collection:, object_id_:, id:, request_options: {}) + end + + sig do + override.returns( + { + collection: String, + object_id_: String, + id: String, + request_options: Knockapi::RequestOptions + } + ) + end + def to_hash + end + end + end +end diff --git a/rbi/knockapi/models/user_unset_preferences_params.rbi b/rbi/knockapi/models/user_unset_preferences_params.rbi new file mode 100644 index 00000000..a7cda0bb --- /dev/null +++ b/rbi/knockapi/models/user_unset_preferences_params.rbi @@ -0,0 +1,46 @@ +# typed: strong + +module Knockapi + module Models + class UserUnsetPreferencesParams < Knockapi::Internal::Type::BaseModel + extend Knockapi::Internal::Type::RequestParameters::Converter + include Knockapi::Internal::Type::RequestParameters + + OrHash = + T.type_alias do + T.any( + Knockapi::UserUnsetPreferencesParams, + Knockapi::Internal::AnyHash + ) + end + + sig { returns(String) } + attr_accessor :user_id + + sig { returns(String) } + attr_accessor :id + + sig do + params( + user_id: String, + id: String, + request_options: Knockapi::RequestOptions::OrHash + ).returns(T.attached_class) + end + def self.new(user_id:, id:, request_options: {}) + end + + sig do + override.returns( + { + user_id: String, + id: String, + request_options: Knockapi::RequestOptions + } + ) + end + def to_hash + end + end + end +end diff --git a/rbi/knockapi/resources/objects.rbi b/rbi/knockapi/resources/objects.rbi index 97d049fc..97384573 100644 --- a/rbi/knockapi/resources/objects.rbi +++ b/rbi/knockapi/resources/objects.rbi @@ -532,6 +532,26 @@ module Knockapi ) end + # Unsets the preference set for the object, removing it entirely. + sig do + params( + collection: String, + object_id_: String, + id: String, + request_options: Knockapi::RequestOptions::OrHash + ).void + end + def unset_preferences( + # The collection this object belongs to. + collection, + # Unique identifier for the object. + object_id_, + # Unique identifier for the preference set. + id, + request_options: {} + ) + end + # @api private sig { params(client: Knockapi::Client).returns(T.attached_class) } def self.new(client:) diff --git a/rbi/knockapi/resources/users.rbi b/rbi/knockapi/resources/users.rbi index 6ed05eee..80f68df8 100644 --- a/rbi/knockapi/resources/users.rbi +++ b/rbi/knockapi/resources/users.rbi @@ -464,6 +464,23 @@ module Knockapi ) end + # Unsets the preference set for the user, removing it entirely. + sig do + params( + user_id: String, + id: String, + request_options: Knockapi::RequestOptions::OrHash + ).void + end + def unset_preferences( + # The unique identifier of the user. + user_id, + # Unique identifier for the preference set. + id, + request_options: {} + ) + end + # @api private sig { params(client: Knockapi::Client).returns(T.attached_class) } def self.new(client:) diff --git a/sig/knockapi/models.rbs b/sig/knockapi/models.rbs index 7fd3a3ac..725e951a 100644 --- a/sig/knockapi/models.rbs +++ b/sig/knockapi/models.rbs @@ -95,6 +95,8 @@ module Knockapi class ObjectUnsetChannelDataParams = Knockapi::Models::ObjectUnsetChannelDataParams + class ObjectUnsetPreferencesParams = Knockapi::Models::ObjectUnsetPreferencesParams + class PageInfo = Knockapi::Models::PageInfo module Providers = Knockapi::Models::Providers @@ -165,6 +167,8 @@ module Knockapi class UserUnsetChannelDataParams = Knockapi::Models::UserUnsetChannelDataParams + class UserUnsetPreferencesParams = Knockapi::Models::UserUnsetPreferencesParams + class UserUpdateParams = Knockapi::Models::UserUpdateParams class WorkflowCancelParams = Knockapi::Models::WorkflowCancelParams diff --git a/sig/knockapi/models/object_unset_preferences_params.rbs b/sig/knockapi/models/object_unset_preferences_params.rbs new file mode 100644 index 00000000..49d3676f --- /dev/null +++ b/sig/knockapi/models/object_unset_preferences_params.rbs @@ -0,0 +1,32 @@ +module Knockapi + module Models + type object_unset_preferences_params = + { collection: String, object_id_: String, id: String } + & Knockapi::Internal::Type::request_parameters + + class ObjectUnsetPreferencesParams < Knockapi::Internal::Type::BaseModel + extend Knockapi::Internal::Type::RequestParameters::Converter + include Knockapi::Internal::Type::RequestParameters + + attr_accessor collection: String + + attr_accessor object_id_: String + + attr_accessor id: String + + def initialize: ( + collection: String, + object_id_: String, + id: String, + ?request_options: Knockapi::request_opts + ) -> void + + def to_hash: -> { + collection: String, + object_id_: String, + id: String, + request_options: Knockapi::RequestOptions + } + end + end +end diff --git a/sig/knockapi/models/user_unset_preferences_params.rbs b/sig/knockapi/models/user_unset_preferences_params.rbs new file mode 100644 index 00000000..36f012de --- /dev/null +++ b/sig/knockapi/models/user_unset_preferences_params.rbs @@ -0,0 +1,28 @@ +module Knockapi + module Models + type user_unset_preferences_params = + { user_id: String, id: String } + & Knockapi::Internal::Type::request_parameters + + class UserUnsetPreferencesParams < Knockapi::Internal::Type::BaseModel + extend Knockapi::Internal::Type::RequestParameters::Converter + include Knockapi::Internal::Type::RequestParameters + + attr_accessor user_id: String + + attr_accessor id: String + + def initialize: ( + user_id: String, + id: String, + ?request_options: Knockapi::request_opts + ) -> void + + def to_hash: -> { + user_id: String, + id: String, + request_options: Knockapi::RequestOptions + } + end + end +end diff --git a/sig/knockapi/resources/objects.rbs b/sig/knockapi/resources/objects.rbs index 71d80f3e..7bd42627 100644 --- a/sig/knockapi/resources/objects.rbs +++ b/sig/knockapi/resources/objects.rbs @@ -142,6 +142,13 @@ module Knockapi ?request_options: Knockapi::request_opts ) -> nil + def unset_preferences: ( + String collection, + String object_id_, + String id, + ?request_options: Knockapi::request_opts + ) -> nil + def initialize: (client: Knockapi::Client) -> void end end diff --git a/sig/knockapi/resources/users.rbs b/sig/knockapi/resources/users.rbs index 39321e6d..1f316317 100644 --- a/sig/knockapi/resources/users.rbs +++ b/sig/knockapi/resources/users.rbs @@ -127,6 +127,12 @@ module Knockapi ?request_options: Knockapi::request_opts ) -> nil + def unset_preferences: ( + String user_id, + String id, + ?request_options: Knockapi::request_opts + ) -> nil + def initialize: (client: Knockapi::Client) -> void end end diff --git a/test/knockapi/resources/objects_test.rb b/test/knockapi/resources/objects_test.rb index d44ea708..da6524f5 100644 --- a/test/knockapi/resources/objects_test.rb +++ b/test/knockapi/resources/objects_test.rb @@ -286,4 +286,12 @@ def test_unset_channel_data response => nil end end + + def test_unset_preferences + response = @knock.objects.unset_preferences("collection", "object_id", "default") + + assert_pattern do + response => nil + end + end end diff --git a/test/knockapi/resources/users_test.rb b/test/knockapi/resources/users_test.rb index c4b25eeb..44bd2037 100644 --- a/test/knockapi/resources/users_test.rb +++ b/test/knockapi/resources/users_test.rb @@ -298,4 +298,12 @@ def test_unset_channel_data response => nil end end + + def test_unset_preferences + response = @knock.users.unset_preferences("user_id", "default") + + assert_pattern do + response => nil + end + end end From f710ae264c9e1acdcf36b41b93e49cd7a8ebaf12 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 6 Apr 2026 18:09:11 +0000 Subject: [PATCH 07/13] feat(api): api update --- .stats.yml | 4 ++-- .../models/users/guide_get_channel_response.rb | 10 +++++++++- .../models/users/guide_get_channel_response.rbi | 11 +++++++++++ .../models/users/guide_get_channel_response.rbs | 7 +++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index b81442b0..f2a12050 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 92 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-f7658bcdf4b85c3c7b283f0dc216e7eb425d4ff258674fa79f6caa0eeb340b5e.yml -openapi_spec_hash: c80f2985521f9fc3cb931940915e6a99 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-9424b756f0a9438c5869b404da1779095190ea58a215179b29bef2b8cb65b106.yml +openapi_spec_hash: 9adf51786e9a57c01a0c29710ff70f95 config_hash: a3056fe062e62c7ca4d3931ccf3f6d06 diff --git a/lib/knockapi/models/users/guide_get_channel_response.rb b/lib/knockapi/models/users/guide_get_channel_response.rb index c3006989..96c7eddf 100644 --- a/lib/knockapi/models/users/guide_get_channel_response.rb +++ b/lib/knockapi/models/users/guide_get_channel_response.rb @@ -88,6 +88,12 @@ class Entry < Knockapi::Internal::Type::BaseModel # @return [String, nil] optional :channel_id, String + # @!attribute dashboard_url + # URL to this guide in the Knock dashboard + # + # @return [String, nil] + optional :dashboard_url, String + # @!attribute inserted_at # # @return [Time, nil] @@ -121,7 +127,7 @@ class Entry < Knockapi::Internal::Type::BaseModel # @return [Time, nil] optional :updated_at, Time - # @!method initialize(id: nil, _typename: nil, activation_url_patterns: nil, activation_url_rules: nil, active: nil, bypass_global_group_limit: nil, channel_id: nil, inserted_at: nil, key: nil, semver: nil, steps: nil, type: nil, updated_at: nil) + # @!method initialize(id: nil, _typename: nil, activation_url_patterns: nil, activation_url_rules: nil, active: nil, bypass_global_group_limit: nil, channel_id: nil, dashboard_url: nil, inserted_at: nil, key: nil, semver: nil, steps: nil, type: nil, updated_at: nil) # Some parameter documentations has been truncated, see # {Knockapi::Models::Users::GuideGetChannelResponse::Entry} for more details. # @@ -139,6 +145,8 @@ class Entry < Knockapi::Internal::Type::BaseModel # # @param channel_id [String] # + # @param dashboard_url [String] URL to this guide in the Knock dashboard + # # @param inserted_at [Time] # # @param key [String] The key of the guide. diff --git a/rbi/knockapi/models/users/guide_get_channel_response.rbi b/rbi/knockapi/models/users/guide_get_channel_response.rbi index 4c546889..d30d11d2 100644 --- a/rbi/knockapi/models/users/guide_get_channel_response.rbi +++ b/rbi/knockapi/models/users/guide_get_channel_response.rbi @@ -184,6 +184,13 @@ module Knockapi sig { params(channel_id: String).void } attr_writer :channel_id + # URL to this guide in the Knock dashboard + sig { returns(T.nilable(String)) } + attr_reader :dashboard_url + + sig { params(dashboard_url: String).void } + attr_writer :dashboard_url + sig { returns(T.nilable(Time)) } attr_reader :inserted_at @@ -252,6 +259,7 @@ module Knockapi active: T::Boolean, bypass_global_group_limit: T::Boolean, channel_id: String, + dashboard_url: String, inserted_at: Time, key: String, semver: String, @@ -278,6 +286,8 @@ module Knockapi active: nil, bypass_global_group_limit: nil, channel_id: nil, + # URL to this guide in the Knock dashboard + dashboard_url: nil, inserted_at: nil, # The key of the guide. key: nil, @@ -305,6 +315,7 @@ module Knockapi active: T::Boolean, bypass_global_group_limit: T::Boolean, channel_id: String, + dashboard_url: String, inserted_at: Time, key: String, semver: String, diff --git a/sig/knockapi/models/users/guide_get_channel_response.rbs b/sig/knockapi/models/users/guide_get_channel_response.rbs index f2dbaae6..79ca3503 100644 --- a/sig/knockapi/models/users/guide_get_channel_response.rbs +++ b/sig/knockapi/models/users/guide_get_channel_response.rbs @@ -41,6 +41,7 @@ module Knockapi active: bool, bypass_global_group_limit: bool, channel_id: String, + dashboard_url: String, inserted_at: Time, key: String, semver: String, @@ -82,6 +83,10 @@ module Knockapi def channel_id=: (String) -> String + attr_reader dashboard_url: String? + + def dashboard_url=: (String) -> String + attr_reader inserted_at: Time? def inserted_at=: (Time) -> Time @@ -116,6 +121,7 @@ module Knockapi ?active: bool, ?bypass_global_group_limit: bool, ?channel_id: String, + ?dashboard_url: String, ?inserted_at: Time, ?key: String, ?semver: String, @@ -132,6 +138,7 @@ module Knockapi active: bool, bypass_global_group_limit: bool, channel_id: String, + dashboard_url: String, inserted_at: Time, key: String, semver: String, From 0715076b3cb219501a9bedd7a449f4cedef2babb Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 20:03:55 +0000 Subject: [PATCH 08/13] fix: multipart encoding for file arrays --- lib/knockapi/internal/util.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/knockapi/internal/util.rb b/lib/knockapi/internal/util.rb index 7c80600d..24ef15bf 100644 --- a/lib/knockapi/internal/util.rb +++ b/lib/knockapi/internal/util.rb @@ -610,6 +610,7 @@ def encode_query_params(query) # # @return [Array(String, Enumerable)] private def encode_multipart_streaming(body) + # rubocop:disable Style/CaseEquality # RFC 1521 Section 7.2.1 says we should have 70 char maximum for boundary length boundary = SecureRandom.urlsafe_base64(46) @@ -619,7 +620,7 @@ def encode_query_params(query) in Hash body.each do |key, val| case val - in Array if val.all? { primitive?(_1) } + in Array if val.all? { primitive?(_1) || Knockapi::Internal::Type::FileInput === _1 } val.each do |v| write_multipart_chunk(y, boundary: boundary, key: key, val: v, closing: closing) end @@ -635,6 +636,7 @@ def encode_query_params(query) fused_io = fused_enum(strio) { closing.each(&:call) } [boundary, fused_io] + # rubocop:enable Style/CaseEquality end # @api private From 35446791c2f0779b17348e4eb7be78db2f0f9970 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:09:47 +0000 Subject: [PATCH 09/13] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index f2a12050..30151525 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 92 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-9424b756f0a9438c5869b404da1779095190ea58a215179b29bef2b8cb65b106.yml -openapi_spec_hash: 9adf51786e9a57c01a0c29710ff70f95 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-3e8f3a4664d48b3d546339018b451a356f8e20c223a2d21e7c3824fad4cddc7b.yml +openapi_spec_hash: c2b6637451a63e39c1f1042c6a7cc7f7 config_hash: a3056fe062e62c7ca4d3931ccf3f6d06 From 52fa84de3f52f70ca5744cbd80ecdf2902a2133e Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 18:03:16 +0000 Subject: [PATCH 10/13] codegen metadata --- .stats.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 30151525..f2a12050 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 92 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-3e8f3a4664d48b3d546339018b451a356f8e20c223a2d21e7c3824fad4cddc7b.yml -openapi_spec_hash: c2b6637451a63e39c1f1042c6a7cc7f7 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-9424b756f0a9438c5869b404da1779095190ea58a215179b29bef2b8cb65b106.yml +openapi_spec_hash: 9adf51786e9a57c01a0c29710ff70f95 config_hash: a3056fe062e62c7ca4d3931ccf3f6d06 From e75ece07830058e3118eeedb63e713c64981d5b6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 16:28:35 +0000 Subject: [PATCH 11/13] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index f2a12050..71d9096a 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 92 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-9424b756f0a9438c5869b404da1779095190ea58a215179b29bef2b8cb65b106.yml -openapi_spec_hash: 9adf51786e9a57c01a0c29710ff70f95 +openapi_spec_hash: c2b6637451a63e39c1f1042c6a7cc7f7 config_hash: a3056fe062e62c7ca4d3931ccf3f6d06 From cf7ad986fdc61d37c36507d82cf792cf1ceab303 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:47:03 +0000 Subject: [PATCH 12/13] codegen metadata --- .stats.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stats.yml b/.stats.yml index 71d9096a..30151525 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 92 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-9424b756f0a9438c5869b404da1779095190ea58a215179b29bef2b8cb65b106.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/knock%2Fknock-3e8f3a4664d48b3d546339018b451a356f8e20c223a2d21e7c3824fad4cddc7b.yml openapi_spec_hash: c2b6637451a63e39c1f1042c6a7cc7f7 config_hash: a3056fe062e62c7ca4d3931ccf3f6d06 From 24a0093f3e63edd192071dc5f657340c929195de Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:47:22 +0000 Subject: [PATCH 13/13] release: 1.36.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 22 ++++++++++++++++++++++ Gemfile.lock | 2 +- README.md | 2 +- lib/knockapi/version.rb | 2 +- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 44959ac4..f29e96b8 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.35.0" + ".": "1.36.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 962cfa00..9bf65cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 1.36.0 (2026-04-10) + +Full Changelog: [v1.35.0...v1.36.0](https://github.com/knocklabs/knock-ruby/compare/v1.35.0...v1.36.0) + +### Features + +* **api:** added new unset preferences methods ([9b272e8](https://github.com/knocklabs/knock-ruby/commit/9b272e8ced5eb194a57d79ba442fba9539a0c0ef)) +* **api:** api update ([f710ae2](https://github.com/knocklabs/knock-ruby/commit/f710ae264c9e1acdcf36b41b93e49cd7a8ebaf12)) + + +### Bug Fixes + +* align path encoding with RFC 3986 section 3.3 ([3e2268d](https://github.com/knocklabs/knock-ruby/commit/3e2268d3e0547fa66ad253e35c86da963cc36215)) +* multipart encoding for file arrays ([0715076](https://github.com/knocklabs/knock-ruby/commit/0715076b3cb219501a9bedd7a449f4cedef2babb)) +* variable name typo ([cde1131](https://github.com/knocklabs/knock-ruby/commit/cde113151eb2879204409723971653616876fdee)) + + +### Chores + +* **tests:** bump steady to v0.20.1 ([6eb6756](https://github.com/knocklabs/knock-ruby/commit/6eb6756ef89a7b99a3825bd5ab899bf2f0b030e2)) +* **tests:** bump steady to v0.20.2 ([4206b20](https://github.com/knocklabs/knock-ruby/commit/4206b20a8cd60362598da173185bbd236e659eff)) + ## 1.35.0 (2026-03-27) Full Changelog: [v1.34.0...v1.35.0](https://github.com/knocklabs/knock-ruby/compare/v1.34.0...v1.35.0) diff --git a/Gemfile.lock b/Gemfile.lock index 160fe40a..07907897 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,7 +11,7 @@ GIT PATH remote: . specs: - knockapi (1.35.0) + knockapi (1.36.0) cgi connection_pool diff --git a/README.md b/README.md index 8eed89b1..fcc79b32 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ To use this gem, install via Bundler by adding the following to your application ```ruby -gem "knockapi", "~> 1.35.0" +gem "knockapi", "~> 1.36.0" ``` diff --git a/lib/knockapi/version.rb b/lib/knockapi/version.rb index 97ce31a3..5a13de61 100644 --- a/lib/knockapi/version.rb +++ b/lib/knockapi/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Knockapi - VERSION = "1.35.0" + VERSION = "1.36.0" end