Skip to content

Commit c9b0a05

Browse files
authored
Merge pull request #98 from makinosp/develop
Develop
2 parents b4f4550 + 7c88c46 commit c9b0a05

18 files changed

+148
-89
lines changed

Sources/VRCKit/APIClient.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public final actor APIClient {
4343
/// - Throws: `VRCKitError.unexpectedError` if the username and password cannot be converted to UTF-8 data.
4444
private func encodeAuthorization(_ credential: Credential) throws -> String {
4545
guard let payload = credential.authString.data(using: .utf8) else {
46-
throw VRCKitError.unexpected
46+
throw VRCKitError.credentialNotSet
4747
}
4848
return "Basic \(payload.base64EncodedString())"
4949
}
@@ -108,7 +108,7 @@ public final actor APIClient {
108108
return
109109
}
110110
guard let data = data, let reponse = urlResponse as? HTTPURLResponse else {
111-
continuation.resume(throwing: VRCKitError.invalidResponse)
111+
continuation.resume(throwing: VRCKitError.invalidResponse(String(describing: data)))
112112
return
113113
}
114114
continuation.resume(returning: (data, reponse))
@@ -121,7 +121,7 @@ public final actor APIClient {
121121
private func requestWithFoundation(_ request: URLRequest) async throws -> HTTPResponse {
122122
let (data, response) = try await URLSession.shared.data(for: request)
123123
guard let response = response as? HTTPURLResponse else {
124-
throw VRCKitError.invalidResponse
124+
throw VRCKitError.invalidResponse(String(describing: data))
125125
}
126126
return (data, response)
127127
}

Sources/VRCKit/Errors.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@ public enum VRCKitError: Error, LocalizedError, Equatable {
2121
/// Represents an error indicating that the client has been deallocated.
2222
case clientDeallocated
2323

24+
/// Represents an error indicating that credential not set.
25+
case credentialNotSet
26+
2427
/// Represents an error indicating an invalid response was received.
25-
case invalidResponse
28+
case invalidResponse(_ details: String)
2629

2730
/// Represents an error indicating an invalid request with additional details.
2831
case invalidRequest(_ details: String)
2932

3033
/// Represents an error indicating an authentication failure.
3134
case unauthorized
3235

33-
/// Represents an unexpected error.
34-
case unexpected
35-
3636
/// Represents an url error.
3737
case urlError
3838

@@ -42,21 +42,21 @@ public enum VRCKitError: Error, LocalizedError, Equatable {
4242
case .apiError: "API Error"
4343
case .badGateway: "Bad Gateway"
4444
case .clientDeallocated: "Client Deallocated"
45+
case .credentialNotSet: "Credential Error"
4546
case .invalidResponse: "Invalid Response"
4647
case .invalidRequest: "Invalid Request"
4748
case .unauthorized: "Unauthorized"
48-
case .unexpected: "Unexpected"
4949
case .urlError: "URL Error"
5050
}
5151
}
5252

5353
/// Provides a localized failure reason for the error.
5454
public var failureReason: String? {
5555
switch self {
56-
case .apiError(let details), .invalidRequest(let details):
57-
details
58-
default:
59-
errorDescription
56+
case .apiError(let details): details
57+
case .invalidRequest(let details): details
58+
case .invalidResponse(let details): details
59+
default: errorDescription
6060
}
6161
}
6262
}

Sources/VRCKit/Protocols/AuthenticationServiceProtocol.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,29 @@
66
//
77

88
public protocol AuthenticationServiceProtocol: Sendable {
9+
10+
/// Check if a user exists by their user ID.
11+
/// - Parameter userId: The ID of the user to check.
12+
/// - Returns: A boolean indicating if the user exists.
913
func exists(userId: String) async throws -> Bool
14+
15+
/// Fetches the authenticated user's information or determines if two-factor authentication (2FA) verification is required.
16+
/// - Returns: An `Either<User, VerifyType>` result, which is `.left(User)` if the user is successfully authenticated,
17+
/// - Throws: An error if the request fails or if the response cannot be decoded. If an unexpected decoding issue occurs,
18+
/// it throws `VRCKitError.unexpected`.
1019
func loginUserInfo() async throws -> Either<User, VerifyType>
20+
21+
/// Verifies 2-factor authentication using either TOTP or Email OTP.
22+
/// - Parameters:
23+
/// - verifyType: The type of verification (TOTP or Email OTP).
24+
/// - code: The 6-digit verification code.
25+
/// - Returns: A boolean indicating if verification was successful.
1126
func verify2FA(verifyType: VerifyType, code: String) async throws -> Bool
27+
28+
/// Verifies the user's authentication token.
29+
/// - Returns: A boolean indicating if the token is valid.
1230
func verifyAuthToken() async throws -> Bool
31+
32+
/// Logs out the user and deletes cookies.
1333
func logout() async throws
1434
}

Sources/VRCKit/Protocols/FavoriteServiceProtocol.swift

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,52 @@
66
//
77

88
public protocol FavoriteServiceProtocol: Sendable {
9+
/// Asynchronously retrieves a list of favorite groups from the server.
10+
/// - Returns: An array of `FavoriteGroup` objects.
911
func listFavoriteGroups() async throws -> [FavoriteGroup]
12+
13+
/// Lists a user's all favorites with the specified parameters.
14+
/// - Parameter type: The type of favorite (e.g., friend, world).
15+
/// - Returns: An array of `Favorite` objects.
1016
func listFavorites(type: FavoriteType) async throws -> [Favorite]
17+
18+
/// Lists a user's favorites with the specified parameters.
19+
/// - Parameters:
20+
/// - n: The number of favorites to retrieve. Default is `60`.
21+
/// - offset: Offset value of favorites to retrive. Default is `0`.
22+
/// - type: The type of favorite (e.g., friend, world).
23+
/// - tag: An optional tag to filter favorites.
24+
/// - Returns: An array of `Favorite` objects.
25+
func listFavorites(n: Int, offset: Int, type: FavoriteType, tag: String?) async throws -> [Favorite]
26+
27+
/// Fetches details of favorite groups asynchronously.
28+
/// - Parameters:
29+
/// - favoriteGroups: An array of `FavoriteGroup` objects.
30+
/// - type: The type of favorite (e.g., friend, world).
31+
/// - Returns: An array of `FavoriteList` objects containing detailed information about the favorite groups.
1132
func fetchFavoriteList(favoriteGroups: [FavoriteGroup], type: FavoriteType) async throws -> [FavoriteList]
33+
34+
/// Adds a new favorite to a specific group.
35+
/// - Parameters:
36+
/// - type: The type of favorite (e.g., friend, world).
37+
/// - favoriteId: The ID of the item to favorite.
38+
/// - tag: The tag to associate with the favorite.
39+
/// - Returns: The newly added `Favorite` object.
1240
func addFavorite(type: FavoriteType, favoriteId: String, tag: String) async throws -> Favorite
41+
42+
/// Updates a favorite group with the given parameters, display name, and visibility.
43+
/// - Parameters:
44+
/// - source: An object containing the favorite group's details.
45+
/// - displayName: The new display name to update the favorite group with.
46+
/// - visibility: The new visibility setting for the favorite group.
1347
func updateFavoriteGroup(
1448
source: FavoriteGroup,
1549
displayName: String,
1650
visibility: FavoriteGroup.Visibility
1751
) async throws
52+
53+
/// Asynchronously remove favorite.
54+
/// - Parameter favoriteId: The ID of the favorite to remove.
55+
/// - Returns: A `SuccessResponse` objects.
1856
func removeFavorite(favoriteId: String) async throws -> SuccessResponse
1957
}

Sources/VRCKit/Protocols/FriendServiceProtocol.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,26 @@
66
//
77

88
public protocol FriendServiceProtocol: Sendable {
9+
/// Fetches a list of friends with pagination support.
10+
/// - Parameters:
11+
/// - offset: The offset to start retrieving friends from.
12+
/// - n: The maximum number of friends to retrieve in the request (default is 60).
13+
/// - offline: A Boolean indicating whether to include offline friends.
14+
/// - Returns: An array of `Friend` objects representing the user's friends.
15+
/// - Throws: An error if the request fails or decoding is unsuccessful.
916
func fetchFriends(offset: Int, n: Int, offline: Bool) async throws -> [Friend]
17+
18+
/// Fetches a list of friends up to a specified count, using multiple requests if needed.
19+
/// - Parameters:
20+
/// - count: The total number of friends to retrieve.
21+
/// - offline: A Boolean indicating whether to include offline friends.
22+
/// - Returns: An array of `Friend` objects representing the user's friends.
23+
/// - Throws: An error if any request fails or decoding is unsuccessful.
1024
func fetchFriends(count: Int, offline: Bool) async throws -> [Friend]
25+
26+
/// Removes a friend with the specified ID.
27+
/// - Parameter id: The ID of the friend to be removed.
28+
/// - Throws: An error if the request fails.
1129
func unfriend(id: String) async throws
1230
}
1331

Sources/VRCKit/Protocols/ImageUrlRepresentableProtocol.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88
import Foundation
99

1010
public protocol ImageUrlRepresentable: Sendable {
11+
/// Replaces the last numeric component in the provided image URL with a specified resolution and returns a new URL.
12+
///
13+
/// - Parameters:
14+
/// - url: The original image URL to modify.
15+
/// - resolution: The desired image resolution as an `ImageResolution` value. The original resolution is `.origin`.
16+
///
17+
/// - Returns: A new URL with the last numeric component replaced by the specified resolution.
1118
func imageUrl(_ resolution: ImageResolution) -> URL?
1219
}
1320

Sources/VRCKit/Protocols/InstanceServiceProtocol.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@
66
//
77

88
public protocol InstanceServiceProtocol: Sendable {
9+
/// Fetches an instance of a world using the specified world ID and instance ID.
10+
/// - Parameters:
11+
/// - worldId: The ID of the world to fetch the instance from.
12+
/// - instanceId: The ID of the instance to fetch.
13+
/// - Returns: An `Instance` object representing the fetched instance.
14+
/// - Throws: An error if the request fails or the data cannot be decoded.
915
func fetchInstance(worldId: String, instanceId: String) async throws -> Instance
16+
17+
/// Fetches an instance using the specified location string.
18+
/// - Parameter location: The location string in the format "worldId:instanceId".
19+
/// - Returns: An `Instance` object representing the fetched instance.
20+
/// - Throws: An error if the request fails or the data cannot be decoded.
1021
func fetchInstance(location: String) async throws -> Instance
1122
}

Sources/VRCKit/Protocols/UserNoteServiceProtocol.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
//
77

88
public protocol UserNoteServiceProtocol: Sendable {
9+
/// Updates the note for a specific user by sending the note to the API.
10+
/// - Parameters:
11+
/// - targetUserId: The ID of the user for whom the note is being updated.
12+
/// - note: The content of the note to be added or updated.
13+
/// - Returns: A `UserNoteResponse` containing the updated note information.
914
func updateUserNote(targetUserId: String, note: String) async throws -> UserNoteResponse
15+
16+
/// Clears the note for a specific user by sending an empty note to the API.
17+
/// - Parameter targetUserId: The ID of the user whose note is being cleared.
1018
func clearUserNote(targetUserId: String) async throws
1119
}

Sources/VRCKit/Protocols/UserServiceProtocol.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
//
77

88
public protocol UserServiceProtocol: Sendable {
9+
/// Fetches detailed information about a specific user.
10+
/// - Parameter userId: The ID of the user to retrieve.
11+
/// - Returns: A `UserDetail` object containing detailed information about the specified user.
12+
/// - Throws: An error if the request fails or decoding is unsuccessful.
913
func fetchUser(userId: String) async throws -> UserDetail
14+
15+
/// Updates the information for a specific user.
16+
/// - Parameters:
17+
/// - id: The ID of the user to update.
18+
/// - editedInfo: An `EditableUserInfo` object containing the updated user information.
19+
/// - Throws: An error if the request fails or encoding is unsuccessful.
1020
func updateUser(id: String, editedInfo: EditableUserInfo) async throws
1121
}

Sources/VRCKit/Protocols/WorldServiceProtocol.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@
66
//
77

88
public protocol WorldServiceProtocol: Sendable {
9+
/// Fetches detailed information about a specific world.
10+
/// - Parameter worldId: The ID of the world to retrieve.
11+
/// - Returns: A `World` object containing the details of the specified world.
12+
/// - Throws: An error if the request fails or decoding is unsuccessful.
913
func fetchWorld(worldId: String) async throws -> World
14+
15+
/// Retrieves the list of favorited worlds.
16+
/// - Returns: An array of `FavoriteWorld` objects representing the user's favorited worlds.
17+
/// - Throws: An error if any request fails or decoding is unsuccessful.
1018
func fetchFavoritedWorlds() async throws -> [FavoriteWorld]
19+
20+
/// Fetches a paginated list of favorited worlds.
21+
/// This function retrieves a subset of favorited worlds based on the specified limit and offset.
22+
/// - Parameters:
23+
/// - n: The maximum number of worlds to retrieve in the current request.
24+
/// - offset: The offset used to paginate the results.
25+
/// - Returns: An array of `FavoriteWorld` objects representing a subset of favorited worlds.
26+
/// - Throws: An error if the request fails or decoding is unsuccessful.
27+
func fetchFavoritedWorlds(n: Int, offset: Int) async throws -> [FavoriteWorld]
1128
}

0 commit comments

Comments
 (0)