From 1f2617cfc6499b29c4c8e69d5f98efb4d7ee0e9b Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Sat, 27 Jun 2026 14:07:21 -0300 Subject: [PATCH 01/32] feat(realtime-v3): add PhoenixMessage and PhoenixPayload --- Sources/RealtimeV3/PhoenixMessage.swift | 65 +++++++++++++++++++ .../RealtimeV3Tests/PhoenixMessageTests.swift | 19 ++++++ 2 files changed, 84 insertions(+) create mode 100644 Sources/RealtimeV3/PhoenixMessage.swift create mode 100644 Tests/RealtimeV3Tests/PhoenixMessageTests.swift diff --git a/Sources/RealtimeV3/PhoenixMessage.swift b/Sources/RealtimeV3/PhoenixMessage.swift new file mode 100644 index 000000000..61ac6656b --- /dev/null +++ b/Sources/RealtimeV3/PhoenixMessage.swift @@ -0,0 +1,65 @@ +// +// PhoenixMessage.swift +// RealtimeV3 +// +// Created by Guilherme Souza on 27/06/26. +// + +import Foundation + +/// A Phoenix protocol message received from the WebSocket connection. +public struct PhoenixMessage: Sendable { + /// Phoenix join reference correlating this frame to its `phx_join`. Always + /// `nil` when the channel is configured for protocol v1 (4-tuple frames + /// have no joinRef field). Under v2: `nil` for frames that predate the + /// current join (rare). + public let joinRef: String? + + /// Phoenix message reference for request/reply correlation. Set on + /// pushes the SDK sent and on the matching `phx_reply`. `nil` for + /// server-pushed events (`broadcast`, `postgres_changes`, etc.). + public let ref: String? + + /// Channel topic this frame belongs to. Always matches this channel's topic + /// for channel iterators; included on the struct so consumers that hand + /// `PhoenixMessage` values across boundaries (logging, debugging, + /// multi-topic aggregation) keep the routing key. + public let topic: String + + /// Server-side event name. Includes user-level events (`"broadcast"`, + /// `"postgres_changes"`, `"presence_diff"`, `"presence_state"`, `"system"`) + /// and Phoenix internals (`"phx_reply"`, `"phx_close"`, `"phx_error"`). + public let event: String + + /// Raw payload as received. JSON for text frames, `Data` for binary + /// (Phoenix v2 broadcast). + public let payload: PhoenixPayload + + /// Local receipt timestamp. + public let receivedAt: Date + + /// Creates a new Phoenix message. + public init( + joinRef: String?, + ref: String?, + topic: String, + event: String, + payload: PhoenixPayload, + receivedAt: Date + ) { + self.joinRef = joinRef + self.ref = ref + self.topic = topic + self.event = event + self.payload = payload + self.receivedAt = receivedAt + } +} + +/// The payload of a Phoenix message. +public enum PhoenixPayload: Sendable { + /// JSON payload from a text frame. + case json(JSONValue) + /// Binary payload from a binary frame. + case binary(Data) +} diff --git a/Tests/RealtimeV3Tests/PhoenixMessageTests.swift b/Tests/RealtimeV3Tests/PhoenixMessageTests.swift new file mode 100644 index 000000000..46763f1a4 --- /dev/null +++ b/Tests/RealtimeV3Tests/PhoenixMessageTests.swift @@ -0,0 +1,19 @@ +import Foundation +import Testing + +@testable import RealtimeV3 + +@Suite struct PhoenixMessageTests { + @Test func constructsBroadcastFrame() { + let msg = PhoenixMessage( + joinRef: "1", ref: nil, topic: "room:1", event: "broadcast", + payload: .json(["x": 1]), receivedAt: Date(timeIntervalSince1970: 0) + ) + #expect(msg.event == "broadcast") + if case .json(let v) = msg.payload { + #expect(v["x"] == 1) + } else { + Issue.record("expected json") + } + } +} From f2c7b811bc0ec156ebcb819c6a7dd8cc834a27e4 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 06:56:49 -0300 Subject: [PATCH 02/32] chore: add swift-openapi-runtime and codegen Makefile targets --- Brewfile | 2 ++ Makefile | 23 +++++++++++++++++++++++ Package.resolved | 11 ++++++++++- Package.swift | 8 ++++---- 4 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 Brewfile diff --git a/Brewfile b/Brewfile new file mode 100644 index 000000000..8abb3cf87 --- /dev/null +++ b/Brewfile @@ -0,0 +1,2 @@ +brew "smithy-language-server" # provides smithy CLI, pin via brew pin if needed +brew "swift-openapi-generator" # or install via mint/artifact diff --git a/Makefile b/Makefile index 47d217cfd..8e21a3a98 100644 --- a/Makefile +++ b/Makefile @@ -90,3 +90,26 @@ coverage: define udid_for $(shell xcrun simctl list --json devices available '$(1)' | jq -r '[.devices|to_entries|sort_by(.key)|reverse|.[].value|select(length > 0)|.[0]][0].udid') endef + +# ── Code generation ──────────────────────────────────────────────────────────── + +generate-smithy: + cd smithy && smithy build + +generate-swift-storage: + swift-openapi-generator generate \ + --config Sources/Storage/openapi-generator-config.yaml \ + --output-directory Sources/Storage/Generated \ + smithy/output/openapi/StorageService.openapi.json + +generate-swift-functions: + swift-openapi-generator generate \ + --config Sources/Functions/openapi-generator-config.yaml \ + --output-directory Sources/Functions/Generated \ + smithy/output/openapi/FunctionsService.openapi.json + +generate: generate-smithy generate-swift-storage generate-swift-functions + +check-generate: + $(MAKE) generate + git diff --exit-code || (echo "Generated artifacts are out of date. Run 'make generate' and commit." && exit 1) diff --git a/Package.resolved b/Package.resolved index 79af7114f..afb04c386 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "29002d4029daf5ab8af84c3caf63c13f21de3eeabe8719aa25aedda69e1bd1f3", + "originHash" : "d67654c567b66ca26d2029195c055c655be7538d0fcbb9842b011c68bee7903f", "pins" : [ { "identity" : "mocker", @@ -82,6 +82,15 @@ "version" : "1.3.1" } }, + { + "identity" : "swift-openapi-runtime", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-runtime", + "state" : { + "revision" : "3d3a8457661daf7fb260ceeb9f0e24e5204ba5fb", + "version" : "1.12.0" + } + }, { "identity" : "swift-snapshot-testing", "kind" : "remoteSourceControl", diff --git a/Package.swift b/Package.swift index 08bfae2ae..928e101f4 100644 --- a/Package.swift +++ b/Package.swift @@ -31,6 +31,7 @@ let package = Package( .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.2.2"), .package(url: "https://github.com/WeTransfer/Mocker", from: "3.0.0"), .package(url: "https://github.com/mattt/Replay.git", from: "0.4.0"), + .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.0.0"), ], targets: [ .target( @@ -41,6 +42,7 @@ let package = Package( .product(name: "Clocks", package: "swift-clocks"), .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), .product(name: "IssueReporting", package: "xctest-dynamic-overlay"), + .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), ] ), .testTarget( @@ -79,9 +81,8 @@ let package = Package( .target( name: "Functions", dependencies: [ - .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), - .product(name: "HTTPTypes", package: "swift-http-types"), "Helpers", + .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), ] ), .testTarget( @@ -162,9 +163,8 @@ let package = Package( .target( name: "Storage", dependencies: [ - .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), - .product(name: "HTTPTypes", package: "swift-http-types"), "Helpers", + .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), ] ), .testTarget( From 59484f2e2ff9227fa8061d1b33686b1de05f6486 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 06:58:19 -0300 Subject: [PATCH 03/32] chore: add .PHONY for codegen Makefile targets --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 8e21a3a98..8e3fc618c 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,8 @@ endef # ── Code generation ──────────────────────────────────────────────────────────── +.PHONY: generate-smithy generate-swift-storage generate-swift-functions generate check-generate + generate-smithy: cd smithy && smithy build From 319483b1d343c669f8f237bfe9f142e9a48f42e1 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 07:00:36 -0300 Subject: [PATCH 04/32] feat(codegen): add Smithy models for Storage and Functions --- smithy/model/common.smithy | 8 + smithy/model/functions.smithy | 42 +++++ smithy/model/storage.smithy | 340 ++++++++++++++++++++++++++++++++++ smithy/smithy-build.json | 44 +++++ 4 files changed, 434 insertions(+) create mode 100644 smithy/model/common.smithy create mode 100644 smithy/model/functions.smithy create mode 100644 smithy/model/storage.smithy create mode 100644 smithy/smithy-build.json diff --git a/smithy/model/common.smithy b/smithy/model/common.smithy new file mode 100644 index 000000000..cc9197d82 --- /dev/null +++ b/smithy/model/common.smithy @@ -0,0 +1,8 @@ +$version: "2" + +namespace io.supabase + +/// Common string list shape reused across services. +list StringList { + member: String +} diff --git a/smithy/model/functions.smithy b/smithy/model/functions.smithy new file mode 100644 index 000000000..8ccaa4856 --- /dev/null +++ b/smithy/model/functions.smithy @@ -0,0 +1,42 @@ +$version: "2" + +namespace io.supabase.functions + +use aws.protocols#restJson1 + +@restJson1 +@title("Supabase Functions API") +service FunctionsService { + version: "1.0" + operations: [InvokeFunction] + errors: [FunctionsError] +} + +@http(method: "POST", uri: "/functions/v1/{functionName}", code: 200) +operation InvokeFunction { + input: InvokeFunctionInput + output: InvokeFunctionOutput + errors: [FunctionsError] +} + +structure InvokeFunctionInput { + @required + @httpLabel + functionName: String + + @httpHeader("x-region") + region: String + + @httpPayload + body: Blob +} + +structure InvokeFunctionOutput { + @httpPayload + body: Blob +} + +@error("client") +structure FunctionsError { + message: String +} diff --git a/smithy/model/storage.smithy b/smithy/model/storage.smithy new file mode 100644 index 000000000..d3c3cf046 --- /dev/null +++ b/smithy/model/storage.smithy @@ -0,0 +1,340 @@ +$version: "2" + +namespace io.supabase.storage + +use aws.protocols#restJson1 +use io.supabase#StringList + +@restJson1 +@title("Supabase Storage API") +service StorageService { + version: "1.0" + operations: [ + ListBuckets + GetBucket + CreateBucket + UpdateBucket + EmptyBucket + DeleteBucket + MoveObject + CopyObject + DeleteObjects + ListObjects + GetObjectInfo + HeadObject + CreateSignedUrl + CreateSignedUrls + CreateSignedUploadUrl + ] + errors: [StorageError] +} + +// ─── Bucket Operations ───────────────────────────────────────────────────── + +@http(method: "GET", uri: "/bucket", code: 200) +@readonly +operation ListBuckets { + output: ListBucketsOutput + errors: [StorageError] +} + +structure ListBucketsOutput { + @required + @httpPayload + items: BucketList +} + +list BucketList { + member: Bucket +} + +@http(method: "GET", uri: "/bucket/{id}", code: 200) +@readonly +operation GetBucket { + input: GetBucketInput + output: Bucket + errors: [StorageError] +} + +structure GetBucketInput { + @required + @httpLabel + id: String +} + +@http(method: "POST", uri: "/bucket", code: 200) +operation CreateBucket { + input: CreateBucketInput + errors: [StorageError] +} + +structure CreateBucketInput { + @required id: String + @required name: String + @required @jsonName("public") isPublic: Boolean + file_size_limit: Long + allowed_mime_types: StringList +} + +@http(method: "PUT", uri: "/bucket/{id}", code: 200) +operation UpdateBucket { + input: UpdateBucketInput + errors: [StorageError] +} + +structure UpdateBucketInput { + @required + @httpLabel + id: String + + @required @jsonName("public") isPublic: Boolean + file_size_limit: Long + allowed_mime_types: StringList +} + +@http(method: "POST", uri: "/bucket/{id}/empty", code: 200) +operation EmptyBucket { + input: EmptyBucketInput + errors: [StorageError] +} + +structure EmptyBucketInput { + @required + @httpLabel + id: String +} + +@http(method: "DELETE", uri: "/bucket/{id}", code: 200) +operation DeleteBucket { + input: DeleteBucketInput + errors: [StorageError] +} + +structure DeleteBucketInput { + @required + @httpLabel + id: String +} + +// ─── Object Operations ───────────────────────────────────────────────────── + +@http(method: "POST", uri: "/object/move", code: 200) +operation MoveObject { + input: MoveObjectInput + errors: [StorageError] +} + +structure MoveObjectInput { + @required bucketId: String + @required sourceKey: String + @required destinationKey: String + destinationBucket: String +} + +@http(method: "POST", uri: "/object/copy", code: 200) +operation CopyObject { + input: CopyObjectInput + output: CopyObjectOutput + errors: [StorageError] +} + +structure CopyObjectInput { + @required bucketId: String + @required sourceKey: String + @required destinationKey: String + destinationBucket: String +} + +structure CopyObjectOutput { + @required Key: String +} + +@http(method: "DELETE", uri: "/object/{bucketId}", code: 200) +operation DeleteObjects { + input: DeleteObjectsInput + output: DeleteObjectsOutput + errors: [StorageError] +} + +structure DeleteObjectsInput { + @required + @httpLabel + bucketId: String + + @required prefixes: StringList +} + +structure DeleteObjectsOutput { + @required + @httpPayload + items: FileObjectList +} + +list FileObjectList { + member: FileObject +} + +@http(method: "POST", uri: "/object/list/{bucketId}", code: 200) +operation ListObjects { + input: ListObjectsInput + output: ListObjectsOutput + errors: [StorageError] +} + +structure ListObjectsInput { + @required + @httpLabel + bucketId: String + + @required prefix: String + limit: Integer + offset: Integer + sortBy: SortBy +} + +structure SortBy { + column: String + order: String +} + +structure ListObjectsOutput { + @required + @httpPayload + items: FileObjectList +} + +@http(method: "GET", uri: "/object/info/{bucketId}/{wildcardPath+}", code: 200) +@readonly +operation GetObjectInfo { + input: GetObjectInfoInput + output: FileInfo + errors: [StorageError] +} + +structure GetObjectInfoInput { + @required @httpLabel bucketId: String + @required @httpLabel wildcardPath: String +} + +@http(method: "HEAD", uri: "/object/{bucketId}/{wildcardPath+}", code: 200) +@readonly +operation HeadObject { + input: HeadObjectInput + errors: [StorageError] +} + +structure HeadObjectInput { + @required @httpLabel bucketId: String + @required @httpLabel wildcardPath: String +} + +@http(method: "POST", uri: "/object/sign/{bucketId}/{wildcardPath+}", code: 200) +operation CreateSignedUrl { + input: CreateSignedUrlInput + output: CreateSignedUrlOutput + errors: [StorageError] +} + +structure CreateSignedUrlInput { + @required @httpLabel bucketId: String + @required @httpLabel wildcardPath: String + @required expiresIn: Integer +} + +structure CreateSignedUrlOutput { + @required signedURL: String +} + +@http(method: "POST", uri: "/object/sign/{bucketId}", code: 200) +operation CreateSignedUrls { + input: CreateSignedUrlsInput + output: CreateSignedUrlsOutput + errors: [StorageError] +} + +structure CreateSignedUrlsInput { + @required @httpLabel bucketId: String + @required expiresIn: Integer + @required paths: StringList +} + +structure CreateSignedUrlsOutput { + @required + @httpPayload + items: SignedUrlResultList +} + +list SignedUrlResultList { + member: SignedUrlResult +} + +structure SignedUrlResult { + signedURL: String + @required path: String + error: String +} + +@http(method: "POST", uri: "/object/upload/sign/{bucketId}/{wildcardPath+}", code: 200) +operation CreateSignedUploadUrl { + input: CreateSignedUploadUrlInput + output: CreateSignedUploadUrlOutput + errors: [StorageError] +} + +structure CreateSignedUploadUrlInput { + @required @httpLabel bucketId: String + @required @httpLabel wildcardPath: String + @httpHeader("x-upsert") upsert: String +} + +structure CreateSignedUploadUrlOutput { + @required url: String +} + +// ─── Shared Shapes ───────────────────────────────────────────────────────── + +structure Bucket { + @required id: String + @required name: String + @required @jsonName("public") isPublic: Boolean + file_size_limit: Long + allowed_mime_types: StringList + created_at: String + updated_at: String +} + +structure FileObject { + @required name: String + id: String + updated_at: String + created_at: String + last_accessed_at: String + metadata: FileMetadata +} + +structure FileMetadata { + eTag: String + size: Long + mimetype: String + cacheControl: String + lastModified: String + contentLength: Long + httpStatusCode: Integer +} + +structure FileInfo { + eTag: String + size: Long + mimetype: String + cacheControl: String + lastModified: String + contentLength: Long + httpStatusCode: Integer +} + +@error("client") +structure StorageError { + message: String + error: String + statusCode: String +} diff --git a/smithy/smithy-build.json b/smithy/smithy-build.json new file mode 100644 index 000000000..263cc9ecf --- /dev/null +++ b/smithy/smithy-build.json @@ -0,0 +1,44 @@ +{ + "version": "1.0", + "maven": { + "dependencies": [ + "software.amazon.smithy:smithy-openapi:1.52.1", + "software.amazon.smithy:smithy-aws-traits:1.52.1" + ] + }, + "sources": ["model"], + "projections": { + "storage-openapi": { + "transforms": [ + { + "name": "includeServices", + "args": { + "services": ["io.supabase.storage#StorageService"] + } + } + ], + "plugins": { + "openapi": { + "service": "io.supabase.storage#StorageService", + "protocol": "aws.protocols#restJson1" + } + } + }, + "functions-openapi": { + "transforms": [ + { + "name": "includeServices", + "args": { + "services": ["io.supabase.functions#FunctionsService"] + } + } + ], + "plugins": { + "openapi": { + "service": "io.supabase.functions#FunctionsService", + "protocol": "aws.protocols#restJson1" + } + } + } + } +} From 32675b3907bed219bb54fcdad0aa0648bf737673 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 07:02:07 -0300 Subject: [PATCH 05/32] chore(codegen): track smithy output directory in git --- smithy/output/openapi/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 smithy/output/openapi/.gitkeep diff --git a/smithy/output/openapi/.gitkeep b/smithy/output/openapi/.gitkeep new file mode 100644 index 000000000..e69de29bb From dfc7368e78570854349e5cdbfc914c014b46f2b5 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 07:09:29 -0300 Subject: [PATCH 06/32] feat(codegen): generate OpenAPI specs and Swift clients from Smithy models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix storage.smithy: remove @httpPayload from list members (AWS restJson1 constraint), add @idempotent to PUT/DELETE operations, suppress UnexpectedPayload danger for DeleteObjects - Update Makefile generate-smithy to copy build output to smithy/output/openapi/ - Update Makefile to use ~/bin/swift-openapi-generator (built from source) - Add openapi-generator-config.yaml for Storage and Functions - Generate StorageService.openapi.json and FunctionsService.openapi.json - Generate Sources/Storage/Generated/{Types,Client}.swift - Generate Sources/Functions/Generated/{Types,Client}.swift Build currently fails with "multiple producers" for Types.swift — existing Types.swift in each module conflicts with generated Types.swift; resolved in Task 4/5 when Package.swift targets are restructured. --- Makefile | 6 +- Sources/Functions/Generated/Client.swift | 138 + Sources/Functions/Generated/Types.swift | 274 ++ .../Functions/openapi-generator-config.yaml | 4 + Sources/Storage/Generated/Client.swift | 1219 ++++++ Sources/Storage/Generated/Types.swift | 3539 +++++++++++++++++ Sources/Storage/openapi-generator-config.yaml | 4 + smithy/model/storage.smithy | 8 +- .../openapi/FunctionsService.openapi.json | 82 + .../openapi/StorageService.openapi.json | 1037 +++++ 10 files changed, 6305 insertions(+), 6 deletions(-) create mode 100644 Sources/Functions/Generated/Client.swift create mode 100644 Sources/Functions/Generated/Types.swift create mode 100644 Sources/Functions/openapi-generator-config.yaml create mode 100644 Sources/Storage/Generated/Client.swift create mode 100644 Sources/Storage/Generated/Types.swift create mode 100644 Sources/Storage/openapi-generator-config.yaml create mode 100644 smithy/output/openapi/FunctionsService.openapi.json create mode 100644 smithy/output/openapi/StorageService.openapi.json diff --git a/Makefile b/Makefile index 8e3fc618c..c3d66399c 100644 --- a/Makefile +++ b/Makefile @@ -97,15 +97,17 @@ endef generate-smithy: cd smithy && smithy build + cp smithy/build/smithy/storage-openapi/openapi/StorageService.openapi.json smithy/output/openapi/StorageService.openapi.json + cp smithy/build/smithy/functions-openapi/openapi/FunctionsService.openapi.json smithy/output/openapi/FunctionsService.openapi.json generate-swift-storage: - swift-openapi-generator generate \ + $(HOME)/bin/swift-openapi-generator generate \ --config Sources/Storage/openapi-generator-config.yaml \ --output-directory Sources/Storage/Generated \ smithy/output/openapi/StorageService.openapi.json generate-swift-functions: - swift-openapi-generator generate \ + $(HOME)/bin/swift-openapi-generator generate \ --config Sources/Functions/openapi-generator-config.yaml \ --output-directory Sources/Functions/Generated \ smithy/output/openapi/FunctionsService.openapi.json diff --git a/Sources/Functions/Generated/Client.swift b/Sources/Functions/Generated/Client.swift new file mode 100644 index 000000000..2b1819cea --- /dev/null +++ b/Sources/Functions/Generated/Client.swift @@ -0,0 +1,138 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +internal struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { + client.converter + } + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. + internal func InvokeFunction(_ input: Operations.InvokeFunction.Input) async throws -> Operations.InvokeFunction.Output { + try await client.send( + input: input, + forOperation: Operations.InvokeFunction.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: input.headers.x_hyphen_region + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case .none: + body = nil + case let .binary(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.InvokeFunction.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.InvokeFunction.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } +} diff --git a/Sources/Functions/Generated/Types.swift b/Sources/Functions/Generated/Types.swift new file mode 100644 index 000000000..90bcbac53 --- /dev/null +++ b/Sources/Functions/Generated/Types.swift @@ -0,0 +1,274 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +internal protocol APIProtocol: Sendable { + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. + func InvokeFunction(_ input: Operations.InvokeFunction.Input) async throws -> Operations.InvokeFunction.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. + internal func InvokeFunction( + path: Operations.InvokeFunction.Input.Path, + headers: Operations.InvokeFunction.Input.Headers = .init(), + body: Operations.InvokeFunction.Input.Body? = nil + ) async throws -> Operations.InvokeFunction.Output { + try await InvokeFunction(Operations.InvokeFunction.Input( + path: path, + headers: headers, + body: body + )) + } +} + +/// Server URLs defined in the OpenAPI document. +internal enum Servers {} + +/// Types generated from the components section of the OpenAPI document. +internal enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + internal enum Schemas { + /// - Remark: Generated from `#/components/schemas/FunctionsErrorResponseContent`. + internal struct FunctionsErrorResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FunctionsErrorResponseContent/message`. + internal var message: Swift.String? + /// Creates a new `FunctionsErrorResponseContent`. + /// + /// - Parameters: + /// - message: + internal init(message: Swift.String? = nil) { + self.message = message + } + internal enum CodingKeys: String, CodingKey { + case message + } + } + /// - Remark: Generated from `#/components/schemas/InvokeFunctionInputPayload`. + internal typealias InvokeFunctionInputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/InvokeFunctionOutputPayload`. + internal typealias InvokeFunctionOutputPayload = OpenAPIRuntime.Base64EncodedData + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + internal enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + internal enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + internal enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + internal enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +internal enum Operations { + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. + internal enum InvokeFunction { + internal static let id: Swift.String = "InvokeFunction" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.InvokeFunction.Input.Path + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/header/x-region`. + internal var x_hyphen_region: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_region: + /// - accept: + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Operations.InvokeFunction.Input.Headers + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.InvokeFunction.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.InvokeFunction.Input.Path, + headers: Operations.InvokeFunction.Input.Headers = .init(), + body: Operations.InvokeFunction.Input.Body? = nil + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.InvokeFunction.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.InvokeFunction.Output.Ok.Body) { + self.body = body + } + } + /// InvokeFunction 200 response + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.InvokeFunction.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.InvokeFunction.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.FunctionsErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FunctionsErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.InvokeFunction.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.InvokeFunction.Output.BadRequest.Body) { + self.body = body + } + } + /// FunctionsError 400 response + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.InvokeFunction.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.InvokeFunction.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } +} diff --git a/Sources/Functions/openapi-generator-config.yaml b/Sources/Functions/openapi-generator-config.yaml new file mode 100644 index 000000000..1df6f2876 --- /dev/null +++ b/Sources/Functions/openapi-generator-config.yaml @@ -0,0 +1,4 @@ +generate: + - types + - client +accessModifier: internal diff --git a/Sources/Storage/Generated/Client.swift b/Sources/Storage/Generated/Client.swift new file mode 100644 index 000000000..03f9c7472 --- /dev/null +++ b/Sources/Storage/Generated/Client.swift @@ -0,0 +1,1219 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +internal struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { + client.converter + } + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(ListBuckets)`. + internal func ListBuckets(_ input: Operations.ListBuckets.Input) async throws -> Operations.ListBuckets.Output { + try await client.send( + input: input, + forOperation: Operations.ListBuckets.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.ListBuckets.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.ListBucketsResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.ListBuckets.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)`. + internal func CreateBucket(_ input: Operations.CreateBucket.Input) async throws -> Operations.CreateBucket.Output { + try await client.send( + input: input, + forOperation: Operations.CreateBucket.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + return .ok(.init()) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateBucket.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(GetBucket)`. + internal func GetBucket(_ input: Operations.GetBucket.Input) async throws -> Operations.GetBucket.Output { + try await client.send( + input: input, + forOperation: Operations.GetBucket.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetBucket.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.GetBucketResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetBucket.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)`. + internal func UpdateBucket(_ input: Operations.UpdateBucket.Input) async throws -> Operations.UpdateBucket.Output { + try await client.send( + input: input, + forOperation: Operations.UpdateBucket.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + return .ok(.init()) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpdateBucket.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)`. + internal func DeleteBucket(_ input: Operations.DeleteBucket.Input) async throws -> Operations.DeleteBucket.Output { + try await client.send( + input: input, + forOperation: Operations.DeleteBucket.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + return .ok(.init()) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.DeleteBucket.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)`. + internal func EmptyBucket(_ input: Operations.EmptyBucket.Input) async throws -> Operations.EmptyBucket.Output { + try await client.send( + input: input, + forOperation: Operations.EmptyBucket.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}/empty", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + return .ok(.init()) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.EmptyBucket.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(CopyObject)`. + internal func CopyObject(_ input: Operations.CopyObject.Input) async throws -> Operations.CopyObject.Output { + try await client.send( + input: input, + forOperation: Operations.CopyObject.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/copy", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CopyObject.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CopyObjectResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CopyObject.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath+}/get(GetObjectInfo)`. + internal func GetObjectInfo(_ input: Operations.GetObjectInfo.Input) async throws -> Operations.GetObjectInfo.Output { + try await client.send( + input: input, + forOperation: Operations.GetObjectInfo.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/info/{}/wildcardPath+", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetObjectInfo.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.GetObjectInfoResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetObjectInfo.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(ListObjects)`. + internal func ListObjects(_ input: Operations.ListObjects.Input) async throws -> Operations.ListObjects.Output { + try await client.send( + input: input, + forOperation: Operations.ListObjects.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/list/{}", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.ListObjects.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.ListObjectsResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.ListObjects.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)`. + internal func MoveObject(_ input: Operations.MoveObject.Input) async throws -> Operations.MoveObject.Output { + try await client.send( + input: input, + forOperation: Operations.MoveObject.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/move", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + return .ok(.init()) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.MoveObject.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(CreateSignedUrls)`. + internal func CreateSignedUrls(_ input: Operations.CreateSignedUrls.Input) async throws -> Operations.CreateSignedUrls.Output { + try await client.send( + input: input, + forOperation: Operations.CreateSignedUrls.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/sign/{}", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateSignedUrls.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CreateSignedUrlsResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateSignedUrls.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUrl)`. + internal func CreateSignedUrl(_ input: Operations.CreateSignedUrl.Input) async throws -> Operations.CreateSignedUrl.Output { + try await client.send( + input: input, + forOperation: Operations.CreateSignedUrl.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/sign/{}/wildcardPath+", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateSignedUrl.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CreateSignedUrlResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateSignedUrl.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUploadUrl)`. + internal func CreateSignedUploadUrl(_ input: Operations.CreateSignedUploadUrl.Input) async throws -> Operations.CreateSignedUploadUrl.Output { + try await client.send( + input: input, + forOperation: Operations.CreateSignedUploadUrl.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/upload/sign/{}/wildcardPath+", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateSignedUploadUrl.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CreateSignedUploadUrlResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateSignedUploadUrl.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)`. + internal func DeleteObjects(_ input: Operations.DeleteObjects.Input) async throws -> Operations.DeleteObjects.Output { + try await client.send( + input: input, + forOperation: Operations.DeleteObjects.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.DeleteObjects.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DeleteObjectsResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.DeleteObjects.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. + internal func HeadObject(_ input: Operations.HeadObject.Input) async throws -> Operations.HeadObject.Output { + try await client.send( + input: input, + forOperation: Operations.HeadObject.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}/wildcardPath+", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .head + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + return .ok(.init()) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.HeadObject.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } +} diff --git a/Sources/Storage/Generated/Types.swift b/Sources/Storage/Generated/Types.swift new file mode 100644 index 000000000..6dff2facc --- /dev/null +++ b/Sources/Storage/Generated/Types.swift @@ -0,0 +1,3539 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +internal protocol APIProtocol: Sendable { + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(ListBuckets)`. + func ListBuckets(_ input: Operations.ListBuckets.Input) async throws -> Operations.ListBuckets.Output + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)`. + func CreateBucket(_ input: Operations.CreateBucket.Input) async throws -> Operations.CreateBucket.Output + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(GetBucket)`. + func GetBucket(_ input: Operations.GetBucket.Input) async throws -> Operations.GetBucket.Output + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)`. + func UpdateBucket(_ input: Operations.UpdateBucket.Input) async throws -> Operations.UpdateBucket.Output + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)`. + func DeleteBucket(_ input: Operations.DeleteBucket.Input) async throws -> Operations.DeleteBucket.Output + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)`. + func EmptyBucket(_ input: Operations.EmptyBucket.Input) async throws -> Operations.EmptyBucket.Output + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(CopyObject)`. + func CopyObject(_ input: Operations.CopyObject.Input) async throws -> Operations.CopyObject.Output + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath+}/get(GetObjectInfo)`. + func GetObjectInfo(_ input: Operations.GetObjectInfo.Input) async throws -> Operations.GetObjectInfo.Output + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(ListObjects)`. + func ListObjects(_ input: Operations.ListObjects.Input) async throws -> Operations.ListObjects.Output + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)`. + func MoveObject(_ input: Operations.MoveObject.Input) async throws -> Operations.MoveObject.Output + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(CreateSignedUrls)`. + func CreateSignedUrls(_ input: Operations.CreateSignedUrls.Input) async throws -> Operations.CreateSignedUrls.Output + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUrl)`. + func CreateSignedUrl(_ input: Operations.CreateSignedUrl.Input) async throws -> Operations.CreateSignedUrl.Output + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUploadUrl)`. + func CreateSignedUploadUrl(_ input: Operations.CreateSignedUploadUrl.Input) async throws -> Operations.CreateSignedUploadUrl.Output + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)`. + func DeleteObjects(_ input: Operations.DeleteObjects.Input) async throws -> Operations.DeleteObjects.Output + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. + func HeadObject(_ input: Operations.HeadObject.Input) async throws -> Operations.HeadObject.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(ListBuckets)`. + internal func ListBuckets(headers: Operations.ListBuckets.Input.Headers = .init()) async throws -> Operations.ListBuckets.Output { + try await ListBuckets(Operations.ListBuckets.Input(headers: headers)) + } + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)`. + internal func CreateBucket( + headers: Operations.CreateBucket.Input.Headers = .init(), + body: Operations.CreateBucket.Input.Body + ) async throws -> Operations.CreateBucket.Output { + try await CreateBucket(Operations.CreateBucket.Input( + headers: headers, + body: body + )) + } + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(GetBucket)`. + internal func GetBucket( + path: Operations.GetBucket.Input.Path, + headers: Operations.GetBucket.Input.Headers = .init() + ) async throws -> Operations.GetBucket.Output { + try await GetBucket(Operations.GetBucket.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)`. + internal func UpdateBucket( + path: Operations.UpdateBucket.Input.Path, + headers: Operations.UpdateBucket.Input.Headers = .init(), + body: Operations.UpdateBucket.Input.Body + ) async throws -> Operations.UpdateBucket.Output { + try await UpdateBucket(Operations.UpdateBucket.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)`. + internal func DeleteBucket( + path: Operations.DeleteBucket.Input.Path, + headers: Operations.DeleteBucket.Input.Headers = .init() + ) async throws -> Operations.DeleteBucket.Output { + try await DeleteBucket(Operations.DeleteBucket.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)`. + internal func EmptyBucket( + path: Operations.EmptyBucket.Input.Path, + headers: Operations.EmptyBucket.Input.Headers = .init() + ) async throws -> Operations.EmptyBucket.Output { + try await EmptyBucket(Operations.EmptyBucket.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(CopyObject)`. + internal func CopyObject( + headers: Operations.CopyObject.Input.Headers = .init(), + body: Operations.CopyObject.Input.Body + ) async throws -> Operations.CopyObject.Output { + try await CopyObject(Operations.CopyObject.Input( + headers: headers, + body: body + )) + } + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath+}/get(GetObjectInfo)`. + internal func GetObjectInfo( + path: Operations.GetObjectInfo.Input.Path, + headers: Operations.GetObjectInfo.Input.Headers = .init() + ) async throws -> Operations.GetObjectInfo.Output { + try await GetObjectInfo(Operations.GetObjectInfo.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(ListObjects)`. + internal func ListObjects( + path: Operations.ListObjects.Input.Path, + headers: Operations.ListObjects.Input.Headers = .init(), + body: Operations.ListObjects.Input.Body + ) async throws -> Operations.ListObjects.Output { + try await ListObjects(Operations.ListObjects.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)`. + internal func MoveObject( + headers: Operations.MoveObject.Input.Headers = .init(), + body: Operations.MoveObject.Input.Body + ) async throws -> Operations.MoveObject.Output { + try await MoveObject(Operations.MoveObject.Input( + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(CreateSignedUrls)`. + internal func CreateSignedUrls( + path: Operations.CreateSignedUrls.Input.Path, + headers: Operations.CreateSignedUrls.Input.Headers = .init(), + body: Operations.CreateSignedUrls.Input.Body + ) async throws -> Operations.CreateSignedUrls.Output { + try await CreateSignedUrls(Operations.CreateSignedUrls.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUrl)`. + internal func CreateSignedUrl( + path: Operations.CreateSignedUrl.Input.Path, + headers: Operations.CreateSignedUrl.Input.Headers = .init(), + body: Operations.CreateSignedUrl.Input.Body + ) async throws -> Operations.CreateSignedUrl.Output { + try await CreateSignedUrl(Operations.CreateSignedUrl.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUploadUrl)`. + internal func CreateSignedUploadUrl( + path: Operations.CreateSignedUploadUrl.Input.Path, + headers: Operations.CreateSignedUploadUrl.Input.Headers = .init() + ) async throws -> Operations.CreateSignedUploadUrl.Output { + try await CreateSignedUploadUrl(Operations.CreateSignedUploadUrl.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)`. + internal func DeleteObjects( + path: Operations.DeleteObjects.Input.Path, + headers: Operations.DeleteObjects.Input.Headers = .init(), + body: Operations.DeleteObjects.Input.Body + ) async throws -> Operations.DeleteObjects.Output { + try await DeleteObjects(Operations.DeleteObjects.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. + internal func HeadObject( + path: Operations.HeadObject.Input.Path, + headers: Operations.HeadObject.Input.Headers = .init() + ) async throws -> Operations.HeadObject.Output { + try await HeadObject(Operations.HeadObject.Input( + path: path, + headers: headers + )) + } +} + +/// Server URLs defined in the OpenAPI document. +internal enum Servers {} + +/// Types generated from the components section of the OpenAPI document. +internal enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + internal enum Schemas { + /// - Remark: Generated from `#/components/schemas/Bucket`. + internal struct Bucket: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/Bucket/id`. + internal var id: Swift.String + /// - Remark: Generated from `#/components/schemas/Bucket/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/Bucket/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/Bucket/file_size_limit`. + internal var file_size_limit: Swift.Double? + /// Common string list shape reused across services. + /// + /// - Remark: Generated from `#/components/schemas/Bucket/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/Bucket/created_at`. + internal var created_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/Bucket/updated_at`. + internal var updated_at: Swift.String? + /// Creates a new `Bucket`. + /// + /// - Parameters: + /// - id: + /// - name: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: Common string list shape reused across services. + /// - created_at: + /// - updated_at: + internal init( + id: Swift.String, + name: Swift.String, + _public: Swift.Bool, + file_size_limit: Swift.Double? = nil, + allowed_mime_types: [Swift.String]? = nil, + created_at: Swift.String? = nil, + updated_at: Swift.String? = nil + ) { + self.id = id + self.name = name + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + self.created_at = created_at + self.updated_at = updated_at + } + internal enum CodingKeys: String, CodingKey { + case id + case name + case _public = "public" + case file_size_limit + case allowed_mime_types + case created_at + case updated_at + } + } + /// - Remark: Generated from `#/components/schemas/CopyObjectRequestContent`. + internal struct CopyObjectRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CopyObjectRequestContent/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/components/schemas/CopyObjectRequestContent/sourceKey`. + internal var sourceKey: Swift.String + /// - Remark: Generated from `#/components/schemas/CopyObjectRequestContent/destinationKey`. + internal var destinationKey: Swift.String + /// - Remark: Generated from `#/components/schemas/CopyObjectRequestContent/destinationBucket`. + internal var destinationBucket: Swift.String? + /// Creates a new `CopyObjectRequestContent`. + /// + /// - Parameters: + /// - bucketId: + /// - sourceKey: + /// - destinationKey: + /// - destinationBucket: + internal init( + bucketId: Swift.String, + sourceKey: Swift.String, + destinationKey: Swift.String, + destinationBucket: Swift.String? = nil + ) { + self.bucketId = bucketId + self.sourceKey = sourceKey + self.destinationKey = destinationKey + self.destinationBucket = destinationBucket + } + internal enum CodingKeys: String, CodingKey { + case bucketId + case sourceKey + case destinationKey + case destinationBucket + } + } + /// - Remark: Generated from `#/components/schemas/CopyObjectResponseContent`. + internal struct CopyObjectResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CopyObjectResponseContent/Key`. + internal var Key: Swift.String + /// Creates a new `CopyObjectResponseContent`. + /// + /// - Parameters: + /// - Key: + internal init(Key: Swift.String) { + self.Key = Key + } + internal enum CodingKeys: String, CodingKey { + case Key + } + } + /// - Remark: Generated from `#/components/schemas/CreateBucketRequestContent`. + internal struct CreateBucketRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateBucketRequestContent/id`. + internal var id: Swift.String + /// - Remark: Generated from `#/components/schemas/CreateBucketRequestContent/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/CreateBucketRequestContent/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/CreateBucketRequestContent/file_size_limit`. + internal var file_size_limit: Swift.Double? + /// Common string list shape reused across services. + /// + /// - Remark: Generated from `#/components/schemas/CreateBucketRequestContent/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// Creates a new `CreateBucketRequestContent`. + /// + /// - Parameters: + /// - id: + /// - name: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: Common string list shape reused across services. + internal init( + id: Swift.String, + name: Swift.String, + _public: Swift.Bool, + file_size_limit: Swift.Double? = nil, + allowed_mime_types: [Swift.String]? = nil + ) { + self.id = id + self.name = name + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + } + internal enum CodingKeys: String, CodingKey { + case id + case name + case _public = "public" + case file_size_limit + case allowed_mime_types + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUploadUrlResponseContent`. + internal struct CreateSignedUploadUrlResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUploadUrlResponseContent/url`. + internal var url: Swift.String + /// Creates a new `CreateSignedUploadUrlResponseContent`. + /// + /// - Parameters: + /// - url: + internal init(url: Swift.String) { + self.url = url + } + internal enum CodingKeys: String, CodingKey { + case url + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlRequestContent`. + internal struct CreateSignedUrlRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlRequestContent/expiresIn`. + internal var expiresIn: Swift.Double + /// Creates a new `CreateSignedUrlRequestContent`. + /// + /// - Parameters: + /// - expiresIn: + internal init(expiresIn: Swift.Double) { + self.expiresIn = expiresIn + } + internal enum CodingKeys: String, CodingKey { + case expiresIn + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlResponseContent`. + internal struct CreateSignedUrlResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlResponseContent/signedURL`. + internal var signedURL: Swift.String + /// Creates a new `CreateSignedUrlResponseContent`. + /// + /// - Parameters: + /// - signedURL: + internal init(signedURL: Swift.String) { + self.signedURL = signedURL + } + internal enum CodingKeys: String, CodingKey { + case signedURL + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsRequestContent`. + internal struct CreateSignedUrlsRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsRequestContent/expiresIn`. + internal var expiresIn: Swift.Double + /// Common string list shape reused across services. + /// + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsRequestContent/paths`. + internal var paths: [Swift.String] + /// Creates a new `CreateSignedUrlsRequestContent`. + /// + /// - Parameters: + /// - expiresIn: + /// - paths: Common string list shape reused across services. + internal init( + expiresIn: Swift.Double, + paths: [Swift.String] + ) { + self.expiresIn = expiresIn + self.paths = paths + } + internal enum CodingKeys: String, CodingKey { + case expiresIn + case paths + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsResponseContent`. + internal struct CreateSignedUrlsResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsResponseContent/items`. + internal var items: [Components.Schemas.SignedUrlResult] + /// Creates a new `CreateSignedUrlsResponseContent`. + /// + /// - Parameters: + /// - items: + internal init(items: [Components.Schemas.SignedUrlResult]) { + self.items = items + } + internal enum CodingKeys: String, CodingKey { + case items + } + } + /// - Remark: Generated from `#/components/schemas/DeleteObjectsRequestContent`. + internal struct DeleteObjectsRequestContent: Codable, Hashable, Sendable { + /// Common string list shape reused across services. + /// + /// - Remark: Generated from `#/components/schemas/DeleteObjectsRequestContent/prefixes`. + internal var prefixes: [Swift.String] + /// Creates a new `DeleteObjectsRequestContent`. + /// + /// - Parameters: + /// - prefixes: Common string list shape reused across services. + internal init(prefixes: [Swift.String]) { + self.prefixes = prefixes + } + internal enum CodingKeys: String, CodingKey { + case prefixes + } + } + /// - Remark: Generated from `#/components/schemas/DeleteObjectsResponseContent`. + internal struct DeleteObjectsResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/DeleteObjectsResponseContent/items`. + internal var items: [Components.Schemas.FileObject] + /// Creates a new `DeleteObjectsResponseContent`. + /// + /// - Parameters: + /// - items: + internal init(items: [Components.Schemas.FileObject]) { + self.items = items + } + internal enum CodingKeys: String, CodingKey { + case items + } + } + /// - Remark: Generated from `#/components/schemas/FileMetadata`. + internal struct FileMetadata: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FileMetadata/eTag`. + internal var eTag: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/size`. + internal var size: Swift.Double? + /// - Remark: Generated from `#/components/schemas/FileMetadata/mimetype`. + internal var mimetype: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/cacheControl`. + internal var cacheControl: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/lastModified`. + internal var lastModified: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/contentLength`. + internal var contentLength: Swift.Double? + /// - Remark: Generated from `#/components/schemas/FileMetadata/httpStatusCode`. + internal var httpStatusCode: Swift.Double? + /// Creates a new `FileMetadata`. + /// + /// - Parameters: + /// - eTag: + /// - size: + /// - mimetype: + /// - cacheControl: + /// - lastModified: + /// - contentLength: + /// - httpStatusCode: + internal init( + eTag: Swift.String? = nil, + size: Swift.Double? = nil, + mimetype: Swift.String? = nil, + cacheControl: Swift.String? = nil, + lastModified: Swift.String? = nil, + contentLength: Swift.Double? = nil, + httpStatusCode: Swift.Double? = nil + ) { + self.eTag = eTag + self.size = size + self.mimetype = mimetype + self.cacheControl = cacheControl + self.lastModified = lastModified + self.contentLength = contentLength + self.httpStatusCode = httpStatusCode + } + internal enum CodingKeys: String, CodingKey { + case eTag + case size + case mimetype + case cacheControl + case lastModified + case contentLength + case httpStatusCode + } + } + /// - Remark: Generated from `#/components/schemas/FileObject`. + internal struct FileObject: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FileObject/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/FileObject/id`. + internal var id: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/updated_at`. + internal var updated_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/created_at`. + internal var created_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/last_accessed_at`. + internal var last_accessed_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/metadata`. + internal var metadata: Components.Schemas.FileMetadata? + /// Creates a new `FileObject`. + /// + /// - Parameters: + /// - name: + /// - id: + /// - updated_at: + /// - created_at: + /// - last_accessed_at: + /// - metadata: + internal init( + name: Swift.String, + id: Swift.String? = nil, + updated_at: Swift.String? = nil, + created_at: Swift.String? = nil, + last_accessed_at: Swift.String? = nil, + metadata: Components.Schemas.FileMetadata? = nil + ) { + self.name = name + self.id = id + self.updated_at = updated_at + self.created_at = created_at + self.last_accessed_at = last_accessed_at + self.metadata = metadata + } + internal enum CodingKeys: String, CodingKey { + case name + case id + case updated_at + case created_at + case last_accessed_at + case metadata + } + } + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent`. + internal struct GetBucketResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/id`. + internal var id: Swift.String + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/file_size_limit`. + internal var file_size_limit: Swift.Double? + /// Common string list shape reused across services. + /// + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/created_at`. + internal var created_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/GetBucketResponseContent/updated_at`. + internal var updated_at: Swift.String? + /// Creates a new `GetBucketResponseContent`. + /// + /// - Parameters: + /// - id: + /// - name: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: Common string list shape reused across services. + /// - created_at: + /// - updated_at: + internal init( + id: Swift.String, + name: Swift.String, + _public: Swift.Bool, + file_size_limit: Swift.Double? = nil, + allowed_mime_types: [Swift.String]? = nil, + created_at: Swift.String? = nil, + updated_at: Swift.String? = nil + ) { + self.id = id + self.name = name + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + self.created_at = created_at + self.updated_at = updated_at + } + internal enum CodingKeys: String, CodingKey { + case id + case name + case _public = "public" + case file_size_limit + case allowed_mime_types + case created_at + case updated_at + } + } + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent`. + internal struct GetObjectInfoResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/eTag`. + internal var eTag: Swift.String? + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/size`. + internal var size: Swift.Double? + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/mimetype`. + internal var mimetype: Swift.String? + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/cacheControl`. + internal var cacheControl: Swift.String? + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/lastModified`. + internal var lastModified: Swift.String? + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/contentLength`. + internal var contentLength: Swift.Double? + /// - Remark: Generated from `#/components/schemas/GetObjectInfoResponseContent/httpStatusCode`. + internal var httpStatusCode: Swift.Double? + /// Creates a new `GetObjectInfoResponseContent`. + /// + /// - Parameters: + /// - eTag: + /// - size: + /// - mimetype: + /// - cacheControl: + /// - lastModified: + /// - contentLength: + /// - httpStatusCode: + internal init( + eTag: Swift.String? = nil, + size: Swift.Double? = nil, + mimetype: Swift.String? = nil, + cacheControl: Swift.String? = nil, + lastModified: Swift.String? = nil, + contentLength: Swift.Double? = nil, + httpStatusCode: Swift.Double? = nil + ) { + self.eTag = eTag + self.size = size + self.mimetype = mimetype + self.cacheControl = cacheControl + self.lastModified = lastModified + self.contentLength = contentLength + self.httpStatusCode = httpStatusCode + } + internal enum CodingKeys: String, CodingKey { + case eTag + case size + case mimetype + case cacheControl + case lastModified + case contentLength + case httpStatusCode + } + } + /// - Remark: Generated from `#/components/schemas/ListBucketsResponseContent`. + internal struct ListBucketsResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ListBucketsResponseContent/items`. + internal var items: [Components.Schemas.Bucket] + /// Creates a new `ListBucketsResponseContent`. + /// + /// - Parameters: + /// - items: + internal init(items: [Components.Schemas.Bucket]) { + self.items = items + } + internal enum CodingKeys: String, CodingKey { + case items + } + } + /// - Remark: Generated from `#/components/schemas/ListObjectsRequestContent`. + internal struct ListObjectsRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ListObjectsRequestContent/prefix`. + internal var prefix: Swift.String + /// - Remark: Generated from `#/components/schemas/ListObjectsRequestContent/limit`. + internal var limit: Swift.Double? + /// - Remark: Generated from `#/components/schemas/ListObjectsRequestContent/offset`. + internal var offset: Swift.Double? + /// - Remark: Generated from `#/components/schemas/ListObjectsRequestContent/sortBy`. + internal var sortBy: Components.Schemas.SortBy? + /// Creates a new `ListObjectsRequestContent`. + /// + /// - Parameters: + /// - prefix: + /// - limit: + /// - offset: + /// - sortBy: + internal init( + prefix: Swift.String, + limit: Swift.Double? = nil, + offset: Swift.Double? = nil, + sortBy: Components.Schemas.SortBy? = nil + ) { + self.prefix = prefix + self.limit = limit + self.offset = offset + self.sortBy = sortBy + } + internal enum CodingKeys: String, CodingKey { + case prefix + case limit + case offset + case sortBy + } + } + /// - Remark: Generated from `#/components/schemas/ListObjectsResponseContent`. + internal struct ListObjectsResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ListObjectsResponseContent/items`. + internal var items: [Components.Schemas.FileObject] + /// Creates a new `ListObjectsResponseContent`. + /// + /// - Parameters: + /// - items: + internal init(items: [Components.Schemas.FileObject]) { + self.items = items + } + internal enum CodingKeys: String, CodingKey { + case items + } + } + /// - Remark: Generated from `#/components/schemas/MoveObjectRequestContent`. + internal struct MoveObjectRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/MoveObjectRequestContent/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/components/schemas/MoveObjectRequestContent/sourceKey`. + internal var sourceKey: Swift.String + /// - Remark: Generated from `#/components/schemas/MoveObjectRequestContent/destinationKey`. + internal var destinationKey: Swift.String + /// - Remark: Generated from `#/components/schemas/MoveObjectRequestContent/destinationBucket`. + internal var destinationBucket: Swift.String? + /// Creates a new `MoveObjectRequestContent`. + /// + /// - Parameters: + /// - bucketId: + /// - sourceKey: + /// - destinationKey: + /// - destinationBucket: + internal init( + bucketId: Swift.String, + sourceKey: Swift.String, + destinationKey: Swift.String, + destinationBucket: Swift.String? = nil + ) { + self.bucketId = bucketId + self.sourceKey = sourceKey + self.destinationKey = destinationKey + self.destinationBucket = destinationBucket + } + internal enum CodingKeys: String, CodingKey { + case bucketId + case sourceKey + case destinationKey + case destinationBucket + } + } + /// - Remark: Generated from `#/components/schemas/SignedUrlResult`. + internal struct SignedUrlResult: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/SignedUrlResult/signedURL`. + internal var signedURL: Swift.String? + /// - Remark: Generated from `#/components/schemas/SignedUrlResult/path`. + internal var path: Swift.String + /// - Remark: Generated from `#/components/schemas/SignedUrlResult/error`. + internal var error: Swift.String? + /// Creates a new `SignedUrlResult`. + /// + /// - Parameters: + /// - signedURL: + /// - path: + /// - error: + internal init( + signedURL: Swift.String? = nil, + path: Swift.String, + error: Swift.String? = nil + ) { + self.signedURL = signedURL + self.path = path + self.error = error + } + internal enum CodingKeys: String, CodingKey { + case signedURL + case path + case error + } + } + /// - Remark: Generated from `#/components/schemas/SortBy`. + internal struct SortBy: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/SortBy/column`. + internal var column: Swift.String? + /// - Remark: Generated from `#/components/schemas/SortBy/order`. + internal var order: Swift.String? + /// Creates a new `SortBy`. + /// + /// - Parameters: + /// - column: + /// - order: + internal init( + column: Swift.String? = nil, + order: Swift.String? = nil + ) { + self.column = column + self.order = order + } + internal enum CodingKeys: String, CodingKey { + case column + case order + } + } + /// - Remark: Generated from `#/components/schemas/StorageErrorResponseContent`. + internal struct StorageErrorResponseContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/StorageErrorResponseContent/message`. + internal var message: Swift.String? + /// - Remark: Generated from `#/components/schemas/StorageErrorResponseContent/error`. + internal var error: Swift.String? + /// - Remark: Generated from `#/components/schemas/StorageErrorResponseContent/statusCode`. + internal var statusCode: Swift.String? + /// Creates a new `StorageErrorResponseContent`. + /// + /// - Parameters: + /// - message: + /// - error: + /// - statusCode: + internal init( + message: Swift.String? = nil, + error: Swift.String? = nil, + statusCode: Swift.String? = nil + ) { + self.message = message + self.error = error + self.statusCode = statusCode + } + internal enum CodingKeys: String, CodingKey { + case message + case error + case statusCode + } + } + /// - Remark: Generated from `#/components/schemas/UpdateBucketRequestContent`. + internal struct UpdateBucketRequestContent: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/UpdateBucketRequestContent/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/UpdateBucketRequestContent/file_size_limit`. + internal var file_size_limit: Swift.Double? + /// Common string list shape reused across services. + /// + /// - Remark: Generated from `#/components/schemas/UpdateBucketRequestContent/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// Creates a new `UpdateBucketRequestContent`. + /// + /// - Parameters: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: Common string list shape reused across services. + internal init( + _public: Swift.Bool, + file_size_limit: Swift.Double? = nil, + allowed_mime_types: [Swift.String]? = nil + ) { + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + } + internal enum CodingKeys: String, CodingKey { + case _public = "public" + case file_size_limit + case allowed_mime_types + } + } + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + internal enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + internal enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + internal enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + internal enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +internal enum Operations { + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(ListBuckets)`. + internal enum ListBuckets { + internal static let id: Swift.String = "ListBuckets" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.ListBuckets.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + internal init(headers: Operations.ListBuckets.Input.Headers = .init()) { + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/200/content/application\/json`. + case json(Components.Schemas.ListBucketsResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.ListBucketsResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.ListBuckets.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.ListBuckets.Output.Ok.Body) { + self.body = body + } + } + /// ListBuckets 200 response + /// + /// - Remark: Generated from `#/paths//bucket/get(ListBuckets)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.ListBuckets.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.ListBuckets.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.ListBuckets.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.ListBuckets.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//bucket/get(ListBuckets)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.ListBuckets.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.ListBuckets.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)`. + internal enum CreateBucket { + internal static let id: Swift.String = "CreateBucket" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.CreateBucket.Input.Headers + /// - Remark: Generated from `#/paths/bucket/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CreateBucketRequestContent) + } + internal var body: Operations.CreateBucket.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + internal init( + headers: Operations.CreateBucket.Input.Headers = .init(), + body: Operations.CreateBucket.Input.Body + ) { + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + internal init() {} + } + /// CreateBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CreateBucket.Output.Ok) + /// CreateBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + internal static var ok: Self { + .ok(.init()) + } + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CreateBucket.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateBucket.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateBucket.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//bucket/post(CreateBucket)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CreateBucket.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CreateBucket.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(GetBucket)`. + internal enum GetBucket { + internal static let id: Swift.String = "GetBucket" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.GetBucket.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/GET/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.GetBucket.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.GetBucket.Input.Path, + headers: Operations.GetBucket.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.GetBucketResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.GetBucketResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.GetBucket.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.GetBucket.Output.Ok.Body) { + self.body = body + } + } + /// GetBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/get(GetBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.GetBucket.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.GetBucket.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.GetBucket.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.GetBucket.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/get(GetBucket)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.GetBucket.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.GetBucket.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)`. + internal enum UpdateBucket { + internal static let id: Swift.String = "UpdateBucket" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.UpdateBucket.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.UpdateBucket.Input.Headers + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/requestBody/content/application\/json`. + case json(Components.Schemas.UpdateBucketRequestContent) + } + internal var body: Operations.UpdateBucket.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.UpdateBucket.Input.Path, + headers: Operations.UpdateBucket.Input.Headers = .init(), + body: Operations.UpdateBucket.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + internal init() {} + } + /// UpdateBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.UpdateBucket.Output.Ok) + /// UpdateBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + internal static var ok: Self { + .ok(.init()) + } + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.UpdateBucket.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpdateBucket.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UpdateBucket.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/put(UpdateBucket)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.UpdateBucket.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.UpdateBucket.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)`. + internal enum DeleteBucket { + internal static let id: Swift.String = "DeleteBucket" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.DeleteBucket.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.DeleteBucket.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.DeleteBucket.Input.Path, + headers: Operations.DeleteBucket.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + internal init() {} + } + /// DeleteBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.DeleteBucket.Output.Ok) + /// DeleteBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + internal static var ok: Self { + .ok(.init()) + } + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.DeleteBucket.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.DeleteBucket.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.DeleteBucket.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/delete(DeleteBucket)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.DeleteBucket.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.DeleteBucket.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)`. + internal enum EmptyBucket { + internal static let id: Swift.String = "EmptyBucket" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.EmptyBucket.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.EmptyBucket.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.EmptyBucket.Input.Path, + headers: Operations.EmptyBucket.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + internal init() {} + } + /// EmptyBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.EmptyBucket.Output.Ok) + /// EmptyBucket 200 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)/responses/200`. + /// + /// HTTP response code: `200 ok`. + internal static var ok: Self { + .ok(.init()) + } + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.EmptyBucket.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.EmptyBucket.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.EmptyBucket.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(EmptyBucket)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.EmptyBucket.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.EmptyBucket.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(CopyObject)`. + internal enum CopyObject { + internal static let id: Swift.String = "CopyObject" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.CopyObject.Input.Headers + /// - Remark: Generated from `#/paths/object/copy/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CopyObjectRequestContent) + } + internal var body: Operations.CopyObject.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + internal init( + headers: Operations.CopyObject.Input.Headers = .init(), + body: Operations.CopyObject.Input.Body + ) { + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CopyObjectResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CopyObjectResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CopyObject.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CopyObject.Output.Ok.Body) { + self.body = body + } + } + /// CopyObject 200 response + /// + /// - Remark: Generated from `#/paths//object/copy/post(CopyObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CopyObject.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CopyObject.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CopyObject.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CopyObject.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/copy/post(CopyObject)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CopyObject.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CopyObject.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath+}/get(GetObjectInfo)`. + internal enum GetObjectInfo { + internal static let id: Swift.String = "GetObjectInfo" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/path/wildcardPath+`. + internal var wildcardPath_plus_: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath_plus_: + internal init( + bucketId: Swift.String, + wildcardPath_plus_: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath_plus_ = wildcardPath_plus_ + } + } + internal var path: Operations.GetObjectInfo.Input.Path + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.GetObjectInfo.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.GetObjectInfo.Input.Path, + headers: Operations.GetObjectInfo.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.GetObjectInfoResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.GetObjectInfoResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.GetObjectInfo.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.GetObjectInfo.Output.Ok.Body) { + self.body = body + } + } + /// GetObjectInfo 200 response + /// + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath+}/get(GetObjectInfo)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.GetObjectInfo.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.GetObjectInfo.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath+}/GET/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.GetObjectInfo.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.GetObjectInfo.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath+}/get(GetObjectInfo)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.GetObjectInfo.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.GetObjectInfo.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(ListObjects)`. + internal enum ListObjects { + internal static let id: Swift.String = "ListObjects" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + internal init(bucketId: Swift.String) { + self.bucketId = bucketId + } + } + internal var path: Operations.ListObjects.Input.Path + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.ListObjects.Input.Headers + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.ListObjectsRequestContent) + } + internal var body: Operations.ListObjects.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.ListObjects.Input.Path, + headers: Operations.ListObjects.Input.Headers = .init(), + body: Operations.ListObjects.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.ListObjectsResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.ListObjectsResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.ListObjects.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.ListObjects.Output.Ok.Body) { + self.body = body + } + } + /// ListObjects 200 response + /// + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(ListObjects)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.ListObjects.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.ListObjects.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.ListObjects.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.ListObjects.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(ListObjects)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.ListObjects.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.ListObjects.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)`. + internal enum MoveObject { + internal static let id: Swift.String = "MoveObject" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.MoveObject.Input.Headers + /// - Remark: Generated from `#/paths/object/move/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/requestBody/content/application\/json`. + case json(Components.Schemas.MoveObjectRequestContent) + } + internal var body: Operations.MoveObject.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + internal init( + headers: Operations.MoveObject.Input.Headers = .init(), + body: Operations.MoveObject.Input.Body + ) { + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + internal init() {} + } + /// MoveObject 200 response + /// + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.MoveObject.Output.Ok) + /// MoveObject 200 response + /// + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + internal static var ok: Self { + .ok(.init()) + } + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.MoveObject.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.MoveObject.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.MoveObject.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/move/post(MoveObject)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.MoveObject.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.MoveObject.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(CreateSignedUrls)`. + internal enum CreateSignedUrls { + internal static let id: Swift.String = "CreateSignedUrls" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + internal init(bucketId: Swift.String) { + self.bucketId = bucketId + } + } + internal var path: Operations.CreateSignedUrls.Input.Path + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.CreateSignedUrls.Input.Headers + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlsRequestContent) + } + internal var body: Operations.CreateSignedUrls.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.CreateSignedUrls.Input.Path, + headers: Operations.CreateSignedUrls.Input.Headers = .init(), + body: Operations.CreateSignedUrls.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlsResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CreateSignedUrlsResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateSignedUrls.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateSignedUrls.Output.Ok.Body) { + self.body = body + } + } + /// CreateSignedUrls 200 response + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(CreateSignedUrls)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CreateSignedUrls.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CreateSignedUrls.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateSignedUrls.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateSignedUrls.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(CreateSignedUrls)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CreateSignedUrls.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CreateSignedUrls.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUrl)`. + internal enum CreateSignedUrl { + internal static let id: Swift.String = "CreateSignedUrl" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/path/wildcardPath+`. + internal var wildcardPath_plus_: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath_plus_: + internal init( + bucketId: Swift.String, + wildcardPath_plus_: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath_plus_ = wildcardPath_plus_ + } + } + internal var path: Operations.CreateSignedUrl.Input.Path + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.CreateSignedUrl.Input.Headers + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlRequestContent) + } + internal var body: Operations.CreateSignedUrl.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.CreateSignedUrl.Input.Path, + headers: Operations.CreateSignedUrl.Input.Headers = .init(), + body: Operations.CreateSignedUrl.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CreateSignedUrlResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateSignedUrl.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateSignedUrl.Output.Ok.Body) { + self.body = body + } + } + /// CreateSignedUrl 200 response + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUrl)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CreateSignedUrl.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CreateSignedUrl.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath+}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateSignedUrl.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateSignedUrl.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUrl)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CreateSignedUrl.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CreateSignedUrl.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUploadUrl)`. + internal enum CreateSignedUploadUrl { + internal static let id: Swift.String = "CreateSignedUploadUrl" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/path/wildcardPath+`. + internal var wildcardPath_plus_: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath_plus_: + internal init( + bucketId: Swift.String, + wildcardPath_plus_: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath_plus_ = wildcardPath_plus_ + } + } + internal var path: Operations.CreateSignedUploadUrl.Input.Path + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_upsert: + /// - accept: + internal init( + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.CreateSignedUploadUrl.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.CreateSignedUploadUrl.Input.Path, + headers: Operations.CreateSignedUploadUrl.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CreateSignedUploadUrlResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CreateSignedUploadUrlResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateSignedUploadUrl.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateSignedUploadUrl.Output.Ok.Body) { + self.body = body + } + } + /// CreateSignedUploadUrl 200 response + /// + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUploadUrl)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CreateSignedUploadUrl.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CreateSignedUploadUrl.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath+}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateSignedUploadUrl.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateSignedUploadUrl.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath+}/post(CreateSignedUploadUrl)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CreateSignedUploadUrl.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CreateSignedUploadUrl.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)`. + internal enum DeleteObjects { + internal static let id: Swift.String = "DeleteObjects" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/path/bucketId`. + internal var bucketId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + internal init(bucketId: Swift.String) { + self.bucketId = bucketId + } + } + internal var path: Operations.DeleteObjects.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.DeleteObjects.Input.Headers + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/requestBody/content/application\/json`. + case json(Components.Schemas.DeleteObjectsRequestContent) + } + internal var body: Operations.DeleteObjects.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.DeleteObjects.Input.Path, + headers: Operations.DeleteObjects.Input.Headers = .init(), + body: Operations.DeleteObjects.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/200/content/application\/json`. + case json(Components.Schemas.DeleteObjectsResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DeleteObjectsResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.DeleteObjects.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.DeleteObjects.Output.Ok.Body) { + self.body = body + } + } + /// DeleteObjects 200 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.DeleteObjects.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.DeleteObjects.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.DeleteObjects.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.DeleteObjects.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.DeleteObjects.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.DeleteObjects.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. + internal enum HeadObject { + internal static let id: Swift.String = "HeadObject" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/HEAD/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/HEAD/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/HEAD/path/wildcardPath+`. + internal var wildcardPath_plus_: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath_plus_: + internal init( + bucketId: Swift.String, + wildcardPath_plus_: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath_plus_ = wildcardPath_plus_ + } + } + internal var path: Operations.HeadObject.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/HEAD/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.HeadObject.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.HeadObject.Input.Path, + headers: Operations.HeadObject.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// Creates a new `Ok`. + internal init() {} + } + /// HeadObject 200 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.HeadObject.Output.Ok) + /// HeadObject 200 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + internal static var ok: Self { + .ok(.init()) + } + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.HeadObject.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/HEAD/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/HEAD/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.HeadObject.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.HeadObject.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.HeadObject.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.HeadObject.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } +} diff --git a/Sources/Storage/openapi-generator-config.yaml b/Sources/Storage/openapi-generator-config.yaml new file mode 100644 index 000000000..1df6f2876 --- /dev/null +++ b/Sources/Storage/openapi-generator-config.yaml @@ -0,0 +1,4 @@ +generate: + - types + - client +accessModifier: internal diff --git a/smithy/model/storage.smithy b/smithy/model/storage.smithy index d3c3cf046..b512458ea 100644 --- a/smithy/model/storage.smithy +++ b/smithy/model/storage.smithy @@ -40,7 +40,6 @@ operation ListBuckets { structure ListBucketsOutput { @required - @httpPayload items: BucketList } @@ -77,6 +76,7 @@ structure CreateBucketInput { } @http(method: "PUT", uri: "/bucket/{id}", code: 200) +@idempotent operation UpdateBucket { input: UpdateBucketInput errors: [StorageError] @@ -105,6 +105,7 @@ structure EmptyBucketInput { } @http(method: "DELETE", uri: "/bucket/{id}", code: 200) +@idempotent operation DeleteBucket { input: DeleteBucketInput errors: [StorageError] @@ -150,6 +151,8 @@ structure CopyObjectOutput { } @http(method: "DELETE", uri: "/object/{bucketId}", code: 200) +@idempotent +@suppress(["HttpMethodSemantics.UnexpectedPayload"]) operation DeleteObjects { input: DeleteObjectsInput output: DeleteObjectsOutput @@ -166,7 +169,6 @@ structure DeleteObjectsInput { structure DeleteObjectsOutput { @required - @httpPayload items: FileObjectList } @@ -199,7 +201,6 @@ structure SortBy { structure ListObjectsOutput { @required - @httpPayload items: FileObjectList } @@ -260,7 +261,6 @@ structure CreateSignedUrlsInput { structure CreateSignedUrlsOutput { @required - @httpPayload items: SignedUrlResultList } diff --git a/smithy/output/openapi/FunctionsService.openapi.json b/smithy/output/openapi/FunctionsService.openapi.json new file mode 100644 index 000000000..d91b56316 --- /dev/null +++ b/smithy/output/openapi/FunctionsService.openapi.json @@ -0,0 +1,82 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "Supabase Functions API", + "version": "1.0" + }, + "paths": { + "/functions/v1/{functionName}": { + "post": { + "operationId": "InvokeFunction", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionInputPayload" + } + } + } + }, + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "x-region", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "InvokeFunction 200 response", + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionOutputPayload" + } + } + } + }, + "400": { + "description": "FunctionsError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FunctionsErrorResponseContent" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "FunctionsErrorResponseContent": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "InvokeFunctionInputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionOutputPayload": { + "type": "string", + "format": "byte" + } + } + } +} diff --git a/smithy/output/openapi/StorageService.openapi.json b/smithy/output/openapi/StorageService.openapi.json new file mode 100644 index 000000000..6cb6e6944 --- /dev/null +++ b/smithy/output/openapi/StorageService.openapi.json @@ -0,0 +1,1037 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "Supabase Storage API", + "version": "1.0" + }, + "paths": { + "/bucket": { + "get": { + "operationId": "ListBuckets", + "responses": { + "200": { + "description": "ListBuckets 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListBucketsResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + }, + "post": { + "operationId": "CreateBucket", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBucketRequestContent" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "CreateBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/bucket/{id}": { + "delete": { + "operationId": "DeleteBucket", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "DeleteBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + }, + "get": { + "operationId": "GetBucket", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetBucket 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetBucketResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + }, + "put": { + "operationId": "UpdateBucket", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBucketRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/bucket/{id}/empty": { + "post": { + "operationId": "EmptyBucket", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "EmptyBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/copy": { + "post": { + "operationId": "CopyObject", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CopyObjectRequestContent" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "CopyObject 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CopyObjectResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/info/{bucketId}/{wildcardPath+}": { + "get": { + "operationId": "GetObjectInfo", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetObjectInfo 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetObjectInfoResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/list/{bucketId}": { + "post": { + "operationId": "ListObjects", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListObjectsRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "ListObjects 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListObjectsResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/move": { + "post": { + "operationId": "MoveObject", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MoveObjectRequestContent" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "MoveObject 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/sign/{bucketId}": { + "post": { + "operationId": "CreateSignedUrls", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlsRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "CreateSignedUrls 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlsResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/sign/{bucketId}/{wildcardPath+}": { + "post": { + "operationId": "CreateSignedUrl", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "CreateSignedUrl 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/upload/sign/{bucketId}/{wildcardPath+}": { + "post": { + "operationId": "CreateSignedUploadUrl", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "x-upsert", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "CreateSignedUploadUrl 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUploadUrlResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/{bucketId}": { + "delete": { + "operationId": "DeleteObjects", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteObjectsRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "DeleteObjects 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteObjectsResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/{bucketId}/{wildcardPath+}": { + "head": { + "operationId": "HeadObject", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "HeadObject 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Bucket": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "public" + ] + }, + "CopyObjectRequestContent": { + "type": "object", + "properties": { + "bucketId": { + "type": "string" + }, + "sourceKey": { + "type": "string" + }, + "destinationKey": { + "type": "string" + }, + "destinationBucket": { + "type": "string" + } + }, + "required": [ + "bucketId", + "destinationKey", + "sourceKey" + ] + }, + "CopyObjectResponseContent": { + "type": "object", + "properties": { + "Key": { + "type": "string" + } + }, + "required": [ + "Key" + ] + }, + "CreateBucketRequestContent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + } + }, + "required": [ + "id", + "name", + "public" + ] + }, + "CreateSignedUploadUrlResponseContent": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ] + }, + "CreateSignedUrlRequestContent": { + "type": "object", + "properties": { + "expiresIn": { + "type": "number" + } + }, + "required": [ + "expiresIn" + ] + }, + "CreateSignedUrlResponseContent": { + "type": "object", + "properties": { + "signedURL": { + "type": "string" + } + }, + "required": [ + "signedURL" + ] + }, + "CreateSignedUrlsRequestContent": { + "type": "object", + "properties": { + "expiresIn": { + "type": "number" + }, + "paths": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + } + }, + "required": [ + "expiresIn", + "paths" + ] + }, + "CreateSignedUrlsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignedUrlResult" + } + } + }, + "required": [ + "items" + ] + }, + "DeleteObjectsRequestContent": { + "type": "object", + "properties": { + "prefixes": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + } + }, + "required": [ + "prefixes" + ] + }, + "DeleteObjectsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileObject" + } + } + }, + "required": [ + "items" + ] + }, + "FileMetadata": { + "type": "object", + "properties": { + "eTag": { + "type": "string" + }, + "size": { + "type": "number" + }, + "mimetype": { + "type": "string" + }, + "cacheControl": { + "type": "string" + }, + "lastModified": { + "type": "string" + }, + "contentLength": { + "type": "number" + }, + "httpStatusCode": { + "type": "number" + } + } + }, + "FileObject": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "last_accessed_at": { + "type": "string" + }, + "metadata": { + "$ref": "#/components/schemas/FileMetadata" + } + }, + "required": [ + "name" + ] + }, + "GetBucketResponseContent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "public" + ] + }, + "GetObjectInfoResponseContent": { + "type": "object", + "properties": { + "eTag": { + "type": "string" + }, + "size": { + "type": "number" + }, + "mimetype": { + "type": "string" + }, + "cacheControl": { + "type": "string" + }, + "lastModified": { + "type": "string" + }, + "contentLength": { + "type": "number" + }, + "httpStatusCode": { + "type": "number" + } + } + }, + "ListBucketsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Bucket" + } + } + }, + "required": [ + "items" + ] + }, + "ListObjectsRequestContent": { + "type": "object", + "properties": { + "prefix": { + "type": "string" + }, + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "sortBy": { + "$ref": "#/components/schemas/SortBy" + } + }, + "required": [ + "prefix" + ] + }, + "ListObjectsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileObject" + } + } + }, + "required": [ + "items" + ] + }, + "MoveObjectRequestContent": { + "type": "object", + "properties": { + "bucketId": { + "type": "string" + }, + "sourceKey": { + "type": "string" + }, + "destinationKey": { + "type": "string" + }, + "destinationBucket": { + "type": "string" + } + }, + "required": [ + "bucketId", + "destinationKey", + "sourceKey" + ] + }, + "SignedUrlResult": { + "type": "object", + "properties": { + "signedURL": { + "type": "string" + }, + "path": { + "type": "string" + }, + "error": { + "type": "string" + } + }, + "required": [ + "path" + ] + }, + "SortBy": { + "type": "object", + "properties": { + "column": { + "type": "string" + }, + "order": { + "type": "string" + } + } + }, + "StorageErrorResponseContent": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "error": { + "type": "string" + }, + "statusCode": { + "type": "string" + } + } + }, + "UpdateBucketRequestContent": { + "type": "object", + "properties": { + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + } + }, + "required": [ + "public" + ] + } + } + } +} From 5c9aebf43438bb0f0e5248eba10ccc08e751d7b3 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 07:13:12 -0300 Subject: [PATCH 07/32] fix(codegen): resolve Types.swift SPM conflict and portable Makefile generator path --- .gitignore | 1 + Makefile | 14 +++++++++----- .../{Types.swift => FunctionsTypes.swift} | 0 .../Storage/{Types.swift => StorageTypes.swift} | 0 4 files changed, 10 insertions(+), 5 deletions(-) rename Sources/Functions/{Types.swift => FunctionsTypes.swift} (100%) rename Sources/Storage/{Types.swift => StorageTypes.swift} (100%) diff --git a/.gitignore b/.gitignore index 0c2c61c92..c9dd4759c 100644 --- a/.gitignore +++ b/.gitignore @@ -115,3 +115,4 @@ yarn-debug.log* yarn-error.log* .jj/ .treq/ +smithy/build/ diff --git a/Makefile b/Makefile index c3d66399c..a8d8b18ec 100644 --- a/Makefile +++ b/Makefile @@ -93,21 +93,25 @@ endef # ── Code generation ──────────────────────────────────────────────────────────── -.PHONY: generate-smithy generate-swift-storage generate-swift-functions generate check-generate +.PHONY: generate-smithy generate-swift-storage generate-swift-functions generate check-generate check-swift-openapi-generator + +check-swift-openapi-generator: + @which swift-openapi-generator > /dev/null 2>&1 || \ + (echo "Error: swift-openapi-generator not found in PATH. Build from source: https://github.com/apple/swift-openapi-generator" && exit 1) generate-smithy: cd smithy && smithy build cp smithy/build/smithy/storage-openapi/openapi/StorageService.openapi.json smithy/output/openapi/StorageService.openapi.json cp smithy/build/smithy/functions-openapi/openapi/FunctionsService.openapi.json smithy/output/openapi/FunctionsService.openapi.json -generate-swift-storage: - $(HOME)/bin/swift-openapi-generator generate \ +generate-swift-storage: check-swift-openapi-generator + swift-openapi-generator generate \ --config Sources/Storage/openapi-generator-config.yaml \ --output-directory Sources/Storage/Generated \ smithy/output/openapi/StorageService.openapi.json -generate-swift-functions: - $(HOME)/bin/swift-openapi-generator generate \ +generate-swift-functions: check-swift-openapi-generator + swift-openapi-generator generate \ --config Sources/Functions/openapi-generator-config.yaml \ --output-directory Sources/Functions/Generated \ smithy/output/openapi/FunctionsService.openapi.json diff --git a/Sources/Functions/Types.swift b/Sources/Functions/FunctionsTypes.swift similarity index 100% rename from Sources/Functions/Types.swift rename to Sources/Functions/FunctionsTypes.swift diff --git a/Sources/Storage/Types.swift b/Sources/Storage/StorageTypes.swift similarity index 100% rename from Sources/Storage/Types.swift rename to Sources/Storage/StorageTypes.swift From 74d720200451e11d692daf0a4b8d0ee6581bc6f3 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 07:20:56 -0300 Subject: [PATCH 08/32] feat(helpers): add SupabaseClientTransport for generated API clients --- Sources/Helpers/SupabaseClientTransport.swift | 124 +++++++++++++++++ .../SupabaseClientTransportTests.swift | 128 ++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 Sources/Helpers/SupabaseClientTransport.swift create mode 100644 Tests/HelpersTests/SupabaseClientTransportTests.swift diff --git a/Sources/Helpers/SupabaseClientTransport.swift b/Sources/Helpers/SupabaseClientTransport.swift new file mode 100644 index 000000000..e89a8d28f --- /dev/null +++ b/Sources/Helpers/SupabaseClientTransport.swift @@ -0,0 +1,124 @@ +// +// SupabaseClientTransport.swift +// Helpers +// +// Created by Guilherme Souza on 30/06/26. +// + +import Foundation +import HTTPTypes +import OpenAPIRuntime + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +/// URLSession-based `ClientTransport` for generated Supabase API clients. +/// +/// Builds `URLRequest` values from `HTTPRequest`, injects a Bearer token via +/// `tokenProvider` when the request has no existing `Authorization` header, +/// and converts the response back to `HTTPResponse` + `HTTPBody`. +/// +/// This transport is standalone — it does not depend on `_HTTPClient`. +package struct SupabaseClientTransport: ClientTransport, @unchecked Sendable { + package let session: URLSession + package let tokenProvider: (@Sendable () async throws -> String?)? + + package init( + session: URLSession = URLSession(configuration: .default), + tokenProvider: (@Sendable () async throws -> String?)? = nil + ) { + self.session = session + self.tokenProvider = tokenProvider + } + + package func send( + _ request: HTTPTypes.HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String + ) async throws -> (HTTPTypes.HTTPResponse, HTTPBody?) { + let urlRequest = try await buildURLRequest(request, body: body, baseURL: baseURL) + let (data, urlResponse) = try await session.data(for: urlRequest) + + guard let httpURLResponse = urlResponse as? HTTPURLResponse else { + throw URLError(.badServerResponse) + } + + var responseHeaderFields = HTTPFields() + for (key, value) in httpURLResponse.allHeaderFields { + let keyString = String(describing: key) + let valueString = String(describing: value) + if let fieldName = HTTPField.Name(keyString) { + responseHeaderFields.append(HTTPField(name: fieldName, value: valueString)) + } + } + + let httpResponse = HTTPTypes.HTTPResponse( + status: HTTPTypes.HTTPResponse.Status(code: httpURLResponse.statusCode), + headerFields: responseHeaderFields + ) + + let responseBody: HTTPBody? = data.isEmpty ? nil : HTTPBody(data) + return (httpResponse, responseBody) + } + + private func buildURLRequest( + _ request: HTTPTypes.HTTPRequest, + body: HTTPBody?, + baseURL: URL + ) async throws -> URLRequest { + guard + var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: false), + let requestPath = request.path + else { + throw URLError(.badURL) + } + + // Merge the operation path into the base URL path. + // Base: https://x.supabase.co/storage/v1 path: /bucket + // Result: https://x.supabase.co/storage/v1/bucket + let existingPath = + components.path.hasSuffix("/") + ? String(components.path.dropLast()) : components.path + let operationPath = requestPath.hasPrefix("/") ? requestPath : "/\(requestPath)" + components.path = existingPath + operationPath + + // Move query items from the request path into URLComponents. + if let queryStart = operationPath.firstIndex(of: "?") { + let queryString = String(operationPath[queryStart...].dropFirst()) + components.query = queryString + components.path = existingPath + String(operationPath[operationPath.startIndex.. (Data, HTTPURLResponse) + ) -> URLSession { + MockURLProtocol.handler = handler + let config = URLSessionConfiguration.ephemeral + config.protocolClasses = [MockURLProtocol.self] + return URLSession(configuration: config) + } +} + +final class MockURLProtocol: URLProtocol, @unchecked Sendable { + nonisolated(unsafe) static var handler: + (@Sendable (URLRequest) throws -> (Data, HTTPURLResponse))? + + override class func canInit(with request: URLRequest) -> Bool { true } + override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } + + override func startLoading() { + guard let handler = MockURLProtocol.handler else { return } + do { + let (data, response) = try handler(request) + client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) + client?.urlProtocol(self, didLoad: data) + client?.urlProtocolDidFinishLoading(self) + } catch { + client?.urlProtocol(self, didFailWithError: error) + } + } + + override func stopLoading() {} +} From cf4a2db14da3ea2e5d4a0eca09f40e3975593e4c Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 07:24:41 -0300 Subject: [PATCH 09/32] fix(helpers): use URLSessionTransport for streaming in SupabaseClientTransport --- Package.resolved | 20 +++- Package.swift | 3 + Sources/Helpers/SupabaseClientTransport.swift | 102 +++--------------- .../SupabaseClientTransportTests.swift | 7 +- 4 files changed, 40 insertions(+), 92 deletions(-) diff --git a/Package.resolved b/Package.resolved index afb04c386..0367630e8 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "d67654c567b66ca26d2029195c055c655be7538d0fcbb9842b011c68bee7903f", + "originHash" : "9c103d3f53af06b11e324fc8ea4bfd6859ac3631d96c033ae7aaaae794154249", "pins" : [ { "identity" : "mocker", @@ -46,6 +46,15 @@ "version" : "1.0.6" } }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "a0cb0954ecb21e4e31b0070e6ed5674e8556685a", + "version" : "1.6.0" + } + }, { "identity" : "swift-concurrency-extras", "kind" : "remoteSourceControl", @@ -91,6 +100,15 @@ "version" : "1.12.0" } }, + { + "identity" : "swift-openapi-urlsession", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-urlsession", + "state" : { + "revision" : "08796d36c99ad2318929bfa1d1e40f82194b65cc", + "version" : "1.3.1" + } + }, { "identity" : "swift-snapshot-testing", "kind" : "remoteSourceControl", diff --git a/Package.swift b/Package.swift index 928e101f4..e0576b703 100644 --- a/Package.swift +++ b/Package.swift @@ -32,6 +32,7 @@ let package = Package( .package(url: "https://github.com/WeTransfer/Mocker", from: "3.0.0"), .package(url: "https://github.com/mattt/Replay.git", from: "0.4.0"), .package(url: "https://github.com/apple/swift-openapi-runtime", from: "1.0.0"), + .package(url: "https://github.com/apple/swift-openapi-urlsession", from: "1.0.0"), ], targets: [ .target( @@ -43,11 +44,13 @@ let package = Package( .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), .product(name: "IssueReporting", package: "xctest-dynamic-overlay"), .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), + .product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession"), ] ), .testTarget( name: "HelpersTests", dependencies: [ + .product(name: "ConcurrencyExtras", package: "swift-concurrency-extras"), .product(name: "CustomDump", package: "swift-custom-dump"), "Helpers", ] diff --git a/Sources/Helpers/SupabaseClientTransport.swift b/Sources/Helpers/SupabaseClientTransport.swift index e89a8d28f..6983ff304 100644 --- a/Sources/Helpers/SupabaseClientTransport.swift +++ b/Sources/Helpers/SupabaseClientTransport.swift @@ -2,33 +2,30 @@ // SupabaseClientTransport.swift // Helpers // -// Created by Guilherme Souza on 30/06/26. -// import Foundation import HTTPTypes import OpenAPIRuntime +import OpenAPIURLSession #if canImport(FoundationNetworking) import FoundationNetworking #endif -/// URLSession-based `ClientTransport` for generated Supabase API clients. -/// -/// Builds `URLRequest` values from `HTTPRequest`, injects a Bearer token via -/// `tokenProvider` when the request has no existing `Authorization` header, -/// and converts the response back to `HTTPResponse` + `HTTPBody`. +/// `ClientTransport` for generated Supabase API clients. /// -/// This transport is standalone — it does not depend on `_HTTPClient`. -package struct SupabaseClientTransport: ClientTransport, @unchecked Sendable { - package let session: URLSession +/// Wraps `URLSessionTransport` from `swift-openapi-urlsession` for correct streaming, +/// and injects a Bearer token when no `Authorization` header is already present. +/// Does not depend on `_HTTPClient`. +package struct SupabaseClientTransport: ClientTransport, Sendable { + private let inner: URLSessionTransport package let tokenProvider: (@Sendable () async throws -> String?)? package init( session: URLSession = URLSession(configuration: .default), tokenProvider: (@Sendable () async throws -> String?)? = nil ) { - self.session = session + self.inner = URLSessionTransport(configuration: .init(session: session)) self.tokenProvider = tokenProvider } @@ -38,87 +35,12 @@ package struct SupabaseClientTransport: ClientTransport, @unchecked Sendable { baseURL: URL, operationID: String ) async throws -> (HTTPTypes.HTTPResponse, HTTPBody?) { - let urlRequest = try await buildURLRequest(request, body: body, baseURL: baseURL) - let (data, urlResponse) = try await session.data(for: urlRequest) - - guard let httpURLResponse = urlResponse as? HTTPURLResponse else { - throw URLError(.badServerResponse) - } - - var responseHeaderFields = HTTPFields() - for (key, value) in httpURLResponse.allHeaderFields { - let keyString = String(describing: key) - let valueString = String(describing: value) - if let fieldName = HTTPField.Name(keyString) { - responseHeaderFields.append(HTTPField(name: fieldName, value: valueString)) - } - } - - let httpResponse = HTTPTypes.HTTPResponse( - status: HTTPTypes.HTTPResponse.Status(code: httpURLResponse.statusCode), - headerFields: responseHeaderFields - ) - - let responseBody: HTTPBody? = data.isEmpty ? nil : HTTPBody(data) - return (httpResponse, responseBody) - } - - private func buildURLRequest( - _ request: HTTPTypes.HTTPRequest, - body: HTTPBody?, - baseURL: URL - ) async throws -> URLRequest { - guard - var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: false), - let requestPath = request.path - else { - throw URLError(.badURL) - } - - // Merge the operation path into the base URL path. - // Base: https://x.supabase.co/storage/v1 path: /bucket - // Result: https://x.supabase.co/storage/v1/bucket - let existingPath = - components.path.hasSuffix("/") - ? String(components.path.dropLast()) : components.path - let operationPath = requestPath.hasPrefix("/") ? requestPath : "/\(requestPath)" - components.path = existingPath + operationPath - - // Move query items from the request path into URLComponents. - if let queryStart = operationPath.firstIndex(of: "?") { - let queryString = String(operationPath[queryStart...].dropFirst()) - components.query = queryString - components.path = existingPath + String(operationPath[operationPath.startIndex..(nil) + var value: URLRequest? { + get { _value.value } + set { _value.withValue { $0 = newValue } } + } } // MARK: - URLSession mock helper From 2ef6d10fe9b5b4e8a2f14fa8d96840d97c71669f Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 08:22:49 -0300 Subject: [PATCH 10/32] feat(storage): wire bucket operations to generated client (Task 5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add package init accepting ClientTransport for testing - Delegate listBuckets/getBucket/createBucket/updateBucket/emptyBucket/deleteBucket to generated Client - Add BucketConversions.swift for Bucket ↔ generated schema conversion - Add MockTransport for unit testing generated client integration - Add StorageClientGeneratedTests with Swift Testing - Add OpenAPIURLSession to Storage target, OpenAPIRuntime to StorageTests target --- Package.swift | 2 + Sources/Storage/BucketConversions.swift | 40 ++++ Sources/Storage/StorageClient.swift | 223 +++++++++++++++--- Tests/StorageTests/MockTransport.swift | 26 ++ .../StorageClientGeneratedTests.swift | 53 +++++ 5 files changed, 312 insertions(+), 32 deletions(-) create mode 100644 Sources/Storage/BucketConversions.swift create mode 100644 Tests/StorageTests/MockTransport.swift create mode 100644 Tests/StorageTests/StorageClientGeneratedTests.swift diff --git a/Package.swift b/Package.swift index e0576b703..cd884681f 100644 --- a/Package.swift +++ b/Package.swift @@ -168,6 +168,7 @@ let package = Package( dependencies: [ "Helpers", .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), + .product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession"), ] ), .testTarget( @@ -176,6 +177,7 @@ let package = Package( .product(name: "CustomDump", package: "swift-custom-dump"), .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), + .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), "Mocker", "TestHelpers", "Storage", diff --git a/Sources/Storage/BucketConversions.swift b/Sources/Storage/BucketConversions.swift new file mode 100644 index 000000000..bbd005902 --- /dev/null +++ b/Sources/Storage/BucketConversions.swift @@ -0,0 +1,40 @@ +// +// BucketConversions.swift +// Storage +// +// Created by Guilherme Souza on 30/06/25. +// + +import Foundation + +extension Bucket { + /// Creates a ``Bucket`` from a generated ``Components/Schemas/Bucket`` value. + init(generated: Components.Schemas.Bucket) { + let formatter = ISO8601DateFormatter() + self.init( + id: generated.id, + name: generated.name, + owner: "", + isPublic: generated._public, + createdAt: generated.created_at.flatMap { formatter.date(from: $0) } ?? Date(), + updatedAt: generated.updated_at.flatMap { formatter.date(from: $0) } ?? Date(), + allowedMimeTypes: generated.allowed_mime_types, + fileSizeLimit: generated.file_size_limit.map { Int64($0) } + ) + } + + /// Creates a ``Bucket`` from a generated ``Components/Schemas/GetBucketResponseContent`` value. + init(generated: Components.Schemas.GetBucketResponseContent) { + let formatter = ISO8601DateFormatter() + self.init( + id: generated.id, + name: generated.name, + owner: "", + isPublic: generated._public, + createdAt: generated.created_at.flatMap { formatter.date(from: $0) } ?? Date(), + updatedAt: generated.updated_at.flatMap { formatter.date(from: $0) } ?? Date(), + allowedMimeTypes: generated.allowed_mime_types, + fileSizeLimit: generated.file_size_limit.map { Int64($0) } + ) + } +} diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index 43aac45c0..3a0832bf6 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -1,5 +1,7 @@ import Foundation import Helpers +import OpenAPIRuntime +import OpenAPIURLSession #if canImport(FoundationNetworking) import FoundationNetworking @@ -138,6 +140,7 @@ public final class StorageClient: Sendable { public let configuration: StorageClientConfiguration package let http: _HTTPClient + let generatedClient: Client private let usesTokenProvider: Bool let downloadDelegate: DownloadSessionDelegate @@ -239,6 +242,9 @@ public final class StorageClient: Sendable { tokenProvider: tokenProvider ) + generatedClient = try! Client( + serverURL: resolvedURL, transport: URLSessionTransport(configuration: .init(session: configuration.session))) + let downloadDelegate = DownloadSessionDelegate() self.downloadDelegate = downloadDelegate @@ -263,6 +269,83 @@ public final class StorageClient: Sendable { ) } + package init( + url: URL, + configuration: StorageClientConfiguration, + transport: any ClientTransport + ) { + var configuration = configuration + + let clientInfoHeader = "X-Client-Info" + let clientInfoHeaders = configuration.headers.keys.filter { + $0.caseInsensitiveCompare(clientInfoHeader) == .orderedSame + } + + if let firstClientInfoHeader = clientInfoHeaders.first { + let clientInfo = configuration.headers[firstClientInfoHeader] + for duplicateHeader in clientInfoHeaders.dropFirst() { + configuration.headers.removeValue(forKey: duplicateHeader) + } + + if firstClientInfoHeader != clientInfoHeader { + configuration.headers.removeValue(forKey: firstClientInfoHeader) + configuration.headers[clientInfoHeader] = clientInfo + } + } else { + configuration.headers["X-Client-Info"] = "storage-swift/\(version)" + } + + var resolvedURL = url + + if configuration.useNewHostname == true { + guard + var components = URLComponents(url: url, resolvingAgainstBaseURL: false), + let host = components.host + else { + fatalError("Client initialized with invalid URL: \(url)") + } + + let regex = try! NSRegularExpression(pattern: "supabase.(co|in|red)$") + let isSupabaseHost = + regex.firstMatch( + in: host, + range: NSRange(location: 0, length: host.utf16.count) + ) != nil + + if isSupabaseHost, !host.contains("storage.supabase.") { + components.host = host.replacingOccurrences(of: "supabase.", with: "storage.supabase.") + } + + resolvedURL = components.url! + } + + self.url = resolvedURL + self.configuration = configuration + usesTokenProvider = false + + http = _HTTPClient( + host: resolvedURL, + session: configuration.session, + tokenProvider: nil + ) + + generatedClient = try! Client(serverURL: resolvedURL, transport: transport) + + let downloadDelegate = DownloadSessionDelegate() + self.downloadDelegate = downloadDelegate + + #if canImport(Darwin) + let downloadSessionConfig: URLSessionConfiguration = .default + #else + let downloadSessionConfig: URLSessionConfiguration = .default + #endif + self.downloadSession = URLSession( + configuration: downloadSessionConfig, + delegate: downloadDelegate, + delegateQueue: nil + ) + } + func mergedHeaders(_ headers: [String: String]? = nil) -> [String: String] { var merged = configuration.headers @@ -432,7 +515,25 @@ public final class StorageClient: Sendable { /// } /// ``` public func listBuckets() async throws -> [Bucket] { - try await fetchDecoded(.get, "bucket") + let output = try await generatedClient.ListBuckets() + switch output { + case .ok(let response): + let content = try response.body.json + return content.items.map(Bucket.init(generated:)) + case .badRequest(let response): + let error = try response.body.json + throw StorageError( + message: error.message ?? error.error ?? "Bad request", + errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, + statusCode: 400 + ) + case .undocumented(let statusCode, _): + throw StorageError( + message: "Unexpected status \(statusCode)", + errorCode: .unknown, + statusCode: statusCode + ) + } } /// Retrieves the details of a single Storage bucket. @@ -448,7 +549,25 @@ public final class StorageClient: Sendable { /// print("Bucket is \(bucket.isPublic ? "public" : "private")") /// ``` public func getBucket(_ id: String) async throws -> Bucket { - try await fetchDecoded(.get, "bucket/\(id)") + let output = try await generatedClient.GetBucket(path: .init(id: id)) + switch output { + case .ok(let response): + let content = try response.body.json + return Bucket(generated: content) + case .badRequest(let response): + let error = try response.body.json + throw StorageError( + message: error.message ?? error.error ?? "Bad request", + errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, + statusCode: 400 + ) + case .undocumented(let statusCode, _): + throw StorageError( + message: "Unexpected status \(statusCode)", + errorCode: .unknown, + statusCode: statusCode + ) + } } struct BucketParameters: Encodable { @@ -493,21 +612,28 @@ public final class StorageClient: Sendable { public func createBucket(_ id: String, options: BucketOptions = .init()) async throws { - try await fetchData( - .post, - "bucket", - body: .data( - encoder.encode( - BucketParameters( - id: id, - name: id, - isPublic: options.isPublic, - fileSizeLimit: options.fileSizeLimit?.bytes, - allowedMimeTypes: options.allowedMimeTypes - ) - ) - ) + let body = Components.Schemas.CreateBucketRequestContent( + id: id, + name: id, + _public: options.isPublic, + file_size_limit: options.fileSizeLimit.map { Double($0.bytes) }, + allowed_mime_types: options.allowedMimeTypes ) + let output = try await generatedClient.CreateBucket(body: .json(body)) + switch output { + case .ok: + return + case .badRequest(let response): + let error = try response.body.json + throw StorageError( + message: error.message ?? error.error ?? "Bad request", + errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, + statusCode: 400 + ) + case .undocumented(let statusCode, _): + throw StorageError( + message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + } } /// Updates the configuration of an existing Storage bucket. @@ -524,21 +650,26 @@ public final class StorageClient: Sendable { /// try await storage.updateBucket("avatars", options: BucketOptions(isPublic: true)) /// ``` public func updateBucket(_ id: String, options: BucketOptions) async throws { - try await fetchData( - .put, - "bucket/\(id)", - body: .data( - encoder.encode( - BucketParameters( - id: id, - name: id, - isPublic: options.isPublic, - fileSizeLimit: options.fileSizeLimit?.bytes, - allowedMimeTypes: options.allowedMimeTypes - ) - ) - ) + let body = Components.Schemas.UpdateBucketRequestContent( + _public: options.isPublic, + file_size_limit: options.fileSizeLimit.map { Double($0.bytes) }, + allowed_mime_types: options.allowedMimeTypes ) + let output = try await generatedClient.UpdateBucket(path: .init(id: id), body: .json(body)) + switch output { + case .ok: + return + case .badRequest(let response): + let error = try response.body.json + throw StorageError( + message: error.message ?? error.error ?? "Bad request", + errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, + statusCode: 400 + ) + case .undocumented(let statusCode, _): + throw StorageError( + message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + } } /// Removes all objects inside a bucket without deleting the bucket itself. @@ -556,7 +687,21 @@ public final class StorageClient: Sendable { /// try await storage.deleteBucket("temp-uploads") /// ``` public func emptyBucket(_ id: String) async throws { - try await fetchData(.post, "bucket/\(id)/empty") + let output = try await generatedClient.EmptyBucket(path: .init(id: id)) + switch output { + case .ok: + return + case .badRequest(let response): + let error = try response.body.json + throw StorageError( + message: error.message ?? error.error ?? "Bad request", + errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, + statusCode: 400 + ) + case .undocumented(let statusCode, _): + throw StorageError( + message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + } } /// Deletes an existing Storage bucket. @@ -574,6 +719,20 @@ public final class StorageClient: Sendable { /// try await storage.deleteBucket("old-bucket") /// ``` public func deleteBucket(_ id: String) async throws { - try await fetchData(.delete, "bucket/\(id)") + let output = try await generatedClient.DeleteBucket(path: .init(id: id)) + switch output { + case .ok: + return + case .badRequest(let response): + let error = try response.body.json + throw StorageError( + message: error.message ?? error.error ?? "Bad request", + errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, + statusCode: 400 + ) + case .undocumented(let statusCode, _): + throw StorageError( + message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + } } } diff --git a/Tests/StorageTests/MockTransport.swift b/Tests/StorageTests/MockTransport.swift new file mode 100644 index 000000000..dac1be06f --- /dev/null +++ b/Tests/StorageTests/MockTransport.swift @@ -0,0 +1,26 @@ +// +// MockTransport.swift +// StorageTests +// +// Created by Guilherme Souza on 30/06/25. +// + +import Foundation +import HTTPTypes +@_spi(Generated) import OpenAPIRuntime + +struct MockTransport: ClientTransport, Sendable { + let responseData: Data + let statusCode: Int + + func send( + _ request: HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String + ) async throws -> (HTTPResponse, HTTPBody?) { + let response = HTTPResponse(status: .init(code: statusCode)) + let responseBody: HTTPBody? = responseData.isEmpty ? nil : HTTPBody(responseData) + return (response, responseBody) + } +} diff --git a/Tests/StorageTests/StorageClientGeneratedTests.swift b/Tests/StorageTests/StorageClientGeneratedTests.swift new file mode 100644 index 000000000..100ec6f6e --- /dev/null +++ b/Tests/StorageTests/StorageClientGeneratedTests.swift @@ -0,0 +1,53 @@ +// +// StorageClientGeneratedTests.swift +// StorageTests +// +// Created by Guilherme Souza on 30/06/25. +// + +import Foundation +import Testing + +@testable import Storage + +@Suite("StorageClient bucket operations via generated client") +struct StorageClientGeneratedTests { + @Test("listBuckets returns decoded buckets") + func listBuckets() async throws { + // Arrange: mock transport returning one bucket wrapped in {items:[...]} as the Smithy spec requires + let json = """ + {"items":[{"id":"avatars","name":"avatars","public":true}]} + """.data(using: .utf8)! + let transport = MockTransport(responseData: json, statusCode: 200) + let client = StorageClient( + url: URL(string: "https://x.supabase.co/storage/v1")!, + configuration: StorageClientConfiguration(headers: [:]), + transport: transport + ) + + // Act + let buckets = try await client.listBuckets() + + // Assert + #expect(buckets.count == 1) + #expect(buckets[0].id == "avatars") + #expect(buckets[0].isPublic == true) + } + + @Test("listBuckets throws StorageError on 400") + func listBucketsBadRequest() async throws { + let json = """ + {"message":"Permission denied","error":"Unauthorized","statusCode":"400"} + """.data(using: .utf8)! + let transport = MockTransport(responseData: json, statusCode: 400) + let client = StorageClient( + url: URL(string: "https://x.supabase.co/storage/v1")!, + configuration: StorageClientConfiguration(headers: [:]), + transport: transport + ) + + await #expect(throws: StorageError.self) { + try await client.listBuckets() + } + } +} From 3c1ba25270164bea464df7606ac5d45c153a86d0 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 08:28:59 -0300 Subject: [PATCH 11/32] fix(storage): address code review findings from task 5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove @_spi(Generated) from MockTransport — ClientTransport is public API - Extract normalizeClientInfoHeaders and resolveStorageURL static helpers to eliminate ~60 lines of duplication between the two package inits - Promote supabase host regex to a static let to avoid repeated compilation - Remove dead #if canImport(Darwin) block (both branches were identical) - Add ISO8601DateFormatter as nonisolated(unsafe) static let in BucketConversions - Add owner:"" comment explaining why the field is absent from generated schema - Add storageError(statusCode:body:) helper; update all .undocumented handlers to extract body detail for more informative error messages - Add Swift Testing tests for getBucket, createBucket, updateBucket, emptyBucket, and deleteBucket (happy path + error path each) --- Sources/Storage/BucketConversions.swift | 18 +- Sources/Storage/StorageClient.swift | 196 +++++++----------- Tests/StorageTests/MockTransport.swift | 2 +- .../StorageClientGeneratedTests.swift | 129 ++++++++++-- 4 files changed, 202 insertions(+), 143 deletions(-) diff --git a/Sources/Storage/BucketConversions.swift b/Sources/Storage/BucketConversions.swift index bbd005902..fa3cd89d1 100644 --- a/Sources/Storage/BucketConversions.swift +++ b/Sources/Storage/BucketConversions.swift @@ -8,16 +8,21 @@ import Foundation extension Bucket { + /// Shared formatter; ISO8601DateFormatter is expensive to instantiate per call. + /// Protected by the fact that `date(from:)` is documented as thread-safe on Apple platforms. + private nonisolated(unsafe) static let iso8601: ISO8601DateFormatter = ISO8601DateFormatter() + /// Creates a ``Bucket`` from a generated ``Components/Schemas/Bucket`` value. init(generated: Components.Schemas.Bucket) { - let formatter = ISO8601DateFormatter() self.init( id: generated.id, name: generated.name, + // The generated Bucket schema does not include an `owner` field; use "" as the + // zero-value sentinel so existing call-sites that ignore owner continue to work. owner: "", isPublic: generated._public, - createdAt: generated.created_at.flatMap { formatter.date(from: $0) } ?? Date(), - updatedAt: generated.updated_at.flatMap { formatter.date(from: $0) } ?? Date(), + createdAt: generated.created_at.flatMap { Bucket.iso8601.date(from: $0) } ?? Date(), + updatedAt: generated.updated_at.flatMap { Bucket.iso8601.date(from: $0) } ?? Date(), allowedMimeTypes: generated.allowed_mime_types, fileSizeLimit: generated.file_size_limit.map { Int64($0) } ) @@ -25,14 +30,15 @@ extension Bucket { /// Creates a ``Bucket`` from a generated ``Components/Schemas/GetBucketResponseContent`` value. init(generated: Components.Schemas.GetBucketResponseContent) { - let formatter = ISO8601DateFormatter() self.init( id: generated.id, name: generated.name, + // The generated GetBucketResponseContent schema does not include an `owner` field; + // use "" as the zero-value sentinel. owner: "", isPublic: generated._public, - createdAt: generated.created_at.flatMap { formatter.date(from: $0) } ?? Date(), - updatedAt: generated.updated_at.flatMap { formatter.date(from: $0) } ?? Date(), + createdAt: generated.created_at.flatMap { Bucket.iso8601.date(from: $0) } ?? Date(), + updatedAt: generated.updated_at.flatMap { Bucket.iso8601.date(from: $0) } ?? Date(), allowedMimeTypes: generated.allowed_mime_types, fileSizeLimit: generated.file_size_limit.map { Int64($0) } ) diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index 3a0832bf6..579724154 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -154,6 +154,55 @@ public final class StorageClient: Sendable { let decoder = JSONDecoder.supabase() + /// Pre-compiled regex used to detect Supabase hostnames for the new-hostname rewrite. + private static let supabaseHostRegex: NSRegularExpression = try! NSRegularExpression( + pattern: "supabase.(co|in|red)$") + + /// Normalises the `X-Client-Info` header in `headers`, deduplicating case-insensitive variants + /// and ensuring the canonical casing `"X-Client-Info"` is used. + private static func normalizeClientInfoHeaders(in headers: inout [String: String]) { + let clientInfoHeader = "X-Client-Info" + let existing = headers.keys.filter { + $0.caseInsensitiveCompare(clientInfoHeader) == .orderedSame + } + if let first = existing.first { + let value = headers[first] + for duplicate in existing.dropFirst() { + headers.removeValue(forKey: duplicate) + } + if first != clientInfoHeader { + headers.removeValue(forKey: first) + headers[clientInfoHeader] = value + } + } else { + headers[clientInfoHeader] = "storage-swift/\(version)" + } + } + + /// Rewrites a legacy Supabase hostname to the dedicated storage subdomain when + /// `configuration.useNewHostname` is `true`. + private static func resolveStorageURL( + url: URL, + configuration: StorageClientConfiguration + ) -> URL { + guard configuration.useNewHostname == true else { return url } + guard + var components = URLComponents(url: url, resolvingAgainstBaseURL: false), + let host = components.host + else { + fatalError("Client initialized with invalid URL: \(url)") + } + let isSupabaseHost = + supabaseHostRegex.firstMatch( + in: host, + range: NSRange(location: 0, length: host.utf16.count) + ) != nil + if isSupabaseHost, !host.contains("storage.supabase.") { + components.host = host.replacingOccurrences(of: "supabase.", with: "storage.supabase.") + } + return components.url! + } + /// Creates a `StorageClient` for standalone use (without a ``SupabaseClient``). /// /// Use this initialiser when you want to interact with Supabase Storage independently, without @@ -183,54 +232,11 @@ public final class StorageClient: Sendable { package init(url: URL, configuration: StorageClientConfiguration, tokenProvider: TokenProvider?) { var configuration = configuration - let clientInfoHeader = "X-Client-Info" - let clientInfoHeaders = configuration.headers.keys.filter { - $0.caseInsensitiveCompare(clientInfoHeader) == .orderedSame - } - - if let firstClientInfoHeader = clientInfoHeaders.first { - let clientInfo = configuration.headers[firstClientInfoHeader] - for duplicateHeader in clientInfoHeaders.dropFirst() { - configuration.headers.removeValue(forKey: duplicateHeader) - } - - if firstClientInfoHeader != clientInfoHeader { - configuration.headers.removeValue(forKey: firstClientInfoHeader) - configuration.headers[clientInfoHeader] = clientInfo - } - } else { - configuration.headers["X-Client-Info"] = "storage-swift/\(version)" - } - - var resolvedURL = url + StorageClient.normalizeClientInfoHeaders(in: &configuration.headers) // if legacy uri is used, replace with new storage host (disables request buffering to allow > 50GB uploads) // "project-ref.supabase.co" becomes "project-ref.storage.supabase.co" - if configuration.useNewHostname == true { - guard - var components = URLComponents(url: url, resolvingAgainstBaseURL: false), - let host = components.host - else { - fatalError("Client initialized with invalid URL: \(url)") - } - - let regex = try! NSRegularExpression(pattern: "supabase.(co|in|red)$") - - let isSupabaseHost = - regex.firstMatch( - in: host, - range: NSRange(location: 0, length: host.utf16.count) - ) != nil - - if isSupabaseHost, !host.contains("storage.supabase.") { - components.host = host.replacingOccurrences( - of: "supabase.", - with: "storage.supabase." - ) - } - - resolvedURL = components.url! - } + let resolvedURL = StorageClient.resolveStorageURL(url: url, configuration: configuration) self.url = resolvedURL self.configuration = configuration @@ -276,48 +282,8 @@ public final class StorageClient: Sendable { ) { var configuration = configuration - let clientInfoHeader = "X-Client-Info" - let clientInfoHeaders = configuration.headers.keys.filter { - $0.caseInsensitiveCompare(clientInfoHeader) == .orderedSame - } - - if let firstClientInfoHeader = clientInfoHeaders.first { - let clientInfo = configuration.headers[firstClientInfoHeader] - for duplicateHeader in clientInfoHeaders.dropFirst() { - configuration.headers.removeValue(forKey: duplicateHeader) - } - - if firstClientInfoHeader != clientInfoHeader { - configuration.headers.removeValue(forKey: firstClientInfoHeader) - configuration.headers[clientInfoHeader] = clientInfo - } - } else { - configuration.headers["X-Client-Info"] = "storage-swift/\(version)" - } - - var resolvedURL = url - - if configuration.useNewHostname == true { - guard - var components = URLComponents(url: url, resolvingAgainstBaseURL: false), - let host = components.host - else { - fatalError("Client initialized with invalid URL: \(url)") - } - - let regex = try! NSRegularExpression(pattern: "supabase.(co|in|red)$") - let isSupabaseHost = - regex.firstMatch( - in: host, - range: NSRange(location: 0, length: host.utf16.count) - ) != nil - - if isSupabaseHost, !host.contains("storage.supabase.") { - components.host = host.replacingOccurrences(of: "supabase.", with: "storage.supabase.") - } - - resolvedURL = components.url! - } + StorageClient.normalizeClientInfoHeaders(in: &configuration.headers) + let resolvedURL = StorageClient.resolveStorageURL(url: url, configuration: configuration) self.url = resolvedURL self.configuration = configuration @@ -334,11 +300,7 @@ public final class StorageClient: Sendable { let downloadDelegate = DownloadSessionDelegate() self.downloadDelegate = downloadDelegate - #if canImport(Darwin) - let downloadSessionConfig: URLSessionConfiguration = .default - #else - let downloadSessionConfig: URLSessionConfiguration = .default - #endif + let downloadSessionConfig: URLSessionConfiguration = .default self.downloadSession = URLSession( configuration: downloadSessionConfig, delegate: downloadDelegate, @@ -346,6 +308,20 @@ public final class StorageClient: Sendable { ) } + /// Builds a ``StorageError`` from an undocumented HTTP response, extracting body detail when + /// available. + private func storageError( + statusCode: Int, + body: OpenAPIRuntime.UndocumentedPayload? + ) async -> StorageError { + var detail: String? = nil + if let httpBody = body?.body { + detail = try? await String(collecting: httpBody, upTo: 4096) + } + let message = detail.flatMap { $0.isEmpty ? nil : $0 } ?? "Unexpected status \(statusCode)" + return StorageError(message: message, errorCode: .unknown, statusCode: statusCode) + } + func mergedHeaders(_ headers: [String: String]? = nil) -> [String: String] { var merged = configuration.headers @@ -527,12 +503,8 @@ public final class StorageClient: Sendable { errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, statusCode: 400 ) - case .undocumented(let statusCode, _): - throw StorageError( - message: "Unexpected status \(statusCode)", - errorCode: .unknown, - statusCode: statusCode - ) + case .undocumented(let statusCode, let payload): + throw await storageError(statusCode: statusCode, body: payload) } } @@ -561,12 +533,8 @@ public final class StorageClient: Sendable { errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, statusCode: 400 ) - case .undocumented(let statusCode, _): - throw StorageError( - message: "Unexpected status \(statusCode)", - errorCode: .unknown, - statusCode: statusCode - ) + case .undocumented(let statusCode, let payload): + throw await storageError(statusCode: statusCode, body: payload) } } @@ -630,9 +598,8 @@ public final class StorageClient: Sendable { errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, statusCode: 400 ) - case .undocumented(let statusCode, _): - throw StorageError( - message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + case .undocumented(let statusCode, let payload): + throw await storageError(statusCode: statusCode, body: payload) } } @@ -666,9 +633,8 @@ public final class StorageClient: Sendable { errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, statusCode: 400 ) - case .undocumented(let statusCode, _): - throw StorageError( - message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + case .undocumented(let statusCode, let payload): + throw await storageError(statusCode: statusCode, body: payload) } } @@ -698,9 +664,8 @@ public final class StorageClient: Sendable { errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, statusCode: 400 ) - case .undocumented(let statusCode, _): - throw StorageError( - message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + case .undocumented(let statusCode, let payload): + throw await storageError(statusCode: statusCode, body: payload) } } @@ -730,9 +695,8 @@ public final class StorageClient: Sendable { errorCode: error.error.map(StorageErrorCode.init(_:)) ?? .unknown, statusCode: 400 ) - case .undocumented(let statusCode, _): - throw StorageError( - message: "Unexpected status \(statusCode)", errorCode: .unknown, statusCode: statusCode) + case .undocumented(let statusCode, let payload): + throw await storageError(statusCode: statusCode, body: payload) } } } diff --git a/Tests/StorageTests/MockTransport.swift b/Tests/StorageTests/MockTransport.swift index dac1be06f..0188dfcf0 100644 --- a/Tests/StorageTests/MockTransport.swift +++ b/Tests/StorageTests/MockTransport.swift @@ -7,7 +7,7 @@ import Foundation import HTTPTypes -@_spi(Generated) import OpenAPIRuntime +import OpenAPIRuntime struct MockTransport: ClientTransport, Sendable { let responseData: Data diff --git a/Tests/StorageTests/StorageClientGeneratedTests.swift b/Tests/StorageTests/StorageClientGeneratedTests.swift index 100ec6f6e..d4783072c 100644 --- a/Tests/StorageTests/StorageClientGeneratedTests.swift +++ b/Tests/StorageTests/StorageClientGeneratedTests.swift @@ -12,23 +12,32 @@ import Testing @Suite("StorageClient bucket operations via generated client") struct StorageClientGeneratedTests { - @Test("listBuckets returns decoded buckets") - func listBuckets() async throws { - // Arrange: mock transport returning one bucket wrapped in {items:[...]} as the Smithy spec requires - let json = """ - {"items":[{"id":"avatars","name":"avatars","public":true}]} - """.data(using: .utf8)! - let transport = MockTransport(responseData: json, statusCode: 200) - let client = StorageClient( + + // MARK: - Helpers + + private func makeClient(json: String, statusCode: Int) -> StorageClient { + let data = json.data(using: .utf8)! + let transport = MockTransport(responseData: data, statusCode: statusCode) + return StorageClient( url: URL(string: "https://x.supabase.co/storage/v1")!, configuration: StorageClientConfiguration(headers: [:]), transport: transport ) + } - // Act - let buckets = try await client.listBuckets() + private static let badRequestJSON = """ + {"message":"Permission denied","error":"Unauthorized","statusCode":"400"} + """ + + // MARK: - listBuckets - // Assert + @Test("listBuckets returns decoded buckets") + func listBuckets() async throws { + let client = makeClient( + json: #"{"items":[{"id":"avatars","name":"avatars","public":true}]}"#, + statusCode: 200 + ) + let buckets = try await client.listBuckets() #expect(buckets.count == 1) #expect(buckets[0].id == "avatars") #expect(buckets[0].isPublic == true) @@ -36,18 +45,98 @@ struct StorageClientGeneratedTests { @Test("listBuckets throws StorageError on 400") func listBucketsBadRequest() async throws { - let json = """ - {"message":"Permission denied","error":"Unauthorized","statusCode":"400"} - """.data(using: .utf8)! - let transport = MockTransport(responseData: json, statusCode: 400) - let client = StorageClient( - url: URL(string: "https://x.supabase.co/storage/v1")!, - configuration: StorageClientConfiguration(headers: [:]), - transport: transport + let client = makeClient(json: Self.badRequestJSON, statusCode: 400) + await #expect(throws: StorageError.self) { + try await client.listBuckets() + } + } + + // MARK: - getBucket + + @Test("getBucket returns decoded bucket") + func getBucket() async throws { + let client = makeClient( + json: #"{"id":"avatars","name":"avatars","public":false}"#, + statusCode: 200 ) + let bucket = try await client.getBucket("avatars") + #expect(bucket.id == "avatars") + #expect(bucket.isPublic == false) + } + @Test("getBucket throws StorageError on 400") + func getBucketBadRequest() async throws { + let client = makeClient(json: Self.badRequestJSON, statusCode: 400) await #expect(throws: StorageError.self) { - try await client.listBuckets() + try await client.getBucket("avatars") + } + } + + // MARK: - createBucket + + @Test("createBucket succeeds on 200") + func createBucket() async throws { + let client = makeClient(json: #"{"name":"avatars"}"#, statusCode: 200) + // Should not throw. + try await client.createBucket("avatars") + } + + @Test("createBucket throws StorageError on 400") + func createBucketBadRequest() async throws { + let client = makeClient(json: Self.badRequestJSON, statusCode: 400) + await #expect(throws: StorageError.self) { + try await client.createBucket("avatars") + } + } + + // MARK: - updateBucket + + @Test("updateBucket succeeds on 200") + func updateBucket() async throws { + let client = makeClient(json: #"{"message":"Successfully updated"}"#, statusCode: 200) + // Should not throw. + try await client.updateBucket("avatars", options: BucketOptions(isPublic: true)) + } + + @Test("updateBucket throws StorageError on 400") + func updateBucketBadRequest() async throws { + let client = makeClient(json: Self.badRequestJSON, statusCode: 400) + await #expect(throws: StorageError.self) { + try await client.updateBucket("avatars", options: BucketOptions(isPublic: true)) + } + } + + // MARK: - emptyBucket + + @Test("emptyBucket succeeds on 200") + func emptyBucket() async throws { + let client = makeClient(json: #"{"message":"Successfully emptied"}"#, statusCode: 200) + // Should not throw. + try await client.emptyBucket("avatars") + } + + @Test("emptyBucket throws StorageError on 400") + func emptyBucketBadRequest() async throws { + let client = makeClient(json: Self.badRequestJSON, statusCode: 400) + await #expect(throws: StorageError.self) { + try await client.emptyBucket("avatars") + } + } + + // MARK: - deleteBucket + + @Test("deleteBucket succeeds on 200") + func deleteBucket() async throws { + let client = makeClient(json: #"{"message":"Successfully deleted"}"#, statusCode: 200) + // Should not throw. + try await client.deleteBucket("avatars") + } + + @Test("deleteBucket throws StorageError on 400") + func deleteBucketBadRequest() async throws { + let client = makeClient(json: Self.badRequestJSON, statusCode: 400) + await #expect(throws: StorageError.self) { + try await client.deleteBucket("avatars") } } } From 9cd501ff80b59928f16bb9a4b4a27a173c58095b Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 08:30:47 -0300 Subject: [PATCH 12/32] fix(storage): make generatedClient private --- Sources/Storage/StorageClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index 579724154..379e50678 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -140,7 +140,7 @@ public final class StorageClient: Sendable { public let configuration: StorageClientConfiguration package let http: _HTTPClient - let generatedClient: Client + private let generatedClient: Client private let usesTokenProvider: Bool let downloadDelegate: DownloadSessionDelegate From bb6d97b3a2bc07db2c2600ed8a4cf817abeb066a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 08:34:53 -0300 Subject: [PATCH 13/32] feat(functions): delegate invoke to generated Smithy client --- Package.swift | 1 + Sources/Functions/FunctionsClient.swift | 89 +++++++++++++++++++ .../FunctionsTests/FunctionsClientTests.swift | 50 +++++++++++ Tests/FunctionsTests/MockTransport.swift | 30 +++++++ 4 files changed, 170 insertions(+) create mode 100644 Tests/FunctionsTests/MockTransport.swift diff --git a/Package.swift b/Package.swift index cd884681f..01b60ef21 100644 --- a/Package.swift +++ b/Package.swift @@ -95,6 +95,7 @@ let package = Package( .product(name: "InlineSnapshotTesting", package: "swift-snapshot-testing"), .product(name: "Replay", package: "Replay"), .product(name: "SnapshotTesting", package: "swift-snapshot-testing"), + .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), "Functions", "Mocker", diff --git a/Sources/Functions/FunctionsClient.swift b/Sources/Functions/FunctionsClient.swift index b924e959c..304307847 100644 --- a/Sources/Functions/FunctionsClient.swift +++ b/Sources/Functions/FunctionsClient.swift @@ -1,6 +1,7 @@ import ConcurrencyExtras import Foundation import Helpers +import OpenAPIRuntime #if canImport(FoundationNetworking) import FoundationNetworking @@ -70,6 +71,7 @@ public actor FunctionsClient { public private(set) var headers: [String: String] = [:] private let http: _HTTPClient + private let generatedClient: Client? /// Creates a `FunctionsClient` for standalone use (without a ``SupabaseClient``). /// @@ -130,6 +132,33 @@ public actor FunctionsClient { session: session, tokenProvider: tokenProvider ) + self.generatedClient = nil + self.headers = headers + if self.headers["X-Client-Info"] == nil { + self.headers["X-Client-Info"] = "functions-swift/\(version)" + } + } + + /// Creates a `FunctionsClient` backed by the generated OpenAPI client for testing. + /// + /// - Parameters: + /// - url: The base URL for the functions endpoint. + /// - headers: Additional headers included in every request. + /// - region: The default region to invoke functions in. + /// - transport: A `ClientTransport` used by the generated client (e.g. `MockTransport` in tests). + /// - decoder: The `JSONDecoder` used by `invokeDecodable`. + package init( + url: URL, + headers: [String: String] = [:], + region: FunctionRegion? = nil, + transport: any ClientTransport, + decoder: JSONDecoder = JSONDecoder() + ) { + self.url = url + self.region = region + self.decoder = decoder + self.http = _HTTPClient(host: url) + self.generatedClient = Client(serverURL: url, transport: transport) self.headers = headers if self.headers["X-Client-Info"] == nil { self.headers["X-Client-Info"] = "functions-swift/\(version)" @@ -239,6 +268,15 @@ public actor FunctionsClient { ) async throws -> (Data, HTTPURLResponse) { var options = FunctionInvokeOptions() applyOptions(&options) + + if let generatedClient { + return try await invokeViaGeneratedClient( + functionName: functionName, + options: options, + generatedClient: generatedClient + ) + } + let (functionURL, method, query, allHeaders, body) = requestComponents( functionName: functionName, options: options @@ -266,6 +304,57 @@ public actor FunctionsClient { } } + private func invokeViaGeneratedClient( + functionName: String, + options: FunctionInvokeOptions, + generatedClient: Client + ) async throws -> (Data, HTTPURLResponse) { + let input = Operations.InvokeFunction.Input( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: (options.region ?? region)?.rawValue), + body: options.body.map { .binary(HTTPBody($0)) } + ) + + let output = try await generatedClient.InvokeFunction(input) + + switch output { + case .ok(let response): + let data = try await Data(collecting: response.body.binary, upTo: .max) + let httpResponse = HTTPURLResponse( + url: url.appendingPathComponent(functionName), + statusCode: 200, + httpVersion: nil, + headerFields: nil + )! + return (data, httpResponse) + case .badRequest(let response): + let body = try response.body.json + let data = (body.message ?? "").data(using: .utf8) ?? Data() + throw FunctionsError.httpError(code: 400, data: data) + case .undocumented(let statusCode, let payload): + // Check for relay error header in undocumented responses. + if payload.headerFields[.init("x-relay-error")!] == "true" { + throw FunctionsError.relayError + } + let data: Data + if let body = payload.body { + data = try await Data(collecting: body, upTo: .max) + } else { + data = Data() + } + if statusCode >= 200 && statusCode < 300 { + let httpResponse = HTTPURLResponse( + url: url.appendingPathComponent(functionName), + statusCode: statusCode, + httpVersion: nil, + headerFields: nil + )! + return (data, httpResponse) + } + throw FunctionsError.httpError(code: statusCode, data: data) + } + } + #if canImport(Darwin) /// Invokes a function and returns an async byte stream for the response body. /// diff --git a/Tests/FunctionsTests/FunctionsClientTests.swift b/Tests/FunctionsTests/FunctionsClientTests.swift index fcd220ffe..9734aef50 100644 --- a/Tests/FunctionsTests/FunctionsClientTests.swift +++ b/Tests/FunctionsTests/FunctionsClientTests.swift @@ -2,6 +2,7 @@ import ConcurrencyExtras import InlineSnapshotTesting import Mocker import TestHelpers +import Testing import XCTest @testable import Functions @@ -420,3 +421,52 @@ final class FunctionsClientTests: XCTestCase { } #endif } + +// MARK: - Generated client tests (Swift Testing) + +@Suite("FunctionsClient via generated client") +struct FunctionsClientGeneratedTests { + @Test("invoke returns response data") + func invokesFunction() async throws { + let responseData = Data("{\"result\":\"ok\"}".utf8) + let transport = MockTransport(responseData: responseData, statusCode: 200) + let client = FunctionsClient( + url: URL(string: "https://x.supabase.co/functions/v1")!, + transport: transport + ) + + let (data, _) = try await client.invoke("hello") + #expect(data == responseData) + } + + @Test("invoke throws httpError on non-2xx response") + func throwsOnError() async throws { + let errorData = Data("{\"error\":\"not found\"}".utf8) + let transport = MockTransport(responseData: errorData, statusCode: 404) + let client = FunctionsClient( + url: URL(string: "https://x.supabase.co/functions/v1")!, + transport: transport + ) + + await #expect(throws: FunctionsError.self) { + _ = try await client.invoke("missing") + } + } + + @Test("invoke throws relayError when x-relay-error header is present") + func throwsRelayError() async throws { + var transport = MockTransport(responseData: Data(), statusCode: 299) + transport.responseHeaders = [.init("x-relay-error")!: "true"] + let client = FunctionsClient( + url: URL(string: "https://x.supabase.co/functions/v1")!, + transport: transport + ) + + await #expect { + _ = try await client.invoke("relay-fn") + } throws: { error in + guard case FunctionsError.relayError = error else { return false } + return true + } + } +} diff --git a/Tests/FunctionsTests/MockTransport.swift b/Tests/FunctionsTests/MockTransport.swift new file mode 100644 index 000000000..42215725c --- /dev/null +++ b/Tests/FunctionsTests/MockTransport.swift @@ -0,0 +1,30 @@ +// +// MockTransport.swift +// FunctionsTests +// +// Created by Guilherme Souza on 30/06/25. +// + +import Foundation +import HTTPTypes +import OpenAPIRuntime + +struct MockTransport: ClientTransport, Sendable { + let responseData: Data + let statusCode: Int + var responseHeaders: HTTPFields = [:] + + func send( + _ request: HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String + ) async throws -> (HTTPResponse, HTTPBody?) { + var response = HTTPResponse(status: .init(code: statusCode)) + for field in responseHeaders { + response.headerFields.append(field) + } + let responseBody: HTTPBody? = responseData.isEmpty ? nil : HTTPBody(responseData) + return (response, responseBody) + } +} From 9ce8648a1ba91c88acfc238cf3116aa64965011a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 08:37:09 -0300 Subject: [PATCH 14/32] fix(functions): preserve raw error bytes on 400 badRequest response --- Sources/Functions/FunctionsClient.swift | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Sources/Functions/FunctionsClient.swift b/Sources/Functions/FunctionsClient.swift index 304307847..86b671b6e 100644 --- a/Sources/Functions/FunctionsClient.swift +++ b/Sources/Functions/FunctionsClient.swift @@ -328,8 +328,14 @@ public actor FunctionsClient { )! return (data, httpResponse) case .badRequest(let response): - let body = try response.body.json - let data = (body.message ?? "").data(using: .utf8) ?? Data() + let rawBody = response.body + let data: Data + switch rawBody { + case .json(let body): + // Collect raw bytes so callers can inspect the full error payload. + let encoded = try JSONEncoder().encode(body) + data = encoded + } throw FunctionsError.httpError(code: 400, data: data) case .undocumented(let statusCode, let payload): // Check for relay error header in undocumented responses. From 71f393cc68b79b5a8d4695b45dca59f2c6d3b4f1 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 08:42:16 -0300 Subject: [PATCH 15/32] fix(codegen): wire SupabaseClientTransport in production init; exclude config YAMLs Replace bare URLSessionTransport with SupabaseClientTransport in the production StorageClient init so that Authorization headers are injected from the token provider. Also exclude openapi-generator-config.yaml from the Storage and Functions SPM targets to eliminate unhandled-file warnings. --- Package.swift | 6 ++++-- Sources/Storage/StorageClient.swift | 7 +++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index 01b60ef21..633efbba2 100644 --- a/Package.swift +++ b/Package.swift @@ -86,7 +86,8 @@ let package = Package( dependencies: [ "Helpers", .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), - ] + ], + exclude: ["openapi-generator-config.yaml"] ), .testTarget( name: "FunctionsTests", @@ -170,7 +171,8 @@ let package = Package( "Helpers", .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), .product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession"), - ] + ], + exclude: ["openapi-generator-config.yaml"] ), .testTarget( name: "StorageTests", diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index 379e50678..a4dc49a23 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -248,8 +248,11 @@ public final class StorageClient: Sendable { tokenProvider: tokenProvider ) - generatedClient = try! Client( - serverURL: resolvedURL, transport: URLSessionTransport(configuration: .init(session: configuration.session))) + let transport = SupabaseClientTransport( + session: configuration.session, + tokenProvider: tokenProvider + ) + generatedClient = try! Client(serverURL: resolvedURL, transport: transport) let downloadDelegate = DownloadSessionDelegate() self.downloadDelegate = downloadDelegate From 8b29046728bbe920f9d3ded159a15b095d11b318 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 09:53:06 -0300 Subject: [PATCH 16/32] feat(helpers): add SupabaseMiddleware; simplify SupabaseClientTransport --- Sources/Helpers/SupabaseClientTransport.swift | 20 +-- Sources/Helpers/SupabaseMiddleware.swift | 50 +++++++ Sources/Storage/StorageClient.swift | 12 +- .../SupabaseClientTransportTests.swift | 128 +----------------- .../SupabaseMiddlewareTests.swift | 109 +++++++++++++++ 5 files changed, 177 insertions(+), 142 deletions(-) create mode 100644 Sources/Helpers/SupabaseMiddleware.swift create mode 100644 Tests/HelpersTests/SupabaseMiddlewareTests.swift diff --git a/Sources/Helpers/SupabaseClientTransport.swift b/Sources/Helpers/SupabaseClientTransport.swift index 6983ff304..5248a0820 100644 --- a/Sources/Helpers/SupabaseClientTransport.swift +++ b/Sources/Helpers/SupabaseClientTransport.swift @@ -14,19 +14,13 @@ import OpenAPIURLSession /// `ClientTransport` for generated Supabase API clients. /// -/// Wraps `URLSessionTransport` from `swift-openapi-urlsession` for correct streaming, -/// and injects a Bearer token when no `Authorization` header is already present. -/// Does not depend on `_HTTPClient`. +/// Pure delegation to `URLSessionTransport` for correct streaming behaviour. +/// Header injection (auth, apikey, X-Client-Info) is handled by `SupabaseMiddleware`. package struct SupabaseClientTransport: ClientTransport, Sendable { private let inner: URLSessionTransport - package let tokenProvider: (@Sendable () async throws -> String?)? - package init( - session: URLSession = URLSession(configuration: .default), - tokenProvider: (@Sendable () async throws -> String?)? = nil - ) { + package init(session: URLSession = URLSession(configuration: .default)) { self.inner = URLSessionTransport(configuration: .init(session: session)) - self.tokenProvider = tokenProvider } package func send( @@ -35,12 +29,6 @@ package struct SupabaseClientTransport: ClientTransport, Sendable { baseURL: URL, operationID: String ) async throws -> (HTTPTypes.HTTPResponse, HTTPBody?) { - var request = request - if request.headerFields[HTTPField.Name.authorization] == nil, - let token = try await tokenProvider?() - { - request.headerFields[HTTPField.Name.authorization] = "Bearer \(token)" - } - return try await inner.send(request, body: body, baseURL: baseURL, operationID: operationID) + try await inner.send(request, body: body, baseURL: baseURL, operationID: operationID) } } diff --git a/Sources/Helpers/SupabaseMiddleware.swift b/Sources/Helpers/SupabaseMiddleware.swift new file mode 100644 index 000000000..08483c481 --- /dev/null +++ b/Sources/Helpers/SupabaseMiddleware.swift @@ -0,0 +1,50 @@ +// +// SupabaseMiddleware.swift +// Helpers +// + +import Foundation +import HTTPTypes +import OpenAPIRuntime + +#if canImport(FoundationNetworking) + import FoundationNetworking +#endif + +/// `ClientMiddleware` that injects static headers and a dynamic Bearer token +/// into every outgoing request for generated Supabase API clients. +package struct SupabaseMiddleware: ClientMiddleware, Sendable { + private let headers: [String: String] + private let tokenProvider: (@Sendable () async throws -> String?)? + + package init( + headers: [String: String], + tokenProvider: (@Sendable () async throws -> String?)? = nil + ) { + self.headers = headers + self.tokenProvider = tokenProvider + } + + package func intercept( + _ request: HTTPTypes.HTTPRequest, + body: HTTPBody?, + baseURL: URL, + operationID: String, + next: @Sendable (HTTPTypes.HTTPRequest, HTTPBody?, URL) async throws -> ( + HTTPTypes.HTTPResponse, HTTPBody? + ) + ) async throws -> (HTTPTypes.HTTPResponse, HTTPBody?) { + var request = request + for (key, value) in headers { + if let name = HTTPField.Name(key), request.headerFields[name] == nil { + request.headerFields[name] = value + } + } + if request.headerFields[.authorization] == nil, + let token = try await tokenProvider?() + { + request.headerFields[.authorization] = "Bearer \(token)" + } + return try await next(request, body, baseURL) + } +} diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index a4dc49a23..09159111b 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -248,11 +248,13 @@ public final class StorageClient: Sendable { tokenProvider: tokenProvider ) - let transport = SupabaseClientTransport( - session: configuration.session, + let transport = SupabaseClientTransport(session: configuration.session) + let middleware = SupabaseMiddleware( + headers: configuration.headers, tokenProvider: tokenProvider ) - generatedClient = try! Client(serverURL: resolvedURL, transport: transport) + generatedClient = try! Client( + serverURL: resolvedURL, transport: transport, middlewares: [middleware]) let downloadDelegate = DownloadSessionDelegate() self.downloadDelegate = downloadDelegate @@ -298,7 +300,9 @@ public final class StorageClient: Sendable { tokenProvider: nil ) - generatedClient = try! Client(serverURL: resolvedURL, transport: transport) + let middleware = SupabaseMiddleware(headers: configuration.headers, tokenProvider: nil) + generatedClient = try! Client( + serverURL: resolvedURL, transport: transport, middlewares: [middleware]) let downloadDelegate = DownloadSessionDelegate() self.downloadDelegate = downloadDelegate diff --git a/Tests/HelpersTests/SupabaseClientTransportTests.swift b/Tests/HelpersTests/SupabaseClientTransportTests.swift index b2bb0f22f..fb207d693 100644 --- a/Tests/HelpersTests/SupabaseClientTransportTests.swift +++ b/Tests/HelpersTests/SupabaseClientTransportTests.swift @@ -1,133 +1,17 @@ // // SupabaseClientTransportTests.swift -// Helpers -// -// Created by Guilherme Souza on 30/06/26. +// HelpersTests // -import ConcurrencyExtras import Foundation -import HTTPTypes -import OpenAPIRuntime import Testing - @testable import Helpers -@Suite("SupabaseClientTransport", .serialized) +@Suite("SupabaseClientTransport") struct SupabaseClientTransportTests { - @Test("sends request to correct URL") - func sendsToCorrectURL() async throws { - let box = RequestBox() - let session = URLSession.mockSession { request in - box.value = request - return ( - Data("{}".utf8), - HTTPURLResponse( - url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)! - ) - } - - let transport = SupabaseClientTransport(session: session, tokenProvider: nil) - let baseURL = URL(string: "https://example.supabase.co/storage/v1")! - let httpRequest = HTTPTypes.HTTPRequest( - method: .get, scheme: nil, authority: nil, path: "/bucket") - - _ = try await transport.send( - httpRequest, body: nil, baseURL: baseURL, operationID: "listBuckets") - - #expect(box.value?.url?.absoluteString == "https://example.supabase.co/storage/v1/bucket") - #expect(box.value?.httpMethod == "GET") - } - - @Test("injects Bearer token when tokenProvider returns a token") - func injectsToken() async throws { - let box = RequestBox() - let session = URLSession.mockSession { request in - box.value = request - return ( - Data(), - HTTPURLResponse( - url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)! - ) - } - - let transport = SupabaseClientTransport(session: session, tokenProvider: { "test-token" }) - let baseURL = URL(string: "https://example.supabase.co/storage/v1")! - let httpRequest = HTTPTypes.HTTPRequest( - method: .get, scheme: nil, authority: nil, path: "/bucket") - - _ = try await transport.send( - httpRequest, body: nil, baseURL: baseURL, operationID: "listBuckets") - - #expect(box.value?.value(forHTTPHeaderField: "Authorization") == "Bearer test-token") - } - - @Test("does not overwrite existing Authorization header") - func doesNotOverwriteAuth() async throws { - let box = RequestBox() - let session = URLSession.mockSession { request in - box.value = request - return ( - Data(), - HTTPURLResponse( - url: request.url!, statusCode: 200, httpVersion: nil, headerFields: nil)! - ) - } - - let transport = SupabaseClientTransport(session: session, tokenProvider: { "injected-token" }) - let baseURL = URL(string: "https://example.supabase.co/storage/v1")! - var httpRequest = HTTPTypes.HTTPRequest( - method: .get, scheme: nil, authority: nil, path: "/bucket") - httpRequest.headerFields[.authorization] = "Bearer caller-token" - - _ = try await transport.send( - httpRequest, body: nil, baseURL: baseURL, operationID: "listBuckets") - - #expect(box.value?.value(forHTTPHeaderField: "Authorization") == "Bearer caller-token") + @Test("init does not crash") + func initSucceeds() { + let transport = SupabaseClientTransport() + _ = transport // Sendable — just verify it constructs } } - -// MARK: - Thread-safe capture box - -final class RequestBox: @unchecked Sendable { - private let _value = LockIsolated(nil) - var value: URLRequest? { - get { _value.value } - set { _value.withValue { $0 = newValue } } - } -} - -// MARK: - URLSession mock helper - -extension URLSession { - static func mockSession( - handler: @escaping @Sendable (URLRequest) throws -> (Data, HTTPURLResponse) - ) -> URLSession { - MockURLProtocol.handler = handler - let config = URLSessionConfiguration.ephemeral - config.protocolClasses = [MockURLProtocol.self] - return URLSession(configuration: config) - } -} - -final class MockURLProtocol: URLProtocol, @unchecked Sendable { - nonisolated(unsafe) static var handler: - (@Sendable (URLRequest) throws -> (Data, HTTPURLResponse))? - - override class func canInit(with request: URLRequest) -> Bool { true } - override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } - - override func startLoading() { - guard let handler = MockURLProtocol.handler else { return } - do { - let (data, response) = try handler(request) - client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: .notAllowed) - client?.urlProtocol(self, didLoad: data) - client?.urlProtocolDidFinishLoading(self) - } catch { - client?.urlProtocol(self, didFailWithError: error) - } - } - - override func stopLoading() {} -} diff --git a/Tests/HelpersTests/SupabaseMiddlewareTests.swift b/Tests/HelpersTests/SupabaseMiddlewareTests.swift new file mode 100644 index 000000000..ea2bbdb6f --- /dev/null +++ b/Tests/HelpersTests/SupabaseMiddlewareTests.swift @@ -0,0 +1,109 @@ +// +// SupabaseMiddlewareTests.swift +// HelpersTests +// + +import Foundation +import HTTPTypes +import OpenAPIRuntime +import Testing +@testable import Helpers + +@Suite("SupabaseMiddleware") +struct SupabaseMiddlewareTests { + // A simple next handler that echoes back a fixed response and captures the forwarded request. + actor RequestCapture { + var last: HTTPTypes.HTTPRequest? + func capture(_ request: HTTPTypes.HTTPRequest) { last = request } + } + + private func makeNext( + capture: RequestCapture? = nil, + status: Int = 200, + responseHeaders: [(String, String)] = [] + ) -> @Sendable (HTTPTypes.HTTPRequest, HTTPBody?, URL) async throws -> ( + HTTPTypes.HTTPResponse, HTTPBody? + ) { + return { request, _, _ in + await capture?.capture(request) + var fields = HTTPFields() + for (name, value) in responseHeaders { + fields[HTTPField.Name(name)!] = value + } + return (HTTPTypes.HTTPResponse(status: .init(code: status), headerFields: fields), nil) + } + } + + @Test("injects static headers into request") + func injectsStaticHeaders() async throws { + let middleware = SupabaseMiddleware(headers: ["apikey": "my-key", "X-Client-Info": "sdk/1"]) + let capture = RequestCapture() + let next = makeNext(capture: capture) + _ = try await middleware.intercept( + HTTPTypes.HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"), + body: nil, baseURL: URL(string: "https://example.com")!, + operationID: "op", next: next + ) + let forwarded = await capture.last + #expect(forwarded?.headerFields[HTTPField.Name("apikey")!] == "my-key") + #expect(forwarded?.headerFields[HTTPField.Name("X-Client-Info")!] == "sdk/1") + } + + @Test("does not overwrite existing header") + func doesNotOverwriteExistingHeader() async throws { + let middleware = SupabaseMiddleware(headers: ["apikey": "middleware-key"]) + let capture = RequestCapture() + let next = makeNext(capture: capture) + var request = HTTPTypes.HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/") + request.headerFields[HTTPField.Name("apikey")!] = "caller-key" + _ = try await middleware.intercept( + request, body: nil, baseURL: URL(string: "https://example.com")!, + operationID: "op", next: next + ) + let forwarded = await capture.last + #expect(forwarded?.headerFields[HTTPField.Name("apikey")!] == "caller-key") + } + + @Test("injects Bearer token from tokenProvider") + func injectsBearerToken() async throws { + let middleware = SupabaseMiddleware(headers: [:], tokenProvider: { "test-token" }) + let capture = RequestCapture() + let next = makeNext(capture: capture) + _ = try await middleware.intercept( + HTTPTypes.HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"), + body: nil, baseURL: URL(string: "https://example.com")!, + operationID: "op", next: next + ) + let forwarded = await capture.last + #expect(forwarded?.headerFields[.authorization] == "Bearer test-token") + } + + @Test("does not overwrite existing Authorization header") + func doesNotOverwriteExistingAuthorization() async throws { + let middleware = SupabaseMiddleware(headers: [:], tokenProvider: { "new-token" }) + let capture = RequestCapture() + let next = makeNext(capture: capture) + var request = HTTPTypes.HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/") + request.headerFields[.authorization] = "Bearer existing-token" + _ = try await middleware.intercept( + request, body: nil, baseURL: URL(string: "https://example.com")!, + operationID: "op", next: next + ) + let forwarded = await capture.last + #expect(forwarded?.headerFields[.authorization] == "Bearer existing-token") + } + + @Test("no Authorization injected when tokenProvider is nil") + func noAuthHeaderWhenNoProvider() async throws { + let middleware = SupabaseMiddleware(headers: [:], tokenProvider: nil) + let capture = RequestCapture() + let next = makeNext(capture: capture) + _ = try await middleware.intercept( + HTTPTypes.HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"), + body: nil, baseURL: URL(string: "https://example.com")!, + operationID: "op", next: next + ) + let forwarded = await capture.last + #expect(forwarded?.headerFields[.authorization] == nil) + } +} From a39829beb40d683e3683d467f33d861bccb5e9dd Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 10:22:44 -0300 Subject: [PATCH 17/32] refactor(helpers): delete SupabaseClientTransport; use URLSessionTransport directly --- Package.swift | 1 - Sources/Helpers/SupabaseClientTransport.swift | 34 ------------------- Sources/Storage/StorageClient.swift | 2 +- .../SupabaseClientTransportTests.swift | 17 ---------- 4 files changed, 1 insertion(+), 53 deletions(-) delete mode 100644 Sources/Helpers/SupabaseClientTransport.swift delete mode 100644 Tests/HelpersTests/SupabaseClientTransportTests.swift diff --git a/Package.swift b/Package.swift index 633efbba2..c44514d0c 100644 --- a/Package.swift +++ b/Package.swift @@ -44,7 +44,6 @@ let package = Package( .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), .product(name: "IssueReporting", package: "xctest-dynamic-overlay"), .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), - .product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession"), ] ), .testTarget( diff --git a/Sources/Helpers/SupabaseClientTransport.swift b/Sources/Helpers/SupabaseClientTransport.swift deleted file mode 100644 index 5248a0820..000000000 --- a/Sources/Helpers/SupabaseClientTransport.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// SupabaseClientTransport.swift -// Helpers -// - -import Foundation -import HTTPTypes -import OpenAPIRuntime -import OpenAPIURLSession - -#if canImport(FoundationNetworking) - import FoundationNetworking -#endif - -/// `ClientTransport` for generated Supabase API clients. -/// -/// Pure delegation to `URLSessionTransport` for correct streaming behaviour. -/// Header injection (auth, apikey, X-Client-Info) is handled by `SupabaseMiddleware`. -package struct SupabaseClientTransport: ClientTransport, Sendable { - private let inner: URLSessionTransport - - package init(session: URLSession = URLSession(configuration: .default)) { - self.inner = URLSessionTransport(configuration: .init(session: session)) - } - - package func send( - _ request: HTTPTypes.HTTPRequest, - body: HTTPBody?, - baseURL: URL, - operationID: String - ) async throws -> (HTTPTypes.HTTPResponse, HTTPBody?) { - try await inner.send(request, body: body, baseURL: baseURL, operationID: operationID) - } -} diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index 09159111b..54d6b4c1f 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -248,7 +248,7 @@ public final class StorageClient: Sendable { tokenProvider: tokenProvider ) - let transport = SupabaseClientTransport(session: configuration.session) + let transport = URLSessionTransport(configuration: .init(session: configuration.session)) let middleware = SupabaseMiddleware( headers: configuration.headers, tokenProvider: tokenProvider diff --git a/Tests/HelpersTests/SupabaseClientTransportTests.swift b/Tests/HelpersTests/SupabaseClientTransportTests.swift deleted file mode 100644 index fb207d693..000000000 --- a/Tests/HelpersTests/SupabaseClientTransportTests.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// SupabaseClientTransportTests.swift -// HelpersTests -// - -import Foundation -import Testing -@testable import Helpers - -@Suite("SupabaseClientTransport") -struct SupabaseClientTransportTests { - @Test("init does not crash") - func initSucceeds() { - let transport = SupabaseClientTransport() - _ = transport // Sendable — just verify it constructs - } -} From 895b91dccef93c246373351b506efc3e37821a64 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 10:28:04 -0300 Subject: [PATCH 18/32] feat(functions): add RelayErrorMiddleware; wire SupabaseMiddleware into production init --- Package.swift | 2 + Sources/Functions/FunctionsClient.swift | 13 ++-- Sources/Functions/RelayErrorMiddleware.swift | 31 ++++++++++ .../RelayErrorMiddlewareTests.swift | 60 +++++++++++++++++++ 4 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 Sources/Functions/RelayErrorMiddleware.swift create mode 100644 Tests/FunctionsTests/RelayErrorMiddlewareTests.swift diff --git a/Package.swift b/Package.swift index c44514d0c..b188830f5 100644 --- a/Package.swift +++ b/Package.swift @@ -85,6 +85,7 @@ let package = Package( dependencies: [ "Helpers", .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), + .product(name: "OpenAPIURLSession", package: "swift-openapi-urlsession"), ], exclude: ["openapi-generator-config.yaml"] ), @@ -96,6 +97,7 @@ let package = Package( .product(name: "Replay", package: "Replay"), .product(name: "SnapshotTesting", package: "swift-snapshot-testing"), .product(name: "OpenAPIRuntime", package: "swift-openapi-runtime"), + .product(name: "HTTPTypes", package: "swift-http-types"), .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"), "Functions", "Mocker", diff --git a/Sources/Functions/FunctionsClient.swift b/Sources/Functions/FunctionsClient.swift index 86b671b6e..931d60d62 100644 --- a/Sources/Functions/FunctionsClient.swift +++ b/Sources/Functions/FunctionsClient.swift @@ -2,6 +2,7 @@ import ConcurrencyExtras import Foundation import Helpers import OpenAPIRuntime +import OpenAPIURLSession #if canImport(FoundationNetworking) import FoundationNetworking @@ -132,7 +133,13 @@ public actor FunctionsClient { session: session, tokenProvider: tokenProvider ) - self.generatedClient = nil + let transport = URLSessionTransport(configuration: .init(session: session)) + let middleware = SupabaseMiddleware(headers: headers, tokenProvider: tokenProvider) + generatedClient = try? Client( + serverURL: url, + transport: transport, + middlewares: [middleware, RelayErrorMiddleware()] + ) self.headers = headers if self.headers["X-Client-Info"] == nil { self.headers["X-Client-Info"] = "functions-swift/\(version)" @@ -338,10 +345,6 @@ public actor FunctionsClient { } throw FunctionsError.httpError(code: 400, data: data) case .undocumented(let statusCode, let payload): - // Check for relay error header in undocumented responses. - if payload.headerFields[.init("x-relay-error")!] == "true" { - throw FunctionsError.relayError - } let data: Data if let body = payload.body { data = try await Data(collecting: body, upTo: .max) diff --git a/Sources/Functions/RelayErrorMiddleware.swift b/Sources/Functions/RelayErrorMiddleware.swift new file mode 100644 index 000000000..3755a5b8b --- /dev/null +++ b/Sources/Functions/RelayErrorMiddleware.swift @@ -0,0 +1,31 @@ +// +// RelayErrorMiddleware.swift +// Functions +// +// Created by Guilherme Souza on 30/06/26. +// + +import Foundation +import HTTPTypes +import OpenAPIRuntime + +struct RelayErrorMiddleware: ClientMiddleware, Sendable { + func intercept( + _ request: HTTPTypes.HTTPRequest, + body: OpenAPIRuntime.HTTPBody?, + baseURL: URL, + operationID: String, + next: + @Sendable (HTTPTypes.HTTPRequest, OpenAPIRuntime.HTTPBody?, URL) async throws -> ( + HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody? + ) + ) async throws -> (HTTPTypes.HTTPResponse, OpenAPIRuntime.HTTPBody?) { + let (response, responseBody) = try await next(request, body, baseURL) + if let fieldName = HTTPField.Name("x-relay-error"), + response.headerFields[fieldName] == "true" + { + throw FunctionsError.relayError + } + return (response, responseBody) + } +} diff --git a/Tests/FunctionsTests/RelayErrorMiddlewareTests.swift b/Tests/FunctionsTests/RelayErrorMiddlewareTests.swift new file mode 100644 index 000000000..210121e90 --- /dev/null +++ b/Tests/FunctionsTests/RelayErrorMiddlewareTests.swift @@ -0,0 +1,60 @@ +// +// RelayErrorMiddlewareTests.swift +// Functions +// +// Created by Guilherme Souza on 30/06/26. +// + +import HTTPTypes +import OpenAPIRuntime +import Testing + +@testable import Functions + +@Suite struct RelayErrorMiddlewareTests { + let middleware = RelayErrorMiddleware() + + @Test func throwsRelayErrorOnGenuine200() async throws { + var response = HTTPResponse(status: .ok) + response.headerFields[HTTPField.Name("x-relay-error")!] = "true" + + await #expect(throws: FunctionsError.relayError) { + try await middleware.intercept( + HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"), + body: nil, + baseURL: URL(string: "https://example.com")!, + operationID: "test", + next: { _, _, _ in (response, nil) } + ) + } + } + + @Test func passesCleanResponseThrough() async throws { + let response = HTTPResponse(status: .ok) + + let (result, _) = try await middleware.intercept( + HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"), + body: nil, + baseURL: URL(string: "https://example.com")!, + operationID: "test", + next: { _, _, _ in (response, nil) } + ) + + #expect(result.status == .ok) + } + + @Test func throwsRelayErrorOnNon200() async throws { + var response = HTTPResponse(status: .badRequest) + response.headerFields[HTTPField.Name("x-relay-error")!] = "true" + + await #expect(throws: FunctionsError.relayError) { + try await middleware.intercept( + HTTPRequest(method: .get, scheme: nil, authority: nil, path: "/"), + body: nil, + baseURL: URL(string: "https://example.com")!, + operationID: "test", + next: { _, _, _ in (response, nil) } + ) + } + } +} From 8050e9a86aa45c3c0f43cc93fc2751eb4bdcbf0e Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 10:28:23 -0300 Subject: [PATCH 19/32] feat(functions): add RelayErrorMiddleware; wire SupabaseMiddleware into production init --- Sources/Functions/FunctionsClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Functions/FunctionsClient.swift b/Sources/Functions/FunctionsClient.swift index 931d60d62..2e4f1e02a 100644 --- a/Sources/Functions/FunctionsClient.swift +++ b/Sources/Functions/FunctionsClient.swift @@ -135,7 +135,7 @@ public actor FunctionsClient { ) let transport = URLSessionTransport(configuration: .init(session: session)) let middleware = SupabaseMiddleware(headers: headers, tokenProvider: tokenProvider) - generatedClient = try? Client( + generatedClient = Client( serverURL: url, transport: transport, middlewares: [middleware, RelayErrorMiddleware()] From 10f895e317e61d1f2c4a7ebe26fc724b4d5feb48 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 10:44:11 -0300 Subject: [PATCH 20/32] spike(storage): add uploadObject/updateObject multipart operations with streaming file body --- Sources/Storage/Generated/Client.swift | 303 +++ Sources/Storage/Generated/Types.swift | 564 +++++ Sources/Storage/StorageClient.swift | 2 +- .../StorageFileApi+GeneratedUpload.swift | 198 ++ .../openapi/StorageService.openapi.json | 2096 +++++++++-------- 5 files changed, 2195 insertions(+), 968 deletions(-) create mode 100644 Sources/Storage/StorageFileApi+GeneratedUpload.swift diff --git a/Sources/Storage/Generated/Client.swift b/Sources/Storage/Generated/Client.swift index 03f9c7472..968114baf 100644 --- a/Sources/Storage/Generated/Client.swift +++ b/Sources/Storage/Generated/Client.swift @@ -1154,6 +1154,309 @@ internal struct Client: APIProtocol { } ) } + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/post(UploadObject)`. + internal func UploadObject(_ input: Operations.UploadObject.Input) async throws -> Operations.UploadObject.Output { + try await client.send( + input: input, + forOperation: Operations.UploadObject.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}/wildcardPath+", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .multipartForm(value): + body = try converter.setRequiredRequestBodyAsMultipart( + value, + headerFields: &request.headerFields, + contentType: "multipart/form-data", + allowsUnknownParts: true, + requiredExactlyOncePartNames: [ + "file" + ], + requiredAtLeastOncePartNames: [], + atMostOncePartNames: [ + "cacheControl", + "metadata" + ], + zeroOrMoreTimesPartNames: [], + encoding: { part in + switch part { + case let .cacheControl(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "text/plain" + ) + return .init( + name: "cacheControl", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .metadata(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsJSON( + value.body, + headerFields: &headerFields, + contentType: "application/json; charset=utf-8" + ) + return .init( + name: "metadata", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .file(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "application/octet-stream" + ) + return .init( + name: "file", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .undocumented(value): + return value + } + } + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UploadObject.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FileUploadedResponse.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UploadObject.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/put(UpdateObject)`. + internal func UpdateObject(_ input: Operations.UpdateObject.Input) async throws -> Operations.UpdateObject.Output { + try await client.send( + input: input, + forOperation: Operations.UpdateObject.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}/wildcardPath+", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .multipartForm(value): + body = try converter.setRequiredRequestBodyAsMultipart( + value, + headerFields: &request.headerFields, + contentType: "multipart/form-data", + allowsUnknownParts: true, + requiredExactlyOncePartNames: [ + "file" + ], + requiredAtLeastOncePartNames: [], + atMostOncePartNames: [ + "cacheControl", + "metadata" + ], + zeroOrMoreTimesPartNames: [], + encoding: { part in + switch part { + case let .cacheControl(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "text/plain" + ) + return .init( + name: "cacheControl", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .metadata(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsJSON( + value.body, + headerFields: &headerFields, + contentType: "application/json; charset=utf-8" + ) + return .init( + name: "metadata", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .file(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "application/octet-stream" + ) + return .init( + name: "file", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .undocumented(value): + return value + } + } + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpdateObject.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FileUploadedResponse.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpdateObject.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. internal func HeadObject(_ input: Operations.HeadObject.Input) async throws -> Operations.HeadObject.Output { diff --git a/Sources/Storage/Generated/Types.swift b/Sources/Storage/Generated/Types.swift index 6dff2facc..7d215dae0 100644 --- a/Sources/Storage/Generated/Types.swift +++ b/Sources/Storage/Generated/Types.swift @@ -53,6 +53,12 @@ internal protocol APIProtocol: Sendable { /// - Remark: HTTP `DELETE /object/{bucketId}`. /// - Remark: Generated from `#/paths//object/{bucketId}/delete(DeleteObjects)`. func DeleteObjects(_ input: Operations.DeleteObjects.Input) async throws -> Operations.DeleteObjects.Output + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/post(UploadObject)`. + func UploadObject(_ input: Operations.UploadObject.Input) async throws -> Operations.UploadObject.Output + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/put(UpdateObject)`. + func UpdateObject(_ input: Operations.UpdateObject.Input) async throws -> Operations.UpdateObject.Output /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. func HeadObject(_ input: Operations.HeadObject.Input) async throws -> Operations.HeadObject.Output @@ -218,6 +224,32 @@ extension APIProtocol { body: body )) } + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/post(UploadObject)`. + internal func UploadObject( + path: Operations.UploadObject.Input.Path, + headers: Operations.UploadObject.Input.Headers = .init(), + body: Operations.UploadObject.Input.Body + ) async throws -> Operations.UploadObject.Output { + try await UploadObject(Operations.UploadObject.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/put(UpdateObject)`. + internal func UpdateObject( + path: Operations.UpdateObject.Input.Path, + headers: Operations.UpdateObject.Input.Headers = .init(), + body: Operations.UpdateObject.Input.Body + ) async throws -> Operations.UpdateObject.Output { + try await UpdateObject(Operations.UpdateObject.Input( + path: path, + headers: headers, + body: body + )) + } /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. internal func HeadObject( @@ -923,6 +955,29 @@ internal enum Components { case allowed_mime_types } } + /// - Remark: Generated from `#/components/schemas/FileUploadedResponse`. + internal struct FileUploadedResponse: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FileUploadedResponse/Key`. + internal var Key: Swift.String + /// - Remark: Generated from `#/components/schemas/FileUploadedResponse/Id`. + internal var Id: Swift.String + /// Creates a new `FileUploadedResponse`. + /// + /// - Parameters: + /// - Key: + /// - Id: + internal init( + Key: Swift.String, + Id: Swift.String + ) { + self.Key = Key + self.Id = Id + } + internal enum CodingKeys: String, CodingKey { + case Key + case Id + } + } } /// Types generated from the `#/components/parameters` section of the OpenAPI document. internal enum Parameters {} @@ -3368,6 +3423,515 @@ internal enum Operations { } } } + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/post(UploadObject)`. + internal enum UploadObject { + internal static let id: Swift.String = "UploadObject" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/path/wildcardPath+`. + internal var wildcardPath_plus_: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath_plus_: + internal init( + bucketId: Swift.String, + wildcardPath_plus_: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath_plus_ = wildcardPath_plus_ + } + } + internal var path: Operations.UploadObject.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_upsert: + /// - accept: + internal init( + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.UploadObject.Input.Headers + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody/multipartForm`. + internal enum multipartFormPayload: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody/multipartForm/cacheControl`. + internal struct cacheControlPayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `cacheControlPayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case cacheControl(OpenAPIRuntime.MultipartPart) + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody/multipartForm/metadata`. + internal struct metadataPayload: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody/multipartForm/metadata/content/body`. + internal struct bodyPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer + /// Creates a new `bodyPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + internal var body: Operations.UploadObject.Input.Body.multipartFormPayload.metadataPayload.bodyPayload + /// Creates a new `metadataPayload`. + /// + /// - Parameters: + /// - body: + internal init(body: Operations.UploadObject.Input.Body.multipartFormPayload.metadataPayload.bodyPayload) { + self.body = body + } + } + case metadata(OpenAPIRuntime.MultipartPart) + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody/multipartForm/file`. + internal struct filePayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `filePayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case file(OpenAPIRuntime.MultipartPart) + case undocumented(OpenAPIRuntime.MultipartRawPart) + } + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/requestBody/content/multipart\/form-data`. + case multipartForm(OpenAPIRuntime.MultipartBody) + } + internal var body: Operations.UploadObject.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.UploadObject.Input.Path, + headers: Operations.UploadObject.Input.Headers = .init(), + body: Operations.UploadObject.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.FileUploadedResponse) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FileUploadedResponse { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UploadObject.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UploadObject.Output.Ok.Body) { + self.body = body + } + } + /// Upload successful + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/post(UploadObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.UploadObject.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.UploadObject.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UploadObject.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UploadObject.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/post(UploadObject)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.UploadObject.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.UploadObject.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath+}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/put(UpdateObject)`. + internal enum UpdateObject { + internal static let id: Swift.String = "UpdateObject" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/path/wildcardPath+`. + internal var wildcardPath_plus_: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath_plus_: + internal init( + bucketId: Swift.String, + wildcardPath_plus_: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath_plus_ = wildcardPath_plus_ + } + } + internal var path: Operations.UpdateObject.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.UpdateObject.Input.Headers + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody/multipartForm`. + internal enum multipartFormPayload: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody/multipartForm/cacheControl`. + internal struct cacheControlPayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `cacheControlPayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case cacheControl(OpenAPIRuntime.MultipartPart) + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody/multipartForm/metadata`. + internal struct metadataPayload: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody/multipartForm/metadata/content/body`. + internal struct bodyPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer + /// Creates a new `bodyPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: OpenAPIRuntime.OpenAPIObjectContainer = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + internal var body: Operations.UpdateObject.Input.Body.multipartFormPayload.metadataPayload.bodyPayload + /// Creates a new `metadataPayload`. + /// + /// - Parameters: + /// - body: + internal init(body: Operations.UpdateObject.Input.Body.multipartFormPayload.metadataPayload.bodyPayload) { + self.body = body + } + } + case metadata(OpenAPIRuntime.MultipartPart) + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody/multipartForm/file`. + internal struct filePayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `filePayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case file(OpenAPIRuntime.MultipartPart) + case undocumented(OpenAPIRuntime.MultipartRawPart) + } + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/requestBody/content/multipart\/form-data`. + case multipartForm(OpenAPIRuntime.MultipartBody) + } + internal var body: Operations.UpdateObject.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.UpdateObject.Input.Path, + headers: Operations.UpdateObject.Input.Headers = .init(), + body: Operations.UpdateObject.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/responses/200/content/application\/json`. + case json(Components.Schemas.FileUploadedResponse) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FileUploadedResponse { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpdateObject.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UpdateObject.Output.Ok.Body) { + self.body = body + } + } + /// Upload successful + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/put(UpdateObject)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.UpdateObject.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.UpdateObject.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath+}/PUT/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpdateObject.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UpdateObject.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/put(UpdateObject)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.UpdateObject.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.UpdateObject.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. internal enum HeadObject { diff --git a/Sources/Storage/StorageClient.swift b/Sources/Storage/StorageClient.swift index 54d6b4c1f..8f9db0438 100644 --- a/Sources/Storage/StorageClient.swift +++ b/Sources/Storage/StorageClient.swift @@ -140,7 +140,7 @@ public final class StorageClient: Sendable { public let configuration: StorageClientConfiguration package let http: _HTTPClient - private let generatedClient: Client + let generatedClient: Client private let usesTokenProvider: Bool let downloadDelegate: DownloadSessionDelegate diff --git a/Sources/Storage/StorageFileApi+GeneratedUpload.swift b/Sources/Storage/StorageFileApi+GeneratedUpload.swift new file mode 100644 index 000000000..047918883 --- /dev/null +++ b/Sources/Storage/StorageFileApi+GeneratedUpload.swift @@ -0,0 +1,198 @@ +// +// StorageFileApi+GeneratedUpload.swift +// Storage +// +// SPIKE — demonstrates how the generated multipart client handles streaming +// uploads. The file part is backed by an AsyncStream of 64 KB chunks from +// FileHandle, so the file is never fully buffered in memory. +// +// TUS (resumable) uploads are NOT covered here — the TUS state machine +// cannot be expressed in standard OpenAPI and stays hand-written. +// +// Content-Type limitation: the generated serializer hardcodes +// "application/octet-stream" for the file part. Passing a custom MIME type +// requires a raw MultipartRawPart, which is left as a follow-up. +// + +import Foundation +import OpenAPIRuntime + +extension StorageFileAPI { + + // MARK: - Upload (POST) via generated client + + /// Upload `data` to `path` using the generated multipart client. + func uploadViaGeneratedClient( + _ path: String, + data: Data, + options: FileOptions = FileOptions(), + upsert: Bool = false + ) async throws -> FileUploadedResponse { + let (bucketId, objectPath) = splitPath(path) + typealias Part = Operations.UploadObject.Input.Body.multipartFormPayload + + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: HTTPBody(data)), filename: nil))) + + let output = try await client.generatedClient.UploadObject( + path: .init(bucketId: bucketId, wildcardPath_plus_: objectPath), + headers: .init(x_hyphen_upsert: upsert ? "true" : nil), + body: .multipartForm(MultipartBody(parts)) + ) + switch output { + case .ok(let ok): + switch ok.body { + case .json(let body): return FileUploadedResponse(key: body.Key, id: body.Id) + } + case .badRequest(let err): + switch err.body { + case .json(let body): + throw URLError( + .unknown, userInfo: [NSLocalizedDescriptionKey: body.message ?? "Unknown error"]) + } + case .undocumented(let code, _): + throw URLError(.unknown, userInfo: [NSLocalizedDescriptionKey: "HTTP \(code)"]) + } + } + + /// Upload a file at `fileURL` streaming in 64 KB chunks. + func uploadViaGeneratedClient( + _ path: String, + fileURL: URL, + options: FileOptions = FileOptions(), + upsert: Bool = false + ) async throws -> FileUploadedResponse { + let (bucketId, objectPath) = splitPath(path) + typealias Part = Operations.UploadObject.Input.Body.multipartFormPayload + + let fileSize = (try? fileURL.resourceValues(forKeys: [.fileSizeKey]).fileSize).flatMap { + Int64($0) + } + let length: HTTPBody.Length = fileSize.map { .known($0) } ?? .unknown + let fileBody = chunkedBody(from: fileURL, length: length) + + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: fileBody), filename: nil))) + + let output = try await client.generatedClient.UploadObject( + path: .init(bucketId: bucketId, wildcardPath_plus_: objectPath), + headers: .init(x_hyphen_upsert: upsert ? "true" : nil), + body: .multipartForm(MultipartBody(parts)) + ) + switch output { + case .ok(let ok): + switch ok.body { + case .json(let body): return FileUploadedResponse(key: body.Key, id: body.Id) + } + case .badRequest(let err): + switch err.body { + case .json(let body): + throw URLError( + .unknown, userInfo: [NSLocalizedDescriptionKey: body.message ?? "Unknown error"]) + } + case .undocumented(let code, _): + throw URLError(.unknown, userInfo: [NSLocalizedDescriptionKey: "HTTP \(code)"]) + } + } + + // MARK: - Update (PUT) via generated client + + /// Overwrite the object at `path` using the generated multipart client. + func updateViaGeneratedClient( + _ path: String, + data: Data, + options: FileOptions = FileOptions() + ) async throws -> FileUploadedResponse { + let (bucketId, objectPath) = splitPath(path) + typealias Part = Operations.UpdateObject.Input.Body.multipartFormPayload + + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: HTTPBody(data)), filename: nil))) + + let output = try await client.generatedClient.UpdateObject( + path: .init(bucketId: bucketId, wildcardPath_plus_: objectPath), + body: .multipartForm(MultipartBody(parts)) + ) + switch output { + case .ok(let ok): + switch ok.body { + case .json(let body): return FileUploadedResponse(key: body.Key, id: body.Id) + } + case .badRequest(let err): + switch err.body { + case .json(let body): + throw URLError( + .unknown, userInfo: [NSLocalizedDescriptionKey: body.message ?? "Unknown error"]) + } + case .undocumented(let code, _): + throw URLError(.unknown, userInfo: [NSLocalizedDescriptionKey: "HTTP \(code)"]) + } + } + + // MARK: - Private helpers + + private func splitPath(_ path: String) -> (bucketId: String, objectPath: String) { + let components = path.split(separator: "/", maxSplits: 1, omittingEmptySubsequences: false) + return ( + components.first.map(String.init) ?? "", + components.dropFirst().first.map(String.init) ?? "" + ) + } + + /// Wraps a file URL in an HTTPBody that streams 64 KB chunks via FileHandle. + private func chunkedBody(from url: URL, length: HTTPBody.Length) -> HTTPBody { + let chunkSize = 65_536 + return HTTPBody( + AsyncStream> { continuation in + Task { + guard let handle = try? FileHandle(forReadingFrom: url) else { + continuation.finish() + return + } + defer { try? handle.close() } + while true { + let chunk = handle.readData(ofLength: chunkSize) + if chunk.isEmpty { break } + continuation.yield(ArraySlice(chunk)) + } + continuation.finish() + } + }, + length: length, + iterationBehavior: .single + ) + } +} + +/// Return value from upload/update operations. +public struct FileUploadedResponse: Sendable { + public let key: String + public let id: String? +} diff --git a/smithy/output/openapi/StorageService.openapi.json b/smithy/output/openapi/StorageService.openapi.json index 6cb6e6944..9f9470727 100644 --- a/smithy/output/openapi/StorageService.openapi.json +++ b/smithy/output/openapi/StorageService.openapi.json @@ -1,1037 +1,1199 @@ { - "openapi": "3.0.2", - "info": { - "title": "Supabase Storage API", - "version": "1.0" - }, - "paths": { - "/bucket": { - "get": { - "operationId": "ListBuckets", - "responses": { - "200": { - "description": "ListBuckets 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListBucketsResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "openapi": "3.0.2", + "info": { + "title": "Supabase Storage API", + "version": "1.0" + }, + "paths": { + "/bucket": { + "get": { + "operationId": "ListBuckets", + "responses": { + "200": { + "description": "ListBuckets 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListBucketsResponseContent" } - }, - "post": { - "operationId": "CreateBucket", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateBucketRequestContent" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "CreateBucket 200 response" - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } } + } + } + }, + "post": { + "operationId": "CreateBucket", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateBucketRequestContent" + } + } + }, + "required": true }, - "/bucket/{id}": { - "delete": { - "operationId": "DeleteBucket", - "parameters": [ - { - "name": "id", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "DeleteBucket 200 response" - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "responses": { + "200": { + "description": "CreateBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } + } + } + } + } + }, + "/bucket/{id}": { + "delete": { + "operationId": "DeleteBucket", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" }, - "get": { - "operationId": "GetBucket", - "parameters": [ - { - "name": "id", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "GetBucket 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetBucketResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "required": true + } + ], + "responses": { + "200": { + "description": "DeleteBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } + } + } + } + }, + "get": { + "operationId": "GetBucket", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" }, - "put": { - "operationId": "UpdateBucket", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateBucketRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "id", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "UpdateBucket 200 response" - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "required": true + } + ], + "responses": { + "200": { + "description": "GetBucket 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetBucketResponseContent" } + } } - }, - "/bucket/{id}/empty": { - "post": { - "operationId": "EmptyBucket", - "parameters": [ - { - "name": "id", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "EmptyBucket 200 response" - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } + } + } + } + }, + "put": { + "operationId": "UpdateBucket", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateBucketRequestContent" + } } + }, + "required": true }, - "/object/copy": { - "post": { - "operationId": "CopyObject", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CopyObjectRequestContent" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "CopyObject 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CopyObjectResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "UpdateBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } } - }, - "/object/info/{bucketId}/{wildcardPath+}": { - "get": { - "operationId": "GetObjectInfo", - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "wildcardPath+", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "GetObjectInfo 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/GetObjectInfoResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + } + } + } + }, + "/bucket/{id}/empty": { + "post": { + "operationId": "EmptyBucket", + "parameters": [ + { + "name": "id", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "EmptyBucket 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } } + } + } + } + }, + "/object/copy": { + "post": { + "operationId": "CopyObject", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CopyObjectRequestContent" + } + } + }, + "required": true }, - "/object/list/{bucketId}": { - "post": { - "operationId": "ListObjects", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListObjectsRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "ListObjects 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ListObjectsResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "responses": { + "200": { + "description": "CopyObject 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CopyObjectResponseContent" } + } } - }, - "/object/move": { - "post": { - "operationId": "MoveObject", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/MoveObjectRequestContent" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "MoveObject 200 response" - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } } - }, - "/object/sign/{bucketId}": { - "post": { - "operationId": "CreateSignedUrls", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignedUrlsRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "CreateSignedUrls 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignedUrlsResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + } + } + } + }, + "/object/info/{bucketId}/{wildcardPath+}": { + "get": { + "operationId": "GetObjectInfo", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetObjectInfo 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetObjectInfoResponseContent" } + } } - }, - "/object/sign/{bucketId}/{wildcardPath+}": { - "post": { - "operationId": "CreateSignedUrl", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignedUrlRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "wildcardPath+", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "CreateSignedUrl 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignedUrlResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } } + } + } + } + }, + "/object/list/{bucketId}": { + "post": { + "operationId": "ListObjects", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListObjectsRequestContent" + } + } + }, + "required": true }, - "/object/upload/sign/{bucketId}/{wildcardPath+}": { - "post": { - "operationId": "CreateSignedUploadUrl", - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "wildcardPath+", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "x-upsert", - "in": "header", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "CreateSignedUploadUrl 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignedUploadUrlResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "ListObjects 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListObjectsResponseContent" } + } } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/move": { + "post": { + "operationId": "MoveObject", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MoveObjectRequestContent" + } + } + }, + "required": true }, - "/object/{bucketId}": { - "delete": { - "operationId": "DeleteObjects", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteObjectsRequestContent" - } - } - }, - "required": true - }, - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "DeleteObjects 200 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteObjectsResponseContent" - } - } - } - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "responses": { + "200": { + "description": "MoveObject 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } } + } + } + } + }, + "/object/sign/{bucketId}": { + "post": { + "operationId": "CreateSignedUrls", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlsRequestContent" + } + } + }, + "required": true }, - "/object/{bucketId}/{wildcardPath+}": { - "head": { - "operationId": "HeadObject", - "parameters": [ - { - "name": "bucketId", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "wildcardPath+", - "in": "path", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "HeadObject 200 response" - }, - "400": { - "description": "StorageError 400 response", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/StorageErrorResponseContent" - } - } - } - } + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "CreateSignedUrls 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlsResponseContent" } + } } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } } + } }, - "components": { - "schemas": { - "Bucket": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "public": { - "type": "boolean" - }, - "file_size_limit": { - "type": "number" - }, - "allowed_mime_types": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Common string list shape reused across services." - }, - "created_at": { - "type": "string" - }, - "updated_at": { - "type": "string" - } - }, - "required": [ - "id", - "name", - "public" - ] + "/object/sign/{bucketId}/{wildcardPath+}": { + "post": { + "operationId": "CreateSignedUrl", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" }, - "CopyObjectRequestContent": { - "type": "object", - "properties": { - "bucketId": { - "type": "string" - }, - "sourceKey": { - "type": "string" - }, - "destinationKey": { - "type": "string" - }, - "destinationBucket": { - "type": "string" - } - }, - "required": [ - "bucketId", - "destinationKey", - "sourceKey" - ] + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" }, - "CopyObjectResponseContent": { - "type": "object", - "properties": { - "Key": { - "type": "string" - } - }, - "required": [ - "Key" - ] + "required": true + } + ], + "responses": { + "200": { + "description": "CreateSignedUrl 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUrlResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/upload/sign/{bucketId}/{wildcardPath+}": { + "post": { + "operationId": "CreateSignedUploadUrl", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" }, - "CreateBucketRequestContent": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "public": { - "type": "boolean" - }, - "file_size_limit": { - "type": "number" - }, - "allowed_mime_types": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Common string list shape reused across services." - } - }, - "required": [ - "id", - "name", - "public" - ] + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" }, - "CreateSignedUploadUrlResponseContent": { - "type": "object", - "properties": { - "url": { - "type": "string" - } - }, - "required": [ - "url" - ] + "required": true + }, + { + "name": "x-upsert", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "CreateSignedUploadUrl 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignedUploadUrlResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/{bucketId}": { + "delete": { + "operationId": "DeleteObjects", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteObjectsRequestContent" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" }, - "CreateSignedUrlRequestContent": { - "type": "object", - "properties": { - "expiresIn": { - "type": "number" - } - }, - "required": [ - "expiresIn" - ] + "required": true + } + ], + "responses": { + "200": { + "description": "DeleteObjects 200 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteObjectsResponseContent" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/object/{bucketId}/{wildcardPath+}": { + "head": { + "operationId": "HeadObject", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" }, - "CreateSignedUrlResponseContent": { - "type": "object", - "properties": { - "signedURL": { - "type": "string" - } - }, - "required": [ - "signedURL" - ] + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" }, - "CreateSignedUrlsRequestContent": { - "type": "object", - "properties": { - "expiresIn": { - "type": "number" - }, - "paths": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Common string list shape reused across services." - } - }, - "required": [ - "expiresIn", - "paths" - ] + "required": true + } + ], + "responses": { + "200": { + "description": "HeadObject 200 response" + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + }, + "post": { + "operationId": "UploadObject", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" }, - "CreateSignedUrlsResponseContent": { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SignedUrlResult" - } - } - }, - "required": [ - "items" - ] + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" }, - "DeleteObjectsRequestContent": { - "type": "object", - "properties": { - "prefixes": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Common string list shape reused across services." - } - }, - "required": [ - "prefixes" - ] + "required": true + }, + { + "name": "x-upsert", + "in": "header", + "schema": { + "type": "string" }, - "DeleteObjectsResponseContent": { + "required": false + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { "type": "object", "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FileObject" - } - } + "cacheControl": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": true + }, + "file": { + "type": "string", + "format": "binary" + } }, "required": [ - "items" + "file" ] - }, - "FileMetadata": { - "type": "object", - "properties": { - "eTag": { - "type": "string" - }, - "size": { - "type": "number" - }, - "mimetype": { - "type": "string" - }, - "cacheControl": { - "type": "string" - }, - "lastModified": { - "type": "string" - }, - "contentLength": { - "type": "number" - }, - "httpStatusCode": { - "type": "number" - } + } + } + } + }, + "responses": { + "200": { + "description": "Upload successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FileUploadedResponse" } - }, - "FileObject": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "last_accessed_at": { - "type": "string" - }, - "metadata": { - "$ref": "#/components/schemas/FileMetadata" - } - }, - "required": [ - "name" - ] - }, - "GetBucketResponseContent": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "public": { - "type": "boolean" - }, - "file_size_limit": { - "type": "number" - }, - "allowed_mime_types": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Common string list shape reused across services." - }, - "created_at": { - "type": "string" - }, - "updated_at": { - "type": "string" - } - }, - "required": [ - "id", - "name", - "public" - ] - }, - "GetObjectInfoResponseContent": { - "type": "object", - "properties": { - "eTag": { - "type": "string" - }, - "size": { - "type": "number" - }, - "mimetype": { - "type": "string" - }, - "cacheControl": { - "type": "string" - }, - "lastModified": { - "type": "string" - }, - "contentLength": { - "type": "number" - }, - "httpStatusCode": { - "type": "number" - } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" } + } + } + } + } + }, + "put": { + "operationId": "UpdateObject", + "parameters": [ + { + "name": "bucketId", + "in": "path", + "schema": { + "type": "string" }, - "ListBucketsResponseContent": { - "type": "object", - "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Bucket" - } - } - }, - "required": [ - "items" - ] - }, - "ListObjectsRequestContent": { - "type": "object", - "properties": { - "prefix": { - "type": "string" - }, - "limit": { - "type": "number" - }, - "offset": { - "type": "number" - }, - "sortBy": { - "$ref": "#/components/schemas/SortBy" - } - }, - "required": [ - "prefix" - ] + "required": true + }, + { + "name": "wildcardPath+", + "in": "path", + "schema": { + "type": "string" }, - "ListObjectsResponseContent": { + "required": true + } + ], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { "type": "object", "properties": { - "items": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FileObject" - } - } + "cacheControl": { + "type": "string" + }, + "metadata": { + "type": "object", + "additionalProperties": true + }, + "file": { + "type": "string", + "format": "binary" + } }, "required": [ - "items" + "file" ] + } + } + } + }, + "responses": { + "200": { + "description": "Upload successful", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FileUploadedResponse" + } + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Bucket": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" }, - "MoveObjectRequestContent": { - "type": "object", - "properties": { - "bucketId": { - "type": "string" - }, - "sourceKey": { - "type": "string" - }, - "destinationKey": { - "type": "string" - }, - "destinationBucket": { - "type": "string" - } - }, - "required": [ - "bucketId", - "destinationKey", - "sourceKey" - ] + "description": "Common string list shape reused across services." + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "public" + ] + }, + "CopyObjectRequestContent": { + "type": "object", + "properties": { + "bucketId": { + "type": "string" + }, + "sourceKey": { + "type": "string" + }, + "destinationKey": { + "type": "string" + }, + "destinationBucket": { + "type": "string" + } + }, + "required": [ + "bucketId", + "destinationKey", + "sourceKey" + ] + }, + "CopyObjectResponseContent": { + "type": "object", + "properties": { + "Key": { + "type": "string" + } + }, + "required": [ + "Key" + ] + }, + "CreateBucketRequestContent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" }, - "SignedUrlResult": { - "type": "object", - "properties": { - "signedURL": { - "type": "string" - }, - "path": { - "type": "string" - }, - "error": { - "type": "string" - } - }, - "required": [ - "path" - ] + "description": "Common string list shape reused across services." + } + }, + "required": [ + "id", + "name", + "public" + ] + }, + "CreateSignedUploadUrlResponseContent": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ] + }, + "CreateSignedUrlRequestContent": { + "type": "object", + "properties": { + "expiresIn": { + "type": "number" + } + }, + "required": [ + "expiresIn" + ] + }, + "CreateSignedUrlResponseContent": { + "type": "object", + "properties": { + "signedURL": { + "type": "string" + } + }, + "required": [ + "signedURL" + ] + }, + "CreateSignedUrlsRequestContent": { + "type": "object", + "properties": { + "expiresIn": { + "type": "number" + }, + "paths": { + "type": "array", + "items": { + "type": "string" }, - "SortBy": { - "type": "object", - "properties": { - "column": { - "type": "string" - }, - "order": { - "type": "string" - } - } + "description": "Common string list shape reused across services." + } + }, + "required": [ + "expiresIn", + "paths" + ] + }, + "CreateSignedUrlsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SignedUrlResult" + } + } + }, + "required": [ + "items" + ] + }, + "DeleteObjectsRequestContent": { + "type": "object", + "properties": { + "prefixes": { + "type": "array", + "items": { + "type": "string" }, - "StorageErrorResponseContent": { - "type": "object", - "properties": { - "message": { - "type": "string" - }, - "error": { - "type": "string" - }, - "statusCode": { - "type": "string" - } - } + "description": "Common string list shape reused across services." + } + }, + "required": [ + "prefixes" + ] + }, + "DeleteObjectsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileObject" + } + } + }, + "required": [ + "items" + ] + }, + "FileMetadata": { + "type": "object", + "properties": { + "eTag": { + "type": "string" + }, + "size": { + "type": "number" + }, + "mimetype": { + "type": "string" + }, + "cacheControl": { + "type": "string" + }, + "lastModified": { + "type": "string" + }, + "contentLength": { + "type": "number" + }, + "httpStatusCode": { + "type": "number" + } + } + }, + "FileObject": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "last_accessed_at": { + "type": "string" + }, + "metadata": { + "$ref": "#/components/schemas/FileMetadata" + } + }, + "required": [ + "name" + ] + }, + "GetBucketResponseContent": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" }, - "UpdateBucketRequestContent": { - "type": "object", - "properties": { - "public": { - "type": "boolean" - }, - "file_size_limit": { - "type": "number" - }, - "allowed_mime_types": { - "type": "array", - "items": { - "type": "string" - }, - "description": "Common string list shape reused across services." - } - }, - "required": [ - "public" - ] + "description": "Common string list shape reused across services." + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "public" + ] + }, + "GetObjectInfoResponseContent": { + "type": "object", + "properties": { + "eTag": { + "type": "string" + }, + "size": { + "type": "number" + }, + "mimetype": { + "type": "string" + }, + "cacheControl": { + "type": "string" + }, + "lastModified": { + "type": "string" + }, + "contentLength": { + "type": "number" + }, + "httpStatusCode": { + "type": "number" + } + } + }, + "ListBucketsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Bucket" } + } + }, + "required": [ + "items" + ] + }, + "ListObjectsRequestContent": { + "type": "object", + "properties": { + "prefix": { + "type": "string" + }, + "limit": { + "type": "number" + }, + "offset": { + "type": "number" + }, + "sortBy": { + "$ref": "#/components/schemas/SortBy" + } + }, + "required": [ + "prefix" + ] + }, + "ListObjectsResponseContent": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/FileObject" + } + } + }, + "required": [ + "items" + ] + }, + "MoveObjectRequestContent": { + "type": "object", + "properties": { + "bucketId": { + "type": "string" + }, + "sourceKey": { + "type": "string" + }, + "destinationKey": { + "type": "string" + }, + "destinationBucket": { + "type": "string" + } + }, + "required": [ + "bucketId", + "destinationKey", + "sourceKey" + ] + }, + "SignedUrlResult": { + "type": "object", + "properties": { + "signedURL": { + "type": "string" + }, + "path": { + "type": "string" + }, + "error": { + "type": "string" + } + }, + "required": [ + "path" + ] + }, + "SortBy": { + "type": "object", + "properties": { + "column": { + "type": "string" + }, + "order": { + "type": "string" + } + } + }, + "StorageErrorResponseContent": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "error": { + "type": "string" + }, + "statusCode": { + "type": "string" + } } + }, + "UpdateBucketRequestContent": { + "type": "object", + "properties": { + "public": { + "type": "boolean" + }, + "file_size_limit": { + "type": "number" + }, + "allowed_mime_types": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Common string list shape reused across services." + } + }, + "required": [ + "public" + ] + }, + "FileUploadedResponse": { + "type": "object", + "properties": { + "Key": { + "type": "string" + }, + "Id": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "Key", + "Id" + ] + } } -} + } +} \ No newline at end of file From e6aee660aa8602bb5b53b66046d09c2a6a37646a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 11:00:26 -0300 Subject: [PATCH 21/32] spike(storage): add TUS operations to Smithy model; patch streaming blob to HTTPBody --- Makefile | 1 + Sources/Storage/Generated/Client.swift | 251 +++++++ Sources/Storage/Generated/Types.swift | 626 ++++++++++++++++++ smithy/model/storage.smithy | 110 +++ .../openapi/StorageService.openapi.json | 189 ++++++ smithy/patch-openapi.py | 94 +++ 6 files changed, 1271 insertions(+) create mode 100644 smithy/patch-openapi.py diff --git a/Makefile b/Makefile index a8d8b18ec..34620616a 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,7 @@ generate-smithy: cd smithy && smithy build cp smithy/build/smithy/storage-openapi/openapi/StorageService.openapi.json smithy/output/openapi/StorageService.openapi.json cp smithy/build/smithy/functions-openapi/openapi/FunctionsService.openapi.json smithy/output/openapi/FunctionsService.openapi.json + python3 smithy/patch-openapi.py smithy/output/openapi/StorageService.openapi.json generate-swift-storage: check-swift-openapi-generator swift-openapi-generator generate \ diff --git a/Sources/Storage/Generated/Client.swift b/Sources/Storage/Generated/Client.swift index 968114baf..97c4f4ff3 100644 --- a/Sources/Storage/Generated/Client.swift +++ b/Sources/Storage/Generated/Client.swift @@ -1519,4 +1519,255 @@ internal struct Client: APIProtocol { } ) } + /// Step 1: Create a new TUS upload session. + /// The server responds with a Location header containing the upload URL. + /// + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(CreateTusUpload)`. + internal func CreateTusUpload(_ input: Operations.CreateTusUpload.Input) async throws -> Operations.CreateTusUpload.Output { + try await client.send( + input: input, + forOperation: Operations.CreateTusUpload.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/upload/resumable", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Tus-Resumable", + value: input.headers.Tus_hyphen_Resumable + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Upload-Length", + value: input.headers.Upload_hyphen_Length + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Upload-Metadata", + value: input.headers.Upload_hyphen_Metadata + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + let headers: Operations.CreateTusUpload.Output.Created.Headers = .init(Location: try converter.getRequiredHeaderFieldAsURI( + in: response.headerFields, + name: "Location", + as: Swift.String.self + )) + return .created(.init(headers: headers)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CreateTusUpload.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// Step 2: Upload a chunk of data to an existing TUS session. + /// Repeat with increasing Upload-Offset until all bytes are sent. + /// + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(UploadChunk)`. + internal func UploadChunk(_ input: Operations.UploadChunk.Input) async throws -> Operations.UploadChunk.Output { + try await client.send( + input: input, + forOperation: Operations.UploadChunk.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/upload/resumable/{}", + parameters: [ + input.path.uploadId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .patch + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Tus-Resumable", + value: input.headers.Tus_hyphen_Resumable + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Upload-Offset", + value: input.headers.Upload_hyphen_Offset + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + let headers: Operations.UploadChunk.Output.NoContent.Headers = .init(Upload_hyphen_Offset: try converter.getRequiredHeaderFieldAsURI( + in: response.headerFields, + name: "Upload-Offset", + as: Swift.Double.self + )) + return .noContent(.init(headers: headers)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UploadChunk.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// Step 3: Query the server-side offset of a TUS session (used when resuming). + /// + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(GetUploadOffset)`. + internal func GetUploadOffset(_ input: Operations.GetUploadOffset.Input) async throws -> Operations.GetUploadOffset.Output { + try await client.send( + input: input, + forOperation: Operations.GetUploadOffset.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/upload/resumable/{}", + parameters: [ + input.path.uploadId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .head + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Tus-Resumable", + value: input.headers.Tus_hyphen_Resumable + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.GetUploadOffset.Output.Ok.Headers = .init(Upload_hyphen_Offset: try converter.getRequiredHeaderFieldAsURI( + in: response.headerFields, + name: "Upload-Offset", + as: Swift.Double.self + )) + return .ok(.init(headers: headers)) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.GetUploadOffset.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } } diff --git a/Sources/Storage/Generated/Types.swift b/Sources/Storage/Generated/Types.swift index 7d215dae0..dd0de708c 100644 --- a/Sources/Storage/Generated/Types.swift +++ b/Sources/Storage/Generated/Types.swift @@ -62,6 +62,23 @@ internal protocol APIProtocol: Sendable { /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath+}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath+}/head(HeadObject)`. func HeadObject(_ input: Operations.HeadObject.Input) async throws -> Operations.HeadObject.Output + /// Step 1: Create a new TUS upload session. + /// The server responds with a Location header containing the upload URL. + /// + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(CreateTusUpload)`. + func CreateTusUpload(_ input: Operations.CreateTusUpload.Input) async throws -> Operations.CreateTusUpload.Output + /// Step 2: Upload a chunk of data to an existing TUS session. + /// Repeat with increasing Upload-Offset until all bytes are sent. + /// + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(UploadChunk)`. + func UploadChunk(_ input: Operations.UploadChunk.Input) async throws -> Operations.UploadChunk.Output + /// Step 3: Query the server-side offset of a TUS session (used when resuming). + /// + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(GetUploadOffset)`. + func GetUploadOffset(_ input: Operations.GetUploadOffset.Input) async throws -> Operations.GetUploadOffset.Output } /// Convenience overloads for operation inputs. @@ -261,6 +278,43 @@ extension APIProtocol { headers: headers )) } + /// Step 1: Create a new TUS upload session. + /// The server responds with a Location header containing the upload URL. + /// + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(CreateTusUpload)`. + internal func CreateTusUpload(headers: Operations.CreateTusUpload.Input.Headers) async throws -> Operations.CreateTusUpload.Output { + try await CreateTusUpload(Operations.CreateTusUpload.Input(headers: headers)) + } + /// Step 2: Upload a chunk of data to an existing TUS session. + /// Repeat with increasing Upload-Offset until all bytes are sent. + /// + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(UploadChunk)`. + internal func UploadChunk( + path: Operations.UploadChunk.Input.Path, + headers: Operations.UploadChunk.Input.Headers, + body: Operations.UploadChunk.Input.Body + ) async throws -> Operations.UploadChunk.Output { + try await UploadChunk(Operations.UploadChunk.Input( + path: path, + headers: headers, + body: body + )) + } + /// Step 3: Query the server-side offset of a TUS session (used when resuming). + /// + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(GetUploadOffset)`. + internal func GetUploadOffset( + path: Operations.GetUploadOffset.Input.Path, + headers: Operations.GetUploadOffset.Input.Headers + ) async throws -> Operations.GetUploadOffset.Output { + try await GetUploadOffset(Operations.GetUploadOffset.Input( + path: path, + headers: headers + )) + } } /// Server URLs defined in the OpenAPI document. @@ -955,6 +1009,10 @@ internal enum Components { case allowed_mime_types } } + /// Raw chunk bytes, streamed directly — never buffered. + /// + /// - Remark: Generated from `#/components/schemas/UploadChunkInputPayload`. + internal typealias UploadChunkInputPayload = OpenAPIRuntime.HTTPBody /// - Remark: Generated from `#/components/schemas/FileUploadedResponse`. internal struct FileUploadedResponse: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/FileUploadedResponse/Key`. @@ -4100,4 +4158,572 @@ internal enum Operations { } } } + /// Step 1: Create a new TUS upload session. + /// The server responds with a Location header containing the upload URL. + /// + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(CreateTusUpload)`. + internal enum CreateTusUpload { + internal static let id: Swift.String = "CreateTusUpload" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/Tus-Resumable`. + internal var Tus_hyphen_Resumable: Swift.String + /// Total size of the file in bytes. + /// + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/Upload-Length`. + internal var Upload_hyphen_Length: Swift.Double + /// Base64-encoded TUS metadata (bucketName, objectName, contentType, cacheControl). + /// + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/Upload-Metadata`. + internal var Upload_hyphen_Metadata: Swift.String + /// Set to "true" to overwrite an existing object at the same path. + /// + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Tus_hyphen_Resumable: + /// - Upload_hyphen_Length: Total size of the file in bytes. + /// - Upload_hyphen_Metadata: Base64-encoded TUS metadata (bucketName, objectName, contentType, cacheControl). + /// - x_hyphen_upsert: Set to "true" to overwrite an existing object at the same path. + /// - accept: + internal init( + Tus_hyphen_Resumable: Swift.String, + Upload_hyphen_Length: Swift.Double, + Upload_hyphen_Metadata: Swift.String, + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Tus_hyphen_Resumable = Tus_hyphen_Resumable + self.Upload_hyphen_Length = Upload_hyphen_Length + self.Upload_hyphen_Metadata = Upload_hyphen_Metadata + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.CreateTusUpload.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + internal init(headers: Operations.CreateTusUpload.Input.Headers) { + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Created: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/201/headers`. + internal struct Headers: Sendable, Hashable { + /// Full URL of the created upload session. Used in subsequent PATCH/HEAD requests. + /// + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/201/headers/Location`. + internal var Location: Swift.String + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Location: Full URL of the created upload session. Used in subsequent PATCH/HEAD requests. + internal init(Location: Swift.String) { + self.Location = Location + } + } + /// Received HTTP response headers + internal var headers: Operations.CreateTusUpload.Output.Created.Headers + /// Creates a new `Created`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + internal init(headers: Operations.CreateTusUpload.Output.Created.Headers) { + self.headers = headers + } + } + /// CreateTusUpload 201 response + /// + /// - Remark: Generated from `#/paths//upload/resumable/post(CreateTusUpload)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.CreateTusUpload.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + internal var created: Operations.CreateTusUpload.Output.Created { + get throws { + switch self { + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CreateTusUpload.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CreateTusUpload.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//upload/resumable/post(CreateTusUpload)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CreateTusUpload.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CreateTusUpload.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Step 2: Upload a chunk of data to an existing TUS session. + /// Repeat with increasing Upload-Offset until all bytes are sent. + /// + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(UploadChunk)`. + internal enum UploadChunk { + internal static let id: Swift.String = "UploadChunk" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/path/uploadId`. + internal var uploadId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - uploadId: + internal init(uploadId: Swift.String) { + self.uploadId = uploadId + } + } + internal var path: Operations.UploadChunk.Input.Path + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/header/Tus-Resumable`. + internal var Tus_hyphen_Resumable: Swift.String + /// Byte offset at which this chunk begins. + /// + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/header/Upload-Offset`. + internal var Upload_hyphen_Offset: Swift.Double + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Tus_hyphen_Resumable: + /// - Upload_hyphen_Offset: Byte offset at which this chunk begins. + /// - accept: + internal init( + Tus_hyphen_Resumable: Swift.String, + Upload_hyphen_Offset: Swift.Double, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Tus_hyphen_Resumable = Tus_hyphen_Resumable + self.Upload_hyphen_Offset = Upload_hyphen_Offset + self.accept = accept + } + } + internal var headers: Operations.UploadChunk.Input.Headers + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.UploadChunk.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.UploadChunk.Input.Path, + headers: Operations.UploadChunk.Input.Headers, + body: Operations.UploadChunk.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/204/headers`. + internal struct Headers: Sendable, Hashable { + /// New server-side offset after the chunk was accepted. + /// + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/204/headers/Upload-Offset`. + internal var Upload_hyphen_Offset: Swift.Double + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Upload_hyphen_Offset: New server-side offset after the chunk was accepted. + internal init(Upload_hyphen_Offset: Swift.Double) { + self.Upload_hyphen_Offset = Upload_hyphen_Offset + } + } + /// Received HTTP response headers + internal var headers: Operations.UploadChunk.Output.NoContent.Headers + /// Creates a new `NoContent`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + internal init(headers: Operations.UploadChunk.Output.NoContent.Headers) { + self.headers = headers + } + } + /// UploadChunk 204 response + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(UploadChunk)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.UploadChunk.Output.NoContent) + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.UploadChunk.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UploadChunk.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UploadChunk.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(UploadChunk)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.UploadChunk.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.UploadChunk.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Step 3: Query the server-side offset of a TUS session (used when resuming). + /// + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(GetUploadOffset)`. + internal enum GetUploadOffset { + internal static let id: Swift.String = "GetUploadOffset" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/path/uploadId`. + internal var uploadId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - uploadId: + internal init(uploadId: Swift.String) { + self.uploadId = uploadId + } + } + internal var path: Operations.GetUploadOffset.Input.Path + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/header/Tus-Resumable`. + internal var Tus_hyphen_Resumable: Swift.String + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Tus_hyphen_Resumable: + /// - accept: + internal init( + Tus_hyphen_Resumable: Swift.String, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Tus_hyphen_Resumable = Tus_hyphen_Resumable + self.accept = accept + } + } + internal var headers: Operations.GetUploadOffset.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.GetUploadOffset.Input.Path, + headers: Operations.GetUploadOffset.Input.Headers + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/200/headers/Upload-Offset`. + internal var Upload_hyphen_Offset: Swift.Double + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Upload_hyphen_Offset: + internal init(Upload_hyphen_Offset: Swift.Double) { + self.Upload_hyphen_Offset = Upload_hyphen_Offset + } + } + /// Received HTTP response headers + internal var headers: Operations.GetUploadOffset.Output.Ok.Headers + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + internal init(headers: Operations.GetUploadOffset.Output.Ok.Headers) { + self.headers = headers + } + } + /// GetUploadOffset 200 response + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(GetUploadOffset)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.GetUploadOffset.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.GetUploadOffset.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/400/content/application\/json`. + case json(Components.Schemas.StorageErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.GetUploadOffset.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.GetUploadOffset.Output.BadRequest.Body) { + self.body = body + } + } + /// StorageError 400 response + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(GetUploadOffset)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.GetUploadOffset.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.GetUploadOffset.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } } diff --git a/smithy/model/storage.smithy b/smithy/model/storage.smithy index b512458ea..13fd406e0 100644 --- a/smithy/model/storage.smithy +++ b/smithy/model/storage.smithy @@ -25,6 +25,9 @@ service StorageService { CreateSignedUrl CreateSignedUrls CreateSignedUploadUrl + CreateTusUpload + UploadChunk + GetUploadOffset ] errors: [StorageError] } @@ -291,6 +294,113 @@ structure CreateSignedUploadUrlOutput { @required url: String } +// ─── TUS Resumable Upload Operations ─────────────────────────────────────── +// +// Models the three HTTP operations of the TUS 1.0.0 protocol. The application- +// level state machine (chunk sequencing, 409 retry, pause/resume) is NOT +// generated — it lives in TUSUploadEngine, which calls these operations. + +/// Step 1: Create a new TUS upload session. +/// The server responds with a Location header containing the upload URL. +@http(method: "POST", uri: "/upload/resumable", code: 201) +operation CreateTusUpload { + input: CreateTusUploadInput + output: CreateTusUploadOutput + errors: [StorageError] +} + +structure CreateTusUploadInput { + /// Total size of the file in bytes. + @httpHeader("Upload-Length") + @required + uploadLength: Long + + /// Base64-encoded TUS metadata (bucketName, objectName, contentType, cacheControl). + @httpHeader("Upload-Metadata") + @required + uploadMetadata: String + + @httpHeader("Tus-Resumable") + @required + tusResumable: String + + /// Set to "true" to overwrite an existing object at the same path. + @httpHeader("x-upsert") + upsert: String +} + +structure CreateTusUploadOutput { + /// Full URL of the created upload session. Used in subsequent PATCH/HEAD requests. + @httpHeader("Location") + @required + location: String +} + +/// Step 2: Upload a chunk of data to an existing TUS session. +/// Repeat with increasing Upload-Offset until all bytes are sent. +@http(method: "PATCH", uri: "/upload/resumable/{uploadId}", code: 204) +@suppress(["HttpMethodSemantics.UnexpectedPayload"]) +operation UploadChunk { + input: UploadChunkInput + output: UploadChunkOutput + errors: [StorageError] +} + +@streaming +blob ChunkBody + +structure UploadChunkInput { + @httpLabel + @required + uploadId: String + + /// Byte offset at which this chunk begins. + @httpHeader("Upload-Offset") + @required + uploadOffset: Long + + @httpHeader("Tus-Resumable") + @required + tusResumable: String + + /// Raw chunk bytes, streamed directly — never buffered. + @httpPayload + @required + body: ChunkBody +} + +structure UploadChunkOutput { + /// New server-side offset after the chunk was accepted. + @httpHeader("Upload-Offset") + @required + uploadOffset: Long +} + +/// Step 3: Query the server-side offset of a TUS session (used when resuming). +@http(method: "HEAD", uri: "/upload/resumable/{uploadId}", code: 200) +@readonly +operation GetUploadOffset { + input: GetUploadOffsetInput + output: GetUploadOffsetOutput + errors: [StorageError] +} + +structure GetUploadOffsetInput { + @httpLabel + @required + uploadId: String + + @httpHeader("Tus-Resumable") + @required + tusResumable: String +} + +structure GetUploadOffsetOutput { + @httpHeader("Upload-Offset") + @required + uploadOffset: Long +} + // ─── Shared Shapes ───────────────────────────────────────────────────────── structure Bucket { diff --git a/smithy/output/openapi/StorageService.openapi.json b/smithy/output/openapi/StorageService.openapi.json index 9f9470727..0e40c0007 100644 --- a/smithy/output/openapi/StorageService.openapi.json +++ b/smithy/output/openapi/StorageService.openapi.json @@ -736,6 +736,190 @@ } } } + }, + "/upload/resumable": { + "post": { + "description": "Step 1: Create a new TUS upload session.\nThe server responds with a Location header containing the upload URL.", + "operationId": "CreateTusUpload", + "parameters": [ + { + "name": "Tus-Resumable", + "in": "header", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "Upload-Length", + "in": "header", + "description": "Total size of the file in bytes.", + "schema": { + "type": "number", + "description": "Total size of the file in bytes." + }, + "required": true + }, + { + "name": "Upload-Metadata", + "in": "header", + "description": "Base64-encoded TUS metadata (bucketName, objectName, contentType, cacheControl).", + "schema": { + "type": "string", + "description": "Base64-encoded TUS metadata (bucketName, objectName, contentType, cacheControl)." + }, + "required": true + }, + { + "name": "x-upsert", + "in": "header", + "description": "Set to \"true\" to overwrite an existing object at the same path.", + "schema": { + "type": "string", + "description": "Set to \"true\" to overwrite an existing object at the same path." + } + } + ], + "responses": { + "201": { + "description": "CreateTusUpload 201 response", + "headers": { + "Location": { + "description": "Full URL of the created upload session. Used in subsequent PATCH/HEAD requests.", + "schema": { + "type": "string", + "description": "Full URL of the created upload session. Used in subsequent PATCH/HEAD requests." + }, + "required": true + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } + }, + "/upload/resumable/{uploadId}": { + "head": { + "description": "Step 3: Query the server-side offset of a TUS session (used when resuming).", + "operationId": "GetUploadOffset", + "parameters": [ + { + "name": "uploadId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "Tus-Resumable", + "in": "header", + "schema": { + "type": "string" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "GetUploadOffset 200 response", + "headers": { + "Upload-Offset": { + "schema": { + "type": "number" + }, + "required": true + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + }, + "patch": { + "description": "Step 2: Upload a chunk of data to an existing TUS session.\nRepeat with increasing Upload-Offset until all bytes are sent.", + "operationId": "UploadChunk", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/UploadChunkInputPayload" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "uploadId", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "Tus-Resumable", + "in": "header", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "Upload-Offset", + "in": "header", + "description": "Byte offset at which this chunk begins.", + "schema": { + "type": "number", + "description": "Byte offset at which this chunk begins." + }, + "required": true + } + ], + "responses": { + "204": { + "description": "UploadChunk 204 response", + "headers": { + "Upload-Offset": { + "description": "New server-side offset after the chunk was accepted.", + "schema": { + "type": "number", + "description": "New server-side offset after the chunk was accepted." + }, + "required": true + } + } + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StorageErrorResponseContent" + } + } + } + } + } + } } }, "components": { @@ -1178,6 +1362,11 @@ "public" ] }, + "UploadChunkInputPayload": { + "type": "string", + "description": "Raw chunk bytes, streamed directly \u2014 never buffered.", + "format": "binary" + }, "FileUploadedResponse": { "type": "object", "properties": { diff --git a/smithy/patch-openapi.py b/smithy/patch-openapi.py new file mode 100644 index 000000000..e75cda342 --- /dev/null +++ b/smithy/patch-openapi.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +""" +Post-process the Smithy-generated OpenAPI JSON with patches that Smithy +cannot express natively: + +1. UploadChunk body: format: byte → format: binary + (@streaming blob translates to format:byte but swift-openapi-generator + needs format:binary to emit HTTPBody instead of Base64EncodedData) + +2. UploadObject (POST) and UpdateObject (PUT) with multipart/form-data + (Smithy has no native multipart/form-data trait; these are authored here) +""" +import json +import sys + +path = sys.argv[1] if len(sys.argv) > 1 else "output/openapi/StorageService.openapi.json" + +with open(path) as f: + d = json.load(f) + +# ── Patch 1: streaming blob → binary ───────────────────────────────────── +schema = d["components"]["schemas"].get("UploadChunkInputPayload", {}) +if schema.get("format") == "byte": + schema["format"] = "binary" + +# ── Patch 2: multipart upload/update operations ─────────────────────────── +d["components"]["schemas"]["FileUploadedResponse"] = { + "type": "object", + "properties": { + "Key": {"type": "string"}, + "Id": {"type": "string", "format": "uuid"}, + }, + "required": ["Key", "Id"], +} + +upload_form_schema = { + "type": "object", + "properties": { + "cacheControl": {"type": "string"}, + "metadata": {"type": "object", "additionalProperties": True}, + "file": {"type": "string", "format": "binary"}, + }, + "required": ["file"], +} + +upload_responses = { + "200": { + "description": "Upload successful", + "content": { + "application/json": { + "schema": {"$ref": "#/components/schemas/FileUploadedResponse"} + } + }, + }, + "400": { + "description": "StorageError 400 response", + "content": { + "application/json": { + "schema": {"$ref": "#/components/schemas/StorageErrorResponseContent"} + } + }, + }, +} + +wildcard_path = "/object/{bucketId}/{wildcardPath+}" +d["paths"][wildcard_path]["post"] = { + "operationId": "UploadObject", + "parameters": [ + {"name": "bucketId", "in": "path", "schema": {"type": "string"}, "required": True}, + {"name": "wildcardPath+", "in": "path", "schema": {"type": "string"}, "required": True}, + {"name": "x-upsert", "in": "header", "schema": {"type": "string"}, "required": False}, + ], + "requestBody": { + "required": True, + "content": {"multipart/form-data": {"schema": upload_form_schema}}, + }, + "responses": upload_responses, +} + +d["paths"][wildcard_path]["put"] = { + "operationId": "UpdateObject", + "parameters": [ + {"name": "bucketId", "in": "path", "schema": {"type": "string"}, "required": True}, + {"name": "wildcardPath+", "in": "path", "schema": {"type": "string"}, "required": True}, + ], + "requestBody": { + "required": True, + "content": {"multipart/form-data": {"schema": upload_form_schema}}, + }, + "responses": upload_responses, +} + +with open(path, "w") as f: + json.dump(d, f, indent=2) From 4039867981e76c44d231d7571927aa2df6af3b02 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 12:10:21 -0300 Subject: [PATCH 22/32] spike(storage): wire generated client into upload/update/TUS methods Replace MultipartUploadEngine.makeTask in upload/update methods with direct calls to client.generatedClient.UploadObject / UpdateObject. Replace hand-rolled URLRequest HTTP in TUSUploadEngine with CreateTusUpload / GetUploadOffset / UploadChunk generated operations. Delete the spike helper file StorageFileApi+GeneratedUpload.swift. --- Sources/Storage/StorageFileAPI.swift | 234 +++++++++++++++++- .../StorageFileApi+GeneratedUpload.swift | 198 --------------- Sources/Storage/TUSUploadEngine.swift | 156 ++++++------ 3 files changed, 298 insertions(+), 290 deletions(-) delete mode 100644 Sources/Storage/StorageFileApi+GeneratedUpload.swift diff --git a/Sources/Storage/StorageFileAPI.swift b/Sources/Storage/StorageFileAPI.swift index 1bc085445..0dbdb3bd3 100644 --- a/Sources/Storage/StorageFileAPI.swift +++ b/Sources/Storage/StorageFileAPI.swift @@ -1,5 +1,6 @@ import Foundation import Helpers +import OpenAPIRuntime import XCTestDynamicOverlay #if canImport(FoundationNetworking) @@ -150,8 +151,15 @@ public struct StorageFileAPI: Sendable { return TUSUploadEngine.makeTask( bucketId: bucketId, path: path, source: .data(data), options: options, client: client) } else { - return MultipartUploadEngine.makeTask( - bucketId: bucketId, path: path, source: .data(data), options: options, client: client) + return generatedUploadTask(path: path) { + let parts = self.buildUploadParts(data: data, options: options) + let output = try await self.client.generatedClient.UploadObject( + path: .init(bucketId: self.bucketId, wildcardPath_plus_: path), + headers: .init(x_hyphen_upsert: options.upsert ? "true" : nil), + body: .multipartForm(MultipartBody(parts)) + ) + return try self.extractUploadedResponse(from: output) + } } } @@ -201,8 +209,15 @@ public struct StorageFileAPI: Sendable { return TUSUploadEngine.makeTask( bucketId: bucketId, path: path, source: .fileURL(fileURL), options: options, client: client) } else { - return MultipartUploadEngine.makeTask( - bucketId: bucketId, path: path, source: .fileURL(fileURL), options: options, client: client) + return generatedUploadTask(path: path) { + let parts = self.buildUploadParts(fileURL: fileURL, options: options) + let output = try await self.client.generatedClient.UploadObject( + path: .init(bucketId: self.bucketId, wildcardPath_plus_: path), + headers: .init(x_hyphen_upsert: options.upsert ? "true" : nil), + body: .multipartForm(MultipartBody(parts)) + ) + return try self.extractUploadedResponse(from: output) + } } } @@ -233,9 +248,14 @@ public struct StorageFileAPI: Sendable { data: Data, options: FileOptions = FileOptions() ) -> StorageUploadTask { - MultipartUploadEngine.makeTask( - bucketId: bucketId, path: path, source: .data(data), options: options, - httpMethod: .put, client: client) + return generatedUploadTask(path: path) { + let parts = self.buildUpdateParts(data: data, options: options) + let output = try await self.client.generatedClient.UpdateObject( + path: .init(bucketId: self.bucketId, wildcardPath_plus_: path), + body: .multipartForm(MultipartBody(parts)) + ) + return try self.extractUpdatedResponse(from: output) + } } /// Replaces an existing file at the specified path with the contents of a local `URL`. @@ -265,9 +285,14 @@ public struct StorageFileAPI: Sendable { fileURL: URL, options: FileOptions = FileOptions() ) -> StorageUploadTask { - MultipartUploadEngine.makeTask( - bucketId: bucketId, path: path, source: .fileURL(fileURL), options: options, - httpMethod: .put, client: client) + return generatedUploadTask(path: path) { + let parts = self.buildUpdateParts(fileURL: fileURL, options: options) + let output = try await self.client.generatedClient.UpdateObject( + path: .init(bucketId: self.bucketId, wildcardPath_plus_: path), + body: .multipartForm(MultipartBody(parts)) + ) + return try self.extractUpdatedResponse(from: output) + } } /// Moves an existing file to a new path within the same or a different bucket. @@ -1143,6 +1168,195 @@ public struct StorageFileAPI: Sendable { let trimmed = path.hasPrefix("/") ? String(path.dropFirst()) : path return "\(bucketId)/\(trimmed)" } + + // MARK: - Generated client helpers + + private func generatedUploadTask( + path: String, + operation: @Sendable @escaping () async throws -> FileUploadResponse + ) -> StorageUploadTask { + let (eventStream, _) = AsyncStream>.makeStream() + let resultTask = Task { + try await operation() + } + return StorageUploadTask( + events: eventStream, + resultTask: resultTask, + pause: {}, + resume: {}, + cancel: { resultTask.cancel() } + ) + } + + private func buildUploadParts( + data: Data, + options: FileOptions + ) -> [Operations.UploadObject.Input.Body.multipartFormPayload] { + typealias Part = Operations.UploadObject.Input.Body.multipartFormPayload + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: HTTPBody(data)), filename: nil))) + return parts + } + + private func buildUploadParts( + fileURL: URL, + options: FileOptions + ) -> [Operations.UploadObject.Input.Body.multipartFormPayload] { + typealias Part = Operations.UploadObject.Input.Body.multipartFormPayload + let fileSize = (try? fileURL.resourceValues(forKeys: [.fileSizeKey]).fileSize).flatMap { + Int64($0) + } + let length: HTTPBody.Length = fileSize.map { .known($0) } ?? .unknown + let chunkSize = 65_536 + let fileBody = HTTPBody( + AsyncStream> { continuation in + Task { + guard let handle = try? FileHandle(forReadingFrom: fileURL) else { + continuation.finish() + return + } + defer { try? handle.close() } + while true { + let chunk = handle.readData(ofLength: chunkSize) + if chunk.isEmpty { break } + continuation.yield(ArraySlice(chunk)) + } + continuation.finish() + } + }, + length: length, + iterationBehavior: .single + ) + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: fileBody), filename: nil))) + return parts + } + + private func buildUpdateParts( + data: Data, + options: FileOptions + ) -> [Operations.UpdateObject.Input.Body.multipartFormPayload] { + typealias Part = Operations.UpdateObject.Input.Body.multipartFormPayload + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: HTTPBody(data)), filename: nil))) + return parts + } + + private func buildUpdateParts( + fileURL: URL, + options: FileOptions + ) -> [Operations.UpdateObject.Input.Body.multipartFormPayload] { + typealias Part = Operations.UpdateObject.Input.Body.multipartFormPayload + let fileSize = (try? fileURL.resourceValues(forKeys: [.fileSizeKey]).fileSize).flatMap { + Int64($0) + } + let length: HTTPBody.Length = fileSize.map { .known($0) } ?? .unknown + let chunkSize = 65_536 + let fileBody = HTTPBody( + AsyncStream> { continuation in + Task { + guard let handle = try? FileHandle(forReadingFrom: fileURL) else { + continuation.finish() + return + } + defer { try? handle.close() } + while true { + let chunk = handle.readData(ofLength: chunkSize) + if chunk.isEmpty { break } + continuation.yield(ArraySlice(chunk)) + } + continuation.finish() + } + }, + length: length, + iterationBehavior: .single + ) + var parts: [Part] = [ + .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) + ] + if let metadata = options.metadata, + let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) + { + parts.append( + .metadata( + .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) + } + parts.append(.file(.init(payload: .init(body: fileBody), filename: nil))) + return parts + } + + private func extractUploadedResponse( + from output: Operations.UploadObject.Output + ) throws -> FileUploadResponse { + switch output { + case .ok(let ok): + switch ok.body { + case .json(let body): + return FileUploadResponse( + id: UUID(uuidString: body.Id) ?? UUID(), + path: body.Key, + fullPath: body.Key + ) + } + case .badRequest(let err): + switch err.body { + case .json(let body): + throw StorageError(message: body.message ?? "Upload failed", errorCode: .unknown) + } + case .undocumented(let code, _): + throw StorageError(message: "HTTP \(code)", errorCode: .unknown) + } + } + + private func extractUpdatedResponse( + from output: Operations.UpdateObject.Output + ) throws -> FileUploadResponse { + switch output { + case .ok(let ok): + switch ok.body { + case .json(let body): + return FileUploadResponse( + id: UUID(uuidString: body.Id) ?? UUID(), + path: body.Key, + fullPath: body.Key + ) + } + case .badRequest(let err): + switch err.body { + case .json(let body): + throw StorageError(message: body.message ?? "Update failed", errorCode: .unknown) + } + case .undocumented(let code, _): + throw StorageError(message: "HTTP \(code)", errorCode: .unknown) + } + } } func _removeEmptyFolders(_ path: String) -> String { diff --git a/Sources/Storage/StorageFileApi+GeneratedUpload.swift b/Sources/Storage/StorageFileApi+GeneratedUpload.swift deleted file mode 100644 index 047918883..000000000 --- a/Sources/Storage/StorageFileApi+GeneratedUpload.swift +++ /dev/null @@ -1,198 +0,0 @@ -// -// StorageFileApi+GeneratedUpload.swift -// Storage -// -// SPIKE — demonstrates how the generated multipart client handles streaming -// uploads. The file part is backed by an AsyncStream of 64 KB chunks from -// FileHandle, so the file is never fully buffered in memory. -// -// TUS (resumable) uploads are NOT covered here — the TUS state machine -// cannot be expressed in standard OpenAPI and stays hand-written. -// -// Content-Type limitation: the generated serializer hardcodes -// "application/octet-stream" for the file part. Passing a custom MIME type -// requires a raw MultipartRawPart, which is left as a follow-up. -// - -import Foundation -import OpenAPIRuntime - -extension StorageFileAPI { - - // MARK: - Upload (POST) via generated client - - /// Upload `data` to `path` using the generated multipart client. - func uploadViaGeneratedClient( - _ path: String, - data: Data, - options: FileOptions = FileOptions(), - upsert: Bool = false - ) async throws -> FileUploadedResponse { - let (bucketId, objectPath) = splitPath(path) - typealias Part = Operations.UploadObject.Input.Body.multipartFormPayload - - var parts: [Part] = [ - .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) - ] - if let metadata = options.metadata, - let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) - { - parts.append( - .metadata( - .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) - } - parts.append(.file(.init(payload: .init(body: HTTPBody(data)), filename: nil))) - - let output = try await client.generatedClient.UploadObject( - path: .init(bucketId: bucketId, wildcardPath_plus_: objectPath), - headers: .init(x_hyphen_upsert: upsert ? "true" : nil), - body: .multipartForm(MultipartBody(parts)) - ) - switch output { - case .ok(let ok): - switch ok.body { - case .json(let body): return FileUploadedResponse(key: body.Key, id: body.Id) - } - case .badRequest(let err): - switch err.body { - case .json(let body): - throw URLError( - .unknown, userInfo: [NSLocalizedDescriptionKey: body.message ?? "Unknown error"]) - } - case .undocumented(let code, _): - throw URLError(.unknown, userInfo: [NSLocalizedDescriptionKey: "HTTP \(code)"]) - } - } - - /// Upload a file at `fileURL` streaming in 64 KB chunks. - func uploadViaGeneratedClient( - _ path: String, - fileURL: URL, - options: FileOptions = FileOptions(), - upsert: Bool = false - ) async throws -> FileUploadedResponse { - let (bucketId, objectPath) = splitPath(path) - typealias Part = Operations.UploadObject.Input.Body.multipartFormPayload - - let fileSize = (try? fileURL.resourceValues(forKeys: [.fileSizeKey]).fileSize).flatMap { - Int64($0) - } - let length: HTTPBody.Length = fileSize.map { .known($0) } ?? .unknown - let fileBody = chunkedBody(from: fileURL, length: length) - - var parts: [Part] = [ - .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) - ] - if let metadata = options.metadata, - let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) - { - parts.append( - .metadata( - .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) - } - parts.append(.file(.init(payload: .init(body: fileBody), filename: nil))) - - let output = try await client.generatedClient.UploadObject( - path: .init(bucketId: bucketId, wildcardPath_plus_: objectPath), - headers: .init(x_hyphen_upsert: upsert ? "true" : nil), - body: .multipartForm(MultipartBody(parts)) - ) - switch output { - case .ok(let ok): - switch ok.body { - case .json(let body): return FileUploadedResponse(key: body.Key, id: body.Id) - } - case .badRequest(let err): - switch err.body { - case .json(let body): - throw URLError( - .unknown, userInfo: [NSLocalizedDescriptionKey: body.message ?? "Unknown error"]) - } - case .undocumented(let code, _): - throw URLError(.unknown, userInfo: [NSLocalizedDescriptionKey: "HTTP \(code)"]) - } - } - - // MARK: - Update (PUT) via generated client - - /// Overwrite the object at `path` using the generated multipart client. - func updateViaGeneratedClient( - _ path: String, - data: Data, - options: FileOptions = FileOptions() - ) async throws -> FileUploadedResponse { - let (bucketId, objectPath) = splitPath(path) - typealias Part = Operations.UpdateObject.Input.Body.multipartFormPayload - - var parts: [Part] = [ - .cacheControl(.init(payload: .init(body: HTTPBody(options.cacheControl)), filename: nil)) - ] - if let metadata = options.metadata, - let container = try? OpenAPIObjectContainer(unvalidatedValue: metadata) - { - parts.append( - .metadata( - .init(payload: .init(body: .init(additionalProperties: container)), filename: nil))) - } - parts.append(.file(.init(payload: .init(body: HTTPBody(data)), filename: nil))) - - let output = try await client.generatedClient.UpdateObject( - path: .init(bucketId: bucketId, wildcardPath_plus_: objectPath), - body: .multipartForm(MultipartBody(parts)) - ) - switch output { - case .ok(let ok): - switch ok.body { - case .json(let body): return FileUploadedResponse(key: body.Key, id: body.Id) - } - case .badRequest(let err): - switch err.body { - case .json(let body): - throw URLError( - .unknown, userInfo: [NSLocalizedDescriptionKey: body.message ?? "Unknown error"]) - } - case .undocumented(let code, _): - throw URLError(.unknown, userInfo: [NSLocalizedDescriptionKey: "HTTP \(code)"]) - } - } - - // MARK: - Private helpers - - private func splitPath(_ path: String) -> (bucketId: String, objectPath: String) { - let components = path.split(separator: "/", maxSplits: 1, omittingEmptySubsequences: false) - return ( - components.first.map(String.init) ?? "", - components.dropFirst().first.map(String.init) ?? "" - ) - } - - /// Wraps a file URL in an HTTPBody that streams 64 KB chunks via FileHandle. - private func chunkedBody(from url: URL, length: HTTPBody.Length) -> HTTPBody { - let chunkSize = 65_536 - return HTTPBody( - AsyncStream> { continuation in - Task { - guard let handle = try? FileHandle(forReadingFrom: url) else { - continuation.finish() - return - } - defer { try? handle.close() } - while true { - let chunk = handle.readData(ofLength: chunkSize) - if chunk.isEmpty { break } - continuation.yield(ArraySlice(chunk)) - } - continuation.finish() - } - }, - length: length, - iterationBehavior: .single - ) - } -} - -/// Return value from upload/update operations. -public struct FileUploadedResponse: Sendable { - public let key: String - public let id: String? -} diff --git a/Sources/Storage/TUSUploadEngine.swift b/Sources/Storage/TUSUploadEngine.swift index 6054aadd2..84c837ef6 100644 --- a/Sources/Storage/TUSUploadEngine.swift +++ b/Sources/Storage/TUSUploadEngine.swift @@ -7,6 +7,7 @@ import Foundation import Helpers +import OpenAPIRuntime #if canImport(FoundationNetworking) import FoundationNetworking @@ -177,47 +178,49 @@ actor TUSUploadEngine { // MARK: - TUS protocol private func createUpload(totalBytes: Int64) async throws -> URL { - var request = try await makeRequest( - url: client.url.appendingPathComponent("upload/resumable"), - method: .post - ) - request.setValue("1.0.0", forHTTPHeaderField: "Tus-Resumable") - request.setValue("\(totalBytes)", forHTTPHeaderField: "Upload-Length") - request.setValue(tusMetadata(), forHTTPHeaderField: "Upload-Metadata") - request.setValue("0", forHTTPHeaderField: "Content-Length") - if options.upsert { - request.setValue("true", forHTTPHeaderField: "x-upsert") - } - - let (_, response) = try await client.http.session.data(for: request) - guard let httpResponse = response as? HTTPURLResponse else { - throw StorageError(message: "Invalid response", errorCode: .unknown) - } - guard httpResponse.statusCode == 201, - let location = httpResponse.value(forHTTPHeaderField: "Location"), - let locationURL = URL(string: location) - else { - throw StorageError( - message: "TUS create failed", - errorCode: .unknown, - statusCode: httpResponse.statusCode + let output = try await client.generatedClient.CreateTusUpload( + headers: .init( + Tus_hyphen_Resumable: "1.0.0", + Upload_hyphen_Length: Double(totalBytes), + Upload_hyphen_Metadata: tusMetadata(), + x_hyphen_upsert: options.upsert ? "true" : nil ) + ) + switch output { + case .created(let created): + guard let locationURL = URL(string: created.headers.Location) else { + throw StorageError(message: "TUS create: invalid Location header", errorCode: .unknown) + } + return locationURL + case .badRequest(let err): + switch err.body { + case .json(let body): + throw StorageError(message: body.message ?? "TUS create failed", errorCode: .unknown) + } + case .undocumented(let code, _): + throw StorageError(message: "TUS create HTTP \(code)", errorCode: .unknown) } - return locationURL } private func fetchOffset(uploadURL: URL) async throws -> Int64 { - var request = try await makeRequest(url: uploadURL, method: .head) - request.setValue("1.0.0", forHTTPHeaderField: "Tus-Resumable") - - let (_, response) = try await client.http.session.data(for: request) - guard let httpResponse = response as? HTTPURLResponse, - let offsetString = httpResponse.value(forHTTPHeaderField: "Upload-Offset"), - let offset = Int64(offsetString) - else { - throw StorageError(message: "TUS HEAD failed", errorCode: .unknown) + guard let uploadId = uploadURL.pathComponents.last, !uploadId.isEmpty else { + throw StorageError(message: "Invalid upload URL", errorCode: .unknown) + } + let output = try await client.generatedClient.GetUploadOffset( + path: .init(uploadId: uploadId), + headers: .init(Tus_hyphen_Resumable: "1.0.0") + ) + switch output { + case .ok(let ok): + return Int64(ok.headers.Upload_hyphen_Offset) + case .badRequest(let err): + switch err.body { + case .json(let body): + throw StorageError(message: body.message ?? "TUS HEAD failed", errorCode: .unknown) + } + case .undocumented(let code, _): + throw StorageError(message: "TUS HEAD HTTP \(code)", errorCode: .unknown) } - return offset } private func uploadChunks(to uploadURL: URL, from startOffset: Int64, totalBytes: Int64) @@ -242,53 +245,46 @@ actor TUSUploadEngine { ) } - var request = try await makeRequest(url: uploadURL, method: .patch) - request.setValue("1.0.0", forHTTPHeaderField: "Tus-Resumable") - request.setValue("\(offset)", forHTTPHeaderField: "Upload-Offset") - request.setValue("application/offset+octet-stream", forHTTPHeaderField: "Content-Type") - // Content-Length is set automatically by URLSession.upload(for:from:) - - let (_, response) = try await client.http.session.upload(for: request, from: chunk) - guard let httpResponse = response as? HTTPURLResponse else { - throw StorageError(message: "Invalid PATCH response", errorCode: .unknown) - } + let uploadId = uploadURL.pathComponents.last ?? "" + let patchOutput = try await client.generatedClient.UploadChunk( + path: .init(uploadId: uploadId), + headers: .init( + Tus_hyphen_Resumable: "1.0.0", + Upload_hyphen_Offset: Double(offset) + ), + body: .binary(HTTPBody(chunk)) + ) - if httpResponse.statusCode == 409 { - consecutive409s += 1 - // TUS spec does not define a retry limit; guard against a misbehaving server - // that permanently rejects our offset by capping consecutive 409 resyncs. - guard consecutive409s <= 3 else { - throw StorageError( - message: "TUS upload stalled: server returned 409 four times in a row", - errorCode: .unknown) + switch patchOutput { + case .noContent(let noContent): + consecutive409s = 0 + offset = Int64(noContent.headers.Upload_hyphen_Offset) + case .badRequest(let err): + switch err.body { + case .json(let body): + throw StorageError(message: body.message ?? "TUS PATCH failed", errorCode: .unknown) } - let serverOffset = try await fetchOffset(uploadURL: uploadURL) - offset = serverOffset - // The server may report offset == totalBytes (file already fully uploaded). - // Break so the post-loop completion block handles it instead of re-entering - // the loop body with a zero-length chunk. - if offset >= totalBytes { break } - continue - } - - guard httpResponse.statusCode == 200 || httpResponse.statusCode == 204 else { - throw StorageError( - message: "TUS PATCH failed", - errorCode: .unknown, - statusCode: httpResponse.statusCode - ) - } - - guard - let newOffsetString = httpResponse.value(forHTTPHeaderField: "Upload-Offset"), - let newOffset = Int64(newOffsetString) - else { - throw StorageError(message: "Missing Upload-Offset in PATCH response", errorCode: .unknown) + case .undocumented(let statusCode, _): + if statusCode == 409 { + consecutive409s += 1 + // TUS spec does not define a retry limit; guard against a misbehaving server + // that permanently rejects our offset by capping consecutive 409 resyncs. + guard consecutive409s <= 3 else { + throw StorageError( + message: "TUS upload stalled: server returned 409 four times in a row", + errorCode: .unknown) + } + let serverOffset = try await fetchOffset(uploadURL: uploadURL) + offset = serverOffset + // The server may report offset == totalBytes (file already fully uploaded). + // Break so the post-loop completion block handles it instead of re-entering + // the loop body with a zero-length chunk. + if offset >= totalBytes { break } + continue + } + throw StorageError(message: "TUS PATCH HTTP \(statusCode)", errorCode: .unknown) } - consecutive409s = 0 - offset = newOffset - eventsContinuation.yield( .progress( TransferProgress( @@ -320,10 +316,6 @@ actor TUSUploadEngine { // MARK: - Helpers - private func makeRequest(url: URL, method: HTTPMethod) async throws -> URLRequest { - try await client.http.createRequest(method, url: url, headers: client.mergedHeaders()) - } - // The upload URL last path component is base64("{bucket}/{path}/{uuid}"). // Extract the UUID so it can be included in the FileUploadResponse. private func extractUploadId(from uploadURL: URL) -> UUID? { From be1f5af119aabe8998d3e13336e6cecef927a137 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 12:27:35 -0300 Subject: [PATCH 23/32] spike(functions): supersede _HTTPClient with generated client entirely MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the hand-written _HTTPClient path from FunctionsClient. Both invoke() and invokeStream() now go exclusively through the generated InvokeFunction operation. invokeStream() bridges the HTTPBody AsyncSequence from the generated response body to AsyncThrowingStream with no intermediate buffering — bytes are forwarded chunk-by-chunk as they arrive. Spike limitations (documented in class-level doc comment): - POST-only: FunctionInvokeOptions.method / .query not forwarded - HTTPURLResponse is fabricated (status code only, no headers) --- Sources/Functions/FunctionsClient.swift | 330 ++++++------------------ 1 file changed, 75 insertions(+), 255 deletions(-) diff --git a/Sources/Functions/FunctionsClient.swift b/Sources/Functions/FunctionsClient.swift index 2e4f1e02a..b24f62243 100644 --- a/Sources/Functions/FunctionsClient.swift +++ b/Sources/Functions/FunctionsClient.swift @@ -1,4 +1,3 @@ -import ConcurrencyExtras import Foundation import Helpers import OpenAPIRuntime @@ -36,69 +35,36 @@ let version = Helpers.version /// /// When used via ``SupabaseClient``, authentication tokens are automatically refreshed and injected /// into every request. You do not need to manage ``setAuth(token:)`` manually in that case. +/// +/// ## Spike limitations +/// +/// The generated client is POST-only. `FunctionInvokeOptions.method` and +/// `FunctionInvokeOptions.query` are accepted by the API for future compatibility but are not +/// forwarded to the server in this spike implementation. The Smithy model needs to be extended +/// to support custom HTTP methods and query parameters. +/// +/// The `HTTPURLResponse` returned by `invoke` is fabricated (status code only, no headers), +/// because the generated `ClientMiddleware` layer does not yet expose per-request response headers +/// to the caller. This is a known limitation. public actor FunctionsClient { /// The maximum time an Edge Function may be idle before the gateway returns a 504. - /// - /// Supabase enforces a 150-second request idle timeout for Edge Functions. The client - /// configures the underlying `URLSession` with this value so local timeouts align with - /// the server-side limit. - /// - /// See: https://supabase.com/docs/guides/functions/limits public static let requestIdleTimeout: TimeInterval = 150 /// The base URL used to build per-function request URLs. - /// - /// Individual function URLs are formed by appending the function name to this URL, - /// e.g. `https://.supabase.co/functions/v1/my-function`. public let url: URL /// The default region in which functions are invoked. - /// - /// Per-invocation overrides via ``FunctionInvokeOptions/region`` take - /// precedence over this value. Pass `nil` to let Supabase route to the nearest region - /// automatically. public let region: FunctionRegion? /// The JSON decoder used to decode response bodies in ``invokeDecodable(_:as:decoder:options:)``. - /// - /// Per-call override is also available via the `decoder` - /// parameter of ``invokeDecodable(_:as:decoder:options:)``. public let decoder: JSONDecoder /// The HTTP headers sent with every request. - /// - /// Per-invocation headers supplied via ``FunctionInvokeOptions/headers`` are merged on - /// top of these values, with the per-invocation values winning on collision. public private(set) var headers: [String: String] = [:] - private let http: _HTTPClient - private let generatedClient: Client? + private let generatedClient: Client /// Creates a `FunctionsClient` for standalone use (without a ``SupabaseClient``). - /// - /// Use this initialiser when you want to call Edge Functions independently, without the - /// broader Supabase client stack. For most apps you should create a ``SupabaseClient`` and - /// access its `functions` property instead. - /// - /// - Parameters: - /// - url: The base URL for the functions endpoint, - /// e.g. `https://.supabase.co/functions/v1`. - /// - headers: Additional headers included in every request. Defaults to an empty dictionary. - /// An `X-Client-Info` header is always added automatically. - /// - region: The default region to invoke functions in. Defaults to `nil` (automatic routing). - /// - session: The `URLSession` used to perform HTTP requests. Defaults to a new session with - /// ``requestIdleTimeout`` applied to `timeoutIntervalForRequest`. - /// - decoder: The `JSONDecoder` used by ``invokeDecodable(_:as:decoder:options:)``. - /// Defaults to `JSONDecoder()`. - /// - /// ## Example - /// - /// ```swift - /// let functions = FunctionsClient( - /// url: URL(string: "https://.supabase.co/functions/v1")!, - /// headers: ["apikey": "", "Authorization": "Bearer "] - /// ) - /// ``` public init( url: URL, headers: [String: String] = [:], @@ -128,11 +94,6 @@ public actor FunctionsClient { self.region = region self.decoder = decoder session.configuration.timeoutIntervalForRequest = Self.requestIdleTimeout - self.http = _HTTPClient( - host: url, - session: session, - tokenProvider: tokenProvider - ) let transport = URLSessionTransport(configuration: .init(session: session)) let middleware = SupabaseMiddleware(headers: headers, tokenProvider: tokenProvider) generatedClient = Client( @@ -146,14 +107,7 @@ public actor FunctionsClient { } } - /// Creates a `FunctionsClient` backed by the generated OpenAPI client for testing. - /// - /// - Parameters: - /// - url: The base URL for the functions endpoint. - /// - headers: Additional headers included in every request. - /// - region: The default region to invoke functions in. - /// - transport: A `ClientTransport` used by the generated client (e.g. `MockTransport` in tests). - /// - decoder: The `JSONDecoder` used by `invokeDecodable`. + /// Creates a `FunctionsClient` backed by a custom transport (e.g. `MockTransport` in tests). package init( url: URL, headers: [String: String] = [:], @@ -164,7 +118,6 @@ public actor FunctionsClient { self.url = url self.region = region self.decoder = decoder - self.http = _HTTPClient(host: url) self.generatedClient = Client(serverURL: url, transport: transport) self.headers = headers if self.headers["X-Client-Info"] == nil { @@ -173,25 +126,6 @@ public actor FunctionsClient { } /// Updates the `Authorization` header used for subsequent requests. - /// - /// Pass a JWT to attach a `Bearer` token, or `nil` to remove the header entirely (e.g. for - /// public functions that don't require authentication). - /// - /// When using ``SupabaseClient``, this method is called automatically whenever the - /// authenticated session changes — you do not need to call it yourself. - /// - /// - Parameter token: A JWT access token, or `nil` to clear the authorization header. - /// - /// ## Example - /// - /// ```swift - /// // Attach a token before invoking a protected function - /// await functions.setAuth(token: session.accessToken) - /// let (data, _) = try await functions.invoke("protected-function") - /// - /// // Remove the token for a public function call - /// await functions.setAuth(token: nil) - /// ``` public func setAuth(token: String?) { if let token { headers["Authorization"] = "Bearer \(token)" @@ -201,33 +135,6 @@ public actor FunctionsClient { } /// Invokes a function and decodes the JSON response body into the inferred `Decodable` type. - /// - /// The response body is decoded using the `decoder` parameter if provided, otherwise the - /// instance-level ``decoder`` is used. - /// - /// - Parameters: - /// - functionName: The name of the Edge Function to invoke. - /// - decoder: An optional `JSONDecoder` to use for this call. When `nil`, falls back to the - /// instance ``decoder``. Defaults to `nil`. - /// - options: A closure that configures ``FunctionInvokeOptions`` before the request is sent. - /// Defaults to a no-op closure. - /// - Returns: A tuple of the decoded value and the raw `HTTPURLResponse`. - /// - Throws: ``FunctionsError`` on relay or HTTP errors, or a decoding error if the response - /// body cannot be decoded into `T`. - /// - /// ## Example - /// - /// ```swift - /// struct HelloResponse: Decodable { - /// let message: String - /// } - /// - /// let (response, _) = try await functions.invokeDecodable("hello", as: HelloResponse.self) { - /// $0.method = .get - /// $0.query = ["name": "world"] - /// } - /// print(response.message) // "Hello, world!" - /// ``` public func invokeDecodable( _ functionName: String, as _: T.Type = T.self, @@ -241,33 +148,10 @@ public actor FunctionsClient { ) } - /// Invokes a function and returns the raw response body and `HTTPURLResponse`. - /// - /// Use this method when you need full control over response handling — for example, when the - /// function returns non-JSON data, or when you want to inspect status codes and headers directly. - /// - /// - Parameters: - /// - functionName: The name of the Edge Function to invoke. - /// - options: A closure that configures ``FunctionInvokeOptions`` before the request is sent. - /// Defaults to a no-op closure. - /// - Returns: A tuple of the raw `Data` body and the `HTTPURLResponse`. - /// - Throws: ``FunctionsError/relayError`` if the relay reports an error, - /// ``FunctionsError/httpError(code:data:)`` for non-2xx responses, or a transport-level error. - /// - /// ## Example + /// Invokes a function and returns the raw response body and a fabricated `HTTPURLResponse`. /// - /// ```swift - /// struct RequestBody: Encodable { - /// let userId: String - /// } - /// - /// let (data, response) = try await functions.invoke("process-user") { - /// $0.method = .post - /// $0.body = try! JSONEncoder().encode(RequestBody(userId: "abc123")) - /// $0.headers["Content-Type"] = "application/json" - /// } - /// print(response.statusCode) // 200 - /// ``` + /// - Note: The returned `HTTPURLResponse` carries the HTTP status code only. Response headers + /// are not yet available through the generated client. @discardableResult public func invoke( _ functionName: String, @@ -276,46 +160,6 @@ public actor FunctionsClient { var options = FunctionInvokeOptions() applyOptions(&options) - if let generatedClient { - return try await invokeViaGeneratedClient( - functionName: functionName, - options: options, - generatedClient: generatedClient - ) - } - - let (functionURL, method, query, allHeaders, body) = requestComponents( - functionName: functionName, - options: options - ) - - do { - let (data, response) = try await http.fetchData( - method, - url: functionURL, - query: query.isEmpty ? nil : query, - body: body, - headers: allHeaders.isEmpty ? nil : allHeaders - ) - - if response.value(forHTTPHeaderField: "x-relay-error") == "true" { - throw FunctionsError.relayError - } - - return (data, response) - } catch let error as HTTPClientError { - if case .responseError(let response, let data) = error { - throw FunctionsError.httpError(code: response.statusCode, data: data) - } - throw error - } - } - - private func invokeViaGeneratedClient( - functionName: String, - options: FunctionInvokeOptions, - generatedClient: Client - ) async throws -> (Data, HTTPURLResponse) { let input = Operations.InvokeFunction.Input( path: .init(functionName: functionName), headers: .init(x_hyphen_region: (options.region ?? region)?.rawValue), @@ -326,24 +170,18 @@ public actor FunctionsClient { switch output { case .ok(let response): - let data = try await Data(collecting: response.body.binary, upTo: .max) - let httpResponse = HTTPURLResponse( - url: url.appendingPathComponent(functionName), - statusCode: 200, - httpVersion: nil, - headerFields: nil - )! - return (data, httpResponse) + let httpBody = try response.body.binary + let data = try await Data(collecting: httpBody, upTo: .max) + return (data, fabricatedResponse(functionName: functionName, statusCode: 200)) + case .badRequest(let response): - let rawBody = response.body let data: Data - switch rawBody { + switch response.body { case .json(let body): - // Collect raw bytes so callers can inspect the full error payload. - let encoded = try JSONEncoder().encode(body) - data = encoded + data = (try? JSONEncoder().encode(body)) ?? Data() } throw FunctionsError.httpError(code: 400, data: data) + case .undocumented(let statusCode, let payload): let data: Data if let body = payload.body { @@ -352,13 +190,7 @@ public actor FunctionsClient { data = Data() } if statusCode >= 200 && statusCode < 300 { - let httpResponse = HTTPURLResponse( - url: url.appendingPathComponent(functionName), - statusCode: statusCode, - httpVersion: nil, - headerFields: nil - )! - return (data, httpResponse) + return (data, fabricatedResponse(functionName: functionName, statusCode: statusCode)) } throw FunctionsError.httpError(code: statusCode, data: data) } @@ -367,29 +199,10 @@ public actor FunctionsClient { #if canImport(Darwin) /// Invokes a function and returns an async byte stream for the response body. /// - /// Use this method for functions that return large payloads or use server-sent events / - /// chunked transfer encoding. The stream yields individual `UInt8` bytes as they arrive. - /// - /// - Parameters: - /// - functionName: The name of the Edge Function to invoke. - /// - options: A closure that configures ``FunctionInvokeOptions`` before the request is sent. - /// Defaults to a no-op closure. - /// - Returns: A tuple of an `AsyncThrowingStream` and the initial - /// `HTTPURLResponse`. - /// - Throws: ``FunctionsError/relayError`` if the relay reports an error, - /// ``FunctionsError/httpError(code:data:)`` for non-2xx responses, or a transport-level error. - /// - /// ## Example + /// The stream is backed directly by the `HTTPBody` from the generated client — bytes are + /// yielded chunk-by-chunk as they arrive from the server without any intermediate buffering. /// - /// ```swift - /// let (stream, _) = try await functions.invokeStream("stream-data") - /// - /// var buffer = Data() - /// for try await byte in stream { - /// buffer.append(byte) - /// } - /// print(String(data: buffer, encoding: .utf8) ?? "") - /// ``` + /// - Note: The returned `HTTPURLResponse` carries the HTTP status code only. @available(macOS 12.0, *) public func invokeStream( _ functionName: String, @@ -397,57 +210,64 @@ public actor FunctionsClient { ) async throws -> (AsyncThrowingStream, HTTPURLResponse) { var options = FunctionInvokeOptions() applyOptions(&options) - let (functionURL, method, query, allHeaders, body) = requestComponents( - functionName: functionName, - options: options + + let input = Operations.InvokeFunction.Input( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: (options.region ?? region)?.rawValue), + body: options.body.map { .binary(HTTPBody($0)) } ) - do { - let (bytes, response) = try await http.fetchStream( - method, - url: functionURL, - query: query.isEmpty ? nil : query, - body: body, - headers: allHeaders.isEmpty ? nil : allHeaders - ) + let output = try await generatedClient.InvokeFunction(input) + + switch output { + case .ok(let response): + // Bridge HTTPBody (AsyncSequence>) to AsyncThrowingStream. + // Bytes are forwarded chunk-by-chunk without intermediate buffering. + let httpBody = try response.body.binary + let stream = AsyncThrowingStream { continuation in + Task { + do { + for try await chunk in httpBody { + for byte in chunk { + continuation.yield(byte) + } + } + continuation.finish() + } catch { + continuation.finish(throwing: error) + } + } + } + return (stream, fabricatedResponse(functionName: functionName, statusCode: 200)) - if response.value(forHTTPHeaderField: "x-relay-error") == "true" { - throw FunctionsError.relayError + case .badRequest(let response): + let data: Data + switch response.body { + case .json(let body): + data = (try? JSONEncoder().encode(body)) ?? Data() } + throw FunctionsError.httpError(code: 400, data: data) - return (bytes, response) - } catch let error as HTTPClientError { - if case .responseError(let response, let data) = error { - throw FunctionsError.httpError(code: response.statusCode, data: data) + case .undocumented(let statusCode, let payload): + let data: Data + if let body = payload.body { + data = try await Data(collecting: body, upTo: .max) + } else { + data = Data() } - throw error + throw FunctionsError.httpError(code: statusCode, data: data) } } #endif - private func requestComponents( - functionName: String, - options: FunctionInvokeOptions - ) -> ( - url: URL, - method: HTTPMethod, - query: [String: String], - headers: [String: String], - body: RequestBody? - ) { - let method = - options.method.flatMap { HTTPMethod(rawValue: $0.rawValue) } ?? .post - var query = options.query - var allHeaders = headers.merging(options.headers) { _, new in new } + // MARK: - Private - if let region = (options.region ?? region)?.rawValue { - allHeaders["x-region"] = region - query["forceFunctionRegion"] = region - } - - let body: RequestBody? = options.body.map { .data($0) } - return ( - url.appendingPathComponent(functionName), method, query, allHeaders, body - ) + private func fabricatedResponse(functionName: String, statusCode: Int) -> HTTPURLResponse { + HTTPURLResponse( + url: url.appendingPathComponent(functionName), + statusCode: statusCode, + httpVersion: nil, + headerFields: nil + )! } } From 61350d47e643db6ba34d4fef595cc4300d384a30 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 30 Jun 2026 12:57:51 -0300 Subject: [PATCH 24/32] spike(functions): add GET/PUT/PATCH/DELETE invoke methods via multi-operation Smithy model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Smithy requires a fixed HTTP method per operation, so we model all five methods Supabase Edge Functions accept as separate operations on the same path. FunctionsClient.invoke() and invokeStream() now dispatch to the appropriate generated method based on FunctionInvokeOptions.method. Generated Types.swift shares InvokeFunctionOutput and InvokeFunctionBodyInput across POST/PUT/PATCH/DELETE to avoid duplication. GET gets its own input type (no body — Smithy rejects @httpPayload on GET). The invokeGeneratedClient() helper centralises the dispatch switch so both invoke() and invokeStream() stay focused on response handling. --- Sources/Functions/FunctionsClient.swift | 58 +- Sources/Functions/Generated/Client.swift | 371 ++++++++----- Sources/Functions/Generated/Types.swift | 504 +++++++++--------- smithy/model/functions.smithy | 71 ++- .../openapi/FunctionsService.openapi.json | 235 +++++++- 5 files changed, 840 insertions(+), 399 deletions(-) diff --git a/Sources/Functions/FunctionsClient.swift b/Sources/Functions/FunctionsClient.swift index b24f62243..bf82da4d1 100644 --- a/Sources/Functions/FunctionsClient.swift +++ b/Sources/Functions/FunctionsClient.swift @@ -160,13 +160,8 @@ public actor FunctionsClient { var options = FunctionInvokeOptions() applyOptions(&options) - let input = Operations.InvokeFunction.Input( - path: .init(functionName: functionName), - headers: .init(x_hyphen_region: (options.region ?? region)?.rawValue), - body: options.body.map { .binary(HTTPBody($0)) } - ) - - let output = try await generatedClient.InvokeFunction(input) + let output = try await invokeGeneratedClient( + functionName: functionName, options: options) switch output { case .ok(let response): @@ -211,13 +206,8 @@ public actor FunctionsClient { var options = FunctionInvokeOptions() applyOptions(&options) - let input = Operations.InvokeFunction.Input( - path: .init(functionName: functionName), - headers: .init(x_hyphen_region: (options.region ?? region)?.rawValue), - body: options.body.map { .binary(HTTPBody($0)) } - ) - - let output = try await generatedClient.InvokeFunction(input) + let output = try await invokeGeneratedClient( + functionName: functionName, options: options) switch output { case .ok(let response): @@ -262,6 +252,46 @@ public actor FunctionsClient { // MARK: - Private + private func invokeGeneratedClient( + functionName: String, + options: FunctionInvokeOptions + ) async throws -> Operations.InvokeFunctionOutput { + let region = (options.region ?? self.region)?.rawValue + let body = options.body.map { Operations.InvokeFunctionBodyInput.Body.binary(HTTPBody($0)) } + + switch options.method ?? .post { + case .get: + return try await generatedClient.InvokeFunctionGet( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: region) + ) + case .post: + return try await generatedClient.InvokeFunctionPost( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: region), + body: body + ) + case .put: + return try await generatedClient.InvokeFunctionPut( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: region), + body: body + ) + case .patch: + return try await generatedClient.InvokeFunctionPatch( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: region), + body: body + ) + case .delete: + return try await generatedClient.InvokeFunctionDelete( + path: .init(functionName: functionName), + headers: .init(x_hyphen_region: region), + body: body + ) + } + } + private func fabricatedResponse(functionName: String, statusCode: Int) -> HTTPURLResponse { HTTPURLResponse( url: url.appendingPathComponent(functionName), diff --git a/Sources/Functions/Generated/Client.swift b/Sources/Functions/Generated/Client.swift index 2b1819cea..d1ba31142 100644 --- a/Sources/Functions/Generated/Client.swift +++ b/Sources/Functions/Generated/Client.swift @@ -1,138 +1,253 @@ +import HTTPTypes // Generated by swift-openapi-generator, do not modify. @_spi(Generated) import OpenAPIRuntime + #if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date + @preconcurrency import struct Foundation.URL + @preconcurrency import struct Foundation.Data + @preconcurrency import struct Foundation.Date #else -import struct Foundation.URL -import struct Foundation.Data -import struct Foundation.Date + import struct Foundation.URL + import struct Foundation.Data + import struct Foundation.Date #endif -import HTTPTypes internal struct Client: APIProtocol { - /// The underlying HTTP client. - private let client: UniversalClient - /// Creates a new client. - /// - Parameters: - /// - serverURL: The server URL that the client connects to. Any server - /// URLs defined in the OpenAPI document are available as static methods - /// on the ``Servers`` type. - /// - configuration: A set of configuration values for the client. - /// - transport: A transport that performs HTTP operations. - /// - middlewares: A list of middlewares to call before the transport. - internal init( - serverURL: Foundation.URL, - configuration: Configuration = .init(), - transport: any ClientTransport, - middlewares: [any ClientMiddleware] = [] - ) { - self.client = .init( - serverURL: serverURL, - configuration: configuration, - transport: transport, - middlewares: middlewares - ) + private let client: UniversalClient + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { client.converter } + + // ── Shared deserialization helper ────────────────────────────────────────── + + private func deserializeInvokeOutput( + response: HTTPTypes.HTTPResponse, + responseBody: OpenAPIRuntime.HTTPBody? + ) async throws -> Operations.InvokeFunctionOutput { + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let chosenContentType = try converter.bestContentType( + received: contentType, + options: ["application/octet-stream"] + ) + switch chosenContentType { + case "application/octet-stream": + let body: Operations.InvokeFunctionOutput.Ok.Body = + try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { .binary($0) } + ) + return .ok(.init(body: body)) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let chosenContentType = try converter.bestContentType( + received: contentType, + options: ["application/json"] + ) + switch chosenContentType { + case "application/json": + let body: Operations.InvokeFunctionOutput.BadRequest.Body = + try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsErrorResponseContent.self, + from: responseBody, + transforming: { .json($0) } + ) + return .badRequest(.init(body: body)) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + default: + return .undocumented( + statusCode: response.status.code, + .init(headerFields: response.headerFields, body: responseBody) + ) } - private var converter: Converter { - client.converter + } + + // ── Shared header serialization helper ──────────────────────────────────── + + private func serializeInvokeHeaders( + into request: inout HTTPTypes.HTTPRequest, + xRegion: Swift.String?, + accept: [OpenAPIRuntime.AcceptHeaderContentType] + ) throws { + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: xRegion + ) + converter.setAcceptHeader(in: &request.headerFields, contentTypes: accept) + } + + // ── Shared body serialization helper ────────────────────────────────────── + + private func serializeInvokeBody( + _ body: Operations.InvokeFunctionBodyInput.Body?, + into request: inout HTTPTypes.HTTPRequest + ) throws -> OpenAPIRuntime.HTTPBody? { + switch body { + case .none: + return nil + case .binary(let value): + return try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) } - /// - Remark: HTTP `POST /functions/v1/{functionName}`. - /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. - internal func InvokeFunction(_ input: Operations.InvokeFunction.Input) async throws -> Operations.InvokeFunction.Output { - try await client.send( - input: input, - forOperation: Operations.InvokeFunction.id, - serializer: { input in - let path = try converter.renderedPath( - template: "/functions/v1/{}", - parameters: [ - input.path.functionName - ] - ) - var request: HTTPTypes.HTTPRequest = .init( - soar_path: path, - method: .post - ) - suppressMutabilityWarning(&request) - try converter.setHeaderFieldAsURI( - in: &request.headerFields, - name: "x-region", - value: input.headers.x_hyphen_region - ) - converter.setAcceptHeader( - in: &request.headerFields, - contentTypes: input.headers.accept - ) - let body: OpenAPIRuntime.HTTPBody? - switch input.body { - case .none: - body = nil - case let .binary(value): - body = try converter.setOptionalRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - } - return (request, body) - }, - deserializer: { response, responseBody in - switch response.status.code { - case 200: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.InvokeFunction.Output.Ok.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/octet-stream" - ] - ) - switch chosenContentType { - case "application/octet-stream": - body = try converter.getResponseBodyAsBinary( - OpenAPIRuntime.HTTPBody.self, - from: responseBody, - transforming: { value in - .binary(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .ok(.init(body: body)) - case 400: - let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) - let body: Operations.InvokeFunction.Output.BadRequest.Body - let chosenContentType = try converter.bestContentType( - received: contentType, - options: [ - "application/json" - ] - ) - switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Components.Schemas.FunctionsErrorResponseContent.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - default: - preconditionFailure("bestContentType chose an invalid content type.") - } - return .badRequest(.init(body: body)) - default: - return .undocumented( - statusCode: response.status.code, - .init( - headerFields: response.headerFields, - body: responseBody - ) - ) - } - } + } + + // ── GET ─────────────────────────────────────────────────────────────────── + + /// - Remark: HTTP `GET /functions/v1/{functionName}`. + internal func InvokeFunctionGet(_ input: Operations.InvokeFunctionGet.Input) async throws + -> Operations.InvokeFunctionOutput + { + try await client.send( + input: input, + forOperation: Operations.InvokeFunctionGet.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [input.path.functionName] ) - } + var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .get) + suppressMutabilityWarning(&request) + try serializeInvokeHeaders( + into: &request, + xRegion: input.headers.x_hyphen_region, + accept: input.headers.accept + ) + return (request, nil) + }, + deserializer: deserializeInvokeOutput + ) + } + + // ── POST ────────────────────────────────────────────────────────────────── + + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + internal func InvokeFunctionPost(_ input: Operations.InvokeFunctionPost.Input) async throws + -> Operations.InvokeFunctionOutput + { + try await client.send( + input: input, + forOperation: Operations.InvokeFunctionPost.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [input.path.functionName] + ) + var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .post) + suppressMutabilityWarning(&request) + try serializeInvokeHeaders( + into: &request, + xRegion: input.headers.x_hyphen_region, + accept: input.headers.accept + ) + let body = try serializeInvokeBody(input.body, into: &request) + return (request, body) + }, + deserializer: deserializeInvokeOutput + ) + } + + // ── PUT ─────────────────────────────────────────────────────────────────── + + /// - Remark: HTTP `PUT /functions/v1/{functionName}`. + internal func InvokeFunctionPut(_ input: Operations.InvokeFunctionPut.Input) async throws + -> Operations.InvokeFunctionOutput + { + try await client.send( + input: input, + forOperation: Operations.InvokeFunctionPut.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [input.path.functionName] + ) + var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .put) + suppressMutabilityWarning(&request) + try serializeInvokeHeaders( + into: &request, + xRegion: input.headers.x_hyphen_region, + accept: input.headers.accept + ) + let body = try serializeInvokeBody(input.body, into: &request) + return (request, body) + }, + deserializer: deserializeInvokeOutput + ) + } + + // ── PATCH ───────────────────────────────────────────────────────────────── + + /// - Remark: HTTP `PATCH /functions/v1/{functionName}`. + internal func InvokeFunctionPatch(_ input: Operations.InvokeFunctionPatch.Input) async throws + -> Operations.InvokeFunctionOutput + { + try await client.send( + input: input, + forOperation: Operations.InvokeFunctionPatch.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [input.path.functionName] + ) + var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .patch) + suppressMutabilityWarning(&request) + try serializeInvokeHeaders( + into: &request, + xRegion: input.headers.x_hyphen_region, + accept: input.headers.accept + ) + let body = try serializeInvokeBody(input.body, into: &request) + return (request, body) + }, + deserializer: deserializeInvokeOutput + ) + } + + // ── DELETE ──────────────────────────────────────────────────────────────── + + /// - Remark: HTTP `DELETE /functions/v1/{functionName}`. + internal func InvokeFunctionDelete(_ input: Operations.InvokeFunctionDelete.Input) async throws + -> Operations.InvokeFunctionOutput + { + try await client.send( + input: input, + forOperation: Operations.InvokeFunctionDelete.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [input.path.functionName] + ) + var request: HTTPTypes.HTTPRequest = .init(soar_path: path, method: .delete) + suppressMutabilityWarning(&request) + try serializeInvokeHeaders( + into: &request, + xRegion: input.headers.x_hyphen_region, + accept: input.headers.accept + ) + let body = try serializeInvokeBody(input.body, into: &request) + return (request, body) + }, + deserializer: deserializeInvokeOutput + ) + } } diff --git a/Sources/Functions/Generated/Types.swift b/Sources/Functions/Generated/Types.swift index 90bcbac53..3c1fc508c 100644 --- a/Sources/Functions/Generated/Types.swift +++ b/Sources/Functions/Generated/Types.swift @@ -1,36 +1,79 @@ // Generated by swift-openapi-generator, do not modify. @_spi(Generated) import OpenAPIRuntime + #if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date + @preconcurrency import struct Foundation.URL + @preconcurrency import struct Foundation.Data + @preconcurrency import struct Foundation.Date #else -import struct Foundation.URL -import struct Foundation.Data -import struct Foundation.Date + import struct Foundation.URL + import struct Foundation.Data + import struct Foundation.Date #endif /// A type that performs HTTP operations defined by the OpenAPI document. internal protocol APIProtocol: Sendable { - /// - Remark: HTTP `POST /functions/v1/{functionName}`. - /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. - func InvokeFunction(_ input: Operations.InvokeFunction.Input) async throws -> Operations.InvokeFunction.Output + /// - Remark: HTTP `GET /functions/v1/{functionName}`. + func InvokeFunctionGet(_ input: Operations.InvokeFunctionGet.Input) async throws + -> Operations.InvokeFunctionOutput + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + func InvokeFunctionPost(_ input: Operations.InvokeFunctionPost.Input) async throws + -> Operations.InvokeFunctionOutput + /// - Remark: HTTP `PUT /functions/v1/{functionName}`. + func InvokeFunctionPut(_ input: Operations.InvokeFunctionPut.Input) async throws + -> Operations.InvokeFunctionOutput + /// - Remark: HTTP `PATCH /functions/v1/{functionName}`. + func InvokeFunctionPatch(_ input: Operations.InvokeFunctionPatch.Input) async throws + -> Operations.InvokeFunctionOutput + /// - Remark: HTTP `DELETE /functions/v1/{functionName}`. + func InvokeFunctionDelete(_ input: Operations.InvokeFunctionDelete.Input) async throws + -> Operations.InvokeFunctionOutput } /// Convenience overloads for operation inputs. extension APIProtocol { - /// - Remark: HTTP `POST /functions/v1/{functionName}`. - /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. - internal func InvokeFunction( - path: Operations.InvokeFunction.Input.Path, - headers: Operations.InvokeFunction.Input.Headers = .init(), - body: Operations.InvokeFunction.Input.Body? = nil - ) async throws -> Operations.InvokeFunction.Output { - try await InvokeFunction(Operations.InvokeFunction.Input( - path: path, - headers: headers, - body: body - )) - } + internal func InvokeFunctionGet( + path: Operations.InvokeFunctionGet.Input.Path, + headers: Operations.InvokeFunctionGet.Input.Headers = .init() + ) async throws -> Operations.InvokeFunctionOutput { + try await InvokeFunctionGet( + Operations.InvokeFunctionGet.Input(path: path, headers: headers)) + } + + internal func InvokeFunctionPost( + path: Operations.InvokeFunctionPost.Input.Path, + headers: Operations.InvokeFunctionPost.Input.Headers = .init(), + body: Operations.InvokeFunctionPost.Input.Body? = nil + ) async throws -> Operations.InvokeFunctionOutput { + try await InvokeFunctionPost( + Operations.InvokeFunctionPost.Input(path: path, headers: headers, body: body)) + } + + internal func InvokeFunctionPut( + path: Operations.InvokeFunctionPut.Input.Path, + headers: Operations.InvokeFunctionPut.Input.Headers = .init(), + body: Operations.InvokeFunctionPut.Input.Body? = nil + ) async throws -> Operations.InvokeFunctionOutput { + try await InvokeFunctionPut( + Operations.InvokeFunctionPut.Input(path: path, headers: headers, body: body)) + } + + internal func InvokeFunctionPatch( + path: Operations.InvokeFunctionPatch.Input.Path, + headers: Operations.InvokeFunctionPatch.Input.Headers = .init(), + body: Operations.InvokeFunctionPatch.Input.Body? = nil + ) async throws -> Operations.InvokeFunctionOutput { + try await InvokeFunctionPatch( + Operations.InvokeFunctionPatch.Input(path: path, headers: headers, body: body)) + } + + internal func InvokeFunctionDelete( + path: Operations.InvokeFunctionDelete.Input.Path, + headers: Operations.InvokeFunctionDelete.Input.Headers = .init(), + body: Operations.InvokeFunctionDelete.Input.Body? = nil + ) async throws -> Operations.InvokeFunctionOutput { + try await InvokeFunctionDelete( + Operations.InvokeFunctionDelete.Input(path: path, headers: headers, body: body)) + } } /// Server URLs defined in the OpenAPI document. @@ -38,237 +81,210 @@ internal enum Servers {} /// Types generated from the components section of the OpenAPI document. internal enum Components { - /// Types generated from the `#/components/schemas` section of the OpenAPI document. - internal enum Schemas { - /// - Remark: Generated from `#/components/schemas/FunctionsErrorResponseContent`. - internal struct FunctionsErrorResponseContent: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/components/schemas/FunctionsErrorResponseContent/message`. - internal var message: Swift.String? - /// Creates a new `FunctionsErrorResponseContent`. - /// - /// - Parameters: - /// - message: - internal init(message: Swift.String? = nil) { - self.message = message - } - internal enum CodingKeys: String, CodingKey { - case message - } - } - /// - Remark: Generated from `#/components/schemas/InvokeFunctionInputPayload`. - internal typealias InvokeFunctionInputPayload = OpenAPIRuntime.Base64EncodedData - /// - Remark: Generated from `#/components/schemas/InvokeFunctionOutputPayload`. - internal typealias InvokeFunctionOutputPayload = OpenAPIRuntime.Base64EncodedData + internal enum Schemas { + internal struct FunctionsErrorResponseContent: Codable, Hashable, Sendable { + internal var message: Swift.String? + internal init(message: Swift.String? = nil) { + self.message = message + } + internal enum CodingKeys: String, CodingKey { + case message + } } - /// Types generated from the `#/components/parameters` section of the OpenAPI document. - internal enum Parameters {} - /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. - internal enum RequestBodies {} - /// Types generated from the `#/components/responses` section of the OpenAPI document. - internal enum Responses {} - /// Types generated from the `#/components/headers` section of the OpenAPI document. - internal enum Headers {} + } + internal enum Parameters {} + internal enum RequestBodies {} + internal enum Responses {} + internal enum Headers {} } /// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. internal enum Operations { - /// - Remark: HTTP `POST /functions/v1/{functionName}`. - /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)`. - internal enum InvokeFunction { - internal static let id: Swift.String = "InvokeFunction" - internal struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/path`. - internal struct Path: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/path/functionName`. - internal var functionName: Swift.String - /// Creates a new `Path`. - /// - /// - Parameters: - /// - functionName: - internal init(functionName: Swift.String) { - self.functionName = functionName - } - } - internal var path: Operations.InvokeFunction.Input.Path - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/header`. - internal struct Headers: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/header/x-region`. - internal var x_hyphen_region: Swift.String? - internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] - /// Creates a new `Headers`. - /// - /// - Parameters: - /// - x_hyphen_region: - /// - accept: - internal init( - x_hyphen_region: Swift.String? = nil, - accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() - ) { - self.x_hyphen_region = x_hyphen_region - self.accept = accept - } - } - internal var headers: Operations.InvokeFunction.Input.Headers - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody`. - internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - } - internal var body: Operations.InvokeFunction.Input.Body? - /// Creates a new `Input`. - /// - /// - Parameters: - /// - path: - /// - headers: - /// - body: - internal init( - path: Operations.InvokeFunction.Input.Path, - headers: Operations.InvokeFunction.Input.Headers = .init(), - body: Operations.InvokeFunction.Input.Body? = nil - ) { - self.path = path - self.headers = headers - self.body = body + + // ── Shared output and accept type for all InvokeFunctionXxx operations ──── + + /// Shared acceptable content type for all InvokeFunctionXxx operations. + internal enum InvokeFunctionAcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": self = .binary + case "application/json": self = .json + default: self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case .binary: return "application/octet-stream" + case .json: return "application/json" + case .other(let s): return s + } + } + internal static var allCases: [Self] { [.binary, .json] } + } + + /// Shared output type for all InvokeFunctionXxx operations. + internal enum InvokeFunctionOutput: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + internal enum Body: Sendable, Hashable { + case binary(OpenAPIRuntime.HTTPBody) + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case .binary(let body): return body } + } } - internal enum Output: Sendable, Hashable { - internal struct Ok: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content`. - internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.binary`. - /// - /// - Throws: An error if `self` is not `.binary`. - /// - SeeAlso: `.binary`. - internal var binary: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .binary(body): - return body - } - } - } - } - /// Received HTTP response body - internal var body: Operations.InvokeFunction.Output.Ok.Body - /// Creates a new `Ok`. - /// - /// - Parameters: - /// - body: Received HTTP response body - internal init(body: Operations.InvokeFunction.Output.Ok.Body) { - self.body = body - } - } - /// InvokeFunction 200 response - /// - /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)/responses/200`. - /// - /// HTTP response code: `200 ok`. - case ok(Operations.InvokeFunction.Output.Ok) - /// The associated value of the enum case if `self` is `.ok`. - /// - /// - Throws: An error if `self` is not `.ok`. - /// - SeeAlso: `.ok`. - internal var ok: Operations.InvokeFunction.Output.Ok { - get throws { - switch self { - case let .ok(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "ok", - response: self - ) - } - } - } - internal struct BadRequest: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/400/content`. - internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/400/content/application\/json`. - case json(Components.Schemas.FunctionsErrorResponseContent) - /// The associated value of the enum case if `self` is `.json`. - /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: Components.Schemas.FunctionsErrorResponseContent { - get throws { - switch self { - case let .json(body): - return body - } - } - } - } - /// Received HTTP response body - internal var body: Operations.InvokeFunction.Output.BadRequest.Body - /// Creates a new `BadRequest`. - /// - /// - Parameters: - /// - body: Received HTTP response body - internal init(body: Operations.InvokeFunction.Output.BadRequest.Body) { - self.body = body - } - } - /// FunctionsError 400 response - /// - /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(InvokeFunction)/responses/400`. - /// - /// HTTP response code: `400 badRequest`. - case badRequest(Operations.InvokeFunction.Output.BadRequest) - /// The associated value of the enum case if `self` is `.badRequest`. - /// - /// - Throws: An error if `self` is not `.badRequest`. - /// - SeeAlso: `.badRequest`. - internal var badRequest: Operations.InvokeFunction.Output.BadRequest { - get throws { - switch self { - case let .badRequest(response): - return response - default: - try throwUnexpectedResponseStatus( - expectedStatus: "badRequest", - response: self - ) - } - } - } - /// Undocumented response. - /// - /// A response with a code that is not documented in the OpenAPI document. - case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal var body: Body + internal init(body: Body) { self.body = body } + } + case ok(Ok) + internal var ok: Ok { + get throws { + switch self { + case .ok(let r): return r + default: try throwUnexpectedResponseStatus(expectedStatus: "ok", response: self) } - internal enum AcceptableContentType: AcceptableProtocol { - case binary - case json - case other(Swift.String) - internal init?(rawValue: Swift.String) { - switch rawValue.lowercased() { - case "application/octet-stream": - self = .binary - case "application/json": - self = .json - default: - self = .other(rawValue) - } - } - internal var rawValue: Swift.String { - switch self { - case let .other(string): - return string - case .binary: - return "application/octet-stream" - case .json: - return "application/json" - } - } - internal static var allCases: [Self] { - [ - .binary, - .json - ] + } + } + internal struct BadRequest: Sendable, Hashable { + internal enum Body: Sendable, Hashable { + case json(Components.Schemas.FunctionsErrorResponseContent) + internal var json: Components.Schemas.FunctionsErrorResponseContent { + get throws { + switch self { + case .json(let body): return body } + } + } + } + internal var body: Body + internal init(body: Body) { self.body = body } + } + case badRequest(BadRequest) + internal var badRequest: BadRequest { + get throws { + switch self { + case .badRequest(let r): return r + default: try throwUnexpectedResponseStatus(expectedStatus: "badRequest", response: self) + } + } + } + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + + // ── Shared input for methods that carry a body (POST, PUT, PATCH, DELETE) ─ + + /// Input struct reused by POST, PUT, PATCH, and DELETE operations. + /// + /// Declared as a top-level struct so each operation typealias can reference it + /// and FunctionsClient can construct one value and dispatch to any of the four. + internal struct InvokeFunctionBodyInput: Sendable, Hashable { + internal struct Path: Sendable, Hashable { + internal var functionName: Swift.String + internal init(functionName: Swift.String) { self.functionName = functionName } + } + internal var path: Path + internal struct Headers: Sendable, Hashable { + internal var x_hyphen_region: Swift.String? + internal var accept: + [OpenAPIRuntime.AcceptHeaderContentType] + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType< + Operations.InvokeFunctionAcceptableContentType + >] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Headers + internal enum Body: Sendable, Hashable { + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Body? + internal init( + path: Path, + headers: Headers = .init(), + body: Body? = nil + ) { + self.path = path + self.headers = headers + self.body = body + } + } + + // ── GET — no body ────────────────────────────────────────────────────────── + + internal enum InvokeFunctionGet { + internal static let id: Swift.String = "InvokeFunctionGet" + internal struct Input: Sendable, Hashable { + internal struct Path: Sendable, Hashable { + internal var functionName: Swift.String + internal init(functionName: Swift.String) { self.functionName = functionName } + } + internal var path: Path + internal struct Headers: Sendable, Hashable { + internal var x_hyphen_region: Swift.String? + internal var accept: + [OpenAPIRuntime.AcceptHeaderContentType] + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType< + Operations.InvokeFunctionAcceptableContentType + >] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept } + } + internal var headers: Headers + internal init(path: Path, headers: Headers = .init()) { + self.path = path + self.headers = headers + } } + internal typealias Output = InvokeFunctionOutput + internal typealias AcceptableContentType = InvokeFunctionAcceptableContentType + } + + // ── POST ─────────────────────────────────────────────────────────────────── + + internal enum InvokeFunctionPost { + internal static let id: Swift.String = "InvokeFunctionPost" + internal typealias Input = InvokeFunctionBodyInput + internal typealias Output = InvokeFunctionOutput + internal typealias AcceptableContentType = InvokeFunctionAcceptableContentType + } + + // ── PUT ──────────────────────────────────────────────────────────────────── + + internal enum InvokeFunctionPut { + internal static let id: Swift.String = "InvokeFunctionPut" + internal typealias Input = InvokeFunctionBodyInput + internal typealias Output = InvokeFunctionOutput + internal typealias AcceptableContentType = InvokeFunctionAcceptableContentType + } + + // ── PATCH ────────────────────────────────────────────────────────────────── + + internal enum InvokeFunctionPatch { + internal static let id: Swift.String = "InvokeFunctionPatch" + internal typealias Input = InvokeFunctionBodyInput + internal typealias Output = InvokeFunctionOutput + internal typealias AcceptableContentType = InvokeFunctionAcceptableContentType + } + + // ── DELETE ───────────────────────────────────────────────────────────────── + + internal enum InvokeFunctionDelete { + internal static let id: Swift.String = "InvokeFunctionDelete" + internal typealias Input = InvokeFunctionBodyInput + internal typealias Output = InvokeFunctionOutput + internal typealias AcceptableContentType = InvokeFunctionAcceptableContentType + } } diff --git a/smithy/model/functions.smithy b/smithy/model/functions.smithy index 8ccaa4856..eebcc437d 100644 --- a/smithy/model/functions.smithy +++ b/smithy/model/functions.smithy @@ -8,17 +8,19 @@ use aws.protocols#restJson1 @title("Supabase Functions API") service FunctionsService { version: "1.0" - operations: [InvokeFunction] + operations: [ + InvokeFunctionGet + InvokeFunctionPost + InvokeFunctionPut + InvokeFunctionPatch + InvokeFunctionDelete + ] errors: [FunctionsError] } -@http(method: "POST", uri: "/functions/v1/{functionName}", code: 200) -operation InvokeFunction { - input: InvokeFunctionInput - output: InvokeFunctionOutput - errors: [FunctionsError] -} +// ─── Shared Shapes ───────────────────────────────────────────────────────── +/// Input for methods that carry a request body (POST, PUT, PATCH, DELETE). structure InvokeFunctionInput { @required @httpLabel @@ -31,11 +33,66 @@ structure InvokeFunctionInput { body: Blob } +/// Input for GET — no body, which GET does not support. +structure InvokeFunctionGetInput { + @required + @httpLabel + functionName: String + + @httpHeader("x-region") + region: String +} + structure InvokeFunctionOutput { @httpPayload body: Blob } +// ─── Operations (one per HTTP method) ────────────────────────────────────── +// +// Smithy requires a fixed HTTP method per operation. We model all five +// methods Supabase Edge Functions accept; FunctionsClient.invoke() dispatches +// to the appropriate generated method based on FunctionInvokeOptions.method. + +@http(method: "GET", uri: "/functions/v1/{functionName}", code: 200) +@readonly +operation InvokeFunctionGet { + input: InvokeFunctionGetInput + output: InvokeFunctionOutput + errors: [FunctionsError] +} + +@http(method: "POST", uri: "/functions/v1/{functionName}", code: 200) +operation InvokeFunctionPost { + input: InvokeFunctionInput + output: InvokeFunctionOutput + errors: [FunctionsError] +} + +@http(method: "PUT", uri: "/functions/v1/{functionName}", code: 200) +@idempotent +operation InvokeFunctionPut { + input: InvokeFunctionInput + output: InvokeFunctionOutput + errors: [FunctionsError] +} + +@http(method: "PATCH", uri: "/functions/v1/{functionName}", code: 200) +operation InvokeFunctionPatch { + input: InvokeFunctionInput + output: InvokeFunctionOutput + errors: [FunctionsError] +} + +@http(method: "DELETE", uri: "/functions/v1/{functionName}", code: 200) +@idempotent +@suppress(["HttpMethodSemantics.UnexpectedPayload"]) +operation InvokeFunctionDelete { + input: InvokeFunctionInput + output: InvokeFunctionOutput + errors: [FunctionsError] +} + @error("client") structure FunctionsError { message: String diff --git a/smithy/output/openapi/FunctionsService.openapi.json b/smithy/output/openapi/FunctionsService.openapi.json index d91b56316..9f4f9db18 100644 --- a/smithy/output/openapi/FunctionsService.openapi.json +++ b/smithy/output/openapi/FunctionsService.openapi.json @@ -6,13 +6,208 @@ }, "paths": { "/functions/v1/{functionName}": { + "delete": { + "operationId": "InvokeFunctionDelete", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionDeleteInputPayload" + } + } + } + }, + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "x-region", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "InvokeFunctionDelete 200 response", + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionDeleteOutputPayload" + } + } + } + }, + "400": { + "description": "FunctionsError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FunctionsErrorResponseContent" + } + } + } + } + } + }, + "get": { + "operationId": "InvokeFunctionGet", + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "x-region", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "InvokeFunctionGet 200 response", + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionGetOutputPayload" + } + } + } + }, + "400": { + "description": "FunctionsError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FunctionsErrorResponseContent" + } + } + } + } + } + }, + "patch": { + "operationId": "InvokeFunctionPatch", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionPatchInputPayload" + } + } + } + }, + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "x-region", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "InvokeFunctionPatch 200 response", + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionPatchOutputPayload" + } + } + } + }, + "400": { + "description": "FunctionsError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FunctionsErrorResponseContent" + } + } + } + } + } + }, "post": { - "operationId": "InvokeFunction", + "operationId": "InvokeFunctionPost", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionPostInputPayload" + } + } + } + }, + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "x-region", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "InvokeFunctionPost 200 response", + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InvokeFunctionPostOutputPayload" + } + } + } + }, + "400": { + "description": "FunctionsError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FunctionsErrorResponseContent" + } + } + } + } + } + }, + "put": { + "operationId": "InvokeFunctionPut", "requestBody": { "content": { "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/InvokeFunctionInputPayload" + "$ref": "#/components/schemas/InvokeFunctionPutInputPayload" } } } @@ -36,11 +231,11 @@ ], "responses": { "200": { - "description": "InvokeFunction 200 response", + "description": "InvokeFunctionPut 200 response", "content": { "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/InvokeFunctionOutputPayload" + "$ref": "#/components/schemas/InvokeFunctionPutOutputPayload" } } } @@ -69,11 +264,39 @@ } } }, - "InvokeFunctionInputPayload": { + "InvokeFunctionDeleteInputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionDeleteOutputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionGetOutputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionPatchInputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionPatchOutputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionPostInputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionPostOutputPayload": { + "type": "string", + "format": "byte" + }, + "InvokeFunctionPutInputPayload": { "type": "string", "format": "byte" }, - "InvokeFunctionOutputPayload": { + "InvokeFunctionPutOutputPayload": { "type": "string", "format": "byte" } From 57b360388dac62ea4bef66e625ebdfa36fdf67dd Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 06:46:59 -0300 Subject: [PATCH 25/32] spike(postgrest): generate Swift client from shared DatabaseService model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rewrite Makefile to use sync-models target pulling pre-built OpenAPI artifacts from supabase/sdk instead of maintaining local Smithy models - Add generate-swift-postgrest target and PostgREST openapi-generator-config - Add DatabaseService.openapi.json to spike's output/openapi/ - Commit generated Client.swift (912 lines) and Types.swift (2057 lines) for the PostgREST database service Key finding: the @httpQueryParams StringMap for `filters` is emitted as a single named query param "filters" by Smithy → OpenAPI, then serialized as one param by swift-openapi-generator. PostgREST requires each filter key to be its own query param (?id=eq.5&name=like.*foo*). This confirms the transport layer (path, method, fixed params, headers, body, Content-Range) is fully codegen-able; only the query-builder that populates the filter map stays hand-written — which was already the design intent. --- Makefile | 31 +- Sources/PostgREST/Generated/Client.swift | 912 ++++++++ Sources/PostgREST/Generated/Types.swift | 2057 +++++++++++++++++ .../PostgREST/openapi-generator-config.yaml | 4 + .../openapi/DatabaseService.openapi.json | 741 ++++++ 5 files changed, 3740 insertions(+), 5 deletions(-) create mode 100644 Sources/PostgREST/Generated/Client.swift create mode 100644 Sources/PostgREST/Generated/Types.swift create mode 100644 Sources/PostgREST/openapi-generator-config.yaml create mode 100644 smithy/output/openapi/DatabaseService.openapi.json diff --git a/Makefile b/Makefile index 34620616a..87013ce21 100644 --- a/Makefile +++ b/Makefile @@ -93,16 +93,31 @@ endef # ── Code generation ──────────────────────────────────────────────────────────── -.PHONY: generate-smithy generate-swift-storage generate-swift-functions generate check-generate check-swift-openapi-generator +.PHONY: sync-models generate-smithy generate-swift-storage generate-swift-functions generate-swift-postgrest generate check-generate check-swift-openapi-generator + +# Path to a local checkout of supabase/sdk (override with SDK_REPO=/path/to/sdk) +SDK_REPO ?= $(shell git rev-parse --show-toplevel)/../../sdk check-swift-openapi-generator: @which swift-openapi-generator > /dev/null 2>&1 || \ (echo "Error: swift-openapi-generator not found in PATH. Build from source: https://github.com/apple/swift-openapi-generator" && exit 1) +# Copy pre-generated OpenAPI artifacts from supabase/sdk (no Smithy install needed) +sync-models: + @test -d "$(SDK_REPO)/smithy/openapi" || \ + (echo "Error: supabase/sdk repo not found at $(SDK_REPO). Clone it or set SDK_REPO=/path/to/sdk" && exit 1) + cp "$(SDK_REPO)/smithy/openapi/StorageService.openapi.json" smithy/output/openapi/StorageService.openapi.json + cp "$(SDK_REPO)/smithy/openapi/FunctionsService.openapi.json" smithy/output/openapi/FunctionsService.openapi.json + cp "$(SDK_REPO)/smithy/openapi/DatabaseService.openapi.json" smithy/output/openapi/DatabaseService.openapi.json + python3 smithy/patch-openapi.py smithy/output/openapi/StorageService.openapi.json + @echo "Models synced from $(SDK_REPO)" + +# Build Smithy models locally (requires Smithy CLI; use sync-models instead if not installed) generate-smithy: - cd smithy && smithy build - cp smithy/build/smithy/storage-openapi/openapi/StorageService.openapi.json smithy/output/openapi/StorageService.openapi.json - cp smithy/build/smithy/functions-openapi/openapi/FunctionsService.openapi.json smithy/output/openapi/FunctionsService.openapi.json + cd "$(SDK_REPO)/smithy" && smithy build + cp "$(SDK_REPO)/smithy/build/smithy/storage-openapi/openapi/StorageService.openapi.json" smithy/output/openapi/StorageService.openapi.json + cp "$(SDK_REPO)/smithy/build/smithy/functions-openapi/openapi/FunctionsService.openapi.json" smithy/output/openapi/FunctionsService.openapi.json + cp "$(SDK_REPO)/smithy/build/smithy/database-openapi/openapi/DatabaseService.openapi.json" smithy/output/openapi/DatabaseService.openapi.json python3 smithy/patch-openapi.py smithy/output/openapi/StorageService.openapi.json generate-swift-storage: check-swift-openapi-generator @@ -117,7 +132,13 @@ generate-swift-functions: check-swift-openapi-generator --output-directory Sources/Functions/Generated \ smithy/output/openapi/FunctionsService.openapi.json -generate: generate-smithy generate-swift-storage generate-swift-functions +generate-swift-postgrest: check-swift-openapi-generator + swift-openapi-generator generate \ + --config Sources/PostgREST/openapi-generator-config.yaml \ + --output-directory Sources/PostgREST/Generated \ + smithy/output/openapi/DatabaseService.openapi.json + +generate: sync-models generate-swift-storage generate-swift-functions generate-swift-postgrest check-generate: $(MAKE) generate diff --git a/Sources/PostgREST/Generated/Client.swift b/Sources/PostgREST/Generated/Client.swift new file mode 100644 index 000000000..2b61ad34d --- /dev/null +++ b/Sources/PostgREST/Generated/Client.swift @@ -0,0 +1,912 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +/// PostgREST-backed database API. +/// +/// Base URL: https://{project-ref}.supabase.co/rest/v1 +/// +/// Known limitations: +/// 1. Write operations return 204 (no body) by default and 200 with a body when +/// Prefer: return=representation — the model uses 200 throughout so generators +/// always produce body-parsing code; clients must tolerate empty bodies. +/// 2. RPC GET arguments are function-specific; they are expressed via the same +/// @httpQueryParams map as row filters, with function-defined keys. +internal struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { + client.converter + } + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(CallRpcGet)`. + internal func CallRpcGet(_ input: Operations.CallRpcGet.Input) async throws -> Operations.CallRpcGet.Output { + try await client.send( + input: input, + forOperation: Operations.CallRpcGet.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/rpc/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "args", + value: input.query.args + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.CallRpcGet.Output.Ok.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CallRpcGet.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CallRpcGet.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(CallRpcPost)`. + internal func CallRpcPost(_ input: Operations.CallRpcPost.Input) async throws -> Operations.CallRpcPost.Output { + try await client.send( + input: input, + forOperation: Operations.CallRpcPost.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/rpc/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case .none: + body = nil + case let .binary(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.CallRpcPost.Output.Ok.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CallRpcPost.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.CallRpcPost.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(SelectRows)`. + internal func SelectRows(_ input: Operations.SelectRows.Input) async throws -> Operations.SelectRows.Output { + try await client.send( + input: input, + forOperation: Operations.SelectRows.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "order", + value: input.query.order + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "limit", + value: input.query.limit + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "offset", + value: input.query.offset + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "filters", + value: input.query.filters + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Range", + value: input.headers.Range + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Range-Unit", + value: input.headers.Range_hyphen_Unit + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.SelectRows.Output.Ok.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.SelectRows.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.SelectRows.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(InsertRows)`. + internal func InsertRows(_ input: Operations.InsertRows.Input) async throws -> Operations.InsertRows.Output { + try await client.send( + input: input, + forOperation: Operations.InsertRows.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "columns", + value: input.query.columns + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + let headers: Operations.InsertRows.Output.Created.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.InsertRows.Output.Created.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .created(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.InsertRows.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(UpdateRows)`. + internal func UpdateRows(_ input: Operations.UpdateRows.Input) async throws -> Operations.UpdateRows.Output { + try await client.send( + input: input, + forOperation: Operations.UpdateRows.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .patch + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "filters", + value: input.query.filters + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.UpdateRows.Output.Ok.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpdateRows.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpdateRows.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(UpsertRows)`. + internal func UpsertRows(_ input: Operations.UpsertRows.Input) async throws -> Operations.UpsertRows.Output { + try await client.send( + input: input, + forOperation: Operations.UpsertRows.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "on_conflict", + value: input.query.on_conflict + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "filters", + value: input.query.filters + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.UpsertRows.Output.Ok.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpsertRows.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.UpsertRows.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(DeleteRows)`. + internal func DeleteRows(_ input: Operations.DeleteRows.Input) async throws -> Operations.DeleteRows.Output { + try await client.send( + input: input, + forOperation: Operations.DeleteRows.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "filters", + value: input.query.filters + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.DeleteRows.Output.Ok.Headers = .init(Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + )) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.DeleteRows.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + case 400: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.DeleteRows.Output.BadRequest.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.DatabaseErrorResponseContent.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .badRequest(.init(body: body)) + default: + return .undocumented( + statusCode: response.status.code, + .init( + headerFields: response.headerFields, + body: responseBody + ) + ) + } + } + ) + } +} diff --git a/Sources/PostgREST/Generated/Types.swift b/Sources/PostgREST/Generated/Types.swift new file mode 100644 index 000000000..183d33f34 --- /dev/null +++ b/Sources/PostgREST/Generated/Types.swift @@ -0,0 +1,2057 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +internal protocol APIProtocol: Sendable { + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(CallRpcGet)`. + func CallRpcGet(_ input: Operations.CallRpcGet.Input) async throws -> Operations.CallRpcGet.Output + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(CallRpcPost)`. + func CallRpcPost(_ input: Operations.CallRpcPost.Input) async throws -> Operations.CallRpcPost.Output + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(SelectRows)`. + func SelectRows(_ input: Operations.SelectRows.Input) async throws -> Operations.SelectRows.Output + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(InsertRows)`. + func InsertRows(_ input: Operations.InsertRows.Input) async throws -> Operations.InsertRows.Output + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(UpdateRows)`. + func UpdateRows(_ input: Operations.UpdateRows.Input) async throws -> Operations.UpdateRows.Output + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(UpsertRows)`. + func UpsertRows(_ input: Operations.UpsertRows.Input) async throws -> Operations.UpsertRows.Output + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(DeleteRows)`. + func DeleteRows(_ input: Operations.DeleteRows.Input) async throws -> Operations.DeleteRows.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(CallRpcGet)`. + internal func CallRpcGet( + path: Operations.CallRpcGet.Input.Path, + query: Operations.CallRpcGet.Input.Query = .init(), + headers: Operations.CallRpcGet.Input.Headers = .init() + ) async throws -> Operations.CallRpcGet.Output { + try await CallRpcGet(Operations.CallRpcGet.Input( + path: path, + query: query, + headers: headers + )) + } + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(CallRpcPost)`. + internal func CallRpcPost( + path: Operations.CallRpcPost.Input.Path, + query: Operations.CallRpcPost.Input.Query = .init(), + headers: Operations.CallRpcPost.Input.Headers = .init(), + body: Operations.CallRpcPost.Input.Body? = nil + ) async throws -> Operations.CallRpcPost.Output { + try await CallRpcPost(Operations.CallRpcPost.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(SelectRows)`. + internal func SelectRows( + path: Operations.SelectRows.Input.Path, + query: Operations.SelectRows.Input.Query = .init(), + headers: Operations.SelectRows.Input.Headers = .init() + ) async throws -> Operations.SelectRows.Output { + try await SelectRows(Operations.SelectRows.Input( + path: path, + query: query, + headers: headers + )) + } + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(InsertRows)`. + internal func InsertRows( + path: Operations.InsertRows.Input.Path, + query: Operations.InsertRows.Input.Query = .init(), + headers: Operations.InsertRows.Input.Headers = .init(), + body: Operations.InsertRows.Input.Body + ) async throws -> Operations.InsertRows.Output { + try await InsertRows(Operations.InsertRows.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(UpdateRows)`. + internal func UpdateRows( + path: Operations.UpdateRows.Input.Path, + query: Operations.UpdateRows.Input.Query = .init(), + headers: Operations.UpdateRows.Input.Headers = .init(), + body: Operations.UpdateRows.Input.Body + ) async throws -> Operations.UpdateRows.Output { + try await UpdateRows(Operations.UpdateRows.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(UpsertRows)`. + internal func UpsertRows( + path: Operations.UpsertRows.Input.Path, + query: Operations.UpsertRows.Input.Query = .init(), + headers: Operations.UpsertRows.Input.Headers = .init(), + body: Operations.UpsertRows.Input.Body + ) async throws -> Operations.UpsertRows.Output { + try await UpsertRows(Operations.UpsertRows.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(DeleteRows)`. + internal func DeleteRows( + path: Operations.DeleteRows.Input.Path, + query: Operations.DeleteRows.Input.Query = .init(), + headers: Operations.DeleteRows.Input.Headers = .init() + ) async throws -> Operations.DeleteRows.Output { + try await DeleteRows(Operations.DeleteRows.Input( + path: path, + query: query, + headers: headers + )) + } +} + +/// Server URLs defined in the OpenAPI document. +internal enum Servers {} + +/// Types generated from the components section of the OpenAPI document. +internal enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + internal enum Schemas { + /// - Remark: Generated from `#/components/schemas/CallRpcGetOutputPayload`. + internal typealias CallRpcGetOutputPayload = OpenAPIRuntime.Base64EncodedData + /// Named parameters as a JSON object, or a single argument when combined + /// with Prefer: params=single-object. + /// + /// - Remark: Generated from `#/components/schemas/CallRpcPostInputPayload`. + internal typealias CallRpcPostInputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/CallRpcPostOutputPayload`. + internal typealias CallRpcPostOutputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/DatabaseErrorResponseContent`. + internal struct DatabaseErrorResponseContent: Codable, Hashable, Sendable { + /// PostgreSQL error code (e.g. "23505") or PostgREST error code (e.g. "PGRST301"). + /// + /// - Remark: Generated from `#/components/schemas/DatabaseErrorResponseContent/code`. + internal var code: Swift.String? + /// Human-readable error message. + /// + /// - Remark: Generated from `#/components/schemas/DatabaseErrorResponseContent/message`. + internal var message: Swift.String? + /// Extra context — constraint name, offending column, etc. + /// + /// - Remark: Generated from `#/components/schemas/DatabaseErrorResponseContent/details`. + internal var details: Swift.String? + /// Hint from PostgreSQL. + /// + /// - Remark: Generated from `#/components/schemas/DatabaseErrorResponseContent/hint`. + internal var hint: Swift.String? + /// Creates a new `DatabaseErrorResponseContent`. + /// + /// - Parameters: + /// - code: PostgreSQL error code (e.g. "23505") or PostgREST error code (e.g. "PGRST301"). + /// - message: Human-readable error message. + /// - details: Extra context — constraint name, offending column, etc. + /// - hint: Hint from PostgreSQL. + internal init( + code: Swift.String? = nil, + message: Swift.String? = nil, + details: Swift.String? = nil, + hint: Swift.String? = nil + ) { + self.code = code + self.message = message + self.details = details + self.hint = hint + } + internal enum CodingKeys: String, CodingKey { + case code + case message + case details + case hint + } + } + /// - Remark: Generated from `#/components/schemas/DeleteRowsOutputPayload`. + internal typealias DeleteRowsOutputPayload = OpenAPIRuntime.Base64EncodedData + /// JSON object or array of objects to insert. + /// + /// - Remark: Generated from `#/components/schemas/InsertRowsInputPayload`. + internal typealias InsertRowsInputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/InsertRowsOutputPayload`. + internal typealias InsertRowsOutputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/SelectRowsOutputPayload`. + internal typealias SelectRowsOutputPayload = OpenAPIRuntime.Base64EncodedData + /// Generic string-to-string map — used for arbitrary query parameter collections + /// (e.g. PostgREST filter params, RPC GET arguments). + /// + /// - Remark: Generated from `#/components/schemas/StringMap`. + internal struct StringMap: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `StringMap`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// Partial JSON object with fields to update. + /// + /// - Remark: Generated from `#/components/schemas/UpdateRowsInputPayload`. + internal typealias UpdateRowsInputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/UpdateRowsOutputPayload`. + internal typealias UpdateRowsOutputPayload = OpenAPIRuntime.Base64EncodedData + /// JSON object or array of objects to upsert. + /// + /// - Remark: Generated from `#/components/schemas/UpsertRowsInputPayload`. + internal typealias UpsertRowsInputPayload = OpenAPIRuntime.Base64EncodedData + /// - Remark: Generated from `#/components/schemas/UpsertRowsOutputPayload`. + internal typealias UpsertRowsOutputPayload = OpenAPIRuntime.Base64EncodedData + /// PostgREST column filter operators. Format a filter value as "{operator}.{value}", e.g. "eq.5". Prefix with "not." to negate: "not.eq.5". For logical grouping use keys "or" / "and" in the filters map. + /// + /// - Remark: Generated from `#/components/schemas/FilterOperator`. + internal enum FilterOperator: String, Codable, Hashable, Sendable, CaseIterable { + case eq = "eq" + case neq = "neq" + case lt = "lt" + case lte = "lte" + case gt = "gt" + case gte = "gte" + case like = "like" + case ilike = "ilike" + case match = "match" + case imatch = "imatch" + case _is = "is" + case isdistinct = "isdistinct" + case _in = "in" + case cs = "cs" + case cd = "cd" + case ov = "ov" + case sl = "sl" + case sr = "sr" + case nxl = "nxl" + case nxr = "nxr" + case adj = "adj" + case fts = "fts" + case plfts = "plfts" + case phfts = "phfts" + case wfts = "wfts" + } + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + internal enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + internal enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + internal enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + internal enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +internal enum Operations { + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(CallRpcGet)`. + internal enum CallRpcGet { + internal static let id: Swift.String = "CallRpcGet" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.CallRpcGet.Input.Path + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query/select`. + internal var select: Swift.String? + /// Function arguments — each entry becomes a query parameter. + /// Keys and value formats are defined by the PostgreSQL function signature. + /// + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query/args`. + internal var args: Components.Schemas.StringMap? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: + /// - args: Function arguments — each entry becomes a query parameter. + internal init( + select: Swift.String? = nil, + args: Components.Schemas.StringMap? = nil + ) { + self.select = select + self.args = args + } + } + internal var query: Operations.CallRpcGet.Input.Query + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.CallRpcGet.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + internal init( + path: Operations.CallRpcGet.Input.Path, + query: Operations.CallRpcGet.Input.Query = .init(), + headers: Operations.CallRpcGet.Input.Headers = .init() + ) { + self.path = path + self.query = query + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.CallRpcGet.Output.Ok.Headers + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CallRpcGet.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.CallRpcGet.Output.Ok.Headers = .init(), + body: Operations.CallRpcGet.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// CallRpcGet 200 response + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(CallRpcGet)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CallRpcGet.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CallRpcGet.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CallRpcGet.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CallRpcGet.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(CallRpcGet)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CallRpcGet.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CallRpcGet.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(CallRpcPost)`. + internal enum CallRpcPost { + internal static let id: Swift.String = "CallRpcPost" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.CallRpcPost.Input.Path + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query/select`. + internal var select: Swift.String? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: + internal init(select: Swift.String? = nil) { + self.select = select + } + } + internal var query: Operations.CallRpcPost.Input.Query + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// e.g. "params=single-object" — treat the entire body as a single parameter. + /// + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header/Prefer`. + internal var Prefer: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Profile: + /// - Prefer: e.g. "params=single-object" — treat the entire body as a single parameter. + /// - accept: + internal init( + Content_hyphen_Profile: Swift.String? = nil, + Prefer: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Prefer = Prefer + self.accept = accept + } + } + internal var headers: Operations.CallRpcPost.Input.Headers + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.CallRpcPost.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.CallRpcPost.Input.Path, + query: Operations.CallRpcPost.Input.Query = .init(), + headers: Operations.CallRpcPost.Input.Headers = .init(), + body: Operations.CallRpcPost.Input.Body? = nil + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.CallRpcPost.Output.Ok.Headers + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CallRpcPost.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.CallRpcPost.Output.Ok.Headers = .init(), + body: Operations.CallRpcPost.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// CallRpcPost 200 response + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(CallRpcPost)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.CallRpcPost.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.CallRpcPost.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.CallRpcPost.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.CallRpcPost.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(CallRpcPost)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.CallRpcPost.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.CallRpcPost.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(SelectRows)`. + internal enum SelectRows { + internal static let id: Swift.String = "SelectRows" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.SelectRows.Input.Path + /// - Remark: Generated from `#/paths/{table}/GET/query`. + internal struct Query: Sendable, Hashable { + /// Column selection — comma-separated, supports aliasing, casting, embedded + /// resources, and JSON operators. e.g. "id,name,orders(total,status)". + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/select`. + internal var select: Swift.String? + /// Ordering — e.g. "name.asc,age.desc.nullslast" + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/order`. + internal var order: Swift.String? + /// Maximum number of rows to return. + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/limit`. + internal var limit: Swift.Double? + /// Row offset for pagination. + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/offset`. + internal var offset: Swift.Double? + /// Horizontal filters — each entry becomes a query parameter. + /// Key: column name (or "or"/"and" for logical groups). + /// Value: "{operator}.{value}" e.g. {"id": "eq.5", "name": "like.foo*"}. + /// See FilterOperator for the full list of operators. + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/filters`. + internal var filters: Components.Schemas.StringMap? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: Column selection — comma-separated, supports aliasing, casting, embedded + /// - order: Ordering — e.g. "name.asc,age.desc.nullslast" + /// - limit: Maximum number of rows to return. + /// - offset: Row offset for pagination. + /// - filters: Horizontal filters — each entry becomes a query parameter. + internal init( + select: Swift.String? = nil, + order: Swift.String? = nil, + limit: Swift.Double? = nil, + offset: Swift.Double? = nil, + filters: Components.Schemas.StringMap? = nil + ) { + self.select = select + self.order = order + self.limit = limit + self.offset = offset + self.filters = filters + } + } + internal var query: Operations.SelectRows.Input.Query + /// - Remark: Generated from `#/paths/{table}/GET/header`. + internal struct Headers: Sendable, Hashable { + /// Target a non-default schema exposed by PostgREST. + /// + /// - Remark: Generated from `#/paths/{table}/GET/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + /// Counting mode. e.g. "count=exact", "count=planned", "count=estimated". + /// + /// - Remark: Generated from `#/paths/{table}/GET/header/Prefer`. + internal var Prefer: Swift.String? + /// Range-based pagination — e.g. "0-9" (ten rows starting at 0). + /// + /// - Remark: Generated from `#/paths/{table}/GET/header/Range`. + internal var Range: Swift.String? + /// Unit for the Range header. Defaults to "items". + /// + /// - Remark: Generated from `#/paths/{table}/GET/header/Range-Unit`. + internal var Range_hyphen_Unit: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Profile: Target a non-default schema exposed by PostgREST. + /// - Prefer: Counting mode. e.g. "count=exact", "count=planned", "count=estimated". + /// - Range: Range-based pagination — e.g. "0-9" (ten rows starting at 0). + /// - Range_hyphen_Unit: Unit for the Range header. Defaults to "items". + /// - accept: + internal init( + Accept_hyphen_Profile: Swift.String? = nil, + Prefer: Swift.String? = nil, + Range: Swift.String? = nil, + Range_hyphen_Unit: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.Prefer = Prefer + self.Range = Range + self.Range_hyphen_Unit = Range_hyphen_Unit + self.accept = accept + } + } + internal var headers: Operations.SelectRows.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + internal init( + path: Operations.SelectRows.Input.Path, + query: Operations.SelectRows.Input.Query = .init(), + headers: Operations.SelectRows.Input.Headers = .init() + ) { + self.path = path + self.query = query + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + /// + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.SelectRows.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.SelectRows.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.SelectRows.Output.Ok.Headers = .init(), + body: Operations.SelectRows.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// SelectRows 200 response + /// + /// - Remark: Generated from `#/paths//{table}/get(SelectRows)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.SelectRows.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.SelectRows.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.SelectRows.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.SelectRows.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//{table}/get(SelectRows)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.SelectRows.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.SelectRows.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(InsertRows)`. + internal enum InsertRows { + internal static let id: Swift.String = "InsertRows" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.InsertRows.Input.Path + /// - Remark: Generated from `#/paths/{table}/POST/query`. + internal struct Query: Sendable, Hashable { + /// Columns to select in the returned representation (requires return=representation). + /// + /// - Remark: Generated from `#/paths/{table}/POST/query/select`. + internal var select: Swift.String? + /// Restrict which columns may be populated (useful with CSV uploads). + /// + /// - Remark: Generated from `#/paths/{table}/POST/query/columns`. + internal var columns: Swift.String? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: Columns to select in the returned representation (requires return=representation). + /// - columns: Restrict which columns may be populated (useful with CSV uploads). + internal init( + select: Swift.String? = nil, + columns: Swift.String? = nil + ) { + self.select = select + self.columns = columns + } + } + internal var query: Operations.InsertRows.Input.Query + /// - Remark: Generated from `#/paths/{table}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// Target a non-default schema for the write. + /// + /// - Remark: Generated from `#/paths/{table}/POST/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// Return behavior and conflict handling. + /// e.g. "return=representation", "return=minimal" (default), + /// "return=headers-only", "resolution=merge-duplicates". + /// + /// - Remark: Generated from `#/paths/{table}/POST/header/Prefer`. + internal var Prefer: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Profile: Target a non-default schema for the write. + /// - Prefer: Return behavior and conflict handling. + /// - accept: + internal init( + Content_hyphen_Profile: Swift.String? = nil, + Prefer: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Prefer = Prefer + self.accept = accept + } + } + internal var headers: Operations.InsertRows.Input.Headers + /// - Remark: Generated from `#/paths/{table}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.InsertRows.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.InsertRows.Input.Path, + query: Operations.InsertRows.Input.Query = .init(), + headers: Operations.InsertRows.Input.Headers = .init(), + body: Operations.InsertRows.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Created: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/headers`. + internal struct Headers: Sendable, Hashable { + /// Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + /// + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.InsertRows.Output.Created.Headers + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.InsertRows.Output.Created.Body + /// Creates a new `Created`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.InsertRows.Output.Created.Headers = .init(), + body: Operations.InsertRows.Output.Created.Body + ) { + self.headers = headers + self.body = body + } + } + /// InsertRows 201 response + /// + /// - Remark: Generated from `#/paths//{table}/post(InsertRows)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.InsertRows.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + internal var created: Operations.InsertRows.Output.Created { + get throws { + switch self { + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.InsertRows.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.InsertRows.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//{table}/post(InsertRows)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.InsertRows.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.InsertRows.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(UpdateRows)`. + internal enum UpdateRows { + internal static let id: Swift.String = "UpdateRows" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.UpdateRows.Input.Path + /// - Remark: Generated from `#/paths/{table}/PATCH/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/query/select`. + internal var select: Swift.String? + /// Horizontal filters — rows matching these filters will be updated. + /// Key: column name. Value: "{operator}.{value}" e.g. {"id": "eq.5"}. + /// + /// - Remark: Generated from `#/paths/{table}/PATCH/query/filters`. + internal var filters: Components.Schemas.StringMap? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: + /// - filters: Horizontal filters — rows matching these filters will be updated. + internal init( + select: Swift.String? = nil, + filters: Components.Schemas.StringMap? = nil + ) { + self.select = select + self.filters = filters + } + } + internal var query: Operations.UpdateRows.Input.Query + /// - Remark: Generated from `#/paths/{table}/PATCH/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PATCH/header/Prefer`. + internal var Prefer: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Profile: + /// - Prefer: + /// - accept: + internal init( + Content_hyphen_Profile: Swift.String? = nil, + Prefer: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Prefer = Prefer + self.accept = accept + } + } + internal var headers: Operations.UpdateRows.Input.Headers + /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.UpdateRows.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.UpdateRows.Input.Path, + query: Operations.UpdateRows.Input.Query = .init(), + headers: Operations.UpdateRows.Input.Headers = .init(), + body: Operations.UpdateRows.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + /// + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.UpdateRows.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpdateRows.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.UpdateRows.Output.Ok.Headers = .init(), + body: Operations.UpdateRows.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// UpdateRows 200 response + /// + /// - Remark: Generated from `#/paths//{table}/patch(UpdateRows)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.UpdateRows.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.UpdateRows.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpdateRows.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UpdateRows.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//{table}/patch(UpdateRows)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.UpdateRows.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.UpdateRows.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(UpsertRows)`. + internal enum UpsertRows { + internal static let id: Swift.String = "UpsertRows" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.UpsertRows.Input.Path + /// - Remark: Generated from `#/paths/{table}/PUT/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/query/select`. + internal var select: Swift.String? + /// Columns to match for conflict detection (if not the primary key). + /// + /// - Remark: Generated from `#/paths/{table}/PUT/query/on_conflict`. + internal var on_conflict: Swift.String? + /// Horizontal filters — rows matching these filters will be upserted. + /// + /// - Remark: Generated from `#/paths/{table}/PUT/query/filters`. + internal var filters: Components.Schemas.StringMap? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: + /// - on_conflict: Columns to match for conflict detection (if not the primary key). + /// - filters: Horizontal filters — rows matching these filters will be upserted. + internal init( + select: Swift.String? = nil, + on_conflict: Swift.String? = nil, + filters: Components.Schemas.StringMap? = nil + ) { + self.select = select + self.on_conflict = on_conflict + self.filters = filters + } + } + internal var query: Operations.UpsertRows.Input.Query + /// - Remark: Generated from `#/paths/{table}/PUT/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// e.g. "return=representation", "resolution=merge-duplicates", + /// "resolution=ignore-duplicates". + /// + /// - Remark: Generated from `#/paths/{table}/PUT/header/Prefer`. + internal var Prefer: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Profile: + /// - Prefer: e.g. "return=representation", "resolution=merge-duplicates", + /// - accept: + internal init( + Content_hyphen_Profile: Swift.String? = nil, + Prefer: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Prefer = Prefer + self.accept = accept + } + } + internal var headers: Operations.UpsertRows.Input.Headers + /// - Remark: Generated from `#/paths/{table}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.UpsertRows.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.UpsertRows.Input.Path, + query: Operations.UpsertRows.Input.Query = .init(), + headers: Operations.UpsertRows.Input.Headers = .init(), + body: Operations.UpsertRows.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + /// + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.UpsertRows.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpsertRows.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.UpsertRows.Output.Ok.Headers = .init(), + body: Operations.UpsertRows.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// UpsertRows 200 response + /// + /// - Remark: Generated from `#/paths//{table}/put(UpsertRows)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.UpsertRows.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.UpsertRows.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.UpsertRows.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.UpsertRows.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//{table}/put(UpsertRows)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.UpsertRows.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.UpsertRows.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(DeleteRows)`. + internal enum DeleteRows { + internal static let id: Swift.String = "DeleteRows" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.DeleteRows.Input.Path + /// - Remark: Generated from `#/paths/{table}/DELETE/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/query/select`. + internal var select: Swift.String? + /// Horizontal filters — rows matching these filters will be deleted. + /// + /// - Remark: Generated from `#/paths/{table}/DELETE/query/filters`. + internal var filters: Components.Schemas.StringMap? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: + /// - filters: Horizontal filters — rows matching these filters will be deleted. + internal init( + select: Swift.String? = nil, + filters: Components.Schemas.StringMap? = nil + ) { + self.select = select + self.filters = filters + } + } + internal var query: Operations.DeleteRows.Input.Query + /// - Remark: Generated from `#/paths/{table}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/{table}/DELETE/header/Prefer`. + internal var Prefer: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Profile: + /// - Prefer: + /// - accept: + internal init( + Content_hyphen_Profile: Swift.String? = nil, + Prefer: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Prefer = Prefer + self.accept = accept + } + } + internal var headers: Operations.DeleteRows.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + internal init( + path: Operations.DeleteRows.Input.Path, + query: Operations.DeleteRows.Input.Query = .init(), + headers: Operations.DeleteRows.Input.Headers = .init() + ) { + self.path = path + self.query = query + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + /// + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: Pagination info — e.g. "0-9/200" (range/total) or "0-9/*" (unknown count). + internal init(Content_hyphen_Range: Swift.String? = nil) { + self.Content_hyphen_Range = Content_hyphen_Range + } + } + /// Received HTTP response headers + internal var headers: Operations.DeleteRows.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.DeleteRows.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.DeleteRows.Output.Ok.Headers = .init(), + body: Operations.DeleteRows.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// DeleteRows 200 response + /// + /// - Remark: Generated from `#/paths//{table}/delete(DeleteRows)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.DeleteRows.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.DeleteRows.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct BadRequest: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/400/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/400/content/application\/json`. + case json(Components.Schemas.DatabaseErrorResponseContent) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.DatabaseErrorResponseContent { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.DeleteRows.Output.BadRequest.Body + /// Creates a new `BadRequest`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.DeleteRows.Output.BadRequest.Body) { + self.body = body + } + } + /// DatabaseError 400 response + /// + /// - Remark: Generated from `#/paths//{table}/delete(DeleteRows)/responses/400`. + /// + /// HTTP response code: `400 badRequest`. + case badRequest(Operations.DeleteRows.Output.BadRequest) + /// The associated value of the enum case if `self` is `.badRequest`. + /// + /// - Throws: An error if `self` is not `.badRequest`. + /// - SeeAlso: `.badRequest`. + internal var badRequest: Operations.DeleteRows.Output.BadRequest { + get throws { + switch self { + case let .badRequest(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "badRequest", + response: self + ) + } + } + } + /// Undocumented response. + /// + /// A response with a code that is not documented in the OpenAPI document. + case undocumented(statusCode: Swift.Int, OpenAPIRuntime.UndocumentedPayload) + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } +} diff --git a/Sources/PostgREST/openapi-generator-config.yaml b/Sources/PostgREST/openapi-generator-config.yaml new file mode 100644 index 000000000..1df6f2876 --- /dev/null +++ b/Sources/PostgREST/openapi-generator-config.yaml @@ -0,0 +1,4 @@ +generate: + - types + - client +accessModifier: internal diff --git a/smithy/output/openapi/DatabaseService.openapi.json b/smithy/output/openapi/DatabaseService.openapi.json new file mode 100644 index 000000000..51263cdd7 --- /dev/null +++ b/smithy/output/openapi/DatabaseService.openapi.json @@ -0,0 +1,741 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "Supabase Database API", + "version": "1.0", + "description": "PostgREST-backed database API.\n\nBase URL: https://{project-ref}.supabase.co/rest/v1\n\nKnown limitations:\n 1. Write operations return 204 (no body) by default and 200 with a body when\n Prefer: return=representation \u2014 the model uses 200 throughout so generators\n always produce body-parsing code; clients must tolerate empty bodies.\n 2. RPC GET arguments are function-specific; they are expressed via the same\n @httpQueryParams map as row filters, with function-defined keys." + }, + "paths": { + "/rpc/{functionName}": { + "get": { + "operationId": "CallRpcGet", + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "args", + "in": "query", + "description": "Function arguments \u2014 each entry becomes a query parameter.\nKeys and value formats are defined by the PostgreSQL function signature.", + "style": "form", + "schema": { + "$ref": "#/components/schemas/StringMap" + } + }, + { + "name": "Accept-Profile", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "CallRpcGet 200 response", + "headers": { + "Content-Range": { + "schema": { + "type": "string" + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/CallRpcGetOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + }, + "post": { + "operationId": "CallRpcPost", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/CallRpcPostInputPayload" + } + } + } + }, + "parameters": [ + { + "name": "functionName", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "Content-Profile", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "Prefer", + "in": "header", + "description": "e.g. \"params=single-object\" \u2014 treat the entire body as a single parameter.", + "schema": { + "type": "string", + "description": "e.g. \"params=single-object\" \u2014 treat the entire body as a single parameter." + } + } + ], + "responses": { + "200": { + "description": "CallRpcPost 200 response", + "headers": { + "Content-Range": { + "schema": { + "type": "string" + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/CallRpcPostOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + } + }, + "/{table}": { + "delete": { + "operationId": "DeleteRows", + "parameters": [ + { + "name": "table", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "filters", + "in": "query", + "description": "Horizontal filters \u2014 rows matching these filters will be deleted.", + "style": "form", + "schema": { + "$ref": "#/components/schemas/StringMap" + } + }, + { + "name": "Content-Profile", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "Prefer", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "DeleteRows 200 response", + "headers": { + "Content-Range": { + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count).", + "schema": { + "type": "string", + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count)." + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/DeleteRowsOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + }, + "get": { + "operationId": "SelectRows", + "parameters": [ + { + "name": "table", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "description": "Column selection \u2014 comma-separated, supports aliasing, casting, embedded\nresources, and JSON operators. e.g. \"id,name,orders(total,status)\".", + "schema": { + "type": "string", + "description": "Column selection \u2014 comma-separated, supports aliasing, casting, embedded\nresources, and JSON operators. e.g. \"id,name,orders(total,status)\"." + } + }, + { + "name": "order", + "in": "query", + "description": "Ordering \u2014 e.g. \"name.asc,age.desc.nullslast\"", + "schema": { + "type": "string", + "description": "Ordering \u2014 e.g. \"name.asc,age.desc.nullslast\"" + } + }, + { + "name": "limit", + "in": "query", + "description": "Maximum number of rows to return.", + "schema": { + "type": "number", + "description": "Maximum number of rows to return." + } + }, + { + "name": "offset", + "in": "query", + "description": "Row offset for pagination.", + "schema": { + "type": "number", + "description": "Row offset for pagination." + } + }, + { + "name": "filters", + "in": "query", + "description": "Horizontal filters \u2014 each entry becomes a query parameter.\nKey: column name (or \"or\"/\"and\" for logical groups).\nValue: \"{operator}.{value}\" e.g. {\"id\": \"eq.5\", \"name\": \"like.foo*\"}.\nSee FilterOperator for the full list of operators.", + "style": "form", + "schema": { + "$ref": "#/components/schemas/StringMap" + } + }, + { + "name": "Accept", + "in": "header", + "description": "Response format. e.g. \"application/json\" (default), \"text/csv\",\n\"application/vnd.pgrst.object+json\" (singular-row mode).", + "schema": { + "type": "string", + "description": "Response format. e.g. \"application/json\" (default), \"text/csv\",\n\"application/vnd.pgrst.object+json\" (singular-row mode)." + } + }, + { + "name": "Accept-Profile", + "in": "header", + "description": "Target a non-default schema exposed by PostgREST.", + "schema": { + "type": "string", + "description": "Target a non-default schema exposed by PostgREST." + } + }, + { + "name": "Prefer", + "in": "header", + "description": "Counting mode. e.g. \"count=exact\", \"count=planned\", \"count=estimated\".", + "schema": { + "type": "string", + "description": "Counting mode. e.g. \"count=exact\", \"count=planned\", \"count=estimated\"." + } + }, + { + "name": "Range", + "in": "header", + "description": "Range-based pagination \u2014 e.g. \"0-9\" (ten rows starting at 0).", + "schema": { + "type": "string", + "description": "Range-based pagination \u2014 e.g. \"0-9\" (ten rows starting at 0)." + } + }, + { + "name": "Range-Unit", + "in": "header", + "description": "Unit for the Range header. Defaults to \"items\".", + "schema": { + "type": "string", + "description": "Unit for the Range header. Defaults to \"items\"." + } + } + ], + "responses": { + "200": { + "description": "SelectRows 200 response", + "headers": { + "Content-Range": { + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count).", + "schema": { + "type": "string", + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count)." + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/SelectRowsOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + }, + "patch": { + "operationId": "UpdateRows", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/UpdateRowsInputPayload" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "table", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "filters", + "in": "query", + "description": "Horizontal filters \u2014 rows matching these filters will be updated.\nKey: column name. Value: \"{operator}.{value}\" e.g. {\"id\": \"eq.5\"}.", + "style": "form", + "schema": { + "$ref": "#/components/schemas/StringMap" + } + }, + { + "name": "Content-Profile", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "Prefer", + "in": "header", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "UpdateRows 200 response", + "headers": { + "Content-Range": { + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count).", + "schema": { + "type": "string", + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count)." + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/UpdateRowsOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + }, + "post": { + "operationId": "InsertRows", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InsertRowsInputPayload" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "table", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "description": "Columns to select in the returned representation (requires return=representation).", + "schema": { + "type": "string", + "description": "Columns to select in the returned representation (requires return=representation)." + } + }, + { + "name": "columns", + "in": "query", + "description": "Restrict which columns may be populated (useful with CSV uploads).", + "schema": { + "type": "string", + "description": "Restrict which columns may be populated (useful with CSV uploads)." + } + }, + { + "name": "Content-Profile", + "in": "header", + "description": "Target a non-default schema for the write.", + "schema": { + "type": "string", + "description": "Target a non-default schema for the write." + } + }, + { + "name": "Prefer", + "in": "header", + "description": "Return behavior and conflict handling.\ne.g. \"return=representation\", \"return=minimal\" (default),\n \"return=headers-only\", \"resolution=merge-duplicates\".", + "schema": { + "type": "string", + "description": "Return behavior and conflict handling.\ne.g. \"return=representation\", \"return=minimal\" (default),\n \"return=headers-only\", \"resolution=merge-duplicates\"." + } + } + ], + "responses": { + "201": { + "description": "InsertRows 201 response", + "headers": { + "Content-Range": { + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count).", + "schema": { + "type": "string", + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count)." + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/InsertRowsOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + }, + "put": { + "operationId": "UpsertRows", + "requestBody": { + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/UpsertRowsInputPayload" + } + } + }, + "required": true + }, + "parameters": [ + { + "name": "table", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "select", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "on_conflict", + "in": "query", + "description": "Columns to match for conflict detection (if not the primary key).", + "schema": { + "type": "string", + "description": "Columns to match for conflict detection (if not the primary key)." + } + }, + { + "name": "filters", + "in": "query", + "description": "Horizontal filters \u2014 rows matching these filters will be upserted.", + "style": "form", + "schema": { + "$ref": "#/components/schemas/StringMap" + } + }, + { + "name": "Content-Profile", + "in": "header", + "schema": { + "type": "string" + } + }, + { + "name": "Prefer", + "in": "header", + "description": "e.g. \"return=representation\", \"resolution=merge-duplicates\",\n \"resolution=ignore-duplicates\".", + "schema": { + "type": "string", + "description": "e.g. \"return=representation\", \"resolution=merge-duplicates\",\n \"resolution=ignore-duplicates\"." + } + } + ], + "responses": { + "200": { + "description": "UpsertRows 200 response", + "headers": { + "Content-Range": { + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count).", + "schema": { + "type": "string", + "description": "Pagination info \u2014 e.g. \"0-9/200\" (range/total) or \"0-9/*\" (unknown count)." + } + } + }, + "content": { + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/UpsertRowsOutputPayload" + } + } + } + }, + "400": { + "description": "DatabaseError 400 response", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatabaseErrorResponseContent" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "CallRpcGetOutputPayload": { + "type": "string", + "format": "byte" + }, + "CallRpcPostInputPayload": { + "type": "string", + "description": "Named parameters as a JSON object, or a single argument when combined\nwith Prefer: params=single-object.", + "format": "byte" + }, + "CallRpcPostOutputPayload": { + "type": "string", + "format": "byte" + }, + "DatabaseErrorResponseContent": { + "type": "object", + "properties": { + "code": { + "type": "string", + "description": "PostgreSQL error code (e.g. \"23505\") or PostgREST error code (e.g. \"PGRST301\")." + }, + "message": { + "type": "string", + "description": "Human-readable error message." + }, + "details": { + "type": "string", + "description": "Extra context \u2014 constraint name, offending column, etc." + }, + "hint": { + "type": "string", + "description": "Hint from PostgreSQL." + } + } + }, + "DeleteRowsOutputPayload": { + "type": "string", + "format": "byte" + }, + "InsertRowsInputPayload": { + "type": "string", + "description": "JSON object or array of objects to insert.", + "format": "byte" + }, + "InsertRowsOutputPayload": { + "type": "string", + "format": "byte" + }, + "SelectRowsOutputPayload": { + "type": "string", + "format": "byte" + }, + "StringMap": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "description": "Generic string-to-string map \u2014 used for arbitrary query parameter collections\n(e.g. PostgREST filter params, RPC GET arguments)." + }, + "UpdateRowsInputPayload": { + "type": "string", + "description": "Partial JSON object with fields to update.", + "format": "byte" + }, + "UpdateRowsOutputPayload": { + "type": "string", + "format": "byte" + }, + "UpsertRowsInputPayload": { + "type": "string", + "description": "JSON object or array of objects to upsert.", + "format": "byte" + }, + "UpsertRowsOutputPayload": { + "type": "string", + "format": "byte" + }, + "FilterOperator": { + "type": "string", + "description": "PostgREST column filter operators. Format a filter value as \"{operator}.{value}\", e.g. \"eq.5\". Prefix with \"not.\" to negate: \"not.eq.5\". For logical grouping use keys \"or\" / \"and\" in the filters map.", + "enum": [ + "eq", + "neq", + "lt", + "lte", + "gt", + "gte", + "like", + "ilike", + "match", + "imatch", + "is", + "isdistinct", + "in", + "cs", + "cd", + "ov", + "sl", + "sr", + "nxl", + "nxr", + "adj", + "fts", + "plfts", + "phfts", + "wfts" + ] + } + } + } +} \ No newline at end of file From 41584ccb4aa1fa5093b344164b330f5e8e6a6c5a Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 08:14:54 -0300 Subject: [PATCH 26/32] spike(typespec): generate Swift clients from TypeSpec OpenAPI (PR #53 in supabase/sdk) Generated from typespec/openapi artifacts in supabase/sdk PR #53 for side-by-side comparison against the Smithy-generated clients. Line counts: Storage: 1376+3963 = 5339 (Smithy: 1773+4729 = 6502) Functions: 494+1134 = 1628 (Smithy: 253+ 290 = 543) PostgREST: 745+1724 = 2469 (Smithy: 912+2057 = 2969) Total: = 9436 (Smithy: = 10014) --- .../Functions/GeneratedTypeSpec/Client.swift | 494 ++ .../Functions/GeneratedTypeSpec/Types.swift | 1134 +++++ .../PostgREST/GeneratedTypeSpec/Client.swift | 745 ++++ .../PostgREST/GeneratedTypeSpec/Types.swift | 1724 +++++++ .../Storage/GeneratedTypeSpec/Client.swift | 1376 ++++++ Sources/Storage/GeneratedTypeSpec/Types.swift | 3963 +++++++++++++++++ .../openapi.Supabase.Functions.yaml | 183 + .../openapi.Supabase.PostgREST.yaml | 344 ++ .../openapi.Supabase.Storage.yaml | 723 +++ 9 files changed, 10686 insertions(+) create mode 100644 Sources/Functions/GeneratedTypeSpec/Client.swift create mode 100644 Sources/Functions/GeneratedTypeSpec/Types.swift create mode 100644 Sources/PostgREST/GeneratedTypeSpec/Client.swift create mode 100644 Sources/PostgREST/GeneratedTypeSpec/Types.swift create mode 100644 Sources/Storage/GeneratedTypeSpec/Client.swift create mode 100644 Sources/Storage/GeneratedTypeSpec/Types.swift create mode 100644 smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml create mode 100644 smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml create mode 100644 smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml diff --git a/Sources/Functions/GeneratedTypeSpec/Client.swift b/Sources/Functions/GeneratedTypeSpec/Client.swift new file mode 100644 index 000000000..bd985f607 --- /dev/null +++ b/Sources/Functions/GeneratedTypeSpec/Client.swift @@ -0,0 +1,494 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +internal struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { + client.converter + } + /// - Remark: HTTP `GET /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/get(FunctionInvocations_invokeGet)`. + internal func FunctionInvocations_invokeGet(_ input: Operations.FunctionInvocations_invokeGet.Input) async throws -> Operations.FunctionInvocations_invokeGet.Output { + try await client.send( + input: input, + forOperation: Operations.FunctionInvocations_invokeGet.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: input.headers.x_hyphen_region + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokeGet.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokeGet.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(FunctionInvocations_invokePost)`. + internal func FunctionInvocations_invokePost(_ input: Operations.FunctionInvocations_invokePost.Input) async throws -> Operations.FunctionInvocations_invokePost.Output { + try await client.send( + input: input, + forOperation: Operations.FunctionInvocations_invokePost.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: input.headers.x_hyphen_region + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case .none: + body = nil + case let .binary(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokePost.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokePost.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PATCH /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/patch(FunctionInvocations_invokePatch)`. + internal func FunctionInvocations_invokePatch(_ input: Operations.FunctionInvocations_invokePatch.Input) async throws -> Operations.FunctionInvocations_invokePatch.Output { + try await client.send( + input: input, + forOperation: Operations.FunctionInvocations_invokePatch.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .patch + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: input.headers.x_hyphen_region + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case .none: + body = nil + case let .binary(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokePatch.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokePatch.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/put(FunctionInvocations_invokePut)`. + internal func FunctionInvocations_invokePut(_ input: Operations.FunctionInvocations_invokePut.Input) async throws -> Operations.FunctionInvocations_invokePut.Output { + try await client.send( + input: input, + forOperation: Operations.FunctionInvocations_invokePut.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: input.headers.x_hyphen_region + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case .none: + body = nil + case let .binary(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokePut.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokePut.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/delete(FunctionInvocations_invokeDelete)`. + internal func FunctionInvocations_invokeDelete(_ input: Operations.FunctionInvocations_invokeDelete.Input) async throws -> Operations.FunctionInvocations_invokeDelete.Output { + try await client.send( + input: input, + forOperation: Operations.FunctionInvocations_invokeDelete.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/functions/v1/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-region", + value: input.headers.x_hyphen_region + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case .none: + body = nil + case let .binary(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokeDelete.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/octet-stream" + ] + ) + switch chosenContentType { + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .binary(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.FunctionInvocations_invokeDelete.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FunctionsError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } +} diff --git a/Sources/Functions/GeneratedTypeSpec/Types.swift b/Sources/Functions/GeneratedTypeSpec/Types.swift new file mode 100644 index 000000000..fc91bcd9e --- /dev/null +++ b/Sources/Functions/GeneratedTypeSpec/Types.swift @@ -0,0 +1,1134 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +internal protocol APIProtocol: Sendable { + /// - Remark: HTTP `GET /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/get(FunctionInvocations_invokeGet)`. + func FunctionInvocations_invokeGet(_ input: Operations.FunctionInvocations_invokeGet.Input) async throws -> Operations.FunctionInvocations_invokeGet.Output + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(FunctionInvocations_invokePost)`. + func FunctionInvocations_invokePost(_ input: Operations.FunctionInvocations_invokePost.Input) async throws -> Operations.FunctionInvocations_invokePost.Output + /// - Remark: HTTP `PATCH /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/patch(FunctionInvocations_invokePatch)`. + func FunctionInvocations_invokePatch(_ input: Operations.FunctionInvocations_invokePatch.Input) async throws -> Operations.FunctionInvocations_invokePatch.Output + /// - Remark: HTTP `PUT /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/put(FunctionInvocations_invokePut)`. + func FunctionInvocations_invokePut(_ input: Operations.FunctionInvocations_invokePut.Input) async throws -> Operations.FunctionInvocations_invokePut.Output + /// - Remark: HTTP `DELETE /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/delete(FunctionInvocations_invokeDelete)`. + func FunctionInvocations_invokeDelete(_ input: Operations.FunctionInvocations_invokeDelete.Input) async throws -> Operations.FunctionInvocations_invokeDelete.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// - Remark: HTTP `GET /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/get(FunctionInvocations_invokeGet)`. + internal func FunctionInvocations_invokeGet( + path: Operations.FunctionInvocations_invokeGet.Input.Path, + headers: Operations.FunctionInvocations_invokeGet.Input.Headers = .init() + ) async throws -> Operations.FunctionInvocations_invokeGet.Output { + try await FunctionInvocations_invokeGet(Operations.FunctionInvocations_invokeGet.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(FunctionInvocations_invokePost)`. + internal func FunctionInvocations_invokePost( + path: Operations.FunctionInvocations_invokePost.Input.Path, + headers: Operations.FunctionInvocations_invokePost.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokePost.Input.Body? = nil + ) async throws -> Operations.FunctionInvocations_invokePost.Output { + try await FunctionInvocations_invokePost(Operations.FunctionInvocations_invokePost.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PATCH /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/patch(FunctionInvocations_invokePatch)`. + internal func FunctionInvocations_invokePatch( + path: Operations.FunctionInvocations_invokePatch.Input.Path, + headers: Operations.FunctionInvocations_invokePatch.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokePatch.Input.Body? = nil + ) async throws -> Operations.FunctionInvocations_invokePatch.Output { + try await FunctionInvocations_invokePatch(Operations.FunctionInvocations_invokePatch.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PUT /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/put(FunctionInvocations_invokePut)`. + internal func FunctionInvocations_invokePut( + path: Operations.FunctionInvocations_invokePut.Input.Path, + headers: Operations.FunctionInvocations_invokePut.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokePut.Input.Body? = nil + ) async throws -> Operations.FunctionInvocations_invokePut.Output { + try await FunctionInvocations_invokePut(Operations.FunctionInvocations_invokePut.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `DELETE /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/delete(FunctionInvocations_invokeDelete)`. + internal func FunctionInvocations_invokeDelete( + path: Operations.FunctionInvocations_invokeDelete.Input.Path, + headers: Operations.FunctionInvocations_invokeDelete.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokeDelete.Input.Body? = nil + ) async throws -> Operations.FunctionInvocations_invokeDelete.Output { + try await FunctionInvocations_invokeDelete(Operations.FunctionInvocations_invokeDelete.Input( + path: path, + headers: headers, + body: body + )) + } +} + +/// Server URLs defined in the OpenAPI document. +internal enum Servers { + /// Supabase Edge Functions endpoint + internal enum Server1 { + /// Supabase Edge Functions endpoint + /// + /// - Parameters: + /// - baseUrl: + internal static func url(baseUrl: Swift.String = "") throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "{baseUrl}", + variables: [ + .init( + name: "baseUrl", + value: baseUrl + ) + ] + ) + } + } + /// Supabase Edge Functions endpoint + /// + /// - Parameters: + /// - baseUrl: + @available(*, deprecated, renamed: "Servers.Server1.url") + internal static func server1(baseUrl: Swift.String = "") throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "{baseUrl}", + variables: [ + .init( + name: "baseUrl", + value: baseUrl + ) + ] + ) + } +} + +/// Types generated from the components section of the OpenAPI document. +internal enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + internal enum Schemas { + /// - Remark: Generated from `#/components/schemas/FunctionsError`. + internal struct FunctionsError: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FunctionsError/message`. + internal var message: Swift.String? + /// Creates a new `FunctionsError`. + /// + /// - Parameters: + /// - message: + internal init(message: Swift.String? = nil) { + self.message = message + } + internal enum CodingKeys: String, CodingKey { + case message + } + } + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + internal enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + internal enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + internal enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + internal enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +internal enum Operations { + /// - Remark: HTTP `GET /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/get(FunctionInvocations_invokeGet)`. + internal enum FunctionInvocations_invokeGet { + internal static let id: Swift.String = "FunctionInvocations_invokeGet" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.FunctionInvocations_invokeGet.Input.Path + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/header/x-region`. + internal var x_hyphen_region: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_region: + /// - accept: + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Operations.FunctionInvocations_invokeGet.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.FunctionInvocations_invokeGet.Input.Path, + headers: Operations.FunctionInvocations_invokeGet.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokeGet.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokeGet.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/get(FunctionInvocations_invokeGet)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.FunctionInvocations_invokeGet.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.FunctionInvocations_invokeGet.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/default/content/application\/json`. + case json(Components.Schemas.FunctionsError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FunctionsError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokeGet.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokeGet.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/get(FunctionInvocations_invokeGet)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.FunctionInvocations_invokeGet.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.FunctionInvocations_invokeGet.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `POST /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(FunctionInvocations_invokePost)`. + internal enum FunctionInvocations_invokePost { + internal static let id: Swift.String = "FunctionInvocations_invokePost" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.FunctionInvocations_invokePost.Input.Path + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/header/x-region`. + internal var x_hyphen_region: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_region: + /// - accept: + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Operations.FunctionInvocations_invokePost.Input.Headers + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.FunctionInvocations_invokePost.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.FunctionInvocations_invokePost.Input.Path, + headers: Operations.FunctionInvocations_invokePost.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokePost.Input.Body? = nil + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokePost.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokePost.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(FunctionInvocations_invokePost)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.FunctionInvocations_invokePost.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.FunctionInvocations_invokePost.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.FunctionsError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FunctionsError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokePost.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokePost.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/post(FunctionInvocations_invokePost)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.FunctionInvocations_invokePost.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.FunctionInvocations_invokePost.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `PATCH /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/patch(FunctionInvocations_invokePatch)`. + internal enum FunctionInvocations_invokePatch { + internal static let id: Swift.String = "FunctionInvocations_invokePatch" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.FunctionInvocations_invokePatch.Input.Path + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/header/x-region`. + internal var x_hyphen_region: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_region: + /// - accept: + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Operations.FunctionInvocations_invokePatch.Input.Headers + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.FunctionInvocations_invokePatch.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.FunctionInvocations_invokePatch.Input.Path, + headers: Operations.FunctionInvocations_invokePatch.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokePatch.Input.Body? = nil + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokePatch.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokePatch.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/patch(FunctionInvocations_invokePatch)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.FunctionInvocations_invokePatch.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.FunctionInvocations_invokePatch.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/default/content/application\/json`. + case json(Components.Schemas.FunctionsError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FunctionsError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokePatch.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokePatch.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/patch(FunctionInvocations_invokePatch)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.FunctionInvocations_invokePatch.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.FunctionInvocations_invokePatch.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `PUT /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/put(FunctionInvocations_invokePut)`. + internal enum FunctionInvocations_invokePut { + internal static let id: Swift.String = "FunctionInvocations_invokePut" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.FunctionInvocations_invokePut.Input.Path + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/header/x-region`. + internal var x_hyphen_region: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_region: + /// - accept: + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Operations.FunctionInvocations_invokePut.Input.Headers + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.FunctionInvocations_invokePut.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.FunctionInvocations_invokePut.Input.Path, + headers: Operations.FunctionInvocations_invokePut.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokePut.Input.Body? = nil + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokePut.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokePut.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/put(FunctionInvocations_invokePut)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.FunctionInvocations_invokePut.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.FunctionInvocations_invokePut.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/default/content/application\/json`. + case json(Components.Schemas.FunctionsError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FunctionsError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokePut.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokePut.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/put(FunctionInvocations_invokePut)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.FunctionInvocations_invokePut.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.FunctionInvocations_invokePut.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /functions/v1/{functionName}`. + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/delete(FunctionInvocations_invokeDelete)`. + internal enum FunctionInvocations_invokeDelete { + internal static let id: Swift.String = "FunctionInvocations_invokeDelete" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.FunctionInvocations_invokeDelete.Input.Path + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/header/x-region`. + internal var x_hyphen_region: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_region: + /// - accept: + internal init( + x_hyphen_region: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_region = x_hyphen_region + self.accept = accept + } + } + internal var headers: Operations.FunctionInvocations_invokeDelete.Input.Headers + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.FunctionInvocations_invokeDelete.Input.Body? + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.FunctionInvocations_invokeDelete.Input.Path, + headers: Operations.FunctionInvocations_invokeDelete.Input.Headers = .init(), + body: Operations.FunctionInvocations_invokeDelete.Input.Body? = nil + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. + /// + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .binary(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokeDelete.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokeDelete.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/delete(FunctionInvocations_invokeDelete)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.FunctionInvocations_invokeDelete.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.FunctionInvocations_invokeDelete.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/default/content/application\/json`. + case json(Components.Schemas.FunctionsError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FunctionsError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.FunctionInvocations_invokeDelete.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.FunctionInvocations_invokeDelete.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//functions/v1/{functionName}/delete(FunctionInvocations_invokeDelete)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.FunctionInvocations_invokeDelete.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.FunctionInvocations_invokeDelete.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case binary + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .binary: + return "application/octet-stream" + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .binary, + .json + ] + } + } + } +} diff --git a/Sources/PostgREST/GeneratedTypeSpec/Client.swift b/Sources/PostgREST/GeneratedTypeSpec/Client.swift new file mode 100644 index 000000000..94410226b --- /dev/null +++ b/Sources/PostgREST/GeneratedTypeSpec/Client.swift @@ -0,0 +1,745 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +internal struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { + client.converter + } + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. + internal func RpcOperations_rpc(_ input: Operations.RpcOperations_rpc.Input) async throws -> Operations.RpcOperations_rpc.Output { + try await client.send( + input: input, + forOperation: Operations.RpcOperations_rpc.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/rpc/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "params", + value: input.query.params + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.RpcOperations_rpc.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.RpcOperations_rpc.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. + internal func TableOperations_from(_ input: Operations.TableOperations_from.Input) async throws -> Operations.TableOperations_from.Output { + try await client.send( + input: input, + forOperation: Operations.TableOperations_from.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "params", + value: input.query.params + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Range", + value: input.headers.Range + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.TableOperations_from.Output.Ok.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_from.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_from.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. + internal func TableOperations_insert(_ input: Operations.TableOperations_insert.Input) async throws -> Operations.TableOperations_insert.Output { + try await client.send( + input: input, + forOperation: Operations.TableOperations_insert.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "params", + value: input.query.params + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + let headers: Operations.TableOperations_insert.Output.Created.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_insert.Output.Created.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .created(.init( + headers: headers, + body: body + )) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_insert.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. + internal func TableOperations_update(_ input: Operations.TableOperations_update.Input) async throws -> Operations.TableOperations_update.Output { + try await client.send( + input: input, + forOperation: Operations.TableOperations_update.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .patch + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "params", + value: input.query.params + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.TableOperations_update.Output.Ok.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_update.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_update.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. + internal func TableOperations_upsert(_ input: Operations.TableOperations_upsert.Input) async throws -> Operations.TableOperations_upsert.Output { + try await client.send( + input: input, + forOperation: Operations.TableOperations_upsert.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "params", + value: input.query.params + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.TableOperations_upsert.Output.Ok.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_upsert.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_upsert.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. + internal func TableOperations_deleteRows(_ input: Operations.TableOperations_deleteRows.Input) async throws -> Operations.TableOperations_deleteRows.Output { + try await client.send( + input: input, + forOperation: Operations.TableOperations_deleteRows.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/{}", + parameters: [ + input.path.table + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "params", + value: input.query.params + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Prefer", + value: input.headers.Prefer + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Content-Profile", + value: input.headers.Content_hyphen_Profile + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.TableOperations_deleteRows.Output.Ok.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_deleteRows.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TableOperations_deleteRows.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } +} diff --git a/Sources/PostgREST/GeneratedTypeSpec/Types.swift b/Sources/PostgREST/GeneratedTypeSpec/Types.swift new file mode 100644 index 000000000..8d897a472 --- /dev/null +++ b/Sources/PostgREST/GeneratedTypeSpec/Types.swift @@ -0,0 +1,1724 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +internal protocol APIProtocol: Sendable { + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. + func RpcOperations_rpc(_ input: Operations.RpcOperations_rpc.Input) async throws -> Operations.RpcOperations_rpc.Output + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. + func TableOperations_from(_ input: Operations.TableOperations_from.Input) async throws -> Operations.TableOperations_from.Output + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. + func TableOperations_insert(_ input: Operations.TableOperations_insert.Input) async throws -> Operations.TableOperations_insert.Output + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. + func TableOperations_update(_ input: Operations.TableOperations_update.Input) async throws -> Operations.TableOperations_update.Output + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. + func TableOperations_upsert(_ input: Operations.TableOperations_upsert.Input) async throws -> Operations.TableOperations_upsert.Output + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. + func TableOperations_deleteRows(_ input: Operations.TableOperations_deleteRows.Input) async throws -> Operations.TableOperations_deleteRows.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. + internal func RpcOperations_rpc( + path: Operations.RpcOperations_rpc.Input.Path, + query: Operations.RpcOperations_rpc.Input.Query = .init(), + headers: Operations.RpcOperations_rpc.Input.Headers = .init(), + body: Operations.RpcOperations_rpc.Input.Body + ) async throws -> Operations.RpcOperations_rpc.Output { + try await RpcOperations_rpc(Operations.RpcOperations_rpc.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. + internal func TableOperations_from( + path: Operations.TableOperations_from.Input.Path, + query: Operations.TableOperations_from.Input.Query = .init(), + headers: Operations.TableOperations_from.Input.Headers = .init() + ) async throws -> Operations.TableOperations_from.Output { + try await TableOperations_from(Operations.TableOperations_from.Input( + path: path, + query: query, + headers: headers + )) + } + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. + internal func TableOperations_insert( + path: Operations.TableOperations_insert.Input.Path, + query: Operations.TableOperations_insert.Input.Query = .init(), + headers: Operations.TableOperations_insert.Input.Headers = .init(), + body: Operations.TableOperations_insert.Input.Body + ) async throws -> Operations.TableOperations_insert.Output { + try await TableOperations_insert(Operations.TableOperations_insert.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. + internal func TableOperations_update( + path: Operations.TableOperations_update.Input.Path, + query: Operations.TableOperations_update.Input.Query = .init(), + headers: Operations.TableOperations_update.Input.Headers = .init(), + body: Operations.TableOperations_update.Input.Body + ) async throws -> Operations.TableOperations_update.Output { + try await TableOperations_update(Operations.TableOperations_update.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. + internal func TableOperations_upsert( + path: Operations.TableOperations_upsert.Input.Path, + query: Operations.TableOperations_upsert.Input.Query = .init(), + headers: Operations.TableOperations_upsert.Input.Headers = .init(), + body: Operations.TableOperations_upsert.Input.Body + ) async throws -> Operations.TableOperations_upsert.Output { + try await TableOperations_upsert(Operations.TableOperations_upsert.Input( + path: path, + query: query, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. + internal func TableOperations_deleteRows( + path: Operations.TableOperations_deleteRows.Input.Path, + query: Operations.TableOperations_deleteRows.Input.Query = .init(), + headers: Operations.TableOperations_deleteRows.Input.Headers = .init() + ) async throws -> Operations.TableOperations_deleteRows.Output { + try await TableOperations_deleteRows(Operations.TableOperations_deleteRows.Input( + path: path, + query: query, + headers: headers + )) + } +} + +/// Server URLs defined in the OpenAPI document. +internal enum Servers { + /// Supabase PostgREST endpoint + internal enum Server1 { + /// Supabase PostgREST endpoint + /// + /// - Parameters: + /// - baseUrl: + internal static func url(baseUrl: Swift.String = "") throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "{baseUrl}", + variables: [ + .init( + name: "baseUrl", + value: baseUrl + ) + ] + ) + } + } + /// Supabase PostgREST endpoint + /// + /// - Parameters: + /// - baseUrl: + @available(*, deprecated, renamed: "Servers.Server1.url") + internal static func server1(baseUrl: Swift.String = "") throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "{baseUrl}", + variables: [ + .init( + name: "baseUrl", + value: baseUrl + ) + ] + ) + } +} + +/// Types generated from the components section of the OpenAPI document. +internal enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + internal enum Schemas { + /// - Remark: Generated from `#/components/schemas/PostgRESTError`. + internal struct PostgRESTError: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/PostgRESTError/message`. + internal var message: Swift.String? + /// - Remark: Generated from `#/components/schemas/PostgRESTError/code`. + internal var code: Swift.String? + /// - Remark: Generated from `#/components/schemas/PostgRESTError/details`. + internal var details: Swift.String? + /// - Remark: Generated from `#/components/schemas/PostgRESTError/hint`. + internal var hint: Swift.String? + /// Creates a new `PostgRESTError`. + /// + /// - Parameters: + /// - message: + /// - code: + /// - details: + /// - hint: + internal init( + message: Swift.String? = nil, + code: Swift.String? = nil, + details: Swift.String? = nil, + hint: Swift.String? = nil + ) { + self.message = message + self.code = code + self.details = details + self.hint = hint + } + internal enum CodingKeys: String, CodingKey { + case message + case code + case details + case hint + } + } + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + internal enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + internal enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + internal enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + internal enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +internal enum Operations { + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. + internal enum RpcOperations_rpc { + internal static let id: Swift.String = "RpcOperations_rpc" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.RpcOperations_rpc.Input.Path + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query/params`. + internal struct paramsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `paramsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query/params`. + internal var params: Operations.RpcOperations_rpc.Input.Query.paramsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - params: + internal init(params: Operations.RpcOperations_rpc.Input.Query.paramsPayload? = nil) { + self.params = params + } + } + internal var query: Operations.RpcOperations_rpc.Input.Query + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header/Prefer`. + internal var Prefer: Swift.String? + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Prefer: + /// - Content_hyphen_Profile: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Prefer: Swift.String? = nil, + Content_hyphen_Profile: Swift.String? = nil, + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Prefer = Prefer + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.RpcOperations_rpc.Input.Headers + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + } + internal var body: Operations.RpcOperations_rpc.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.RpcOperations_rpc.Input.Path, + query: Operations.RpcOperations_rpc.Input.Query = .init(), + headers: Operations.RpcOperations_rpc.Input.Headers = .init(), + body: Operations.RpcOperations_rpc.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.RpcOperations_rpc.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.RpcOperations_rpc.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.RpcOperations_rpc.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.RpcOperations_rpc.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.RpcOperations_rpc.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.RpcOperations_rpc.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.RpcOperations_rpc.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.RpcOperations_rpc.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `GET /{table}`. + /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. + internal enum TableOperations_from { + internal static let id: Swift.String = "TableOperations_from" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.TableOperations_from.Input.Path + /// - Remark: Generated from `#/paths/{table}/GET/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/query/params`. + internal struct paramsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `paramsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// - Remark: Generated from `#/paths/{table}/GET/query/params`. + internal var params: Operations.TableOperations_from.Input.Query.paramsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - params: + internal init(params: Operations.TableOperations_from.Input.Query.paramsPayload? = nil) { + self.params = params + } + } + internal var query: Operations.TableOperations_from.Input.Query + /// - Remark: Generated from `#/paths/{table}/GET/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/header/Range`. + internal var Range: Swift.String? + /// - Remark: Generated from `#/paths/{table}/GET/header/Prefer`. + internal var Prefer: Swift.String? + /// - Remark: Generated from `#/paths/{table}/GET/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Range: + /// - Prefer: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Range: Swift.String? = nil, + Prefer: Swift.String? = nil, + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Range = Range + self.Prefer = Prefer + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.TableOperations_from.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + internal init( + path: Operations.TableOperations_from.Input.Path, + query: Operations.TableOperations_from.Input.Query = .init(), + headers: Operations.TableOperations_from.Input.Headers = .init() + ) { + self.path = path + self.query = query + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.TableOperations_from.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_from.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.TableOperations_from.Output.Ok.Headers = .init(), + body: Operations.TableOperations_from.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.TableOperations_from.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.TableOperations_from.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/GET/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_from.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TableOperations_from.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TableOperations_from.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TableOperations_from.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /{table}`. + /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. + internal enum TableOperations_insert { + internal static let id: Swift.String = "TableOperations_insert" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.TableOperations_insert.Input.Path + /// - Remark: Generated from `#/paths/{table}/POST/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/query/params`. + internal struct paramsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `paramsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// - Remark: Generated from `#/paths/{table}/POST/query/params`. + internal var params: Operations.TableOperations_insert.Input.Query.paramsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - params: + internal init(params: Operations.TableOperations_insert.Input.Query.paramsPayload? = nil) { + self.params = params + } + } + internal var query: Operations.TableOperations_insert.Input.Query + /// - Remark: Generated from `#/paths/{table}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/header/Prefer`. + internal var Prefer: Swift.String? + /// - Remark: Generated from `#/paths/{table}/POST/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/{table}/POST/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Prefer: + /// - Content_hyphen_Profile: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Prefer: Swift.String? = nil, + Content_hyphen_Profile: Swift.String? = nil, + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Prefer = Prefer + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.TableOperations_insert.Input.Headers + /// - Remark: Generated from `#/paths/{table}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + } + internal var body: Operations.TableOperations_insert.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.TableOperations_insert.Input.Path, + query: Operations.TableOperations_insert.Input.Query = .init(), + headers: Operations.TableOperations_insert.Input.Headers = .init(), + body: Operations.TableOperations_insert.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Created: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.TableOperations_insert.Output.Created.Headers + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_insert.Output.Created.Body + /// Creates a new `Created`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.TableOperations_insert.Output.Created.Headers = .init(), + body: Operations.TableOperations_insert.Output.Created.Body + ) { + self.headers = headers + self.body = body + } + } + /// The request has succeeded and a new resource has been created as a result. + /// + /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.TableOperations_insert.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + internal var created: Operations.TableOperations_insert.Output.Created { + get throws { + switch self { + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_insert.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TableOperations_insert.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TableOperations_insert.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TableOperations_insert.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PATCH /{table}`. + /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. + internal enum TableOperations_update { + internal static let id: Swift.String = "TableOperations_update" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.TableOperations_update.Input.Path + /// - Remark: Generated from `#/paths/{table}/PATCH/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/query/params`. + internal struct paramsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `paramsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// - Remark: Generated from `#/paths/{table}/PATCH/query/params`. + internal var params: Operations.TableOperations_update.Input.Query.paramsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - params: + internal init(params: Operations.TableOperations_update.Input.Query.paramsPayload? = nil) { + self.params = params + } + } + internal var query: Operations.TableOperations_update.Input.Query + /// - Remark: Generated from `#/paths/{table}/PATCH/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/header/Prefer`. + internal var Prefer: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PATCH/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PATCH/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Prefer: + /// - Content_hyphen_Profile: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Prefer: Swift.String? = nil, + Content_hyphen_Profile: Swift.String? = nil, + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Prefer = Prefer + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.TableOperations_update.Input.Headers + /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + } + internal var body: Operations.TableOperations_update.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.TableOperations_update.Input.Path, + query: Operations.TableOperations_update.Input.Query = .init(), + headers: Operations.TableOperations_update.Input.Headers = .init(), + body: Operations.TableOperations_update.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.TableOperations_update.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_update.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.TableOperations_update.Output.Ok.Headers = .init(), + body: Operations.TableOperations_update.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.TableOperations_update.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.TableOperations_update.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_update.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TableOperations_update.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TableOperations_update.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TableOperations_update.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PUT /{table}`. + /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. + internal enum TableOperations_upsert { + internal static let id: Swift.String = "TableOperations_upsert" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.TableOperations_upsert.Input.Path + /// - Remark: Generated from `#/paths/{table}/PUT/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/query/params`. + internal struct paramsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `paramsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// - Remark: Generated from `#/paths/{table}/PUT/query/params`. + internal var params: Operations.TableOperations_upsert.Input.Query.paramsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - params: + internal init(params: Operations.TableOperations_upsert.Input.Query.paramsPayload? = nil) { + self.params = params + } + } + internal var query: Operations.TableOperations_upsert.Input.Query + /// - Remark: Generated from `#/paths/{table}/PUT/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/header/Prefer`. + internal var Prefer: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PUT/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PUT/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Prefer: + /// - Content_hyphen_Profile: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Prefer: Swift.String? = nil, + Content_hyphen_Profile: Swift.String? = nil, + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Prefer = Prefer + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.TableOperations_upsert.Input.Headers + /// - Remark: Generated from `#/paths/{table}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + } + internal var body: Operations.TableOperations_upsert.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + /// - body: + internal init( + path: Operations.TableOperations_upsert.Input.Path, + query: Operations.TableOperations_upsert.Input.Query = .init(), + headers: Operations.TableOperations_upsert.Input.Headers = .init(), + body: Operations.TableOperations_upsert.Input.Body + ) { + self.path = path + self.query = query + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.TableOperations_upsert.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_upsert.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.TableOperations_upsert.Output.Ok.Headers = .init(), + body: Operations.TableOperations_upsert.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.TableOperations_upsert.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.TableOperations_upsert.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/PUT/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_upsert.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TableOperations_upsert.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TableOperations_upsert.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TableOperations_upsert.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /{table}`. + /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. + internal enum TableOperations_deleteRows { + internal static let id: Swift.String = "TableOperations_deleteRows" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/path/table`. + internal var table: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - table: + internal init(table: Swift.String) { + self.table = table + } + } + internal var path: Operations.TableOperations_deleteRows.Input.Path + /// - Remark: Generated from `#/paths/{table}/DELETE/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/query/params`. + internal struct paramsPayload: Codable, Hashable, Sendable { + /// A container of undocumented properties. + internal var additionalProperties: [String: Swift.String] + /// Creates a new `paramsPayload`. + /// + /// - Parameters: + /// - additionalProperties: A container of undocumented properties. + internal init(additionalProperties: [String: Swift.String] = .init()) { + self.additionalProperties = additionalProperties + } + internal init(from decoder: any Swift.Decoder) throws { + additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try encoder.encodeAdditionalProperties(additionalProperties) + } + } + /// - Remark: Generated from `#/paths/{table}/DELETE/query/params`. + internal var params: Operations.TableOperations_deleteRows.Input.Query.paramsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - params: + internal init(params: Operations.TableOperations_deleteRows.Input.Query.paramsPayload? = nil) { + self.params = params + } + } + internal var query: Operations.TableOperations_deleteRows.Input.Query + /// - Remark: Generated from `#/paths/{table}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/header/Prefer`. + internal var Prefer: Swift.String? + /// - Remark: Generated from `#/paths/{table}/DELETE/header/Content-Profile`. + internal var Content_hyphen_Profile: Swift.String? + /// - Remark: Generated from `#/paths/{table}/DELETE/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Prefer: + /// - Content_hyphen_Profile: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Prefer: Swift.String? = nil, + Content_hyphen_Profile: Swift.String? = nil, + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Prefer = Prefer + self.Content_hyphen_Profile = Content_hyphen_Profile + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.TableOperations_deleteRows.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + internal init( + path: Operations.TableOperations_deleteRows.Input.Path, + query: Operations.TableOperations_deleteRows.Input.Query = .init(), + headers: Operations.TableOperations_deleteRows.Input.Headers = .init() + ) { + self.path = path + self.query = query + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.TableOperations_deleteRows.Output.Ok.Headers + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_deleteRows.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.TableOperations_deleteRows.Output.Ok.Headers = .init(), + body: Operations.TableOperations_deleteRows.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.TableOperations_deleteRows.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.TableOperations_deleteRows.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TableOperations_deleteRows.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TableOperations_deleteRows.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TableOperations_deleteRows.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TableOperations_deleteRows.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } +} diff --git a/Sources/Storage/GeneratedTypeSpec/Client.swift b/Sources/Storage/GeneratedTypeSpec/Client.swift new file mode 100644 index 000000000..d4cd9c403 --- /dev/null +++ b/Sources/Storage/GeneratedTypeSpec/Client.swift @@ -0,0 +1,1376 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +import HTTPTypes +internal struct Client: APIProtocol { + /// The underlying HTTP client. + private let client: UniversalClient + /// Creates a new client. + /// - Parameters: + /// - serverURL: The server URL that the client connects to. Any server + /// URLs defined in the OpenAPI document are available as static methods + /// on the ``Servers`` type. + /// - configuration: A set of configuration values for the client. + /// - transport: A transport that performs HTTP operations. + /// - middlewares: A list of middlewares to call before the transport. + internal init( + serverURL: Foundation.URL, + configuration: Configuration = .init(), + transport: any ClientTransport, + middlewares: [any ClientMiddleware] = [] + ) { + self.client = .init( + serverURL: serverURL, + configuration: configuration, + transport: transport, + middlewares: middlewares + ) + } + private var converter: Converter { + client.converter + } + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(Buckets_list)`. + internal func Buckets_list(_ input: Operations.Buckets_list.Input) async throws -> Operations.Buckets_list.Output { + try await client.send( + input: input, + forOperation: Operations.Buckets_list.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_list.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.Bucket].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_list.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)`. + internal func Buckets_create(_ input: Operations.Buckets_create.Input) async throws -> Operations.Buckets_create.Output { + try await client.send( + input: input, + forOperation: Operations.Buckets_create.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_create.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(Buckets_get)`. + internal func Buckets_get(_ input: Operations.Buckets_get.Input) async throws -> Operations.Buckets_get.Output { + try await client.send( + input: input, + forOperation: Operations.Buckets_get.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_get.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.Bucket.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_get.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)`. + internal func Buckets_update(_ input: Operations.Buckets_update.Input) async throws -> Operations.Buckets_update.Output { + try await client.send( + input: input, + forOperation: Operations.Buckets_update.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_update.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)`. + internal func Buckets_deleteBucket(_ input: Operations.Buckets_deleteBucket.Input) async throws -> Operations.Buckets_deleteBucket.Output { + try await client.send( + input: input, + forOperation: Operations.Buckets_deleteBucket.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_deleteBucket.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)`. + internal func Buckets_empty(_ input: Operations.Buckets_empty.Input) async throws -> Operations.Buckets_empty.Output { + try await client.send( + input: input, + forOperation: Operations.Buckets_empty.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/bucket/{}/empty", + parameters: [ + input.path.id + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Buckets_empty.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(Objects_copy)`. + internal func Objects_copy(_ input: Operations.Objects_copy.Input) async throws -> Operations.Objects_copy.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_copy.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/copy", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_copy.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CopyObjectOutput.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_copy.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath}/get(Objects_info)`. + internal func Objects_info(_ input: Operations.Objects_info.Input) async throws -> Operations.Objects_info.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_info.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/info/{}/{}", + parameters: [ + input.path.bucketId, + input.path.wildcardPath + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_info.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FileInfo.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_info.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(Objects_list)`. + internal func Objects_list(_ input: Operations.Objects_list.Input) async throws -> Operations.Objects_list.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_list.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/list/{}", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_list.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.FileObject].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_list.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)`. + internal func Objects_move(_ input: Operations.Objects_move.Input) async throws -> Operations.Objects_move.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_move.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/move", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_move.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(Objects_createSignedUrls)`. + internal func Objects_createSignedUrls(_ input: Operations.Objects_createSignedUrls.Input) async throws -> Operations.Objects_createSignedUrls.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_createSignedUrls.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/sign/{}", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_createSignedUrls.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.SignedUrlResult].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_createSignedUrls.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUrl)`. + internal func Objects_createSignedUrl(_ input: Operations.Objects_createSignedUrl.Input) async throws -> Operations.Objects_createSignedUrl.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_createSignedUrl.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/sign/{}/{}", + parameters: [ + input.path.bucketId, + input.path.wildcardPath + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_createSignedUrl.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CreateSignedUrlOutput.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_createSignedUrl.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUploadUrl)`. + internal func Objects_createSignedUploadUrl(_ input: Operations.Objects_createSignedUploadUrl.Input) async throws -> Operations.Objects_createSignedUploadUrl.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_createSignedUploadUrl.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/upload/sign/{}/{}", + parameters: [ + input.path.bucketId, + input.path.wildcardPath + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_createSignedUploadUrl.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.CreateSignedUploadUrlOutput.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_createSignedUploadUrl.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)`. + internal func Objects_deleteObjects(_ input: Operations.Objects_deleteObjects.Input) async throws -> Operations.Objects_deleteObjects.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_deleteObjects.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}", + parameters: [ + input.path.bucketId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .delete + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_deleteObjects.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + [Components.Schemas.FileObject].self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_deleteObjects.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. + internal func Objects_head(_ input: Operations.Objects_head.Input) async throws -> Operations.Objects_head.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_head.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}/{}", + parameters: [ + input.path.bucketId, + input.path.wildcardPath + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .head + ) + suppressMutabilityWarning(&request) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + return .noContent(.init()) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_head.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(TusUploads_create)`. + internal func TusUploads_create(_ input: Operations.TusUploads_create.Input) async throws -> Operations.TusUploads_create.Output { + try await client.send( + input: input, + forOperation: Operations.TusUploads_create.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/upload/resumable", + parameters: [] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Upload-Length", + value: input.headers.Upload_hyphen_Length + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Upload-Metadata", + value: input.headers.Upload_hyphen_Metadata + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Tus-Resumable", + value: input.headers.Tus_hyphen_Resumable + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 201: + let headers: Operations.TusUploads_create.Output.Created.Headers = .init(location: try converter.getRequiredHeaderFieldAsURI( + in: response.headerFields, + name: "location", + as: Swift.String.self + )) + return .created(.init(headers: headers)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TusUploads_create.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(TusUploads_uploadChunk)`. + internal func TusUploads_uploadChunk(_ input: Operations.TusUploads_uploadChunk.Input) async throws -> Operations.TusUploads_uploadChunk.Output { + try await client.send( + input: input, + forOperation: Operations.TusUploads_uploadChunk.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/upload/resumable/{}", + parameters: [ + input.path.uploadId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .patch + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Upload-Offset", + value: input.headers.Upload_hyphen_Offset + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Tus-Resumable", + value: input.headers.Tus_hyphen_Resumable + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "application/octet-stream" + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 204: + let headers: Operations.TusUploads_uploadChunk.Output.NoContent.Headers = .init(Upload_hyphen_Offset: try converter.getRequiredHeaderFieldAsURI( + in: response.headerFields, + name: "Upload-Offset", + as: Swift.Int64.self + )) + return .noContent(.init(headers: headers)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TusUploads_uploadChunk.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(TusUploads_getOffset)`. + internal func TusUploads_getOffset(_ input: Operations.TusUploads_getOffset.Input) async throws -> Operations.TusUploads_getOffset.Output { + try await client.send( + input: input, + forOperation: Operations.TusUploads_getOffset.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/upload/resumable/{}", + parameters: [ + input.path.uploadId + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .head + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Tus-Resumable", + value: input.headers.Tus_hyphen_Resumable + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.TusUploads_getOffset.Output.Ok.Headers = .init(Upload_hyphen_Offset: try converter.getRequiredHeaderFieldAsURI( + in: response.headerFields, + name: "Upload-Offset", + as: Swift.Int64.self + )) + return .ok(.init(headers: headers)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.TusUploads_getOffset.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } +} diff --git a/Sources/Storage/GeneratedTypeSpec/Types.swift b/Sources/Storage/GeneratedTypeSpec/Types.swift new file mode 100644 index 000000000..05d8abb54 --- /dev/null +++ b/Sources/Storage/GeneratedTypeSpec/Types.swift @@ -0,0 +1,3963 @@ +// Generated by swift-openapi-generator, do not modify. +@_spi(Generated) import OpenAPIRuntime +#if os(Linux) +@preconcurrency import struct Foundation.URL +@preconcurrency import struct Foundation.Data +@preconcurrency import struct Foundation.Date +#else +import struct Foundation.URL +import struct Foundation.Data +import struct Foundation.Date +#endif +/// A type that performs HTTP operations defined by the OpenAPI document. +internal protocol APIProtocol: Sendable { + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(Buckets_list)`. + func Buckets_list(_ input: Operations.Buckets_list.Input) async throws -> Operations.Buckets_list.Output + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)`. + func Buckets_create(_ input: Operations.Buckets_create.Input) async throws -> Operations.Buckets_create.Output + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(Buckets_get)`. + func Buckets_get(_ input: Operations.Buckets_get.Input) async throws -> Operations.Buckets_get.Output + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)`. + func Buckets_update(_ input: Operations.Buckets_update.Input) async throws -> Operations.Buckets_update.Output + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)`. + func Buckets_deleteBucket(_ input: Operations.Buckets_deleteBucket.Input) async throws -> Operations.Buckets_deleteBucket.Output + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)`. + func Buckets_empty(_ input: Operations.Buckets_empty.Input) async throws -> Operations.Buckets_empty.Output + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(Objects_copy)`. + func Objects_copy(_ input: Operations.Objects_copy.Input) async throws -> Operations.Objects_copy.Output + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath}/get(Objects_info)`. + func Objects_info(_ input: Operations.Objects_info.Input) async throws -> Operations.Objects_info.Output + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(Objects_list)`. + func Objects_list(_ input: Operations.Objects_list.Input) async throws -> Operations.Objects_list.Output + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)`. + func Objects_move(_ input: Operations.Objects_move.Input) async throws -> Operations.Objects_move.Output + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(Objects_createSignedUrls)`. + func Objects_createSignedUrls(_ input: Operations.Objects_createSignedUrls.Input) async throws -> Operations.Objects_createSignedUrls.Output + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUrl)`. + func Objects_createSignedUrl(_ input: Operations.Objects_createSignedUrl.Input) async throws -> Operations.Objects_createSignedUrl.Output + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUploadUrl)`. + func Objects_createSignedUploadUrl(_ input: Operations.Objects_createSignedUploadUrl.Input) async throws -> Operations.Objects_createSignedUploadUrl.Output + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)`. + func Objects_deleteObjects(_ input: Operations.Objects_deleteObjects.Input) async throws -> Operations.Objects_deleteObjects.Output + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. + func Objects_head(_ input: Operations.Objects_head.Input) async throws -> Operations.Objects_head.Output + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(TusUploads_create)`. + func TusUploads_create(_ input: Operations.TusUploads_create.Input) async throws -> Operations.TusUploads_create.Output + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(TusUploads_uploadChunk)`. + func TusUploads_uploadChunk(_ input: Operations.TusUploads_uploadChunk.Input) async throws -> Operations.TusUploads_uploadChunk.Output + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(TusUploads_getOffset)`. + func TusUploads_getOffset(_ input: Operations.TusUploads_getOffset.Input) async throws -> Operations.TusUploads_getOffset.Output +} + +/// Convenience overloads for operation inputs. +extension APIProtocol { + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(Buckets_list)`. + internal func Buckets_list(headers: Operations.Buckets_list.Input.Headers = .init()) async throws -> Operations.Buckets_list.Output { + try await Buckets_list(Operations.Buckets_list.Input(headers: headers)) + } + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)`. + internal func Buckets_create( + headers: Operations.Buckets_create.Input.Headers = .init(), + body: Operations.Buckets_create.Input.Body + ) async throws -> Operations.Buckets_create.Output { + try await Buckets_create(Operations.Buckets_create.Input( + headers: headers, + body: body + )) + } + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(Buckets_get)`. + internal func Buckets_get( + path: Operations.Buckets_get.Input.Path, + headers: Operations.Buckets_get.Input.Headers = .init() + ) async throws -> Operations.Buckets_get.Output { + try await Buckets_get(Operations.Buckets_get.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)`. + internal func Buckets_update( + path: Operations.Buckets_update.Input.Path, + headers: Operations.Buckets_update.Input.Headers = .init(), + body: Operations.Buckets_update.Input.Body + ) async throws -> Operations.Buckets_update.Output { + try await Buckets_update(Operations.Buckets_update.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)`. + internal func Buckets_deleteBucket( + path: Operations.Buckets_deleteBucket.Input.Path, + headers: Operations.Buckets_deleteBucket.Input.Headers = .init() + ) async throws -> Operations.Buckets_deleteBucket.Output { + try await Buckets_deleteBucket(Operations.Buckets_deleteBucket.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)`. + internal func Buckets_empty( + path: Operations.Buckets_empty.Input.Path, + headers: Operations.Buckets_empty.Input.Headers = .init() + ) async throws -> Operations.Buckets_empty.Output { + try await Buckets_empty(Operations.Buckets_empty.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(Objects_copy)`. + internal func Objects_copy( + headers: Operations.Objects_copy.Input.Headers = .init(), + body: Operations.Objects_copy.Input.Body + ) async throws -> Operations.Objects_copy.Output { + try await Objects_copy(Operations.Objects_copy.Input( + headers: headers, + body: body + )) + } + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath}/get(Objects_info)`. + internal func Objects_info( + path: Operations.Objects_info.Input.Path, + headers: Operations.Objects_info.Input.Headers = .init() + ) async throws -> Operations.Objects_info.Output { + try await Objects_info(Operations.Objects_info.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(Objects_list)`. + internal func Objects_list( + path: Operations.Objects_list.Input.Path, + headers: Operations.Objects_list.Input.Headers = .init(), + body: Operations.Objects_list.Input.Body + ) async throws -> Operations.Objects_list.Output { + try await Objects_list(Operations.Objects_list.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)`. + internal func Objects_move( + headers: Operations.Objects_move.Input.Headers = .init(), + body: Operations.Objects_move.Input.Body + ) async throws -> Operations.Objects_move.Output { + try await Objects_move(Operations.Objects_move.Input( + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(Objects_createSignedUrls)`. + internal func Objects_createSignedUrls( + path: Operations.Objects_createSignedUrls.Input.Path, + headers: Operations.Objects_createSignedUrls.Input.Headers = .init(), + body: Operations.Objects_createSignedUrls.Input.Body + ) async throws -> Operations.Objects_createSignedUrls.Output { + try await Objects_createSignedUrls(Operations.Objects_createSignedUrls.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUrl)`. + internal func Objects_createSignedUrl( + path: Operations.Objects_createSignedUrl.Input.Path, + headers: Operations.Objects_createSignedUrl.Input.Headers = .init(), + body: Operations.Objects_createSignedUrl.Input.Body + ) async throws -> Operations.Objects_createSignedUrl.Output { + try await Objects_createSignedUrl(Operations.Objects_createSignedUrl.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUploadUrl)`. + internal func Objects_createSignedUploadUrl( + path: Operations.Objects_createSignedUploadUrl.Input.Path, + headers: Operations.Objects_createSignedUploadUrl.Input.Headers = .init() + ) async throws -> Operations.Objects_createSignedUploadUrl.Output { + try await Objects_createSignedUploadUrl(Operations.Objects_createSignedUploadUrl.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)`. + internal func Objects_deleteObjects( + path: Operations.Objects_deleteObjects.Input.Path, + headers: Operations.Objects_deleteObjects.Input.Headers = .init(), + body: Operations.Objects_deleteObjects.Input.Body + ) async throws -> Operations.Objects_deleteObjects.Output { + try await Objects_deleteObjects(Operations.Objects_deleteObjects.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. + internal func Objects_head( + path: Operations.Objects_head.Input.Path, + headers: Operations.Objects_head.Input.Headers = .init() + ) async throws -> Operations.Objects_head.Output { + try await Objects_head(Operations.Objects_head.Input( + path: path, + headers: headers + )) + } + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(TusUploads_create)`. + internal func TusUploads_create(headers: Operations.TusUploads_create.Input.Headers) async throws -> Operations.TusUploads_create.Output { + try await TusUploads_create(Operations.TusUploads_create.Input(headers: headers)) + } + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(TusUploads_uploadChunk)`. + internal func TusUploads_uploadChunk( + path: Operations.TusUploads_uploadChunk.Input.Path, + headers: Operations.TusUploads_uploadChunk.Input.Headers, + body: Operations.TusUploads_uploadChunk.Input.Body + ) async throws -> Operations.TusUploads_uploadChunk.Output { + try await TusUploads_uploadChunk(Operations.TusUploads_uploadChunk.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(TusUploads_getOffset)`. + internal func TusUploads_getOffset( + path: Operations.TusUploads_getOffset.Input.Path, + headers: Operations.TusUploads_getOffset.Input.Headers + ) async throws -> Operations.TusUploads_getOffset.Output { + try await TusUploads_getOffset(Operations.TusUploads_getOffset.Input( + path: path, + headers: headers + )) + } +} + +/// Server URLs defined in the OpenAPI document. +internal enum Servers { + /// Supabase Storage endpoint + internal enum Server1 { + /// Supabase Storage endpoint + /// + /// - Parameters: + /// - baseUrl: + internal static func url(baseUrl: Swift.String = "") throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "{baseUrl}", + variables: [ + .init( + name: "baseUrl", + value: baseUrl + ) + ] + ) + } + } + /// Supabase Storage endpoint + /// + /// - Parameters: + /// - baseUrl: + @available(*, deprecated, renamed: "Servers.Server1.url") + internal static func server1(baseUrl: Swift.String = "") throws -> Foundation.URL { + try Foundation.URL( + validatingOpenAPIServerURL: "{baseUrl}", + variables: [ + .init( + name: "baseUrl", + value: baseUrl + ) + ] + ) + } +} + +/// Types generated from the components section of the OpenAPI document. +internal enum Components { + /// Types generated from the `#/components/schemas` section of the OpenAPI document. + internal enum Schemas { + /// - Remark: Generated from `#/components/schemas/Bucket`. + internal struct Bucket: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/Bucket/id`. + internal var id: Swift.String + /// - Remark: Generated from `#/components/schemas/Bucket/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/Bucket/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/Bucket/file_size_limit`. + internal var file_size_limit: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/Bucket/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// - Remark: Generated from `#/components/schemas/Bucket/created_at`. + internal var created_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/Bucket/updated_at`. + internal var updated_at: Swift.String? + /// Creates a new `Bucket`. + /// + /// - Parameters: + /// - id: + /// - name: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: + /// - created_at: + /// - updated_at: + internal init( + id: Swift.String, + name: Swift.String, + _public: Swift.Bool, + file_size_limit: Swift.Int64? = nil, + allowed_mime_types: [Swift.String]? = nil, + created_at: Swift.String? = nil, + updated_at: Swift.String? = nil + ) { + self.id = id + self.name = name + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + self.created_at = created_at + self.updated_at = updated_at + } + internal enum CodingKeys: String, CodingKey { + case id + case name + case _public = "public" + case file_size_limit + case allowed_mime_types + case created_at + case updated_at + } + } + /// - Remark: Generated from `#/components/schemas/CopyObjectInput`. + internal struct CopyObjectInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CopyObjectInput/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/components/schemas/CopyObjectInput/sourceKey`. + internal var sourceKey: Swift.String + /// - Remark: Generated from `#/components/schemas/CopyObjectInput/destinationKey`. + internal var destinationKey: Swift.String + /// - Remark: Generated from `#/components/schemas/CopyObjectInput/destinationBucket`. + internal var destinationBucket: Swift.String? + /// Creates a new `CopyObjectInput`. + /// + /// - Parameters: + /// - bucketId: + /// - sourceKey: + /// - destinationKey: + /// - destinationBucket: + internal init( + bucketId: Swift.String, + sourceKey: Swift.String, + destinationKey: Swift.String, + destinationBucket: Swift.String? = nil + ) { + self.bucketId = bucketId + self.sourceKey = sourceKey + self.destinationKey = destinationKey + self.destinationBucket = destinationBucket + } + internal enum CodingKeys: String, CodingKey { + case bucketId + case sourceKey + case destinationKey + case destinationBucket + } + } + /// - Remark: Generated from `#/components/schemas/CopyObjectOutput`. + internal struct CopyObjectOutput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CopyObjectOutput/Key`. + internal var Key: Swift.String + /// Creates a new `CopyObjectOutput`. + /// + /// - Parameters: + /// - Key: + internal init(Key: Swift.String) { + self.Key = Key + } + internal enum CodingKeys: String, CodingKey { + case Key + } + } + /// - Remark: Generated from `#/components/schemas/CreateBucketInput`. + internal struct CreateBucketInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateBucketInput/id`. + internal var id: Swift.String + /// - Remark: Generated from `#/components/schemas/CreateBucketInput/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/CreateBucketInput/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/CreateBucketInput/file_size_limit`. + internal var file_size_limit: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/CreateBucketInput/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// Creates a new `CreateBucketInput`. + /// + /// - Parameters: + /// - id: + /// - name: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: + internal init( + id: Swift.String, + name: Swift.String, + _public: Swift.Bool, + file_size_limit: Swift.Int64? = nil, + allowed_mime_types: [Swift.String]? = nil + ) { + self.id = id + self.name = name + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + } + internal enum CodingKeys: String, CodingKey { + case id + case name + case _public = "public" + case file_size_limit + case allowed_mime_types + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUploadUrlOutput`. + internal struct CreateSignedUploadUrlOutput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUploadUrlOutput/url`. + internal var url: Swift.String + /// Creates a new `CreateSignedUploadUrlOutput`. + /// + /// - Parameters: + /// - url: + internal init(url: Swift.String) { + self.url = url + } + internal enum CodingKeys: String, CodingKey { + case url + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlInput`. + internal struct CreateSignedUrlInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlInput/expiresIn`. + internal var expiresIn: Swift.Int32 + /// Creates a new `CreateSignedUrlInput`. + /// + /// - Parameters: + /// - expiresIn: + internal init(expiresIn: Swift.Int32) { + self.expiresIn = expiresIn + } + internal enum CodingKeys: String, CodingKey { + case expiresIn + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlOutput`. + internal struct CreateSignedUrlOutput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlOutput/signedURL`. + internal var signedURL: Swift.String + /// Creates a new `CreateSignedUrlOutput`. + /// + /// - Parameters: + /// - signedURL: + internal init(signedURL: Swift.String) { + self.signedURL = signedURL + } + internal enum CodingKeys: String, CodingKey { + case signedURL + } + } + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsInput`. + internal struct CreateSignedUrlsInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsInput/expiresIn`. + internal var expiresIn: Swift.Int32 + /// - Remark: Generated from `#/components/schemas/CreateSignedUrlsInput/paths`. + internal var paths: [Swift.String] + /// Creates a new `CreateSignedUrlsInput`. + /// + /// - Parameters: + /// - expiresIn: + /// - paths: + internal init( + expiresIn: Swift.Int32, + paths: [Swift.String] + ) { + self.expiresIn = expiresIn + self.paths = paths + } + internal enum CodingKeys: String, CodingKey { + case expiresIn + case paths + } + } + /// - Remark: Generated from `#/components/schemas/FileInfo`. + internal struct FileInfo: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FileInfo/eTag`. + internal var eTag: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileInfo/size`. + internal var size: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/FileInfo/mimetype`. + internal var mimetype: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileInfo/cacheControl`. + internal var cacheControl: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileInfo/lastModified`. + internal var lastModified: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileInfo/contentLength`. + internal var contentLength: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/FileInfo/httpStatusCode`. + internal var httpStatusCode: Swift.Int32? + /// Creates a new `FileInfo`. + /// + /// - Parameters: + /// - eTag: + /// - size: + /// - mimetype: + /// - cacheControl: + /// - lastModified: + /// - contentLength: + /// - httpStatusCode: + internal init( + eTag: Swift.String? = nil, + size: Swift.Int64? = nil, + mimetype: Swift.String? = nil, + cacheControl: Swift.String? = nil, + lastModified: Swift.String? = nil, + contentLength: Swift.Int64? = nil, + httpStatusCode: Swift.Int32? = nil + ) { + self.eTag = eTag + self.size = size + self.mimetype = mimetype + self.cacheControl = cacheControl + self.lastModified = lastModified + self.contentLength = contentLength + self.httpStatusCode = httpStatusCode + } + internal enum CodingKeys: String, CodingKey { + case eTag + case size + case mimetype + case cacheControl + case lastModified + case contentLength + case httpStatusCode + } + } + /// - Remark: Generated from `#/components/schemas/FileMetadata`. + internal struct FileMetadata: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FileMetadata/eTag`. + internal var eTag: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/size`. + internal var size: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/FileMetadata/mimetype`. + internal var mimetype: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/cacheControl`. + internal var cacheControl: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/lastModified`. + internal var lastModified: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileMetadata/contentLength`. + internal var contentLength: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/FileMetadata/httpStatusCode`. + internal var httpStatusCode: Swift.Int32? + /// Creates a new `FileMetadata`. + /// + /// - Parameters: + /// - eTag: + /// - size: + /// - mimetype: + /// - cacheControl: + /// - lastModified: + /// - contentLength: + /// - httpStatusCode: + internal init( + eTag: Swift.String? = nil, + size: Swift.Int64? = nil, + mimetype: Swift.String? = nil, + cacheControl: Swift.String? = nil, + lastModified: Swift.String? = nil, + contentLength: Swift.Int64? = nil, + httpStatusCode: Swift.Int32? = nil + ) { + self.eTag = eTag + self.size = size + self.mimetype = mimetype + self.cacheControl = cacheControl + self.lastModified = lastModified + self.contentLength = contentLength + self.httpStatusCode = httpStatusCode + } + internal enum CodingKeys: String, CodingKey { + case eTag + case size + case mimetype + case cacheControl + case lastModified + case contentLength + case httpStatusCode + } + } + /// - Remark: Generated from `#/components/schemas/FileObject`. + internal struct FileObject: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/FileObject/name`. + internal var name: Swift.String + /// - Remark: Generated from `#/components/schemas/FileObject/id`. + internal var id: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/updated_at`. + internal var updated_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/created_at`. + internal var created_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/last_accessed_at`. + internal var last_accessed_at: Swift.String? + /// - Remark: Generated from `#/components/schemas/FileObject/metadata`. + internal var metadata: Components.Schemas.FileMetadata? + /// Creates a new `FileObject`. + /// + /// - Parameters: + /// - name: + /// - id: + /// - updated_at: + /// - created_at: + /// - last_accessed_at: + /// - metadata: + internal init( + name: Swift.String, + id: Swift.String? = nil, + updated_at: Swift.String? = nil, + created_at: Swift.String? = nil, + last_accessed_at: Swift.String? = nil, + metadata: Components.Schemas.FileMetadata? = nil + ) { + self.name = name + self.id = id + self.updated_at = updated_at + self.created_at = created_at + self.last_accessed_at = last_accessed_at + self.metadata = metadata + } + internal enum CodingKeys: String, CodingKey { + case name + case id + case updated_at + case created_at + case last_accessed_at + case metadata + } + } + /// - Remark: Generated from `#/components/schemas/ListObjectsInput`. + internal struct ListObjectsInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/ListObjectsInput/prefix`. + internal var prefix: Swift.String + /// - Remark: Generated from `#/components/schemas/ListObjectsInput/limit`. + internal var limit: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/ListObjectsInput/offset`. + internal var offset: Swift.Int32? + /// - Remark: Generated from `#/components/schemas/ListObjectsInput/sortBy`. + internal var sortBy: Components.Schemas.SortBy? + /// Creates a new `ListObjectsInput`. + /// + /// - Parameters: + /// - prefix: + /// - limit: + /// - offset: + /// - sortBy: + internal init( + prefix: Swift.String, + limit: Swift.Int32? = nil, + offset: Swift.Int32? = nil, + sortBy: Components.Schemas.SortBy? = nil + ) { + self.prefix = prefix + self.limit = limit + self.offset = offset + self.sortBy = sortBy + } + internal enum CodingKeys: String, CodingKey { + case prefix + case limit + case offset + case sortBy + } + } + /// - Remark: Generated from `#/components/schemas/MoveObjectInput`. + internal struct MoveObjectInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/MoveObjectInput/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/components/schemas/MoveObjectInput/sourceKey`. + internal var sourceKey: Swift.String + /// - Remark: Generated from `#/components/schemas/MoveObjectInput/destinationKey`. + internal var destinationKey: Swift.String + /// - Remark: Generated from `#/components/schemas/MoveObjectInput/destinationBucket`. + internal var destinationBucket: Swift.String? + /// Creates a new `MoveObjectInput`. + /// + /// - Parameters: + /// - bucketId: + /// - sourceKey: + /// - destinationKey: + /// - destinationBucket: + internal init( + bucketId: Swift.String, + sourceKey: Swift.String, + destinationKey: Swift.String, + destinationBucket: Swift.String? = nil + ) { + self.bucketId = bucketId + self.sourceKey = sourceKey + self.destinationKey = destinationKey + self.destinationBucket = destinationBucket + } + internal enum CodingKeys: String, CodingKey { + case bucketId + case sourceKey + case destinationKey + case destinationBucket + } + } + /// - Remark: Generated from `#/components/schemas/SignedUrlResult`. + internal struct SignedUrlResult: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/SignedUrlResult/signedURL`. + internal var signedURL: Swift.String? + /// - Remark: Generated from `#/components/schemas/SignedUrlResult/path`. + internal var path: Swift.String + /// - Remark: Generated from `#/components/schemas/SignedUrlResult/error`. + internal var error: Swift.String? + /// Creates a new `SignedUrlResult`. + /// + /// - Parameters: + /// - signedURL: + /// - path: + /// - error: + internal init( + signedURL: Swift.String? = nil, + path: Swift.String, + error: Swift.String? = nil + ) { + self.signedURL = signedURL + self.path = path + self.error = error + } + internal enum CodingKeys: String, CodingKey { + case signedURL + case path + case error + } + } + /// - Remark: Generated from `#/components/schemas/SortBy`. + internal struct SortBy: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/SortBy/column`. + internal var column: Swift.String? + /// - Remark: Generated from `#/components/schemas/SortBy/order`. + internal var order: Swift.String? + /// Creates a new `SortBy`. + /// + /// - Parameters: + /// - column: + /// - order: + internal init( + column: Swift.String? = nil, + order: Swift.String? = nil + ) { + self.column = column + self.order = order + } + internal enum CodingKeys: String, CodingKey { + case column + case order + } + } + /// - Remark: Generated from `#/components/schemas/StorageError`. + internal struct StorageError: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/StorageError/message`. + internal var message: Swift.String? + /// - Remark: Generated from `#/components/schemas/StorageError/error`. + internal var error: Swift.String? + /// - Remark: Generated from `#/components/schemas/StorageError/statusCode`. + internal var statusCode: Swift.String? + /// Creates a new `StorageError`. + /// + /// - Parameters: + /// - message: + /// - error: + /// - statusCode: + internal init( + message: Swift.String? = nil, + error: Swift.String? = nil, + statusCode: Swift.String? = nil + ) { + self.message = message + self.error = error + self.statusCode = statusCode + } + internal enum CodingKeys: String, CodingKey { + case message + case error + case statusCode + } + } + /// - Remark: Generated from `#/components/schemas/UpdateBucketInput`. + internal struct UpdateBucketInput: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/components/schemas/UpdateBucketInput/public`. + internal var _public: Swift.Bool + /// - Remark: Generated from `#/components/schemas/UpdateBucketInput/file_size_limit`. + internal var file_size_limit: Swift.Int64? + /// - Remark: Generated from `#/components/schemas/UpdateBucketInput/allowed_mime_types`. + internal var allowed_mime_types: [Swift.String]? + /// Creates a new `UpdateBucketInput`. + /// + /// - Parameters: + /// - _public: + /// - file_size_limit: + /// - allowed_mime_types: + internal init( + _public: Swift.Bool, + file_size_limit: Swift.Int64? = nil, + allowed_mime_types: [Swift.String]? = nil + ) { + self._public = _public + self.file_size_limit = file_size_limit + self.allowed_mime_types = allowed_mime_types + } + internal enum CodingKeys: String, CodingKey { + case _public = "public" + case file_size_limit + case allowed_mime_types + } + } + } + /// Types generated from the `#/components/parameters` section of the OpenAPI document. + internal enum Parameters {} + /// Types generated from the `#/components/requestBodies` section of the OpenAPI document. + internal enum RequestBodies {} + /// Types generated from the `#/components/responses` section of the OpenAPI document. + internal enum Responses {} + /// Types generated from the `#/components/headers` section of the OpenAPI document. + internal enum Headers {} +} + +/// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. +internal enum Operations { + /// - Remark: HTTP `GET /bucket`. + /// - Remark: Generated from `#/paths//bucket/get(Buckets_list)`. + internal enum Buckets_list { + internal static let id: Swift.String = "Buckets_list" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Buckets_list.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + internal init(headers: Operations.Buckets_list.Input.Headers = .init()) { + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/200/content/application\/json`. + case json([Components.Schemas.Bucket]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: [Components.Schemas.Bucket] { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_list.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_list.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//bucket/get(Buckets_list)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Buckets_list.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Buckets_list.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/GET/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_list.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_list.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//bucket/get(Buckets_list)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Buckets_list.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Buckets_list.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /bucket`. + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)`. + internal enum Buckets_create { + internal static let id: Swift.String = "Buckets_create" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Buckets_create.Input.Headers + /// - Remark: Generated from `#/paths/bucket/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CreateBucketInput) + } + internal var body: Operations.Buckets_create.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + internal init( + headers: Operations.Buckets_create.Input.Headers = .init(), + body: Operations.Buckets_create.Input.Body + ) { + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + internal init() {} + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.Buckets_create.Output.NoContent) + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + internal static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.Buckets_create.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_create.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_create.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//bucket/post(Buckets_create)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Buckets_create.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Buckets_create.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `GET /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/get(Buckets_get)`. + internal enum Buckets_get { + internal static let id: Swift.String = "Buckets_get" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.Buckets_get.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/GET/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Buckets_get.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.Buckets_get.Input.Path, + headers: Operations.Buckets_get.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.Bucket) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.Bucket { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_get.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_get.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/get(Buckets_get)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Buckets_get.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Buckets_get.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/GET/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_get.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_get.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/get(Buckets_get)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Buckets_get.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Buckets_get.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PUT /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)`. + internal enum Buckets_update { + internal static let id: Swift.String = "Buckets_update" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.Buckets_update.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Buckets_update.Input.Headers + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/requestBody/content/application\/json`. + case json(Components.Schemas.UpdateBucketInput) + } + internal var body: Operations.Buckets_update.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Buckets_update.Input.Path, + headers: Operations.Buckets_update.Input.Headers = .init(), + body: Operations.Buckets_update.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + internal init() {} + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.Buckets_update.Output.NoContent) + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + internal static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.Buckets_update.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/PUT/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_update.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_update.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/put(Buckets_update)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Buckets_update.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Buckets_update.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /bucket/{id}`. + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)`. + internal enum Buckets_deleteBucket { + internal static let id: Swift.String = "Buckets_deleteBucket" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.Buckets_deleteBucket.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Buckets_deleteBucket.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.Buckets_deleteBucket.Input.Path, + headers: Operations.Buckets_deleteBucket.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + internal init() {} + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.Buckets_deleteBucket.Output.NoContent) + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + internal static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.Buckets_deleteBucket.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/DELETE/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_deleteBucket.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_deleteBucket.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/delete(Buckets_deleteBucket)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Buckets_deleteBucket.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Buckets_deleteBucket.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /bucket/{id}/empty`. + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)`. + internal enum Buckets_empty { + internal static let id: Swift.String = "Buckets_empty" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/path/id`. + internal var id: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - id: + internal init(id: Swift.String) { + self.id = id + } + } + internal var path: Operations.Buckets_empty.Input.Path + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Buckets_empty.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.Buckets_empty.Input.Path, + headers: Operations.Buckets_empty.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + internal init() {} + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.Buckets_empty.Output.NoContent) + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + internal static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.Buckets_empty.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/bucket/{id}/empty/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Buckets_empty.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Buckets_empty.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//bucket/{id}/empty/post(Buckets_empty)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Buckets_empty.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Buckets_empty.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/copy`. + /// - Remark: Generated from `#/paths//object/copy/post(Objects_copy)`. + internal enum Objects_copy { + internal static let id: Swift.String = "Objects_copy" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_copy.Input.Headers + /// - Remark: Generated from `#/paths/object/copy/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CopyObjectInput) + } + internal var body: Operations.Objects_copy.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + internal init( + headers: Operations.Objects_copy.Input.Headers = .init(), + body: Operations.Objects_copy.Input.Body + ) { + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CopyObjectOutput) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CopyObjectOutput { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_copy.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_copy.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/copy/post(Objects_copy)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_copy.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_copy.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/copy/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_copy.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_copy.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/copy/post(Objects_copy)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_copy.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_copy.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `GET /object/info/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath}/get(Objects_info)`. + internal enum Objects_info { + internal static let id: Swift.String = "Objects_info" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/path/wildcardPath`. + internal var wildcardPath: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath: + internal init( + bucketId: Swift.String, + wildcardPath: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath = wildcardPath + } + } + internal var path: Operations.Objects_info.Input.Path + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_info.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.Objects_info.Input.Path, + headers: Operations.Objects_info.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/responses/200/content/application\/json`. + case json(Components.Schemas.FileInfo) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FileInfo { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_info.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_info.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath}/get(Objects_info)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_info.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_info.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/info/{bucketId}/{wildcardPath}/GET/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_info.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_info.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/info/{bucketId}/{wildcardPath}/get(Objects_info)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_info.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_info.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/list/{bucketId}`. + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(Objects_list)`. + internal enum Objects_list { + internal static let id: Swift.String = "Objects_list" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + internal init(bucketId: Swift.String) { + self.bucketId = bucketId + } + } + internal var path: Operations.Objects_list.Input.Path + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_list.Input.Headers + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.ListObjectsInput) + } + internal var body: Operations.Objects_list.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Objects_list.Input.Path, + headers: Operations.Objects_list.Input.Headers = .init(), + body: Operations.Objects_list.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/200/content/application\/json`. + case json([Components.Schemas.FileObject]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: [Components.Schemas.FileObject] { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_list.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_list.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(Objects_list)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_list.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_list.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/list/{bucketId}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_list.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_list.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/list/{bucketId}/post(Objects_list)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_list.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_list.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/move`. + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)`. + internal enum Objects_move { + internal static let id: Swift.String = "Objects_move" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_move.Input.Headers + /// - Remark: Generated from `#/paths/object/move/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/requestBody/content/application\/json`. + case json(Components.Schemas.MoveObjectInput) + } + internal var body: Operations.Objects_move.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + /// - body: + internal init( + headers: Operations.Objects_move.Input.Headers = .init(), + body: Operations.Objects_move.Input.Body + ) { + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + internal init() {} + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.Objects_move.Output.NoContent) + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + internal static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.Objects_move.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/move/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_move.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_move.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/move/post(Objects_move)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_move.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_move.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/sign/{bucketId}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(Objects_createSignedUrls)`. + internal enum Objects_createSignedUrls { + internal static let id: Swift.String = "Objects_createSignedUrls" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + internal init(bucketId: Swift.String) { + self.bucketId = bucketId + } + } + internal var path: Operations.Objects_createSignedUrls.Input.Path + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_createSignedUrls.Input.Headers + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlsInput) + } + internal var body: Operations.Objects_createSignedUrls.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Objects_createSignedUrls.Input.Path, + headers: Operations.Objects_createSignedUrls.Input.Headers = .init(), + body: Operations.Objects_createSignedUrls.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/200/content/application\/json`. + case json([Components.Schemas.SignedUrlResult]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: [Components.Schemas.SignedUrlResult] { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_createSignedUrls.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_createSignedUrls.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(Objects_createSignedUrls)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_createSignedUrls.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_createSignedUrls.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_createSignedUrls.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_createSignedUrls.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/post(Objects_createSignedUrls)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_createSignedUrls.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_createSignedUrls.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUrl)`. + internal enum Objects_createSignedUrl { + internal static let id: Swift.String = "Objects_createSignedUrl" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/path/wildcardPath`. + internal var wildcardPath: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath: + internal init( + bucketId: Swift.String, + wildcardPath: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath = wildcardPath + } + } + internal var path: Operations.Objects_createSignedUrl.Input.Path + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_createSignedUrl.Input.Headers + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/requestBody/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlInput) + } + internal var body: Operations.Objects_createSignedUrl.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Objects_createSignedUrl.Input.Path, + headers: Operations.Objects_createSignedUrl.Input.Headers = .init(), + body: Operations.Objects_createSignedUrl.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CreateSignedUrlOutput) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CreateSignedUrlOutput { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_createSignedUrl.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_createSignedUrl.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUrl)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_createSignedUrl.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_createSignedUrl.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/sign/{bucketId}/{wildcardPath}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_createSignedUrl.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_createSignedUrl.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUrl)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_createSignedUrl.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_createSignedUrl.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /object/upload/sign/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUploadUrl)`. + internal enum Objects_createSignedUploadUrl { + internal static let id: Swift.String = "Objects_createSignedUploadUrl" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/path/wildcardPath`. + internal var wildcardPath: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath: + internal init( + bucketId: Swift.String, + wildcardPath: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath = wildcardPath + } + } + internal var path: Operations.Objects_createSignedUploadUrl.Input.Path + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_upsert: + /// - accept: + internal init( + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.Objects_createSignedUploadUrl.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.Objects_createSignedUploadUrl.Input.Path, + headers: Operations.Objects_createSignedUploadUrl.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.CreateSignedUploadUrlOutput) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.CreateSignedUploadUrlOutput { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_createSignedUploadUrl.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_createSignedUploadUrl.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUploadUrl)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_createSignedUploadUrl.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_createSignedUploadUrl.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/upload/sign/{bucketId}/{wildcardPath}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_createSignedUploadUrl.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_createSignedUploadUrl.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/upload/sign/{bucketId}/{wildcardPath}/post(Objects_createSignedUploadUrl)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_createSignedUploadUrl.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_createSignedUploadUrl.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `DELETE /object/{bucketId}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)`. + internal enum Objects_deleteObjects { + internal static let id: Swift.String = "Objects_deleteObjects" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/path/bucketId`. + internal var bucketId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + internal init(bucketId: Swift.String) { + self.bucketId = bucketId + } + } + internal var path: Operations.Objects_deleteObjects.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_deleteObjects.Input.Headers + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/requestBody/json`. + internal struct jsonPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/requestBody/json/prefixes`. + internal var prefixes: [Swift.String] + /// Creates a new `jsonPayload`. + /// + /// - Parameters: + /// - prefixes: + internal init(prefixes: [Swift.String]) { + self.prefixes = prefixes + } + internal enum CodingKeys: String, CodingKey { + case prefixes + } + } + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/requestBody/content/application\/json`. + case json(Operations.Objects_deleteObjects.Input.Body.jsonPayload) + } + internal var body: Operations.Objects_deleteObjects.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Objects_deleteObjects.Input.Path, + headers: Operations.Objects_deleteObjects.Input.Headers = .init(), + body: Operations.Objects_deleteObjects.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/200/content/application\/json`. + case json([Components.Schemas.FileObject]) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: [Components.Schemas.FileObject] { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_deleteObjects.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_deleteObjects.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_deleteObjects.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_deleteObjects.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/DELETE/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_deleteObjects.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_deleteObjects.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_deleteObjects.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_deleteObjects.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. + internal enum Objects_head { + internal static let id: Swift.String = "Objects_head" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/HEAD/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/HEAD/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/HEAD/path/wildcardPath`. + internal var wildcardPath: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath: + internal init( + bucketId: Swift.String, + wildcardPath: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath = wildcardPath + } + } + internal var path: Operations.Objects_head.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/HEAD/header`. + internal struct Headers: Sendable, Hashable { + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - accept: + internal init(accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues()) { + self.accept = accept + } + } + internal var headers: Operations.Objects_head.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.Objects_head.Input.Path, + headers: Operations.Objects_head.Input.Headers = .init() + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// Creates a new `NoContent`. + internal init() {} + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.Objects_head.Output.NoContent) + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + internal static var noContent: Self { + .noContent(.init()) + } + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.Objects_head.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/HEAD/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/HEAD/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_head.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_head.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_head.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_head.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `POST /upload/resumable`. + /// - Remark: Generated from `#/paths//upload/resumable/post(TusUploads_create)`. + internal enum TusUploads_create { + internal static let id: Swift.String = "TusUploads_create" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/Upload-Length`. + internal var Upload_hyphen_Length: Swift.Int64 + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/Upload-Metadata`. + internal var Upload_hyphen_Metadata: Swift.String + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/Tus-Resumable`. + internal var Tus_hyphen_Resumable: Swift.String + /// - Remark: Generated from `#/paths/upload/resumable/POST/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Upload_hyphen_Length: + /// - Upload_hyphen_Metadata: + /// - Tus_hyphen_Resumable: + /// - x_hyphen_upsert: + /// - accept: + internal init( + Upload_hyphen_Length: Swift.Int64, + Upload_hyphen_Metadata: Swift.String, + Tus_hyphen_Resumable: Swift.String, + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Upload_hyphen_Length = Upload_hyphen_Length + self.Upload_hyphen_Metadata = Upload_hyphen_Metadata + self.Tus_hyphen_Resumable = Tus_hyphen_Resumable + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.TusUploads_create.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - headers: + internal init(headers: Operations.TusUploads_create.Input.Headers) { + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Created: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/201/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/201/headers/location`. + internal var location: Swift.String + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - location: + internal init(location: Swift.String) { + self.location = location + } + } + /// Received HTTP response headers + internal var headers: Operations.TusUploads_create.Output.Created.Headers + /// Creates a new `Created`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + internal init(headers: Operations.TusUploads_create.Output.Created.Headers) { + self.headers = headers + } + } + /// The request has succeeded and a new resource has been created as a result. + /// + /// - Remark: Generated from `#/paths//upload/resumable/post(TusUploads_create)/responses/201`. + /// + /// HTTP response code: `201 created`. + case created(Operations.TusUploads_create.Output.Created) + /// The associated value of the enum case if `self` is `.created`. + /// + /// - Throws: An error if `self` is not `.created`. + /// - SeeAlso: `.created`. + internal var created: Operations.TusUploads_create.Output.Created { + get throws { + switch self { + case let .created(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "created", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TusUploads_create.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TusUploads_create.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//upload/resumable/post(TusUploads_create)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TusUploads_create.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TusUploads_create.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PATCH /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(TusUploads_uploadChunk)`. + internal enum TusUploads_uploadChunk { + internal static let id: Swift.String = "TusUploads_uploadChunk" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/path/uploadId`. + internal var uploadId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - uploadId: + internal init(uploadId: Swift.String) { + self.uploadId = uploadId + } + } + internal var path: Operations.TusUploads_uploadChunk.Input.Path + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/header/Upload-Offset`. + internal var Upload_hyphen_Offset: Swift.Int64 + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/header/Tus-Resumable`. + internal var Tus_hyphen_Resumable: Swift.String + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Upload_hyphen_Offset: + /// - Tus_hyphen_Resumable: + /// - accept: + internal init( + Upload_hyphen_Offset: Swift.Int64, + Tus_hyphen_Resumable: Swift.String, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Upload_hyphen_Offset = Upload_hyphen_Offset + self.Tus_hyphen_Resumable = Tus_hyphen_Resumable + self.accept = accept + } + } + internal var headers: Operations.TusUploads_uploadChunk.Input.Headers + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + } + internal var body: Operations.TusUploads_uploadChunk.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.TusUploads_uploadChunk.Input.Path, + headers: Operations.TusUploads_uploadChunk.Input.Headers, + body: Operations.TusUploads_uploadChunk.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct NoContent: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/204/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/204/headers/Upload-Offset`. + internal var Upload_hyphen_Offset: Swift.Int64 + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Upload_hyphen_Offset: + internal init(Upload_hyphen_Offset: Swift.Int64) { + self.Upload_hyphen_Offset = Upload_hyphen_Offset + } + } + /// Received HTTP response headers + internal var headers: Operations.TusUploads_uploadChunk.Output.NoContent.Headers + /// Creates a new `NoContent`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + internal init(headers: Operations.TusUploads_uploadChunk.Output.NoContent.Headers) { + self.headers = headers + } + } + /// There is no content to send for this request, but the headers may be useful. + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(TusUploads_uploadChunk)/responses/204`. + /// + /// HTTP response code: `204 noContent`. + case noContent(Operations.TusUploads_uploadChunk.Output.NoContent) + /// The associated value of the enum case if `self` is `.noContent`. + /// + /// - Throws: An error if `self` is not `.noContent`. + /// - SeeAlso: `.noContent`. + internal var noContent: Operations.TusUploads_uploadChunk.Output.NoContent { + get throws { + switch self { + case let .noContent(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "noContent", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/PATCH/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TusUploads_uploadChunk.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TusUploads_uploadChunk.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/patch(TusUploads_uploadChunk)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TusUploads_uploadChunk.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TusUploads_uploadChunk.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `HEAD /upload/resumable/{uploadId}`. + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(TusUploads_getOffset)`. + internal enum TusUploads_getOffset { + internal static let id: Swift.String = "TusUploads_getOffset" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/path/uploadId`. + internal var uploadId: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - uploadId: + internal init(uploadId: Swift.String) { + self.uploadId = uploadId + } + } + internal var path: Operations.TusUploads_getOffset.Input.Path + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/header/Tus-Resumable`. + internal var Tus_hyphen_Resumable: Swift.String + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Tus_hyphen_Resumable: + /// - accept: + internal init( + Tus_hyphen_Resumable: Swift.String, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Tus_hyphen_Resumable = Tus_hyphen_Resumable + self.accept = accept + } + } + internal var headers: Operations.TusUploads_getOffset.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + internal init( + path: Operations.TusUploads_getOffset.Input.Path, + headers: Operations.TusUploads_getOffset.Input.Headers + ) { + self.path = path + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/200/headers/Upload-Offset`. + internal var Upload_hyphen_Offset: Swift.Int64 + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Upload_hyphen_Offset: + internal init(Upload_hyphen_Offset: Swift.Int64) { + self.Upload_hyphen_Offset = Upload_hyphen_Offset + } + } + /// Received HTTP response headers + internal var headers: Operations.TusUploads_getOffset.Output.Ok.Headers + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + internal init(headers: Operations.TusUploads_getOffset.Output.Ok.Headers) { + self.headers = headers + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(TusUploads_getOffset)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.TusUploads_getOffset.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.TusUploads_getOffset.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/upload/resumable/{uploadId}/HEAD/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.TusUploads_getOffset.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.TusUploads_getOffset.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//upload/resumable/{uploadId}/head(TusUploads_getOffset)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.TusUploads_getOffset.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.TusUploads_getOffset.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } +} diff --git a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml new file mode 100644 index 000000000..5cb17ff73 --- /dev/null +++ b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml @@ -0,0 +1,183 @@ +openapi: 3.0.0 +info: + title: Supabase Edge Functions API + version: '1.0' +tags: [] +paths: + /functions/v1/{functionName}: + get: + operationId: FunctionInvocations_invokeGet + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: x-region + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/FunctionsError' + post: + operationId: FunctionInvocations_invokePost + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: x-region + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/FunctionsError' + requestBody: + required: false + content: + application/octet-stream: + schema: + type: string + format: binary + put: + operationId: FunctionInvocations_invokePut + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: x-region + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/FunctionsError' + requestBody: + required: false + content: + application/octet-stream: + schema: + type: string + format: binary + patch: + operationId: FunctionInvocations_invokePatch + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: x-region + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/FunctionsError' + requestBody: + required: false + content: + application/octet-stream: + schema: + type: string + format: binary + delete: + operationId: FunctionInvocations_invokeDelete + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: x-region + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/octet-stream: + schema: + type: string + format: binary + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/FunctionsError' + requestBody: + required: false + content: + application/octet-stream: + schema: + type: string + format: binary +components: + schemas: + FunctionsError: + type: object + properties: + message: + type: string +servers: + - url: '{baseUrl}' + description: Supabase Edge Functions endpoint + variables: + baseUrl: + default: '' diff --git a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml new file mode 100644 index 000000000..eb081a370 --- /dev/null +++ b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml @@ -0,0 +1,344 @@ +openapi: 3.0.0 +info: + title: Supabase PostgREST API + version: '1.0' +tags: [] +paths: + /rpc/{functionName}: + post: + operationId: RpcOperations_rpc + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: params + in: query + required: false + schema: + type: object + additionalProperties: + type: string + - name: Prefer + in: header + required: false + schema: + type: string + - name: Content-Profile + in: header + required: false + schema: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' + requestBody: + required: true + content: + application/json: + schema: {} + /{table}: + get: + operationId: TableOperations_from + parameters: + - name: table + in: path + required: true + schema: + type: string + - name: params + in: query + required: false + schema: + type: object + additionalProperties: + type: string + - name: Range + in: header + required: false + schema: + type: string + - name: Prefer + in: header + required: false + schema: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' + post: + operationId: TableOperations_insert + parameters: + - name: table + in: path + required: true + schema: + type: string + - name: params + in: query + required: false + schema: + type: object + additionalProperties: + type: string + - name: Prefer + in: header + required: false + schema: + type: string + - name: Content-Profile + in: header + required: false + schema: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '201': + description: The request has succeeded and a new resource has been created as a result. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' + requestBody: + required: true + content: + application/json: + schema: {} + put: + operationId: TableOperations_upsert + parameters: + - name: table + in: path + required: true + schema: + type: string + - name: params + in: query + required: false + schema: + type: object + additionalProperties: + type: string + - name: Prefer + in: header + required: false + schema: + type: string + - name: Content-Profile + in: header + required: false + schema: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' + requestBody: + required: true + content: + application/json: + schema: {} + patch: + operationId: TableOperations_update + parameters: + - name: table + in: path + required: true + schema: + type: string + - name: params + in: query + required: false + schema: + type: object + additionalProperties: + type: string + - name: Prefer + in: header + required: false + schema: + type: string + - name: Content-Profile + in: header + required: false + schema: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' + requestBody: + required: true + content: + application/json: + schema: {} + delete: + operationId: TableOperations_deleteRows + parameters: + - name: table + in: path + required: true + schema: + type: string + - name: params + in: query + required: false + schema: + type: object + additionalProperties: + type: string + - name: Prefer + in: header + required: false + schema: + type: string + - name: Content-Profile + in: header + required: false + schema: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' +components: + schemas: + PostgRESTError: + type: object + properties: + message: + type: string + code: + type: string + details: + type: string + hint: + type: string +servers: + - url: '{baseUrl}' + description: Supabase PostgREST endpoint + variables: + baseUrl: + default: '' diff --git a/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml b/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml new file mode 100644 index 000000000..758d1f6b0 --- /dev/null +++ b/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml @@ -0,0 +1,723 @@ +openapi: 3.0.0 +info: + title: Supabase Storage API + version: '1.0' +tags: [] +paths: + /bucket: + get: + operationId: Buckets_list + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Bucket' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + post: + operationId: Buckets_create + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateBucketInput' + /bucket/{id}: + get: + operationId: Buckets_get + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/Bucket' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + put: + operationId: Buckets_update + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateBucketInput' + delete: + operationId: Buckets_deleteBucket + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + /bucket/{id}/empty: + post: + operationId: Buckets_empty + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + /object/copy: + post: + operationId: Objects_copy + parameters: [] + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/CopyObjectOutput' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CopyObjectInput' + /object/info/{bucketId}/{wildcardPath}: + get: + operationId: Objects_info + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + - name: wildcardPath + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/FileInfo' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + /object/list/{bucketId}: + post: + operationId: Objects_list + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/FileObject' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ListObjectsInput' + /object/move: + post: + operationId: Objects_move + parameters: [] + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/MoveObjectInput' + /object/sign/{bucketId}: + post: + operationId: Objects_createSignedUrls + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/SignedUrlResult' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateSignedUrlsInput' + /object/sign/{bucketId}/{wildcardPath}: + post: + operationId: Objects_createSignedUrl + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + - name: wildcardPath + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/CreateSignedUrlOutput' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/CreateSignedUrlInput' + /object/upload/sign/{bucketId}/{wildcardPath}: + post: + operationId: Objects_createSignedUploadUrl + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + - name: wildcardPath + in: path + required: true + schema: + type: string + - name: x-upsert + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/CreateSignedUploadUrlOutput' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + /object/{bucketId}: + delete: + operationId: Objects_deleteObjects + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/FileObject' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + prefixes: + type: array + items: + type: string + required: + - prefixes + /object/{bucketId}/{wildcardPath}: + head: + operationId: Objects_head + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + - name: wildcardPath + in: path + required: true + schema: + type: string + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + /upload/resumable: + post: + operationId: TusUploads_create + parameters: + - name: Upload-Length + in: header + required: true + schema: + type: integer + format: int64 + - name: Upload-Metadata + in: header + required: true + schema: + type: string + - name: Tus-Resumable + in: header + required: true + schema: + type: string + - name: x-upsert + in: header + required: false + schema: + type: string + responses: + '201': + description: The request has succeeded and a new resource has been created as a result. + headers: + location: + required: true + schema: + type: string + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + /upload/resumable/{uploadId}: + patch: + operationId: TusUploads_uploadChunk + parameters: + - name: uploadId + in: path + required: true + schema: + type: string + - name: Upload-Offset + in: header + required: true + schema: + type: integer + format: int64 + - name: Tus-Resumable + in: header + required: true + schema: + type: string + responses: + '204': + description: 'There is no content to send for this request, but the headers may be useful. ' + headers: + Upload-Offset: + required: true + schema: + type: integer + format: int64 + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + application/octet-stream: + schema: + type: string + format: binary + head: + operationId: TusUploads_getOffset + parameters: + - name: uploadId + in: path + required: true + schema: + type: string + - name: Tus-Resumable + in: header + required: true + schema: + type: string + responses: + '200': + description: The request has succeeded. + headers: + Upload-Offset: + required: true + schema: + type: integer + format: int64 + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' +components: + schemas: + Bucket: + type: object + required: + - id + - name + - public + properties: + id: + type: string + name: + type: string + public: + type: boolean + file_size_limit: + type: integer + format: int64 + allowed_mime_types: + type: array + items: + type: string + created_at: + type: string + updated_at: + type: string + CopyObjectInput: + type: object + required: + - bucketId + - sourceKey + - destinationKey + properties: + bucketId: + type: string + sourceKey: + type: string + destinationKey: + type: string + destinationBucket: + type: string + CopyObjectOutput: + type: object + required: + - Key + properties: + Key: + type: string + CreateBucketInput: + type: object + required: + - id + - name + - public + properties: + id: + type: string + name: + type: string + public: + type: boolean + file_size_limit: + type: integer + format: int64 + allowed_mime_types: + type: array + items: + type: string + CreateSignedUploadUrlOutput: + type: object + required: + - url + properties: + url: + type: string + CreateSignedUrlInput: + type: object + required: + - expiresIn + properties: + expiresIn: + type: integer + format: int32 + CreateSignedUrlOutput: + type: object + required: + - signedURL + properties: + signedURL: + type: string + CreateSignedUrlsInput: + type: object + required: + - expiresIn + - paths + properties: + expiresIn: + type: integer + format: int32 + paths: + type: array + items: + type: string + FileInfo: + type: object + properties: + eTag: + type: string + size: + type: integer + format: int64 + mimetype: + type: string + cacheControl: + type: string + lastModified: + type: string + contentLength: + type: integer + format: int64 + httpStatusCode: + type: integer + format: int32 + FileMetadata: + type: object + properties: + eTag: + type: string + size: + type: integer + format: int64 + mimetype: + type: string + cacheControl: + type: string + lastModified: + type: string + contentLength: + type: integer + format: int64 + httpStatusCode: + type: integer + format: int32 + FileObject: + type: object + required: + - name + properties: + name: + type: string + id: + type: string + updated_at: + type: string + created_at: + type: string + last_accessed_at: + type: string + metadata: + $ref: '#/components/schemas/FileMetadata' + ListObjectsInput: + type: object + required: + - prefix + properties: + prefix: + type: string + limit: + type: integer + format: int32 + offset: + type: integer + format: int32 + sortBy: + $ref: '#/components/schemas/SortBy' + MoveObjectInput: + type: object + required: + - bucketId + - sourceKey + - destinationKey + properties: + bucketId: + type: string + sourceKey: + type: string + destinationKey: + type: string + destinationBucket: + type: string + SignedUrlResult: + type: object + required: + - path + properties: + signedURL: + type: string + path: + type: string + error: + type: string + SortBy: + type: object + properties: + column: + type: string + order: + type: string + StorageError: + type: object + properties: + message: + type: string + error: + type: string + statusCode: + type: string + UpdateBucketInput: + type: object + required: + - public + properties: + public: + type: boolean + file_size_limit: + type: integer + format: int64 + allowed_mime_types: + type: array + items: + type: string +servers: + - url: '{baseUrl}' + description: Supabase Storage endpoint + variables: + baseUrl: + default: '' From 744dac53fae2cb32f60448fac6c719bcc56f2ad1 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 08:42:45 -0300 Subject: [PATCH 27/32] spike(typespec): regenerate PostgREST Swift client from fixed TypeSpec model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated postgrest.tsp in supabase/sdk (commit 720bc1d) splits named fixed params from the dynamic filters map. Changes in generated output: - select, order, limit (Swift.Int), offset (Swift.Int) are now separate typed members on each table operation query struct - filters: filtersPayload (additionalProperties[String:String]) is its own member, not mixed with fixed params - FilterOperator enum (24 operators) generated from TypeSpec enum - RpcOperations_rpcGet added as a separate GET operation for RPC - 2969→3107 lines (TypeSpec now matches Smithy coverage) --- .../PostgREST/GeneratedTypeSpec/Client.swift | 239 +++++++- .../PostgREST/GeneratedTypeSpec/Types.swift | 573 +++++++++++++++--- .../openapi.Supabase.PostgREST.yaml | 198 +++++- 3 files changed, 911 insertions(+), 99 deletions(-) diff --git a/Sources/PostgREST/GeneratedTypeSpec/Client.swift b/Sources/PostgREST/GeneratedTypeSpec/Client.swift index 94410226b..4ba177d51 100644 --- a/Sources/PostgREST/GeneratedTypeSpec/Client.swift +++ b/Sources/PostgREST/GeneratedTypeSpec/Client.swift @@ -37,6 +37,122 @@ internal struct Client: APIProtocol { private var converter: Converter { client.converter } + /// Call a read-only RPC function via GET. + /// Function arguments are passed as query params (each arg is its own param). + /// + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(RpcOperations_rpcGet)`. + internal func RpcOperations_rpcGet(_ input: Operations.RpcOperations_rpcGet.Input) async throws -> Operations.RpcOperations_rpcGet.Output { + try await client.send( + input: input, + forOperation: Operations.RpcOperations_rpcGet.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/rpc/{}", + parameters: [ + input.path.functionName + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .get + ) + suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: true, + name: "args", + value: input.query.args + ) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "Accept-Profile", + value: input.headers.Accept_hyphen_Profile + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + return (request, nil) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let headers: Operations.RpcOperations_rpcGet.Output.Ok.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.RpcOperations_rpcGet.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + OpenAPIRuntime.OpenAPIValueContainer.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init( + headers: headers, + body: body + )) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.RpcOperations_rpcGet.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.PostgRESTError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// Call an RPC function via POST with a JSON body. + /// /// - Remark: HTTP `POST /rpc/{functionName}`. /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. internal func RpcOperations_rpc(_ input: Operations.RpcOperations_rpc.Input) async throws -> Operations.RpcOperations_rpc.Output { @@ -58,9 +174,9 @@ internal struct Client: APIProtocol { try converter.setQueryItemAsURI( in: &request, style: .form, - explode: true, - name: "params", - value: input.query.params + explode: false, + name: "select", + value: input.query.select ) try converter.setHeaderFieldAsURI( in: &request.headerFields, @@ -95,6 +211,18 @@ internal struct Client: APIProtocol { deserializer: { response, responseBody in switch response.status.code { case 200: + let headers: Operations.RpcOperations_rpc.Output.Ok.Headers = .init( + Content_hyphen_Range: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Content-Range", + as: Swift.String.self + ), + Preference_hyphen_Applied: try converter.getOptionalHeaderFieldAsURI( + in: response.headerFields, + name: "Preference-Applied", + as: Swift.String.self + ) + ) let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.RpcOperations_rpc.Output.Ok.Body let chosenContentType = try converter.bestContentType( @@ -115,7 +243,10 @@ internal struct Client: APIProtocol { default: preconditionFailure("bestContentType chose an invalid content type.") } - return .ok(.init(body: body)) + return .ok(.init( + headers: headers, + body: body + )) default: let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) let body: Operations.RpcOperations_rpc.Output.Default.Body @@ -145,6 +276,13 @@ internal struct Client: APIProtocol { } ) } + /// SELECT rows from a table. + /// + /// Fixed params (select, order, limit, offset) are named so generators emit + /// typed, documented parameters. Column filters are passed via `filters`: + /// each map entry becomes its own query parameter when serialized + /// (explode: true), e.g. {"id": "eq.5"} → ?id=eq.5. + /// /// - Remark: HTTP `GET /{table}`. /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. internal func TableOperations_from(_ input: Operations.TableOperations_from.Input) async throws -> Operations.TableOperations_from.Output { @@ -163,12 +301,40 @@ internal struct Client: APIProtocol { method: .get ) suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "order", + value: input.query.order + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "limit", + value: input.query.limit + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "offset", + value: input.query.offset + ) try converter.setQueryItemAsURI( in: &request, style: .form, explode: true, - name: "params", - value: input.query.params + name: "filters", + value: input.query.filters ) try converter.setHeaderFieldAsURI( in: &request.headerFields, @@ -259,6 +425,8 @@ internal struct Client: APIProtocol { } ) } + /// INSERT rows into a table. + /// /// - Remark: HTTP `POST /{table}`. /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. internal func TableOperations_insert(_ input: Operations.TableOperations_insert.Input) async throws -> Operations.TableOperations_insert.Output { @@ -280,9 +448,16 @@ internal struct Client: APIProtocol { try converter.setQueryItemAsURI( in: &request, style: .form, - explode: true, - name: "params", - value: input.query.params + explode: false, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "columns", + value: input.query.columns ) try converter.setHeaderFieldAsURI( in: &request.headerFields, @@ -382,6 +557,8 @@ internal struct Client: APIProtocol { } ) } + /// UPDATE rows matching the filter. + /// /// - Remark: HTTP `PATCH /{table}`. /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. internal func TableOperations_update(_ input: Operations.TableOperations_update.Input) async throws -> Operations.TableOperations_update.Output { @@ -400,12 +577,19 @@ internal struct Client: APIProtocol { method: .patch ) suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "select", + value: input.query.select + ) try converter.setQueryItemAsURI( in: &request, style: .form, explode: true, - name: "params", - value: input.query.params + name: "filters", + value: input.query.filters ) try converter.setHeaderFieldAsURI( in: &request.headerFields, @@ -505,6 +689,8 @@ internal struct Client: APIProtocol { } ) } + /// UPSERT rows (PUT). + /// /// - Remark: HTTP `PUT /{table}`. /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. internal func TableOperations_upsert(_ input: Operations.TableOperations_upsert.Input) async throws -> Operations.TableOperations_upsert.Output { @@ -523,12 +709,26 @@ internal struct Client: APIProtocol { method: .put ) suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "select", + value: input.query.select + ) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "on_conflict", + value: input.query.on_conflict + ) try converter.setQueryItemAsURI( in: &request, style: .form, explode: true, - name: "params", - value: input.query.params + name: "filters", + value: input.query.filters ) try converter.setHeaderFieldAsURI( in: &request.headerFields, @@ -628,6 +828,8 @@ internal struct Client: APIProtocol { } ) } + /// DELETE rows matching the filter. + /// /// - Remark: HTTP `DELETE /{table}`. /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. internal func TableOperations_deleteRows(_ input: Operations.TableOperations_deleteRows.Input) async throws -> Operations.TableOperations_deleteRows.Output { @@ -646,12 +848,19 @@ internal struct Client: APIProtocol { method: .delete ) suppressMutabilityWarning(&request) + try converter.setQueryItemAsURI( + in: &request, + style: .form, + explode: false, + name: "select", + value: input.query.select + ) try converter.setQueryItemAsURI( in: &request, style: .form, explode: true, - name: "params", - value: input.query.params + name: "filters", + value: input.query.filters ) try converter.setHeaderFieldAsURI( in: &request.headerFields, diff --git a/Sources/PostgREST/GeneratedTypeSpec/Types.swift b/Sources/PostgREST/GeneratedTypeSpec/Types.swift index 8d897a472..11900961d 100644 --- a/Sources/PostgREST/GeneratedTypeSpec/Types.swift +++ b/Sources/PostgREST/GeneratedTypeSpec/Types.swift @@ -11,21 +11,44 @@ import struct Foundation.Date #endif /// A type that performs HTTP operations defined by the OpenAPI document. internal protocol APIProtocol: Sendable { + /// Call a read-only RPC function via GET. + /// Function arguments are passed as query params (each arg is its own param). + /// + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(RpcOperations_rpcGet)`. + func RpcOperations_rpcGet(_ input: Operations.RpcOperations_rpcGet.Input) async throws -> Operations.RpcOperations_rpcGet.Output + /// Call an RPC function via POST with a JSON body. + /// /// - Remark: HTTP `POST /rpc/{functionName}`. /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. func RpcOperations_rpc(_ input: Operations.RpcOperations_rpc.Input) async throws -> Operations.RpcOperations_rpc.Output + /// SELECT rows from a table. + /// + /// Fixed params (select, order, limit, offset) are named so generators emit + /// typed, documented parameters. Column filters are passed via `filters`: + /// each map entry becomes its own query parameter when serialized + /// (explode: true), e.g. {"id": "eq.5"} → ?id=eq.5. + /// /// - Remark: HTTP `GET /{table}`. /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. func TableOperations_from(_ input: Operations.TableOperations_from.Input) async throws -> Operations.TableOperations_from.Output + /// INSERT rows into a table. + /// /// - Remark: HTTP `POST /{table}`. /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. func TableOperations_insert(_ input: Operations.TableOperations_insert.Input) async throws -> Operations.TableOperations_insert.Output + /// UPDATE rows matching the filter. + /// /// - Remark: HTTP `PATCH /{table}`. /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. func TableOperations_update(_ input: Operations.TableOperations_update.Input) async throws -> Operations.TableOperations_update.Output + /// UPSERT rows (PUT). + /// /// - Remark: HTTP `PUT /{table}`. /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. func TableOperations_upsert(_ input: Operations.TableOperations_upsert.Input) async throws -> Operations.TableOperations_upsert.Output + /// DELETE rows matching the filter. + /// /// - Remark: HTTP `DELETE /{table}`. /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. func TableOperations_deleteRows(_ input: Operations.TableOperations_deleteRows.Input) async throws -> Operations.TableOperations_deleteRows.Output @@ -33,6 +56,24 @@ internal protocol APIProtocol: Sendable { /// Convenience overloads for operation inputs. extension APIProtocol { + /// Call a read-only RPC function via GET. + /// Function arguments are passed as query params (each arg is its own param). + /// + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(RpcOperations_rpcGet)`. + internal func RpcOperations_rpcGet( + path: Operations.RpcOperations_rpcGet.Input.Path, + query: Operations.RpcOperations_rpcGet.Input.Query = .init(), + headers: Operations.RpcOperations_rpcGet.Input.Headers = .init() + ) async throws -> Operations.RpcOperations_rpcGet.Output { + try await RpcOperations_rpcGet(Operations.RpcOperations_rpcGet.Input( + path: path, + query: query, + headers: headers + )) + } + /// Call an RPC function via POST with a JSON body. + /// /// - Remark: HTTP `POST /rpc/{functionName}`. /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. internal func RpcOperations_rpc( @@ -48,6 +89,13 @@ extension APIProtocol { body: body )) } + /// SELECT rows from a table. + /// + /// Fixed params (select, order, limit, offset) are named so generators emit + /// typed, documented parameters. Column filters are passed via `filters`: + /// each map entry becomes its own query parameter when serialized + /// (explode: true), e.g. {"id": "eq.5"} → ?id=eq.5. + /// /// - Remark: HTTP `GET /{table}`. /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. internal func TableOperations_from( @@ -61,6 +109,8 @@ extension APIProtocol { headers: headers )) } + /// INSERT rows into a table. + /// /// - Remark: HTTP `POST /{table}`. /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. internal func TableOperations_insert( @@ -76,6 +126,8 @@ extension APIProtocol { body: body )) } + /// UPDATE rows matching the filter. + /// /// - Remark: HTTP `PATCH /{table}`. /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. internal func TableOperations_update( @@ -91,6 +143,8 @@ extension APIProtocol { body: body )) } + /// UPSERT rows (PUT). + /// /// - Remark: HTTP `PUT /{table}`. /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. internal func TableOperations_upsert( @@ -106,6 +160,8 @@ extension APIProtocol { body: body )) } + /// DELETE rows matching the filter. + /// /// - Remark: HTTP `DELETE /{table}`. /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. internal func TableOperations_deleteRows( @@ -163,6 +219,39 @@ internal enum Servers { internal enum Components { /// Types generated from the `#/components/schemas` section of the OpenAPI document. internal enum Schemas { + /// PostgREST column filter operators. + /// Format a filter value as "{operator}.{value}", e.g. "eq.5". + /// Prefix with "not." to negate: "not.eq.5". + /// For logical grouping use keys "or" / "and" in the filters map. + /// + /// - Remark: Generated from `#/components/schemas/FilterOperator`. + internal enum FilterOperator: String, Codable, Hashable, Sendable, CaseIterable { + case eq = "eq" + case neq = "neq" + case lt = "lt" + case lte = "lte" + case gt = "gt" + case gte = "gte" + case like = "like" + case ilike = "ilike" + case match = "match" + case imatch = "imatch" + case _is = "is" + case isdistinct = "isdistinct" + case _in = "in" + case cs = "cs" + case cd = "cd" + case ov = "ov" + case sl = "sl" + case sr = "sr" + case nxl = "nxl" + case nxr = "nxr" + case adj = "adj" + case fts = "fts" + case plfts = "plfts" + case phfts = "phfts" + case wfts = "wfts" + } /// - Remark: Generated from `#/components/schemas/PostgRESTError`. internal struct PostgRESTError: Codable, Hashable, Sendable { /// - Remark: Generated from `#/components/schemas/PostgRESTError/message`. @@ -211,14 +300,17 @@ internal enum Components { /// API operations, with input and output types, generated from `#/paths` in the OpenAPI document. internal enum Operations { - /// - Remark: HTTP `POST /rpc/{functionName}`. - /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. - internal enum RpcOperations_rpc { - internal static let id: Swift.String = "RpcOperations_rpc" + /// Call a read-only RPC function via GET. + /// Function arguments are passed as query params (each arg is its own param). + /// + /// - Remark: HTTP `GET /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(RpcOperations_rpcGet)`. + internal enum RpcOperations_rpcGet { + internal static let id: Swift.String = "RpcOperations_rpcGet" internal struct Input: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path`. + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/path`. internal struct Path: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path/functionName`. + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/path/functionName`. internal var functionName: Swift.String /// Creates a new `Path`. /// @@ -228,14 +320,16 @@ internal enum Operations { self.functionName = functionName } } - internal var path: Operations.RpcOperations_rpc.Input.Path - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query`. + internal var path: Operations.RpcOperations_rpcGet.Input.Path + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query`. internal struct Query: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query/params`. - internal struct paramsPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query/select`. + internal var select: Swift.String? + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query/args`. + internal struct argsPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. internal var additionalProperties: [String: Swift.String] - /// Creates a new `paramsPayload`. + /// Creates a new `argsPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. @@ -249,14 +343,245 @@ internal enum Operations { try encoder.encodeAdditionalProperties(additionalProperties) } } - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query/params`. - internal var params: Operations.RpcOperations_rpc.Input.Query.paramsPayload? + /// Function arguments — each entry becomes its own query parameter. + /// + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/query/args`. + internal var args: Operations.RpcOperations_rpcGet.Input.Query.argsPayload? + /// Creates a new `Query`. + /// + /// - Parameters: + /// - select: + /// - args: Function arguments — each entry becomes its own query parameter. + internal init( + select: Swift.String? = nil, + args: Operations.RpcOperations_rpcGet.Input.Query.argsPayload? = nil + ) { + self.select = select + self.args = args + } + } + internal var query: Operations.RpcOperations_rpcGet.Input.Query + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/header/Accept-Profile`. + internal var Accept_hyphen_Profile: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Accept_hyphen_Profile: + /// - accept: + internal init( + Accept_hyphen_Profile: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.Accept_hyphen_Profile = Accept_hyphen_Profile + self.accept = accept + } + } + internal var headers: Operations.RpcOperations_rpcGet.Input.Headers + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - query: + /// - headers: + internal init( + path: Operations.RpcOperations_rpcGet.Input.Path, + query: Operations.RpcOperations_rpcGet.Input.Query = .init(), + headers: Operations.RpcOperations_rpcGet.Input.Headers = .init() + ) { + self.path = path + self.query = query + self.headers = headers + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.RpcOperations_rpcGet.Output.Ok.Headers + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: OpenAPIRuntime.OpenAPIValueContainer { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.RpcOperations_rpcGet.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - headers: Received HTTP response headers + /// - body: Received HTTP response body + internal init( + headers: Operations.RpcOperations_rpcGet.Output.Ok.Headers = .init(), + body: Operations.RpcOperations_rpcGet.Output.Ok.Body + ) { + self.headers = headers + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(RpcOperations_rpcGet)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.RpcOperations_rpcGet.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.RpcOperations_rpcGet.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/default/content/application\/json`. + case json(Components.Schemas.PostgRESTError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.PostgRESTError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.RpcOperations_rpcGet.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.RpcOperations_rpcGet.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//rpc/{functionName}/get(RpcOperations_rpcGet)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.RpcOperations_rpcGet.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.RpcOperations_rpcGet.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// Call an RPC function via POST with a JSON body. + /// + /// - Remark: HTTP `POST /rpc/{functionName}`. + /// - Remark: Generated from `#/paths//rpc/{functionName}/post(RpcOperations_rpc)`. + internal enum RpcOperations_rpc { + internal static let id: Swift.String = "RpcOperations_rpc" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/path/functionName`. + internal var functionName: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - functionName: + internal init(functionName: Swift.String) { + self.functionName = functionName + } + } + internal var path: Operations.RpcOperations_rpc.Input.Path + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query`. + internal struct Query: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/query/select`. + internal var select: Swift.String? /// Creates a new `Query`. /// /// - Parameters: - /// - params: - internal init(params: Operations.RpcOperations_rpc.Input.Query.paramsPayload? = nil) { - self.params = params + /// - select: + internal init(select: Swift.String? = nil) { + self.select = select } } internal var query: Operations.RpcOperations_rpc.Input.Query @@ -316,6 +641,27 @@ internal enum Operations { } internal enum Output: Sendable, Hashable { internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/headers`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/headers/Content-Range`. + internal var Content_hyphen_Range: Swift.String? + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/headers/Preference-Applied`. + internal var Preference_hyphen_Applied: Swift.String? + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - Content_hyphen_Range: + /// - Preference_hyphen_Applied: + internal init( + Content_hyphen_Range: Swift.String? = nil, + Preference_hyphen_Applied: Swift.String? = nil + ) { + self.Content_hyphen_Range = Content_hyphen_Range + self.Preference_hyphen_Applied = Preference_hyphen_Applied + } + } + /// Received HTTP response headers + internal var headers: Operations.RpcOperations_rpc.Output.Ok.Headers /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content`. internal enum Body: Sendable, Hashable { /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content/application\/json`. @@ -338,8 +684,13 @@ internal enum Operations { /// Creates a new `Ok`. /// /// - Parameters: + /// - headers: Received HTTP response headers /// - body: Received HTTP response body - internal init(body: Operations.RpcOperations_rpc.Output.Ok.Body) { + internal init( + headers: Operations.RpcOperations_rpc.Output.Ok.Headers = .init(), + body: Operations.RpcOperations_rpc.Output.Ok.Body + ) { + self.headers = headers self.body = body } } @@ -444,6 +795,13 @@ internal enum Operations { } } } + /// SELECT rows from a table. + /// + /// Fixed params (select, order, limit, offset) are named so generators emit + /// typed, documented parameters. Column filters are passed via `filters`: + /// each map entry becomes its own query parameter when serialized + /// (explode: true), e.g. {"id": "eq.5"} → ?id=eq.5. + /// /// - Remark: HTTP `GET /{table}`. /// - Remark: Generated from `#/paths//{table}/get(TableOperations_from)`. internal enum TableOperations_from { @@ -464,11 +822,28 @@ internal enum Operations { internal var path: Operations.TableOperations_from.Input.Path /// - Remark: Generated from `#/paths/{table}/GET/query`. internal struct Query: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/GET/query/params`. - internal struct paramsPayload: Codable, Hashable, Sendable { + /// Column selection — comma-separated list, supports aliasing, casting, + /// embedded resources, and JSON operators. e.g. "id,name,orders(total)". + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/select`. + internal var select: Swift.String? + /// Ordering — e.g. "name.asc,age.desc.nullslast" + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/order`. + internal var order: Swift.String? + /// Maximum number of rows to return. + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/limit`. + internal var limit: Swift.Int? + /// Row offset for pagination. + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/offset`. + internal var offset: Swift.Int? + /// - Remark: Generated from `#/paths/{table}/GET/query/filters`. + internal struct filtersPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. internal var additionalProperties: [String: Swift.String] - /// Creates a new `paramsPayload`. + /// Creates a new `filtersPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. @@ -482,14 +857,33 @@ internal enum Operations { try encoder.encodeAdditionalProperties(additionalProperties) } } - /// - Remark: Generated from `#/paths/{table}/GET/query/params`. - internal var params: Operations.TableOperations_from.Input.Query.paramsPayload? + /// Horizontal filters — each entry becomes a separate query parameter. + /// Key: column name (or "or"/"and" for logical groups). + /// Value: "{operator}.{value}" e.g. {"id": "eq.5", "name": "like.foo*"}. + /// See FilterOperator for the full operator list. + /// + /// - Remark: Generated from `#/paths/{table}/GET/query/filters`. + internal var filters: Operations.TableOperations_from.Input.Query.filtersPayload? /// Creates a new `Query`. /// /// - Parameters: - /// - params: - internal init(params: Operations.TableOperations_from.Input.Query.paramsPayload? = nil) { - self.params = params + /// - select: Column selection — comma-separated list, supports aliasing, casting, + /// - order: Ordering — e.g. "name.asc,age.desc.nullslast" + /// - limit: Maximum number of rows to return. + /// - offset: Row offset for pagination. + /// - filters: Horizontal filters — each entry becomes a separate query parameter. + internal init( + select: Swift.String? = nil, + order: Swift.String? = nil, + limit: Swift.Int? = nil, + offset: Swift.Int? = nil, + filters: Operations.TableOperations_from.Input.Query.filtersPayload? = nil + ) { + self.select = select + self.order = order + self.limit = limit + self.offset = offset + self.filters = filters } } internal var query: Operations.TableOperations_from.Input.Query @@ -694,6 +1088,8 @@ internal enum Operations { } } } + /// INSERT rows into a table. + /// /// - Remark: HTTP `POST /{table}`. /// - Remark: Generated from `#/paths//{table}/post(TableOperations_insert)`. internal enum TableOperations_insert { @@ -714,32 +1110,25 @@ internal enum Operations { internal var path: Operations.TableOperations_insert.Input.Path /// - Remark: Generated from `#/paths/{table}/POST/query`. internal struct Query: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/POST/query/params`. - internal struct paramsPayload: Codable, Hashable, Sendable { - /// A container of undocumented properties. - internal var additionalProperties: [String: Swift.String] - /// Creates a new `paramsPayload`. - /// - /// - Parameters: - /// - additionalProperties: A container of undocumented properties. - internal init(additionalProperties: [String: Swift.String] = .init()) { - self.additionalProperties = additionalProperties - } - internal init(from decoder: any Swift.Decoder) throws { - additionalProperties = try decoder.decodeAdditionalProperties(knownKeys: []) - } - internal func encode(to encoder: any Swift.Encoder) throws { - try encoder.encodeAdditionalProperties(additionalProperties) - } - } - /// - Remark: Generated from `#/paths/{table}/POST/query/params`. - internal var params: Operations.TableOperations_insert.Input.Query.paramsPayload? + /// Column selection for the returned representation (requires Prefer: return=representation). + /// + /// - Remark: Generated from `#/paths/{table}/POST/query/select`. + internal var select: Swift.String? + /// Columns hint for bulk insert. + /// + /// - Remark: Generated from `#/paths/{table}/POST/query/columns`. + internal var columns: Swift.String? /// Creates a new `Query`. /// /// - Parameters: - /// - params: - internal init(params: Operations.TableOperations_insert.Input.Query.paramsPayload? = nil) { - self.params = params + /// - select: Column selection for the returned representation (requires Prefer: return=representation). + /// - columns: Columns hint for bulk insert. + internal init( + select: Swift.String? = nil, + columns: Swift.String? = nil + ) { + self.select = select + self.columns = columns } } internal var query: Operations.TableOperations_insert.Input.Query @@ -953,6 +1342,8 @@ internal enum Operations { } } } + /// UPDATE rows matching the filter. + /// /// - Remark: HTTP `PATCH /{table}`. /// - Remark: Generated from `#/paths//{table}/patch(TableOperations_update)`. internal enum TableOperations_update { @@ -973,11 +1364,13 @@ internal enum Operations { internal var path: Operations.TableOperations_update.Input.Path /// - Remark: Generated from `#/paths/{table}/PATCH/query`. internal struct Query: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PATCH/query/params`. - internal struct paramsPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/{table}/PATCH/query/select`. + internal var select: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PATCH/query/filters`. + internal struct filtersPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. internal var additionalProperties: [String: Swift.String] - /// Creates a new `paramsPayload`. + /// Creates a new `filtersPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. @@ -991,14 +1384,21 @@ internal enum Operations { try encoder.encodeAdditionalProperties(additionalProperties) } } - /// - Remark: Generated from `#/paths/{table}/PATCH/query/params`. - internal var params: Operations.TableOperations_update.Input.Query.paramsPayload? + /// Horizontal filters — each entry becomes a separate query parameter. + /// + /// - Remark: Generated from `#/paths/{table}/PATCH/query/filters`. + internal var filters: Operations.TableOperations_update.Input.Query.filtersPayload? /// Creates a new `Query`. /// /// - Parameters: - /// - params: - internal init(params: Operations.TableOperations_update.Input.Query.paramsPayload? = nil) { - self.params = params + /// - select: + /// - filters: Horizontal filters — each entry becomes a separate query parameter. + internal init( + select: Swift.String? = nil, + filters: Operations.TableOperations_update.Input.Query.filtersPayload? = nil + ) { + self.select = select + self.filters = filters } } internal var query: Operations.TableOperations_update.Input.Query @@ -1212,6 +1612,8 @@ internal enum Operations { } } } + /// UPSERT rows (PUT). + /// /// - Remark: HTTP `PUT /{table}`. /// - Remark: Generated from `#/paths//{table}/put(TableOperations_upsert)`. internal enum TableOperations_upsert { @@ -1232,11 +1634,17 @@ internal enum Operations { internal var path: Operations.TableOperations_upsert.Input.Path /// - Remark: Generated from `#/paths/{table}/PUT/query`. internal struct Query: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PUT/query/params`. - internal struct paramsPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/{table}/PUT/query/select`. + internal var select: Swift.String? + /// Comma-separated columns to use as the conflict target for upsert. + /// + /// - Remark: Generated from `#/paths/{table}/PUT/query/on_conflict`. + internal var on_conflict: Swift.String? + /// - Remark: Generated from `#/paths/{table}/PUT/query/filters`. + internal struct filtersPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. internal var additionalProperties: [String: Swift.String] - /// Creates a new `paramsPayload`. + /// Creates a new `filtersPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. @@ -1250,14 +1658,24 @@ internal enum Operations { try encoder.encodeAdditionalProperties(additionalProperties) } } - /// - Remark: Generated from `#/paths/{table}/PUT/query/params`. - internal var params: Operations.TableOperations_upsert.Input.Query.paramsPayload? + /// Horizontal filters — each entry becomes a separate query parameter. + /// + /// - Remark: Generated from `#/paths/{table}/PUT/query/filters`. + internal var filters: Operations.TableOperations_upsert.Input.Query.filtersPayload? /// Creates a new `Query`. /// /// - Parameters: - /// - params: - internal init(params: Operations.TableOperations_upsert.Input.Query.paramsPayload? = nil) { - self.params = params + /// - select: + /// - on_conflict: Comma-separated columns to use as the conflict target for upsert. + /// - filters: Horizontal filters — each entry becomes a separate query parameter. + internal init( + select: Swift.String? = nil, + on_conflict: Swift.String? = nil, + filters: Operations.TableOperations_upsert.Input.Query.filtersPayload? = nil + ) { + self.select = select + self.on_conflict = on_conflict + self.filters = filters } } internal var query: Operations.TableOperations_upsert.Input.Query @@ -1471,6 +1889,8 @@ internal enum Operations { } } } + /// DELETE rows matching the filter. + /// /// - Remark: HTTP `DELETE /{table}`. /// - Remark: Generated from `#/paths//{table}/delete(TableOperations_deleteRows)`. internal enum TableOperations_deleteRows { @@ -1491,11 +1911,13 @@ internal enum Operations { internal var path: Operations.TableOperations_deleteRows.Input.Path /// - Remark: Generated from `#/paths/{table}/DELETE/query`. internal struct Query: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/DELETE/query/params`. - internal struct paramsPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/{table}/DELETE/query/select`. + internal var select: Swift.String? + /// - Remark: Generated from `#/paths/{table}/DELETE/query/filters`. + internal struct filtersPayload: Codable, Hashable, Sendable { /// A container of undocumented properties. internal var additionalProperties: [String: Swift.String] - /// Creates a new `paramsPayload`. + /// Creates a new `filtersPayload`. /// /// - Parameters: /// - additionalProperties: A container of undocumented properties. @@ -1509,14 +1931,21 @@ internal enum Operations { try encoder.encodeAdditionalProperties(additionalProperties) } } - /// - Remark: Generated from `#/paths/{table}/DELETE/query/params`. - internal var params: Operations.TableOperations_deleteRows.Input.Query.paramsPayload? + /// Horizontal filters — each entry becomes a separate query parameter. + /// + /// - Remark: Generated from `#/paths/{table}/DELETE/query/filters`. + internal var filters: Operations.TableOperations_deleteRows.Input.Query.filtersPayload? /// Creates a new `Query`. /// /// - Parameters: - /// - params: - internal init(params: Operations.TableOperations_deleteRows.Input.Query.paramsPayload? = nil) { - self.params = params + /// - select: + /// - filters: Horizontal filters — each entry becomes a separate query parameter. + internal init( + select: Swift.String? = nil, + filters: Operations.TableOperations_deleteRows.Input.Query.filtersPayload? = nil + ) { + self.select = select + self.filters = filters } } internal var query: Operations.TableOperations_deleteRows.Input.Query diff --git a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml index eb081a370..174db24fb 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml @@ -7,19 +7,19 @@ paths: /rpc/{functionName}: post: operationId: RpcOperations_rpc + description: Call an RPC function via POST with a JSON body. parameters: - name: functionName in: path required: true schema: type: string - - name: params + - name: select in: query required: false schema: - type: object - additionalProperties: - type: string + type: string + explode: false - name: Prefer in: header required: false @@ -38,6 +38,15 @@ paths: responses: '200': description: The request has succeeded. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string content: application/json: schema: {} @@ -52,18 +61,111 @@ paths: content: application/json: schema: {} + get: + operationId: RpcOperations_rpcGet + description: |- + Call a read-only RPC function via GET. + Function arguments are passed as query params (each arg is its own param). + parameters: + - name: functionName + in: path + required: true + schema: + type: string + - name: select + in: query + required: false + schema: + type: string + explode: false + - name: args + in: query + required: false + description: Function arguments — each entry becomes its own query parameter. + schema: + type: object + additionalProperties: + type: string + - name: Accept-Profile + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + headers: + Content-Range: + required: false + schema: + type: string + Preference-Applied: + required: false + schema: + type: string + content: + application/json: + schema: {} + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/PostgRESTError' /{table}: get: operationId: TableOperations_from + description: |- + SELECT rows from a table. + + Fixed params (select, order, limit, offset) are named so generators emit + typed, documented parameters. Column filters are passed via `filters`: + each map entry becomes its own query parameter when serialized + (explode: true), e.g. {"id": "eq.5"} → ?id=eq.5. parameters: - name: table in: path required: true schema: type: string - - name: params + - name: select + in: query + required: false + description: |- + Column selection — comma-separated list, supports aliasing, casting, + embedded resources, and JSON operators. e.g. "id,name,orders(total)". + schema: + type: string + explode: false + - name: order + in: query + required: false + description: Ordering — e.g. "name.asc,age.desc.nullslast" + schema: + type: string + explode: false + - name: limit + in: query + required: false + description: Maximum number of rows to return. + schema: + type: integer + explode: false + - name: offset + in: query + required: false + description: Row offset for pagination. + schema: + type: integer + explode: false + - name: filters in: query required: false + description: |- + Horizontal filters — each entry becomes a separate query parameter. + Key: column name (or "or"/"and" for logical groups). + Value: "{operator}.{value}" e.g. {"id": "eq.5", "name": "like.foo*"}. + See FilterOperator for the full operator list. schema: type: object additionalProperties: @@ -106,19 +208,27 @@ paths: $ref: '#/components/schemas/PostgRESTError' post: operationId: TableOperations_insert + description: INSERT rows into a table. parameters: - name: table in: path required: true schema: type: string - - name: params + - name: select in: query required: false + description: 'Column selection for the returned representation (requires Prefer: return=representation).' schema: - type: object - additionalProperties: - type: string + type: string + explode: false + - name: columns + in: query + required: false + description: Columns hint for bulk insert. + schema: + type: string + explode: false - name: Prefer in: header required: false @@ -162,15 +272,30 @@ paths: schema: {} put: operationId: TableOperations_upsert + description: UPSERT rows (PUT). parameters: - name: table in: path required: true schema: type: string - - name: params + - name: select + in: query + required: false + schema: + type: string + explode: false + - name: on_conflict in: query required: false + description: Comma-separated columns to use as the conflict target for upsert. + schema: + type: string + explode: false + - name: filters + in: query + required: false + description: Horizontal filters — each entry becomes a separate query parameter. schema: type: object additionalProperties: @@ -218,15 +343,23 @@ paths: schema: {} patch: operationId: TableOperations_update + description: UPDATE rows matching the filter. parameters: - name: table in: path required: true schema: type: string - - name: params + - name: select in: query required: false + schema: + type: string + explode: false + - name: filters + in: query + required: false + description: Horizontal filters — each entry becomes a separate query parameter. schema: type: object additionalProperties: @@ -274,15 +407,23 @@ paths: schema: {} delete: operationId: TableOperations_deleteRows + description: DELETE rows matching the filter. parameters: - name: table in: path required: true schema: type: string - - name: params + - name: select + in: query + required: false + schema: + type: string + explode: false + - name: filters in: query required: false + description: Horizontal filters — each entry becomes a separate query parameter. schema: type: object additionalProperties: @@ -325,6 +466,39 @@ paths: $ref: '#/components/schemas/PostgRESTError' components: schemas: + FilterOperator: + type: string + enum: + - eq + - neq + - lt + - lte + - gt + - gte + - like + - ilike + - match + - imatch + - is + - isdistinct + - in + - cs + - cd + - ov + - sl + - sr + - nxl + - nxr + - adj + - fts + - plfts + - phfts + - wfts + description: |- + PostgREST column filter operators. + Format a filter value as "{operator}.{value}", e.g. "eq.5". + Prefix with "not." to negate: "not.eq.5". + For logical grouping use keys "or" / "and" in the filters map. PostgRESTError: type: object properties: From 4f29a3bad20108c7b6de8488bc543b18a264ad61 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 08:46:11 -0300 Subject: [PATCH 28/32] spike(typespec): regenerate Storage and PostgREST Swift clients from fixed TypeSpec models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Storage: Objects_upload (POST) and Objects_update (PUT) now generated with native multipart/form-data bodies (cacheControl + file parts) — no patch script needed. Smithy required patch-openapi.py to inject these manually. PostgREST: select/order/limit(Int)/offset(Int) are separate typed query members; filters is a separate additionalProperties map; FilterOperator enum and RpcOperations_rpcGet are present. Storage line count: 1376→1646 Client + 3963→4443 Types (multipart added) All remaining gaps from initial comparison are now closed. --- .../Storage/GeneratedTypeSpec/Client.swift | 270 ++++++++++ Sources/Storage/GeneratedTypeSpec/Types.swift | 480 ++++++++++++++++++ .../openapi.Supabase.Storage.yaml | 90 ++++ 3 files changed, 840 insertions(+) diff --git a/Sources/Storage/GeneratedTypeSpec/Client.swift b/Sources/Storage/GeneratedTypeSpec/Client.swift index d4cd9c403..9a1a543e7 100644 --- a/Sources/Storage/GeneratedTypeSpec/Client.swift +++ b/Sources/Storage/GeneratedTypeSpec/Client.swift @@ -1087,6 +1087,276 @@ internal struct Client: APIProtocol { } ) } + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/post(Objects_upload)`. + internal func Objects_upload(_ input: Operations.Objects_upload.Input) async throws -> Operations.Objects_upload.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_upload.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}/{}", + parameters: [ + input.path.bucketId, + input.path.wildcardPath + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .post + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .multipartForm(value): + body = try converter.setRequiredRequestBodyAsMultipart( + value, + headerFields: &request.headerFields, + contentType: "multipart/form-data", + allowsUnknownParts: true, + requiredExactlyOncePartNames: [ + "file" + ], + requiredAtLeastOncePartNames: [], + atMostOncePartNames: [ + "cacheControl" + ], + zeroOrMoreTimesPartNames: [], + encoding: { part in + switch part { + case let .cacheControl(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "text/plain" + ) + return .init( + name: "cacheControl", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .file(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "application/octet-stream" + ) + return .init( + name: "file", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .undocumented(value): + return value + } + } + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_upload.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FileObject.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_upload.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/put(Objects_update)`. + internal func Objects_update(_ input: Operations.Objects_update.Input) async throws -> Operations.Objects_update.Output { + try await client.send( + input: input, + forOperation: Operations.Objects_update.id, + serializer: { input in + let path = try converter.renderedPath( + template: "/object/{}/{}", + parameters: [ + input.path.bucketId, + input.path.wildcardPath + ] + ) + var request: HTTPTypes.HTTPRequest = .init( + soar_path: path, + method: .put + ) + suppressMutabilityWarning(&request) + try converter.setHeaderFieldAsURI( + in: &request.headerFields, + name: "x-upsert", + value: input.headers.x_hyphen_upsert + ) + converter.setAcceptHeader( + in: &request.headerFields, + contentTypes: input.headers.accept + ) + let body: OpenAPIRuntime.HTTPBody? + switch input.body { + case let .multipartForm(value): + body = try converter.setRequiredRequestBodyAsMultipart( + value, + headerFields: &request.headerFields, + contentType: "multipart/form-data", + allowsUnknownParts: true, + requiredExactlyOncePartNames: [ + "file" + ], + requiredAtLeastOncePartNames: [], + atMostOncePartNames: [ + "cacheControl" + ], + zeroOrMoreTimesPartNames: [], + encoding: { part in + switch part { + case let .cacheControl(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "text/plain" + ) + return .init( + name: "cacheControl", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .file(wrapped): + var headerFields: HTTPTypes.HTTPFields = .init() + let value = wrapped.payload + let body = try converter.setRequiredRequestBodyAsBinary( + value.body, + headerFields: &headerFields, + contentType: "application/octet-stream" + ) + return .init( + name: "file", + filename: wrapped.filename, + headerFields: headerFields, + body: body + ) + case let .undocumented(value): + return value + } + } + ) + } + return (request, body) + }, + deserializer: { response, responseBody in + switch response.status.code { + case 200: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_update.Output.Ok.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.FileObject.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .ok(.init(body: body)) + default: + let contentType = converter.extractContentTypeIfPresent(in: response.headerFields) + let body: Operations.Objects_update.Output.Default.Body + let chosenContentType = try converter.bestContentType( + received: contentType, + options: [ + "application/json" + ] + ) + switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Components.Schemas.StorageError.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) + default: + preconditionFailure("bestContentType chose an invalid content type.") + } + return .`default`( + statusCode: response.status.code, + .init(body: body) + ) + } + } + ) + } /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. internal func Objects_head(_ input: Operations.Objects_head.Input) async throws -> Operations.Objects_head.Output { diff --git a/Sources/Storage/GeneratedTypeSpec/Types.swift b/Sources/Storage/GeneratedTypeSpec/Types.swift index 05d8abb54..e5f633f68 100644 --- a/Sources/Storage/GeneratedTypeSpec/Types.swift +++ b/Sources/Storage/GeneratedTypeSpec/Types.swift @@ -53,6 +53,12 @@ internal protocol APIProtocol: Sendable { /// - Remark: HTTP `DELETE /object/{bucketId}`. /// - Remark: Generated from `#/paths//object/{bucketId}/delete(Objects_deleteObjects)`. func Objects_deleteObjects(_ input: Operations.Objects_deleteObjects.Input) async throws -> Operations.Objects_deleteObjects.Output + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/post(Objects_upload)`. + func Objects_upload(_ input: Operations.Objects_upload.Input) async throws -> Operations.Objects_upload.Output + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/put(Objects_update)`. + func Objects_update(_ input: Operations.Objects_update.Input) async throws -> Operations.Objects_update.Output /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. func Objects_head(_ input: Operations.Objects_head.Input) async throws -> Operations.Objects_head.Output @@ -227,6 +233,32 @@ extension APIProtocol { body: body )) } + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/post(Objects_upload)`. + internal func Objects_upload( + path: Operations.Objects_upload.Input.Path, + headers: Operations.Objects_upload.Input.Headers = .init(), + body: Operations.Objects_upload.Input.Body + ) async throws -> Operations.Objects_upload.Output { + try await Objects_upload(Operations.Objects_upload.Input( + path: path, + headers: headers, + body: body + )) + } + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/put(Objects_update)`. + internal func Objects_update( + path: Operations.Objects_update.Input.Path, + headers: Operations.Objects_update.Input.Headers = .init(), + body: Operations.Objects_update.Input.Body + ) async throws -> Operations.Objects_update.Output { + try await Objects_update(Operations.Objects_update.Input( + path: path, + headers: headers, + body: body + )) + } /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. internal func Objects_head( @@ -3260,6 +3292,454 @@ internal enum Operations { } } } + /// - Remark: HTTP `POST /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/post(Objects_upload)`. + internal enum Objects_upload { + internal static let id: Swift.String = "Objects_upload" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/path/wildcardPath`. + internal var wildcardPath: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath: + internal init( + bucketId: Swift.String, + wildcardPath: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath = wildcardPath + } + } + internal var path: Operations.Objects_upload.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_upsert: + /// - accept: + internal init( + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.Objects_upload.Input.Headers + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/requestBody/multipartForm`. + internal enum multipartFormPayload: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/requestBody/multipartForm/cacheControl`. + internal struct cacheControlPayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `cacheControlPayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case cacheControl(OpenAPIRuntime.MultipartPart) + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/requestBody/multipartForm/file`. + internal struct filePayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `filePayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case file(OpenAPIRuntime.MultipartPart) + case undocumented(OpenAPIRuntime.MultipartRawPart) + } + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/requestBody/content/multipart\/form-data`. + case multipartForm(OpenAPIRuntime.MultipartBody) + } + internal var body: Operations.Objects_upload.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Objects_upload.Input.Path, + headers: Operations.Objects_upload.Input.Headers = .init(), + body: Operations.Objects_upload.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/responses/200/content/application\/json`. + case json(Components.Schemas.FileObject) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FileObject { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_upload.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_upload.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/post(Objects_upload)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_upload.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_upload.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/POST/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_upload.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_upload.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/post(Objects_upload)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_upload.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_upload.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } + /// - Remark: HTTP `PUT /object/{bucketId}/{wildcardPath}`. + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/put(Objects_update)`. + internal enum Objects_update { + internal static let id: Swift.String = "Objects_update" + internal struct Input: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/path`. + internal struct Path: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/path/bucketId`. + internal var bucketId: Swift.String + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/path/wildcardPath`. + internal var wildcardPath: Swift.String + /// Creates a new `Path`. + /// + /// - Parameters: + /// - bucketId: + /// - wildcardPath: + internal init( + bucketId: Swift.String, + wildcardPath: Swift.String + ) { + self.bucketId = bucketId + self.wildcardPath = wildcardPath + } + } + internal var path: Operations.Objects_update.Input.Path + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/header`. + internal struct Headers: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/header/x-upsert`. + internal var x_hyphen_upsert: Swift.String? + internal var accept: [OpenAPIRuntime.AcceptHeaderContentType] + /// Creates a new `Headers`. + /// + /// - Parameters: + /// - x_hyphen_upsert: + /// - accept: + internal init( + x_hyphen_upsert: Swift.String? = nil, + accept: [OpenAPIRuntime.AcceptHeaderContentType] = .defaultValues() + ) { + self.x_hyphen_upsert = x_hyphen_upsert + self.accept = accept + } + } + internal var headers: Operations.Objects_update.Input.Headers + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/requestBody`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/requestBody/multipartForm`. + internal enum multipartFormPayload: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/requestBody/multipartForm/cacheControl`. + internal struct cacheControlPayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `cacheControlPayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case cacheControl(OpenAPIRuntime.MultipartPart) + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/requestBody/multipartForm/file`. + internal struct filePayload: Sendable, Hashable { + internal var body: OpenAPIRuntime.HTTPBody + /// Creates a new `filePayload`. + /// + /// - Parameters: + /// - body: + internal init(body: OpenAPIRuntime.HTTPBody) { + self.body = body + } + } + case file(OpenAPIRuntime.MultipartPart) + case undocumented(OpenAPIRuntime.MultipartRawPart) + } + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/requestBody/content/multipart\/form-data`. + case multipartForm(OpenAPIRuntime.MultipartBody) + } + internal var body: Operations.Objects_update.Input.Body + /// Creates a new `Input`. + /// + /// - Parameters: + /// - path: + /// - headers: + /// - body: + internal init( + path: Operations.Objects_update.Input.Path, + headers: Operations.Objects_update.Input.Headers = .init(), + body: Operations.Objects_update.Input.Body + ) { + self.path = path + self.headers = headers + self.body = body + } + } + internal enum Output: Sendable, Hashable { + internal struct Ok: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/responses/200/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/responses/200/content/application\/json`. + case json(Components.Schemas.FileObject) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.FileObject { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_update.Output.Ok.Body + /// Creates a new `Ok`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_update.Output.Ok.Body) { + self.body = body + } + } + /// The request has succeeded. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/put(Objects_update)/responses/200`. + /// + /// HTTP response code: `200 ok`. + case ok(Operations.Objects_update.Output.Ok) + /// The associated value of the enum case if `self` is `.ok`. + /// + /// - Throws: An error if `self` is not `.ok`. + /// - SeeAlso: `.ok`. + internal var ok: Operations.Objects_update.Output.Ok { + get throws { + switch self { + case let .ok(response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "ok", + response: self + ) + } + } + } + internal struct Default: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/responses/default/content`. + internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/object/{bucketId}/{wildcardPath}/PUT/responses/default/content/application\/json`. + case json(Components.Schemas.StorageError) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Components.Schemas.StorageError { + get throws { + switch self { + case let .json(body): + return body + } + } + } + } + /// Received HTTP response body + internal var body: Operations.Objects_update.Output.Default.Body + /// Creates a new `Default`. + /// + /// - Parameters: + /// - body: Received HTTP response body + internal init(body: Operations.Objects_update.Output.Default.Body) { + self.body = body + } + } + /// An unexpected error response. + /// + /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/put(Objects_update)/responses/default`. + /// + /// HTTP response code: `default`. + case `default`(statusCode: Swift.Int, Operations.Objects_update.Output.Default) + /// The associated value of the enum case if `self` is `.`default``. + /// + /// - Throws: An error if `self` is not `.`default``. + /// - SeeAlso: `.`default``. + internal var `default`: Operations.Objects_update.Output.Default { + get throws { + switch self { + case let .`default`(_, response): + return response + default: + try throwUnexpectedResponseStatus( + expectedStatus: "default", + response: self + ) + } + } + } + } + internal enum AcceptableContentType: AcceptableProtocol { + case json + case other(Swift.String) + internal init?(rawValue: Swift.String) { + switch rawValue.lowercased() { + case "application/json": + self = .json + default: + self = .other(rawValue) + } + } + internal var rawValue: Swift.String { + switch self { + case let .other(string): + return string + case .json: + return "application/json" + } + } + internal static var allCases: [Self] { + [ + .json + ] + } + } + } /// - Remark: HTTP `HEAD /object/{bucketId}/{wildcardPath}`. /// - Remark: Generated from `#/paths//object/{bucketId}/{wildcardPath}/head(Objects_head)`. internal enum Objects_head { diff --git a/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml b/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml index 758d1f6b0..c2dd289ab 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.Storage.yaml @@ -375,6 +375,96 @@ paths: application/json: schema: $ref: '#/components/schemas/StorageError' + post: + operationId: Objects_upload + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + - name: wildcardPath + in: path + required: true + schema: + type: string + - name: x-upsert + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/FileObject' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + cacheControl: + type: string + file: + type: string + format: binary + required: + - file + put: + operationId: Objects_update + parameters: + - name: bucketId + in: path + required: true + schema: + type: string + - name: wildcardPath + in: path + required: true + schema: + type: string + - name: x-upsert + in: header + required: false + schema: + type: string + responses: + '200': + description: The request has succeeded. + content: + application/json: + schema: + $ref: '#/components/schemas/FileObject' + default: + description: An unexpected error response. + content: + application/json: + schema: + $ref: '#/components/schemas/StorageError' + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + cacheControl: + type: string + file: + type: string + format: binary + required: + - file /upload/resumable: post: operationId: TusUploads_create From ed14e505ee30a5986673acee22c03d2e9a1bd7e8 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 08:49:51 -0300 Subject: [PATCH 29/32] spike(typespec): regenerate PostgREST client with HTTPBody response/request bodies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follows supabase/sdk commit 3cd468b. Replaces OpenAPIValueContainer (any-JSON) with HTTPBody (streaming binary) on all response and request bodies — now identical to the Smithy-generated output in this respect. --- .../PostgREST/GeneratedTypeSpec/Client.swift | 94 +++++------ .../PostgREST/GeneratedTypeSpec/Types.swift | 156 +++++++++++------- .../openapi.Supabase.PostgREST.yaml | 66 +++++--- 3 files changed, 190 insertions(+), 126 deletions(-) diff --git a/Sources/PostgREST/GeneratedTypeSpec/Client.swift b/Sources/PostgREST/GeneratedTypeSpec/Client.swift index 4ba177d51..7f730a3fa 100644 --- a/Sources/PostgREST/GeneratedTypeSpec/Client.swift +++ b/Sources/PostgREST/GeneratedTypeSpec/Client.swift @@ -103,16 +103,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: @@ -199,11 +199,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .json(value): - body = try converter.setRequiredRequestBodyAsJSON( + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" + contentType: "application/octet-stream" ) } return (request, body) @@ -228,16 +228,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: @@ -377,16 +377,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: @@ -480,11 +480,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .json(value): - body = try converter.setRequiredRequestBodyAsJSON( + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" + contentType: "application/octet-stream" ) } return (request, body) @@ -509,16 +509,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: @@ -612,11 +612,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .json(value): - body = try converter.setRequiredRequestBodyAsJSON( + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" + contentType: "application/octet-stream" ) } return (request, body) @@ -641,16 +641,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: @@ -751,11 +751,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .json(value): - body = try converter.setRequiredRequestBodyAsJSON( + case let .binary(value): + body = try converter.setRequiredRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" + contentType: "application/octet-stream" ) } return (request, body) @@ -780,16 +780,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: @@ -903,16 +903,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json" + "application/octet-stream" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - OpenAPIRuntime.OpenAPIValueContainer.self, + case "application/octet-stream": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .json(value) + .binary(value) } ) default: diff --git a/Sources/PostgREST/GeneratedTypeSpec/Types.swift b/Sources/PostgREST/GeneratedTypeSpec/Types.swift index 11900961d..397a384b2 100644 --- a/Sources/PostgREST/GeneratedTypeSpec/Types.swift +++ b/Sources/PostgREST/GeneratedTypeSpec/Types.swift @@ -421,16 +421,16 @@ internal enum Operations { internal var headers: Operations.RpcOperations_rpcGet.Output.Ok.Headers /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/rpc/{functionName}/GET/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -527,10 +527,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -541,12 +544,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } @@ -616,8 +622,8 @@ internal enum Operations { internal var headers: Operations.RpcOperations_rpc.Input.Headers /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) } internal var body: Operations.RpcOperations_rpc.Input.Body /// Creates a new `Input`. @@ -664,16 +670,16 @@ internal enum Operations { internal var headers: Operations.RpcOperations_rpc.Output.Ok.Headers /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -770,10 +776,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -784,12 +793,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } @@ -957,16 +969,16 @@ internal enum Operations { internal var headers: Operations.TableOperations_from.Output.Ok.Headers /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/{table}/GET/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -1063,10 +1075,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -1077,12 +1092,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } @@ -1163,8 +1181,8 @@ internal enum Operations { internal var headers: Operations.TableOperations_insert.Input.Headers /// - Remark: Generated from `#/paths/{table}/POST/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/POST/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) + /// - Remark: Generated from `#/paths/{table}/POST/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) } internal var body: Operations.TableOperations_insert.Input.Body /// Creates a new `Input`. @@ -1211,16 +1229,16 @@ internal enum Operations { internal var headers: Operations.TableOperations_insert.Output.Created.Headers /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/{table}/POST/responses/201/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -1317,10 +1335,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -1331,12 +1352,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } @@ -1433,8 +1457,8 @@ internal enum Operations { internal var headers: Operations.TableOperations_update.Input.Headers /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) + /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) } internal var body: Operations.TableOperations_update.Input.Body /// Creates a new `Input`. @@ -1481,16 +1505,16 @@ internal enum Operations { internal var headers: Operations.TableOperations_update.Output.Ok.Headers /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/{table}/PATCH/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -1587,10 +1611,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -1601,12 +1628,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } @@ -1710,8 +1740,8 @@ internal enum Operations { internal var headers: Operations.TableOperations_upsert.Input.Headers /// - Remark: Generated from `#/paths/{table}/PUT/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PUT/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) + /// - Remark: Generated from `#/paths/{table}/PUT/requestBody/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) } internal var body: Operations.TableOperations_upsert.Input.Body /// Creates a new `Input`. @@ -1758,16 +1788,16 @@ internal enum Operations { internal var headers: Operations.TableOperations_upsert.Output.Ok.Headers /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/{table}/PUT/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -1864,10 +1894,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -1878,12 +1911,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } @@ -2019,16 +2055,16 @@ internal enum Operations { internal var headers: Operations.TableOperations_deleteRows.Output.Ok.Headers /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/{table}/DELETE/responses/200/content/application\/octet-stream`. + case binary(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.binary`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: OpenAPIRuntime.OpenAPIValueContainer { + /// - Throws: An error if `self` is not `.binary`. + /// - SeeAlso: `.binary`. + internal var binary: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .binary(body): return body } } @@ -2125,10 +2161,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case binary case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "application/octet-stream": + self = .binary case "application/json": self = .json default: @@ -2139,12 +2178,15 @@ internal enum Operations { switch self { case let .other(string): return string + case .binary: + return "application/octet-stream" case .json: return "application/json" } } internal static var allCases: [Self] { [ + .binary, .json ] } diff --git a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml index 174db24fb..78cb09acf 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml @@ -48,8 +48,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: @@ -59,8 +61,10 @@ paths: requestBody: required: true content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary get: operationId: RpcOperations_rpcGet description: |- @@ -104,8 +108,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: @@ -198,8 +204,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: @@ -257,8 +265,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: @@ -268,8 +278,10 @@ paths: requestBody: required: true content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary put: operationId: TableOperations_upsert description: UPSERT rows (PUT). @@ -328,8 +340,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: @@ -339,8 +353,10 @@ paths: requestBody: required: true content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary patch: operationId: TableOperations_update description: UPDATE rows matching the filter. @@ -392,8 +408,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: @@ -403,8 +421,10 @@ paths: requestBody: required: true content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary delete: operationId: TableOperations_deleteRows description: DELETE rows matching the filter. @@ -456,8 +476,10 @@ paths: schema: type: string content: - application/json: - schema: {} + application/octet-stream: + schema: + type: string + format: binary default: description: An unexpected error response. content: From 7c171a89316b43d4adaed188af4320aa15981969 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 08:58:29 -0300 Subject: [PATCH 30/32] spike(typespec): regenerate Functions and PostgREST clients with corrected body types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Functions invoke Body enum now has four cases: .json(OpenAPIValueContainer) — application/json .binary(HTTPBody) — application/octet-stream .plainText(HTTPBody) — text/plain .urlEncodedForm(String) — application/x-www-form-urlencoded PostgREST request body reverted to .json(OpenAPIValueContainer) since PostgREST accepts JSON row arrays/objects; response body stays .binary(HTTPBody) so the SDK layer decodes into the caller's Decodable type. --- .../Functions/GeneratedTypeSpec/Client.swift | 72 +++++++++++++++++++ .../Functions/GeneratedTypeSpec/Types.swift | 24 +++++++ .../PostgREST/GeneratedTypeSpec/Client.swift | 24 +++---- .../PostgREST/GeneratedTypeSpec/Types.swift | 16 ++--- .../openapi.Supabase.Functions.yaml | 32 +++++++++ .../openapi.Supabase.PostgREST.yaml | 24 +++---- 6 files changed, 156 insertions(+), 36 deletions(-) diff --git a/Sources/Functions/GeneratedTypeSpec/Client.swift b/Sources/Functions/GeneratedTypeSpec/Client.swift index bd985f607..07aab6d82 100644 --- a/Sources/Functions/GeneratedTypeSpec/Client.swift +++ b/Sources/Functions/GeneratedTypeSpec/Client.swift @@ -150,12 +150,30 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil + case let .json(value): + body = try converter.setOptionalRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) case let .binary(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, contentType: "application/octet-stream" ) + case let .plainText(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + case let .urlEncodedForm(value): + body = try converter.setOptionalRequestBodyAsURLEncodedForm( + value, + headerFields: &request.headerFields, + contentType: "application/x-www-form-urlencoded" + ) } return (request, body) }, @@ -243,12 +261,30 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil + case let .json(value): + body = try converter.setOptionalRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) case let .binary(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, contentType: "application/octet-stream" ) + case let .plainText(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + case let .urlEncodedForm(value): + body = try converter.setOptionalRequestBodyAsURLEncodedForm( + value, + headerFields: &request.headerFields, + contentType: "application/x-www-form-urlencoded" + ) } return (request, body) }, @@ -336,12 +372,30 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil + case let .json(value): + body = try converter.setOptionalRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) case let .binary(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, contentType: "application/octet-stream" ) + case let .plainText(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + case let .urlEncodedForm(value): + body = try converter.setOptionalRequestBodyAsURLEncodedForm( + value, + headerFields: &request.headerFields, + contentType: "application/x-www-form-urlencoded" + ) } return (request, body) }, @@ -429,12 +483,30 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil + case let .json(value): + body = try converter.setOptionalRequestBodyAsJSON( + value, + headerFields: &request.headerFields, + contentType: "application/json; charset=utf-8" + ) case let .binary(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, contentType: "application/octet-stream" ) + case let .plainText(value): + body = try converter.setOptionalRequestBodyAsBinary( + value, + headerFields: &request.headerFields, + contentType: "text/plain" + ) + case let .urlEncodedForm(value): + body = try converter.setOptionalRequestBodyAsURLEncodedForm( + value, + headerFields: &request.headerFields, + contentType: "application/x-www-form-urlencoded" + ) } return (request, body) }, diff --git a/Sources/Functions/GeneratedTypeSpec/Types.swift b/Sources/Functions/GeneratedTypeSpec/Types.swift index fc91bcd9e..b236bbf95 100644 --- a/Sources/Functions/GeneratedTypeSpec/Types.swift +++ b/Sources/Functions/GeneratedTypeSpec/Types.swift @@ -390,8 +390,14 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokePost.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/x-www-form-urlencoded`. + case urlEncodedForm(Swift.String) } internal var body: Operations.FunctionInvocations_invokePost.Input.Body? /// Creates a new `Input`. @@ -585,8 +591,14 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokePatch.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/x-www-form-urlencoded`. + case urlEncodedForm(Swift.String) } internal var body: Operations.FunctionInvocations_invokePatch.Input.Body? /// Creates a new `Input`. @@ -780,8 +792,14 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokePut.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/x-www-form-urlencoded`. + case urlEncodedForm(Swift.String) } internal var body: Operations.FunctionInvocations_invokePut.Input.Body? /// Creates a new `Input`. @@ -975,8 +993,14 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokeDelete.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/x-www-form-urlencoded`. + case urlEncodedForm(Swift.String) } internal var body: Operations.FunctionInvocations_invokeDelete.Input.Body? /// Creates a new `Input`. diff --git a/Sources/PostgREST/GeneratedTypeSpec/Client.swift b/Sources/PostgREST/GeneratedTypeSpec/Client.swift index 7f730a3fa..ee63fc2a0 100644 --- a/Sources/PostgREST/GeneratedTypeSpec/Client.swift +++ b/Sources/PostgREST/GeneratedTypeSpec/Client.swift @@ -199,11 +199,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .binary(value): - body = try converter.setRequiredRequestBodyAsBinary( + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( value, headerFields: &request.headerFields, - contentType: "application/octet-stream" + contentType: "application/json; charset=utf-8" ) } return (request, body) @@ -480,11 +480,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .binary(value): - body = try converter.setRequiredRequestBodyAsBinary( + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( value, headerFields: &request.headerFields, - contentType: "application/octet-stream" + contentType: "application/json; charset=utf-8" ) } return (request, body) @@ -612,11 +612,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .binary(value): - body = try converter.setRequiredRequestBodyAsBinary( + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( value, headerFields: &request.headerFields, - contentType: "application/octet-stream" + contentType: "application/json; charset=utf-8" ) } return (request, body) @@ -751,11 +751,11 @@ internal struct Client: APIProtocol { ) let body: OpenAPIRuntime.HTTPBody? switch input.body { - case let .binary(value): - body = try converter.setRequiredRequestBodyAsBinary( + case let .json(value): + body = try converter.setRequiredRequestBodyAsJSON( value, headerFields: &request.headerFields, - contentType: "application/octet-stream" + contentType: "application/json; charset=utf-8" ) } return (request, body) diff --git a/Sources/PostgREST/GeneratedTypeSpec/Types.swift b/Sources/PostgREST/GeneratedTypeSpec/Types.swift index 397a384b2..f772608a7 100644 --- a/Sources/PostgREST/GeneratedTypeSpec/Types.swift +++ b/Sources/PostgREST/GeneratedTypeSpec/Types.swift @@ -622,8 +622,8 @@ internal enum Operations { internal var headers: Operations.RpcOperations_rpc.Input.Headers /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/rpc/{functionName}/POST/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) } internal var body: Operations.RpcOperations_rpc.Input.Body /// Creates a new `Input`. @@ -1181,8 +1181,8 @@ internal enum Operations { internal var headers: Operations.TableOperations_insert.Input.Headers /// - Remark: Generated from `#/paths/{table}/POST/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/POST/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/{table}/POST/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) } internal var body: Operations.TableOperations_insert.Input.Body /// Creates a new `Input`. @@ -1457,8 +1457,8 @@ internal enum Operations { internal var headers: Operations.TableOperations_update.Input.Headers /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/{table}/PATCH/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) } internal var body: Operations.TableOperations_update.Input.Body /// Creates a new `Input`. @@ -1740,8 +1740,8 @@ internal enum Operations { internal var headers: Operations.TableOperations_upsert.Input.Headers /// - Remark: Generated from `#/paths/{table}/PUT/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/{table}/PUT/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) + /// - Remark: Generated from `#/paths/{table}/PUT/requestBody/content/application\/json`. + case json(OpenAPIRuntime.OpenAPIValueContainer) } internal var body: Operations.TableOperations_upsert.Input.Body /// Creates a new `Input`. diff --git a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml index 5cb17ff73..7ab7f27ef 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml @@ -62,10 +62,18 @@ paths: requestBody: required: false content: + application/json: + schema: {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string + application/x-www-form-urlencoded: + schema: + type: string put: operationId: FunctionInvocations_invokePut parameters: @@ -96,10 +104,18 @@ paths: requestBody: required: false content: + application/json: + schema: {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string + application/x-www-form-urlencoded: + schema: + type: string patch: operationId: FunctionInvocations_invokePatch parameters: @@ -130,10 +146,18 @@ paths: requestBody: required: false content: + application/json: + schema: {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string + application/x-www-form-urlencoded: + schema: + type: string delete: operationId: FunctionInvocations_invokeDelete parameters: @@ -164,10 +188,18 @@ paths: requestBody: required: false content: + application/json: + schema: {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string + application/x-www-form-urlencoded: + schema: + type: string components: schemas: FunctionsError: diff --git a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml index 78cb09acf..ab0bf341f 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.PostgREST.yaml @@ -61,10 +61,8 @@ paths: requestBody: required: true content: - application/octet-stream: - schema: - type: string - format: binary + application/json: + schema: {} get: operationId: RpcOperations_rpcGet description: |- @@ -278,10 +276,8 @@ paths: requestBody: required: true content: - application/octet-stream: - schema: - type: string - format: binary + application/json: + schema: {} put: operationId: TableOperations_upsert description: UPSERT rows (PUT). @@ -353,10 +349,8 @@ paths: requestBody: required: true content: - application/octet-stream: - schema: - type: string - format: binary + application/json: + schema: {} patch: operationId: TableOperations_update description: UPDATE rows matching the filter. @@ -421,10 +415,8 @@ paths: requestBody: required: true content: - application/octet-stream: - schema: - type: string - format: binary + application/json: + schema: {} delete: operationId: TableOperations_deleteRows description: DELETE rows matching the filter. From 16406b498f24732b7e315d8343d1c6aabcf5ea02 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 13:52:37 -0300 Subject: [PATCH 31/32] spike(typespec): regenerate Functions client with multi-type response body MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Response Body enum now has three cases matching the response content-type: .json(OpenAPIValueContainer) — application/json .binary(HTTPBody) — application/octet-stream .plainText(HTTPBody) — text/plain Request Body enum unchanged (json/binary/plainText/urlEncodedForm). --- .../Functions/GeneratedTypeSpec/Client.swift | 80 +++- .../Functions/GeneratedTypeSpec/Types.swift | 424 +++++++++++++++++- .../openapi.Supabase.Functions.yaml | 32 ++ 3 files changed, 508 insertions(+), 28 deletions(-) diff --git a/Sources/Functions/GeneratedTypeSpec/Client.swift b/Sources/Functions/GeneratedTypeSpec/Client.swift index 07aab6d82..25f5c3663 100644 --- a/Sources/Functions/GeneratedTypeSpec/Client.swift +++ b/Sources/Functions/GeneratedTypeSpec/Client.swift @@ -185,10 +185,20 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/octet-stream" + "application/json", + "application/octet-stream", + "text/plain" ] ) switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Operations.FunctionInvocations_invokePost.Output.Ok.Body.jsonPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) case "application/octet-stream": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, @@ -197,6 +207,14 @@ internal struct Client: APIProtocol { .binary(value) } ) + case "text/plain": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .plainText(value) + } + ) default: preconditionFailure("bestContentType chose an invalid content type.") } @@ -296,10 +314,20 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/octet-stream" + "application/json", + "application/octet-stream", + "text/plain" ] ) switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Operations.FunctionInvocations_invokePatch.Output.Ok.Body.jsonPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) case "application/octet-stream": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, @@ -308,6 +336,14 @@ internal struct Client: APIProtocol { .binary(value) } ) + case "text/plain": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .plainText(value) + } + ) default: preconditionFailure("bestContentType chose an invalid content type.") } @@ -407,10 +443,20 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/octet-stream" + "application/json", + "application/octet-stream", + "text/plain" ] ) switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Operations.FunctionInvocations_invokePut.Output.Ok.Body.jsonPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) case "application/octet-stream": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, @@ -419,6 +465,14 @@ internal struct Client: APIProtocol { .binary(value) } ) + case "text/plain": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .plainText(value) + } + ) default: preconditionFailure("bestContentType chose an invalid content type.") } @@ -518,10 +572,20 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/octet-stream" + "application/json", + "application/octet-stream", + "text/plain" ] ) switch chosenContentType { + case "application/json": + body = try await converter.getResponseBodyAsJSON( + Operations.FunctionInvocations_invokeDelete.Output.Ok.Body.jsonPayload.self, + from: responseBody, + transforming: { value in + .json(value) + } + ) case "application/octet-stream": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, @@ -530,6 +594,14 @@ internal struct Client: APIProtocol { .binary(value) } ) + case "text/plain": + body = try converter.getResponseBodyAsBinary( + OpenAPIRuntime.HTTPBody.self, + from: responseBody, + transforming: { value in + .plainText(value) + } + ) default: preconditionFailure("bestContentType chose an invalid content type.") } diff --git a/Sources/Functions/GeneratedTypeSpec/Types.swift b/Sources/Functions/GeneratedTypeSpec/Types.swift index b236bbf95..74c08c1e1 100644 --- a/Sources/Functions/GeneratedTypeSpec/Types.swift +++ b/Sources/Functions/GeneratedTypeSpec/Types.swift @@ -420,6 +420,70 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/json`. + internal struct jsonPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/json/value1`. + internal var value1: OpenAPIRuntime.OpenAPIValueContainer? + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/json/value2`. + internal var value2: OpenAPIRuntime.OpenAPIValueContainer? + /// Creates a new `jsonPayload`. + /// + /// - Parameters: + /// - value1: + /// - value2: + internal init( + value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, + value2: OpenAPIRuntime.OpenAPIValueContainer? = nil + ) { + self.value1 = value1 + self.value2 = value2 + } + internal init(from decoder: any Swift.Decoder) throws { + var errors: [any Swift.Error] = [] + do { + self.value1 = try .init(from: decoder) + } catch { + errors.append(error) + } + do { + self.value2 = try .init(from: decoder) + } catch { + errors.append(error) + } + try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( + [ + self.value1, + self.value2 + ], + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try self.value1?.encode(to: encoder) + try self.value2?.encode(to: encoder) + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/json`. + case json(Operations.FunctionInvocations_invokePost.Output.Ok.Body.jsonPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Operations.FunctionInvocations_invokePost.Output.Ok.Body.jsonPayload { + get throws { + switch self { + case let .json(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } + } + } /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.binary`. @@ -431,6 +495,30 @@ internal enum Operations { switch self { case let .binary(body): return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/octet-stream", + body: self + ) + } + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.plainText`. + /// + /// - Throws: An error if `self` is not `.plainText`. + /// - SeeAlso: `.plainText`. + internal var plainText: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .plainText(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/plain", + body: self + ) } } } @@ -521,15 +609,18 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { - case binary case json + case binary + case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/octet-stream": - self = .binary case "application/json": self = .json + case "application/octet-stream": + self = .binary + case "text/plain": + self = .plainText default: self = .other(rawValue) } @@ -538,16 +629,19 @@ internal enum Operations { switch self { case let .other(string): return string - case .binary: - return "application/octet-stream" case .json: return "application/json" + case .binary: + return "application/octet-stream" + case .plainText: + return "text/plain" } } internal static var allCases: [Self] { [ + .json, .binary, - .json + .plainText ] } } @@ -621,6 +715,70 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/json`. + internal struct jsonPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/json/value1`. + internal var value1: OpenAPIRuntime.OpenAPIValueContainer? + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/json/value2`. + internal var value2: OpenAPIRuntime.OpenAPIValueContainer? + /// Creates a new `jsonPayload`. + /// + /// - Parameters: + /// - value1: + /// - value2: + internal init( + value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, + value2: OpenAPIRuntime.OpenAPIValueContainer? = nil + ) { + self.value1 = value1 + self.value2 = value2 + } + internal init(from decoder: any Swift.Decoder) throws { + var errors: [any Swift.Error] = [] + do { + self.value1 = try .init(from: decoder) + } catch { + errors.append(error) + } + do { + self.value2 = try .init(from: decoder) + } catch { + errors.append(error) + } + try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( + [ + self.value1, + self.value2 + ], + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try self.value1?.encode(to: encoder) + try self.value2?.encode(to: encoder) + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/application\/json`. + case json(Operations.FunctionInvocations_invokePatch.Output.Ok.Body.jsonPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Operations.FunctionInvocations_invokePatch.Output.Ok.Body.jsonPayload { + get throws { + switch self { + case let .json(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } + } + } /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.binary`. @@ -632,6 +790,30 @@ internal enum Operations { switch self { case let .binary(body): return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/octet-stream", + body: self + ) + } + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.plainText`. + /// + /// - Throws: An error if `self` is not `.plainText`. + /// - SeeAlso: `.plainText`. + internal var plainText: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .plainText(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/plain", + body: self + ) } } } @@ -722,15 +904,18 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { - case binary case json + case binary + case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/octet-stream": - self = .binary case "application/json": self = .json + case "application/octet-stream": + self = .binary + case "text/plain": + self = .plainText default: self = .other(rawValue) } @@ -739,16 +924,19 @@ internal enum Operations { switch self { case let .other(string): return string - case .binary: - return "application/octet-stream" case .json: return "application/json" + case .binary: + return "application/octet-stream" + case .plainText: + return "text/plain" } } internal static var allCases: [Self] { [ + .json, .binary, - .json + .plainText ] } } @@ -822,6 +1010,70 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/json`. + internal struct jsonPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/json/value1`. + internal var value1: OpenAPIRuntime.OpenAPIValueContainer? + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/json/value2`. + internal var value2: OpenAPIRuntime.OpenAPIValueContainer? + /// Creates a new `jsonPayload`. + /// + /// - Parameters: + /// - value1: + /// - value2: + internal init( + value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, + value2: OpenAPIRuntime.OpenAPIValueContainer? = nil + ) { + self.value1 = value1 + self.value2 = value2 + } + internal init(from decoder: any Swift.Decoder) throws { + var errors: [any Swift.Error] = [] + do { + self.value1 = try .init(from: decoder) + } catch { + errors.append(error) + } + do { + self.value2 = try .init(from: decoder) + } catch { + errors.append(error) + } + try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( + [ + self.value1, + self.value2 + ], + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try self.value1?.encode(to: encoder) + try self.value2?.encode(to: encoder) + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/application\/json`. + case json(Operations.FunctionInvocations_invokePut.Output.Ok.Body.jsonPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Operations.FunctionInvocations_invokePut.Output.Ok.Body.jsonPayload { + get throws { + switch self { + case let .json(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } + } + } /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.binary`. @@ -833,6 +1085,30 @@ internal enum Operations { switch self { case let .binary(body): return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/octet-stream", + body: self + ) + } + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.plainText`. + /// + /// - Throws: An error if `self` is not `.plainText`. + /// - SeeAlso: `.plainText`. + internal var plainText: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .plainText(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/plain", + body: self + ) } } } @@ -923,15 +1199,18 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { - case binary case json + case binary + case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/octet-stream": - self = .binary case "application/json": self = .json + case "application/octet-stream": + self = .binary + case "text/plain": + self = .plainText default: self = .other(rawValue) } @@ -940,16 +1219,19 @@ internal enum Operations { switch self { case let .other(string): return string - case .binary: - return "application/octet-stream" case .json: return "application/json" + case .binary: + return "application/octet-stream" + case .plainText: + return "text/plain" } } internal static var allCases: [Self] { [ + .json, .binary, - .json + .plainText ] } } @@ -1023,6 +1305,70 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content`. internal enum Body: Sendable, Hashable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/json`. + internal struct jsonPayload: Codable, Hashable, Sendable { + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/json/value1`. + internal var value1: OpenAPIRuntime.OpenAPIValueContainer? + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/json/value2`. + internal var value2: OpenAPIRuntime.OpenAPIValueContainer? + /// Creates a new `jsonPayload`. + /// + /// - Parameters: + /// - value1: + /// - value2: + internal init( + value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, + value2: OpenAPIRuntime.OpenAPIValueContainer? = nil + ) { + self.value1 = value1 + self.value2 = value2 + } + internal init(from decoder: any Swift.Decoder) throws { + var errors: [any Swift.Error] = [] + do { + self.value1 = try .init(from: decoder) + } catch { + errors.append(error) + } + do { + self.value2 = try .init(from: decoder) + } catch { + errors.append(error) + } + try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( + [ + self.value1, + self.value2 + ], + type: Self.self, + codingPath: decoder.codingPath, + errors: errors + ) + } + internal func encode(to encoder: any Swift.Encoder) throws { + try self.value1?.encode(to: encoder) + try self.value2?.encode(to: encoder) + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/application\/json`. + case json(Operations.FunctionInvocations_invokeDelete.Output.Ok.Body.jsonPayload) + /// The associated value of the enum case if `self` is `.json`. + /// + /// - Throws: An error if `self` is not `.json`. + /// - SeeAlso: `.json`. + internal var json: Operations.FunctionInvocations_invokeDelete.Output.Ok.Body.jsonPayload { + get throws { + switch self { + case let .json(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/json", + body: self + ) + } + } + } /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/application\/octet-stream`. case binary(OpenAPIRuntime.HTTPBody) /// The associated value of the enum case if `self` is `.binary`. @@ -1034,6 +1380,30 @@ internal enum Operations { switch self { case let .binary(body): return body + default: + try throwUnexpectedResponseBody( + expectedContent: "application/octet-stream", + body: self + ) + } + } + } + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/text\/plain`. + case plainText(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.plainText`. + /// + /// - Throws: An error if `self` is not `.plainText`. + /// - SeeAlso: `.plainText`. + internal var plainText: OpenAPIRuntime.HTTPBody { + get throws { + switch self { + case let .plainText(body): + return body + default: + try throwUnexpectedResponseBody( + expectedContent: "text/plain", + body: self + ) } } } @@ -1124,15 +1494,18 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { - case binary case json + case binary + case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/octet-stream": - self = .binary case "application/json": self = .json + case "application/octet-stream": + self = .binary + case "text/plain": + self = .plainText default: self = .other(rawValue) } @@ -1141,16 +1514,19 @@ internal enum Operations { switch self { case let .other(string): return string - case .binary: - return "application/octet-stream" case .json: return "application/json" + case .binary: + return "application/octet-stream" + case .plainText: + return "text/plain" } } internal static var allCases: [Self] { [ + .json, .binary, - .json + .plainText ] } } diff --git a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml index 7ab7f27ef..b13f27b14 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml @@ -49,10 +49,18 @@ paths: '200': description: The request has succeeded. content: + application/json: + schema: + anyOf: + - {} + - {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string default: description: An unexpected error response. content: @@ -91,10 +99,18 @@ paths: '200': description: The request has succeeded. content: + application/json: + schema: + anyOf: + - {} + - {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string default: description: An unexpected error response. content: @@ -133,10 +149,18 @@ paths: '200': description: The request has succeeded. content: + application/json: + schema: + anyOf: + - {} + - {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string default: description: An unexpected error response. content: @@ -175,10 +199,18 @@ paths: '200': description: The request has succeeded. content: + application/json: + schema: + anyOf: + - {} + - {} application/octet-stream: schema: type: string format: binary + text/plain: + schema: + type: string default: description: An unexpected error response. content: From e29d81486846066cab6cf748ce8286b3fe27e12b Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Wed, 1 Jul 2026 14:02:57 -0300 Subject: [PATCH 32/32] spike(typespec): regenerate Functions client with generic HTTPBody (*/* content type) Replace the @sharedRoute multi-variant approach with a single operation per HTTP method. Both request body and response body are now HTTPBody (case any), generic enough for any content type: JSON, binary, text, event-stream, etc. --- .../Functions/GeneratedTypeSpec/Client.swift | 190 +----- .../Functions/GeneratedTypeSpec/Types.swift | 554 +++--------------- .../openapi.Supabase.Functions.yaml | 82 +-- 3 files changed, 109 insertions(+), 717 deletions(-) diff --git a/Sources/Functions/GeneratedTypeSpec/Client.swift b/Sources/Functions/GeneratedTypeSpec/Client.swift index 25f5c3663..915bca8a8 100644 --- a/Sources/Functions/GeneratedTypeSpec/Client.swift +++ b/Sources/Functions/GeneratedTypeSpec/Client.swift @@ -74,16 +74,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/octet-stream" + "*/*" ] ) switch chosenContentType { - case "application/octet-stream": + case "*/*": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .binary(value) + .any(value) } ) default: @@ -150,29 +150,11 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil - case let .json(value): - body = try converter.setOptionalRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - case let .binary(value): - body = try converter.setOptionalRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - case let .plainText(value): + case let .any(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "text/plain" - ) - case let .urlEncodedForm(value): - body = try converter.setOptionalRequestBodyAsURLEncodedForm( - value, - headerFields: &request.headerFields, - contentType: "application/x-www-form-urlencoded" + contentType: "*/*" ) } return (request, body) @@ -185,34 +167,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json", - "application/octet-stream", - "text/plain" + "*/*" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Operations.FunctionInvocations_invokePost.Output.Ok.Body.jsonPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - case "application/octet-stream": - body = try converter.getResponseBodyAsBinary( - OpenAPIRuntime.HTTPBody.self, - from: responseBody, - transforming: { value in - .binary(value) - } - ) - case "text/plain": + case "*/*": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .plainText(value) + .any(value) } ) default: @@ -279,29 +243,11 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil - case let .json(value): - body = try converter.setOptionalRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - case let .binary(value): - body = try converter.setOptionalRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - case let .plainText(value): + case let .any(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "text/plain" - ) - case let .urlEncodedForm(value): - body = try converter.setOptionalRequestBodyAsURLEncodedForm( - value, - headerFields: &request.headerFields, - contentType: "application/x-www-form-urlencoded" + contentType: "*/*" ) } return (request, body) @@ -314,34 +260,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json", - "application/octet-stream", - "text/plain" + "*/*" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Operations.FunctionInvocations_invokePatch.Output.Ok.Body.jsonPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - case "application/octet-stream": - body = try converter.getResponseBodyAsBinary( - OpenAPIRuntime.HTTPBody.self, - from: responseBody, - transforming: { value in - .binary(value) - } - ) - case "text/plain": + case "*/*": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .plainText(value) + .any(value) } ) default: @@ -408,29 +336,11 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil - case let .json(value): - body = try converter.setOptionalRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - case let .binary(value): - body = try converter.setOptionalRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - case let .plainText(value): + case let .any(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "text/plain" - ) - case let .urlEncodedForm(value): - body = try converter.setOptionalRequestBodyAsURLEncodedForm( - value, - headerFields: &request.headerFields, - contentType: "application/x-www-form-urlencoded" + contentType: "*/*" ) } return (request, body) @@ -443,34 +353,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json", - "application/octet-stream", - "text/plain" + "*/*" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Operations.FunctionInvocations_invokePut.Output.Ok.Body.jsonPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - case "application/octet-stream": - body = try converter.getResponseBodyAsBinary( - OpenAPIRuntime.HTTPBody.self, - from: responseBody, - transforming: { value in - .binary(value) - } - ) - case "text/plain": + case "*/*": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .plainText(value) + .any(value) } ) default: @@ -537,29 +429,11 @@ internal struct Client: APIProtocol { switch input.body { case .none: body = nil - case let .json(value): - body = try converter.setOptionalRequestBodyAsJSON( - value, - headerFields: &request.headerFields, - contentType: "application/json; charset=utf-8" - ) - case let .binary(value): - body = try converter.setOptionalRequestBodyAsBinary( - value, - headerFields: &request.headerFields, - contentType: "application/octet-stream" - ) - case let .plainText(value): + case let .any(value): body = try converter.setOptionalRequestBodyAsBinary( value, headerFields: &request.headerFields, - contentType: "text/plain" - ) - case let .urlEncodedForm(value): - body = try converter.setOptionalRequestBodyAsURLEncodedForm( - value, - headerFields: &request.headerFields, - contentType: "application/x-www-form-urlencoded" + contentType: "*/*" ) } return (request, body) @@ -572,34 +446,16 @@ internal struct Client: APIProtocol { let chosenContentType = try converter.bestContentType( received: contentType, options: [ - "application/json", - "application/octet-stream", - "text/plain" + "*/*" ] ) switch chosenContentType { - case "application/json": - body = try await converter.getResponseBodyAsJSON( - Operations.FunctionInvocations_invokeDelete.Output.Ok.Body.jsonPayload.self, - from: responseBody, - transforming: { value in - .json(value) - } - ) - case "application/octet-stream": - body = try converter.getResponseBodyAsBinary( - OpenAPIRuntime.HTTPBody.self, - from: responseBody, - transforming: { value in - .binary(value) - } - ) - case "text/plain": + case "*/*": body = try converter.getResponseBodyAsBinary( OpenAPIRuntime.HTTPBody.self, from: responseBody, transforming: { value in - .plainText(value) + .any(value) } ) default: diff --git a/Sources/Functions/GeneratedTypeSpec/Types.swift b/Sources/Functions/GeneratedTypeSpec/Types.swift index 74c08c1e1..0e97df4b9 100644 --- a/Sources/Functions/GeneratedTypeSpec/Types.swift +++ b/Sources/Functions/GeneratedTypeSpec/Types.swift @@ -219,16 +219,16 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/200/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.binary`. + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/GET/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. /// - /// - Throws: An error if `self` is not `.binary`. - /// - SeeAlso: `.binary`. - internal var binary: OpenAPIRuntime.HTTPBody { + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + internal var any: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .binary(body): + case let .any(body): return body } } @@ -320,13 +320,13 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { - case binary + case any case json case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { - case "application/octet-stream": - self = .binary + case "*/*": + self = .any case "application/json": self = .json default: @@ -337,15 +337,15 @@ internal enum Operations { switch self { case let .other(string): return string - case .binary: - return "application/octet-stream" + case .any: + return "*/*" case .json: return "application/json" } } internal static var allCases: [Self] { [ - .binary, + .any, .json ] } @@ -390,14 +390,8 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokePost.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/application\/x-www-form-urlencoded`. - case urlEncodedForm(Swift.String) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/requestBody/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) } internal var body: Operations.FunctionInvocations_invokePost.Input.Body? /// Creates a new `Input`. @@ -420,105 +414,17 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/json`. - internal struct jsonPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/json/value1`. - internal var value1: OpenAPIRuntime.OpenAPIValueContainer? - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/json/value2`. - internal var value2: OpenAPIRuntime.OpenAPIValueContainer? - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - value1: - /// - value2: - internal init( - value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, - value2: OpenAPIRuntime.OpenAPIValueContainer? = nil - ) { - self.value1 = value1 - self.value2 = value2 - } - internal init(from decoder: any Swift.Decoder) throws { - var errors: [any Swift.Error] = [] - do { - self.value1 = try .init(from: decoder) - } catch { - errors.append(error) - } - do { - self.value2 = try .init(from: decoder) - } catch { - errors.append(error) - } - try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( - [ - self.value1, - self.value2 - ], - type: Self.self, - codingPath: decoder.codingPath, - errors: errors - ) - } - internal func encode(to encoder: any Swift.Encoder) throws { - try self.value1?.encode(to: encoder) - try self.value2?.encode(to: encoder) - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/json`. - case json(Operations.FunctionInvocations_invokePost.Output.Ok.Body.jsonPayload) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: Operations.FunctionInvocations_invokePost.Output.Ok.Body.jsonPayload { + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + internal var any: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .any(body): return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/json", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.binary`. - /// - /// - Throws: An error if `self` is not `.binary`. - /// - SeeAlso: `.binary`. - internal var binary: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .binary(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/octet-stream", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/POST/responses/200/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.plainText`. - /// - /// - Throws: An error if `self` is not `.plainText`. - /// - SeeAlso: `.plainText`. - internal var plainText: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .plainText(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "text/plain", - body: self - ) } } } @@ -609,18 +515,15 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case any case json - case binary - case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "*/*": + self = .any case "application/json": self = .json - case "application/octet-stream": - self = .binary - case "text/plain": - self = .plainText default: self = .other(rawValue) } @@ -629,19 +532,16 @@ internal enum Operations { switch self { case let .other(string): return string + case .any: + return "*/*" case .json: return "application/json" - case .binary: - return "application/octet-stream" - case .plainText: - return "text/plain" } } internal static var allCases: [Self] { [ - .json, - .binary, - .plainText + .any, + .json ] } } @@ -685,14 +585,8 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokePatch.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/application\/x-www-form-urlencoded`. - case urlEncodedForm(Swift.String) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/requestBody/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) } internal var body: Operations.FunctionInvocations_invokePatch.Input.Body? /// Creates a new `Input`. @@ -715,105 +609,17 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/json`. - internal struct jsonPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/json/value1`. - internal var value1: OpenAPIRuntime.OpenAPIValueContainer? - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/json/value2`. - internal var value2: OpenAPIRuntime.OpenAPIValueContainer? - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - value1: - /// - value2: - internal init( - value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, - value2: OpenAPIRuntime.OpenAPIValueContainer? = nil - ) { - self.value1 = value1 - self.value2 = value2 - } - internal init(from decoder: any Swift.Decoder) throws { - var errors: [any Swift.Error] = [] - do { - self.value1 = try .init(from: decoder) - } catch { - errors.append(error) - } - do { - self.value2 = try .init(from: decoder) - } catch { - errors.append(error) - } - try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( - [ - self.value1, - self.value2 - ], - type: Self.self, - codingPath: decoder.codingPath, - errors: errors - ) - } - internal func encode(to encoder: any Swift.Encoder) throws { - try self.value1?.encode(to: encoder) - try self.value2?.encode(to: encoder) - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/application\/json`. - case json(Operations.FunctionInvocations_invokePatch.Output.Ok.Body.jsonPayload) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: Operations.FunctionInvocations_invokePatch.Output.Ok.Body.jsonPayload { + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + internal var any: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .any(body): return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/json", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.binary`. - /// - /// - Throws: An error if `self` is not `.binary`. - /// - SeeAlso: `.binary`. - internal var binary: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .binary(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/octet-stream", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PATCH/responses/200/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.plainText`. - /// - /// - Throws: An error if `self` is not `.plainText`. - /// - SeeAlso: `.plainText`. - internal var plainText: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .plainText(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "text/plain", - body: self - ) } } } @@ -904,18 +710,15 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case any case json - case binary - case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "*/*": + self = .any case "application/json": self = .json - case "application/octet-stream": - self = .binary - case "text/plain": - self = .plainText default: self = .other(rawValue) } @@ -924,19 +727,16 @@ internal enum Operations { switch self { case let .other(string): return string + case .any: + return "*/*" case .json: return "application/json" - case .binary: - return "application/octet-stream" - case .plainText: - return "text/plain" } } internal static var allCases: [Self] { [ - .json, - .binary, - .plainText + .any, + .json ] } } @@ -980,14 +780,8 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokePut.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/application\/x-www-form-urlencoded`. - case urlEncodedForm(Swift.String) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/requestBody/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) } internal var body: Operations.FunctionInvocations_invokePut.Input.Body? /// Creates a new `Input`. @@ -1010,105 +804,17 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/json`. - internal struct jsonPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/json/value1`. - internal var value1: OpenAPIRuntime.OpenAPIValueContainer? - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/json/value2`. - internal var value2: OpenAPIRuntime.OpenAPIValueContainer? - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - value1: - /// - value2: - internal init( - value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, - value2: OpenAPIRuntime.OpenAPIValueContainer? = nil - ) { - self.value1 = value1 - self.value2 = value2 - } - internal init(from decoder: any Swift.Decoder) throws { - var errors: [any Swift.Error] = [] - do { - self.value1 = try .init(from: decoder) - } catch { - errors.append(error) - } - do { - self.value2 = try .init(from: decoder) - } catch { - errors.append(error) - } - try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( - [ - self.value1, - self.value2 - ], - type: Self.self, - codingPath: decoder.codingPath, - errors: errors - ) - } - internal func encode(to encoder: any Swift.Encoder) throws { - try self.value1?.encode(to: encoder) - try self.value2?.encode(to: encoder) - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/application\/json`. - case json(Operations.FunctionInvocations_invokePut.Output.Ok.Body.jsonPayload) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: Operations.FunctionInvocations_invokePut.Output.Ok.Body.jsonPayload { + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + internal var any: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .any(body): return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/json", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.binary`. - /// - /// - Throws: An error if `self` is not `.binary`. - /// - SeeAlso: `.binary`. - internal var binary: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .binary(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/octet-stream", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/PUT/responses/200/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.plainText`. - /// - /// - Throws: An error if `self` is not `.plainText`. - /// - SeeAlso: `.plainText`. - internal var plainText: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .plainText(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "text/plain", - body: self - ) } } } @@ -1199,18 +905,15 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case any case json - case binary - case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "*/*": + self = .any case "application/json": self = .json - case "application/octet-stream": - self = .binary - case "text/plain": - self = .plainText default: self = .other(rawValue) } @@ -1219,19 +922,16 @@ internal enum Operations { switch self { case let .other(string): return string + case .any: + return "*/*" case .json: return "application/json" - case .binary: - return "application/octet-stream" - case .plainText: - return "text/plain" } } internal static var allCases: [Self] { [ - .json, - .binary, - .plainText + .any, + .json ] } } @@ -1275,14 +975,8 @@ internal enum Operations { internal var headers: Operations.FunctionInvocations_invokeDelete.Input.Headers /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/json`. - case json(OpenAPIRuntime.OpenAPIValueContainer) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/application\/x-www-form-urlencoded`. - case urlEncodedForm(Swift.String) + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/requestBody/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) } internal var body: Operations.FunctionInvocations_invokeDelete.Input.Body? /// Creates a new `Input`. @@ -1305,105 +999,17 @@ internal enum Operations { internal struct Ok: Sendable, Hashable { /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content`. internal enum Body: Sendable, Hashable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/json`. - internal struct jsonPayload: Codable, Hashable, Sendable { - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/json/value1`. - internal var value1: OpenAPIRuntime.OpenAPIValueContainer? - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/json/value2`. - internal var value2: OpenAPIRuntime.OpenAPIValueContainer? - /// Creates a new `jsonPayload`. - /// - /// - Parameters: - /// - value1: - /// - value2: - internal init( - value1: OpenAPIRuntime.OpenAPIValueContainer? = nil, - value2: OpenAPIRuntime.OpenAPIValueContainer? = nil - ) { - self.value1 = value1 - self.value2 = value2 - } - internal init(from decoder: any Swift.Decoder) throws { - var errors: [any Swift.Error] = [] - do { - self.value1 = try .init(from: decoder) - } catch { - errors.append(error) - } - do { - self.value2 = try .init(from: decoder) - } catch { - errors.append(error) - } - try Swift.DecodingError.verifyAtLeastOneSchemaIsNotNil( - [ - self.value1, - self.value2 - ], - type: Self.self, - codingPath: decoder.codingPath, - errors: errors - ) - } - internal func encode(to encoder: any Swift.Encoder) throws { - try self.value1?.encode(to: encoder) - try self.value2?.encode(to: encoder) - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/application\/json`. - case json(Operations.FunctionInvocations_invokeDelete.Output.Ok.Body.jsonPayload) - /// The associated value of the enum case if `self` is `.json`. + /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/*\/*`. + case any(OpenAPIRuntime.HTTPBody) + /// The associated value of the enum case if `self` is `.any`. /// - /// - Throws: An error if `self` is not `.json`. - /// - SeeAlso: `.json`. - internal var json: Operations.FunctionInvocations_invokeDelete.Output.Ok.Body.jsonPayload { + /// - Throws: An error if `self` is not `.any`. + /// - SeeAlso: `.any`. + internal var any: OpenAPIRuntime.HTTPBody { get throws { switch self { - case let .json(body): + case let .any(body): return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/json", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/application\/octet-stream`. - case binary(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.binary`. - /// - /// - Throws: An error if `self` is not `.binary`. - /// - SeeAlso: `.binary`. - internal var binary: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .binary(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "application/octet-stream", - body: self - ) - } - } - } - /// - Remark: Generated from `#/paths/functions/v1/{functionName}/DELETE/responses/200/content/text\/plain`. - case plainText(OpenAPIRuntime.HTTPBody) - /// The associated value of the enum case if `self` is `.plainText`. - /// - /// - Throws: An error if `self` is not `.plainText`. - /// - SeeAlso: `.plainText`. - internal var plainText: OpenAPIRuntime.HTTPBody { - get throws { - switch self { - case let .plainText(body): - return body - default: - try throwUnexpectedResponseBody( - expectedContent: "text/plain", - body: self - ) } } } @@ -1494,18 +1100,15 @@ internal enum Operations { } } internal enum AcceptableContentType: AcceptableProtocol { + case any case json - case binary - case plainText case other(Swift.String) internal init?(rawValue: Swift.String) { switch rawValue.lowercased() { + case "*/*": + self = .any case "application/json": self = .json - case "application/octet-stream": - self = .binary - case "text/plain": - self = .plainText default: self = .other(rawValue) } @@ -1514,19 +1117,16 @@ internal enum Operations { switch self { case let .other(string): return string + case .any: + return "*/*" case .json: return "application/json" - case .binary: - return "application/octet-stream" - case .plainText: - return "text/plain" } } internal static var allCases: [Self] { [ - .json, - .binary, - .plainText + .any, + .json ] } } diff --git a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml index b13f27b14..87a078411 100644 --- a/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml +++ b/smithy/output/typespec-openapi/openapi.Supabase.Functions.yaml @@ -22,7 +22,7 @@ paths: '200': description: The request has succeeded. content: - application/octet-stream: + '*/*': schema: type: string format: binary @@ -49,18 +49,10 @@ paths: '200': description: The request has succeeded. content: - application/json: - schema: - anyOf: - - {} - - {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string default: description: An unexpected error response. content: @@ -70,18 +62,10 @@ paths: requestBody: required: false content: - application/json: - schema: {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string - application/x-www-form-urlencoded: - schema: - type: string put: operationId: FunctionInvocations_invokePut parameters: @@ -99,18 +83,10 @@ paths: '200': description: The request has succeeded. content: - application/json: - schema: - anyOf: - - {} - - {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string default: description: An unexpected error response. content: @@ -120,18 +96,10 @@ paths: requestBody: required: false content: - application/json: - schema: {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string - application/x-www-form-urlencoded: - schema: - type: string patch: operationId: FunctionInvocations_invokePatch parameters: @@ -149,18 +117,10 @@ paths: '200': description: The request has succeeded. content: - application/json: - schema: - anyOf: - - {} - - {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string default: description: An unexpected error response. content: @@ -170,18 +130,10 @@ paths: requestBody: required: false content: - application/json: - schema: {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string - application/x-www-form-urlencoded: - schema: - type: string delete: operationId: FunctionInvocations_invokeDelete parameters: @@ -199,18 +151,10 @@ paths: '200': description: The request has succeeded. content: - application/json: - schema: - anyOf: - - {} - - {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string default: description: An unexpected error response. content: @@ -220,18 +164,10 @@ paths: requestBody: required: false content: - application/json: - schema: {} - application/octet-stream: + '*/*': schema: type: string format: binary - text/plain: - schema: - type: string - application/x-www-form-urlencoded: - schema: - type: string components: schemas: FunctionsError: