api-swift / Sources / IrdAPI / Generated / Sharing.swift
1,536 words
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
// Generated by scripts/gen-api.py from spec/openapi.json — do not edit.

import Foundation

// MARK: - Types

/// Values this build does not know decode as `.unrecognized`.
public enum GrantScope: RawRepresentable, Codable, Sendable, Hashable {
    case dns
    case tunnel
    case ipfs
    case vps
    /// A value the server sent that this version of the package does not list.
    case unrecognized(String)

    /// Every value the spec listed when this file was generated.
    public static let known: [GrantScope] = [.dns, .tunnel, .ipfs, .vps]

    public init(rawValue: String) {
        switch rawValue {
        case "dns": self = .dns
        case "tunnel": self = .tunnel
        case "ipfs": self = .ipfs
        case "vps": self = .vps
        default: self = .unrecognized(rawValue)
        }
    }

    public var rawValue: String {
        switch self {
        case .dns: return "dns"
        case .tunnel: return "tunnel"
        case .ipfs: return "ipfs"
        case .vps: return "vps"
        case .unrecognized(let raw): return raw
        }
    }

    public init(from decoder: any Decoder) throws {
        self.init(rawValue: try decoder.singleValueContainer().decode(String.self))
    }

    public func encode(to encoder: any Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(rawValue)
    }
}

/// Values this build does not know decode as `.unrecognized`.
public enum GrantState: RawRepresentable, Codable, Sendable, Hashable {
    case pending
    case active
    case revoked
    case declined
    case left
    /// A value the server sent that this version of the package does not list.
    case unrecognized(String)

    /// Every value the spec listed when this file was generated.
    public static let known: [GrantState] = [.pending, .active, .revoked, .declined, .left]

    public init(rawValue: String) {
        switch rawValue {
        case "pending": self = .pending
        case "active": self = .active
        case "revoked": self = .revoked
        case "declined": self = .declined
        case "left": self = .left
        default: self = .unrecognized(rawValue)
        }
    }

    public var rawValue: String {
        switch self {
        case .pending: return "pending"
        case .active: return "active"
        case .revoked: return "revoked"
        case .declined: return "declined"
        case .left: return "left"
        case .unrecognized(let raw): return raw
        }
    }

    public init(from decoder: any Decoder) throws {
        self.init(rawValue: try decoder.singleValueContainer().decode(String.self))
    }

    public func encode(to encoder: any Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(rawValue)
    }
}

/// Values this build does not know decode as `.unrecognized`.
public enum GrantPayer: RawRepresentable, Codable, Sendable, Hashable {
    case owner
    case grantee
    case split
    /// A value the server sent that this version of the package does not list.
    case unrecognized(String)

    /// Every value the spec listed when this file was generated.
    public static let known: [GrantPayer] = [.owner, .grantee, .split]

    public init(rawValue: String) {
        switch rawValue {
        case "owner": self = .owner
        case "grantee": self = .grantee
        case "split": self = .split
        default: self = .unrecognized(rawValue)
        }
    }

    public var rawValue: String {
        switch self {
        case .owner: return "owner"
        case .grantee: return "grantee"
        case .split: return "split"
        case .unrecognized(let raw): return raw
        }
    }

    public init(from decoder: any Decoder) throws {
        self.init(rawValue: try decoder.singleValueContainer().decode(String.self))
    }

    public func encode(to encoder: any Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(rawValue)
    }
}

/// Shared by 7 operations.
public struct Grant: Codable, Sendable, Hashable, Identifiable {
    public var id: String
    public var registrationId: String
    public var scopes: [GrantScope]
    public var state: GrantState
    public var invitedEmail: String
    /// Who is billed for usage under the grant — the domain owner (the default), the grantee, or split (each charge booked half to each). Fixed at invite time; resources a delegate creates live on the owner's account in every mode, and IPFS gateway egress bills the owner regardless.
    public var payer: GrantPayer
    /// True on a pending/active grant whose registration expired, transferred out or changed owner — it confers nothing until re-granted.
    public var inactive: Bool
    public var createdAt: String
    public var acceptedAt: String?
    public var revokedAt: String?
    public var domain: String?
    public var ownerEmail: String?

    public init(id: String, registrationId: String, scopes: [GrantScope], state: GrantState, invitedEmail: String, payer: GrantPayer, inactive: Bool, createdAt: String, acceptedAt: String? = nil, revokedAt: String? = nil, domain: String? = nil, ownerEmail: String? = nil) {
        self.id = id
        self.registrationId = registrationId
        self.scopes = scopes
        self.state = state
        self.invitedEmail = invitedEmail
        self.payer = payer
        self.inactive = inactive
        self.createdAt = createdAt
        self.acceptedAt = acceptedAt
        self.revokedAt = revokedAt
        self.domain = domain
        self.ownerEmail = ownerEmail
    }

    enum CodingKeys: String, CodingKey {
        case id
        case registrationId = "registration_id"
        case scopes
        case state
        case invitedEmail = "invited_email"
        case payer
        case inactive
        case createdAt = "created_at"
        case acceptedAt = "accepted_at"
        case revokedAt = "revoked_at"
        case domain
        case ownerEmail = "owner_email"
    }

    /// Explicit so required-but-nullable fields encode as `null` rather than vanishing.
    public func encode(to encoder: any Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(registrationId, forKey: .registrationId)
        try container.encode(scopes, forKey: .scopes)
        try container.encode(state, forKey: .state)
        try container.encode(invitedEmail, forKey: .invitedEmail)
        try container.encode(payer, forKey: .payer)
        try container.encode(inactive, forKey: .inactive)
        try container.encode(createdAt, forKey: .createdAt)
        try container.encode(acceptedAt, forKey: .acceptedAt)
        try container.encode(revokedAt, forKey: .revokedAt)
        try container.encodeIfPresent(domain, forKey: .domain)
        try container.encodeIfPresent(ownerEmail, forKey: .ownerEmail)
    }
}

/// Shared by 2 operations.
public struct GrantsResponse: Codable, Sendable, Hashable {
    public var grants: [Grant]

    public init(grants: [Grant]) {
        self.grants = grants
    }

    enum CodingKeys: String, CodingKey {
        case grants
    }
}

/// Used by POST /domains/registrations/{id}/grants.
public struct InviteBody: Codable, Sendable, Hashable {
    public var email: String
    public var scopes: [GrantScope]
    public var payer: GrantPayer?
    public var totpCode: String?

    public init(email: String, scopes: [GrantScope], payer: GrantPayer? = nil, totpCode: String? = nil) {
        self.email = email
        self.scopes = scopes
        self.payer = payer
        self.totpCode = totpCode
    }

    enum CodingKeys: String, CodingKey {
        case email
        case scopes
        case payer
        case totpCode = "totp_code"
    }
}

/// Shared by 5 operations.
public struct GrantResponse: Codable, Sendable, Hashable {
    public var grant: Grant

    public init(grant: Grant) {
        self.grant = grant
    }

    enum CodingKeys: String, CodingKey {
        case grant
    }
}

// MARK: - Operations

extension IrdOperation {
    public static let sharing_listDomainGrants = IrdOperation(method: .get, pathTemplate: "/domains/registrations/{id}/grants", module: "sharing", name: "listDomainGrants", security: .jwtOnly)
    public static let sharing_invite = IrdOperation(method: .post, pathTemplate: "/domains/registrations/{id}/grants", module: "sharing", name: "invite", security: .jwtOnly)
    public static let sharing_revokeGrant = IrdOperation(method: .delete, pathTemplate: "/domains/registrations/{id}/grants/{grant-id}", module: "sharing", name: "revokeGrant", security: .jwtOnly)
    public static let sharing_listGrants = IrdOperation(method: .get, pathTemplate: "/grants", module: "sharing", name: "listGrants", security: .jwtOnly)
    public static let sharing_acceptGrant = IrdOperation(method: .post, pathTemplate: "/grants/{id}/accept", module: "sharing", name: "acceptGrant", security: .jwtOnly)
    public static let sharing_declineGrant = IrdOperation(method: .post, pathTemplate: "/grants/{id}/decline", module: "sharing", name: "declineGrant", security: .jwtOnly)
    public static let sharing_leaveGrant = IrdOperation(method: .post, pathTemplate: "/grants/{id}/leave", module: "sharing", name: "leaveGrant", security: .jwtOnly)

    static let sharingOperations: [IrdOperation] = [.sharing_listDomainGrants, .sharing_invite, .sharing_revokeGrant, .sharing_listGrants, .sharing_acceptGrant, .sharing_declineGrant, .sharing_leaveGrant]
}

/// The `sharing` operations (7).
public struct SharingAPI: Sendable {
    let client: IrdClient

    /// Who has delegated access to this domain
    /// Every grant ever minted on the registration, newest first — pending invites, active grants and ended history. Rows whose validity lapsed (the registration expired, transferred out or changed owner) carry `inactive: true`. Session JWT only.
    /// `GET /domains/registrations/{id}/grants` — 200
    /// Requires an account session (JWT); API keys answer 401.
    public func listDomainGrants(id: String) async throws -> GrantsResponse {
        try await client.request(.sharing_listDomainGrants, params: ["id": id])
    }

    /// Invite another customer to manage parts of this domain
    /// Grants `email` (an existing ird account) the listed scopes on this domain — `dns` (hosted-zone records), `tunnel` (tunnels on and under it), `ipfs` (gateway-domain bindings), `vps` (servers anchored to it or a subdomain at create) — pending until they accept.
    /// `POST /domains/registrations/{id}/grants` — 201
    /// Requires an account session (JWT); API keys answer 401.
    public func invite(id: String, body: InviteBody) async throws -> GrantResponse {
        try await client.request(.sharing_invite, params: ["id": id], body: body)
    }

    /// Revoke delegated access
    /// Ends a pending or active grant immediately. Deliberately free of the authenticator gate — removing access must never be harder than keeping it. Session JWT only.
    /// `DELETE /domains/registrations/{id}/grants/{grant-id}` — 200
    /// Requires an account session (JWT); API keys answer 401.
    public func revokeGrant(id: String, grantId: String) async throws -> GrantResponse {
        try await client.request(.sharing_revokeGrant, params: ["id": id, "grant-id": grantId])
    }

    /// Domains shared with this account
    /// Active grants where this account is the grantee plus pending invites addressed to any email it controls, newest first, with the domain name and the owner's email joined.
    /// `GET /grants` — 200
    /// Requires an account session (JWT); API keys answer 401.
    public func listGrants() async throws -> GrantsResponse {
        try await client.request(.sharing_listGrants)
    }

    /// Accept a delegated-access invite
    /// Activates a pending invite addressed to an email this account controls.
    /// `POST /grants/{id}/accept` — 200
    /// Requires an account session (JWT); API keys answer 401.
    public func acceptGrant(id: String) async throws -> GrantResponse {
        try await client.request(.sharing_acceptGrant, params: ["id": id])
    }

    /// Decline a delegated-access invite
    /// `POST /grants/{id}/decline` — 200
    /// Requires an account session (JWT); API keys answer 401.
    public func declineGrant(id: String) async throws -> GrantResponse {
        try await client.request(.sharing_declineGrant, params: ["id": id])
    }

    /// Walk away from an active grant
    /// Ends the caller's own grant. On a grantee-pays or split share this also returns hourly billing for resources the delegation anchored fully to the owner — leaving is the grantee's escape hatch even after the grant lapsed.
    /// `POST /grants/{id}/leave` — 200
    /// Requires an account session (JWT); API keys answer 401.
    public func leaveGrant(id: String) async throws -> GrantResponse {
        try await client.request(.sharing_leaveGrant, params: ["id": id])
    }
}

extension IrdClient {
    public var sharing: SharingAPI { SharingAPI(client: self) }
}

static mirror of HEAD · about · clone: git clone https://ird.cod-sursa.ro/api-swift.git