From 1808a5ca4db92380fa4d3d4b4abad2668ab3c3f9 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 15 Oct 2026 15:28:21 +0000 Subject: [PATCH 1/2] Sync OpenAPI specification 1.2.0 --- spec/openapi.yaml | 520 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 519 insertions(+), 1 deletion(-) diff --git a/spec/openapi.yaml b/spec/openapi.yaml index 0a4658d..3939b10 100644 --- a/spec/openapi.yaml +++ b/spec/openapi.yaml @@ -10,7 +10,7 @@ info: license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html - version: 1.1.0 + version: 1.2.0 servers: - url: https://api.timr.com/v1/ @@ -46,6 +46,11 @@ tags: - name: Project Time description: > Time booked on a Task. Where a Working Time records that a person was at work, a Project Time records what they worked on. + - name: Project Time Attachment + description: > + Files attached to a Project Time, such as before-and-after photos documenting the work. Only attachments whose + upload has completed are returned. Adding or deleting an attachment does not change the `last_modified` of the + Project Time, so changed attachments can't be found with the `last_modified_after` filter of the Project Times. - name: Task description: > The account's task tree that Project Times are booked on. Tasks are hierarchical, can be bookable and billable, carry budgets, and can constrain recording. Users gain access through assignments. @@ -58,6 +63,11 @@ tags: - name: Task to Team Assignment description: > Grants a whole Team access to a Task, instead of assigning each of its Users individually. + - name: Task Attachment + description: > + Files attached to a Task, such as instructions or photos. Only attachments whose upload has completed are returned. + Attachments are not inherited: only the attachments attached directly to the Task are returned. Attachments of a + parent Task are not part of the result and have to be fetched from the parent Task itself. - name: Drive Log description: > Logbook entries for trips in a Car: times, mileage, purpose, places visited, and the category separating business from private travel. @@ -1891,6 +1901,187 @@ paths: "400": $ref: '#/components/responses/BadRequest' + /project-times/{project_time_id}/attachments: + get: + operationId: fetchProjectTimeAttachments + tags: + - Project Time Attachment + summary: List Project Time Attachments + description: > + Lists the attachments of a running or completed Project Time whose upload has completed. + parameters: + - name: project_time_id + in: path + description: ID of the Project Time. + required: true + example: 074e7048-9097-11eb-a8b3-0242ac130003 + schema: + type: string + - name: page_token + in: query + description: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + required: false + schema: + type: string + - name: limit + in: query + description: Maximum number of entries per page. Values above 500 are capped at 500. + required: false + schema: + minimum: 1 + default: 20 + type: integer + format: int32 + - name: sort_direction + in: query + description: Direction to sort the entries in. + required: false + schema: + allOf: + - $ref: '#/components/schemas/SortDirection' + default: asc + - name: sort_by + in: query + description: Property to sort the entries by. + required: false + schema: + allOf: + - $ref: '#/components/schemas/AttachmentsSortColumn' + default: uploaded_at + responses: + "200": + description: Page of Project Time Attachments. + content: + application/json: + schema: + $ref: '#/components/schemas/AttachmentsPage' + headers: + Link: + schema: + type: string + format: uri + description: link to the next page including filter parameters and page token + links: + GetProjectTimeAttachmentsNextPage: + operationId: fetchProjectTimeAttachments + parameters: + page_token: '$response.body#/next_page_token' + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + + post: + operationId: createProjectTimeAttachment + tags: + - Project Time Attachment + summary: Upload a Project Time Attachment + description: > + Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to + upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, + before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. + Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file + and the number of attachments per Project Time are limited. + parameters: + - name: project_time_id + in: path + description: ID of the Project Time. + required: true + example: 074e7048-9097-11eb-a8b3-0242ac130003 + schema: + type: string + requestBody: + description: Metadata of the file to upload. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AttachmentMetadata' + responses: + "201": + description: The registered upload with the URL to upload the file to. + content: + application/json: + schema: + $ref: '#/components/schemas/AttachmentUploadResponse' + "400": + $ref: '#/components/responses/BadRequest' + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + + /project-times/{project_time_id}/attachments/{attachment_id}: + get: + operationId: getProjectTimeAttachment + tags: + - Project Time Attachment + summary: Get a Project Time Attachment + description: > + Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed + are found. + parameters: + - name: project_time_id + in: path + description: ID of the Project Time. + required: true + example: 074e7048-9097-11eb-a8b3-0242ac130003 + schema: + type: string + - name: attachment_id + in: path + description: ID of the Project Time Attachment. + required: true + example: 01972ff0-14a2-7814-926c-11d07a1dc20b + schema: + type: string + format: uuid + responses: + "200": + description: The requested Project Time Attachment. + content: + application/json: + schema: + $ref: '#/components/schemas/Attachment' + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + + delete: + operationId: deleteProjectTimeAttachment + tags: + - Project Time Attachment + summary: Delete a Project Time Attachment + description: > + Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed + are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + parameters: + - name: project_time_id + in: path + description: ID of the Project Time. + required: true + example: 074e7048-9097-11eb-a8b3-0242ac130003 + schema: + type: string + - name: attachment_id + in: path + description: ID of the Project Time Attachment. + required: true + example: 01972ff0-14a2-7814-926c-11d07a1dc20b + schema: + type: string + format: uuid + responses: + "204": + description: Deleted. No content is returned. + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + "422": + $ref: '#/components/responses/UnprocessableContent' + /tasks: get: operationId: fetchTasks @@ -2645,6 +2836,185 @@ paths: "409": $ref: '#/components/responses/Conflict' + /tasks/{task_id}/attachments: + get: + operationId: fetchTaskAttachments + tags: + - Task Attachment + summary: List Task Attachments + description: > + Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; + attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + parameters: + - name: task_id + in: path + description: ID of the Task. + required: true + example: 5c2a9f38-9d47-11eb-a8b3-0242ac130003 + schema: + type: string + - name: page_token + in: query + description: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + required: false + schema: + type: string + - name: limit + in: query + description: Maximum number of entries per page. Values above 500 are capped at 500. + required: false + schema: + minimum: 1 + default: 20 + type: integer + format: int32 + - name: sort_direction + in: query + description: Direction to sort the entries in. + required: false + schema: + allOf: + - $ref: '#/components/schemas/SortDirection' + default: asc + - name: sort_by + in: query + description: Property to sort the entries by. + required: false + schema: + allOf: + - $ref: '#/components/schemas/AttachmentsSortColumn' + default: uploaded_at + responses: + "200": + description: Page of Task Attachments. + content: + application/json: + schema: + $ref: '#/components/schemas/AttachmentsPage' + headers: + Link: + schema: + type: string + format: uri + description: link to the next page including filter parameters and page token + links: + GetTaskAttachmentsNextPage: + operationId: fetchTaskAttachments + parameters: + page_token: '$response.body#/next_page_token' + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + + post: + operationId: createTaskAttachment + tags: + - Task Attachment + summary: Upload a Task Attachment + description: > + Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file + with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. + The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not + completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + parameters: + - name: task_id + in: path + description: ID of the Task. + required: true + example: 5c2a9f38-9d47-11eb-a8b3-0242ac130003 + schema: + type: string + requestBody: + description: Metadata of the file to upload. + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/AttachmentMetadata' + responses: + "201": + description: The registered upload with the URL to upload the file to. + content: + application/json: + schema: + $ref: '#/components/schemas/AttachmentUploadResponse' + "400": + $ref: '#/components/responses/BadRequest' + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + + /tasks/{task_id}/attachments/{attachment_id}: + get: + operationId: getTaskAttachment + tags: + - Task Attachment + summary: Get a Task Attachment + description: > + Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached + directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + parameters: + - name: task_id + in: path + description: ID of the Task. + required: true + example: 5c2a9f38-9d47-11eb-a8b3-0242ac130003 + schema: + type: string + - name: attachment_id + in: path + description: ID of the Task Attachment. + required: true + example: 01972ff0-14a2-7814-926c-11d07a1dc20b + schema: + type: string + format: uuid + responses: + "200": + description: The requested Task Attachment. + content: + application/json: + schema: + $ref: '#/components/schemas/Attachment' + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + + delete: + operationId: deleteTaskAttachment + tags: + - Task Attachment + summary: Delete a Task Attachment + description: > + Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached + directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + parameters: + - name: task_id + in: path + description: ID of the Task. + required: true + example: 5c2a9f38-9d47-11eb-a8b3-0242ac130003 + schema: + type: string + - name: attachment_id + in: path + description: ID of the Task Attachment. + required: true + example: 01972ff0-14a2-7814-926c-11d07a1dc20b + schema: + type: string + format: uuid + responses: + "204": + description: Deleted. No content is returned. + "403": + $ref: '#/components/responses/Forbidden' + "404": + $ref: '#/components/responses/NotFound' + /drive-logs: get: operationId: fetchDriveLogs @@ -5989,6 +6359,154 @@ components: enum: - team_name + Attachment: + description: > + A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + type: object + properties: + id: + description: Unique identifier. Treat it as an opaque string. + type: string + format: uuid + example: 01972ff0-14a2-7814-926c-11d07a1dc20b + download: + description: > + Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, + as future versions may also return attachments whose upload has not completed yet. + nullable: true + allOf: + - $ref: '#/components/schemas/AttachmentDownload' + metadata: + $ref: '#/components/schemas/AttachmentMetadata' + uploaded_by: + description: The User who uploaded the file, or null if that User no longer exists. + nullable: true + allOf: + - $ref: '#/components/schemas/UserPartial' + uploaded_at: + description: > + When the upload of the file completed. + RFC 3339 date-time (ISO-8601) + allOf: + - $ref: '#/components/schemas/DateTime' + required: + - id + - download + - metadata + - uploaded_by + - uploaded_at + + AttachmentsPage: + allOf: + - $ref: '#/components/schemas/PagingInformation' + - type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Attachment' + required: + - data + + AttachmentsSortColumn: + description: Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + type: string + enum: + - uploaded_at + + AttachmentUploadResponse: + description: A registered upload of a file, with the pre-signed URL to upload the file to. + type: object + properties: + id: + description: Unique identifier of the attachment. Treat it as an opaque string. + type: string + format: uuid + example: 01972ff0-14a2-7814-926c-11d07a1dc20b + metadata: + $ref: '#/components/schemas/AttachmentMetadata' + upload: + $ref: '#/components/schemas/AttachmentUpload' + required: + - id + - metadata + - upload + + AttachmentUpload: + description: > + Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file + with a PUT request, sending exactly the given headers, before `expires_at`. + type: object + properties: + url: + type: string + example: https://s3.eu-central-1.amazonaws.com/timr-attachments/01972ff0-14a2-7814-926c-11d07a1dc20b?X-Amz-Signature=... + headers: + $ref: '#/components/schemas/AttachmentUploadHeaders' + expires_at: + description: > + When the URL stops being valid. + RFC 3339 date-time (ISO-8601) + allOf: + - $ref: '#/components/schemas/DateTime' + required: + - url + - headers + - expires_at + + AttachmentUploadHeaders: + description: > + Headers to send with the upload request, with exactly these values. Which headers are included can change, so + send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients + set automatically; adding them manually can break the request. + All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + type: object + additionalProperties: + type: string + example: + Content-Type: image/jpeg + Content-Disposition: attachment; filename="before_cleanup.jpeg"; filename*=UTF-8''before_cleanup.jpeg + + AttachmentDownload: + description: > + Pre-signed URL to download the file directly from the storage, without further authentication. The URL is + only valid for a limited time; request the attachment again to get a new URL. + type: object + properties: + url: + type: string + example: https://s3.eu-central-1.amazonaws.com/timr-attachments/01972ff0-14a2-7814-926c-11d07a1dc20b?X-Amz-Signature=... + required: + - url + + AttachmentMetadata: + description: Metadata of the attached file, as provided when it was uploaded. + type: object + properties: + file_name: + type: string + example: before_cleanup.jpeg + content_type: + description: Media type of the file. + type: string + example: image/jpeg + size: + description: Size of the file in bytes. + type: integer + format: int64 + example: 204800 + file_last_modified: + description: > + When the file was last modified on the device it was uploaded from. + RFC 3339 date-time (ISO-8601) + allOf: + - $ref: '#/components/schemas/DateTime' + required: + - file_name + - content_type + - size + - file_last_modified + ProjectTime: description: > One booking on a `task`, from `start` to `end`, optionally `billable`, with `break_times`, notes and From e79ad8f2b122a84f1f5a1e611aef63d4797fe2c4 Mon Sep 17 00:00:00 2001 From: Bernhard Danecker Date: Tue, 20 Oct 2026 14:08:50 +0200 Subject: [PATCH 2/2] Add attachment APIs to SDKs and document contract 1.2.0 Bump each SDK's minor version for the additive contract update. Co-Authored-By: Codex --- sdk/dotnet/Timr.Api/Client/ClientUtils.cs | 2 + .../Timr.Api/Client/HostConfiguration.cs | 12 + .../Endpoints/ProjectTimeAttachmentApi.cs | 2003 +++++++++++++++++ .../Timr.Api/Endpoints/TaskAttachmentApi.cs | 1947 ++++++++++++++++ sdk/dotnet/Timr.Api/Model/Attachment.cs | 268 +++ .../Timr.Api/Model/AttachmentDownload.cs | 169 ++ .../Timr.Api/Model/AttachmentMetadata.cs | 243 ++ sdk/dotnet/Timr.Api/Model/AttachmentUpload.cs | 220 ++ .../Model/AttachmentUploadResponse.cs | 213 ++ sdk/dotnet/Timr.Api/Model/AttachmentsPage.cs | 190 ++ .../Timr.Api/Model/AttachmentsSortColumn.cs | 168 ++ .../api/apis/ProjectTimeAttachmentApi.java | 441 ++++ .../com/timr/api/apis/TaskAttachmentApi.java | 437 ++++ .../java/com/timr/api/models/Attachment.java | 249 ++ .../timr/api/models/AttachmentDownload.java | 116 + .../timr/api/models/AttachmentMetadata.java | 213 ++ .../com/timr/api/models/AttachmentUpload.java | 188 ++ .../api/models/AttachmentUploadResponse.java | 183 ++ .../com/timr/api/models/AttachmentsPage.java | 160 ++ .../api/models/AttachmentsSortColumn.java | 58 + .../api/apis/ProjectTimeAttachmentApi.java | 327 +++ .../com/timr/api/apis/TaskAttachmentApi.java | 325 +++ .../java/com/timr/api/models/Attachment.java | 248 ++ .../timr/api/models/AttachmentDownload.java | 115 + .../timr/api/models/AttachmentMetadata.java | 212 ++ .../com/timr/api/models/AttachmentUpload.java | 187 ++ .../api/models/AttachmentUploadResponse.java | 182 ++ .../com/timr/api/models/AttachmentsPage.java | 159 ++ .../api/models/AttachmentsSortColumn.java | 57 + .../timr/api/apis/ProjectTimeAttachmentApi.kt | 393 ++++ .../com/timr/api/apis/TaskAttachmentApi.kt | 393 ++++ .../kotlin/com/timr/api/models/Attachment.kt | 68 + .../com/timr/api/models/AttachmentDownload.kt | 45 + .../com/timr/api/models/AttachmentMetadata.kt | 60 + .../com/timr/api/models/AttachmentUpload.kt | 55 + .../api/models/AttachmentUploadResponse.kt | 56 + .../com/timr/api/models/AttachmentsPage.kt | 51 + .../timr/api/models/AttachmentsSortColumn.kt | 66 + sdk/python/pyproject.toml | 2 +- sdk/python/timr_api/__init__.py | 20 +- sdk/python/timr_api/api/__init__.py | 2 + .../api/project_time_attachment_api.py | 1249 ++++++++++ .../timr_api/api/task_attachment_api.py | 1246 ++++++++++ sdk/python/timr_api/api_client.py | 2 +- sdk/python/timr_api/configuration.py | 4 +- sdk/python/timr_api/models/__init__.py | 7 + sdk/python/timr_api/models/attachment.py | 120 + .../timr_api/models/attachment_download.py | 88 + .../timr_api/models/attachment_metadata.py | 95 + .../timr_api/models/attachment_upload.py | 93 + .../models/attachment_upload_response.py | 101 + .../timr_api/models/attachments_page.py | 102 + .../models/attachments_sort_column.py | 36 + .../APIs/ProjectTimeAttachmentAPI.swift | 222 ++ .../TimrApi/APIs/TaskAttachmentAPI.swift | 222 ++ sdk/swift/TimrApi/Models/Attachment.swift | 56 + .../TimrApi/Models/AttachmentDownload.swift | 33 + .../TimrApi/Models/AttachmentMetadata.swift | 48 + .../TimrApi/Models/AttachmentUpload.swift | 43 + .../Models/AttachmentUploadResponse.swift | 45 + .../TimrApi/Models/AttachmentsPage.swift | 37 + .../Models/AttachmentsSortColumn.swift | 16 + sdk/typescript-fetch/package-lock.json | 4 +- sdk/typescript-fetch/package.json | 2 +- .../src/apis/ProjectTimeAttachmentApi.ts | 385 ++++ .../src/apis/TaskAttachmentApi.ts | 385 ++++ sdk/typescript-fetch/src/apis/index.ts | 2 + sdk/typescript-fetch/src/models/Attachment.ts | 116 + .../src/models/AttachmentDownload.ts | 64 + .../src/models/AttachmentMetadata.ts | 85 + .../src/models/AttachmentUpload.ts | 80 + .../src/models/AttachmentUploadResponse.ts | 92 + .../src/models/AttachmentsPage.ts | 78 + .../src/models/AttachmentsSortColumn.ts | 51 + sdk/typescript-fetch/src/models/index.ts | 7 + sdk/versions.properties | 14 +- site/guides/07-release-notes.md | 24 + 77 files changed, 15742 insertions(+), 15 deletions(-) create mode 100644 sdk/dotnet/Timr.Api/Endpoints/ProjectTimeAttachmentApi.cs create mode 100644 sdk/dotnet/Timr.Api/Endpoints/TaskAttachmentApi.cs create mode 100644 sdk/dotnet/Timr.Api/Model/Attachment.cs create mode 100644 sdk/dotnet/Timr.Api/Model/AttachmentDownload.cs create mode 100644 sdk/dotnet/Timr.Api/Model/AttachmentMetadata.cs create mode 100644 sdk/dotnet/Timr.Api/Model/AttachmentUpload.cs create mode 100644 sdk/dotnet/Timr.Api/Model/AttachmentUploadResponse.cs create mode 100644 sdk/dotnet/Timr.Api/Model/AttachmentsPage.cs create mode 100644 sdk/dotnet/Timr.Api/Model/AttachmentsSortColumn.cs create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/apis/TaskAttachmentApi.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/Attachment.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentDownload.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentMetadata.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUpload.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUploadResponse.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsPage.java create mode 100644 sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsSortColumn.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/apis/TaskAttachmentApi.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/Attachment.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentDownload.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentMetadata.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUpload.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUploadResponse.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsPage.java create mode 100644 sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsSortColumn.java create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/ProjectTimeAttachmentApi.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/TaskAttachmentApi.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/Attachment.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentDownload.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentMetadata.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUpload.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUploadResponse.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsPage.kt create mode 100644 sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsSortColumn.kt create mode 100644 sdk/python/timr_api/api/project_time_attachment_api.py create mode 100644 sdk/python/timr_api/api/task_attachment_api.py create mode 100644 sdk/python/timr_api/models/attachment.py create mode 100644 sdk/python/timr_api/models/attachment_download.py create mode 100644 sdk/python/timr_api/models/attachment_metadata.py create mode 100644 sdk/python/timr_api/models/attachment_upload.py create mode 100644 sdk/python/timr_api/models/attachment_upload_response.py create mode 100644 sdk/python/timr_api/models/attachments_page.py create mode 100644 sdk/python/timr_api/models/attachments_sort_column.py create mode 100644 sdk/swift/TimrApi/APIs/ProjectTimeAttachmentAPI.swift create mode 100644 sdk/swift/TimrApi/APIs/TaskAttachmentAPI.swift create mode 100644 sdk/swift/TimrApi/Models/Attachment.swift create mode 100644 sdk/swift/TimrApi/Models/AttachmentDownload.swift create mode 100644 sdk/swift/TimrApi/Models/AttachmentMetadata.swift create mode 100644 sdk/swift/TimrApi/Models/AttachmentUpload.swift create mode 100644 sdk/swift/TimrApi/Models/AttachmentUploadResponse.swift create mode 100644 sdk/swift/TimrApi/Models/AttachmentsPage.swift create mode 100644 sdk/swift/TimrApi/Models/AttachmentsSortColumn.swift create mode 100644 sdk/typescript-fetch/src/apis/ProjectTimeAttachmentApi.ts create mode 100644 sdk/typescript-fetch/src/apis/TaskAttachmentApi.ts create mode 100644 sdk/typescript-fetch/src/models/Attachment.ts create mode 100644 sdk/typescript-fetch/src/models/AttachmentDownload.ts create mode 100644 sdk/typescript-fetch/src/models/AttachmentMetadata.ts create mode 100644 sdk/typescript-fetch/src/models/AttachmentUpload.ts create mode 100644 sdk/typescript-fetch/src/models/AttachmentUploadResponse.ts create mode 100644 sdk/typescript-fetch/src/models/AttachmentsPage.ts create mode 100644 sdk/typescript-fetch/src/models/AttachmentsSortColumn.ts create mode 100644 site/guides/07-release-notes.md diff --git a/sdk/dotnet/Timr.Api/Client/ClientUtils.cs b/sdk/dotnet/Timr.Api/Client/ClientUtils.cs index 105a519..c266982 100644 --- a/sdk/dotnet/Timr.Api/Client/ClientUtils.cs +++ b/sdk/dotnet/Timr.Api/Client/ClientUtils.cs @@ -112,6 +112,8 @@ public static bool TryDeserialize(ref Utf8JsonReader reader, JsonSerializerOp return boolean ? "true" : "false"; + if (obj is AttachmentsSortColumn attachmentsSortColumn) + return AttachmentsSortColumnValueConverter.ToJsonValue(attachmentsSortColumn); if (obj is BreakTimeType breakTimeType) return BreakTimeTypeValueConverter.ToJsonValue(breakTimeType); if (obj is BudgetPlanningType budgetPlanningType) diff --git a/sdk/dotnet/Timr.Api/Client/HostConfiguration.cs b/sdk/dotnet/Timr.Api/Client/HostConfiguration.cs index d9227ac..23b8f05 100644 --- a/sdk/dotnet/Timr.Api/Client/HostConfiguration.cs +++ b/sdk/dotnet/Timr.Api/Client/HostConfiguration.cs @@ -47,6 +47,14 @@ internal HostConfiguration(IServiceCollection services) jsonOptions.Converters.Add(new DateOnlyJsonConverter()); jsonOptions.Converters.Add(new DateOnlyNullableJsonConverter()); jsonOptions.Converters.Add(new AccountsJsonConverter()); + jsonOptions.Converters.Add(new AttachmentJsonConverter()); + jsonOptions.Converters.Add(new AttachmentDownloadJsonConverter()); + jsonOptions.Converters.Add(new AttachmentMetadataJsonConverter()); + jsonOptions.Converters.Add(new AttachmentUploadJsonConverter()); + jsonOptions.Converters.Add(new AttachmentUploadResponseJsonConverter()); + jsonOptions.Converters.Add(new AttachmentsPageJsonConverter()); + jsonOptions.Converters.Add(new AttachmentsSortColumnJsonConverter()); + jsonOptions.Converters.Add(new AttachmentsSortColumnNullableJsonConverter()); jsonOptions.Converters.Add(new BreakTimeJsonConverter()); jsonOptions.Converters.Add(new BreakTimeAutomaticJsonConverter()); jsonOptions.Converters.Add(new BreakTimeBaseJsonConverter()); @@ -222,7 +230,9 @@ internal HostConfiguration(IServiceCollection services) _services.AddSingleton(); _services.AddSingleton(); _services.AddSingleton(); + _services.AddSingleton(); _services.AddSingleton(); + _services.AddSingleton(); _services.AddSingleton(); _services.AddSingleton(); _services.AddSingleton(); @@ -282,7 +292,9 @@ internal void Register() builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.IDriveLogCategoryApi", configureClient)); builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.IHolidayCalendarApi", configureClient)); builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.IProjectTimeApi", configureClient)); + builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.IProjectTimeAttachmentApi", configureClient)); builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.ITaskApi", configureClient)); + builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.ITaskAttachmentApi", configureClient)); builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.ITaskToLeaderAssignmentApi", configureClient)); builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.ITaskToTeamAssignmentApi", configureClient)); builders.Add(_services.AddHttpClient("Timr.Api.Endpoints.ITaskToUserAssignmentApi", configureClient)); diff --git a/sdk/dotnet/Timr.Api/Endpoints/ProjectTimeAttachmentApi.cs b/sdk/dotnet/Timr.Api/Endpoints/ProjectTimeAttachmentApi.cs new file mode 100644 index 0000000..204ce5d --- /dev/null +++ b/sdk/dotnet/Timr.Api/Endpoints/ProjectTimeAttachmentApi.cs @@ -0,0 +1,2003 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Net; +using System.IO; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text.Json; +using Timr.Api.Client; +using Timr.Api.Logging; +using Timr.Api.Model; +using System.Diagnostics.CodeAnalysis; + +namespace Timr.Api.Endpoints +{ + /// + /// Represents a collection of functions to interact with the API endpoints + /// This class is registered as transient. + /// + public interface IProjectTimeAttachmentApi : IApi + { + /// + /// The class containing the events + /// + ProjectTimeAttachmentApiEvents Events { get; } + + /// + /// Upload a Project Time Attachment + /// + /// + /// Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <> + Task CreateProjectTimeAttachmentAsync(string projectTimeId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Upload a Project Time Attachment + /// + /// + /// Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + /// + /// ID of the Project Time. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <?> + Task CreateProjectTimeAttachmentOrDefaultAsync(string projectTimeId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Delete a Project Time Attachment + /// + /// + /// Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <> + Task DeleteProjectTimeAttachmentAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Delete a Project Time Attachment + /// + /// + /// Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + /// + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <?> + Task DeleteProjectTimeAttachmentOrDefaultAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + + /// + /// List Project Time Attachments + /// + /// + /// Lists the attachments of a running or completed Project Time whose upload has completed. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <> + Task FetchProjectTimeAttachmentsAsync(string projectTimeId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default); + + /// + /// List Project Time Attachments + /// + /// + /// Lists the attachments of a running or completed Project Time whose upload has completed. + /// + /// ID of the Project Time. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <?> + Task FetchProjectTimeAttachmentsOrDefaultAsync(string projectTimeId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Get a Project Time Attachment + /// + /// + /// Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <> + Task GetProjectTimeAttachmentAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Get a Project Time Attachment + /// + /// + /// Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + /// + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <?> + Task GetProjectTimeAttachmentOrDefaultAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + } + + /// + /// The + /// + public interface ICreateProjectTimeAttachmentApiResponse : Timr.Api.Client.IApiResponse, ICreated, IBadRequest, IForbidden, INotFound + { + /// + /// Returns true if the response is 201 Created + /// + /// + bool IsCreated { get; } + + /// + /// Returns true if the response is 400 BadRequest + /// + /// + bool IsBadRequest { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// The + /// + public interface IDeleteProjectTimeAttachmentApiResponse : Timr.Api.Client.IApiResponse, IForbidden, INotFound, IUnprocessableContent + { + /// + /// Returns true if the response is 204 NoContent + /// + /// + bool IsNoContent { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + + /// + /// Returns true if the response is 422 UnprocessableContent + /// + /// + bool IsUnprocessableContent { get; } + } + + /// + /// The + /// + public interface IFetchProjectTimeAttachmentsApiResponse : Timr.Api.Client.IApiResponse, IOk, IForbidden, INotFound + { + /// + /// Returns true if the response is 200 Ok + /// + /// + bool IsOk { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// The + /// + public interface IGetProjectTimeAttachmentApiResponse : Timr.Api.Client.IApiResponse, IOk, IForbidden, INotFound + { + /// + /// Returns true if the response is 200 Ok + /// + /// + bool IsOk { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// Represents a collection of functions to interact with the API endpoints + /// + public class ProjectTimeAttachmentApiEvents + { + /// + /// The event raised after the server response + /// + public event EventHandler? OnCreateProjectTimeAttachment; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorCreateProjectTimeAttachment; + + internal void ExecuteOnCreateProjectTimeAttachment(ProjectTimeAttachmentApi.CreateProjectTimeAttachmentApiResponse apiResponse) + { + OnCreateProjectTimeAttachment?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorCreateProjectTimeAttachment(Exception exception) + { + OnErrorCreateProjectTimeAttachment?.Invoke(this, new ExceptionEventArgs(exception)); + } + + /// + /// The event raised after the server response + /// + public event EventHandler? OnDeleteProjectTimeAttachment; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorDeleteProjectTimeAttachment; + + internal void ExecuteOnDeleteProjectTimeAttachment(ProjectTimeAttachmentApi.DeleteProjectTimeAttachmentApiResponse apiResponse) + { + OnDeleteProjectTimeAttachment?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorDeleteProjectTimeAttachment(Exception exception) + { + OnErrorDeleteProjectTimeAttachment?.Invoke(this, new ExceptionEventArgs(exception)); + } + + /// + /// The event raised after the server response + /// + public event EventHandler? OnFetchProjectTimeAttachments; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorFetchProjectTimeAttachments; + + internal void ExecuteOnFetchProjectTimeAttachments(ProjectTimeAttachmentApi.FetchProjectTimeAttachmentsApiResponse apiResponse) + { + OnFetchProjectTimeAttachments?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorFetchProjectTimeAttachments(Exception exception) + { + OnErrorFetchProjectTimeAttachments?.Invoke(this, new ExceptionEventArgs(exception)); + } + + /// + /// The event raised after the server response + /// + public event EventHandler? OnGetProjectTimeAttachment; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorGetProjectTimeAttachment; + + internal void ExecuteOnGetProjectTimeAttachment(ProjectTimeAttachmentApi.GetProjectTimeAttachmentApiResponse apiResponse) + { + OnGetProjectTimeAttachment?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorGetProjectTimeAttachment(Exception exception) + { + OnErrorGetProjectTimeAttachment?.Invoke(this, new ExceptionEventArgs(exception)); + } + } + + /// + /// Represents a collection of functions to interact with the API endpoints + /// + public sealed partial class ProjectTimeAttachmentApi : IProjectTimeAttachmentApi + { + private JsonSerializerOptions _jsonSerializerOptions; + + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The HttpClient + /// + public HttpClient HttpClient { get; } + + /// + /// The class containing the events + /// + public ProjectTimeAttachmentApiEvents Events { get; } + + /// + /// A token provider of type + /// + public TokenProvider OauthTokenProvider { get; } + + /// + /// Initializes a new instance of the class. + /// + /// + public ProjectTimeAttachmentApi(ILogger logger, HttpClient httpClient, JsonSerializerOptionsProvider jsonSerializerOptionsProvider, ProjectTimeAttachmentApiEvents projectTimeAttachmentApiEvents, + TokenProvider oauthTokenProvider) + { + _jsonSerializerOptions = jsonSerializerOptionsProvider.Options; + Logger = logger; + HttpClient = httpClient; + Events = projectTimeAttachmentApiEvents; + OauthTokenProvider = oauthTokenProvider; + } + + partial void FormatCreateProjectTimeAttachment(ref string projectTimeId, AttachmentMetadata attachmentMetadata); + + /// + /// Validates the request parameters + /// + /// + /// + /// + private void ValidateCreateProjectTimeAttachment(string projectTimeId, AttachmentMetadata attachmentMetadata) + { + if (projectTimeId == null) + throw new ArgumentNullException(nameof(projectTimeId)); + + if (attachmentMetadata == null) + throw new ArgumentNullException(nameof(attachmentMetadata)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + private void AfterCreateProjectTimeAttachmentDefaultImplementation(ICreateProjectTimeAttachmentApiResponse apiResponseLocalVar, string projectTimeId, AttachmentMetadata attachmentMetadata) + { + bool suppressDefaultLog = false; + AfterCreateProjectTimeAttachment(ref suppressDefaultLog, apiResponseLocalVar, projectTimeId, attachmentMetadata); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + partial void AfterCreateProjectTimeAttachment(ref bool suppressDefaultLog, ICreateProjectTimeAttachmentApiResponse apiResponseLocalVar, string projectTimeId, AttachmentMetadata attachmentMetadata); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + private void OnErrorCreateProjectTimeAttachmentDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, AttachmentMetadata attachmentMetadata) + { + bool suppressDefaultLogLocalVar = false; + OnErrorCreateProjectTimeAttachment(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, projectTimeId, attachmentMetadata); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorCreateProjectTimeAttachment(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, AttachmentMetadata attachmentMetadata); + + /// + /// Upload a Project Time Attachment Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + /// + /// ID of the Project Time. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <> + public async Task CreateProjectTimeAttachmentOrDefaultAsync(string projectTimeId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await CreateProjectTimeAttachmentAsync(projectTimeId, attachmentMetadata, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Upload a Project Time Attachment Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <> + public async Task CreateProjectTimeAttachmentAsync(string projectTimeId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateCreateProjectTimeAttachment(projectTimeId, attachmentMetadata); + + FormatCreateProjectTimeAttachment(ref projectTimeId, attachmentMetadata); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/project-times/{project_time_id}/attachments" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/project-times/{project_time_id}/attachments"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Bproject_time_id%7D", Uri.EscapeDataString(projectTimeId.ToString())); + + httpRequestMessageLocalVar.Content = (attachmentMetadata as object) is Timr.Api.Client.FileParameter fileParameterLocalVar + ? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content) + : httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(attachmentMetadata, _jsonSerializerOptions)); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] contentTypes = new string[] { + "application/json" + }; + + string? contentTypeLocalVar = ClientUtils.SelectHeaderContentType(contentTypes); + + if (contentTypeLocalVar != null && httpRequestMessageLocalVar.Content != null) + httpRequestMessageLocalVar.Content.Headers.ContentType = new MediaTypeHeaderValue(contentTypeLocalVar); + + string[] acceptLocalVars = new string[] { + "application/json", + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Post; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + CreateProjectTimeAttachmentApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/project-times/{project_time_id}/attachments", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterCreateProjectTimeAttachmentDefaultImplementation(apiResponseLocalVar, projectTimeId, attachmentMetadata); + + Events.ExecuteOnCreateProjectTimeAttachment(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorCreateProjectTimeAttachmentDefaultImplementation(e, "/project-times/{project_time_id}/attachments", uriBuilderLocalVar.Path, projectTimeId, attachmentMetadata); + Events.ExecuteOnErrorCreateProjectTimeAttachment(e); + throw; + } + } + + /// + /// The + /// + public partial class CreateProjectTimeAttachmentApiResponse : Timr.Api.Client.ApiResponse, ICreateProjectTimeAttachmentApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public CreateProjectTimeAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public CreateProjectTimeAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 201 Created + /// + /// + public bool IsCreated => 201 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 201 Created + /// + /// + public Timr.Api.Model.AttachmentUploadResponse? Created() + { + bool suppressDefault = false; + Timr.Api.Model.AttachmentUploadResponse? result = null; + OnCreated(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultCreated(); + return result; + } + + private Timr.Api.Model.AttachmentUploadResponse? DefaultCreated() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsCreated + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnCreated(ref bool suppressDefault, ref Timr.Api.Model.AttachmentUploadResponse? result); + + /// + /// Returns true if the response is 201 Created and the deserialized response is not null + /// + /// + /// + public bool TryCreated([NotNullWhen(true)]out Timr.Api.Model.AttachmentUploadResponse? result) + { + result = null; + + try + { + result = Created(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)201); + } + + return result != null; + } + + /// + /// Returns true if the response is 400 BadRequest + /// + /// + public bool IsBadRequest => 400 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 400 BadRequest + /// + /// + public Timr.Api.Model.Error? BadRequest() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnBadRequest(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultBadRequest(); + return result; + } + + private Timr.Api.Model.Error? DefaultBadRequest() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsBadRequest + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnBadRequest(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 400 BadRequest and the deserialized response is not null + /// + /// + /// + public bool TryBadRequest([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = BadRequest(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)400); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + + partial void FormatDeleteProjectTimeAttachment(ref string projectTimeId, ref Guid attachmentId); + + /// + /// Validates the request parameters + /// + /// + /// + private void ValidateDeleteProjectTimeAttachment(string projectTimeId) + { + if (projectTimeId == null) + throw new ArgumentNullException(nameof(projectTimeId)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + private void AfterDeleteProjectTimeAttachmentDefaultImplementation(IDeleteProjectTimeAttachmentApiResponse apiResponseLocalVar, string projectTimeId, Guid attachmentId) + { + bool suppressDefaultLog = false; + AfterDeleteProjectTimeAttachment(ref suppressDefaultLog, apiResponseLocalVar, projectTimeId, attachmentId); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + partial void AfterDeleteProjectTimeAttachment(ref bool suppressDefaultLog, IDeleteProjectTimeAttachmentApiResponse apiResponseLocalVar, string projectTimeId, Guid attachmentId); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + private void OnErrorDeleteProjectTimeAttachmentDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, Guid attachmentId) + { + bool suppressDefaultLogLocalVar = false; + OnErrorDeleteProjectTimeAttachment(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, projectTimeId, attachmentId); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorDeleteProjectTimeAttachment(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, Guid attachmentId); + + /// + /// Delete a Project Time Attachment Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + /// + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task DeleteProjectTimeAttachmentOrDefaultAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await DeleteProjectTimeAttachmentAsync(projectTimeId, attachmentId, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Delete a Project Time Attachment Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task DeleteProjectTimeAttachmentAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateDeleteProjectTimeAttachment(projectTimeId); + + FormatDeleteProjectTimeAttachment(ref projectTimeId, ref attachmentId); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/project-times/{project_time_id}/attachments/{attachment_id}" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/project-times/{project_time_id}/attachments/{attachment_id}"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Bproject_time_id%7D", Uri.EscapeDataString(projectTimeId.ToString())); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Battachment_id%7D", Uri.EscapeDataString(attachmentId.ToString())); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] acceptLocalVars = new string[] { + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Delete; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + DeleteProjectTimeAttachmentApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/project-times/{project_time_id}/attachments/{attachment_id}", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterDeleteProjectTimeAttachmentDefaultImplementation(apiResponseLocalVar, projectTimeId, attachmentId); + + Events.ExecuteOnDeleteProjectTimeAttachment(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorDeleteProjectTimeAttachmentDefaultImplementation(e, "/project-times/{project_time_id}/attachments/{attachment_id}", uriBuilderLocalVar.Path, projectTimeId, attachmentId); + Events.ExecuteOnErrorDeleteProjectTimeAttachment(e); + throw; + } + } + + /// + /// The + /// + public partial class DeleteProjectTimeAttachmentApiResponse : Timr.Api.Client.ApiResponse, IDeleteProjectTimeAttachmentApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public DeleteProjectTimeAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public DeleteProjectTimeAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 204 NoContent + /// + /// + public bool IsNoContent => 204 == (int)StatusCode; + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + /// + /// Returns true if the response is 422 UnprocessableContent + /// + /// + public bool IsUnprocessableContent => 422 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 422 UnprocessableContent + /// + /// + public Timr.Api.Model.Error? UnprocessableContent() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnUnprocessableContent(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultUnprocessableContent(); + return result; + } + + private Timr.Api.Model.Error? DefaultUnprocessableContent() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsUnprocessableContent + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnUnprocessableContent(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 422 UnprocessableContent and the deserialized response is not null + /// + /// + /// + public bool TryUnprocessableContent([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = UnprocessableContent(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)422); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + + partial void FormatFetchProjectTimeAttachments(ref string projectTimeId, ref Option pageToken, ref Option limit, ref Option sortDirection, ref Option sortBy); + + /// + /// Validates the request parameters + /// + /// + /// + /// + private void ValidateFetchProjectTimeAttachments(string projectTimeId, Option pageToken) + { + if (projectTimeId == null) + throw new ArgumentNullException(nameof(projectTimeId)); + + if (pageToken.IsSet && pageToken.Value == null) + throw new ArgumentNullException(nameof(pageToken)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + /// + /// + private void AfterFetchProjectTimeAttachmentsDefaultImplementation(IFetchProjectTimeAttachmentsApiResponse apiResponseLocalVar, string projectTimeId, Option pageToken, Option limit, Option sortDirection, Option sortBy) + { + bool suppressDefaultLog = false; + AfterFetchProjectTimeAttachments(ref suppressDefaultLog, apiResponseLocalVar, projectTimeId, pageToken, limit, sortDirection, sortBy); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + /// + /// + /// + partial void AfterFetchProjectTimeAttachments(ref bool suppressDefaultLog, IFetchProjectTimeAttachmentsApiResponse apiResponseLocalVar, string projectTimeId, Option pageToken, Option limit, Option sortDirection, Option sortBy); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + /// + /// + /// + private void OnErrorFetchProjectTimeAttachmentsDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, Option pageToken, Option limit, Option sortDirection, Option sortBy) + { + bool suppressDefaultLogLocalVar = false; + OnErrorFetchProjectTimeAttachments(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, projectTimeId, pageToken, limit, sortDirection, sortBy); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorFetchProjectTimeAttachments(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, Option pageToken, Option limit, Option sortDirection, Option sortBy); + + /// + /// List Project Time Attachments Lists the attachments of a running or completed Project Time whose upload has completed. + /// + /// ID of the Project Time. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <> + public async Task FetchProjectTimeAttachmentsOrDefaultAsync(string projectTimeId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await FetchProjectTimeAttachmentsAsync(projectTimeId, pageToken, limit, sortDirection, sortBy, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// List Project Time Attachments Lists the attachments of a running or completed Project Time whose upload has completed. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <> + public async Task FetchProjectTimeAttachmentsAsync(string projectTimeId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateFetchProjectTimeAttachments(projectTimeId, pageToken); + + FormatFetchProjectTimeAttachments(ref projectTimeId, ref pageToken, ref limit, ref sortDirection, ref sortBy); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/project-times/{project_time_id}/attachments" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/project-times/{project_time_id}/attachments"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Bproject_time_id%7D", Uri.EscapeDataString(projectTimeId.ToString())); + + System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty); + + if (pageToken.IsSet) + parseQueryStringLocalVar["page_token"] = ClientUtils.ParameterToString(pageToken.Value); + + if (limit.IsSet) + parseQueryStringLocalVar["limit"] = ClientUtils.ParameterToString(limit.Value); + + if (sortDirection.IsSet) + parseQueryStringLocalVar["sort_direction"] = ClientUtils.ParameterToString(sortDirection.Value); + + if (sortBy.IsSet) + parseQueryStringLocalVar["sort_by"] = ClientUtils.ParameterToString(sortBy.Value); + + uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString(); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] acceptLocalVars = new string[] { + "application/json", + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Get; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + FetchProjectTimeAttachmentsApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/project-times/{project_time_id}/attachments", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterFetchProjectTimeAttachmentsDefaultImplementation(apiResponseLocalVar, projectTimeId, pageToken, limit, sortDirection, sortBy); + + Events.ExecuteOnFetchProjectTimeAttachments(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorFetchProjectTimeAttachmentsDefaultImplementation(e, "/project-times/{project_time_id}/attachments", uriBuilderLocalVar.Path, projectTimeId, pageToken, limit, sortDirection, sortBy); + Events.ExecuteOnErrorFetchProjectTimeAttachments(e); + throw; + } + } + + /// + /// The + /// + public partial class FetchProjectTimeAttachmentsApiResponse : Timr.Api.Client.ApiResponse, IFetchProjectTimeAttachmentsApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public FetchProjectTimeAttachmentsApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public FetchProjectTimeAttachmentsApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 200 Ok + /// + /// + public bool IsOk => 200 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 200 Ok + /// + /// + public Timr.Api.Model.AttachmentsPage? Ok() + { + bool suppressDefault = false; + Timr.Api.Model.AttachmentsPage? result = null; + OnOk(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultOk(); + return result; + } + + private Timr.Api.Model.AttachmentsPage? DefaultOk() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsOk + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnOk(ref bool suppressDefault, ref Timr.Api.Model.AttachmentsPage? result); + + /// + /// Returns true if the response is 200 Ok and the deserialized response is not null + /// + /// + /// + public bool TryOk([NotNullWhen(true)]out Timr.Api.Model.AttachmentsPage? result) + { + result = null; + + try + { + result = Ok(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)200); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + + partial void FormatGetProjectTimeAttachment(ref string projectTimeId, ref Guid attachmentId); + + /// + /// Validates the request parameters + /// + /// + /// + private void ValidateGetProjectTimeAttachment(string projectTimeId) + { + if (projectTimeId == null) + throw new ArgumentNullException(nameof(projectTimeId)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + private void AfterGetProjectTimeAttachmentDefaultImplementation(IGetProjectTimeAttachmentApiResponse apiResponseLocalVar, string projectTimeId, Guid attachmentId) + { + bool suppressDefaultLog = false; + AfterGetProjectTimeAttachment(ref suppressDefaultLog, apiResponseLocalVar, projectTimeId, attachmentId); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + partial void AfterGetProjectTimeAttachment(ref bool suppressDefaultLog, IGetProjectTimeAttachmentApiResponse apiResponseLocalVar, string projectTimeId, Guid attachmentId); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + private void OnErrorGetProjectTimeAttachmentDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, Guid attachmentId) + { + bool suppressDefaultLogLocalVar = false; + OnErrorGetProjectTimeAttachment(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, projectTimeId, attachmentId); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorGetProjectTimeAttachment(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string projectTimeId, Guid attachmentId); + + /// + /// Get a Project Time Attachment Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + /// + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task GetProjectTimeAttachmentOrDefaultAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await GetProjectTimeAttachmentAsync(projectTimeId, attachmentId, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Get a Project Time Attachment Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + /// + /// Thrown when fails to make API call + /// ID of the Project Time. + /// ID of the Project Time Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task GetProjectTimeAttachmentAsync(string projectTimeId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateGetProjectTimeAttachment(projectTimeId); + + FormatGetProjectTimeAttachment(ref projectTimeId, ref attachmentId); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/project-times/{project_time_id}/attachments/{attachment_id}" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/project-times/{project_time_id}/attachments/{attachment_id}"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Bproject_time_id%7D", Uri.EscapeDataString(projectTimeId.ToString())); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Battachment_id%7D", Uri.EscapeDataString(attachmentId.ToString())); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] acceptLocalVars = new string[] { + "application/json", + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Get; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + GetProjectTimeAttachmentApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/project-times/{project_time_id}/attachments/{attachment_id}", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterGetProjectTimeAttachmentDefaultImplementation(apiResponseLocalVar, projectTimeId, attachmentId); + + Events.ExecuteOnGetProjectTimeAttachment(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorGetProjectTimeAttachmentDefaultImplementation(e, "/project-times/{project_time_id}/attachments/{attachment_id}", uriBuilderLocalVar.Path, projectTimeId, attachmentId); + Events.ExecuteOnErrorGetProjectTimeAttachment(e); + throw; + } + } + + /// + /// The + /// + public partial class GetProjectTimeAttachmentApiResponse : Timr.Api.Client.ApiResponse, IGetProjectTimeAttachmentApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public GetProjectTimeAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public GetProjectTimeAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 200 Ok + /// + /// + public bool IsOk => 200 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 200 Ok + /// + /// + public Timr.Api.Model.Attachment? Ok() + { + bool suppressDefault = false; + Timr.Api.Model.Attachment? result = null; + OnOk(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultOk(); + return result; + } + + private Timr.Api.Model.Attachment? DefaultOk() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsOk + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnOk(ref bool suppressDefault, ref Timr.Api.Model.Attachment? result); + + /// + /// Returns true if the response is 200 Ok and the deserialized response is not null + /// + /// + /// + public bool TryOk([NotNullWhen(true)]out Timr.Api.Model.Attachment? result) + { + result = null; + + try + { + result = Ok(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)200); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Endpoints/TaskAttachmentApi.cs b/sdk/dotnet/Timr.Api/Endpoints/TaskAttachmentApi.cs new file mode 100644 index 0000000..72e16c3 --- /dev/null +++ b/sdk/dotnet/Timr.Api/Endpoints/TaskAttachmentApi.cs @@ -0,0 +1,1947 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Net; +using System.IO; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text.Json; +using Timr.Api.Client; +using Timr.Api.Logging; +using Timr.Api.Model; +using System.Diagnostics.CodeAnalysis; + +namespace Timr.Api.Endpoints +{ + /// + /// Represents a collection of functions to interact with the API endpoints + /// This class is registered as transient. + /// + public interface ITaskAttachmentApi : IApi + { + /// + /// The class containing the events + /// + TaskAttachmentApiEvents Events { get; } + + /// + /// Upload a Task Attachment + /// + /// + /// Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <> + Task CreateTaskAttachmentAsync(string taskId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Upload a Task Attachment + /// + /// + /// Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + /// + /// ID of the Task. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <?> + Task CreateTaskAttachmentOrDefaultAsync(string taskId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Delete a Task Attachment + /// + /// + /// Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <> + Task DeleteTaskAttachmentAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Delete a Task Attachment + /// + /// + /// Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + /// + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <?> + Task DeleteTaskAttachmentOrDefaultAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + + /// + /// List Task Attachments + /// + /// + /// Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <> + Task FetchTaskAttachmentsAsync(string taskId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default); + + /// + /// List Task Attachments + /// + /// + /// Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + /// + /// ID of the Task. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <?> + Task FetchTaskAttachmentsOrDefaultAsync(string taskId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Get a Task Attachment + /// + /// + /// Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <> + Task GetTaskAttachmentAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + + /// + /// Get a Task Attachment + /// + /// + /// Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + /// + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <?> + Task GetTaskAttachmentOrDefaultAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default); + } + + /// + /// The + /// + public interface ICreateTaskAttachmentApiResponse : Timr.Api.Client.IApiResponse, ICreated, IBadRequest, IForbidden, INotFound + { + /// + /// Returns true if the response is 201 Created + /// + /// + bool IsCreated { get; } + + /// + /// Returns true if the response is 400 BadRequest + /// + /// + bool IsBadRequest { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// The + /// + public interface IDeleteTaskAttachmentApiResponse : Timr.Api.Client.IApiResponse, IForbidden, INotFound + { + /// + /// Returns true if the response is 204 NoContent + /// + /// + bool IsNoContent { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// The + /// + public interface IFetchTaskAttachmentsApiResponse : Timr.Api.Client.IApiResponse, IOk, IForbidden, INotFound + { + /// + /// Returns true if the response is 200 Ok + /// + /// + bool IsOk { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// The + /// + public interface IGetTaskAttachmentApiResponse : Timr.Api.Client.IApiResponse, IOk, IForbidden, INotFound + { + /// + /// Returns true if the response is 200 Ok + /// + /// + bool IsOk { get; } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + bool IsForbidden { get; } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + bool IsNotFound { get; } + } + + /// + /// Represents a collection of functions to interact with the API endpoints + /// + public class TaskAttachmentApiEvents + { + /// + /// The event raised after the server response + /// + public event EventHandler? OnCreateTaskAttachment; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorCreateTaskAttachment; + + internal void ExecuteOnCreateTaskAttachment(TaskAttachmentApi.CreateTaskAttachmentApiResponse apiResponse) + { + OnCreateTaskAttachment?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorCreateTaskAttachment(Exception exception) + { + OnErrorCreateTaskAttachment?.Invoke(this, new ExceptionEventArgs(exception)); + } + + /// + /// The event raised after the server response + /// + public event EventHandler? OnDeleteTaskAttachment; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorDeleteTaskAttachment; + + internal void ExecuteOnDeleteTaskAttachment(TaskAttachmentApi.DeleteTaskAttachmentApiResponse apiResponse) + { + OnDeleteTaskAttachment?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorDeleteTaskAttachment(Exception exception) + { + OnErrorDeleteTaskAttachment?.Invoke(this, new ExceptionEventArgs(exception)); + } + + /// + /// The event raised after the server response + /// + public event EventHandler? OnFetchTaskAttachments; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorFetchTaskAttachments; + + internal void ExecuteOnFetchTaskAttachments(TaskAttachmentApi.FetchTaskAttachmentsApiResponse apiResponse) + { + OnFetchTaskAttachments?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorFetchTaskAttachments(Exception exception) + { + OnErrorFetchTaskAttachments?.Invoke(this, new ExceptionEventArgs(exception)); + } + + /// + /// The event raised after the server response + /// + public event EventHandler? OnGetTaskAttachment; + + /// + /// The event raised after an error querying the server + /// + public event EventHandler? OnErrorGetTaskAttachment; + + internal void ExecuteOnGetTaskAttachment(TaskAttachmentApi.GetTaskAttachmentApiResponse apiResponse) + { + OnGetTaskAttachment?.Invoke(this, new ApiResponseEventArgs(apiResponse)); + } + + internal void ExecuteOnErrorGetTaskAttachment(Exception exception) + { + OnErrorGetTaskAttachment?.Invoke(this, new ExceptionEventArgs(exception)); + } + } + + /// + /// Represents a collection of functions to interact with the API endpoints + /// + public sealed partial class TaskAttachmentApi : ITaskAttachmentApi + { + private JsonSerializerOptions _jsonSerializerOptions; + + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The HttpClient + /// + public HttpClient HttpClient { get; } + + /// + /// The class containing the events + /// + public TaskAttachmentApiEvents Events { get; } + + /// + /// A token provider of type + /// + public TokenProvider OauthTokenProvider { get; } + + /// + /// Initializes a new instance of the class. + /// + /// + public TaskAttachmentApi(ILogger logger, HttpClient httpClient, JsonSerializerOptionsProvider jsonSerializerOptionsProvider, TaskAttachmentApiEvents taskAttachmentApiEvents, + TokenProvider oauthTokenProvider) + { + _jsonSerializerOptions = jsonSerializerOptionsProvider.Options; + Logger = logger; + HttpClient = httpClient; + Events = taskAttachmentApiEvents; + OauthTokenProvider = oauthTokenProvider; + } + + partial void FormatCreateTaskAttachment(ref string taskId, AttachmentMetadata attachmentMetadata); + + /// + /// Validates the request parameters + /// + /// + /// + /// + private void ValidateCreateTaskAttachment(string taskId, AttachmentMetadata attachmentMetadata) + { + if (taskId == null) + throw new ArgumentNullException(nameof(taskId)); + + if (attachmentMetadata == null) + throw new ArgumentNullException(nameof(attachmentMetadata)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + private void AfterCreateTaskAttachmentDefaultImplementation(ICreateTaskAttachmentApiResponse apiResponseLocalVar, string taskId, AttachmentMetadata attachmentMetadata) + { + bool suppressDefaultLog = false; + AfterCreateTaskAttachment(ref suppressDefaultLog, apiResponseLocalVar, taskId, attachmentMetadata); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + partial void AfterCreateTaskAttachment(ref bool suppressDefaultLog, ICreateTaskAttachmentApiResponse apiResponseLocalVar, string taskId, AttachmentMetadata attachmentMetadata); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + private void OnErrorCreateTaskAttachmentDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, AttachmentMetadata attachmentMetadata) + { + bool suppressDefaultLogLocalVar = false; + OnErrorCreateTaskAttachment(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, taskId, attachmentMetadata); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorCreateTaskAttachment(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, AttachmentMetadata attachmentMetadata); + + /// + /// Upload a Task Attachment Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + /// + /// ID of the Task. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <> + public async Task CreateTaskAttachmentOrDefaultAsync(string taskId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await CreateTaskAttachmentAsync(taskId, attachmentMetadata, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Upload a Task Attachment Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// Metadata of the file to upload. + /// Cancellation Token to cancel the request. + /// <> + public async Task CreateTaskAttachmentAsync(string taskId, AttachmentMetadata attachmentMetadata, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateCreateTaskAttachment(taskId, attachmentMetadata); + + FormatCreateTaskAttachment(ref taskId, attachmentMetadata); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/tasks/{task_id}/attachments" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/tasks/{task_id}/attachments"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Btask_id%7D", Uri.EscapeDataString(taskId.ToString())); + + httpRequestMessageLocalVar.Content = (attachmentMetadata as object) is Timr.Api.Client.FileParameter fileParameterLocalVar + ? httpRequestMessageLocalVar.Content = new StreamContent(fileParameterLocalVar.Content) + : httpRequestMessageLocalVar.Content = new StringContent(JsonSerializer.Serialize(attachmentMetadata, _jsonSerializerOptions)); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] contentTypes = new string[] { + "application/json" + }; + + string? contentTypeLocalVar = ClientUtils.SelectHeaderContentType(contentTypes); + + if (contentTypeLocalVar != null && httpRequestMessageLocalVar.Content != null) + httpRequestMessageLocalVar.Content.Headers.ContentType = new MediaTypeHeaderValue(contentTypeLocalVar); + + string[] acceptLocalVars = new string[] { + "application/json", + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Post; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + CreateTaskAttachmentApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/tasks/{task_id}/attachments", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterCreateTaskAttachmentDefaultImplementation(apiResponseLocalVar, taskId, attachmentMetadata); + + Events.ExecuteOnCreateTaskAttachment(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorCreateTaskAttachmentDefaultImplementation(e, "/tasks/{task_id}/attachments", uriBuilderLocalVar.Path, taskId, attachmentMetadata); + Events.ExecuteOnErrorCreateTaskAttachment(e); + throw; + } + } + + /// + /// The + /// + public partial class CreateTaskAttachmentApiResponse : Timr.Api.Client.ApiResponse, ICreateTaskAttachmentApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public CreateTaskAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public CreateTaskAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 201 Created + /// + /// + public bool IsCreated => 201 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 201 Created + /// + /// + public Timr.Api.Model.AttachmentUploadResponse? Created() + { + bool suppressDefault = false; + Timr.Api.Model.AttachmentUploadResponse? result = null; + OnCreated(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultCreated(); + return result; + } + + private Timr.Api.Model.AttachmentUploadResponse? DefaultCreated() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsCreated + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnCreated(ref bool suppressDefault, ref Timr.Api.Model.AttachmentUploadResponse? result); + + /// + /// Returns true if the response is 201 Created and the deserialized response is not null + /// + /// + /// + public bool TryCreated([NotNullWhen(true)]out Timr.Api.Model.AttachmentUploadResponse? result) + { + result = null; + + try + { + result = Created(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)201); + } + + return result != null; + } + + /// + /// Returns true if the response is 400 BadRequest + /// + /// + public bool IsBadRequest => 400 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 400 BadRequest + /// + /// + public Timr.Api.Model.Error? BadRequest() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnBadRequest(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultBadRequest(); + return result; + } + + private Timr.Api.Model.Error? DefaultBadRequest() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsBadRequest + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnBadRequest(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 400 BadRequest and the deserialized response is not null + /// + /// + /// + public bool TryBadRequest([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = BadRequest(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)400); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + + partial void FormatDeleteTaskAttachment(ref string taskId, ref Guid attachmentId); + + /// + /// Validates the request parameters + /// + /// + /// + private void ValidateDeleteTaskAttachment(string taskId) + { + if (taskId == null) + throw new ArgumentNullException(nameof(taskId)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + private void AfterDeleteTaskAttachmentDefaultImplementation(IDeleteTaskAttachmentApiResponse apiResponseLocalVar, string taskId, Guid attachmentId) + { + bool suppressDefaultLog = false; + AfterDeleteTaskAttachment(ref suppressDefaultLog, apiResponseLocalVar, taskId, attachmentId); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + partial void AfterDeleteTaskAttachment(ref bool suppressDefaultLog, IDeleteTaskAttachmentApiResponse apiResponseLocalVar, string taskId, Guid attachmentId); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + private void OnErrorDeleteTaskAttachmentDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, Guid attachmentId) + { + bool suppressDefaultLogLocalVar = false; + OnErrorDeleteTaskAttachment(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, taskId, attachmentId); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorDeleteTaskAttachment(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, Guid attachmentId); + + /// + /// Delete a Task Attachment Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + /// + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task DeleteTaskAttachmentOrDefaultAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await DeleteTaskAttachmentAsync(taskId, attachmentId, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Delete a Task Attachment Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task DeleteTaskAttachmentAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateDeleteTaskAttachment(taskId); + + FormatDeleteTaskAttachment(ref taskId, ref attachmentId); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/tasks/{task_id}/attachments/{attachment_id}" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/tasks/{task_id}/attachments/{attachment_id}"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Btask_id%7D", Uri.EscapeDataString(taskId.ToString())); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Battachment_id%7D", Uri.EscapeDataString(attachmentId.ToString())); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] acceptLocalVars = new string[] { + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Delete; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + DeleteTaskAttachmentApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/tasks/{task_id}/attachments/{attachment_id}", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterDeleteTaskAttachmentDefaultImplementation(apiResponseLocalVar, taskId, attachmentId); + + Events.ExecuteOnDeleteTaskAttachment(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorDeleteTaskAttachmentDefaultImplementation(e, "/tasks/{task_id}/attachments/{attachment_id}", uriBuilderLocalVar.Path, taskId, attachmentId); + Events.ExecuteOnErrorDeleteTaskAttachment(e); + throw; + } + } + + /// + /// The + /// + public partial class DeleteTaskAttachmentApiResponse : Timr.Api.Client.ApiResponse, IDeleteTaskAttachmentApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public DeleteTaskAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public DeleteTaskAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 204 NoContent + /// + /// + public bool IsNoContent => 204 == (int)StatusCode; + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + + partial void FormatFetchTaskAttachments(ref string taskId, ref Option pageToken, ref Option limit, ref Option sortDirection, ref Option sortBy); + + /// + /// Validates the request parameters + /// + /// + /// + /// + private void ValidateFetchTaskAttachments(string taskId, Option pageToken) + { + if (taskId == null) + throw new ArgumentNullException(nameof(taskId)); + + if (pageToken.IsSet && pageToken.Value == null) + throw new ArgumentNullException(nameof(pageToken)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + /// + /// + private void AfterFetchTaskAttachmentsDefaultImplementation(IFetchTaskAttachmentsApiResponse apiResponseLocalVar, string taskId, Option pageToken, Option limit, Option sortDirection, Option sortBy) + { + bool suppressDefaultLog = false; + AfterFetchTaskAttachments(ref suppressDefaultLog, apiResponseLocalVar, taskId, pageToken, limit, sortDirection, sortBy); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + /// + /// + /// + partial void AfterFetchTaskAttachments(ref bool suppressDefaultLog, IFetchTaskAttachmentsApiResponse apiResponseLocalVar, string taskId, Option pageToken, Option limit, Option sortDirection, Option sortBy); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + /// + /// + /// + private void OnErrorFetchTaskAttachmentsDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, Option pageToken, Option limit, Option sortDirection, Option sortBy) + { + bool suppressDefaultLogLocalVar = false; + OnErrorFetchTaskAttachments(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, taskId, pageToken, limit, sortDirection, sortBy); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorFetchTaskAttachments(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, Option pageToken, Option limit, Option sortDirection, Option sortBy); + + /// + /// List Task Attachments Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + /// + /// ID of the Task. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <> + public async Task FetchTaskAttachmentsOrDefaultAsync(string taskId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await FetchTaskAttachmentsAsync(taskId, pageToken, limit, sortDirection, sortBy, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// List Task Attachments Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + /// Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + /// Direction to sort the entries in. (optional) + /// Property to sort the entries by. (optional) + /// Cancellation Token to cancel the request. + /// <> + public async Task FetchTaskAttachmentsAsync(string taskId, Option pageToken = default, Option limit = default, Option sortDirection = default, Option sortBy = default, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateFetchTaskAttachments(taskId, pageToken); + + FormatFetchTaskAttachments(ref taskId, ref pageToken, ref limit, ref sortDirection, ref sortBy); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/tasks/{task_id}/attachments" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/tasks/{task_id}/attachments"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Btask_id%7D", Uri.EscapeDataString(taskId.ToString())); + + System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty); + + if (pageToken.IsSet) + parseQueryStringLocalVar["page_token"] = ClientUtils.ParameterToString(pageToken.Value); + + if (limit.IsSet) + parseQueryStringLocalVar["limit"] = ClientUtils.ParameterToString(limit.Value); + + if (sortDirection.IsSet) + parseQueryStringLocalVar["sort_direction"] = ClientUtils.ParameterToString(sortDirection.Value); + + if (sortBy.IsSet) + parseQueryStringLocalVar["sort_by"] = ClientUtils.ParameterToString(sortBy.Value); + + uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString(); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] acceptLocalVars = new string[] { + "application/json", + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Get; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + FetchTaskAttachmentsApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/tasks/{task_id}/attachments", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterFetchTaskAttachmentsDefaultImplementation(apiResponseLocalVar, taskId, pageToken, limit, sortDirection, sortBy); + + Events.ExecuteOnFetchTaskAttachments(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorFetchTaskAttachmentsDefaultImplementation(e, "/tasks/{task_id}/attachments", uriBuilderLocalVar.Path, taskId, pageToken, limit, sortDirection, sortBy); + Events.ExecuteOnErrorFetchTaskAttachments(e); + throw; + } + } + + /// + /// The + /// + public partial class FetchTaskAttachmentsApiResponse : Timr.Api.Client.ApiResponse, IFetchTaskAttachmentsApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public FetchTaskAttachmentsApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public FetchTaskAttachmentsApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 200 Ok + /// + /// + public bool IsOk => 200 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 200 Ok + /// + /// + public Timr.Api.Model.AttachmentsPage? Ok() + { + bool suppressDefault = false; + Timr.Api.Model.AttachmentsPage? result = null; + OnOk(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultOk(); + return result; + } + + private Timr.Api.Model.AttachmentsPage? DefaultOk() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsOk + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnOk(ref bool suppressDefault, ref Timr.Api.Model.AttachmentsPage? result); + + /// + /// Returns true if the response is 200 Ok and the deserialized response is not null + /// + /// + /// + public bool TryOk([NotNullWhen(true)]out Timr.Api.Model.AttachmentsPage? result) + { + result = null; + + try + { + result = Ok(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)200); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + + partial void FormatGetTaskAttachment(ref string taskId, ref Guid attachmentId); + + /// + /// Validates the request parameters + /// + /// + /// + private void ValidateGetTaskAttachment(string taskId) + { + if (taskId == null) + throw new ArgumentNullException(nameof(taskId)); + } + + /// + /// Processes the server response + /// + /// + /// + /// + private void AfterGetTaskAttachmentDefaultImplementation(IGetTaskAttachmentApiResponse apiResponseLocalVar, string taskId, Guid attachmentId) + { + bool suppressDefaultLog = false; + AfterGetTaskAttachment(ref suppressDefaultLog, apiResponseLocalVar, taskId, attachmentId); + if (!suppressDefaultLog) + Logger.LogInformation(RestLogEvents.ApiRequestCompleted, "{0,-9} | {1} | {2}", (apiResponseLocalVar.DownloadedAt - apiResponseLocalVar.RequestedAt).TotalSeconds, apiResponseLocalVar.StatusCode, apiResponseLocalVar.Path); + } + + /// + /// Processes the server response + /// + /// + /// + /// + /// + partial void AfterGetTaskAttachment(ref bool suppressDefaultLog, IGetTaskAttachmentApiResponse apiResponseLocalVar, string taskId, Guid attachmentId); + + /// + /// Logs exceptions that occur while retrieving the server response + /// + /// + /// + /// + /// + /// + private void OnErrorGetTaskAttachmentDefaultImplementation(Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, Guid attachmentId) + { + bool suppressDefaultLogLocalVar = false; + OnErrorGetTaskAttachment(ref suppressDefaultLogLocalVar, exceptionLocalVar, pathFormatLocalVar, pathLocalVar, taskId, attachmentId); + if (!suppressDefaultLogLocalVar) + Logger.LogError(RestLogEvents.ApiRequestFailed, exceptionLocalVar, "An error occurred while sending the request to the server."); + } + + /// + /// A partial method that gives developers a way to provide customized exception handling + /// + /// + /// + /// + /// + /// + /// + partial void OnErrorGetTaskAttachment(ref bool suppressDefaultLogLocalVar, Exception exceptionLocalVar, string pathFormatLocalVar, string pathLocalVar, string taskId, Guid attachmentId); + + /// + /// Get a Task Attachment Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + /// + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task GetTaskAttachmentOrDefaultAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + try + { + return await GetTaskAttachmentAsync(taskId, attachmentId, cancellationToken).ConfigureAwait(false); + } + catch (Exception) + { + return null; + } + } + + /// + /// Get a Task Attachment Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + /// + /// Thrown when fails to make API call + /// ID of the Task. + /// ID of the Task Attachment. + /// Cancellation Token to cancel the request. + /// <> + public async Task GetTaskAttachmentAsync(string taskId, Guid attachmentId, System.Threading.CancellationToken cancellationToken = default) + { + UriBuilder uriBuilderLocalVar = new UriBuilder(); + + try + { + ValidateGetTaskAttachment(taskId); + + FormatGetTaskAttachment(ref taskId, ref attachmentId); + + using (HttpRequestMessage httpRequestMessageLocalVar = new HttpRequestMessage()) + { + uriBuilderLocalVar.Host = HttpClient.BaseAddress!.Host; + uriBuilderLocalVar.Port = HttpClient.BaseAddress.Port; + uriBuilderLocalVar.Scheme = HttpClient.BaseAddress.Scheme; + uriBuilderLocalVar.Path = HttpClient.BaseAddress.AbsolutePath == "/" + ? "/tasks/{task_id}/attachments/{attachment_id}" + : string.Concat(HttpClient.BaseAddress.AbsolutePath.TrimEnd('/'), "/tasks/{task_id}/attachments/{attachment_id}"); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Btask_id%7D", Uri.EscapeDataString(taskId.ToString())); + uriBuilderLocalVar.Path = uriBuilderLocalVar.Path.Replace("%7Battachment_id%7D", Uri.EscapeDataString(attachmentId.ToString())); + + List tokenBaseLocalVars = new List(); + httpRequestMessageLocalVar.RequestUri = uriBuilderLocalVar.Uri; + + OAuthToken oauthTokenLocalVar1 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar1); + + oauthTokenLocalVar1.UseInHeader(httpRequestMessageLocalVar, ""); + + OAuthToken oauthTokenLocalVar2 = (OAuthToken) await OauthTokenProvider.GetAsync(cancellation: cancellationToken).ConfigureAwait(false); + + tokenBaseLocalVars.Add(oauthTokenLocalVar2); + + oauthTokenLocalVar2.UseInHeader(httpRequestMessageLocalVar, ""); + + string[] acceptLocalVars = new string[] { + "application/json", + "application/problem+json" + }; + + IEnumerable acceptHeaderValuesLocalVar = ClientUtils.SelectHeaderAcceptArray(acceptLocalVars); + + foreach (var acceptLocalVar in acceptHeaderValuesLocalVar) + httpRequestMessageLocalVar.Headers.Accept.Add(acceptLocalVar); + + httpRequestMessageLocalVar.Method = HttpMethod.Get; + + DateTime requestedAtLocalVar = DateTime.UtcNow; + + using (HttpResponseMessage httpResponseMessageLocalVar = await HttpClient.SendAsync(httpRequestMessageLocalVar, cancellationToken).ConfigureAwait(false)) + { + GetTaskAttachmentApiResponse apiResponseLocalVar; + + switch ((int)httpResponseMessageLocalVar.StatusCode) { + default: { + string responseContentLocalVar = await httpResponseMessageLocalVar.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + apiResponseLocalVar = new(Logger, httpRequestMessageLocalVar, httpResponseMessageLocalVar, responseContentLocalVar, "/tasks/{task_id}/attachments/{attachment_id}", requestedAtLocalVar, _jsonSerializerOptions); + + break; + } + } + + AfterGetTaskAttachmentDefaultImplementation(apiResponseLocalVar, taskId, attachmentId); + + Events.ExecuteOnGetTaskAttachment(apiResponseLocalVar); + + if (apiResponseLocalVar.StatusCode == (HttpStatusCode) 429) + foreach(TokenBase tokenBaseLocalVar in tokenBaseLocalVars) + tokenBaseLocalVar.BeginRateLimit(); + + return apiResponseLocalVar; + } + } + } + catch(Exception e) + { + OnErrorGetTaskAttachmentDefaultImplementation(e, "/tasks/{task_id}/attachments/{attachment_id}", uriBuilderLocalVar.Path, taskId, attachmentId); + Events.ExecuteOnErrorGetTaskAttachment(e); + throw; + } + } + + /// + /// The + /// + public partial class GetTaskAttachmentApiResponse : Timr.Api.Client.ApiResponse, IGetTaskAttachmentApiResponse + { + /// + /// The logger + /// + public ILogger Logger { get; } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public GetTaskAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, string rawContent, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, rawContent, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + /// + /// The + /// + /// + /// + /// + /// + /// + /// + /// + public GetTaskAttachmentApiResponse(ILogger logger, System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage, System.IO.Stream contentStream, string path, DateTime requestedAt, System.Text.Json.JsonSerializerOptions jsonSerializerOptions) : base(httpRequestMessage, httpResponseMessage, contentStream, path, requestedAt, jsonSerializerOptions) + { + Logger = logger; + OnCreated(httpRequestMessage, httpResponseMessage); + } + + partial void OnCreated(global::System.Net.Http.HttpRequestMessage httpRequestMessage, System.Net.Http.HttpResponseMessage httpResponseMessage); + + /// + /// Returns true if the response is 200 Ok + /// + /// + public bool IsOk => 200 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 200 Ok + /// + /// + public Timr.Api.Model.Attachment? Ok() + { + bool suppressDefault = false; + Timr.Api.Model.Attachment? result = null; + OnOk(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultOk(); + return result; + } + + private Timr.Api.Model.Attachment? DefaultOk() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsOk + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnOk(ref bool suppressDefault, ref Timr.Api.Model.Attachment? result); + + /// + /// Returns true if the response is 200 Ok and the deserialized response is not null + /// + /// + /// + public bool TryOk([NotNullWhen(true)]out Timr.Api.Model.Attachment? result) + { + result = null; + + try + { + result = Ok(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)200); + } + + return result != null; + } + + /// + /// Returns true if the response is 403 Forbidden + /// + /// + public bool IsForbidden => 403 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 403 Forbidden + /// + /// + public Timr.Api.Model.Error? Forbidden() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnForbidden(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultForbidden(); + return result; + } + + private Timr.Api.Model.Error? DefaultForbidden() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsForbidden + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnForbidden(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 403 Forbidden and the deserialized response is not null + /// + /// + /// + public bool TryForbidden([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = Forbidden(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)403); + } + + return result != null; + } + + /// + /// Returns true if the response is 404 NotFound + /// + /// + public bool IsNotFound => 404 == (int)StatusCode; + + /// + /// Deserializes the response if the response is 404 NotFound + /// + /// + public Timr.Api.Model.Error? NotFound() + { + bool suppressDefault = false; + Timr.Api.Model.Error? result = null; + OnNotFound(ref suppressDefault, ref result); + if (!suppressDefault) + result = DefaultNotFound(); + return result; + } + + private Timr.Api.Model.Error? DefaultNotFound() + { + // NOTICE: Consider this AsModel template deprecated. Implement the appropriate partial method instead + return IsNotFound + ? System.Text.Json.JsonSerializer.Deserialize(RawContent, _jsonSerializerOptions) + : null; + } + + partial void OnNotFound(ref bool suppressDefault, ref Timr.Api.Model.Error? result); + + /// + /// Returns true if the response is 404 NotFound and the deserialized response is not null + /// + /// + /// + public bool TryNotFound([NotNullWhen(true)]out Timr.Api.Model.Error? result) + { + result = null; + + try + { + result = NotFound(); + } catch (Exception e) + { + OnDeserializationErrorDefaultImplementation(e, (HttpStatusCode)404); + } + + return result != null; + } + + private void OnDeserializationErrorDefaultImplementation(Exception exception, HttpStatusCode httpStatusCode) + { + bool suppressDefaultLog = false; + OnDeserializationError(ref suppressDefaultLog, exception, httpStatusCode); + if (!suppressDefaultLog) + Logger.LogError(RestLogEvents.ApiDeserializationFailed, exception, "An error occurred while deserializing the {code} response.", httpStatusCode); + } + + partial void OnDeserializationError(ref bool suppressDefaultLog, Exception exception, HttpStatusCode httpStatusCode); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/Attachment.cs b/sdk/dotnet/Timr.Api/Model/Attachment.cs new file mode 100644 index 0000000..44b4639 --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/Attachment.cs @@ -0,0 +1,268 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + /// + public partial class Attachment : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// Unique identifier. Treat it as an opaque string. + /// metadata + /// When the upload of the file completed. RFC 3339 date-time (ISO-8601) + /// Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + /// The User who uploaded the file, or null if that User no longer exists. + [JsonConstructor] + public Attachment(Guid id, AttachmentMetadata metadata, DateTimeOffset uploadedAt, AttachmentDownload? download = default, UserPartial? uploadedBy = default) + { + Id = id; + Metadata = metadata; + UploadedAt = uploadedAt; + Download = download; + UploadedBy = uploadedBy; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Unique identifier. Treat it as an opaque string. + /// + /// Unique identifier. Treat it as an opaque string. + /* 01972ff0-14a2-7814-926c-11d07a1dc20b */ + [JsonPropertyName("id")] + public Guid Id { get; set; } + + /// + /// Gets or Sets Metadata + /// + [JsonPropertyName("metadata")] + public AttachmentMetadata Metadata { get; set; } + + /// + /// When the upload of the file completed. RFC 3339 date-time (ISO-8601) + /// + /// When the upload of the file completed. RFC 3339 date-time (ISO-8601) + /* 2021-07-16T08:20Z */ + [JsonPropertyName("uploaded_at")] + public DateTimeOffset UploadedAt { get; set; } + + /// + /// Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + /// + /// Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + [JsonPropertyName("download")] + public AttachmentDownload? Download { get; set; } + + /// + /// The User who uploaded the file, or null if that User no longer exists. + /// + /// The User who uploaded the file, or null if that User no longer exists. + [JsonPropertyName("uploaded_by")] + public UserPartial? UploadedBy { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class Attachment {\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Metadata: ").Append(Metadata).Append("\n"); + sb.Append(" UploadedAt: ").Append(UploadedAt).Append("\n"); + sb.Append(" Download: ").Append(Download).Append("\n"); + sb.Append(" UploadedBy: ").Append(UploadedBy).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public partial class AttachmentJsonConverter : JsonConverter + { + partial void OnCreated(); + + /// + /// Initializes a new instance of the class. + /// + public AttachmentJsonConverter() + { + OnCreated(); + } + + /// + /// The format to use to serialize UploadedAt + /// + public string UploadedAtFormat { get; private set; } = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"; + + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override Attachment Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option id = default; + Option metadata = default; + Option uploadedAt = default; + Option download = default; + Option uploadedBy = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string? localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "id": + id = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (Guid?)null : utf8JsonReader.GetGuid()); + break; + case "metadata": + metadata = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)!); + break; + case "uploaded_at": + uploadedAt = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "download": + download = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + case "uploaded_by": + uploadedBy = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + default: + break; + } + } + } + + if (!id.IsSet) + throw new JsonException("Property is required for class Attachment: id."); + + if (!metadata.IsSet) + throw new JsonException("Property is required for class Attachment: metadata."); + + if (!uploadedAt.IsSet) + throw new JsonException("Property is required for class Attachment: uploaded_at."); + + if (!download.IsSet) + throw new JsonException("Property is required for class Attachment: download."); + + if (!uploadedBy.IsSet) + throw new JsonException("Property is required for class Attachment: uploaded_by."); + + if (id.IsSet && id.Value == null) + throw new JsonException("Property is not nullable for class Attachment: id."); + + if (metadata.IsSet && metadata.Value == null) + throw new JsonException("Property is not nullable for class Attachment: metadata."); + + if (uploadedAt.IsSet && uploadedAt.Value == null) + throw new JsonException("Property is not nullable for class Attachment: uploaded_at."); + + return new Attachment(id.Value!.Value!, metadata.Value!, uploadedAt.Value!.Value!, download.Value!, uploadedBy.Value!); + } + + /// + /// Serializes a + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, Attachment attachment, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, attachment, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, Attachment attachment, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteString("id", attachment.Id); + + writer.WritePropertyName("metadata"); + JsonSerializer.Serialize(writer, attachment.Metadata, jsonSerializerOptions); + writer.WriteString("uploaded_at", attachment.UploadedAt.ToString(UploadedAtFormat)); + + if (attachment.Download != null) + { + writer.WritePropertyName("download"); + JsonSerializer.Serialize(writer, attachment.Download, jsonSerializerOptions); + } + else + writer.WriteNull("download"); + if (attachment.UploadedBy != null) + { + writer.WritePropertyName("uploaded_by"); + JsonSerializer.Serialize(writer, attachment.UploadedBy, jsonSerializerOptions); + } + else + writer.WriteNull("uploaded_by"); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/AttachmentDownload.cs b/sdk/dotnet/Timr.Api/Model/AttachmentDownload.cs new file mode 100644 index 0000000..fe19248 --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/AttachmentDownload.cs @@ -0,0 +1,169 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. + /// + public partial class AttachmentDownload : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// url + [JsonConstructor] + public AttachmentDownload(string url) + { + Url = url; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Gets or Sets Url + /// + /* https://s3.eu-central-1.amazonaws.com/timr-attachments/01972ff0-14a2-7814-926c-11d07a1dc20b?X-Amz-Signature=... */ + [JsonPropertyName("url")] + public string Url { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class AttachmentDownload {\n"); + sb.Append(" Url: ").Append(Url).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public partial class AttachmentDownloadJsonConverter : JsonConverter + { + partial void OnCreated(); + + /// + /// Initializes a new instance of the class. + /// + public AttachmentDownloadJsonConverter() + { + OnCreated(); + } + + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override AttachmentDownload Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option url = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string? localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "url": + url = new Option(utf8JsonReader.GetString()!); + break; + default: + break; + } + } + } + + if (!url.IsSet) + throw new JsonException("Property is required for class AttachmentDownload: url."); + + if (url.IsSet && url.Value == null) + throw new JsonException("Property is not nullable for class AttachmentDownload: url."); + + return new AttachmentDownload(url.Value!); + } + + /// + /// Serializes a + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentDownload attachmentDownload, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, attachmentDownload, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, AttachmentDownload attachmentDownload, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteString("url", attachmentDownload.Url); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/AttachmentMetadata.cs b/sdk/dotnet/Timr.Api/Model/AttachmentMetadata.cs new file mode 100644 index 0000000..7cb15ec --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/AttachmentMetadata.cs @@ -0,0 +1,243 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// Metadata of the attached file, as provided when it was uploaded. + /// + public partial class AttachmentMetadata : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// fileName + /// Media type of the file. + /// Size of the file in bytes. + /// When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + [JsonConstructor] + public AttachmentMetadata(string fileName, string contentType, long size, DateTimeOffset fileLastModified) + { + FileName = fileName; + ContentType = contentType; + Size = size; + FileLastModified = fileLastModified; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Gets or Sets FileName + /// + /* before_cleanup.jpeg */ + [JsonPropertyName("file_name")] + public string FileName { get; set; } + + /// + /// Media type of the file. + /// + /// Media type of the file. + /* image/jpeg */ + [JsonPropertyName("content_type")] + public string ContentType { get; set; } + + /// + /// Size of the file in bytes. + /// + /// Size of the file in bytes. + /* 204800 */ + [JsonPropertyName("size")] + public long Size { get; set; } + + /// + /// When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + /// + /// When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + /* 2021-07-16T08:20Z */ + [JsonPropertyName("file_last_modified")] + public DateTimeOffset FileLastModified { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class AttachmentMetadata {\n"); + sb.Append(" FileName: ").Append(FileName).Append("\n"); + sb.Append(" ContentType: ").Append(ContentType).Append("\n"); + sb.Append(" Size: ").Append(Size).Append("\n"); + sb.Append(" FileLastModified: ").Append(FileLastModified).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public partial class AttachmentMetadataJsonConverter : JsonConverter + { + partial void OnCreated(); + + /// + /// Initializes a new instance of the class. + /// + public AttachmentMetadataJsonConverter() + { + OnCreated(); + } + + /// + /// The format to use to serialize FileLastModified + /// + public string FileLastModifiedFormat { get; private set; } = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"; + + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override AttachmentMetadata Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option fileName = default; + Option contentType = default; + Option size = default; + Option fileLastModified = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string? localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "file_name": + fileName = new Option(utf8JsonReader.GetString()!); + break; + case "content_type": + contentType = new Option(utf8JsonReader.GetString()!); + break; + case "size": + size = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (long?)null : utf8JsonReader.GetInt64()); + break; + case "file_last_modified": + fileLastModified = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + default: + break; + } + } + } + + if (!fileName.IsSet) + throw new JsonException("Property is required for class AttachmentMetadata: file_name."); + + if (!contentType.IsSet) + throw new JsonException("Property is required for class AttachmentMetadata: content_type."); + + if (!size.IsSet) + throw new JsonException("Property is required for class AttachmentMetadata: size."); + + if (!fileLastModified.IsSet) + throw new JsonException("Property is required for class AttachmentMetadata: file_last_modified."); + + if (fileName.IsSet && fileName.Value == null) + throw new JsonException("Property is not nullable for class AttachmentMetadata: file_name."); + + if (contentType.IsSet && contentType.Value == null) + throw new JsonException("Property is not nullable for class AttachmentMetadata: content_type."); + + if (size.IsSet && size.Value == null) + throw new JsonException("Property is not nullable for class AttachmentMetadata: size."); + + if (fileLastModified.IsSet && fileLastModified.Value == null) + throw new JsonException("Property is not nullable for class AttachmentMetadata: file_last_modified."); + + return new AttachmentMetadata(fileName.Value!, contentType.Value!, size.Value!.Value!, fileLastModified.Value!.Value!); + } + + /// + /// Serializes a + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentMetadata attachmentMetadata, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, attachmentMetadata, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, AttachmentMetadata attachmentMetadata, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteString("file_name", attachmentMetadata.FileName); + + writer.WriteString("content_type", attachmentMetadata.ContentType); + + writer.WriteNumber("size", attachmentMetadata.Size); + + writer.WriteString("file_last_modified", attachmentMetadata.FileLastModified.ToString(FileLastModifiedFormat)); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/AttachmentUpload.cs b/sdk/dotnet/Timr.Api/Model/AttachmentUpload.cs new file mode 100644 index 0000000..5e8e6aa --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/AttachmentUpload.cs @@ -0,0 +1,220 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. + /// + public partial class AttachmentUpload : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// url + /// Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + /// When the URL stops being valid. RFC 3339 date-time (ISO-8601) + [JsonConstructor] + public AttachmentUpload(string url, Dictionary headers, DateTimeOffset expiresAt) + { + Url = url; + Headers = headers; + ExpiresAt = expiresAt; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Gets or Sets Url + /// + /* https://s3.eu-central-1.amazonaws.com/timr-attachments/01972ff0-14a2-7814-926c-11d07a1dc20b?X-Amz-Signature=... */ + [JsonPropertyName("url")] + public string Url { get; set; } + + /// + /// Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + /// + /// Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + /* {"Content-Type":"image/jpeg","Content-Disposition":"attachment; filename=\"before_cleanup.jpeg\"; filename*=UTF-8''before_cleanup.jpeg"} */ + [JsonPropertyName("headers")] + public Dictionary Headers { get; set; } + + /// + /// When the URL stops being valid. RFC 3339 date-time (ISO-8601) + /// + /// When the URL stops being valid. RFC 3339 date-time (ISO-8601) + /* 2021-07-16T08:20Z */ + [JsonPropertyName("expires_at")] + public DateTimeOffset ExpiresAt { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class AttachmentUpload {\n"); + sb.Append(" Url: ").Append(Url).Append("\n"); + sb.Append(" Headers: ").Append(Headers).Append("\n"); + sb.Append(" ExpiresAt: ").Append(ExpiresAt).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public partial class AttachmentUploadJsonConverter : JsonConverter + { + partial void OnCreated(); + + /// + /// Initializes a new instance of the class. + /// + public AttachmentUploadJsonConverter() + { + OnCreated(); + } + + /// + /// The format to use to serialize ExpiresAt + /// + public string ExpiresAtFormat { get; private set; } = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK"; + + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override AttachmentUpload Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option url = default; + Option?> headers = default; + Option expiresAt = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string? localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "url": + url = new Option(utf8JsonReader.GetString()!); + break; + case "headers": + headers = new Option?>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)!); + break; + case "expires_at": + expiresAt = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)); + break; + default: + break; + } + } + } + + if (!url.IsSet) + throw new JsonException("Property is required for class AttachmentUpload: url."); + + if (!headers.IsSet) + throw new JsonException("Property is required for class AttachmentUpload: headers."); + + if (!expiresAt.IsSet) + throw new JsonException("Property is required for class AttachmentUpload: expires_at."); + + if (url.IsSet && url.Value == null) + throw new JsonException("Property is not nullable for class AttachmentUpload: url."); + + if (headers.IsSet && headers.Value == null) + throw new JsonException("Property is not nullable for class AttachmentUpload: headers."); + + if (expiresAt.IsSet && expiresAt.Value == null) + throw new JsonException("Property is not nullable for class AttachmentUpload: expires_at."); + + return new AttachmentUpload(url.Value!, headers.Value!, expiresAt.Value!.Value!); + } + + /// + /// Serializes a + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentUpload attachmentUpload, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, attachmentUpload, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, AttachmentUpload attachmentUpload, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteString("url", attachmentUpload.Url); + + writer.WritePropertyName("headers"); + JsonSerializer.Serialize(writer, attachmentUpload.Headers, jsonSerializerOptions); + writer.WriteString("expires_at", attachmentUpload.ExpiresAt.ToString(ExpiresAtFormat)); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/AttachmentUploadResponse.cs b/sdk/dotnet/Timr.Api/Model/AttachmentUploadResponse.cs new file mode 100644 index 0000000..49f1077 --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/AttachmentUploadResponse.cs @@ -0,0 +1,213 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// A registered upload of a file, with the pre-signed URL to upload the file to. + /// + public partial class AttachmentUploadResponse : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// Unique identifier of the attachment. Treat it as an opaque string. + /// metadata + /// upload + [JsonConstructor] + public AttachmentUploadResponse(Guid id, AttachmentMetadata metadata, AttachmentUpload upload) + { + Id = id; + Metadata = metadata; + Upload = upload; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Unique identifier of the attachment. Treat it as an opaque string. + /// + /// Unique identifier of the attachment. Treat it as an opaque string. + /* 01972ff0-14a2-7814-926c-11d07a1dc20b */ + [JsonPropertyName("id")] + public Guid Id { get; set; } + + /// + /// Gets or Sets Metadata + /// + [JsonPropertyName("metadata")] + public AttachmentMetadata Metadata { get; set; } + + /// + /// Gets or Sets Upload + /// + [JsonPropertyName("upload")] + public AttachmentUpload Upload { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class AttachmentUploadResponse {\n"); + sb.Append(" Id: ").Append(Id).Append("\n"); + sb.Append(" Metadata: ").Append(Metadata).Append("\n"); + sb.Append(" Upload: ").Append(Upload).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public partial class AttachmentUploadResponseJsonConverter : JsonConverter + { + partial void OnCreated(); + + /// + /// Initializes a new instance of the class. + /// + public AttachmentUploadResponseJsonConverter() + { + OnCreated(); + } + + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override AttachmentUploadResponse Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option id = default; + Option metadata = default; + Option upload = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string? localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "id": + id = new Option(utf8JsonReader.TokenType == JsonTokenType.Null ? (Guid?)null : utf8JsonReader.GetGuid()); + break; + case "metadata": + metadata = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)!); + break; + case "upload": + upload = new Option(JsonSerializer.Deserialize(ref utf8JsonReader, jsonSerializerOptions)!); + break; + default: + break; + } + } + } + + if (!id.IsSet) + throw new JsonException("Property is required for class AttachmentUploadResponse: id."); + + if (!metadata.IsSet) + throw new JsonException("Property is required for class AttachmentUploadResponse: metadata."); + + if (!upload.IsSet) + throw new JsonException("Property is required for class AttachmentUploadResponse: upload."); + + if (id.IsSet && id.Value == null) + throw new JsonException("Property is not nullable for class AttachmentUploadResponse: id."); + + if (metadata.IsSet && metadata.Value == null) + throw new JsonException("Property is not nullable for class AttachmentUploadResponse: metadata."); + + if (upload.IsSet && upload.Value == null) + throw new JsonException("Property is not nullable for class AttachmentUploadResponse: upload."); + + return new AttachmentUploadResponse(id.Value!.Value!, metadata.Value!, upload.Value!); + } + + /// + /// Serializes a + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentUploadResponse attachmentUploadResponse, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, attachmentUploadResponse, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, AttachmentUploadResponse attachmentUploadResponse, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteString("id", attachmentUploadResponse.Id); + + writer.WritePropertyName("metadata"); + JsonSerializer.Serialize(writer, attachmentUploadResponse.Metadata, jsonSerializerOptions); + writer.WritePropertyName("upload"); + JsonSerializer.Serialize(writer, attachmentUploadResponse.Upload, jsonSerializerOptions); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/AttachmentsPage.cs b/sdk/dotnet/Timr.Api/Model/AttachmentsPage.cs new file mode 100644 index 0000000..263444d --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/AttachmentsPage.cs @@ -0,0 +1,190 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// AttachmentsPage + /// + public partial class AttachmentsPage : IValidatableObject + { + /// + /// Initializes a new instance of the class. + /// + /// data + /// Token for the next page, or null when this is the last page. + [JsonConstructor] + public AttachmentsPage(List data, string? nextPageToken = default) + { + Data = data; + NextPageToken = nextPageToken; + OnCreated(); + } + + partial void OnCreated(); + + /// + /// Gets or Sets Data + /// + [JsonPropertyName("data")] + public List Data { get; set; } + + /// + /// Token for the next page, or null when this is the last page. + /// + /// Token for the next page, or null when this is the last page. + [JsonPropertyName("next_page_token")] + public string? NextPageToken { get; set; } + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("class AttachmentsPage {\n"); + sb.Append(" Data: ").Append(Data).Append("\n"); + sb.Append(" NextPageToken: ").Append(NextPageToken).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + + /// + /// A Json converter for type + /// + public partial class AttachmentsPageJsonConverter : JsonConverter + { + partial void OnCreated(); + + /// + /// Initializes a new instance of the class. + /// + public AttachmentsPageJsonConverter() + { + OnCreated(); + } + + /// + /// Deserializes json to + /// + /// + /// + /// + /// + /// + public override AttachmentsPage Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert, JsonSerializerOptions jsonSerializerOptions) + { + int currentDepth = utf8JsonReader.CurrentDepth; + + if (utf8JsonReader.TokenType != JsonTokenType.StartObject && utf8JsonReader.TokenType != JsonTokenType.StartArray) + throw new JsonException(); + + JsonTokenType startingTokenType = utf8JsonReader.TokenType; + + Option?> data = default; + Option nextPageToken = default; + + while (utf8JsonReader.Read()) + { + if (startingTokenType == JsonTokenType.StartObject && utf8JsonReader.TokenType == JsonTokenType.EndObject && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (startingTokenType == JsonTokenType.StartArray && utf8JsonReader.TokenType == JsonTokenType.EndArray && currentDepth == utf8JsonReader.CurrentDepth) + break; + + if (utf8JsonReader.TokenType == JsonTokenType.PropertyName && currentDepth == utf8JsonReader.CurrentDepth - 1) + { + string? localVarJsonPropertyName = utf8JsonReader.GetString(); + utf8JsonReader.Read(); + + switch (localVarJsonPropertyName) + { + case "data": + data = new Option?>(JsonSerializer.Deserialize>(ref utf8JsonReader, jsonSerializerOptions)!); + break; + case "next_page_token": + nextPageToken = new Option(utf8JsonReader.GetString()); + break; + default: + break; + } + } + } + + if (!data.IsSet) + throw new JsonException("Property is required for class AttachmentsPage: data."); + + if (!nextPageToken.IsSet) + throw new JsonException("Property is required for class AttachmentsPage: next_page_token."); + + if (data.IsSet && data.Value == null) + throw new JsonException("Property is not nullable for class AttachmentsPage: data."); + + return new AttachmentsPage(data.Value!, nextPageToken.Value!); + } + + /// + /// Serializes a + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentsPage attachmentsPage, JsonSerializerOptions jsonSerializerOptions) + { + writer.WriteStartObject(); + + WriteProperties(writer, attachmentsPage, jsonSerializerOptions); + writer.WriteEndObject(); + } + + /// + /// Serializes the properties of + /// + /// + /// + /// + public void WriteProperties(Utf8JsonWriter writer, AttachmentsPage attachmentsPage, JsonSerializerOptions jsonSerializerOptions) + { + writer.WritePropertyName("data"); + JsonSerializer.Serialize(writer, attachmentsPage.Data, jsonSerializerOptions); + if (attachmentsPage.NextPageToken != null) + writer.WriteString("next_page_token", attachmentsPage.NextPageToken); + else + writer.WriteNull("next_page_token"); + } + } +} diff --git a/sdk/dotnet/Timr.Api/Model/AttachmentsSortColumn.cs b/sdk/dotnet/Timr.Api/Model/AttachmentsSortColumn.cs new file mode 100644 index 0000000..72c0c1e --- /dev/null +++ b/sdk/dotnet/Timr.Api/Model/AttachmentsSortColumn.cs @@ -0,0 +1,168 @@ +// +/* + * timr API + * + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * Generated by: https://github.com/openapitools/openapi-generator.git + */ + +#nullable enable + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.ComponentModel.DataAnnotations; +using Timr.Api.Client; + +namespace Timr.Api.Model +{ + /// + /// Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + /// + /// Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + public enum AttachmentsSortColumn + { + /// + /// Enum UploadedAt for value: uploaded_at + /// + UploadedAt = 1 + } + + /// + /// Converts to and from the JSON value + /// + public static class AttachmentsSortColumnValueConverter + { + /// + /// Parses a given value to + /// + /// + /// + public static AttachmentsSortColumn FromString(string value) + { + if (value.Equals("uploaded_at")) + return AttachmentsSortColumn.UploadedAt; + + throw new NotImplementedException($"Could not convert value to type AttachmentsSortColumn: '{value}'"); + } + + /// + /// Parses a given value to + /// + /// + /// + public static AttachmentsSortColumn? FromStringOrDefault(string value) + { + if (value.Equals("uploaded_at")) + return AttachmentsSortColumn.UploadedAt; + + return null; + } + + /// + /// Converts the to the json value + /// + /// + /// + /// + public static string ToJsonValue(AttachmentsSortColumn value) + { + if (value == AttachmentsSortColumn.UploadedAt) + return "uploaded_at"; + + throw new NotImplementedException($"Value could not be handled: '{value}'"); + } + } + + /// + /// A Json converter for type + /// + /// + public class AttachmentsSortColumnJsonConverter : JsonConverter + { + /// + /// Returns a from the Json object + /// + /// + /// + /// + /// + public override AttachmentsSortColumn Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + string? rawValue = reader.GetString(); + + AttachmentsSortColumn? result = rawValue == null + ? null + : AttachmentsSortColumnValueConverter.FromStringOrDefault(rawValue); + + if (result != null) + return result.Value; + + throw new JsonException(); + } + + /// + /// Writes the AttachmentsSortColumn to the json writer + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentsSortColumn attachmentsSortColumn, JsonSerializerOptions options) + { + writer.WriteStringValue(AttachmentsSortColumnValueConverter.ToJsonValue(attachmentsSortColumn).ToString()); + } + } + + /// + /// A Json converter for type + /// + public class AttachmentsSortColumnNullableJsonConverter : JsonConverter + { + /// + /// Returns a AttachmentsSortColumn from the Json object + /// + /// + /// + /// + /// + public override AttachmentsSortColumn? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.Null) + return null; + + string? rawValue = reader.GetString(); + + AttachmentsSortColumn? result = rawValue == null + ? null + : AttachmentsSortColumnValueConverter.FromStringOrDefault(rawValue); + + if (result != null) + return result.Value; + + throw new JsonException(); + } + + /// + /// Writes the AttachmentsSortColumn to the json writer + /// + /// + /// + /// + public override void Write(Utf8JsonWriter writer, AttachmentsSortColumn? attachmentsSortColumn, JsonSerializerOptions options) + { + if (attachmentsSortColumn.HasValue) + writer.WriteStringValue(AttachmentsSortColumnValueConverter.ToJsonValue(attachmentsSortColumn.Value).ToString()); + else + writer.WriteNullValue(); + } + } +} diff --git a/sdk/java-restclient/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java b/sdk/java-restclient/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java new file mode 100644 index 0000000..e1f5d3a --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java @@ -0,0 +1,441 @@ +package com.timr.api.apis; + +import com.timr.api.ApiClient; + +import com.timr.api.models.Attachment; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.AttachmentUploadResponse; +import com.timr.api.models.AttachmentsPage; +import com.timr.api.models.AttachmentsSortColumn; +import com.timr.api.models.Error; +import org.jspecify.annotations.Nullable; +import com.timr.api.models.SortDirection; +import java.net.URI; +import java.util.UUID; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClient.ResponseSpec; +import org.springframework.web.client.RestClientResponseException; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class ProjectTimeAttachmentApi { + private ApiClient apiClient; + + public ProjectTimeAttachmentApi() { + this(new ApiClient()); + } + + public ProjectTimeAttachmentApi(ApiClient apiClient) { + this.apiClient = apiClient; + } + + public ApiClient getApiClient() { + return apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; + } + + /** + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return AttachmentUploadResponse + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec createProjectTimeAttachmentRequestCreation(String projectTimeId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + Object postBody = attachmentMetadata; + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new RestClientResponseException("Missing the required parameter 'projectTimeId' when calling createProjectTimeAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // verify the required parameter 'attachmentMetadata' is set + if (attachmentMetadata == null) { + throw new RestClientResponseException("Missing the required parameter 'attachmentMetadata' when calling createProjectTimeAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("project_time_id", projectTimeId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + "application/json" + }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments", HttpMethod.POST, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return AttachmentUploadResponse + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public AttachmentUploadResponse createProjectTimeAttachment(String projectTimeId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return createProjectTimeAttachmentRequestCreation(projectTimeId, attachmentMetadata).body(localVarReturnType); + } + + /** + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return ResponseEntity<AttachmentUploadResponse> + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity createProjectTimeAttachmentWithHttpInfo(String projectTimeId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return createProjectTimeAttachmentRequestCreation(projectTimeId, attachmentMetadata).toEntity(localVarReturnType); + } + + /** + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec createProjectTimeAttachmentWithResponseSpec(String projectTimeId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + return createProjectTimeAttachmentRequestCreation(projectTimeId, attachmentMetadata); + } + + /** + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + *

422 - Unprocessable Content + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec deleteProjectTimeAttachmentRequestCreation(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + Object postBody = null; + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new RestClientResponseException("Missing the required parameter 'projectTimeId' when calling deleteProjectTimeAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new RestClientResponseException("Missing the required parameter 'attachmentId' when calling deleteProjectTimeAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("project_time_id", projectTimeId); + pathParams.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + final String[] localVarAccepts = { + "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments/{attachment_id}", HttpMethod.DELETE, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + *

422 - Unprocessable Content + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public void deleteProjectTimeAttachment(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + deleteProjectTimeAttachmentRequestCreation(projectTimeId, attachmentId).body(localVarReturnType); + } + + /** + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + *

422 - Unprocessable Content + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity deleteProjectTimeAttachmentWithHttpInfo(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return deleteProjectTimeAttachmentRequestCreation(projectTimeId, attachmentId).toEntity(localVarReturnType); + } + + /** + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + *

422 - Unprocessable Content + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec deleteProjectTimeAttachmentWithResponseSpec(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + return deleteProjectTimeAttachmentRequestCreation(projectTimeId, attachmentId); + } + + /** + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + *

200 - Page of Project Time Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return AttachmentsPage + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec fetchProjectTimeAttachmentsRequestCreation(String projectTimeId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + Object postBody = null; + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new RestClientResponseException("Missing the required parameter 'projectTimeId' when calling fetchProjectTimeAttachments", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("project_time_id", projectTimeId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "page_token", pageToken)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "limit", limit)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_direction", sortDirection)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_by", sortBy)); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments", HttpMethod.GET, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + *

200 - Page of Project Time Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return AttachmentsPage + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public AttachmentsPage fetchProjectTimeAttachments(String projectTimeId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return fetchProjectTimeAttachmentsRequestCreation(projectTimeId, pageToken, limit, sortDirection, sortBy).body(localVarReturnType); + } + + /** + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + *

200 - Page of Project Time Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return ResponseEntity<AttachmentsPage> + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity fetchProjectTimeAttachmentsWithHttpInfo(String projectTimeId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return fetchProjectTimeAttachmentsRequestCreation(projectTimeId, pageToken, limit, sortDirection, sortBy).toEntity(localVarReturnType); + } + + /** + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + *

200 - Page of Project Time Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec fetchProjectTimeAttachmentsWithResponseSpec(String projectTimeId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + return fetchProjectTimeAttachmentsRequestCreation(projectTimeId, pageToken, limit, sortDirection, sortBy); + } + + /** + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + *

200 - The requested Project Time Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return Attachment + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec getProjectTimeAttachmentRequestCreation(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + Object postBody = null; + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new RestClientResponseException("Missing the required parameter 'projectTimeId' when calling getProjectTimeAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new RestClientResponseException("Missing the required parameter 'attachmentId' when calling getProjectTimeAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("project_time_id", projectTimeId); + pathParams.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments/{attachment_id}", HttpMethod.GET, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + *

200 - The requested Project Time Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return Attachment + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public Attachment getProjectTimeAttachment(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return getProjectTimeAttachmentRequestCreation(projectTimeId, attachmentId).body(localVarReturnType); + } + + /** + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + *

200 - The requested Project Time Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return ResponseEntity<Attachment> + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity getProjectTimeAttachmentWithHttpInfo(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return getProjectTimeAttachmentRequestCreation(projectTimeId, attachmentId).toEntity(localVarReturnType); + } + + /** + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + *

200 - The requested Project Time Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec getProjectTimeAttachmentWithResponseSpec(String projectTimeId, UUID attachmentId) throws RestClientResponseException { + return getProjectTimeAttachmentRequestCreation(projectTimeId, attachmentId); + } +} diff --git a/sdk/java-restclient/src/main/java/com/timr/api/apis/TaskAttachmentApi.java b/sdk/java-restclient/src/main/java/com/timr/api/apis/TaskAttachmentApi.java new file mode 100644 index 0000000..8895249 --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/apis/TaskAttachmentApi.java @@ -0,0 +1,437 @@ +package com.timr.api.apis; + +import com.timr.api.ApiClient; + +import com.timr.api.models.Attachment; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.AttachmentUploadResponse; +import com.timr.api.models.AttachmentsPage; +import com.timr.api.models.AttachmentsSortColumn; +import com.timr.api.models.Error; +import org.jspecify.annotations.Nullable; +import com.timr.api.models.SortDirection; +import java.net.URI; +import java.util.UUID; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClient.ResponseSpec; +import org.springframework.web.client.RestClientResponseException; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class TaskAttachmentApi { + private ApiClient apiClient; + + public TaskAttachmentApi() { + this(new ApiClient()); + } + + public TaskAttachmentApi(ApiClient apiClient) { + this.apiClient = apiClient; + } + + public ApiClient getApiClient() { + return apiClient; + } + + public void setApiClient(ApiClient apiClient) { + this.apiClient = apiClient; + } + + /** + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return AttachmentUploadResponse + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec createTaskAttachmentRequestCreation(String taskId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + Object postBody = attachmentMetadata; + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new RestClientResponseException("Missing the required parameter 'taskId' when calling createTaskAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // verify the required parameter 'attachmentMetadata' is set + if (attachmentMetadata == null) { + throw new RestClientResponseException("Missing the required parameter 'attachmentMetadata' when calling createTaskAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("task_id", taskId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + "application/json" + }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments", HttpMethod.POST, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return AttachmentUploadResponse + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public AttachmentUploadResponse createTaskAttachment(String taskId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return createTaskAttachmentRequestCreation(taskId, attachmentMetadata).body(localVarReturnType); + } + + /** + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return ResponseEntity<AttachmentUploadResponse> + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity createTaskAttachmentWithHttpInfo(String taskId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return createTaskAttachmentRequestCreation(taskId, attachmentMetadata).toEntity(localVarReturnType); + } + + /** + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec createTaskAttachmentWithResponseSpec(String taskId, AttachmentMetadata attachmentMetadata) throws RestClientResponseException { + return createTaskAttachmentRequestCreation(taskId, attachmentMetadata); + } + + /** + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec deleteTaskAttachmentRequestCreation(String taskId, UUID attachmentId) throws RestClientResponseException { + Object postBody = null; + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new RestClientResponseException("Missing the required parameter 'taskId' when calling deleteTaskAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new RestClientResponseException("Missing the required parameter 'attachmentId' when calling deleteTaskAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("task_id", taskId); + pathParams.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + final String[] localVarAccepts = { + "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments/{attachment_id}", HttpMethod.DELETE, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public void deleteTaskAttachment(String taskId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + deleteTaskAttachmentRequestCreation(taskId, attachmentId).body(localVarReturnType); + } + + /** + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity deleteTaskAttachmentWithHttpInfo(String taskId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return deleteTaskAttachmentRequestCreation(taskId, attachmentId).toEntity(localVarReturnType); + } + + /** + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec deleteTaskAttachmentWithResponseSpec(String taskId, UUID attachmentId) throws RestClientResponseException { + return deleteTaskAttachmentRequestCreation(taskId, attachmentId); + } + + /** + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + *

200 - Page of Task Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return AttachmentsPage + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec fetchTaskAttachmentsRequestCreation(String taskId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + Object postBody = null; + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new RestClientResponseException("Missing the required parameter 'taskId' when calling fetchTaskAttachments", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("task_id", taskId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "page_token", pageToken)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "limit", limit)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_direction", sortDirection)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_by", sortBy)); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments", HttpMethod.GET, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + *

200 - Page of Task Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return AttachmentsPage + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public AttachmentsPage fetchTaskAttachments(String taskId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return fetchTaskAttachmentsRequestCreation(taskId, pageToken, limit, sortDirection, sortBy).body(localVarReturnType); + } + + /** + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + *

200 - Page of Task Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return ResponseEntity<AttachmentsPage> + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity fetchTaskAttachmentsWithHttpInfo(String taskId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return fetchTaskAttachmentsRequestCreation(taskId, pageToken, limit, sortDirection, sortBy).toEntity(localVarReturnType); + } + + /** + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + *

200 - Page of Task Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. + * @param sortDirection Direction to sort the entries in. + * @param sortBy Property to sort the entries by. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec fetchTaskAttachmentsWithResponseSpec(String taskId, @Nullable String pageToken, @Nullable Integer limit, @Nullable SortDirection sortDirection, @Nullable AttachmentsSortColumn sortBy) throws RestClientResponseException { + return fetchTaskAttachmentsRequestCreation(taskId, pageToken, limit, sortDirection, sortBy); + } + + /** + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + *

200 - The requested Task Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return Attachment + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + private ResponseSpec getTaskAttachmentRequestCreation(String taskId, UUID attachmentId) throws RestClientResponseException { + Object postBody = null; + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new RestClientResponseException("Missing the required parameter 'taskId' when calling getTaskAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new RestClientResponseException("Missing the required parameter 'attachmentId' when calling getTaskAttachment", HttpStatus.BAD_REQUEST.value(), HttpStatus.BAD_REQUEST.getReasonPhrase(), null, null, null); + } + // create path and map variables + final Map pathParams = new HashMap<>(); + + pathParams.put("task_id", taskId); + pathParams.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap<>(); + final HttpHeaders headerParams = new HttpHeaders(); + final MultiValueMap cookieParams = new LinkedMultiValueMap<>(); + final MultiValueMap formParams = new LinkedMultiValueMap<>(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments/{attachment_id}", HttpMethod.GET, pathParams, localVarQueryParams, postBody, headerParams, cookieParams, formParams, localVarAccept, localVarContentType, localVarAuthNames, localVarReturnType); + } + + /** + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + *

200 - The requested Task Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return Attachment + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public Attachment getTaskAttachment(String taskId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return getTaskAttachmentRequestCreation(taskId, attachmentId).body(localVarReturnType); + } + + /** + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + *

200 - The requested Task Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return ResponseEntity<Attachment> + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseEntity getTaskAttachmentWithHttpInfo(String taskId, UUID attachmentId) throws RestClientResponseException { + ParameterizedTypeReference localVarReturnType = new ParameterizedTypeReference<>() {}; + return getTaskAttachmentRequestCreation(taskId, attachmentId).toEntity(localVarReturnType); + } + + /** + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + *

200 - The requested Task Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return ResponseSpec + * @throws RestClientResponseException if an error occurs while attempting to invoke the API + */ + public ResponseSpec getTaskAttachmentWithResponseSpec(String taskId, UUID attachmentId) throws RestClientResponseException { + return getTaskAttachmentRequestCreation(taskId, attachmentId); + } +} diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/Attachment.java b/sdk/java-restclient/src/main/java/com/timr/api/models/Attachment.java new file mode 100644 index 0000000..d4c6ffe --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/Attachment.java @@ -0,0 +1,249 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.timr.api.models.AttachmentDownload; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.UserPartial; +import java.time.OffsetDateTime; +import java.util.UUID; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + */ +@JsonPropertyOrder({ + Attachment.JSON_PROPERTY_ID, + Attachment.JSON_PROPERTY_DOWNLOAD, + Attachment.JSON_PROPERTY_METADATA, + Attachment.JSON_PROPERTY_UPLOADED_BY, + Attachment.JSON_PROPERTY_UPLOADED_AT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Attachment { + public static final String JSON_PROPERTY_ID = "id"; + + private UUID id; + + public static final String JSON_PROPERTY_DOWNLOAD = "download"; + + private @Nullable AttachmentDownload download; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + + private AttachmentMetadata metadata; + + public static final String JSON_PROPERTY_UPLOADED_BY = "uploaded_by"; + + private @Nullable UserPartial uploadedBy; + + public static final String JSON_PROPERTY_UPLOADED_AT = "uploaded_at"; + + private OffsetDateTime uploadedAt; + + public Attachment() { + } + + public Attachment id(UUID id) { + + this.id = id; + return this; + } + + /** + * Unique identifier. Treat it as an opaque string. + * @return id + */ + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public UUID getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(UUID id) { + this.id = id; + } + + + public Attachment download(@Nullable AttachmentDownload download) { + + this.download = download; + return this; + } + + /** + * Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + * @return download + */ + + @JsonProperty(value = JSON_PROPERTY_DOWNLOAD, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public @Nullable AttachmentDownload getDownload() { + return download; + } + + + @JsonProperty(value = JSON_PROPERTY_DOWNLOAD, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setDownload(@Nullable AttachmentDownload download) { + this.download = download; + } + + + public Attachment metadata(AttachmentMetadata metadata) { + + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + */ + + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentMetadata getMetadata() { + return metadata; + } + + + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMetadata(AttachmentMetadata metadata) { + this.metadata = metadata; + } + + + public Attachment uploadedBy(@Nullable UserPartial uploadedBy) { + + this.uploadedBy = uploadedBy; + return this; + } + + /** + * The User who uploaded the file, or null if that User no longer exists. + * @return uploadedBy + */ + + @JsonProperty(value = JSON_PROPERTY_UPLOADED_BY, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public @Nullable UserPartial getUploadedBy() { + return uploadedBy; + } + + + @JsonProperty(value = JSON_PROPERTY_UPLOADED_BY, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUploadedBy(@Nullable UserPartial uploadedBy) { + this.uploadedBy = uploadedBy; + } + + + public Attachment uploadedAt(OffsetDateTime uploadedAt) { + + this.uploadedAt = uploadedAt; + return this; + } + + /** + * When the upload of the file completed. RFC 3339 date-time (ISO-8601) + * @return uploadedAt + */ + + @JsonProperty(value = JSON_PROPERTY_UPLOADED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OffsetDateTime getUploadedAt() { + return uploadedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_UPLOADED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUploadedAt(OffsetDateTime uploadedAt) { + this.uploadedAt = uploadedAt; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Attachment attachment = (Attachment) o; + return Objects.equals(this.id, attachment.id) && + Objects.equals(this.download, attachment.download) && + Objects.equals(this.metadata, attachment.metadata) && + Objects.equals(this.uploadedBy, attachment.uploadedBy) && + Objects.equals(this.uploadedAt, attachment.uploadedAt); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(id, download, metadata, uploadedBy, uploadedAt); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Attachment {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentDownload.java b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentDownload.java new file mode 100644 index 0000000..58757e7 --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentDownload.java @@ -0,0 +1,116 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. + */ +@JsonPropertyOrder({ + AttachmentDownload.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentDownload { + public static final String JSON_PROPERTY_URL = "url"; + + private String url; + + public AttachmentDownload() { + } + + public AttachmentDownload url(String url) { + + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(String url) { + this.url = url; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentDownload attachmentDownload = (AttachmentDownload) o; + return Objects.equals(this.url, attachmentDownload.url); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(url); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentDownload {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentMetadata.java b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentMetadata.java new file mode 100644 index 0000000..c8323f6 --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentMetadata.java @@ -0,0 +1,213 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * Metadata of the attached file, as provided when it was uploaded. + */ +@JsonPropertyOrder({ + AttachmentMetadata.JSON_PROPERTY_FILE_NAME, + AttachmentMetadata.JSON_PROPERTY_CONTENT_TYPE, + AttachmentMetadata.JSON_PROPERTY_SIZE, + AttachmentMetadata.JSON_PROPERTY_FILE_LAST_MODIFIED +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentMetadata { + public static final String JSON_PROPERTY_FILE_NAME = "file_name"; + + private String fileName; + + public static final String JSON_PROPERTY_CONTENT_TYPE = "content_type"; + + private String contentType; + + public static final String JSON_PROPERTY_SIZE = "size"; + + private Long size; + + public static final String JSON_PROPERTY_FILE_LAST_MODIFIED = "file_last_modified"; + + private OffsetDateTime fileLastModified; + + public AttachmentMetadata() { + } + + public AttachmentMetadata fileName(String fileName) { + + this.fileName = fileName; + return this; + } + + /** + * Get fileName + * @return fileName + */ + + @JsonProperty(value = JSON_PROPERTY_FILE_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getFileName() { + return fileName; + } + + + @JsonProperty(value = JSON_PROPERTY_FILE_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFileName(String fileName) { + this.fileName = fileName; + } + + + public AttachmentMetadata contentType(String contentType) { + + this.contentType = contentType; + return this; + } + + /** + * Media type of the file. + * @return contentType + */ + + @JsonProperty(value = JSON_PROPERTY_CONTENT_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getContentType() { + return contentType; + } + + + @JsonProperty(value = JSON_PROPERTY_CONTENT_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setContentType(String contentType) { + this.contentType = contentType; + } + + + public AttachmentMetadata size(Long size) { + + this.size = size; + return this; + } + + /** + * Size of the file in bytes. + * @return size + */ + + @JsonProperty(value = JSON_PROPERTY_SIZE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getSize() { + return size; + } + + + @JsonProperty(value = JSON_PROPERTY_SIZE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSize(Long size) { + this.size = size; + } + + + public AttachmentMetadata fileLastModified(OffsetDateTime fileLastModified) { + + this.fileLastModified = fileLastModified; + return this; + } + + /** + * When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + * @return fileLastModified + */ + + @JsonProperty(value = JSON_PROPERTY_FILE_LAST_MODIFIED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OffsetDateTime getFileLastModified() { + return fileLastModified; + } + + + @JsonProperty(value = JSON_PROPERTY_FILE_LAST_MODIFIED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFileLastModified(OffsetDateTime fileLastModified) { + this.fileLastModified = fileLastModified; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentMetadata attachmentMetadata = (AttachmentMetadata) o; + return Objects.equals(this.fileName, attachmentMetadata.fileName) && + Objects.equals(this.contentType, attachmentMetadata.contentType) && + Objects.equals(this.size, attachmentMetadata.size) && + Objects.equals(this.fileLastModified, attachmentMetadata.fileLastModified); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(fileName, contentType, size, fileLastModified); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentMetadata {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUpload.java b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUpload.java new file mode 100644 index 0000000..2405d22 --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUpload.java @@ -0,0 +1,188 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.Map; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. + */ +@JsonPropertyOrder({ + AttachmentUpload.JSON_PROPERTY_URL, + AttachmentUpload.JSON_PROPERTY_HEADERS, + AttachmentUpload.JSON_PROPERTY_EXPIRES_AT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentUpload { + public static final String JSON_PROPERTY_URL = "url"; + + private String url; + + public static final String JSON_PROPERTY_HEADERS = "headers"; + + private Map headers; + + public static final String JSON_PROPERTY_EXPIRES_AT = "expires_at"; + + private OffsetDateTime expiresAt; + + public AttachmentUpload() { + } + + public AttachmentUpload url(String url) { + + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(String url) { + this.url = url; + } + + + public AttachmentUpload headers(Map headers) { + + this.headers = headers; + return this; + } + + public AttachmentUpload putHeadersItem(String key, String headersItem) { + this.headers.put(key, headersItem); + return this; + } + + /** + * Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + * @return headers + */ + + @JsonProperty(value = JSON_PROPERTY_HEADERS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Map getHeaders() { + return headers; + } + + + @JsonProperty(value = JSON_PROPERTY_HEADERS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHeaders(Map headers) { + this.headers = headers; + } + + + public AttachmentUpload expiresAt(OffsetDateTime expiresAt) { + + this.expiresAt = expiresAt; + return this; + } + + /** + * When the URL stops being valid. RFC 3339 date-time (ISO-8601) + * @return expiresAt + */ + + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OffsetDateTime getExpiresAt() { + return expiresAt; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setExpiresAt(OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentUpload attachmentUpload = (AttachmentUpload) o; + return Objects.equals(this.url, attachmentUpload.url) && + Objects.equals(this.headers, attachmentUpload.headers) && + Objects.equals(this.expiresAt, attachmentUpload.expiresAt); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(url, headers, expiresAt); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentUpload {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUploadResponse.java b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUploadResponse.java new file mode 100644 index 0000000..fd3ba39 --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentUploadResponse.java @@ -0,0 +1,183 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.AttachmentUpload; +import java.util.UUID; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * A registered upload of a file, with the pre-signed URL to upload the file to. + */ +@JsonPropertyOrder({ + AttachmentUploadResponse.JSON_PROPERTY_ID, + AttachmentUploadResponse.JSON_PROPERTY_METADATA, + AttachmentUploadResponse.JSON_PROPERTY_UPLOAD +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentUploadResponse { + public static final String JSON_PROPERTY_ID = "id"; + + private UUID id; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + + private AttachmentMetadata metadata; + + public static final String JSON_PROPERTY_UPLOAD = "upload"; + + private AttachmentUpload upload; + + public AttachmentUploadResponse() { + } + + public AttachmentUploadResponse id(UUID id) { + + this.id = id; + return this; + } + + /** + * Unique identifier of the attachment. Treat it as an opaque string. + * @return id + */ + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public UUID getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(UUID id) { + this.id = id; + } + + + public AttachmentUploadResponse metadata(AttachmentMetadata metadata) { + + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + */ + + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentMetadata getMetadata() { + return metadata; + } + + + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMetadata(AttachmentMetadata metadata) { + this.metadata = metadata; + } + + + public AttachmentUploadResponse upload(AttachmentUpload upload) { + + this.upload = upload; + return this; + } + + /** + * Get upload + * @return upload + */ + + @JsonProperty(value = JSON_PROPERTY_UPLOAD, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentUpload getUpload() { + return upload; + } + + + @JsonProperty(value = JSON_PROPERTY_UPLOAD, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUpload(AttachmentUpload upload) { + this.upload = upload; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentUploadResponse attachmentUploadResponse = (AttachmentUploadResponse) o; + return Objects.equals(this.id, attachmentUploadResponse.id) && + Objects.equals(this.metadata, attachmentUploadResponse.metadata) && + Objects.equals(this.upload, attachmentUploadResponse.upload); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(id, metadata, upload); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentUploadResponse {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsPage.java b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsPage.java new file mode 100644 index 0000000..17f107e --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsPage.java @@ -0,0 +1,160 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.timr.api.models.Attachment; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * AttachmentsPage + */ +@JsonPropertyOrder({ + AttachmentsPage.JSON_PROPERTY_NEXT_PAGE_TOKEN, + AttachmentsPage.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentsPage { + public static final String JSON_PROPERTY_NEXT_PAGE_TOKEN = "next_page_token"; + + private @Nullable String nextPageToken; + + public static final String JSON_PROPERTY_DATA = "data"; + + private List data; + + public AttachmentsPage() { + } + + public AttachmentsPage nextPageToken(@Nullable String nextPageToken) { + + this.nextPageToken = nextPageToken; + return this; + } + + /** + * Token for the next page, or null when this is the last page. + * @return nextPageToken + */ + + @JsonProperty(value = JSON_PROPERTY_NEXT_PAGE_TOKEN, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public @Nullable String getNextPageToken() { + return nextPageToken; + } + + + @JsonProperty(value = JSON_PROPERTY_NEXT_PAGE_TOKEN, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNextPageToken(@Nullable String nextPageToken) { + this.nextPageToken = nextPageToken; + } + + + public AttachmentsPage data(List data) { + + this.data = data; + return this; + } + + public AttachmentsPage addDataItem(Attachment dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(List data) { + this.data = data; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentsPage attachmentsPage = (AttachmentsPage) o; + return Objects.equals(this.nextPageToken, attachmentsPage.nextPageToken) && + Objects.equals(this.data, attachmentsPage.data); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(nextPageToken, data); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentsPage {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsSortColumn.java b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsSortColumn.java new file mode 100644 index 0000000..8d53cfc --- /dev/null +++ b/sdk/java-restclient/src/main/java/com/timr/api/models/AttachmentsSortColumn.java @@ -0,0 +1,58 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import org.jspecify.annotations.Nullable; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + */ +public enum AttachmentsSortColumn { + + UPLOADED_AT("uploaded_at"); + + private String value; + + AttachmentsSortColumn(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static AttachmentsSortColumn fromValue(String value) { + for (AttachmentsSortColumn b : AttachmentsSortColumn.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java b/sdk/java-resttemplate/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java new file mode 100644 index 0000000..c0e938d --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/apis/ProjectTimeAttachmentApi.java @@ -0,0 +1,327 @@ +package com.timr.api.apis; + +import com.timr.api.ApiClient; +import com.timr.api.BaseApi; + +import com.timr.api.models.Attachment; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.AttachmentUploadResponse; +import com.timr.api.models.AttachmentsPage; +import com.timr.api.models.AttachmentsSortColumn; +import com.timr.api.models.Error; +import com.timr.api.models.SortDirection; +import java.net.URI; +import java.util.UUID; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +@Component("com.timr.api.apis.ProjectTimeAttachmentApi") +public class ProjectTimeAttachmentApi extends BaseApi { + + public ProjectTimeAttachmentApi() { + super(new ApiClient()); + } + + @Autowired + public ProjectTimeAttachmentApi(ApiClient apiClient) { + super(apiClient); + } + + /** + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. (required) + * @param attachmentMetadata Metadata of the file to upload. (required) + * @return AttachmentUploadResponse + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public AttachmentUploadResponse createProjectTimeAttachment(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nonnull AttachmentMetadata attachmentMetadata) throws RestClientException { + return createProjectTimeAttachmentWithHttpInfo(projectTimeId, attachmentMetadata).getBody(); + } + + /** + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. (required) + * @param attachmentMetadata Metadata of the file to upload. (required) + * @return ResponseEntity<AttachmentUploadResponse> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity createProjectTimeAttachmentWithHttpInfo(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nonnull AttachmentMetadata attachmentMetadata) throws RestClientException { + Object localVarPostBody = attachmentMetadata; + + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'projectTimeId' when calling createProjectTimeAttachment"); + } + + // verify the required parameter 'attachmentMetadata' is set + if (attachmentMetadata == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'attachmentMetadata' when calling createProjectTimeAttachment"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("project_time_id", projectTimeId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + "application/json" + }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments", HttpMethod.POST, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + /** + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + *

422 - Unprocessable Content + * @param projectTimeId ID of the Project Time. (required) + * @param attachmentId ID of the Project Time Attachment. (required) + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public void deleteProjectTimeAttachment(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + deleteProjectTimeAttachmentWithHttpInfo(projectTimeId, attachmentId); + } + + /** + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + *

422 - Unprocessable Content + * @param projectTimeId ID of the Project Time. (required) + * @param attachmentId ID of the Project Time Attachment. (required) + * @return ResponseEntity<Void> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity deleteProjectTimeAttachmentWithHttpInfo(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + Object localVarPostBody = null; + + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'projectTimeId' when calling deleteProjectTimeAttachment"); + } + + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'attachmentId' when calling deleteProjectTimeAttachment"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("project_time_id", projectTimeId); + uriVariables.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments/{attachment_id}", HttpMethod.DELETE, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + /** + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + *

200 - Page of Project Time Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. (required) + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional, default to asc) + * @param sortBy Property to sort the entries by. (optional, default to uploaded_at) + * @return AttachmentsPage + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public AttachmentsPage fetchProjectTimeAttachments(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nullable String pageToken, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable SortDirection sortDirection, @jakarta.annotation.Nullable AttachmentsSortColumn sortBy) throws RestClientException { + return fetchProjectTimeAttachmentsWithHttpInfo(projectTimeId, pageToken, limit, sortDirection, sortBy).getBody(); + } + + /** + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + *

200 - Page of Project Time Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. (required) + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional, default to asc) + * @param sortBy Property to sort the entries by. (optional, default to uploaded_at) + * @return ResponseEntity<AttachmentsPage> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity fetchProjectTimeAttachmentsWithHttpInfo(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nullable String pageToken, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable SortDirection sortDirection, @jakarta.annotation.Nullable AttachmentsSortColumn sortBy) throws RestClientException { + Object localVarPostBody = null; + + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'projectTimeId' when calling fetchProjectTimeAttachments"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("project_time_id", projectTimeId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "page_token", pageToken)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "limit", limit)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_direction", sortDirection)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_by", sortBy)); + + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments", HttpMethod.GET, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + /** + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + *

200 - The requested Project Time Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. (required) + * @param attachmentId ID of the Project Time Attachment. (required) + * @return Attachment + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public Attachment getProjectTimeAttachment(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + return getProjectTimeAttachmentWithHttpInfo(projectTimeId, attachmentId).getBody(); + } + + /** + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + *

200 - The requested Project Time Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param projectTimeId ID of the Project Time. (required) + * @param attachmentId ID of the Project Time Attachment. (required) + * @return ResponseEntity<Attachment> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity getProjectTimeAttachmentWithHttpInfo(@jakarta.annotation.Nonnull String projectTimeId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + Object localVarPostBody = null; + + // verify the required parameter 'projectTimeId' is set + if (projectTimeId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'projectTimeId' when calling getProjectTimeAttachment"); + } + + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'attachmentId' when calling getProjectTimeAttachment"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("project_time_id", projectTimeId); + uriVariables.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/project-times/{project_time_id}/attachments/{attachment_id}", HttpMethod.GET, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + + @Override + public ResponseEntity invokeAPI(String url, HttpMethod method, Object request, ParameterizedTypeReference returnType) throws RestClientException { + String localVarPath = url.replace(apiClient.getBasePath(), ""); + Object localVarPostBody = request; + + final Map uriVariables = new HashMap(); + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + return apiClient.invokeAPI(localVarPath, method, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, returnType); + } +} diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/apis/TaskAttachmentApi.java b/sdk/java-resttemplate/src/main/java/com/timr/api/apis/TaskAttachmentApi.java new file mode 100644 index 0000000..29d974f --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/apis/TaskAttachmentApi.java @@ -0,0 +1,325 @@ +package com.timr.api.apis; + +import com.timr.api.ApiClient; +import com.timr.api.BaseApi; + +import com.timr.api.models.Attachment; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.AttachmentUploadResponse; +import com.timr.api.models.AttachmentsPage; +import com.timr.api.models.AttachmentsSortColumn; +import com.timr.api.models.Error; +import com.timr.api.models.SortDirection; +import java.net.URI; +import java.util.UUID; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +@Component("com.timr.api.apis.TaskAttachmentApi") +public class TaskAttachmentApi extends BaseApi { + + public TaskAttachmentApi() { + super(new ApiClient()); + } + + @Autowired + public TaskAttachmentApi(ApiClient apiClient) { + super(apiClient); + } + + /** + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param attachmentMetadata Metadata of the file to upload. (required) + * @return AttachmentUploadResponse + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public AttachmentUploadResponse createTaskAttachment(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nonnull AttachmentMetadata attachmentMetadata) throws RestClientException { + return createTaskAttachmentWithHttpInfo(taskId, attachmentMetadata).getBody(); + } + + /** + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + *

201 - The registered upload with the URL to upload the file to. + *

400 - Bad Request + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param attachmentMetadata Metadata of the file to upload. (required) + * @return ResponseEntity<AttachmentUploadResponse> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity createTaskAttachmentWithHttpInfo(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nonnull AttachmentMetadata attachmentMetadata) throws RestClientException { + Object localVarPostBody = attachmentMetadata; + + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'taskId' when calling createTaskAttachment"); + } + + // verify the required parameter 'attachmentMetadata' is set + if (attachmentMetadata == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'attachmentMetadata' when calling createTaskAttachment"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("task_id", taskId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { + "application/json" + }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments", HttpMethod.POST, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + /** + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param attachmentId ID of the Task Attachment. (required) + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public void deleteTaskAttachment(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + deleteTaskAttachmentWithHttpInfo(taskId, attachmentId); + } + + /** + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + *

204 - Deleted. No content is returned. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param attachmentId ID of the Task Attachment. (required) + * @return ResponseEntity<Void> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity deleteTaskAttachmentWithHttpInfo(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + Object localVarPostBody = null; + + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'taskId' when calling deleteTaskAttachment"); + } + + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'attachmentId' when calling deleteTaskAttachment"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("task_id", taskId); + uriVariables.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments/{attachment_id}", HttpMethod.DELETE, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + /** + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + *

200 - Page of Task Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional, default to asc) + * @param sortBy Property to sort the entries by. (optional, default to uploaded_at) + * @return AttachmentsPage + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public AttachmentsPage fetchTaskAttachments(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nullable String pageToken, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable SortDirection sortDirection, @jakarta.annotation.Nullable AttachmentsSortColumn sortBy) throws RestClientException { + return fetchTaskAttachmentsWithHttpInfo(taskId, pageToken, limit, sortDirection, sortBy).getBody(); + } + + /** + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + *

200 - Page of Task Attachments. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional, default to asc) + * @param sortBy Property to sort the entries by. (optional, default to uploaded_at) + * @return ResponseEntity<AttachmentsPage> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity fetchTaskAttachmentsWithHttpInfo(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nullable String pageToken, @jakarta.annotation.Nullable Integer limit, @jakarta.annotation.Nullable SortDirection sortDirection, @jakarta.annotation.Nullable AttachmentsSortColumn sortBy) throws RestClientException { + Object localVarPostBody = null; + + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'taskId' when calling fetchTaskAttachments"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("task_id", taskId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "page_token", pageToken)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "limit", limit)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_direction", sortDirection)); + localVarQueryParams.putAll(apiClient.parameterToMultiValueMap(null, "sort_by", sortBy)); + + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments", HttpMethod.GET, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + /** + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + *

200 - The requested Task Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param attachmentId ID of the Task Attachment. (required) + * @return Attachment + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public Attachment getTaskAttachment(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + return getTaskAttachmentWithHttpInfo(taskId, attachmentId).getBody(); + } + + /** + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + *

200 - The requested Task Attachment. + *

403 - Forbidden + *

404 - Not Found + * @param taskId ID of the Task. (required) + * @param attachmentId ID of the Task Attachment. (required) + * @return ResponseEntity<Attachment> + * @throws RestClientException if an error occurs while attempting to invoke the API + */ + public ResponseEntity getTaskAttachmentWithHttpInfo(@jakarta.annotation.Nonnull String taskId, @jakarta.annotation.Nonnull UUID attachmentId) throws RestClientException { + Object localVarPostBody = null; + + // verify the required parameter 'taskId' is set + if (taskId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'taskId' when calling getTaskAttachment"); + } + + // verify the required parameter 'attachmentId' is set + if (attachmentId == null) { + throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'attachmentId' when calling getTaskAttachment"); + } + + // create path and map variables + final Map uriVariables = new HashMap(); + uriVariables.put("task_id", taskId); + uriVariables.put("attachment_id", attachmentId); + + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + ParameterizedTypeReference localReturnType = new ParameterizedTypeReference() {}; + return apiClient.invokeAPI("/tasks/{task_id}/attachments/{attachment_id}", HttpMethod.GET, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, localReturnType); + } + + @Override + public ResponseEntity invokeAPI(String url, HttpMethod method, Object request, ParameterizedTypeReference returnType) throws RestClientException { + String localVarPath = url.replace(apiClient.getBasePath(), ""); + Object localVarPostBody = request; + + final Map uriVariables = new HashMap(); + final MultiValueMap localVarQueryParams = new LinkedMultiValueMap(); + final HttpHeaders localVarHeaderParams = new HttpHeaders(); + final MultiValueMap localVarCookieParams = new LinkedMultiValueMap(); + final MultiValueMap localVarFormParams = new LinkedMultiValueMap(); + + final String[] localVarAccepts = { + "application/json", "application/problem+json" + }; + final List localVarAccept = apiClient.selectHeaderAccept(localVarAccepts); + final String[] localVarContentTypes = { }; + final MediaType localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes); + + String[] localVarAuthNames = new String[] { "OAuth2", "OAuth2" }; + + return apiClient.invokeAPI(localVarPath, method, uriVariables, localVarQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAccept, localVarContentType, localVarAuthNames, returnType); + } +} diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/Attachment.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/Attachment.java new file mode 100644 index 0000000..148fcd3 --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/Attachment.java @@ -0,0 +1,248 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.timr.api.models.AttachmentDownload; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.UserPartial; +import java.time.OffsetDateTime; +import java.util.UUID; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + */ +@JsonPropertyOrder({ + Attachment.JSON_PROPERTY_ID, + Attachment.JSON_PROPERTY_DOWNLOAD, + Attachment.JSON_PROPERTY_METADATA, + Attachment.JSON_PROPERTY_UPLOADED_BY, + Attachment.JSON_PROPERTY_UPLOADED_AT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class Attachment { + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private UUID id; + + public static final String JSON_PROPERTY_DOWNLOAD = "download"; + @jakarta.annotation.Nullable + private AttachmentDownload download; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + @jakarta.annotation.Nonnull + private AttachmentMetadata metadata; + + public static final String JSON_PROPERTY_UPLOADED_BY = "uploaded_by"; + @jakarta.annotation.Nullable + private UserPartial uploadedBy; + + public static final String JSON_PROPERTY_UPLOADED_AT = "uploaded_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime uploadedAt; + + public Attachment() { + } + + public Attachment id(@jakarta.annotation.Nonnull UUID id) { + + this.id = id; + return this; + } + + /** + * Unique identifier. Treat it as an opaque string. + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public UUID getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull UUID id) { + this.id = id; + } + + + public Attachment download(@jakarta.annotation.Nullable AttachmentDownload download) { + + this.download = download; + return this; + } + + /** + * Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + * @return download + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_DOWNLOAD, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentDownload getDownload() { + return download; + } + + + @JsonProperty(value = JSON_PROPERTY_DOWNLOAD, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setDownload(@jakarta.annotation.Nullable AttachmentDownload download) { + this.download = download; + } + + + public Attachment metadata(@jakarta.annotation.Nonnull AttachmentMetadata metadata) { + + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentMetadata getMetadata() { + return metadata; + } + + + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMetadata(@jakarta.annotation.Nonnull AttachmentMetadata metadata) { + this.metadata = metadata; + } + + + public Attachment uploadedBy(@jakarta.annotation.Nullable UserPartial uploadedBy) { + + this.uploadedBy = uploadedBy; + return this; + } + + /** + * The User who uploaded the file, or null if that User no longer exists. + * @return uploadedBy + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_UPLOADED_BY, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public UserPartial getUploadedBy() { + return uploadedBy; + } + + + @JsonProperty(value = JSON_PROPERTY_UPLOADED_BY, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUploadedBy(@jakarta.annotation.Nullable UserPartial uploadedBy) { + this.uploadedBy = uploadedBy; + } + + + public Attachment uploadedAt(@jakarta.annotation.Nonnull OffsetDateTime uploadedAt) { + + this.uploadedAt = uploadedAt; + return this; + } + + /** + * When the upload of the file completed. RFC 3339 date-time (ISO-8601) + * @return uploadedAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_UPLOADED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OffsetDateTime getUploadedAt() { + return uploadedAt; + } + + + @JsonProperty(value = JSON_PROPERTY_UPLOADED_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUploadedAt(@jakarta.annotation.Nonnull OffsetDateTime uploadedAt) { + this.uploadedAt = uploadedAt; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Attachment attachment = (Attachment) o; + return Objects.equals(this.id, attachment.id) && + Objects.equals(this.download, attachment.download) && + Objects.equals(this.metadata, attachment.metadata) && + Objects.equals(this.uploadedBy, attachment.uploadedBy) && + Objects.equals(this.uploadedAt, attachment.uploadedAt); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(id, download, metadata, uploadedBy, uploadedAt); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class Attachment {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentDownload.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentDownload.java new file mode 100644 index 0000000..0f0cd5b --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentDownload.java @@ -0,0 +1,115 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. + */ +@JsonPropertyOrder({ + AttachmentDownload.JSON_PROPERTY_URL +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentDownload { + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private String url; + + public AttachmentDownload() { + } + + public AttachmentDownload url(@jakarta.annotation.Nonnull String url) { + + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull String url) { + this.url = url; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentDownload attachmentDownload = (AttachmentDownload) o; + return Objects.equals(this.url, attachmentDownload.url); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(url); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentDownload {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentMetadata.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentMetadata.java new file mode 100644 index 0000000..0a8334b --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentMetadata.java @@ -0,0 +1,212 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * Metadata of the attached file, as provided when it was uploaded. + */ +@JsonPropertyOrder({ + AttachmentMetadata.JSON_PROPERTY_FILE_NAME, + AttachmentMetadata.JSON_PROPERTY_CONTENT_TYPE, + AttachmentMetadata.JSON_PROPERTY_SIZE, + AttachmentMetadata.JSON_PROPERTY_FILE_LAST_MODIFIED +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentMetadata { + public static final String JSON_PROPERTY_FILE_NAME = "file_name"; + @jakarta.annotation.Nonnull + private String fileName; + + public static final String JSON_PROPERTY_CONTENT_TYPE = "content_type"; + @jakarta.annotation.Nonnull + private String contentType; + + public static final String JSON_PROPERTY_SIZE = "size"; + @jakarta.annotation.Nonnull + private Long size; + + public static final String JSON_PROPERTY_FILE_LAST_MODIFIED = "file_last_modified"; + @jakarta.annotation.Nonnull + private OffsetDateTime fileLastModified; + + public AttachmentMetadata() { + } + + public AttachmentMetadata fileName(@jakarta.annotation.Nonnull String fileName) { + + this.fileName = fileName; + return this; + } + + /** + * Get fileName + * @return fileName + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_FILE_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getFileName() { + return fileName; + } + + + @JsonProperty(value = JSON_PROPERTY_FILE_NAME, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFileName(@jakarta.annotation.Nonnull String fileName) { + this.fileName = fileName; + } + + + public AttachmentMetadata contentType(@jakarta.annotation.Nonnull String contentType) { + + this.contentType = contentType; + return this; + } + + /** + * Media type of the file. + * @return contentType + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_CONTENT_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getContentType() { + return contentType; + } + + + @JsonProperty(value = JSON_PROPERTY_CONTENT_TYPE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setContentType(@jakarta.annotation.Nonnull String contentType) { + this.contentType = contentType; + } + + + public AttachmentMetadata size(@jakarta.annotation.Nonnull Long size) { + + this.size = size; + return this; + } + + /** + * Size of the file in bytes. + * @return size + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_SIZE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Long getSize() { + return size; + } + + + @JsonProperty(value = JSON_PROPERTY_SIZE, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setSize(@jakarta.annotation.Nonnull Long size) { + this.size = size; + } + + + public AttachmentMetadata fileLastModified(@jakarta.annotation.Nonnull OffsetDateTime fileLastModified) { + + this.fileLastModified = fileLastModified; + return this; + } + + /** + * When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + * @return fileLastModified + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_FILE_LAST_MODIFIED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OffsetDateTime getFileLastModified() { + return fileLastModified; + } + + + @JsonProperty(value = JSON_PROPERTY_FILE_LAST_MODIFIED, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setFileLastModified(@jakarta.annotation.Nonnull OffsetDateTime fileLastModified) { + this.fileLastModified = fileLastModified; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentMetadata attachmentMetadata = (AttachmentMetadata) o; + return Objects.equals(this.fileName, attachmentMetadata.fileName) && + Objects.equals(this.contentType, attachmentMetadata.contentType) && + Objects.equals(this.size, attachmentMetadata.size) && + Objects.equals(this.fileLastModified, attachmentMetadata.fileLastModified); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(fileName, contentType, size, fileLastModified); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentMetadata {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUpload.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUpload.java new file mode 100644 index 0000000..038670c --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUpload.java @@ -0,0 +1,187 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.Map; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. + */ +@JsonPropertyOrder({ + AttachmentUpload.JSON_PROPERTY_URL, + AttachmentUpload.JSON_PROPERTY_HEADERS, + AttachmentUpload.JSON_PROPERTY_EXPIRES_AT +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentUpload { + public static final String JSON_PROPERTY_URL = "url"; + @jakarta.annotation.Nonnull + private String url; + + public static final String JSON_PROPERTY_HEADERS = "headers"; + @jakarta.annotation.Nonnull + private Map headers; + + public static final String JSON_PROPERTY_EXPIRES_AT = "expires_at"; + @jakarta.annotation.Nonnull + private OffsetDateTime expiresAt; + + public AttachmentUpload() { + } + + public AttachmentUpload url(@jakarta.annotation.Nonnull String url) { + + this.url = url; + return this; + } + + /** + * Get url + * @return url + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getUrl() { + return url; + } + + + @JsonProperty(value = JSON_PROPERTY_URL, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUrl(@jakarta.annotation.Nonnull String url) { + this.url = url; + } + + + public AttachmentUpload headers(@jakarta.annotation.Nonnull Map headers) { + + this.headers = headers; + return this; + } + + public AttachmentUpload putHeadersItem(String key, String headersItem) { + this.headers.put(key, headersItem); + return this; + } + + /** + * Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + * @return headers + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_HEADERS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public Map getHeaders() { + return headers; + } + + + @JsonProperty(value = JSON_PROPERTY_HEADERS, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setHeaders(@jakarta.annotation.Nonnull Map headers) { + this.headers = headers; + } + + + public AttachmentUpload expiresAt(@jakarta.annotation.Nonnull OffsetDateTime expiresAt) { + + this.expiresAt = expiresAt; + return this; + } + + /** + * When the URL stops being valid. RFC 3339 date-time (ISO-8601) + * @return expiresAt + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public OffsetDateTime getExpiresAt() { + return expiresAt; + } + + + @JsonProperty(value = JSON_PROPERTY_EXPIRES_AT, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setExpiresAt(@jakarta.annotation.Nonnull OffsetDateTime expiresAt) { + this.expiresAt = expiresAt; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentUpload attachmentUpload = (AttachmentUpload) o; + return Objects.equals(this.url, attachmentUpload.url) && + Objects.equals(this.headers, attachmentUpload.headers) && + Objects.equals(this.expiresAt, attachmentUpload.expiresAt); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(url, headers, expiresAt); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentUpload {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUploadResponse.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUploadResponse.java new file mode 100644 index 0000000..b7b4d47 --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentUploadResponse.java @@ -0,0 +1,182 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.timr.api.models.AttachmentMetadata; +import com.timr.api.models.AttachmentUpload; +import java.util.UUID; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * A registered upload of a file, with the pre-signed URL to upload the file to. + */ +@JsonPropertyOrder({ + AttachmentUploadResponse.JSON_PROPERTY_ID, + AttachmentUploadResponse.JSON_PROPERTY_METADATA, + AttachmentUploadResponse.JSON_PROPERTY_UPLOAD +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentUploadResponse { + public static final String JSON_PROPERTY_ID = "id"; + @jakarta.annotation.Nonnull + private UUID id; + + public static final String JSON_PROPERTY_METADATA = "metadata"; + @jakarta.annotation.Nonnull + private AttachmentMetadata metadata; + + public static final String JSON_PROPERTY_UPLOAD = "upload"; + @jakarta.annotation.Nonnull + private AttachmentUpload upload; + + public AttachmentUploadResponse() { + } + + public AttachmentUploadResponse id(@jakarta.annotation.Nonnull UUID id) { + + this.id = id; + return this; + } + + /** + * Unique identifier of the attachment. Treat it as an opaque string. + * @return id + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public UUID getId() { + return id; + } + + + @JsonProperty(value = JSON_PROPERTY_ID, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setId(@jakarta.annotation.Nonnull UUID id) { + this.id = id; + } + + + public AttachmentUploadResponse metadata(@jakarta.annotation.Nonnull AttachmentMetadata metadata) { + + this.metadata = metadata; + return this; + } + + /** + * Get metadata + * @return metadata + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentMetadata getMetadata() { + return metadata; + } + + + @JsonProperty(value = JSON_PROPERTY_METADATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setMetadata(@jakarta.annotation.Nonnull AttachmentMetadata metadata) { + this.metadata = metadata; + } + + + public AttachmentUploadResponse upload(@jakarta.annotation.Nonnull AttachmentUpload upload) { + + this.upload = upload; + return this; + } + + /** + * Get upload + * @return upload + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_UPLOAD, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public AttachmentUpload getUpload() { + return upload; + } + + + @JsonProperty(value = JSON_PROPERTY_UPLOAD, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setUpload(@jakarta.annotation.Nonnull AttachmentUpload upload) { + this.upload = upload; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentUploadResponse attachmentUploadResponse = (AttachmentUploadResponse) o; + return Objects.equals(this.id, attachmentUploadResponse.id) && + Objects.equals(this.metadata, attachmentUploadResponse.metadata) && + Objects.equals(this.upload, attachmentUploadResponse.upload); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(id, metadata, upload); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentUploadResponse {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsPage.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsPage.java new file mode 100644 index 0000000..515955b --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsPage.java @@ -0,0 +1,159 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.timr.api.models.Attachment; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import org.openapitools.jackson.nullable.JsonNullable; +import com.fasterxml.jackson.annotation.*; + +/** + * AttachmentsPage + */ +@JsonPropertyOrder({ + AttachmentsPage.JSON_PROPERTY_NEXT_PAGE_TOKEN, + AttachmentsPage.JSON_PROPERTY_DATA +}) +@jakarta.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen", comments = "Generator version: 7.26.0") +public class AttachmentsPage { + public static final String JSON_PROPERTY_NEXT_PAGE_TOKEN = "next_page_token"; + @jakarta.annotation.Nullable + private String nextPageToken; + + public static final String JSON_PROPERTY_DATA = "data"; + @jakarta.annotation.Nonnull + private List data; + + public AttachmentsPage() { + } + + public AttachmentsPage nextPageToken(@jakarta.annotation.Nullable String nextPageToken) { + + this.nextPageToken = nextPageToken; + return this; + } + + /** + * Token for the next page, or null when this is the last page. + * @return nextPageToken + */ + @jakarta.annotation.Nullable + @JsonProperty(value = JSON_PROPERTY_NEXT_PAGE_TOKEN, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public String getNextPageToken() { + return nextPageToken; + } + + + @JsonProperty(value = JSON_PROPERTY_NEXT_PAGE_TOKEN, required = false) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setNextPageToken(@jakarta.annotation.Nullable String nextPageToken) { + this.nextPageToken = nextPageToken; + } + + + public AttachmentsPage data(@jakarta.annotation.Nonnull List data) { + + this.data = data; + return this; + } + + public AttachmentsPage addDataItem(Attachment dataItem) { + if (this.data == null) { + this.data = new ArrayList<>(); + } + this.data.add(dataItem); + return this; + } + + /** + * Get data + * @return data + */ + @jakarta.annotation.Nonnull + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + + public List getData() { + return data; + } + + + @JsonProperty(value = JSON_PROPERTY_DATA, required = true) + @JsonInclude(value = JsonInclude.Include.ALWAYS) + public void setData(@jakarta.annotation.Nonnull List data) { + this.data = data; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + AttachmentsPage attachmentsPage = (AttachmentsPage) o; + return Objects.equals(this.nextPageToken, attachmentsPage.nextPageToken) && + Objects.equals(this.data, attachmentsPage.data); + } + + private static boolean equalsNullable(JsonNullable a, JsonNullable b) { + return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); + } + + @Override + public int hashCode() { + return Objects.hash(nextPageToken, data); + } + + private static int hashCodeNullable(JsonNullable a) { + if (a == null) { + return 1; + } + return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("class AttachmentsPage {\n"); + sb.append("}"); + return sb.toString(); + } + + /** + * Convert the given object to string with each line indented by 4 spaces + * (except the first line). + */ + private String toIndentedString(Object o) { + return o == null ? "null" : o.toString().replace("\n", "\n "); + } + +} + diff --git a/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsSortColumn.java b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsSortColumn.java new file mode 100644 index 0000000..3f64c2d --- /dev/null +++ b/sdk/java-resttemplate/src/main/java/com/timr/api/models/AttachmentsSortColumn.java @@ -0,0 +1,57 @@ +/* + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +package com.timr.api.models; + +import java.util.Objects; +import java.util.Arrays; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonTypeName; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + */ +public enum AttachmentsSortColumn { + + UPLOADED_AT("uploaded_at"); + + private String value; + + AttachmentsSortColumn(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @Override + public String toString() { + return String.valueOf(value); + } + + @JsonCreator + public static AttachmentsSortColumn fromValue(String value) { + for (AttachmentsSortColumn b : AttachmentsSortColumn.values()) { + if (b.value.equals(value)) { + return b; + } + } + throw new IllegalArgumentException("Unexpected value '" + value + "'"); + } +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/ProjectTimeAttachmentApi.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/ProjectTimeAttachmentApi.kt new file mode 100644 index 0000000..25410c8 --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/ProjectTimeAttachmentApi.kt @@ -0,0 +1,393 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.apis + +import java.io.IOException +import okhttp3.Call +import okhttp3.HttpUrl + +import com.timr.api.models.Attachment +import com.timr.api.models.AttachmentMetadata +import com.timr.api.models.AttachmentUploadResponse +import com.timr.api.models.AttachmentsPage +import com.timr.api.models.AttachmentsSortColumn +import com.timr.api.models.Error +import com.timr.api.models.SortDirection + +import com.google.gson.annotations.SerializedName + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import com.timr.api.infrastructure.ApiClient +import com.timr.api.infrastructure.ApiResponse +import com.timr.api.infrastructure.ClientException +import com.timr.api.infrastructure.ClientError +import com.timr.api.infrastructure.ServerException +import com.timr.api.infrastructure.ServerError +import com.timr.api.infrastructure.MultiValueMap +import com.timr.api.infrastructure.PartConfig +import com.timr.api.infrastructure.RequestConfig +import com.timr.api.infrastructure.RequestMethod +import com.timr.api.infrastructure.ResponseType +import com.timr.api.infrastructure.Success +import com.timr.api.infrastructure.toMultiValue + +open class ProjectTimeAttachmentApi(basePath: kotlin.String = defaultBasePath, client: Call.Factory = ApiClient.defaultClient) : ApiClient(basePath, client) { + companion object { + @JvmStatic + val defaultBasePath: String by lazy { + System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "https://api.timr.com/v1") + } + } + + /** + * POST /project-times/{project_time_id}/attachments + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return AttachmentUploadResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun createProjectTimeAttachment(projectTimeId: kotlin.String, attachmentMetadata: AttachmentMetadata) : AttachmentUploadResponse = withContext(Dispatchers.IO) { + val localVarResponse = createProjectTimeAttachmentWithHttpInfo(projectTimeId = projectTimeId, attachmentMetadata = attachmentMetadata) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as AttachmentUploadResponse + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * POST /project-times/{project_time_id}/attachments + * Upload a Project Time Attachment + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + suspend fun createProjectTimeAttachmentWithHttpInfo(projectTimeId: kotlin.String, attachmentMetadata: AttachmentMetadata) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = createProjectTimeAttachmentRequestConfig(projectTimeId = projectTimeId, attachmentMetadata = attachmentMetadata) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation createProjectTimeAttachment + * + * @param projectTimeId ID of the Project Time. + * @param attachmentMetadata Metadata of the file to upload. + * @return RequestConfig + */ + fun createProjectTimeAttachmentRequestConfig(projectTimeId: kotlin.String, attachmentMetadata: AttachmentMetadata) : RequestConfig { + val localVariableBody = attachmentMetadata + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Content-Type"] = "application/json" + localVariableHeaders["Accept"] = "application/json, application/problem+json" + + return RequestConfig( + method = RequestMethod.POST, + path = "/project-times/{project_time_id}/attachments".replace("{"+"project_time_id"+"}", encodeURIComponent(projectTimeId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + /** + * DELETE /project-times/{project_time_id}/attachments/{attachment_id} + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return void + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun deleteProjectTimeAttachment(projectTimeId: kotlin.String, attachmentId: java.util.UUID) : Unit = withContext(Dispatchers.IO) { + val localVarResponse = deleteProjectTimeAttachmentWithHttpInfo(projectTimeId = projectTimeId, attachmentId = attachmentId) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> Unit + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * DELETE /project-times/{project_time_id}/attachments/{attachment_id} + * Delete a Project Time Attachment + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Throws(IllegalStateException::class, IOException::class) + suspend fun deleteProjectTimeAttachmentWithHttpInfo(projectTimeId: kotlin.String, attachmentId: java.util.UUID) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = deleteProjectTimeAttachmentRequestConfig(projectTimeId = projectTimeId, attachmentId = attachmentId) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation deleteProjectTimeAttachment + * + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return RequestConfig + */ + fun deleteProjectTimeAttachmentRequestConfig(projectTimeId: kotlin.String, attachmentId: java.util.UUID) : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/problem+json" + + return RequestConfig( + method = RequestMethod.DELETE, + path = "/project-times/{project_time_id}/attachments/{attachment_id}".replace("{"+"project_time_id"+"}", encodeURIComponent(projectTimeId.toString())).replace("{"+"attachment_id"+"}", encodeURIComponent(attachmentId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + /** + * GET /project-times/{project_time_id}/attachments + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional) + * @param sortBy Property to sort the entries by. (optional) + * @return AttachmentsPage + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun fetchProjectTimeAttachments(projectTimeId: kotlin.String, pageToken: kotlin.String? = null, limit: kotlin.Int? = 20, sortDirection: SortDirection? = null, sortBy: AttachmentsSortColumn? = null) : AttachmentsPage = withContext(Dispatchers.IO) { + val localVarResponse = fetchProjectTimeAttachmentsWithHttpInfo(projectTimeId = projectTimeId, pageToken = pageToken, limit = limit, sortDirection = sortDirection, sortBy = sortBy) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as AttachmentsPage + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * GET /project-times/{project_time_id}/attachments + * List Project Time Attachments + * Lists the attachments of a running or completed Project Time whose upload has completed. + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional) + * @param sortBy Property to sort the entries by. (optional) + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + suspend fun fetchProjectTimeAttachmentsWithHttpInfo(projectTimeId: kotlin.String, pageToken: kotlin.String?, limit: kotlin.Int?, sortDirection: SortDirection?, sortBy: AttachmentsSortColumn?) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = fetchProjectTimeAttachmentsRequestConfig(projectTimeId = projectTimeId, pageToken = pageToken, limit = limit, sortDirection = sortDirection, sortBy = sortBy) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation fetchProjectTimeAttachments + * + * @param projectTimeId ID of the Project Time. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional) + * @param sortBy Property to sort the entries by. (optional) + * @return RequestConfig + */ + fun fetchProjectTimeAttachmentsRequestConfig(projectTimeId: kotlin.String, pageToken: kotlin.String?, limit: kotlin.Int?, sortDirection: SortDirection?, sortBy: AttachmentsSortColumn?) : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf>() + .apply { + if (pageToken != null) { + put("page_token", listOf(pageToken.toString())) + } + if (limit != null) { + put("limit", listOf(limit.toString())) + } + if (sortDirection != null) { + put("sort_direction", listOf(sortDirection.toString())) + } + if (sortBy != null) { + put("sort_by", listOf(sortBy.toString())) + } + } + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/json, application/problem+json" + + return RequestConfig( + method = RequestMethod.GET, + path = "/project-times/{project_time_id}/attachments".replace("{"+"project_time_id"+"}", encodeURIComponent(projectTimeId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + /** + * GET /project-times/{project_time_id}/attachments/{attachment_id} + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return Attachment + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun getProjectTimeAttachment(projectTimeId: kotlin.String, attachmentId: java.util.UUID) : Attachment = withContext(Dispatchers.IO) { + val localVarResponse = getProjectTimeAttachmentWithHttpInfo(projectTimeId = projectTimeId, attachmentId = attachmentId) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as Attachment + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * GET /project-times/{project_time_id}/attachments/{attachment_id} + * Get a Project Time Attachment + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + suspend fun getProjectTimeAttachmentWithHttpInfo(projectTimeId: kotlin.String, attachmentId: java.util.UUID) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = getProjectTimeAttachmentRequestConfig(projectTimeId = projectTimeId, attachmentId = attachmentId) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation getProjectTimeAttachment + * + * @param projectTimeId ID of the Project Time. + * @param attachmentId ID of the Project Time Attachment. + * @return RequestConfig + */ + fun getProjectTimeAttachmentRequestConfig(projectTimeId: kotlin.String, attachmentId: java.util.UUID) : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/json, application/problem+json" + + return RequestConfig( + method = RequestMethod.GET, + path = "/project-times/{project_time_id}/attachments/{attachment_id}".replace("{"+"project_time_id"+"}", encodeURIComponent(projectTimeId.toString())).replace("{"+"attachment_id"+"}", encodeURIComponent(attachmentId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + + private fun encodeURIComponent(uriComponent: kotlin.String): kotlin.String = + HttpUrl.Builder().scheme("http").host("localhost").addPathSegment(uriComponent).build().encodedPathSegments[0] +} diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/TaskAttachmentApi.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/TaskAttachmentApi.kt new file mode 100644 index 0000000..c09c03a --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/apis/TaskAttachmentApi.kt @@ -0,0 +1,393 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.apis + +import java.io.IOException +import okhttp3.Call +import okhttp3.HttpUrl + +import com.timr.api.models.Attachment +import com.timr.api.models.AttachmentMetadata +import com.timr.api.models.AttachmentUploadResponse +import com.timr.api.models.AttachmentsPage +import com.timr.api.models.AttachmentsSortColumn +import com.timr.api.models.Error +import com.timr.api.models.SortDirection + +import com.google.gson.annotations.SerializedName + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import com.timr.api.infrastructure.ApiClient +import com.timr.api.infrastructure.ApiResponse +import com.timr.api.infrastructure.ClientException +import com.timr.api.infrastructure.ClientError +import com.timr.api.infrastructure.ServerException +import com.timr.api.infrastructure.ServerError +import com.timr.api.infrastructure.MultiValueMap +import com.timr.api.infrastructure.PartConfig +import com.timr.api.infrastructure.RequestConfig +import com.timr.api.infrastructure.RequestMethod +import com.timr.api.infrastructure.ResponseType +import com.timr.api.infrastructure.Success +import com.timr.api.infrastructure.toMultiValue + +open class TaskAttachmentApi(basePath: kotlin.String = defaultBasePath, client: Call.Factory = ApiClient.defaultClient) : ApiClient(basePath, client) { + companion object { + @JvmStatic + val defaultBasePath: String by lazy { + System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "https://api.timr.com/v1") + } + } + + /** + * POST /tasks/{task_id}/attachments + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return AttachmentUploadResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun createTaskAttachment(taskId: kotlin.String, attachmentMetadata: AttachmentMetadata) : AttachmentUploadResponse = withContext(Dispatchers.IO) { + val localVarResponse = createTaskAttachmentWithHttpInfo(taskId = taskId, attachmentMetadata = attachmentMetadata) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as AttachmentUploadResponse + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * POST /tasks/{task_id}/attachments + * Upload a Task Attachment + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + suspend fun createTaskAttachmentWithHttpInfo(taskId: kotlin.String, attachmentMetadata: AttachmentMetadata) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = createTaskAttachmentRequestConfig(taskId = taskId, attachmentMetadata = attachmentMetadata) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation createTaskAttachment + * + * @param taskId ID of the Task. + * @param attachmentMetadata Metadata of the file to upload. + * @return RequestConfig + */ + fun createTaskAttachmentRequestConfig(taskId: kotlin.String, attachmentMetadata: AttachmentMetadata) : RequestConfig { + val localVariableBody = attachmentMetadata + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Content-Type"] = "application/json" + localVariableHeaders["Accept"] = "application/json, application/problem+json" + + return RequestConfig( + method = RequestMethod.POST, + path = "/tasks/{task_id}/attachments".replace("{"+"task_id"+"}", encodeURIComponent(taskId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + /** + * DELETE /tasks/{task_id}/attachments/{attachment_id} + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return void + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun deleteTaskAttachment(taskId: kotlin.String, attachmentId: java.util.UUID) : Unit = withContext(Dispatchers.IO) { + val localVarResponse = deleteTaskAttachmentWithHttpInfo(taskId = taskId, attachmentId = attachmentId) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> Unit + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * DELETE /tasks/{task_id}/attachments/{attachment_id} + * Delete a Task Attachment + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Throws(IllegalStateException::class, IOException::class) + suspend fun deleteTaskAttachmentWithHttpInfo(taskId: kotlin.String, attachmentId: java.util.UUID) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = deleteTaskAttachmentRequestConfig(taskId = taskId, attachmentId = attachmentId) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation deleteTaskAttachment + * + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return RequestConfig + */ + fun deleteTaskAttachmentRequestConfig(taskId: kotlin.String, attachmentId: java.util.UUID) : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/problem+json" + + return RequestConfig( + method = RequestMethod.DELETE, + path = "/tasks/{task_id}/attachments/{attachment_id}".replace("{"+"task_id"+"}", encodeURIComponent(taskId.toString())).replace("{"+"attachment_id"+"}", encodeURIComponent(attachmentId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + /** + * GET /tasks/{task_id}/attachments + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional) + * @param sortBy Property to sort the entries by. (optional) + * @return AttachmentsPage + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun fetchTaskAttachments(taskId: kotlin.String, pageToken: kotlin.String? = null, limit: kotlin.Int? = 20, sortDirection: SortDirection? = null, sortBy: AttachmentsSortColumn? = null) : AttachmentsPage = withContext(Dispatchers.IO) { + val localVarResponse = fetchTaskAttachmentsWithHttpInfo(taskId = taskId, pageToken = pageToken, limit = limit, sortDirection = sortDirection, sortBy = sortBy) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as AttachmentsPage + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * GET /tasks/{task_id}/attachments + * List Task Attachments + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional) + * @param sortBy Property to sort the entries by. (optional) + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + suspend fun fetchTaskAttachmentsWithHttpInfo(taskId: kotlin.String, pageToken: kotlin.String?, limit: kotlin.Int?, sortDirection: SortDirection?, sortBy: AttachmentsSortColumn?) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = fetchTaskAttachmentsRequestConfig(taskId = taskId, pageToken = pageToken, limit = limit, sortDirection = sortDirection, sortBy = sortBy) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation fetchTaskAttachments + * + * @param taskId ID of the Task. + * @param pageToken Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + * @param limit Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + * @param sortDirection Direction to sort the entries in. (optional) + * @param sortBy Property to sort the entries by. (optional) + * @return RequestConfig + */ + fun fetchTaskAttachmentsRequestConfig(taskId: kotlin.String, pageToken: kotlin.String?, limit: kotlin.Int?, sortDirection: SortDirection?, sortBy: AttachmentsSortColumn?) : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf>() + .apply { + if (pageToken != null) { + put("page_token", listOf(pageToken.toString())) + } + if (limit != null) { + put("limit", listOf(limit.toString())) + } + if (sortDirection != null) { + put("sort_direction", listOf(sortDirection.toString())) + } + if (sortBy != null) { + put("sort_by", listOf(sortBy.toString())) + } + } + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/json, application/problem+json" + + return RequestConfig( + method = RequestMethod.GET, + path = "/tasks/{task_id}/attachments".replace("{"+"task_id"+"}", encodeURIComponent(taskId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + /** + * GET /tasks/{task_id}/attachments/{attachment_id} + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return Attachment + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + * @throws UnsupportedOperationException If the API returns an informational or redirection response + * @throws ClientException If the API returns a client error response + * @throws ServerException If the API returns a server error response + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class, UnsupportedOperationException::class, ClientException::class, ServerException::class) + suspend fun getTaskAttachment(taskId: kotlin.String, attachmentId: java.util.UUID) : Attachment = withContext(Dispatchers.IO) { + val localVarResponse = getTaskAttachmentWithHttpInfo(taskId = taskId, attachmentId = attachmentId) + + return@withContext when (localVarResponse.responseType) { + ResponseType.Success -> (localVarResponse as Success<*>).data as Attachment + ResponseType.Informational -> throw UnsupportedOperationException("Client does not support Informational responses.") + ResponseType.Redirection -> throw UnsupportedOperationException("Client does not support Redirection responses.") + ResponseType.ClientError -> { + val localVarError = localVarResponse as ClientError<*> + throw ClientException("Client error : ${localVarError.statusCode} ${localVarError.message.orEmpty()}", localVarError.statusCode, localVarResponse) + } + ResponseType.ServerError -> { + val localVarError = localVarResponse as ServerError<*> + throw ServerException("Server error : ${localVarError.statusCode} ${localVarError.message.orEmpty()} ${localVarError.body}", localVarError.statusCode, localVarResponse) + } + } + } + + /** + * GET /tasks/{task_id}/attachments/{attachment_id} + * Get a Task Attachment + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return ApiResponse + * @throws IllegalStateException If the request is not correctly configured + * @throws IOException Rethrows the OkHttp execute method exception + */ + @Suppress("UNCHECKED_CAST") + @Throws(IllegalStateException::class, IOException::class) + suspend fun getTaskAttachmentWithHttpInfo(taskId: kotlin.String, attachmentId: java.util.UUID) : ApiResponse = withContext(Dispatchers.IO) { + val localVariableConfig = getTaskAttachmentRequestConfig(taskId = taskId, attachmentId = attachmentId) + + return@withContext request( + localVariableConfig + ) + } + + /** + * To obtain the request config of the operation getTaskAttachment + * + * @param taskId ID of the Task. + * @param attachmentId ID of the Task Attachment. + * @return RequestConfig + */ + fun getTaskAttachmentRequestConfig(taskId: kotlin.String, attachmentId: java.util.UUID) : RequestConfig { + val localVariableBody = null + val localVariableQuery: MultiValueMap = mutableMapOf() + val localVariableHeaders: MutableMap = mutableMapOf() + localVariableHeaders["Accept"] = "application/json, application/problem+json" + + return RequestConfig( + method = RequestMethod.GET, + path = "/tasks/{task_id}/attachments/{attachment_id}".replace("{"+"task_id"+"}", encodeURIComponent(taskId.toString())).replace("{"+"attachment_id"+"}", encodeURIComponent(attachmentId.toString())), + query = localVariableQuery, + headers = localVariableHeaders, + requiresAuthentication = true, + body = localVariableBody + ) + } + + + private fun encodeURIComponent(uriComponent: kotlin.String): kotlin.String = + HttpUrl.Builder().scheme("http").host("localhost").addPathSegment(uriComponent).build().encodedPathSegments[0] +} diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/Attachment.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/Attachment.kt new file mode 100644 index 0000000..bbeed97 --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/Attachment.kt @@ -0,0 +1,68 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + +import com.timr.api.models.AttachmentDownload +import com.timr.api.models.AttachmentMetadata +import com.timr.api.models.UserPartial + +import com.google.gson.annotations.SerializedName + +/** + * A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + * + * @param id Unique identifier. Treat it as an opaque string. + * @param download Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + * @param metadata + * @param uploadedBy The User who uploaded the file, or null if that User no longer exists. + * @param uploadedAt When the upload of the file completed. RFC 3339 date-time (ISO-8601) + */ + + +data class Attachment ( + + /* Unique identifier. Treat it as an opaque string. */ + @SerializedName("id") + val id: java.util.UUID, + + /* Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. */ + @SerializedName("download") + val download: AttachmentDownload?, + + @SerializedName("metadata") + val metadata: AttachmentMetadata, + + /* The User who uploaded the file, or null if that User no longer exists. */ + @SerializedName("uploaded_by") + val uploadedBy: UserPartial?, + + /* When the upload of the file completed. RFC 3339 date-time (ISO-8601) */ + @SerializedName("uploaded_at") + val uploadedAt: java.time.OffsetDateTime + +) { + + +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentDownload.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentDownload.kt new file mode 100644 index 0000000..be6c0e9 --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentDownload.kt @@ -0,0 +1,45 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + + +import com.google.gson.annotations.SerializedName + +/** + * Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. + * + * @param url + */ + + +data class AttachmentDownload ( + + @SerializedName("url") + val url: kotlin.String + +) { + + +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentMetadata.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentMetadata.kt new file mode 100644 index 0000000..3c0bf0f --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentMetadata.kt @@ -0,0 +1,60 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + + +import com.google.gson.annotations.SerializedName + +/** + * Metadata of the attached file, as provided when it was uploaded. + * + * @param fileName + * @param contentType Media type of the file. + * @param propertySize Size of the file in bytes. + * @param fileLastModified When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + */ + + +data class AttachmentMetadata ( + + @SerializedName("file_name") + val fileName: kotlin.String, + + /* Media type of the file. */ + @SerializedName("content_type") + val contentType: kotlin.String, + + /* Size of the file in bytes. */ + @SerializedName("size") + val propertySize: kotlin.Long, + + /* When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) */ + @SerializedName("file_last_modified") + val fileLastModified: java.time.OffsetDateTime + +) { + + +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUpload.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUpload.kt new file mode 100644 index 0000000..273c7ef --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUpload.kt @@ -0,0 +1,55 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + + +import com.google.gson.annotations.SerializedName + +/** + * Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. + * + * @param url + * @param headers Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + * @param expiresAt When the URL stops being valid. RFC 3339 date-time (ISO-8601) + */ + + +data class AttachmentUpload ( + + @SerializedName("url") + val url: kotlin.String, + + /* Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). */ + @SerializedName("headers") + val headers: kotlin.collections.Map, + + /* When the URL stops being valid. RFC 3339 date-time (ISO-8601) */ + @SerializedName("expires_at") + val expiresAt: java.time.OffsetDateTime + +) { + + +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUploadResponse.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUploadResponse.kt new file mode 100644 index 0000000..9caadbd --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentUploadResponse.kt @@ -0,0 +1,56 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + +import com.timr.api.models.AttachmentMetadata +import com.timr.api.models.AttachmentUpload + +import com.google.gson.annotations.SerializedName + +/** + * A registered upload of a file, with the pre-signed URL to upload the file to. + * + * @param id Unique identifier of the attachment. Treat it as an opaque string. + * @param metadata + * @param upload + */ + + +data class AttachmentUploadResponse ( + + /* Unique identifier of the attachment. Treat it as an opaque string. */ + @SerializedName("id") + val id: java.util.UUID, + + @SerializedName("metadata") + val metadata: AttachmentMetadata, + + @SerializedName("upload") + val upload: AttachmentUpload + +) { + + +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsPage.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsPage.kt new file mode 100644 index 0000000..0daf8da --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsPage.kt @@ -0,0 +1,51 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + +import com.timr.api.models.Attachment + +import com.google.gson.annotations.SerializedName + +/** + * + * + * @param nextPageToken Token for the next page, or null when this is the last page. + * @param `data` + */ + + +data class AttachmentsPage ( + + /* Token for the next page, or null when this is the last page. */ + @SerializedName("next_page_token") + val nextPageToken: kotlin.String?, + + @SerializedName("data") + val `data`: kotlin.collections.List + +) { + + +} + diff --git a/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsSortColumn.kt b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsSortColumn.kt new file mode 100644 index 0000000..483a12a --- /dev/null +++ b/sdk/kotlin-okhttp/src/main/kotlin/com/timr/api/models/AttachmentsSortColumn.kt @@ -0,0 +1,66 @@ +/** + * + * Please note: + * This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * Do not edit this file manually. + * + */ + +@file:Suppress( + "ArrayInDataClass", + "DuplicatedCode", + "EnumEntryName", + "RemoveRedundantQualifierName", + "RemoveRedundantCallsOfConversionMethods", + "REDUNDANT_CALL_OF_CONVERSION_METHOD", + "RedundantUnitReturnType", + "RemoveEmptyClassBody", + "UnnecessaryVariable", + "UnusedImport", + "UnnecessaryVariable", + "unused" +) + +package com.timr.api.models + + +import com.google.gson.annotations.SerializedName + +/** + * Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + * + * Values: UPLOADED_AT + */ + +enum class AttachmentsSortColumn(val value: kotlin.String) { + + @SerializedName(value = "uploaded_at") + UPLOADED_AT("uploaded_at"); + + /** + * Override [toString()] to avoid using the enum variable name as the value, and instead use + * the actual value defined in the API spec file. + * + * This solves a problem when the variable name and its value are different, and ensures that + * the client sends the correct enum values to the server always. + */ + override fun toString(): kotlin.String = value + + companion object { + /** + * Converts the provided [data] to a [String] on success, null otherwise. + */ + fun encode(data: kotlin.Any?): kotlin.String? = if (data is AttachmentsSortColumn) "$data" else null + + /** + * Returns a valid [AttachmentsSortColumn] for [data], null otherwise. + */ + fun decode(data: kotlin.Any?): AttachmentsSortColumn? = data?.let { + val normalizedData = "$it".lowercase() + entries.firstOrNull { value -> + it == value || normalizedData == "$value".lowercase() + } + } + } +} + diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 7ddbc43..d083c10 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "timr_api" -version = "2.0.0" +version = "2.1.0" description = "timr API" authors = [ {name = "troii Software GmbH",email = "info@timr.com"}, diff --git a/sdk/python/timr_api/__init__.py b/sdk/python/timr_api/__init__.py index 802814a..28f01ae 100644 --- a/sdk/python/timr_api/__init__.py +++ b/sdk/python/timr_api/__init__.py @@ -14,7 +14,7 @@ """ # noqa: E501 -__version__ = "2.0.0" +__version__ = "2.1.0" # Define package exports __all__ = [ @@ -23,7 +23,9 @@ "DriveLogCategoryApi", "HolidayCalendarApi", "ProjectTimeApi", + "ProjectTimeAttachmentApi", "TaskApi", + "TaskAttachmentApi", "TaskToLeaderAssignmentApi", "TaskToTeamAssignmentApi", "TaskToUserAssignmentApi", @@ -45,6 +47,13 @@ "ApiAttributeError", "ApiException", "Accounts", + "Attachment", + "AttachmentDownload", + "AttachmentMetadata", + "AttachmentUpload", + "AttachmentUploadResponse", + "AttachmentsPage", + "AttachmentsSortColumn", "BreakTime", "BreakTimeAutomatic", "BreakTimeBase", @@ -185,7 +194,9 @@ from timr_api.api.drive_log_category_api import DriveLogCategoryApi as DriveLogCategoryApi from timr_api.api.holiday_calendar_api import HolidayCalendarApi as HolidayCalendarApi from timr_api.api.project_time_api import ProjectTimeApi as ProjectTimeApi +from timr_api.api.project_time_attachment_api import ProjectTimeAttachmentApi as ProjectTimeAttachmentApi from timr_api.api.task_api import TaskApi as TaskApi +from timr_api.api.task_attachment_api import TaskAttachmentApi as TaskAttachmentApi from timr_api.api.task_to_leader_assignment_api import TaskToLeaderAssignmentApi as TaskToLeaderAssignmentApi from timr_api.api.task_to_team_assignment_api import TaskToTeamAssignmentApi as TaskToTeamAssignmentApi from timr_api.api.task_to_user_assignment_api import TaskToUserAssignmentApi as TaskToUserAssignmentApi @@ -211,6 +222,13 @@ # import models into sdk package from timr_api.models.accounts import Accounts as Accounts +from timr_api.models.attachment import Attachment as Attachment +from timr_api.models.attachment_download import AttachmentDownload as AttachmentDownload +from timr_api.models.attachment_metadata import AttachmentMetadata as AttachmentMetadata +from timr_api.models.attachment_upload import AttachmentUpload as AttachmentUpload +from timr_api.models.attachment_upload_response import AttachmentUploadResponse as AttachmentUploadResponse +from timr_api.models.attachments_page import AttachmentsPage as AttachmentsPage +from timr_api.models.attachments_sort_column import AttachmentsSortColumn as AttachmentsSortColumn from timr_api.models.break_time import BreakTime as BreakTime from timr_api.models.break_time_automatic import BreakTimeAutomatic as BreakTimeAutomatic from timr_api.models.break_time_base import BreakTimeBase as BreakTimeBase diff --git a/sdk/python/timr_api/api/__init__.py b/sdk/python/timr_api/api/__init__.py index 98d004b..8c8018a 100644 --- a/sdk/python/timr_api/api/__init__.py +++ b/sdk/python/timr_api/api/__init__.py @@ -6,7 +6,9 @@ from timr_api.api.drive_log_category_api import DriveLogCategoryApi from timr_api.api.holiday_calendar_api import HolidayCalendarApi from timr_api.api.project_time_api import ProjectTimeApi +from timr_api.api.project_time_attachment_api import ProjectTimeAttachmentApi from timr_api.api.task_api import TaskApi +from timr_api.api.task_attachment_api import TaskAttachmentApi from timr_api.api.task_to_leader_assignment_api import TaskToLeaderAssignmentApi from timr_api.api.task_to_team_assignment_api import TaskToTeamAssignmentApi from timr_api.api.task_to_user_assignment_api import TaskToUserAssignmentApi diff --git a/sdk/python/timr_api/api/project_time_attachment_api.py b/sdk/python/timr_api/api/project_time_attachment_api.py new file mode 100644 index 0000000..5a85e24 --- /dev/null +++ b/sdk/python/timr_api/api/project_time_attachment_api.py @@ -0,0 +1,1249 @@ +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import Any, Optional +from typing_extensions import Annotated +from uuid import UUID +from timr_api.models.attachment import Attachment +from timr_api.models.attachment_metadata import AttachmentMetadata +from timr_api.models.attachment_upload_response import AttachmentUploadResponse +from timr_api.models.attachments_page import AttachmentsPage + +from timr_api.api_client import ApiClient, RequestSerialized +from timr_api.api_response import ApiResponse +from timr_api.rest import RESTResponseType + + +class ProjectTimeAttachmentApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_project_time_attachment( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_metadata: Annotated[AttachmentMetadata, Field(description="Metadata of the file to upload.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AttachmentUploadResponse: + """Upload a Project Time Attachment + + Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_metadata: Metadata of the file to upload. (required) + :type attachment_metadata: AttachmentMetadata + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_metadata=attachment_metadata, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "AttachmentUploadResponse", + '400': "Error", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_project_time_attachment_with_http_info( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_metadata: Annotated[AttachmentMetadata, Field(description="Metadata of the file to upload.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AttachmentUploadResponse]: + """Upload a Project Time Attachment + + Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_metadata: Metadata of the file to upload. (required) + :type attachment_metadata: AttachmentMetadata + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_metadata=attachment_metadata, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "AttachmentUploadResponse", + '400': "Error", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_project_time_attachment_without_preload_content( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_metadata: Annotated[AttachmentMetadata, Field(description="Metadata of the file to upload.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Upload a Project Time Attachment + + Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_metadata: Metadata of the file to upload. (required) + :type attachment_metadata: AttachmentMetadata + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_metadata=attachment_metadata, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "AttachmentUploadResponse", + '400': "Error", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_project_time_attachment_serialize( + self, + project_time_id, + attachment_metadata, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_time_id is not None: + _path_params['project_time_id'] = project_time_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if attachment_metadata is not None: + _body_params = attachment_metadata + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'application/problem+json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/project-times/{project_time_id}/attachments', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_project_time_attachment( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_id: Annotated[UUID, Field(description="ID of the Project Time Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete a Project Time Attachment + + Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_id: ID of the Project Time Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '403': "Error", + '404': "Error", + '422': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_project_time_attachment_with_http_info( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_id: Annotated[UUID, Field(description="ID of the Project Time Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete a Project Time Attachment + + Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_id: ID of the Project Time Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '403': "Error", + '404': "Error", + '422': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_project_time_attachment_without_preload_content( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_id: Annotated[UUID, Field(description="ID of the Project Time Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete a Project Time Attachment + + Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_id: ID of the Project Time Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '403': "Error", + '404': "Error", + '422': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_project_time_attachment_serialize( + self, + project_time_id, + attachment_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_time_id is not None: + _path_params['project_time_id'] = project_time_id + if attachment_id is not None: + _path_params['attachment_id'] = attachment_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/problem+json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/project-times/{project_time_id}/attachments/{attachment_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def fetch_project_time_attachments( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + page_token: Annotated[Optional[StrictStr], Field(description="Token identifying the page to return. Take it from the 'next_page_token' field of the previous response.")] = None, + limit: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Maximum number of entries per page. Values above 500 are capped at 500.")] = None, + sort_direction: Annotated[Optional[Any], Field(description="Direction to sort the entries in.")] = None, + sort_by: Annotated[Optional[Any], Field(description="Property to sort the entries by.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AttachmentsPage: + """List Project Time Attachments + + Lists the attachments of a running or completed Project Time whose upload has completed. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param page_token: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + :type page_token: str + :param limit: Maximum number of entries per page. Values above 500 are capped at 500. + :type limit: int + :param sort_direction: Direction to sort the entries in. + :type sort_direction: SortDirection + :param sort_by: Property to sort the entries by. + :type sort_by: AttachmentsSortColumn + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._fetch_project_time_attachments_serialize( + project_time_id=project_time_id, + page_token=page_token, + limit=limit, + sort_direction=sort_direction, + sort_by=sort_by, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AttachmentsPage", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def fetch_project_time_attachments_with_http_info( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + page_token: Annotated[Optional[StrictStr], Field(description="Token identifying the page to return. Take it from the 'next_page_token' field of the previous response.")] = None, + limit: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Maximum number of entries per page. Values above 500 are capped at 500.")] = None, + sort_direction: Annotated[Optional[Any], Field(description="Direction to sort the entries in.")] = None, + sort_by: Annotated[Optional[Any], Field(description="Property to sort the entries by.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AttachmentsPage]: + """List Project Time Attachments + + Lists the attachments of a running or completed Project Time whose upload has completed. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param page_token: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + :type page_token: str + :param limit: Maximum number of entries per page. Values above 500 are capped at 500. + :type limit: int + :param sort_direction: Direction to sort the entries in. + :type sort_direction: SortDirection + :param sort_by: Property to sort the entries by. + :type sort_by: AttachmentsSortColumn + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._fetch_project_time_attachments_serialize( + project_time_id=project_time_id, + page_token=page_token, + limit=limit, + sort_direction=sort_direction, + sort_by=sort_by, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AttachmentsPage", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def fetch_project_time_attachments_without_preload_content( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + page_token: Annotated[Optional[StrictStr], Field(description="Token identifying the page to return. Take it from the 'next_page_token' field of the previous response.")] = None, + limit: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Maximum number of entries per page. Values above 500 are capped at 500.")] = None, + sort_direction: Annotated[Optional[Any], Field(description="Direction to sort the entries in.")] = None, + sort_by: Annotated[Optional[Any], Field(description="Property to sort the entries by.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Project Time Attachments + + Lists the attachments of a running or completed Project Time whose upload has completed. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param page_token: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + :type page_token: str + :param limit: Maximum number of entries per page. Values above 500 are capped at 500. + :type limit: int + :param sort_direction: Direction to sort the entries in. + :type sort_direction: SortDirection + :param sort_by: Property to sort the entries by. + :type sort_by: AttachmentsSortColumn + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._fetch_project_time_attachments_serialize( + project_time_id=project_time_id, + page_token=page_token, + limit=limit, + sort_direction=sort_direction, + sort_by=sort_by, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AttachmentsPage", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _fetch_project_time_attachments_serialize( + self, + project_time_id, + page_token, + limit, + sort_direction, + sort_by, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_time_id is not None: + _path_params['project_time_id'] = project_time_id + # process the query parameters + if page_token is not None: + + _query_params.append(('page_token', page_token)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + if sort_direction is not None: + + _query_params.append(('sort_direction', sort_direction.value)) + + if sort_by is not None: + + _query_params.append(('sort_by', sort_by.value)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'application/problem+json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/project-times/{project_time_id}/attachments', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_project_time_attachment( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_id: Annotated[UUID, Field(description="ID of the Project Time Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> Attachment: + """Get a Project Time Attachment + + Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_id: ID of the Project Time Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Attachment", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_project_time_attachment_with_http_info( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_id: Annotated[UUID, Field(description="ID of the Project Time Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[Attachment]: + """Get a Project Time Attachment + + Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_id: ID of the Project Time Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Attachment", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_project_time_attachment_without_preload_content( + self, + project_time_id: Annotated[StrictStr, Field(description="ID of the Project Time.")], + attachment_id: Annotated[UUID, Field(description="ID of the Project Time Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get a Project Time Attachment + + Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + + :param project_time_id: ID of the Project Time. (required) + :type project_time_id: str + :param attachment_id: ID of the Project Time Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_project_time_attachment_serialize( + project_time_id=project_time_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Attachment", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_project_time_attachment_serialize( + self, + project_time_id, + attachment_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if project_time_id is not None: + _path_params['project_time_id'] = project_time_id + if attachment_id is not None: + _path_params['attachment_id'] = attachment_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'application/problem+json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/project-times/{project_time_id}/attachments/{attachment_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/sdk/python/timr_api/api/task_attachment_api.py b/sdk/python/timr_api/api/task_attachment_api.py new file mode 100644 index 0000000..e7ffab3 --- /dev/null +++ b/sdk/python/timr_api/api/task_attachment_api.py @@ -0,0 +1,1246 @@ +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +import warnings +from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt +from typing import Any, Dict, List, Optional, Tuple, Union +from typing_extensions import Annotated + +from pydantic import Field, StrictStr +from typing import Any, Optional +from typing_extensions import Annotated +from uuid import UUID +from timr_api.models.attachment import Attachment +from timr_api.models.attachment_metadata import AttachmentMetadata +from timr_api.models.attachment_upload_response import AttachmentUploadResponse +from timr_api.models.attachments_page import AttachmentsPage + +from timr_api.api_client import ApiClient, RequestSerialized +from timr_api.api_response import ApiResponse +from timr_api.rest import RESTResponseType + + +class TaskAttachmentApi: + """NOTE: This class is auto generated by OpenAPI Generator + Ref: https://openapi-generator.tech + + Do not edit the class manually. + """ + + def __init__(self, api_client=None) -> None: + if api_client is None: + api_client = ApiClient.get_default() + self.api_client = api_client + + + @validate_call + def create_task_attachment( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_metadata: Annotated[AttachmentMetadata, Field(description="Metadata of the file to upload.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AttachmentUploadResponse: + """Upload a Task Attachment + + Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_metadata: Metadata of the file to upload. (required) + :type attachment_metadata: AttachmentMetadata + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_task_attachment_serialize( + task_id=task_id, + attachment_metadata=attachment_metadata, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "AttachmentUploadResponse", + '400': "Error", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def create_task_attachment_with_http_info( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_metadata: Annotated[AttachmentMetadata, Field(description="Metadata of the file to upload.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AttachmentUploadResponse]: + """Upload a Task Attachment + + Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_metadata: Metadata of the file to upload. (required) + :type attachment_metadata: AttachmentMetadata + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_task_attachment_serialize( + task_id=task_id, + attachment_metadata=attachment_metadata, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "AttachmentUploadResponse", + '400': "Error", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def create_task_attachment_without_preload_content( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_metadata: Annotated[AttachmentMetadata, Field(description="Metadata of the file to upload.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Upload a Task Attachment + + Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_metadata: Metadata of the file to upload. (required) + :type attachment_metadata: AttachmentMetadata + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._create_task_attachment_serialize( + task_id=task_id, + attachment_metadata=attachment_metadata, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '201': "AttachmentUploadResponse", + '400': "Error", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _create_task_attachment_serialize( + self, + task_id, + attachment_metadata, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if task_id is not None: + _path_params['task_id'] = task_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + if attachment_metadata is not None: + _body_params = attachment_metadata + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'application/problem+json' + ] + ) + + # set the HTTP header `Content-Type` + if _content_type: + _header_params['Content-Type'] = _content_type + else: + _default_content_type = ( + self.api_client.select_header_content_type( + [ + 'application/json' + ] + ) + ) + if _default_content_type is not None: + _header_params['Content-Type'] = _default_content_type + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='POST', + resource_path='/tasks/{task_id}/attachments', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def delete_task_attachment( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_id: Annotated[UUID, Field(description="ID of the Task Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> None: + """Delete a Task Attachment + + Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_id: ID of the Task Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_task_attachment_serialize( + task_id=task_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def delete_task_attachment_with_http_info( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_id: Annotated[UUID, Field(description="ID of the Task Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[None]: + """Delete a Task Attachment + + Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_id: ID of the Task Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_task_attachment_serialize( + task_id=task_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def delete_task_attachment_without_preload_content( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_id: Annotated[UUID, Field(description="ID of the Task Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Delete a Task Attachment + + Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_id: ID of the Task Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._delete_task_attachment_serialize( + task_id=task_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '204': None, + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _delete_task_attachment_serialize( + self, + task_id, + attachment_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if task_id is not None: + _path_params['task_id'] = task_id + if attachment_id is not None: + _path_params['attachment_id'] = attachment_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/problem+json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='DELETE', + resource_path='/tasks/{task_id}/attachments/{attachment_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def fetch_task_attachments( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + page_token: Annotated[Optional[StrictStr], Field(description="Token identifying the page to return. Take it from the 'next_page_token' field of the previous response.")] = None, + limit: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Maximum number of entries per page. Values above 500 are capped at 500.")] = None, + sort_direction: Annotated[Optional[Any], Field(description="Direction to sort the entries in.")] = None, + sort_by: Annotated[Optional[Any], Field(description="Property to sort the entries by.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> AttachmentsPage: + """List Task Attachments + + Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param page_token: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + :type page_token: str + :param limit: Maximum number of entries per page. Values above 500 are capped at 500. + :type limit: int + :param sort_direction: Direction to sort the entries in. + :type sort_direction: SortDirection + :param sort_by: Property to sort the entries by. + :type sort_by: AttachmentsSortColumn + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._fetch_task_attachments_serialize( + task_id=task_id, + page_token=page_token, + limit=limit, + sort_direction=sort_direction, + sort_by=sort_by, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AttachmentsPage", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def fetch_task_attachments_with_http_info( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + page_token: Annotated[Optional[StrictStr], Field(description="Token identifying the page to return. Take it from the 'next_page_token' field of the previous response.")] = None, + limit: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Maximum number of entries per page. Values above 500 are capped at 500.")] = None, + sort_direction: Annotated[Optional[Any], Field(description="Direction to sort the entries in.")] = None, + sort_by: Annotated[Optional[Any], Field(description="Property to sort the entries by.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[AttachmentsPage]: + """List Task Attachments + + Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param page_token: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + :type page_token: str + :param limit: Maximum number of entries per page. Values above 500 are capped at 500. + :type limit: int + :param sort_direction: Direction to sort the entries in. + :type sort_direction: SortDirection + :param sort_by: Property to sort the entries by. + :type sort_by: AttachmentsSortColumn + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._fetch_task_attachments_serialize( + task_id=task_id, + page_token=page_token, + limit=limit, + sort_direction=sort_direction, + sort_by=sort_by, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AttachmentsPage", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def fetch_task_attachments_without_preload_content( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + page_token: Annotated[Optional[StrictStr], Field(description="Token identifying the page to return. Take it from the 'next_page_token' field of the previous response.")] = None, + limit: Annotated[Optional[Annotated[int, Field(strict=True, ge=1)]], Field(description="Maximum number of entries per page. Values above 500 are capped at 500.")] = None, + sort_direction: Annotated[Optional[Any], Field(description="Direction to sort the entries in.")] = None, + sort_by: Annotated[Optional[Any], Field(description="Property to sort the entries by.")] = None, + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """List Task Attachments + + Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param page_token: Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + :type page_token: str + :param limit: Maximum number of entries per page. Values above 500 are capped at 500. + :type limit: int + :param sort_direction: Direction to sort the entries in. + :type sort_direction: SortDirection + :param sort_by: Property to sort the entries by. + :type sort_by: AttachmentsSortColumn + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._fetch_task_attachments_serialize( + task_id=task_id, + page_token=page_token, + limit=limit, + sort_direction=sort_direction, + sort_by=sort_by, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "AttachmentsPage", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _fetch_task_attachments_serialize( + self, + task_id, + page_token, + limit, + sort_direction, + sort_by, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if task_id is not None: + _path_params['task_id'] = task_id + # process the query parameters + if page_token is not None: + + _query_params.append(('page_token', page_token)) + + if limit is not None: + + _query_params.append(('limit', limit)) + + if sort_direction is not None: + + _query_params.append(('sort_direction', sort_direction.value)) + + if sort_by is not None: + + _query_params.append(('sort_by', sort_by.value)) + + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'application/problem+json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/tasks/{task_id}/attachments', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + + + + @validate_call + def get_task_attachment( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_id: Annotated[UUID, Field(description="ID of the Task Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> Attachment: + """Get a Task Attachment + + Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_id: ID of the Task Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_task_attachment_serialize( + task_id=task_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Attachment", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ).data + + + @validate_call + def get_task_attachment_with_http_info( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_id: Annotated[UUID, Field(description="ID of the Task Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> ApiResponse[Attachment]: + """Get a Task Attachment + + Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_id: ID of the Task Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_task_attachment_serialize( + task_id=task_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Attachment", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + response_data.read() + return self.api_client.response_deserialize( + response_data=response_data, + response_types_map=_response_types_map, + ) + + + @validate_call + def get_task_attachment_without_preload_content( + self, + task_id: Annotated[StrictStr, Field(description="ID of the Task.")], + attachment_id: Annotated[UUID, Field(description="ID of the Task Attachment.")], + _request_timeout: Union[ + None, + Annotated[StrictFloat, Field(gt=0)], + Tuple[ + Annotated[StrictFloat, Field(gt=0)], + Annotated[StrictFloat, Field(gt=0)] + ] + ] = None, + _request_auth: Optional[Dict[StrictStr, Any]] = None, + _content_type: Optional[StrictStr] = None, + _headers: Optional[Dict[StrictStr, Any]] = None, + _host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0, + ) -> RESTResponseType: + """Get a Task Attachment + + Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + + :param task_id: ID of the Task. (required) + :type task_id: str + :param attachment_id: ID of the Task Attachment. (required) + :type attachment_id: UUID + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :type _request_timeout: int, tuple(int, int), optional + :param _request_auth: set to override the auth_settings for an a single + request; this effectively ignores the + authentication in the spec for a single request. + :type _request_auth: dict, optional + :param _content_type: force content-type for the request. + :type _content_type: str, Optional + :param _headers: set to override the headers for a single + request; this effectively ignores the headers + in the spec for a single request. + :type _headers: dict, optional + :param _host_index: set to override the host_index for a single + request; this effectively ignores the host_index + in the spec for a single request. + :type _host_index: int, optional + :return: Returns the result object. + """ # noqa: E501 + + _param = self._get_task_attachment_serialize( + task_id=task_id, + attachment_id=attachment_id, + _request_auth=_request_auth, + _content_type=_content_type, + _headers=_headers, + _host_index=_host_index + ) + + _response_types_map: Dict[str, Optional[str]] = { + '200': "Attachment", + '403': "Error", + '404': "Error", + } + response_data = self.api_client.call_api( + *_param, + _request_timeout=_request_timeout + ) + return response_data.response + + + def _get_task_attachment_serialize( + self, + task_id, + attachment_id, + _request_auth, + _content_type, + _headers, + _host_index, + ) -> RequestSerialized: + + _host = None + + _collection_formats: Dict[str, str] = { + } + + _path_params: Dict[str, str] = {} + _query_params: List[Tuple[str, str]] = [] + _header_params: Dict[str, Optional[str]] = _headers or {} + _form_params: List[Tuple[str, str]] = [] + _files: Dict[ + str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]] + ] = {} + _body_params: Optional[bytes] = None + + # process the path parameters + if task_id is not None: + _path_params['task_id'] = task_id + if attachment_id is not None: + _path_params['attachment_id'] = attachment_id + # process the query parameters + # process the header parameters + # process the form parameters + # process the body parameter + + + # set the HTTP header `Accept` + if 'Accept' not in _header_params: + _header_params['Accept'] = self.api_client.select_header_accept( + [ + 'application/json', + 'application/problem+json' + ] + ) + + + # authentication setting + _auth_settings: List[str] = [ + 'OAuth2', + 'OAuth2' + ] + + return self.api_client.param_serialize( + method='GET', + resource_path='/tasks/{task_id}/attachments/{attachment_id}', + path_params=_path_params, + query_params=_query_params, + header_params=_header_params, + body=_body_params, + post_params=_form_params, + files=_files, + auth_settings=_auth_settings, + collection_formats=_collection_formats, + _host=_host, + _request_auth=_request_auth + ) + + diff --git a/sdk/python/timr_api/api_client.py b/sdk/python/timr_api/api_client.py index a1a729d..02d5c63 100644 --- a/sdk/python/timr_api/api_client.py +++ b/sdk/python/timr_api/api_client.py @@ -91,7 +91,7 @@ def __init__( self.default_headers[header_name] = header_value self.cookie = cookie # Set default User-Agent. - self.user_agent = 'OpenAPI-Generator/2.0.0/python' + self.user_agent = 'OpenAPI-Generator/2.1.0/python' self.client_side_validation = configuration.client_side_validation def __enter__(self): diff --git a/sdk/python/timr_api/configuration.py b/sdk/python/timr_api/configuration.py index b46a8be..2df13cd 100644 --- a/sdk/python/timr_api/configuration.py +++ b/sdk/python/timr_api/configuration.py @@ -569,8 +569,8 @@ def to_debug_report(self) -> str: return "Python SDK Debug Report:\n"\ "OS: {env}\n"\ "Python Version: {pyversion}\n"\ - "Version of the API: 1.1.0\n"\ - "SDK Package Version: 2.0.0".\ + "Version of the API: 1.2.0\n"\ + "SDK Package Version: 2.1.0".\ format(env=sys.platform, pyversion=sys.version) def get_host_settings(self) -> List[HostSetting]: diff --git a/sdk/python/timr_api/models/__init__.py b/sdk/python/timr_api/models/__init__.py index 16b500a..7229914 100644 --- a/sdk/python/timr_api/models/__init__.py +++ b/sdk/python/timr_api/models/__init__.py @@ -14,6 +14,13 @@ # import models into model package from timr_api.models.accounts import Accounts +from timr_api.models.attachment import Attachment +from timr_api.models.attachment_download import AttachmentDownload +from timr_api.models.attachment_metadata import AttachmentMetadata +from timr_api.models.attachment_upload import AttachmentUpload +from timr_api.models.attachment_upload_response import AttachmentUploadResponse +from timr_api.models.attachments_page import AttachmentsPage +from timr_api.models.attachments_sort_column import AttachmentsSortColumn from timr_api.models.break_time import BreakTime from timr_api.models.break_time_automatic import BreakTimeAutomatic from timr_api.models.break_time_base import BreakTimeBase diff --git a/sdk/python/timr_api/models/attachment.py b/sdk/python/timr_api/models/attachment.py new file mode 100644 index 0000000..b3e6365 --- /dev/null +++ b/sdk/python/timr_api/models/attachment.py @@ -0,0 +1,120 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List, Optional +from uuid import UUID +from timr_api.models.attachment_download import AttachmentDownload +from timr_api.models.attachment_metadata import AttachmentMetadata +from timr_api.models.user_partial import UserPartial +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class Attachment(BaseModel): + """ + A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + """ # noqa: E501 + id: UUID = Field(description="Unique identifier. Treat it as an opaque string.", json_schema_extra={"examples": ["01972ff0-14a2-7814-926c-11d07a1dc20b"]}) + download: Optional[AttachmentDownload] = Field(description="Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. ") + metadata: AttachmentMetadata + uploaded_by: Optional[UserPartial] = Field(description="The User who uploaded the file, or null if that User no longer exists.") + uploaded_at: datetime = Field(description="When the upload of the file completed. RFC 3339 date-time (ISO-8601) ", json_schema_extra={"examples": ["2021-07-16T08:20:00Z"]}) + __properties: ClassVar[List[str]] = ["id", "download", "metadata", "uploaded_by", "uploaded_at"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of Attachment from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of download + if self.download: + _dict['download'] = self.download.to_dict() + # override the default output from pydantic by calling `to_dict()` of metadata + if self.metadata: + _dict['metadata'] = self.metadata.to_dict() + # override the default output from pydantic by calling `to_dict()` of uploaded_by + if self.uploaded_by: + _dict['uploaded_by'] = self.uploaded_by.to_dict() + # set to None if download (nullable) is None + # and model_fields_set contains the field + if self.download is None and "download" in self.model_fields_set: + _dict['download'] = None + + # set to None if uploaded_by (nullable) is None + # and model_fields_set contains the field + if self.uploaded_by is None and "uploaded_by" in self.model_fields_set: + _dict['uploaded_by'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of Attachment from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "download": AttachmentDownload.from_dict(obj["download"]) if obj.get("download") is not None else None, + "metadata": AttachmentMetadata.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None, + "uploaded_by": UserPartial.from_dict(obj["uploaded_by"]) if obj.get("uploaded_by") is not None else None, + "uploaded_at": obj.get("uploaded_at") + }) + return _obj + + diff --git a/sdk/python/timr_api/models/attachment_download.py b/sdk/python/timr_api/models/attachment_download.py new file mode 100644 index 0000000..1a26da8 --- /dev/null +++ b/sdk/python/timr_api/models/attachment_download.py @@ -0,0 +1,88 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AttachmentDownload(BaseModel): + """ + Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. + """ # noqa: E501 + url: StrictStr = Field(json_schema_extra={"examples": ["https://s3.eu-central-1.amazonaws.com/timr-attachments/01972ff0-14a2-7814-926c-11d07a1dc20b?X-Amz-Signature=..."]}) + __properties: ClassVar[List[str]] = ["url"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AttachmentDownload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AttachmentDownload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "url": obj.get("url") + }) + return _obj + + diff --git a/sdk/python/timr_api/models/attachment_metadata.py b/sdk/python/timr_api/models/attachment_metadata.py new file mode 100644 index 0000000..59371c9 --- /dev/null +++ b/sdk/python/timr_api/models/attachment_metadata.py @@ -0,0 +1,95 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AttachmentMetadata(BaseModel): + """ + Metadata of the attached file, as provided when it was uploaded. + """ # noqa: E501 + file_name: StrictStr = Field(json_schema_extra={"examples": ["before_cleanup.jpeg"]}) + content_type: StrictStr = Field(description="Media type of the file.", json_schema_extra={"examples": ["image/jpeg"]}) + size: StrictInt = Field(description="Size of the file in bytes.", json_schema_extra={"examples": [204800]}) + file_last_modified: datetime = Field(description="When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) ", json_schema_extra={"examples": ["2021-07-16T08:20:00Z"]}) + __properties: ClassVar[List[str]] = ["file_name", "content_type", "size", "file_last_modified"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AttachmentMetadata from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AttachmentMetadata from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "file_name": obj.get("file_name"), + "content_type": obj.get("content_type"), + "size": obj.get("size"), + "file_last_modified": obj.get("file_last_modified") + }) + return _obj + + diff --git a/sdk/python/timr_api/models/attachment_upload.py b/sdk/python/timr_api/models/attachment_upload.py new file mode 100644 index 0000000..6c8bcba --- /dev/null +++ b/sdk/python/timr_api/models/attachment_upload.py @@ -0,0 +1,93 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from datetime import datetime +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AttachmentUpload(BaseModel): + """ + Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. + """ # noqa: E501 + url: StrictStr = Field(json_schema_extra={"examples": ["https://s3.eu-central-1.amazonaws.com/timr-attachments/01972ff0-14a2-7814-926c-11d07a1dc20b?X-Amz-Signature=..."]}) + headers: Dict[str, StrictStr] = Field(description="Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). ", json_schema_extra={"examples": [{"Content-Type": "image/jpeg", "Content-Disposition": "attachment; filename=\"before_cleanup.jpeg\"; filename*=UTF-8''before_cleanup.jpeg"}]}) + expires_at: datetime = Field(description="When the URL stops being valid. RFC 3339 date-time (ISO-8601) ", json_schema_extra={"examples": ["2021-07-16T08:20:00Z"]}) + __properties: ClassVar[List[str]] = ["url", "headers", "expires_at"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AttachmentUpload from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AttachmentUpload from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "url": obj.get("url"), + "headers": obj.get("headers"), + "expires_at": obj.get("expires_at") + }) + return _obj + + diff --git a/sdk/python/timr_api/models/attachment_upload_response.py b/sdk/python/timr_api/models/attachment_upload_response.py new file mode 100644 index 0000000..88d36ae --- /dev/null +++ b/sdk/python/timr_api/models/attachment_upload_response.py @@ -0,0 +1,101 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field +from typing import Any, ClassVar, Dict, List +from uuid import UUID +from timr_api.models.attachment_metadata import AttachmentMetadata +from timr_api.models.attachment_upload import AttachmentUpload +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AttachmentUploadResponse(BaseModel): + """ + A registered upload of a file, with the pre-signed URL to upload the file to. + """ # noqa: E501 + id: UUID = Field(description="Unique identifier of the attachment. Treat it as an opaque string.", json_schema_extra={"examples": ["01972ff0-14a2-7814-926c-11d07a1dc20b"]}) + metadata: AttachmentMetadata + upload: AttachmentUpload + __properties: ClassVar[List[str]] = ["id", "metadata", "upload"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AttachmentUploadResponse from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of metadata + if self.metadata: + _dict['metadata'] = self.metadata.to_dict() + # override the default output from pydantic by calling `to_dict()` of upload + if self.upload: + _dict['upload'] = self.upload.to_dict() + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AttachmentUploadResponse from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "id": obj.get("id"), + "metadata": AttachmentMetadata.from_dict(obj["metadata"]) if obj.get("metadata") is not None else None, + "upload": AttachmentUpload.from_dict(obj["upload"]) if obj.get("upload") is not None else None + }) + return _obj + + diff --git a/sdk/python/timr_api/models/attachments_page.py b/sdk/python/timr_api/models/attachments_page.py new file mode 100644 index 0000000..89e1cee --- /dev/null +++ b/sdk/python/timr_api/models/attachments_page.py @@ -0,0 +1,102 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import pprint +import re # noqa: F401 +import json + +from pydantic import BaseModel, ConfigDict, Field, StrictStr +from typing import Any, ClassVar, Dict, List, Optional +from timr_api.models.attachment import Attachment +from typing import Optional, Set +from typing_extensions import Self +from pydantic_core import to_jsonable_python + +class AttachmentsPage(BaseModel): + """ + AttachmentsPage + """ # noqa: E501 + next_page_token: Optional[StrictStr] = Field(description="Token for the next page, or null when this is the last page.") + data: List[Attachment] + __properties: ClassVar[List[str]] = ["next_page_token", "data"] + + model_config = ConfigDict( + validate_by_name=True, + validate_by_alias=True, + validate_assignment=True, + protected_namespaces=(), + ) + + + def to_str(self) -> str: + """Returns the string representation of the model using alias""" + return pprint.pformat(self.model_dump(by_alias=True)) + + def to_json(self) -> str: + """Returns the JSON representation of the model using alias""" + return json.dumps(to_jsonable_python(self.to_dict())) + + @classmethod + def from_json(cls, json_str: str) -> Optional[Self]: + """Create an instance of AttachmentsPage from a JSON string""" + return cls.from_dict(json.loads(json_str)) + + def to_dict(self) -> Dict[str, Any]: + """Return the dictionary representation of the model using alias. + + This has the following differences from calling pydantic's + `self.model_dump(by_alias=True)`: + + * `None` is only added to the output dict for nullable fields that + were set at model initialization. Other fields with value `None` + are ignored. + """ + excluded_fields: Set[str] = set([ + ]) + + _dict = self.model_dump( + by_alias=True, + exclude=excluded_fields, + exclude_none=True, + ) + # override the default output from pydantic by calling `to_dict()` of each item in data (list) + _items = [] + if self.data: + for _item_data in self.data: + _items.append(_item_data.to_dict() if _item_data is not None else None) + _dict['data'] = _items + # set to None if next_page_token (nullable) is None + # and model_fields_set contains the field + if self.next_page_token is None and "next_page_token" in self.model_fields_set: + _dict['next_page_token'] = None + + return _dict + + @classmethod + def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: + """Create an instance of AttachmentsPage from a dict""" + if obj is None: + return None + + if not isinstance(obj, dict): + return cls.model_validate(obj) + + _obj = cls.model_validate({ + "next_page_token": obj.get("next_page_token"), + "data": [Attachment.from_dict(_item) for _item in obj["data"]] if obj.get("data") is not None else None + }) + return _obj + + diff --git a/sdk/python/timr_api/models/attachments_sort_column.py b/sdk/python/timr_api/models/attachments_sort_column.py new file mode 100644 index 0000000..75b6ac0 --- /dev/null +++ b/sdk/python/timr_api/models/attachments_sort_column.py @@ -0,0 +1,36 @@ +# coding: utf-8 + +""" + timr API + + REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + + Contact: info@timr.com + Generated by OpenAPI Generator (https://openapi-generator.tech) + + Do not edit the class manually. +""" # noqa: E501 + + +from __future__ import annotations +import json +from enum import Enum +from typing_extensions import Self + + +class AttachmentsSortColumn(str, Enum): + """ + Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + """ + + """ + allowed enum values + """ + UPLOADED_AT = 'uploaded_at' + + @classmethod + def from_json(cls, json_str: str) -> Self: + """Create an instance of AttachmentsSortColumn from a JSON string""" + return cls(json.loads(json_str)) + + diff --git a/sdk/swift/TimrApi/APIs/ProjectTimeAttachmentAPI.swift b/sdk/swift/TimrApi/APIs/ProjectTimeAttachmentAPI.swift new file mode 100644 index 0000000..5f9c781 --- /dev/null +++ b/sdk/swift/TimrApi/APIs/ProjectTimeAttachmentAPI.swift @@ -0,0 +1,222 @@ +// +// ProjectTimeAttachmentAPI.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +open class ProjectTimeAttachmentAPI { + + /** + Upload a Project Time Attachment + + - parameter projectTimeId: (path) ID of the Project Time. + - parameter attachmentMetadata: (body) Metadata of the file to upload. + - returns: AttachmentUploadResponse + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func createProjectTimeAttachment(projectTimeId: String, attachmentMetadata: AttachmentMetadata) async throws -> AttachmentUploadResponse { + return try await createProjectTimeAttachmentWithRequestBuilder(projectTimeId: projectTimeId, attachmentMetadata: attachmentMetadata).execute().body + } + + /** + Upload a Project Time Attachment + - POST /project-times/{project_time_id}/attachments + - Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - parameter projectTimeId: (path) ID of the Project Time. + - parameter attachmentMetadata: (body) Metadata of the file to upload. + - returns: RequestBuilder + */ + open class func createProjectTimeAttachmentWithRequestBuilder(projectTimeId: String, attachmentMetadata: AttachmentMetadata) -> RequestBuilder { + var localVariablePath = "/project-times/{project_time_id}/attachments" + let projectTimeIdPreEscape = "\(APIHelper.mapValueToPathItem(projectTimeId))" + let projectTimeIdPostEscape = projectTimeIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{project_time_id}", with: projectTimeIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters = JSONEncodingHelper.encodingParameters(forEncodableObject: attachmentMetadata) + + let localVariableUrlComponents = URLComponents(string: localVariableURLString) + + let localVariableNillableHeaders: [String: Any?] = [ + "Content-Type": "application/json", + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getBuilder() + + return localVariableRequestBuilder.init(method: "POST", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } + + /** + Delete a Project Time Attachment + + - parameter projectTimeId: (path) ID of the Project Time. + - parameter attachmentId: (path) ID of the Project Time Attachment. + - returns: Void + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func deleteProjectTimeAttachment(projectTimeId: String, attachmentId: UUID) async throws { + return try await deleteProjectTimeAttachmentWithRequestBuilder(projectTimeId: projectTimeId, attachmentId: attachmentId).execute().body + } + + /** + Delete a Project Time Attachment + - DELETE /project-times/{project_time_id}/attachments/{attachment_id} + - Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - parameter projectTimeId: (path) ID of the Project Time. + - parameter attachmentId: (path) ID of the Project Time Attachment. + - returns: RequestBuilder + */ + open class func deleteProjectTimeAttachmentWithRequestBuilder(projectTimeId: String, attachmentId: UUID) -> RequestBuilder { + var localVariablePath = "/project-times/{project_time_id}/attachments/{attachment_id}" + let projectTimeIdPreEscape = "\(APIHelper.mapValueToPathItem(projectTimeId))" + let projectTimeIdPostEscape = projectTimeIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{project_time_id}", with: projectTimeIdPostEscape, options: .literal, range: nil) + let attachmentIdPreEscape = "\(APIHelper.mapValueToPathItem(attachmentId))" + let attachmentIdPostEscape = attachmentIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{attachment_id}", with: attachmentIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters: [String: Any]? = nil + + let localVariableUrlComponents = URLComponents(string: localVariableURLString) + + let localVariableNillableHeaders: [String: Any?] = [ + : + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getNonDecodableBuilder() + + return localVariableRequestBuilder.init(method: "DELETE", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } + + /** + List Project Time Attachments + + - parameter projectTimeId: (path) ID of the Project Time. + - parameter pageToken: (query) Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + - parameter limit: (query) Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + - parameter sortDirection: (query) Direction to sort the entries in. (optional) + - parameter sortBy: (query) Property to sort the entries by. (optional) + - returns: AttachmentsPage + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func fetchProjectTimeAttachments(projectTimeId: String, pageToken: String? = nil, limit: Int? = nil, sortDirection: SortDirection? = nil, sortBy: AttachmentsSortColumn? = nil) async throws -> AttachmentsPage { + return try await fetchProjectTimeAttachmentsWithRequestBuilder(projectTimeId: projectTimeId, pageToken: pageToken, limit: limit, sortDirection: sortDirection, sortBy: sortBy).execute().body + } + + /** + List Project Time Attachments + - GET /project-times/{project_time_id}/attachments + - Lists the attachments of a running or completed Project Time whose upload has completed. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - responseHeaders: [Link(String)] + - parameter projectTimeId: (path) ID of the Project Time. + - parameter pageToken: (query) Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + - parameter limit: (query) Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + - parameter sortDirection: (query) Direction to sort the entries in. (optional) + - parameter sortBy: (query) Property to sort the entries by. (optional) + - returns: RequestBuilder + */ + open class func fetchProjectTimeAttachmentsWithRequestBuilder(projectTimeId: String, pageToken: String? = nil, limit: Int? = nil, sortDirection: SortDirection? = nil, sortBy: AttachmentsSortColumn? = nil) -> RequestBuilder { + var localVariablePath = "/project-times/{project_time_id}/attachments" + let projectTimeIdPreEscape = "\(APIHelper.mapValueToPathItem(projectTimeId))" + let projectTimeIdPostEscape = projectTimeIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{project_time_id}", with: projectTimeIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters: [String: Any]? = nil + + var localVariableUrlComponents = URLComponents(string: localVariableURLString) + let localVariableQueryParameters: [String: (wrappedValue: Any?, isExplode: Bool)] = [ + "page_token": (wrappedValue: pageToken?.encodeToJSON(), isExplode: true), + "limit": (wrappedValue: limit?.encodeToJSON(), isExplode: true), + "sort_direction": (wrappedValue: sortDirection?.encodeToJSON(), isExplode: true), + "sort_by": (wrappedValue: sortBy?.encodeToJSON(), isExplode: true), + ] + localVariableUrlComponents?.queryItems = APIHelper.mapValuesToQueryItems(localVariableQueryParameters) + + let localVariableNillableHeaders: [String: Any?] = [ + : + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getBuilder() + + return localVariableRequestBuilder.init(method: "GET", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } + + /** + Get a Project Time Attachment + + - parameter projectTimeId: (path) ID of the Project Time. + - parameter attachmentId: (path) ID of the Project Time Attachment. + - returns: Attachment + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func getProjectTimeAttachment(projectTimeId: String, attachmentId: UUID) async throws -> Attachment { + return try await getProjectTimeAttachmentWithRequestBuilder(projectTimeId: projectTimeId, attachmentId: attachmentId).execute().body + } + + /** + Get a Project Time Attachment + - GET /project-times/{project_time_id}/attachments/{attachment_id} + - Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - parameter projectTimeId: (path) ID of the Project Time. + - parameter attachmentId: (path) ID of the Project Time Attachment. + - returns: RequestBuilder + */ + open class func getProjectTimeAttachmentWithRequestBuilder(projectTimeId: String, attachmentId: UUID) -> RequestBuilder { + var localVariablePath = "/project-times/{project_time_id}/attachments/{attachment_id}" + let projectTimeIdPreEscape = "\(APIHelper.mapValueToPathItem(projectTimeId))" + let projectTimeIdPostEscape = projectTimeIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{project_time_id}", with: projectTimeIdPostEscape, options: .literal, range: nil) + let attachmentIdPreEscape = "\(APIHelper.mapValueToPathItem(attachmentId))" + let attachmentIdPostEscape = attachmentIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{attachment_id}", with: attachmentIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters: [String: Any]? = nil + + let localVariableUrlComponents = URLComponents(string: localVariableURLString) + + let localVariableNillableHeaders: [String: Any?] = [ + : + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getBuilder() + + return localVariableRequestBuilder.init(method: "GET", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } +} diff --git a/sdk/swift/TimrApi/APIs/TaskAttachmentAPI.swift b/sdk/swift/TimrApi/APIs/TaskAttachmentAPI.swift new file mode 100644 index 0000000..d2b856f --- /dev/null +++ b/sdk/swift/TimrApi/APIs/TaskAttachmentAPI.swift @@ -0,0 +1,222 @@ +// +// TaskAttachmentAPI.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +open class TaskAttachmentAPI { + + /** + Upload a Task Attachment + + - parameter taskId: (path) ID of the Task. + - parameter attachmentMetadata: (body) Metadata of the file to upload. + - returns: AttachmentUploadResponse + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func createTaskAttachment(taskId: String, attachmentMetadata: AttachmentMetadata) async throws -> AttachmentUploadResponse { + return try await createTaskAttachmentWithRequestBuilder(taskId: taskId, attachmentMetadata: attachmentMetadata).execute().body + } + + /** + Upload a Task Attachment + - POST /tasks/{task_id}/attachments + - Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - parameter taskId: (path) ID of the Task. + - parameter attachmentMetadata: (body) Metadata of the file to upload. + - returns: RequestBuilder + */ + open class func createTaskAttachmentWithRequestBuilder(taskId: String, attachmentMetadata: AttachmentMetadata) -> RequestBuilder { + var localVariablePath = "/tasks/{task_id}/attachments" + let taskIdPreEscape = "\(APIHelper.mapValueToPathItem(taskId))" + let taskIdPostEscape = taskIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{task_id}", with: taskIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters = JSONEncodingHelper.encodingParameters(forEncodableObject: attachmentMetadata) + + let localVariableUrlComponents = URLComponents(string: localVariableURLString) + + let localVariableNillableHeaders: [String: Any?] = [ + "Content-Type": "application/json", + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getBuilder() + + return localVariableRequestBuilder.init(method: "POST", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } + + /** + Delete a Task Attachment + + - parameter taskId: (path) ID of the Task. + - parameter attachmentId: (path) ID of the Task Attachment. + - returns: Void + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func deleteTaskAttachment(taskId: String, attachmentId: UUID) async throws { + return try await deleteTaskAttachmentWithRequestBuilder(taskId: taskId, attachmentId: attachmentId).execute().body + } + + /** + Delete a Task Attachment + - DELETE /tasks/{task_id}/attachments/{attachment_id} + - Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - parameter taskId: (path) ID of the Task. + - parameter attachmentId: (path) ID of the Task Attachment. + - returns: RequestBuilder + */ + open class func deleteTaskAttachmentWithRequestBuilder(taskId: String, attachmentId: UUID) -> RequestBuilder { + var localVariablePath = "/tasks/{task_id}/attachments/{attachment_id}" + let taskIdPreEscape = "\(APIHelper.mapValueToPathItem(taskId))" + let taskIdPostEscape = taskIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{task_id}", with: taskIdPostEscape, options: .literal, range: nil) + let attachmentIdPreEscape = "\(APIHelper.mapValueToPathItem(attachmentId))" + let attachmentIdPostEscape = attachmentIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{attachment_id}", with: attachmentIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters: [String: Any]? = nil + + let localVariableUrlComponents = URLComponents(string: localVariableURLString) + + let localVariableNillableHeaders: [String: Any?] = [ + : + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getNonDecodableBuilder() + + return localVariableRequestBuilder.init(method: "DELETE", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } + + /** + List Task Attachments + + - parameter taskId: (path) ID of the Task. + - parameter pageToken: (query) Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + - parameter limit: (query) Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + - parameter sortDirection: (query) Direction to sort the entries in. (optional) + - parameter sortBy: (query) Property to sort the entries by. (optional) + - returns: AttachmentsPage + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func fetchTaskAttachments(taskId: String, pageToken: String? = nil, limit: Int? = nil, sortDirection: SortDirection? = nil, sortBy: AttachmentsSortColumn? = nil) async throws -> AttachmentsPage { + return try await fetchTaskAttachmentsWithRequestBuilder(taskId: taskId, pageToken: pageToken, limit: limit, sortDirection: sortDirection, sortBy: sortBy).execute().body + } + + /** + List Task Attachments + - GET /tasks/{task_id}/attachments + - Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - responseHeaders: [Link(String)] + - parameter taskId: (path) ID of the Task. + - parameter pageToken: (query) Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. (optional) + - parameter limit: (query) Maximum number of entries per page. Values above 500 are capped at 500. (optional, default to 20) + - parameter sortDirection: (query) Direction to sort the entries in. (optional) + - parameter sortBy: (query) Property to sort the entries by. (optional) + - returns: RequestBuilder + */ + open class func fetchTaskAttachmentsWithRequestBuilder(taskId: String, pageToken: String? = nil, limit: Int? = nil, sortDirection: SortDirection? = nil, sortBy: AttachmentsSortColumn? = nil) -> RequestBuilder { + var localVariablePath = "/tasks/{task_id}/attachments" + let taskIdPreEscape = "\(APIHelper.mapValueToPathItem(taskId))" + let taskIdPostEscape = taskIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{task_id}", with: taskIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters: [String: Any]? = nil + + var localVariableUrlComponents = URLComponents(string: localVariableURLString) + let localVariableQueryParameters: [String: (wrappedValue: Any?, isExplode: Bool)] = [ + "page_token": (wrappedValue: pageToken?.encodeToJSON(), isExplode: true), + "limit": (wrappedValue: limit?.encodeToJSON(), isExplode: true), + "sort_direction": (wrappedValue: sortDirection?.encodeToJSON(), isExplode: true), + "sort_by": (wrappedValue: sortBy?.encodeToJSON(), isExplode: true), + ] + localVariableUrlComponents?.queryItems = APIHelper.mapValuesToQueryItems(localVariableQueryParameters) + + let localVariableNillableHeaders: [String: Any?] = [ + : + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getBuilder() + + return localVariableRequestBuilder.init(method: "GET", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } + + /** + Get a Task Attachment + + - parameter taskId: (path) ID of the Task. + - parameter attachmentId: (path) ID of the Task Attachment. + - returns: Attachment + */ + @available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *) + open class func getTaskAttachment(taskId: String, attachmentId: UUID) async throws -> Attachment { + return try await getTaskAttachmentWithRequestBuilder(taskId: taskId, attachmentId: attachmentId).execute().body + } + + /** + Get a Task Attachment + - GET /tasks/{task_id}/attachments/{attachment_id} + - Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + - OAuth: + - type: oauth2 + - name: OAuth2 + - OAuth: + - type: oauth2 + - name: OAuth2 + - parameter taskId: (path) ID of the Task. + - parameter attachmentId: (path) ID of the Task Attachment. + - returns: RequestBuilder + */ + open class func getTaskAttachmentWithRequestBuilder(taskId: String, attachmentId: UUID) -> RequestBuilder { + var localVariablePath = "/tasks/{task_id}/attachments/{attachment_id}" + let taskIdPreEscape = "\(APIHelper.mapValueToPathItem(taskId))" + let taskIdPostEscape = taskIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{task_id}", with: taskIdPostEscape, options: .literal, range: nil) + let attachmentIdPreEscape = "\(APIHelper.mapValueToPathItem(attachmentId))" + let attachmentIdPostEscape = attachmentIdPreEscape.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) ?? "" + localVariablePath = localVariablePath.replacingOccurrences(of: "{attachment_id}", with: attachmentIdPostEscape, options: .literal, range: nil) + let localVariableURLString = TimrAPI.basePath + localVariablePath + let localVariableParameters: [String: Any]? = nil + + let localVariableUrlComponents = URLComponents(string: localVariableURLString) + + let localVariableNillableHeaders: [String: Any?] = [ + : + ] + + let localVariableHeaderParameters = APIHelper.rejectNilHeaders(localVariableNillableHeaders) + + let localVariableRequestBuilder: RequestBuilder.Type = TimrAPI.requestBuilderFactory.getBuilder() + + return localVariableRequestBuilder.init(method: "GET", URLString: (localVariableUrlComponents?.string ?? localVariableURLString), parameters: localVariableParameters, headers: localVariableHeaderParameters, requiresAuthentication: true) + } +} diff --git a/sdk/swift/TimrApi/Models/Attachment.swift b/sdk/swift/TimrApi/Models/Attachment.swift new file mode 100644 index 0000000..82ba602 --- /dev/null +++ b/sdk/swift/TimrApi/Models/Attachment.swift @@ -0,0 +1,56 @@ +// +// Attachment.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +/** A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. */ +public struct Attachment: Codable, JSONEncodable, Hashable { + + /** Unique identifier. Treat it as an opaque string. */ + public var id: UUID + /** Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. */ + public var download: AttachmentDownload? + public var metadata: AttachmentMetadata + /** The User who uploaded the file, or null if that User no longer exists. */ + public var uploadedBy: UserPartial? + /** When the upload of the file completed. RFC 3339 date-time (ISO-8601) */ + public var uploadedAt: Date + + public init(id: UUID, download: AttachmentDownload?, metadata: AttachmentMetadata, uploadedBy: UserPartial?, uploadedAt: Date) { + self.id = id + self.download = download + self.metadata = metadata + self.uploadedBy = uploadedBy + self.uploadedAt = uploadedAt + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case id + case download + case metadata + case uploadedBy = "uploaded_by" + case uploadedAt = "uploaded_at" + } + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) + try container.encode(download, forKey: .download) + try container.encode(metadata, forKey: .metadata) + try container.encode(uploadedBy, forKey: .uploadedBy) + try container.encode(uploadedAt, forKey: .uploadedAt) + } +} + + +@available(iOS 13, tvOS 13, watchOS 6, macOS 10.15, *) +extension Attachment: Identifiable {} diff --git a/sdk/swift/TimrApi/Models/AttachmentDownload.swift b/sdk/swift/TimrApi/Models/AttachmentDownload.swift new file mode 100644 index 0000000..41d7e91 --- /dev/null +++ b/sdk/swift/TimrApi/Models/AttachmentDownload.swift @@ -0,0 +1,33 @@ +// +// AttachmentDownload.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +/** Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. */ +public struct AttachmentDownload: Codable, JSONEncodable, Hashable { + + public var url: String + + public init(url: String) { + self.url = url + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case url + } + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(url, forKey: .url) + } +} + diff --git a/sdk/swift/TimrApi/Models/AttachmentMetadata.swift b/sdk/swift/TimrApi/Models/AttachmentMetadata.swift new file mode 100644 index 0000000..27c260b --- /dev/null +++ b/sdk/swift/TimrApi/Models/AttachmentMetadata.swift @@ -0,0 +1,48 @@ +// +// AttachmentMetadata.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +/** Metadata of the attached file, as provided when it was uploaded. */ +public struct AttachmentMetadata: Codable, JSONEncodable, Hashable { + + public var fileName: String + /** Media type of the file. */ + public var contentType: String + /** Size of the file in bytes. */ + public var size: Int64 + /** When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) */ + public var fileLastModified: Date + + public init(fileName: String, contentType: String, size: Int64, fileLastModified: Date) { + self.fileName = fileName + self.contentType = contentType + self.size = size + self.fileLastModified = fileLastModified + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case fileName = "file_name" + case contentType = "content_type" + case size + case fileLastModified = "file_last_modified" + } + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(fileName, forKey: .fileName) + try container.encode(contentType, forKey: .contentType) + try container.encode(size, forKey: .size) + try container.encode(fileLastModified, forKey: .fileLastModified) + } +} + diff --git a/sdk/swift/TimrApi/Models/AttachmentUpload.swift b/sdk/swift/TimrApi/Models/AttachmentUpload.swift new file mode 100644 index 0000000..ae2f54c --- /dev/null +++ b/sdk/swift/TimrApi/Models/AttachmentUpload.swift @@ -0,0 +1,43 @@ +// +// AttachmentUpload.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +/** Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. */ +public struct AttachmentUpload: Codable, JSONEncodable, Hashable { + + public var url: String + /** Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). */ + public var headers: [String: String] + /** When the URL stops being valid. RFC 3339 date-time (ISO-8601) */ + public var expiresAt: Date + + public init(url: String, headers: [String: String], expiresAt: Date) { + self.url = url + self.headers = headers + self.expiresAt = expiresAt + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case url + case headers + case expiresAt = "expires_at" + } + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(url, forKey: .url) + try container.encode(headers, forKey: .headers) + try container.encode(expiresAt, forKey: .expiresAt) + } +} + diff --git a/sdk/swift/TimrApi/Models/AttachmentUploadResponse.swift b/sdk/swift/TimrApi/Models/AttachmentUploadResponse.swift new file mode 100644 index 0000000..49a05b8 --- /dev/null +++ b/sdk/swift/TimrApi/Models/AttachmentUploadResponse.swift @@ -0,0 +1,45 @@ +// +// AttachmentUploadResponse.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +/** A registered upload of a file, with the pre-signed URL to upload the file to. */ +public struct AttachmentUploadResponse: Codable, JSONEncodable, Hashable { + + /** Unique identifier of the attachment. Treat it as an opaque string. */ + public var id: UUID + public var metadata: AttachmentMetadata + public var upload: AttachmentUpload + + public init(id: UUID, metadata: AttachmentMetadata, upload: AttachmentUpload) { + self.id = id + self.metadata = metadata + self.upload = upload + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case id + case metadata + case upload + } + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(id, forKey: .id) + try container.encode(metadata, forKey: .metadata) + try container.encode(upload, forKey: .upload) + } +} + + +@available(iOS 13, tvOS 13, watchOS 6, macOS 10.15, *) +extension AttachmentUploadResponse: Identifiable {} diff --git a/sdk/swift/TimrApi/Models/AttachmentsPage.swift b/sdk/swift/TimrApi/Models/AttachmentsPage.swift new file mode 100644 index 0000000..ea2791c --- /dev/null +++ b/sdk/swift/TimrApi/Models/AttachmentsPage.swift @@ -0,0 +1,37 @@ +// +// AttachmentsPage.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +public struct AttachmentsPage: Codable, JSONEncodable, Hashable { + + /** Token for the next page, or null when this is the last page. */ + public var nextPageToken: String? + public var data: [Attachment] + + public init(nextPageToken: String?, data: [Attachment]) { + self.nextPageToken = nextPageToken + self.data = data + } + + public enum CodingKeys: String, CodingKey, CaseIterable { + case nextPageToken = "next_page_token" + case data + } + + // Encodable protocol methods + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(nextPageToken, forKey: .nextPageToken) + try container.encode(data, forKey: .data) + } +} + diff --git a/sdk/swift/TimrApi/Models/AttachmentsSortColumn.swift b/sdk/swift/TimrApi/Models/AttachmentsSortColumn.swift new file mode 100644 index 0000000..6bc1bd2 --- /dev/null +++ b/sdk/swift/TimrApi/Models/AttachmentsSortColumn.swift @@ -0,0 +1,16 @@ +// +// AttachmentsSortColumn.swift +// +// Generated by openapi-generator +// https://openapi-generator.tech +// + +import Foundation +#if canImport(AnyCodable) +import AnyCodable +#endif + +/** Sort property for Attachments. `uploaded_at` orders by the time the upload completed. */ +public enum AttachmentsSortColumn: String, Codable, CaseIterable { + case uploadedAt = "uploaded_at" +} diff --git a/sdk/typescript-fetch/package-lock.json b/sdk/typescript-fetch/package-lock.json index 2849c04..68c72eb 100644 --- a/sdk/typescript-fetch/package-lock.json +++ b/sdk/typescript-fetch/package-lock.json @@ -1,12 +1,12 @@ { "name": "timr-api", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "timr-api", - "version": "1.1.0", + "version": "1.2.0", "license": "Apache-2.0", "devDependencies": { "tsdown": "^0.23.1", diff --git a/sdk/typescript-fetch/package.json b/sdk/typescript-fetch/package.json index 7f20949..a1af022 100644 --- a/sdk/typescript-fetch/package.json +++ b/sdk/typescript-fetch/package.json @@ -1,6 +1,6 @@ { "name": "timr-api", - "version": "1.1.0", + "version": "1.2.0", "description": "Official TypeScript client for the timr API", "author": "troii Software GmbH", "homepage": "https://developer.timr.com", diff --git a/sdk/typescript-fetch/src/apis/ProjectTimeAttachmentApi.ts b/sdk/typescript-fetch/src/apis/ProjectTimeAttachmentApi.ts new file mode 100644 index 0000000..0dc3f39 --- /dev/null +++ b/sdk/typescript-fetch/src/apis/ProjectTimeAttachmentApi.ts @@ -0,0 +1,385 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime.js'; +import { + type Attachment, + AttachmentFromJSON, + AttachmentToJSON, +} from '../models/Attachment.js'; +import { + type AttachmentMetadata, + AttachmentMetadataFromJSON, + AttachmentMetadataToJSON, +} from '../models/AttachmentMetadata.js'; +import { + type AttachmentUploadResponse, + AttachmentUploadResponseFromJSON, + AttachmentUploadResponseToJSON, +} from '../models/AttachmentUploadResponse.js'; +import { + type AttachmentsPage, + AttachmentsPageFromJSON, + AttachmentsPageToJSON, +} from '../models/AttachmentsPage.js'; +import { + type AttachmentsSortColumn, + AttachmentsSortColumnFromJSON, + AttachmentsSortColumnToJSON, +} from '../models/AttachmentsSortColumn.js'; +import { + type SortDirection, + SortDirectionFromJSON, + SortDirectionToJSON, +} from '../models/SortDirection.js'; + +type QueryArguments = {} extends T + ? [query?: T, initOverrides?: RequestInit | runtime.InitOverrideFunction] + : [query: T, initOverrides?: RequestInit | runtime.InitOverrideFunction]; + +export interface CreateProjectTimeAttachmentRequest { + /** + * ID of the Project Time. + */ + projectTimeId: string; + /** + * + */ + attachmentMetadata: AttachmentMetadata; +} + +export interface DeleteProjectTimeAttachmentRequest { + /** + * ID of the Project Time. + */ + projectTimeId: string; + /** + * ID of the Project Time Attachment. + */ + attachmentId: string; +} + +export interface FetchProjectTimeAttachmentsRequest { + /** + * ID of the Project Time. + */ + projectTimeId: string; + /** + * Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + */ + pageToken?: string; + /** + * Maximum number of entries per page. Values above 500 are capped at 500. + */ + limit?: number; + /** + * Direction to sort the entries in. + */ + sortDirection?: SortDirection; + /** + * Property to sort the entries by. + */ + sortBy?: AttachmentsSortColumn; +} + +export type FetchProjectTimeAttachmentsQuery = Pick< + FetchProjectTimeAttachmentsRequest, + 'pageToken' | 'limit' | 'sortDirection' | 'sortBy' +>; + +export interface GetProjectTimeAttachmentRequest { + /** + * ID of the Project Time. + */ + projectTimeId: string; + /** + * ID of the Project Time Attachment. + */ + attachmentId: string; +} + +/** + * + */ +export class ProjectTimeAttachmentApi extends runtime.BaseAPI { + + /** + * Creates request options for createProjectTimeAttachment without sending the request + */ + async createProjectTimeAttachmentRequestOpts(requestParameters: CreateProjectTimeAttachmentRequest): Promise { + if (requestParameters['projectTimeId'] == null) { + throw new runtime.RequiredError( + 'projectTimeId', + 'Required parameter "projectTimeId" was null or undefined when calling createProjectTimeAttachment().' + ); + } + + if (requestParameters['attachmentMetadata'] == null) { + throw new runtime.RequiredError( + 'attachmentMetadata', + 'Required parameter "attachmentMetadata" was null or undefined when calling createProjectTimeAttachment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/project-times/{project_time_id}/attachments`; + urlPath = urlPath.replace('{project_time_id}', encodeURIComponent(String(requestParameters['projectTimeId']))); + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AttachmentMetadataToJSON(requestParameters['attachmentMetadata']), + }; + } + + /** + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + * Upload a Project Time Attachment + */ + async createProjectTimeAttachmentRaw(requestParameters: CreateProjectTimeAttachmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createProjectTimeAttachmentRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AttachmentUploadResponseFromJSON(jsonValue)); + } + + /** + * Registers the upload of a single file to a running or completed Project Time and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. Only images can be uploaded, and the size of a file and the number of attachments per Project Time are limited. + * Upload a Project Time Attachment + */ + async createProjectTimeAttachment(projectTimeId: string, attachmentMetadata: AttachmentMetadata, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createProjectTimeAttachmentRaw({ projectTimeId: projectTimeId, attachmentMetadata: attachmentMetadata, }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for deleteProjectTimeAttachment without sending the request + */ + async deleteProjectTimeAttachmentRequestOpts(requestParameters: DeleteProjectTimeAttachmentRequest): Promise { + if (requestParameters['projectTimeId'] == null) { + throw new runtime.RequiredError( + 'projectTimeId', + 'Required parameter "projectTimeId" was null or undefined when calling deleteProjectTimeAttachment().' + ); + } + + if (requestParameters['attachmentId'] == null) { + throw new runtime.RequiredError( + 'attachmentId', + 'Required parameter "attachmentId" was null or undefined when calling deleteProjectTimeAttachment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/project-times/{project_time_id}/attachments/{attachment_id}`; + urlPath = urlPath.replace('{project_time_id}', encodeURIComponent(String(requestParameters['projectTimeId']))); + urlPath = urlPath.replace('{attachment_id}', encodeURIComponent(String(requestParameters['attachmentId']))); + + return { + path: urlPath, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + * Delete a Project Time Attachment + */ + async deleteProjectTimeAttachmentRaw(requestParameters: DeleteProjectTimeAttachmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.deleteProjectTimeAttachmentRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + * Deletes a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. Attachments of a completed Project Time can only be deleted while its status is `changeable`. + * Delete a Project Time Attachment + */ + async deleteProjectTimeAttachment(projectTimeId: string, attachmentId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteProjectTimeAttachmentRaw({ projectTimeId: projectTimeId, attachmentId: attachmentId, }, initOverrides); + } + + /** + * Creates request options for fetchProjectTimeAttachments without sending the request + */ + async fetchProjectTimeAttachmentsRequestOpts(requestParameters: FetchProjectTimeAttachmentsRequest): Promise { + if (requestParameters['projectTimeId'] == null) { + throw new runtime.RequiredError( + 'projectTimeId', + 'Required parameter "projectTimeId" was null or undefined when calling fetchProjectTimeAttachments().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['pageToken'] != null) { + queryParameters['page_token'] = requestParameters['pageToken']; + } + + if (requestParameters['limit'] != null) { + queryParameters['limit'] = requestParameters['limit']; + } + + if (requestParameters['sortDirection'] != null) { + queryParameters['sort_direction'] = requestParameters['sortDirection']; + } + + if (requestParameters['sortBy'] != null) { + queryParameters['sort_by'] = requestParameters['sortBy']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/project-times/{project_time_id}/attachments`; + urlPath = urlPath.replace('{project_time_id}', encodeURIComponent(String(requestParameters['projectTimeId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Lists the attachments of a running or completed Project Time whose upload has completed. + * List Project Time Attachments + */ + async fetchProjectTimeAttachmentsRaw(requestParameters: FetchProjectTimeAttachmentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.fetchProjectTimeAttachmentsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AttachmentsPageFromJSON(jsonValue)); + } + + /** + * Lists the attachments of a running or completed Project Time whose upload has completed. + * List Project Time Attachments + */ + async fetchProjectTimeAttachments(projectTimeId: string, ...[query, initOverrides]: QueryArguments): Promise { + const response = await this.fetchProjectTimeAttachmentsRaw({ ...query, projectTimeId: projectTimeId, }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getProjectTimeAttachment without sending the request + */ + async getProjectTimeAttachmentRequestOpts(requestParameters: GetProjectTimeAttachmentRequest): Promise { + if (requestParameters['projectTimeId'] == null) { + throw new runtime.RequiredError( + 'projectTimeId', + 'Required parameter "projectTimeId" was null or undefined when calling getProjectTimeAttachment().' + ); + } + + if (requestParameters['attachmentId'] == null) { + throw new runtime.RequiredError( + 'attachmentId', + 'Required parameter "attachmentId" was null or undefined when calling getProjectTimeAttachment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/project-times/{project_time_id}/attachments/{attachment_id}`; + urlPath = urlPath.replace('{project_time_id}', encodeURIComponent(String(requestParameters['projectTimeId']))); + urlPath = urlPath.replace('{attachment_id}', encodeURIComponent(String(requestParameters['attachmentId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + * Get a Project Time Attachment + */ + async getProjectTimeAttachmentRaw(requestParameters: GetProjectTimeAttachmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getProjectTimeAttachmentRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AttachmentFromJSON(jsonValue)); + } + + /** + * Returns a single attachment of a running or completed Project Time. Only attachments whose upload has completed are found. + * Get a Project Time Attachment + */ + async getProjectTimeAttachment(projectTimeId: string, attachmentId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getProjectTimeAttachmentRaw({ projectTimeId: projectTimeId, attachmentId: attachmentId, }, initOverrides); + return await response.value(); + } + +} diff --git a/sdk/typescript-fetch/src/apis/TaskAttachmentApi.ts b/sdk/typescript-fetch/src/apis/TaskAttachmentApi.ts new file mode 100644 index 0000000..43fad63 --- /dev/null +++ b/sdk/typescript-fetch/src/apis/TaskAttachmentApi.ts @@ -0,0 +1,385 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import * as runtime from '../runtime.js'; +import { + type Attachment, + AttachmentFromJSON, + AttachmentToJSON, +} from '../models/Attachment.js'; +import { + type AttachmentMetadata, + AttachmentMetadataFromJSON, + AttachmentMetadataToJSON, +} from '../models/AttachmentMetadata.js'; +import { + type AttachmentUploadResponse, + AttachmentUploadResponseFromJSON, + AttachmentUploadResponseToJSON, +} from '../models/AttachmentUploadResponse.js'; +import { + type AttachmentsPage, + AttachmentsPageFromJSON, + AttachmentsPageToJSON, +} from '../models/AttachmentsPage.js'; +import { + type AttachmentsSortColumn, + AttachmentsSortColumnFromJSON, + AttachmentsSortColumnToJSON, +} from '../models/AttachmentsSortColumn.js'; +import { + type SortDirection, + SortDirectionFromJSON, + SortDirectionToJSON, +} from '../models/SortDirection.js'; + +type QueryArguments = {} extends T + ? [query?: T, initOverrides?: RequestInit | runtime.InitOverrideFunction] + : [query: T, initOverrides?: RequestInit | runtime.InitOverrideFunction]; + +export interface CreateTaskAttachmentRequest { + /** + * ID of the Task. + */ + taskId: string; + /** + * + */ + attachmentMetadata: AttachmentMetadata; +} + +export interface DeleteTaskAttachmentRequest { + /** + * ID of the Task. + */ + taskId: string; + /** + * ID of the Task Attachment. + */ + attachmentId: string; +} + +export interface FetchTaskAttachmentsRequest { + /** + * ID of the Task. + */ + taskId: string; + /** + * Token identifying the page to return. Take it from the 'next_page_token' field of the previous response. + */ + pageToken?: string; + /** + * Maximum number of entries per page. Values above 500 are capped at 500. + */ + limit?: number; + /** + * Direction to sort the entries in. + */ + sortDirection?: SortDirection; + /** + * Property to sort the entries by. + */ + sortBy?: AttachmentsSortColumn; +} + +export type FetchTaskAttachmentsQuery = Pick< + FetchTaskAttachmentsRequest, + 'pageToken' | 'limit' | 'sortDirection' | 'sortBy' +>; + +export interface GetTaskAttachmentRequest { + /** + * ID of the Task. + */ + taskId: string; + /** + * ID of the Task Attachment. + */ + attachmentId: string; +} + +/** + * + */ +export class TaskAttachmentApi extends runtime.BaseAPI { + + /** + * Creates request options for createTaskAttachment without sending the request + */ + async createTaskAttachmentRequestOpts(requestParameters: CreateTaskAttachmentRequest): Promise { + if (requestParameters['taskId'] == null) { + throw new runtime.RequiredError( + 'taskId', + 'Required parameter "taskId" was null or undefined when calling createTaskAttachment().' + ); + } + + if (requestParameters['attachmentMetadata'] == null) { + throw new runtime.RequiredError( + 'attachmentMetadata', + 'Required parameter "attachmentMetadata" was null or undefined when calling createTaskAttachment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + headerParameters['Content-Type'] = 'application/json'; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/tasks/{task_id}/attachments`; + urlPath = urlPath.replace('{task_id}', encodeURIComponent(String(requestParameters['taskId']))); + + return { + path: urlPath, + method: 'POST', + headers: headerParameters, + query: queryParameters, + body: AttachmentMetadataToJSON(requestParameters['attachmentMetadata']), + }; + } + + /** + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + * Upload a Task Attachment + */ + async createTaskAttachmentRaw(requestParameters: CreateTaskAttachmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.createTaskAttachmentRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AttachmentUploadResponseFromJSON(jsonValue)); + } + + /** + * Registers the upload of a single file to the Task and returns a pre-signed URL to upload it to. Upload the file with a PUT request to `upload.url`, sending exactly the headers in `upload.headers`, before `upload.expires_at`. The attachment is only returned by the other endpoints once its upload has completed. Uploads that are not completed are discarded automatically. The size of a file and the number of attachments per Task are limited. + * Upload a Task Attachment + */ + async createTaskAttachment(taskId: string, attachmentMetadata: AttachmentMetadata, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.createTaskAttachmentRaw({ taskId: taskId, attachmentMetadata: attachmentMetadata, }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for deleteTaskAttachment without sending the request + */ + async deleteTaskAttachmentRequestOpts(requestParameters: DeleteTaskAttachmentRequest): Promise { + if (requestParameters['taskId'] == null) { + throw new runtime.RequiredError( + 'taskId', + 'Required parameter "taskId" was null or undefined when calling deleteTaskAttachment().' + ); + } + + if (requestParameters['attachmentId'] == null) { + throw new runtime.RequiredError( + 'attachmentId', + 'Required parameter "attachmentId" was null or undefined when calling deleteTaskAttachment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/tasks/{task_id}/attachments/{attachment_id}`; + urlPath = urlPath.replace('{task_id}', encodeURIComponent(String(requestParameters['taskId']))); + urlPath = urlPath.replace('{attachment_id}', encodeURIComponent(String(requestParameters['attachmentId']))); + + return { + path: urlPath, + method: 'DELETE', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + * Delete a Task Attachment + */ + async deleteTaskAttachmentRaw(requestParameters: DeleteTaskAttachmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.deleteTaskAttachmentRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.VoidApiResponse(response); + } + + /** + * Deletes a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be deleted on the parent Task itself. + * Delete a Task Attachment + */ + async deleteTaskAttachment(taskId: string, attachmentId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + await this.deleteTaskAttachmentRaw({ taskId: taskId, attachmentId: attachmentId, }, initOverrides); + } + + /** + * Creates request options for fetchTaskAttachments without sending the request + */ + async fetchTaskAttachmentsRequestOpts(requestParameters: FetchTaskAttachmentsRequest): Promise { + if (requestParameters['taskId'] == null) { + throw new runtime.RequiredError( + 'taskId', + 'Required parameter "taskId" was null or undefined when calling fetchTaskAttachments().' + ); + } + + const queryParameters: any = {}; + + if (requestParameters['pageToken'] != null) { + queryParameters['page_token'] = requestParameters['pageToken']; + } + + if (requestParameters['limit'] != null) { + queryParameters['limit'] = requestParameters['limit']; + } + + if (requestParameters['sortDirection'] != null) { + queryParameters['sort_direction'] = requestParameters['sortDirection']; + } + + if (requestParameters['sortBy'] != null) { + queryParameters['sort_by'] = requestParameters['sortBy']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/tasks/{task_id}/attachments`; + urlPath = urlPath.replace('{task_id}', encodeURIComponent(String(requestParameters['taskId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + * List Task Attachments + */ + async fetchTaskAttachmentsRaw(requestParameters: FetchTaskAttachmentsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.fetchTaskAttachmentsRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AttachmentsPageFromJSON(jsonValue)); + } + + /** + * Lists the attachments whose upload has completed. Only attachments attached directly to the Task are returned; attachments of parent Tasks are not included and have to be fetched from the parent Task itself. + * List Task Attachments + */ + async fetchTaskAttachments(taskId: string, ...[query, initOverrides]: QueryArguments): Promise { + const response = await this.fetchTaskAttachmentsRaw({ ...query, taskId: taskId, }, initOverrides); + return await response.value(); + } + + /** + * Creates request options for getTaskAttachment without sending the request + */ + async getTaskAttachmentRequestOpts(requestParameters: GetTaskAttachmentRequest): Promise { + if (requestParameters['taskId'] == null) { + throw new runtime.RequiredError( + 'taskId', + 'Required parameter "taskId" was null or undefined when calling getTaskAttachment().' + ); + } + + if (requestParameters['attachmentId'] == null) { + throw new runtime.RequiredError( + 'attachmentId', + 'Required parameter "attachmentId" was null or undefined when calling getTaskAttachment().' + ); + } + + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + if (this.configuration && this.configuration.accessToken) { + // oauth required + headerParameters["Authorization"] = await this.configuration.accessToken("OAuth2", []); + } + + + let urlPath = `/tasks/{task_id}/attachments/{attachment_id}`; + urlPath = urlPath.replace('{task_id}', encodeURIComponent(String(requestParameters['taskId']))); + urlPath = urlPath.replace('{attachment_id}', encodeURIComponent(String(requestParameters['attachmentId']))); + + return { + path: urlPath, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }; + } + + /** + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + * Get a Task Attachment + */ + async getTaskAttachmentRaw(requestParameters: GetTaskAttachmentRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const requestOptions = await this.getTaskAttachmentRequestOpts(requestParameters); + const response = await this.request(requestOptions, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AttachmentFromJSON(jsonValue)); + } + + /** + * Returns a single attachment of the Task. Only attachments whose upload has completed and that are attached directly to the Task are found; an attachment of a parent Task has to be fetched from the parent Task itself. + * Get a Task Attachment + */ + async getTaskAttachment(taskId: string, attachmentId: string, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.getTaskAttachmentRaw({ taskId: taskId, attachmentId: attachmentId, }, initOverrides); + return await response.value(); + } + +} diff --git a/sdk/typescript-fetch/src/apis/index.ts b/sdk/typescript-fetch/src/apis/index.ts index 35044e1..ba2923c 100644 --- a/sdk/typescript-fetch/src/apis/index.ts +++ b/sdk/typescript-fetch/src/apis/index.ts @@ -5,7 +5,9 @@ export * from './DriveLogApi.js'; export * from './DriveLogCategoryApi.js'; export * from './HolidayCalendarApi.js'; export * from './ProjectTimeApi.js'; +export * from './ProjectTimeAttachmentApi.js'; export * from './TaskApi.js'; +export * from './TaskAttachmentApi.js'; export * from './TaskToLeaderAssignmentApi.js'; export * from './TaskToTeamAssignmentApi.js'; export * from './TaskToUserAssignmentApi.js'; diff --git a/sdk/typescript-fetch/src/models/Attachment.ts b/sdk/typescript-fetch/src/models/Attachment.ts new file mode 100644 index 0000000..610018b --- /dev/null +++ b/sdk/typescript-fetch/src/models/Attachment.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues, parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime.js'; +import type { AttachmentMetadata } from './AttachmentMetadata.js'; +import { + AttachmentMetadataFromJSON, + AttachmentMetadataFromJSONTyped, + AttachmentMetadataToJSON, + AttachmentMetadataToJSONTyped, +} from './AttachmentMetadata.js'; +import type { AttachmentDownload } from './AttachmentDownload.js'; +import { + AttachmentDownloadFromJSON, + AttachmentDownloadFromJSONTyped, + AttachmentDownloadToJSON, + AttachmentDownloadToJSONTyped, +} from './AttachmentDownload.js'; +import type { UserPartial } from './UserPartial.js'; +import { + UserPartialFromJSON, + UserPartialFromJSONTyped, + UserPartialToJSON, + UserPartialToJSONTyped, +} from './UserPartial.js'; + +/** + * A file attached to an entity, such as a Task or a Project Time. Only attachments whose upload has completed are returned. + * + * @export + * @interface Attachment + */ +export interface Attachment { + /** + * Unique identifier. Treat it as an opaque string. + */ + id: string; + /** + * Temporary URL to download the file, or null if the file cannot be downloaded. Clients have to handle null, as future versions may also return attachments whose upload has not completed yet. + * + */ + download: AttachmentDownload | null; + /** + * + */ + metadata: AttachmentMetadata; + /** + * The User who uploaded the file, or null if that User no longer exists. + */ + uploadedBy: UserPartial | null; + /** + * When the upload of the file completed. RFC 3339 date-time (ISO-8601) + * + */ + uploadedAt: Date; +} + +/** + * Check if a given object implements the Attachment interface. + */ +export function instanceOfAttachment(value: object): value is Attachment { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('download' in value) || value['download'] === undefined) return false; + if (!('metadata' in value) || value['metadata'] === undefined) return false; + if ((!('uploadedBy' in (value as Record)) && !('uploaded_by' in (value as Record))) || ((value as Record)['uploadedBy'] === undefined && (value as Record)['uploaded_by'] === undefined)) return false; + if ((!('uploadedAt' in (value as Record)) && !('uploaded_at' in (value as Record))) || ((value as Record)['uploadedAt'] === undefined && (value as Record)['uploaded_at'] === undefined)) return false; + return true; +} + +export function AttachmentFromJSON(json: any): Attachment { + return AttachmentFromJSONTyped(json, false); +} + +export function AttachmentFromJSONTyped(json: any, ignoreDiscriminator: boolean): Attachment { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'download': AttachmentDownloadFromJSON(json['download']), + 'metadata': AttachmentMetadataFromJSON(json['metadata']), + 'uploadedBy': UserPartialFromJSON(json['uploaded_by']), + 'uploadedAt': (json['uploaded_at'] == null ? json['uploaded_at'] : parseDateTime(json['uploaded_at'])), + }; +} + +export function AttachmentToJSON(json: any): Attachment { + return AttachmentToJSONTyped(json, false); +} + +export function AttachmentToJSONTyped(value?: Attachment | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'download': AttachmentDownloadToJSON(value['download']), + 'metadata': AttachmentMetadataToJSON(value['metadata']), + 'uploaded_by': UserPartialToJSON(value['uploadedBy']), + 'uploaded_at': value['uploadedAt'] == null ? value['uploadedAt'] : serializeDateTime(value['uploadedAt']), + }; +} + diff --git a/sdk/typescript-fetch/src/models/AttachmentDownload.ts b/sdk/typescript-fetch/src/models/AttachmentDownload.ts new file mode 100644 index 0000000..d62516e --- /dev/null +++ b/sdk/typescript-fetch/src/models/AttachmentDownload.ts @@ -0,0 +1,64 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime.js'; +/** + * Pre-signed URL to download the file directly from the storage, without further authentication. The URL is only valid for a limited time; request the attachment again to get a new URL. + * + * @export + * @interface AttachmentDownload + */ +export interface AttachmentDownload { + /** + * + */ + url: string; +} + +/** + * Check if a given object implements the AttachmentDownload interface. + */ +export function instanceOfAttachmentDownload(value: object): value is AttachmentDownload { + if (!('url' in value) || value['url'] === undefined) return false; + return true; +} + +export function AttachmentDownloadFromJSON(json: any): AttachmentDownload { + return AttachmentDownloadFromJSONTyped(json, false); +} + +export function AttachmentDownloadFromJSONTyped(json: any, ignoreDiscriminator: boolean): AttachmentDownload { + if (json == null) { + return json; + } + return { + + 'url': json['url'], + }; +} + +export function AttachmentDownloadToJSON(json: any): AttachmentDownload { + return AttachmentDownloadToJSONTyped(json, false); +} + +export function AttachmentDownloadToJSONTyped(value?: AttachmentDownload | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'url': value['url'], + }; +} + diff --git a/sdk/typescript-fetch/src/models/AttachmentMetadata.ts b/sdk/typescript-fetch/src/models/AttachmentMetadata.ts new file mode 100644 index 0000000..6964ef4 --- /dev/null +++ b/sdk/typescript-fetch/src/models/AttachmentMetadata.ts @@ -0,0 +1,85 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues, parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime.js'; +/** + * Metadata of the attached file, as provided when it was uploaded. + * @export + * @interface AttachmentMetadata + */ +export interface AttachmentMetadata { + /** + * + */ + fileName: string; + /** + * Media type of the file. + */ + contentType: string; + /** + * Size of the file in bytes. + */ + size: number; + /** + * When the file was last modified on the device it was uploaded from. RFC 3339 date-time (ISO-8601) + * + */ + fileLastModified: Date; +} + +/** + * Check if a given object implements the AttachmentMetadata interface. + */ +export function instanceOfAttachmentMetadata(value: object): value is AttachmentMetadata { + if ((!('fileName' in (value as Record)) && !('file_name' in (value as Record))) || ((value as Record)['fileName'] === undefined && (value as Record)['file_name'] === undefined)) return false; + if ((!('contentType' in (value as Record)) && !('content_type' in (value as Record))) || ((value as Record)['contentType'] === undefined && (value as Record)['content_type'] === undefined)) return false; + if (!('size' in value) || value['size'] === undefined) return false; + if ((!('fileLastModified' in (value as Record)) && !('file_last_modified' in (value as Record))) || ((value as Record)['fileLastModified'] === undefined && (value as Record)['file_last_modified'] === undefined)) return false; + return true; +} + +export function AttachmentMetadataFromJSON(json: any): AttachmentMetadata { + return AttachmentMetadataFromJSONTyped(json, false); +} + +export function AttachmentMetadataFromJSONTyped(json: any, ignoreDiscriminator: boolean): AttachmentMetadata { + if (json == null) { + return json; + } + return { + + 'fileName': json['file_name'], + 'contentType': json['content_type'], + 'size': json['size'], + 'fileLastModified': (json['file_last_modified'] == null ? json['file_last_modified'] : parseDateTime(json['file_last_modified'])), + }; +} + +export function AttachmentMetadataToJSON(json: any): AttachmentMetadata { + return AttachmentMetadataToJSONTyped(json, false); +} + +export function AttachmentMetadataToJSONTyped(value?: AttachmentMetadata | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'file_name': value['fileName'], + 'content_type': value['contentType'], + 'size': value['size'], + 'file_last_modified': value['fileLastModified'] == null ? value['fileLastModified'] : serializeDateTime(value['fileLastModified']), + }; +} + diff --git a/sdk/typescript-fetch/src/models/AttachmentUpload.ts b/sdk/typescript-fetch/src/models/AttachmentUpload.ts new file mode 100644 index 0000000..dc35b0a --- /dev/null +++ b/sdk/typescript-fetch/src/models/AttachmentUpload.ts @@ -0,0 +1,80 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues, parseDate, parseDateTime, serializeDate, serializeDateTime } from '../runtime.js'; +/** + * Pre-signed URL to upload the file directly to the storage, without further authentication. Upload the file with a PUT request, sending exactly the given headers, before `expires_at`. + * + * @export + * @interface AttachmentUpload + */ +export interface AttachmentUpload { + /** + * + */ + url: string; + /** + * Headers to send with the upload request, with exactly these values. Which headers are included can change, so send all of them. The upload is also signed for `Host` and `Content-Length` (`metadata.size`), which HTTP clients set automatically; adding them manually can break the request. All values are strings, as HTTP header values are text ([RFC 9110, section 5.5](https://www.rfc-editor.org/rfc/rfc9110#section-5.5)). + * + */ + headers: { [key: string]: string; }; + /** + * When the URL stops being valid. RFC 3339 date-time (ISO-8601) + * + */ + expiresAt: Date; +} + +/** + * Check if a given object implements the AttachmentUpload interface. + */ +export function instanceOfAttachmentUpload(value: object): value is AttachmentUpload { + if (!('url' in value) || value['url'] === undefined) return false; + if (!('headers' in value) || value['headers'] === undefined) return false; + if ((!('expiresAt' in (value as Record)) && !('expires_at' in (value as Record))) || ((value as Record)['expiresAt'] === undefined && (value as Record)['expires_at'] === undefined)) return false; + return true; +} + +export function AttachmentUploadFromJSON(json: any): AttachmentUpload { + return AttachmentUploadFromJSONTyped(json, false); +} + +export function AttachmentUploadFromJSONTyped(json: any, ignoreDiscriminator: boolean): AttachmentUpload { + if (json == null) { + return json; + } + return { + + 'url': json['url'], + 'headers': json['headers'], + 'expiresAt': (json['expires_at'] == null ? json['expires_at'] : parseDateTime(json['expires_at'])), + }; +} + +export function AttachmentUploadToJSON(json: any): AttachmentUpload { + return AttachmentUploadToJSONTyped(json, false); +} + +export function AttachmentUploadToJSONTyped(value?: AttachmentUpload | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'url': value['url'], + 'headers': value['headers'], + 'expires_at': value['expiresAt'] == null ? value['expiresAt'] : serializeDateTime(value['expiresAt']), + }; +} + diff --git a/sdk/typescript-fetch/src/models/AttachmentUploadResponse.ts b/sdk/typescript-fetch/src/models/AttachmentUploadResponse.ts new file mode 100644 index 0000000..18fb3db --- /dev/null +++ b/sdk/typescript-fetch/src/models/AttachmentUploadResponse.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime.js'; +import type { AttachmentUpload } from './AttachmentUpload.js'; +import { + AttachmentUploadFromJSON, + AttachmentUploadFromJSONTyped, + AttachmentUploadToJSON, + AttachmentUploadToJSONTyped, +} from './AttachmentUpload.js'; +import type { AttachmentMetadata } from './AttachmentMetadata.js'; +import { + AttachmentMetadataFromJSON, + AttachmentMetadataFromJSONTyped, + AttachmentMetadataToJSON, + AttachmentMetadataToJSONTyped, +} from './AttachmentMetadata.js'; + +/** + * A registered upload of a file, with the pre-signed URL to upload the file to. + * @export + * @interface AttachmentUploadResponse + */ +export interface AttachmentUploadResponse { + /** + * Unique identifier of the attachment. Treat it as an opaque string. + */ + id: string; + /** + * + */ + metadata: AttachmentMetadata; + /** + * + */ + upload: AttachmentUpload; +} + +/** + * Check if a given object implements the AttachmentUploadResponse interface. + */ +export function instanceOfAttachmentUploadResponse(value: object): value is AttachmentUploadResponse { + if (!('id' in value) || value['id'] === undefined) return false; + if (!('metadata' in value) || value['metadata'] === undefined) return false; + if (!('upload' in value) || value['upload'] === undefined) return false; + return true; +} + +export function AttachmentUploadResponseFromJSON(json: any): AttachmentUploadResponse { + return AttachmentUploadResponseFromJSONTyped(json, false); +} + +export function AttachmentUploadResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AttachmentUploadResponse { + if (json == null) { + return json; + } + return { + + 'id': json['id'], + 'metadata': AttachmentMetadataFromJSON(json['metadata']), + 'upload': AttachmentUploadFromJSON(json['upload']), + }; +} + +export function AttachmentUploadResponseToJSON(json: any): AttachmentUploadResponse { + return AttachmentUploadResponseToJSONTyped(json, false); +} + +export function AttachmentUploadResponseToJSONTyped(value?: AttachmentUploadResponse | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'id': value['id'], + 'metadata': AttachmentMetadataToJSON(value['metadata']), + 'upload': AttachmentUploadToJSON(value['upload']), + }; +} + diff --git a/sdk/typescript-fetch/src/models/AttachmentsPage.ts b/sdk/typescript-fetch/src/models/AttachmentsPage.ts new file mode 100644 index 0000000..c5d40ae --- /dev/null +++ b/sdk/typescript-fetch/src/models/AttachmentsPage.ts @@ -0,0 +1,78 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime.js'; +import type { Attachment } from './Attachment.js'; +import { + AttachmentFromJSON, + AttachmentFromJSONTyped, + AttachmentToJSON, + AttachmentToJSONTyped, +} from './Attachment.js'; + +/** + * + * @export + * @interface AttachmentsPage + */ +export interface AttachmentsPage { + /** + * Token for the next page, or null when this is the last page. + */ + nextPageToken: string | null; + /** + * + */ + data: Array; +} + +/** + * Check if a given object implements the AttachmentsPage interface. + */ +export function instanceOfAttachmentsPage(value: object): value is AttachmentsPage { + if ((!('nextPageToken' in (value as Record)) && !('next_page_token' in (value as Record))) || ((value as Record)['nextPageToken'] === undefined && (value as Record)['next_page_token'] === undefined)) return false; + if (!('data' in value) || value['data'] === undefined) return false; + return true; +} + +export function AttachmentsPageFromJSON(json: any): AttachmentsPage { + return AttachmentsPageFromJSONTyped(json, false); +} + +export function AttachmentsPageFromJSONTyped(json: any, ignoreDiscriminator: boolean): AttachmentsPage { + if (json == null) { + return json; + } + return { + + 'nextPageToken': json['next_page_token'], + 'data': ((json['data'] as Array).map(AttachmentFromJSON)), + }; +} + +export function AttachmentsPageToJSON(json: any): AttachmentsPage { + return AttachmentsPageToJSONTyped(json, false); +} + +export function AttachmentsPageToJSONTyped(value?: AttachmentsPage | null, ignoreDiscriminator: boolean = false): any { + if (value == null) { + return value; + } + + return { + + 'next_page_token': value['nextPageToken'], + 'data': ((value['data'] as Array).map(AttachmentToJSON)), + }; +} + diff --git a/sdk/typescript-fetch/src/models/AttachmentsSortColumn.ts b/sdk/typescript-fetch/src/models/AttachmentsSortColumn.ts new file mode 100644 index 0000000..dc25b36 --- /dev/null +++ b/sdk/typescript-fetch/src/models/AttachmentsSortColumn.ts @@ -0,0 +1,51 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * timr API + * REST API for the timr time tracking service. It exposes the recordings a user makes (working times, project times, drive logs) together with the master data they refer to (users, teams, tasks, cars, working time types, work schedule models, holiday calendars). + * + * Contact: info@timr.com + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +/** + * Sort property for Attachments. `uploaded_at` orders by the time the upload completed. + * @export + */ +export const AttachmentsSortColumn = { + UploadedAt: 'uploaded_at', +} as const; +export type AttachmentsSortColumn = typeof AttachmentsSortColumn[keyof typeof AttachmentsSortColumn]; + + +export function instanceOfAttachmentsSortColumn(value: any): boolean { + for (const key in AttachmentsSortColumn) { + if (Object.prototype.hasOwnProperty.call(AttachmentsSortColumn, key)) { + if (AttachmentsSortColumn[key as keyof typeof AttachmentsSortColumn] === value) { + return true; + } + } + } + return false; +} + +export function AttachmentsSortColumnFromJSON(json: any): AttachmentsSortColumn { + return AttachmentsSortColumnFromJSONTyped(json, false); +} + +export function AttachmentsSortColumnFromJSONTyped(json: any, ignoreDiscriminator: boolean): AttachmentsSortColumn { + return json as AttachmentsSortColumn; +} + +export function AttachmentsSortColumnToJSON(value?: AttachmentsSortColumn | null): any { + return value as any; +} + +export function AttachmentsSortColumnToJSONTyped(value: any, ignoreDiscriminator: boolean): AttachmentsSortColumn { + return value as AttachmentsSortColumn; +} + diff --git a/sdk/typescript-fetch/src/models/index.ts b/sdk/typescript-fetch/src/models/index.ts index cf4221b..58b6239 100644 --- a/sdk/typescript-fetch/src/models/index.ts +++ b/sdk/typescript-fetch/src/models/index.ts @@ -1,6 +1,13 @@ /* tslint:disable */ /* eslint-disable */ export * from './Accounts.js'; +export * from './Attachment.js'; +export * from './AttachmentDownload.js'; +export * from './AttachmentMetadata.js'; +export * from './AttachmentUpload.js'; +export * from './AttachmentUploadResponse.js'; +export * from './AttachmentsPage.js'; +export * from './AttachmentsSortColumn.js'; export * from './BreakTime.js'; export * from './BreakTimeAutomatic.js'; export * from './BreakTimeBase.js'; diff --git a/sdk/versions.properties b/sdk/versions.properties index 8bd55ab..c689166 100644 --- a/sdk/versions.properties +++ b/sdk/versions.properties @@ -3,10 +3,10 @@ # a generator upgrade that renames a method, a language baseline that drops a runtime, or a package # rename all break callers while the contract stands still, and a derived version has no way to say # so. Which contract an SDK speaks is recorded at release time instead. See VERSIONING.md. -java-restclient=1.0.1 -java-resttemplate=1.0.1 -kotlin-okhttp=1.0.1 -python=2.0.0 -swift=1.0.1 -typescript-fetch=1.1.0 -dotnet=2.0.0 +java-restclient=1.1.0 +java-resttemplate=1.1.0 +kotlin-okhttp=1.1.0 +python=2.1.0 +swift=1.1.0 +typescript-fetch=1.2.0 +dotnet=2.1.0 diff --git a/site/guides/07-release-notes.md b/site/guides/07-release-notes.md new file mode 100644 index 0000000..782a78a --- /dev/null +++ b/site/guides/07-release-notes.md @@ -0,0 +1,24 @@ +# Release notes + +## 1.2.0 + +### Task and Project Time attachments + +List, retrieve, upload and delete files attached to Tasks and running or completed Project Times. +The generated SDKs include APIs and models for both attachment types. + +To upload a file, register its metadata with the attachment endpoint, then send the file with a +`PUT` request to the returned `upload.url` before `upload.expires_at`. Send every header returned in +`upload.headers` with its exact value. The storage request needs no additional authentication. +Only completed uploads appear in attachment results; incomplete uploads are discarded automatically. +Project Time uploads accept images only. File sizes and attachment counts are limited. + +Download URLs are temporary. Fetch the attachment again to obtain a fresh URL, and handle a null +`download` value. Task attachment results include only files attached directly to that Task; fetch +parent Task attachments separately. + +Adding or deleting a Project Time attachment does not update the Project Time's `last_modified`. +Synchronize attachments separately from queries using `last_modified_after`. Attachments of a +completed Project Time can only be deleted while its status is `changeable`. + +This contract update is additive; existing endpoints and models are unchanged.