diff --git a/examples/go/go-client/helper/rest/flex/v1/README.md b/examples/go/go-client/helper/rest/flex/v1/README.md index 0e3536d92..b4bb028c6 100644 --- a/examples/go/go-client/helper/rest/flex/v1/README.md +++ b/examples/go/go-client/helper/rest/flex/v1/README.md @@ -35,6 +35,7 @@ Class | Method | HTTP request | Description *CredentialsAWSApi* | [**DeleteCredentialAws**](docs/CredentialsAWSApi.md#deletecredentialaws) | **Delete** /v1/Credentials/AWS/{Sid} | *CredentialsAWSApi* | [**FetchCredentialAws**](docs/CredentialsAWSApi.md#fetchcredentialaws) | **Get** /v1/Credentials/AWS/{Sid} | *CredentialsAWSApi* | [**ListCredentialAws**](docs/CredentialsAWSApi.md#listcredentialaws) | **Get** /v1/Credentials/AWS | +*CredentialsAWSApi* | [**PatchCredentialAws**](docs/CredentialsAWSApi.md#patchcredentialaws) | **Patch** /v1/Credentials/AWS/{Sid} | *CredentialsAWSApi* | [**UpdateCredentialAws**](docs/CredentialsAWSApi.md#updatecredentialaws) | **Post** /v1/Credentials/AWS/{Sid} | *CredentialsAWSHistoryApi* | [**FetchCredentialHistory**](docs/CredentialsAWSHistoryApi.md#fetchcredentialhistory) | **Get** /v1/Credentials/AWS/{Sid}/History | *VoiceApi* | [**UpdateCall**](docs/VoiceApi.md#updatecall) | **Post** /v1/Voice/{Sid} | diff --git a/examples/go/go-client/helper/rest/flex/v1/credentials_aws.go b/examples/go/go-client/helper/rest/flex/v1/credentials_aws.go index 62cfd6df2..b4eaf3c93 100644 --- a/examples/go/go-client/helper/rest/flex/v1/credentials_aws.go +++ b/examples/go/go-client/helper/rest/flex/v1/credentials_aws.go @@ -417,6 +417,54 @@ func (c *ApiService) getNextListCredentialAwsResponse(nextPageUrl string) (inter return ps, nil } +// Optional parameters for the method 'PatchCredentialAws' +type PatchCredentialAwsParams struct { + // + TestString *string `json:"TestString,omitempty"` + // + TestBoolean *bool `json:"TestBoolean,omitempty"` +} + +func (params *PatchCredentialAwsParams) SetTestString(TestString string) *PatchCredentialAwsParams { + params.TestString = &TestString + return params +} +func (params *PatchCredentialAwsParams) SetTestBoolean(TestBoolean bool) *PatchCredentialAwsParams { + params.TestBoolean = &TestBoolean + return params +} + +func (c *ApiService) PatchCredentialAws(Sid string, params *PatchCredentialAwsParams) (*TestResponseObject, error) { + path := "/v1/Credentials/AWS/{Sid}" + path = strings.Replace(path, "{"+"Sid"+"}", Sid, -1) + + data := url.Values{} + headers := map[string]interface{}{ + "Content-Type": "application/x-www-form-urlencoded", + } + + if params != nil && params.TestString != nil { + data.Set("TestString", *params.TestString) + } + if params != nil && params.TestBoolean != nil { + data.Set("TestBoolean", fmt.Sprint(*params.TestBoolean)) + } + + resp, err := c.requestHandler.Patch(c.baseURL+path, data, headers) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + + ps := &TestResponseObject{} + if err := json.NewDecoder(resp.Body).Decode(ps); err != nil { + return nil, err + } + + return ps, err +} + // Optional parameters for the method 'UpdateCredentialAws' type UpdateCredentialAwsParams struct { // diff --git a/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/Aws.java b/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/Aws.java index 1fded4654..03252126b 100644 --- a/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/Aws.java +++ b/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/Aws.java @@ -86,6 +86,12 @@ public static AwsReader reader() { + + + + + + public static AwsUpdater updater(final String pathSid) { return new AwsUpdater( diff --git a/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/AwsPatcher.java b/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/AwsPatcher.java new file mode 100644 index 000000000..a4c62658c --- /dev/null +++ b/examples/java/src/main/java/com/twilio/rest/flexapi/v1/credential/AwsPatcher.java @@ -0,0 +1,103 @@ +/* + * This code was generated by + * ___ _ _ _ _ _ _ ____ ____ ____ _ ____ ____ _ _ ____ ____ ____ ___ __ __ + * | | | | | | | | | __ | | |__| | __ | __ |___ |\ | |___ |__/ |__| | | | |__/ + * | |_|_| | |___ | |__| |__| | | | |__] |___ | \| |___ | \ | | | |__| | \ + * + * Twilio - Accounts + * This is the public Twilio REST API. + * + * NOTE: This class is auto generated by OpenAPI Generator. + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +package com.twilio.rest.flexapi.v1.credential; + +import com.twilio.base.Patcher; +import com.twilio.constant.EnumConstants; +import com.twilio.constant.EnumConstants.ParameterType; +import com.twilio.converter.Serializer; +import com.twilio.exception.ApiConnectionException; +import com.twilio.exception.ApiException; +import com.twilio.exception.RestException; +import com.twilio.http.HttpMethod; +import com.twilio.http.Request; +import com.twilio.http.Response; +import com.twilio.http.TwilioRestClient; +import com.twilio.rest.Domains; + +import com.twilio.type.*; + + + public class AwsPatcher extends Patcher { + private String pathSid; + private String testString; + private Boolean testBoolean; + + public AwsPatcher(final String pathSid) { + this.pathSid = pathSid; + } + + +public AwsPatcher setTestString(final String testString){ + this.testString = testString; + return this; +} + + +public AwsPatcher setTestBoolean(final Boolean testBoolean){ + this.testBoolean = testBoolean; + return this; +} + + + @Override + public Aws patch(final TwilioRestClient client) { + + String path = "/v1/Credentials/AWS/{Sid}"; + + path = path.replace("{"+"Sid"+"}", this.pathSid.toString()); + + + Request request = new Request( + HttpMethod.PATCH, + Domains.FLEXAPI.toString(), + path + ); + request.setContentType(EnumConstants.ContentType.FORM_URLENCODED); + addPostParams(request); + + Response response = client.request(request); + + if (response == null) { + throw new ApiConnectionException("Aws patch failed: Unable to connect to server"); + } else if (!TwilioRestClient.SUCCESS.test(response.getStatusCode())) { + RestException restException = RestException.fromJson( + response.getStream(), + client.getObjectMapper() + ); + if (restException == null) { + throw new ApiException("Server Error, no content", response.getStatusCode()); + } + throw new ApiException(restException); + } + + return Aws.fromJson(response.getStream(), client.getObjectMapper()); + } + + private void addPostParams(final Request request) { + + if (testString != null) { + Serializer.toString(request, "TestString", testString, ParameterType.URLENCODED); + } + + + + if (testBoolean != null) { + Serializer.toString(request, "TestBoolean", testBoolean, ParameterType.URLENCODED); + } + + +} + } diff --git a/examples/node/src/rest/api/v2010/account/call/feedbackCallSummary.ts b/examples/node/src/rest/api/v2010/account/call/feedbackCallSummary.ts index 1dbc152ba..a7d8d85a6 100644 --- a/examples/node/src/rest/api/v2010/account/call/feedbackCallSummary.ts +++ b/examples/node/src/rest/api/v2010/account/call/feedbackCallSummary.ts @@ -70,9 +70,7 @@ export interface FeedbackCallSummaryContextSolution { sid: string; } -export class FeedbackCallSummaryContextImpl - implements FeedbackCallSummaryContext -{ +export class FeedbackCallSummaryContextImpl implements FeedbackCallSummaryContext { protected _solution: FeedbackCallSummaryContextSolution; protected _uri: string; diff --git a/examples/node/src/rest/flexApi/v1/credential/aws.ts b/examples/node/src/rest/flexApi/v1/credential/aws.ts index d74c9c601..bfead1c7a 100644 --- a/examples/node/src/rest/flexApi/v1/credential/aws.ts +++ b/examples/node/src/rest/flexApi/v1/credential/aws.ts @@ -21,6 +21,16 @@ const serialize = require("../../../../base/serialize"); import { isValidPathParam } from "../../../../base/utility"; import { HistoryListInstance } from "./aws/history"; +/** + * Options to pass to patch a AwsInstance + */ +export interface AwsContextPatchOptions { + /** */ + testString?: string; + /** */ + testBoolean?: boolean; +} + /** * Options to pass to update a AwsInstance */ @@ -91,6 +101,29 @@ export interface AwsContext { callback?: (error: Error | null, item?: AwsInstance) => any, ): Promise; + /** + * Patch a AwsInstance + * + * @param callback - Callback to handle processed record + * + * @returns Resolves to processed AwsInstance + */ + patch( + callback?: (error: Error | null, item?: AwsInstance) => any, + ): Promise; + /** + * Patch a AwsInstance + * + * @param params - Parameter for request + * @param callback - Callback to handle processed record + * + * @returns Resolves to processed AwsInstance + */ + patch( + params: AwsContextPatchOptions, + callback?: (error: Error | null, item?: AwsInstance) => any, + ): Promise; + /** * Update a AwsInstance * @@ -195,6 +228,51 @@ export class AwsContextImpl implements AwsContext { return operationPromise; } + patch( + params?: + | AwsContextPatchOptions + | ((error: Error | null, item?: AwsInstance) => any), + callback?: (error: Error | null, item?: AwsInstance) => any, + ): Promise { + if (params instanceof Function) { + callback = params; + params = {}; + } else { + params = params || {}; + } + + let data: any = {}; + + if (params["testString"] !== undefined) + data["TestString"] = params["testString"]; + if (params["testBoolean"] !== undefined) + data["TestBoolean"] = serialize.bool(params["testBoolean"]); + + const headers: any = {}; + headers["Content-Type"] = "application/x-www-form-urlencoded"; + headers["Accept"] = "application/json"; + + const instance = this; + let operationVersion = instance._version, + operationPromise = operationVersion.patch({ + uri: instance._uri, + method: "patch", + data, + headers, + }); + + operationPromise = operationPromise.then( + (payload) => + new AwsInstance(operationVersion, payload, instance._solution.sid), + ); + + operationPromise = instance._version.setPromiseCallback( + operationPromise, + callback, + ); + return operationPromise; + } + update( params?: | AwsContextUpdateOptions @@ -319,6 +397,36 @@ export class AwsInstance { return this._proxy.fetch(callback); } + /** + * Patch a AwsInstance + * + * @param callback - Callback to handle processed record + * + * @returns Resolves to processed AwsInstance + */ + patch( + callback?: (error: Error | null, item?: AwsInstance) => any, + ): Promise; + /** + * Patch a AwsInstance + * + * @param params - Parameter for request + * @param callback - Callback to handle processed record + * + * @returns Resolves to processed AwsInstance + */ + patch( + params: AwsContextPatchOptions, + callback?: (error: Error | null, item?: AwsInstance) => any, + ): Promise; + + patch( + params?: any, + callback?: (error: Error | null, item?: AwsInstance) => any, + ): Promise { + return this._proxy.patch(params, callback); + } + /** * Update a AwsInstance * diff --git a/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsContext.php b/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsContext.php index 4c3fe07b4..e50478eef 100644 --- a/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsContext.php +++ b/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsContext.php @@ -91,6 +91,36 @@ public function fetch(): AwsInstance } + /** + * Patch the AwsInstance + * + * @param array|Options $options Optional Arguments + * @return AwsInstance Patchd AwsInstance + * @throws TwilioException When an HTTP error occurs. + */ + public function patch(array $options = []): AwsInstance + { + + $options = new Values($options); + + $data = Values::of([ + 'TestString' => + $options['testString'], + 'TestBoolean' => + Serialize::booleanToString($options['testBoolean']), + ]); + + $headers = Values::of(['Content-Type' => 'application/x-www-form-urlencoded', 'Accept' => 'application/json' ]); + $payload = $this->version->patch('PATCH', $this->uri, [], $data, $headers); + + return new AwsInstance( + $this->version, + $payload, + $this->solution['sid'] + ); + } + + /** * Update the AwsInstance * diff --git a/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsInstance.php b/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsInstance.php index e137bab9e..9d5872457 100644 --- a/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsInstance.php +++ b/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsInstance.php @@ -99,6 +99,19 @@ public function fetch(): AwsInstance return $this->proxy()->fetch(); } + /** + * Patch the AwsInstance + * + * @param array|Options $options Optional Arguments + * @return AwsInstance Patchd AwsInstance + * @throws TwilioException When an HTTP error occurs. + */ + public function patch(array $options = []): AwsInstance + { + + return $this->proxy()->patch($options); + } + /** * Update the AwsInstance * diff --git a/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsOptions.php b/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsOptions.php index ce3b4f80d..7ec94a0ff 100644 --- a/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsOptions.php +++ b/examples/php/src/Twilio/Rest/FlexApi/V1/Credential/AwsOptions.php @@ -23,6 +23,24 @@ abstract class AwsOptions + /** + * @param string $testString + * @param bool $testBoolean + * @return PatchAwsOptions Options builder + */ + public static function patch( + + string $testString = Values::NONE, + bool $testBoolean = Values::BOOL_NONE + + ): PatchAwsOptions + { + return new PatchAwsOptions( + $testString, + $testBoolean + ); + } + /** * @param string $testString * @param bool $testBoolean @@ -46,6 +64,54 @@ public static function update( +class PatchAwsOptions extends Options + { + /** + * @param string $testString + * @param bool $testBoolean + */ + public function __construct( + + string $testString = Values::NONE, + bool $testBoolean = Values::BOOL_NONE + + ) { + $this->options['testString'] = $testString; + $this->options['testBoolean'] = $testBoolean; + } + + /** + * @param string $testString + * @return $this Fluent Builder + */ + public function setTestString(string $testString): self + { + $this->options['testString'] = $testString; + return $this; + } + + /** + * @param bool $testBoolean + * @return $this Fluent Builder + */ + public function setTestBoolean(bool $testBoolean): self + { + $this->options['testBoolean'] = $testBoolean; + return $this; + } + + /** + * Provide a friendly representation + * + * @return string Machine friendly representation + */ + public function __toString(): string + { + $options = \http_build_query(Values::of($this->options), '', ' '); + return '[Twilio.FlexApi.V1.PatchAwsOptions ' . $options . ']'; + } +} + class UpdateAwsOptions extends Options { /** diff --git a/examples/python/twilio/rest/flex_api/v1/credential/aws/__init__.py b/examples/python/twilio/rest/flex_api/v1/credential/aws/__init__.py index 8c6ee892d..262dfa085 100644 --- a/examples/python/twilio/rest/flex_api/v1/credential/aws/__init__.py +++ b/examples/python/twilio/rest/flex_api/v1/credential/aws/__init__.py @@ -100,6 +100,42 @@ async def fetch_async(self) -> "AwsInstance": """ return await self._proxy.fetch_async() + def patch( + self, + test_string: Union[str, object] = values.unset, + test_boolean: Union[bool, object] = values.unset, + ) -> "AwsInstance": + """ + Patch the AwsInstance + + :param test_string: + :param test_boolean: + + :returns: The patched AwsInstance + """ + return self._proxy.patch( + test_string=test_string, + test_boolean=test_boolean, + ) + + async def patch_async( + self, + test_string: Union[str, object] = values.unset, + test_boolean: Union[bool, object] = values.unset, + ) -> "AwsInstance": + """ + Asynchronous coroutine to patch the AwsInstance + + :param test_string: + :param test_boolean: + + :returns: The patched AwsInstance + """ + return await self._proxy.patch_async( + test_string=test_string, + test_boolean=test_boolean, + ) + def update( self, test_string: Union[str, object] = values.unset, @@ -239,6 +275,70 @@ async def fetch_async(self) -> AwsInstance: sid=self._solution["sid"], ) + def patch( + self, + test_string: Union[str, object] = values.unset, + test_boolean: Union[bool, object] = values.unset, + ) -> AwsInstance: + """ + Patch the AwsInstance + + :param test_string: + :param test_boolean: + + :returns: The patched AwsInstance + """ + + data = values.of( + { + "TestString": test_string, + "TestBoolean": serialize.boolean_to_string(test_boolean), + } + ) + headers = values.of({}) + + headers["Content-Type"] = "application/x-www-form-urlencoded" + + headers["Accept"] = "application/json" + + payload = self._version.patch( + method="PATCH", uri=self._uri, data=data, headers=headers + ) + + return AwsInstance(self._version, payload, sid=self._solution["sid"]) + + async def patch_async( + self, + test_string: Union[str, object] = values.unset, + test_boolean: Union[bool, object] = values.unset, + ) -> AwsInstance: + """ + Asynchronous coroutine to patch the AwsInstance + + :param test_string: + :param test_boolean: + + :returns: The patched AwsInstance + """ + + data = values.of( + { + "TestString": test_string, + "TestBoolean": serialize.boolean_to_string(test_boolean), + } + ) + headers = values.of({}) + + headers["Content-Type"] = "application/x-www-form-urlencoded" + + headers["Accept"] = "application/json" + + payload = await self._version.patch_async( + method="PATCH", uri=self._uri, data=data, headers=headers + ) + + return AwsInstance(self._version, payload, sid=self._solution["sid"]) + def update( self, test_string: Union[str, object] = values.unset, diff --git a/examples/ruby/lib/twilio-ruby/rest/flex_api/v1/credential/aws.rb b/examples/ruby/lib/twilio-ruby/rest/flex_api/v1/credential/aws.rb index b281daad5..475337eb1 100644 --- a/examples/ruby/lib/twilio-ruby/rest/flex_api/v1/credential/aws.rb +++ b/examples/ruby/lib/twilio-ruby/rest/flex_api/v1/credential/aws.rb @@ -161,6 +161,30 @@ def fetch ) end + ## + # Patch the AwsInstance + # @param [String] test_string + # @param [Boolean] test_boolean + # @return [AwsInstance] Patched AwsInstance + def patch( + test_string: :unset, + test_boolean: :unset + ) + data = Twilio::Values.of({ + 'TestString' => test_string, + 'TestBoolean' => test_boolean, + }) + + headers = Twilio::Values.of({ 'Content-Type' => 'application/x-www-form-urlencoded', }) + + payload = @version.patch('PATCH', @uri, data: data, headers: headers) + AwsInstance.new( + @version, + payload, + sid: @solution[:sid], + ) + end + ## # Update the AwsInstance # @param [String] test_string @@ -315,6 +339,21 @@ def fetch context.fetch end + ## + # Patch the AwsInstance + # @param [String] test_string + # @param [Boolean] test_boolean + # @return [AwsInstance] Patched AwsInstance + def patch( + test_string: :unset, + test_boolean: :unset + ) + context.patch( + test_string: test_string, + test_boolean: test_boolean, + ) + end + ## # Update the AwsInstance # @param [String] test_string diff --git a/examples/spec/twilio_flex_v1.yaml b/examples/spec/twilio_flex_v1.yaml index 0d182b27a..902bbaff6 100644 --- a/examples/spec/twilio_flex_v1.yaml +++ b/examples/spec/twilio_flex_v1.yaml @@ -282,6 +282,37 @@ paths: description: OK security: - accountSid_authToken: [ ] + patch: + operationId: PatchCredentialAws + parameters: + - in: path + name: Sid + required: true + schema: + maxLength: 34 + minLength: 34 + pattern: ^CR[0-9a-fA-F]{32}$ + type: string + requestBody: + content: + application/x-www-form-urlencoded: + schema: + properties: + TestString: + type: string + TestBoolean: + type: boolean + title: UpdateCredentialAwsRequest + type: object + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/test.response_object' + description: OK + security: + - accountSid_authToken: [ ] servers: - url: https://flex-api.twilio.com x-twilio: diff --git a/src/main/java/com/twilio/oai/api/ApiResourceBuilder.java b/src/main/java/com/twilio/oai/api/ApiResourceBuilder.java index 355268a87..218dff073 100644 --- a/src/main/java/com/twilio/oai/api/ApiResourceBuilder.java +++ b/src/main/java/com/twilio/oai/api/ApiResourceBuilder.java @@ -4,6 +4,7 @@ import com.twilio.oai.PathUtils; import com.twilio.oai.StringHelper; import com.twilio.oai.common.ApplicationConstants; +import com.twilio.oai.common.EnumConstants; import com.twilio.oai.common.Utility; import com.twilio.oai.resolver.Resolver; import com.twilio.oai.resource.Resource; @@ -223,6 +224,8 @@ protected Map mapOperation(CodegenOperation operation) { if (StringUtils.startsWithIgnoreCase(operation.operationId, "update")) { addOperationName(operation, Operation.UPDATE.getValue()); + } else if (StringUtils.startsWithIgnoreCase(operation.operationId, "patch")) { + addOperationName(operation, Operation.PATCH.getValue()); } else if (StringUtils.startsWithIgnoreCase(operation.operationId, "delete")) { addOperationName(operation, Operation.DELETE.getValue()); } else if (StringUtils.startsWithIgnoreCase(operation.operationId, "create")) { diff --git a/src/main/java/com/twilio/oai/api/FluentApiResourceBuilder.java b/src/main/java/com/twilio/oai/api/FluentApiResourceBuilder.java index d2b4efac0..650a06cf4 100644 --- a/src/main/java/com/twilio/oai/api/FluentApiResourceBuilder.java +++ b/src/main/java/com/twilio/oai/api/FluentApiResourceBuilder.java @@ -2,6 +2,7 @@ import com.twilio.oai.DirectoryStructureService; import com.twilio.oai.PathUtils; +import com.twilio.oai.common.EnumConstants; import com.twilio.oai.common.Utility; import com.twilio.oai.resolver.Resolver; import com.twilio.oai.template.IApiActionTemplate; @@ -15,6 +16,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; import org.openapitools.codegen.CodegenParameter; diff --git a/src/main/java/com/twilio/oai/api/PhpApiResourceBuilder.java b/src/main/java/com/twilio/oai/api/PhpApiResourceBuilder.java index aaf9411c4..cf5035fb2 100644 --- a/src/main/java/com/twilio/oai/api/PhpApiResourceBuilder.java +++ b/src/main/java/com/twilio/oai/api/PhpApiResourceBuilder.java @@ -243,6 +243,7 @@ public ApiResourceBuilder updateOperations(Resolver codegenPar return this; } + private void addOptionFileParams(ApiResourceBuilder apiResourceBuilder) { for (CodegenOperation operation : apiResourceBuilder.codegenOperationList) { if (operation.vendorExtensions.containsKey("x-ignore")) continue; diff --git a/src/main/java/com/twilio/oai/common/EnumConstants.java b/src/main/java/com/twilio/oai/common/EnumConstants.java index 606bc9be7..0bb662c2d 100644 --- a/src/main/java/com/twilio/oai/common/EnumConstants.java +++ b/src/main/java/com/twilio/oai/common/EnumConstants.java @@ -29,6 +29,7 @@ public enum Operation { CREATE("Create"), FETCH("Fetch"), UPDATE("Update"), + PATCH("Patch"), DELETE("Delete"), @@ -165,7 +166,8 @@ public enum SupportedOperation { X_LIST("x-list-operation"), X_UPDATE("x-update-operation"), X_FETCH("x-fetch-operation"), - X_DELETE("x-delete-operation"); + X_DELETE("x-delete-operation"), + X_PATCH("x-patch-operation"); private final String value; } diff --git a/src/main/java/com/twilio/oai/java/JavaTemplateUpdater.java b/src/main/java/com/twilio/oai/java/JavaTemplateUpdater.java index 97d618ca5..755dbee68 100644 --- a/src/main/java/com/twilio/oai/java/JavaTemplateUpdater.java +++ b/src/main/java/com/twilio/oai/java/JavaTemplateUpdater.java @@ -2,6 +2,7 @@ import com.twilio.oai.TwilioJavaGeneratorModern; import com.twilio.oai.common.EnumConstants; +import com.twilio.oai.common.EnumConstants.SupportedOperation; import com.twilio.oai.java.constants.MustacheConstants; import org.openapitools.codegen.CodegenOperation; @@ -12,9 +13,9 @@ import static com.twilio.oai.java.constants.MustacheConstants.ActionType; /* -The JavaTemplateFile class is responsible for managing template mappings for Java code generation. -It defines mappings between operation IDs (starting strings) -and corresponding template files (mustache files) along with their generated file extensions. +The JavaTemplateFile class is responsible for managing template mappings for Java code generation. +It defines mappings between operation IDs (starting strings) +and corresponding template files (mustache files) along with their generated file extensions. Example: Key: Represents the starting string of the operationId (e.g., "create", "fetch"). Value: Represents a mapping between the mustache template file and the generated file extension using AbstractMap.SimpleEntry. @@ -34,7 +35,8 @@ public JavaTemplateUpdater() { "fetch", new AbstractMap.SimpleEntry<>("fetcher.mustache", "Fetcher.java"), "delete", new AbstractMap.SimpleEntry<>("deleter.mustache", "Deleter.java"), "list", new AbstractMap.SimpleEntry<>("reader.mustache", "Reader.java"), - "update", new AbstractMap.SimpleEntry<>("updater.mustache", "Updater.java") + "update", new AbstractMap.SimpleEntry<>("updater.mustache", "Updater.java"), + "patch", new AbstractMap.SimpleEntry<>("patcher.mustache", "Patcher.java") ); apiTemplate = Map.of( API_TEMPLATE, new AbstractMap.SimpleEntry<>("api.mustache", ".java") @@ -61,6 +63,8 @@ public void addApiTemplate(TwilioJavaGeneratorModern twilioJavaGenerator, java.u Delete.add(twilioJavaGenerator, operation, apiOperationTemplate); } else if (Fetch.isFetch(operation)) { Fetch.add(twilioJavaGenerator, operation, apiOperationTemplate); + } else if (Patch.isPatch(operation)) { + Patch.add(twilioJavaGenerator, operation, apiOperationTemplate); } else { throw new RuntimeException("Unsupported operation type for operationId: " + operationId); } @@ -149,4 +153,19 @@ public static void add(TwilioJavaGeneratorModern twilioJavaGenerator, CodegenOpe public static boolean isFetch(CodegenOperation codegenOperation) { return codegenOperation.operationId.toLowerCase().startsWith("fetch"); } -} \ No newline at end of file +} + +class Patch { + public static void add(TwilioJavaGeneratorModern twilioJavaGenerator, CodegenOperation codegenOperation, Map apiOperationTemplate) { + codegenOperation.vendorExtensions.put(SupportedOperation.X_PATCH.getValue(), true); + String key = (String) apiOperationTemplate.get("patch").getKey(); + String value = (String) apiOperationTemplate.get("patch").getValue(); + twilioJavaGenerator.apiTemplateFiles().put(key, value); + + codegenOperation.vendorExtensions.put(MustacheConstants.ACTION_TYPE, ActionType.PATCHER.getValue()); + codegenOperation.vendorExtensions.put(MustacheConstants.ACTION_METHOD, ActionMethod.PATCH.getValue()); + } + public static boolean isPatch(CodegenOperation codegenOperation) { + return codegenOperation.operationId.toLowerCase().startsWith("patch"); + } +} diff --git a/src/main/java/com/twilio/oai/java/constants/MustacheConstants.java b/src/main/java/com/twilio/oai/java/constants/MustacheConstants.java index 6dce31699..945b418bd 100644 --- a/src/main/java/com/twilio/oai/java/constants/MustacheConstants.java +++ b/src/main/java/com/twilio/oai/java/constants/MustacheConstants.java @@ -34,7 +34,8 @@ public enum ActionType { READER("Reader"), UPDATER("Updater"), DELETER("Deleter"), - FETCHER("Fetcher"); + FETCHER("Fetcher"), + PATCHER("Patcher"); private final String value; } @@ -47,9 +48,10 @@ public enum ActionMethod { READ("read"), UPDATE("update"), DELETE("delete"), - FETCH("fetch"); + FETCH("fetch"), + PATCH("patch"); private final String value; } - + } diff --git a/src/main/java/com/twilio/oai/template/JavaApiActionTemplate.java b/src/main/java/com/twilio/oai/template/JavaApiActionTemplate.java index dfaab93ba..24d2b59d2 100644 --- a/src/main/java/com/twilio/oai/template/JavaApiActionTemplate.java +++ b/src/main/java/com/twilio/oai/template/JavaApiActionTemplate.java @@ -23,6 +23,8 @@ public Map> mapping() { Arrays.asList("reader.mustache", "Reader.java"), "update", Arrays.asList("updater.mustache", "Updater.java"), + "patch", + Arrays.asList("updater.mustache", "Updater.java"), API_TEMPLATE, Arrays.asList("api.mustache", ".java"), NESTED_MODELS, diff --git a/src/main/resources/twilio-java/common/imports.mustache b/src/main/resources/twilio-java/common/imports.mustache index 37161458a..4c797675c 100644 --- a/src/main/resources/twilio-java/common/imports.mustache +++ b/src/main/resources/twilio-java/common/imports.mustache @@ -11,6 +11,7 @@ import com.twilio.base.Deleter; import com.twilio.base.Fetcher; import com.twilio.base.Reader; import com.twilio.base.Updater; +import com.twilio.base.Patcher; import com.twilio.constant.EnumConstants; import com.twilio.constant.EnumConstants.ParameterType; import com.twilio.converter.Promoter; diff --git a/src/main/resources/twilio-java/patcher.mustache b/src/main/resources/twilio-java/patcher.mustache new file mode 100644 index 000000000..822f6179a --- /dev/null +++ b/src/main/resources/twilio-java/patcher.mustache @@ -0,0 +1,28 @@ +{{>licenseInfo}} +{{#resources}} +package com.twilio.rest.{{domainPackage}}.{{apiVersion}}{{namespaceSubPart}}; +{{>common/imports}} + +{{#operations}} +{{#vendorExtensions.x-patch-operation}} + public class {{resourceName}}Patcher extends Patcher<{{resourceName}}> { + {{>common/instanceVariables}} + {{>common/constructors}} + {{>patcher/setters}} + {{>patcher/operationMethod}} + {{#queryParams.0}} + {{>common/addQueryParams}} + {{/queryParams.0}} + {{#formParams.0}} + {{>common/addPostParams}} + {{/formParams.0}} + {{#headerParams.0}} + {{>common/addHeaderParams}} + {{/headerParams.0}} + {{#bodyParams.0}} + {{>common/addPostParamsJson}} + {{/bodyParams.0}} + } +{{/vendorExtensions.x-patch-operation}} +{{/operations}} +{{/resources}} diff --git a/src/main/resources/twilio-java/patcher/operationMethod.mustache b/src/main/resources/twilio-java/patcher/operationMethod.mustache new file mode 100644 index 000000000..4817dded3 --- /dev/null +++ b/src/main/resources/twilio-java/patcher/operationMethod.mustache @@ -0,0 +1,54 @@ +{{! +resourceName: Api Name as identified by Directory Structure service +x-common-action-method: used to define operation method and can have values: create, read, update, delete, fetch, patch + Example: https://github.com/twilio/twilio-java/blob/9c2ba4dbc185c5576e67fbeb82ec6f4899093e79/src/main/java/com/twilio/rest/api/v2010/account/MessageCreator.java#L309 + +httpMethod: http method associated in the current operation. +domainName: example api, video, chat, etc. These can be found in Domains.java in twilio-java +vendorExtensions.x-content-type: content type of the request, example: application/json, application/x-www-form-urlencoded +}} + @Override + public {{resourceName}} {{vendorExtensions.x-common-action-method}}(final TwilioRestClient client) { + {{>common/generateUri}} + + Request request = new Request( + HttpMethod.{{httpMethod}}, + Domains.{{#lambda.uppercase}}{{domainName}}{{/lambda.uppercase}}.toString(), + path + ); + {{#vendorExtensions.x-request-content-type}} + request.setContentType(EnumConstants.ContentType.{{vendorExtensions.x-request-content-type}}); + {{/vendorExtensions.x-request-content-type}} + {{#vendorExtensions.x-no-auth}} + request.setAuth(NoAuthStrategy.getInstance()); + {{/vendorExtensions.x-no-auth}} + {{#queryParams.0}} + addQueryParams(request); + {{/queryParams.0}} + {{#headerParams.0}} + addHeaderParams(request); + {{/headerParams.0}} + {{#formParams.0}} + addPostParams(request); + {{/formParams.0}} + {{#bodyParams.0}} + addPostParams(request, client); + {{/bodyParams.0}} + + Response response = client.request(request); + + if (response == null) { + throw new ApiConnectionException("{{resourceName}} patch failed: Unable to connect to server"); + } else if (!TwilioRestClient.SUCCESS.test(response.getStatusCode())) { + RestException restException = RestException.fromJson( + response.getStream(), + client.getObjectMapper() + ); + if (restException == null) { + throw new ApiException("Server Error, no content", response.getStatusCode()); + } + throw new ApiException(restException); + } + + return {{resourceName}}.fromJson(response.getStream(), client.getObjectMapper()); + } diff --git a/src/main/resources/twilio-java/patcher/setters.mustache b/src/main/resources/twilio-java/patcher/setters.mustache new file mode 100644 index 000000000..3fd5bd68a --- /dev/null +++ b/src/main/resources/twilio-java/patcher/setters.mustache @@ -0,0 +1,20 @@ +{{#vendorExtensions.x-setter-methods}} + +public {{resourceName}}Patcher set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(final {{{dataType}}} {{paramName}}){ + this.{{paramName}} = {{paramName}}; + return this; +} + +{{! Optional setter-- Ideally this shouldn't exists, keeping it for backward compatibility }} +{{#isArray}} +public {{resourceName}}Patcher set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(final {{{baseType}}} {{paramName}}){ + return set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(Promoter.listOfOne({{paramName}})); +} +{{/isArray}} +{{! Optional setter, vendorExtensions.x-promotion stores promotion method}} +{{#vendorExtensions.x-promotion}} +public {{resourceName}}Patcher set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}(final String {{paramName}}){ + return set{{#lambda.titlecase}}{{paramName}}{{/lambda.titlecase}}({{vendorExtensions.x-promotion}}); +} +{{/vendorExtensions.x-promotion}} +{{/vendorExtensions.x-setter-methods}} diff --git a/src/main/resources/twilio-python/context.handlebars b/src/main/resources/twilio-python/context.handlebars index 7481248ba..6bda03f62 100644 --- a/src/main/resources/twilio-python/context.handlebars +++ b/src/main/resources/twilio-python/context.handlebars @@ -95,7 +95,84 @@ class {{apiName}}Context(InstanceContext): payload{{#instancePathParams}}, {{paramName}}=self._solution['{{paramName}}']{{/instancePathParams}} ) - {{/vendorExtensions.x-twilio.ignoreOperation}}{{/vendorExtensions.x-is-update-operation}}{{#vendorExtensions.x-is-fetch-operation}}{{^vendorExtensions.x-twilio.ignoreOperation}} + {{/vendorExtensions.x-twilio.ignoreOperation}}{{/vendorExtensions.x-is-update-operation}}{{#vendorExtensions.x-is-patch-operation}}{{^vendorExtensions.x-twilio.ignoreOperation}} + def {{vendorExtensions.x-name-lower}}(self{{#allParams}}, {{paramName}}: {{#if required}}{{{dataType}}}{{else}}Union[{{{dataType}}}, object]=values.unset{{/if}}{{/allParams}}) -> {{instanceName}}: + """ + Patch the {{instanceName}} + {{#allParams}} + :param {{paramName}}: {{{description}}}{{/allParams}} + + :returns: The patched {{instanceName}} + """ + {{#bodyParam}}data = {{paramName}}.to_dict(){{/bodyParam}} + {{^bodyParam}}data = values.of({ {{#allParams}}{{#isFormParam}} + '{{{baseName}}}': {{#if vendorExtensions.x-serialize}}{{vendorExtensions.x-serialize}}({{paramName}}{{#if isArray}}, lambda e: e){{else}}){{/if}}{{else}}{{paramName}}{{/if}},{{/isFormParam}}{{/allParams}} + }){{/bodyParam}} + headers = values.of({}) + {{#allParams}}{{#isHeaderParam}} + {{^if required}} + if not ({{paramName}} is values.unset or (isinstance({{paramName}}, str) and not {{paramName}})):{{/if}} + headers['{{{baseName}}}'] = {{paramName}}{{/isHeaderParam}}{{/allParams}} + {{#consumes}} + headers["Content-Type"] = "{{{mediaType}}}" + {{/consumes}} + {{#vendorExtensions.successProduce}} + headers["Accept"] = "{{{mediaType}}}" + {{/vendorExtensions.successProduce}}{{#if queryParams}} + params = values.of({ {{#allParams}}{{#isQueryParam}}{{#if vendorExtensions.x-prefixed-collapsible-map}}{{else}} + '{{{baseName}}}': {{#if vendorExtensions.x-serialize}}{{vendorExtensions.x-serialize}}({{paramName}}{{#if isArray}}, lambda e: e){{else}}){{/if}}{{else}}{{paramName}}{{/if}},{{/if}}{{/isQueryParam}}{{/allParams}} + }) + + {{#allParams}}{{#isQueryParam}}{{#if vendorExtensions.x-prefixed-collapsible-map}}params.patch({{vendorExtensions.x-serialize}}({{paramName}}, '{{vendorExtensions.x-prefixed-collapsible-map}}')) + {{/if}}{{/isQueryParam}}{{/allParams}}{{/if}} + + payload = self._version.patch(method='{{vendorExtensions.x-http-method}}', uri=self._uri, data=data, headers=headers{{#if queryParams}}, params=params{{/if}}) + + return {{instanceName}}( + self._version, + payload{{#instancePathParams}}, + {{paramName}}=self._solution['{{paramName}}']{{/instancePathParams}} + ) + + async def {{vendorExtensions.x-name-lower}}_async(self{{#allParams}}, {{paramName}}: {{#if required}}{{{dataType}}}{{else}}Union[{{{dataType}}}, object]=values.unset{{/if}}{{/allParams}}) -> {{instanceName}}: + """ + Asynchronous coroutine to patch the {{instanceName}} + {{#allParams}} + :param {{paramName}}: {{{description}}}{{/allParams}} + + :returns: The patched {{instanceName}} + """ + {{#bodyParam}}data = {{paramName}}.to_dict(){{/bodyParam}} + {{^bodyParam}}data = values.of({ {{#allParams}}{{#isFormParam}} + '{{{baseName}}}': {{#if vendorExtensions.x-serialize}}{{vendorExtensions.x-serialize}}({{paramName}}{{#if isArray}}, lambda e: e){{else}}){{/if}}{{else}}{{paramName}}{{/if}},{{/isFormParam}}{{/allParams}} + }){{/bodyParam}} + headers = values.of({}) + {{#allParams}}{{#isHeaderParam}} + {{^if required}} + if not ({{paramName}} is values.unset or (isinstance({{paramName}}, str) and not {{paramName}})):{{/if}} + headers['{{{baseName}}}'] = {{paramName}} + {{/isHeaderParam}}{{/allParams}} + {{#consumes}} + headers["Content-Type"] = "{{{mediaType}}}" + {{/consumes}} + {{#vendorExtensions.successProduce}} + headers["Accept"] = "{{{mediaType}}}" + {{/vendorExtensions.successProduce}}{{#if queryParams}} + params = values.of({ {{#allParams}}{{#isQueryParam}}{{#if vendorExtensions.x-prefixed-collapsible-map}}{{else}} + '{{{baseName}}}': {{#if vendorExtensions.x-serialize}}{{vendorExtensions.x-serialize}}({{paramName}}{{#if isArray}}, lambda e: e){{else}}){{/if}}{{else}}{{paramName}}{{/if}},{{/if}}{{/isQueryParam}}{{/allParams}} + }) + + {{#allParams}}{{#isQueryParam}}{{#if vendorExtensions.x-prefixed-collapsible-map}}params.patch({{vendorExtensions.x-serialize}}({{paramName}}, '{{vendorExtensions.x-prefixed-collapsible-map}}')) + {{/if}}{{/isQueryParam}}{{/allParams}}{{/if}} + + payload = await self._version.patch_async(method='{{vendorExtensions.x-http-method}}', uri=self._uri, data=data, headers=headers{{#if queryParams}}, params=params{{/if}}) + + return {{instanceName}}( + self._version, + payload{{#instancePathParams}}, + {{paramName}}=self._solution['{{paramName}}']{{/instancePathParams}} + ) + {{/vendorExtensions.x-twilio.ignoreOperation}}{{/vendorExtensions.x-is-patch-operation}}{{#vendorExtensions.x-is-fetch-operation}}{{^vendorExtensions.x-twilio.ignoreOperation}} def {{vendorExtensions.x-name-lower}}(self{{#allParams}}, {{paramName}}: {{#if required}}{{{dataType}}}{{else}}Union[{{{dataType}}}, object]=values.unset{{/if}}{{/allParams}}) -> {{instanceName}}: """ Fetch the {{instanceName}} diff --git a/src/main/resources/twilio-python/instance.handlebars b/src/main/resources/twilio-python/instance.handlebars index 9a2060866..4f0cd2e30 100644 --- a/src/main/resources/twilio-python/instance.handlebars +++ b/src/main/resources/twilio-python/instance.handlebars @@ -49,7 +49,27 @@ class {{instanceName}}(InstanceResource): :returns: The updated {{instanceName}} """ return await self._proxy.update_async({{#allParams}}{{paramName}}={{paramName}}, {{/allParams}}) - {{/vendorExtensions.x-is-update-operation}}{{#vendorExtensions.x-is-fetch-operation}} + {{/vendorExtensions.x-is-update-operation}}{{#vendorExtensions.x-is-patch-operation}} + def {{vendorExtensions.x-name-lower}}(self{{#allParams}}, {{paramName}}: {{#if required}}{{{dataType}}}{{else}}Union[{{{dataType}}}, object]=values.unset{{/if}}{{/allParams}}) -> "{{instanceName}}": + """ + Patch the {{instanceName}} + {{#allParams}} + :param {{paramName}}: {{{description}}}{{/allParams}} + + :returns: The patched {{instanceName}} + """ + return self._proxy.patch({{#allParams}}{{paramName}}={{paramName}}, {{/allParams}}) + + async def {{vendorExtensions.x-name-lower}}_async(self{{#allParams}}, {{paramName}}: {{#if required}}{{{dataType}}}{{else}}Union[{{{dataType}}}, object]=values.unset{{/if}}{{/allParams}}) -> "{{instanceName}}": + """ + Asynchronous coroutine to patch the {{instanceName}} + {{#allParams}} + :param {{paramName}}: {{{description}}}{{/allParams}} + + :returns: The patched {{instanceName}} + """ + return await self._proxy.patch_async({{#allParams}}{{paramName}}={{paramName}}, {{/allParams}}) + {{/vendorExtensions.x-is-patch-operation}}{{#vendorExtensions.x-is-fetch-operation}} def {{vendorExtensions.x-name-lower}}(self{{#allParams}}, {{paramName}}: {{#if required}}{{{dataType}}}{{else}}Union[{{{dataType}}}, object]=values.unset{{/if}}{{/allParams}}) -> "{{instanceName}}": """ Fetch the {{instanceName}} diff --git a/src/main/resources/twilio-ruby/methods.mustache b/src/main/resources/twilio-ruby/methods.mustache index a74bd8799..214567ecf 100644 --- a/src/main/resources/twilio-ruby/methods.mustache +++ b/src/main/resources/twilio-ruby/methods.mustache @@ -13,7 +13,7 @@ # @param [{{dataType}}] {{paramName}} {{{description}}} {{/bodyParams}} {{^vendorExtensions.x-is-delete-operation}} - # @return [{{apiName}}Instance] {{#vendorExtensions.x-is-fetch-operation}}{{vendorExtensions.x-name}}ed{{/vendorExtensions.x-is-fetch-operation}}{{^vendorExtensions.x-is-fetch-operation}}{{vendorExtensions.x-name}}d{{/vendorExtensions.x-is-fetch-operation}} {{apiName}}Instance + # @return [{{apiName}}Instance] {{#vendorExtensions.x-is-fetch-operation}}{{vendorExtensions.x-name}}ed{{/vendorExtensions.x-is-fetch-operation}}{{^vendorExtensions.x-is-fetch-operation}}{{^vendorExtensions.x-is-patch-operation}}{{vendorExtensions.x-name}}d{{/vendorExtensions.x-is-patch-operation}}{{#vendorExtensions.x-is-patch-operation}}{{vendorExtensions.x-name}}ed{{/vendorExtensions.x-is-patch-operation}}{{/vendorExtensions.x-is-fetch-operation}} {{apiName}}Instance {{/vendorExtensions.x-is-delete-operation}} {{#vendorExtensions.x-is-delete-operation}} # @return [Boolean] True if delete succeeds, false otherwise