Skip to content

Commit f965349

Browse files
committed
made methods public
Also added sendable to the models
1 parent f2f86d3 commit f965349

2 files changed

Lines changed: 374 additions & 343 deletions

File tree

Sources/MarkbookAPI/MarkbookAPI.swift

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// The Swift Programming Language
2-
// https://docs.swift.org/swift-book
31
// MarkbookAPIClient.swift
42
// Markbook Online REST API v1.5
53
// https://smpcsonline.com.au/markbook/api/v1.5
@@ -8,7 +6,7 @@ import Foundation
86

97
// MARK: - Errors
108

11-
enum MarkbookAPIError: Error, LocalizedError {
9+
public enum MarkbookAPIError: Error, LocalizedError {
1210
/// The server returned a non-2xx HTTP status code.
1311
case httpError(statusCode: Int)
1412
/// The API returned a non-OKAY status in the response body.
@@ -20,7 +18,7 @@ enum MarkbookAPIError: Error, LocalizedError {
2018
/// The session could not be established or refreshed.
2119
case authenticationFailed(underlying: Error)
2220

23-
var errorDescription: String? {
21+
public var errorDescription: String? {
2422
switch self {
2523
case .httpError(let code):
2624
return "HTTP error: \(code)"
@@ -40,7 +38,7 @@ enum MarkbookAPIError: Error, LocalizedError {
4038

4139
/// Defines the full surface area of the Markbook Online API client.
4240
/// Conform a mock to this protocol to enable unit testing without network calls.
43-
protocol MarkbookAPIClientProtocol {
41+
public protocol MarkbookAPIClientProtocol {
4442
func markbookList() async throws -> MarkbookListResponse
4543
func userList() async throws -> UserListResponse
4644
func getMarkbook(key: Int) async throws -> GetMarkbookResponse
@@ -104,14 +102,16 @@ protocol MarkbookAPIClientProtocol {
104102
/// re-authenticates before any call that would use an expired session.
105103
///
106104
/// ```swift
105+
/// import MarkbookAPI
106+
///
107107
/// let client = MarkbookAPIClient(
108108
/// apiKey: "YOUR_32_CHAR_API_KEY",
109109
/// username: "adminuser",
110110
/// password: "secret"
111111
/// )
112112
/// let markbooks = try await client.markbookList()
113113
/// ```
114-
actor MarkbookAPIClient: MarkbookAPIClientProtocol {
114+
public actor MarkbookAPIClient: MarkbookAPIClientProtocol {
115115

116116
// MARK: - Private State
117117

@@ -140,7 +140,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
140140
/// - password: Password for the above user.
141141
/// - baseURL: Override only for testing. Defaults to the production endpoint.
142142
/// - urlSession: Override to inject a mock session for testing.
143-
init(
143+
public init(
144144
apiKey: String,
145145
username: String,
146146
password: String,
@@ -158,22 +158,22 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
158158
// MARK: - Public API Methods
159159

160160
/// Returns the list of all markbooks in the school database.
161-
func markbookList() async throws -> MarkbookListResponse {
161+
public func markbookList() async throws -> MarkbookListResponse {
162162
try await get(queryItems: [
163163
.init(name: "action", value: APIAction.markbookList.rawValue)
164164
])
165165
}
166166

167167
/// Returns the list of all users in the school database.
168-
func userList() async throws -> UserListResponse {
168+
public func userList() async throws -> UserListResponse {
169169
try await get(queryItems: [
170170
.init(name: "action", value: APIAction.userList.rawValue)
171171
])
172172
}
173173

174174
/// Returns the full contents of a markbook, with per-student result arrays.
175175
/// - Parameter key: The markbook key from ``markbookList()``.
176-
func getMarkbook(key: Int) async throws -> GetMarkbookResponse {
176+
public func getMarkbook(key: Int) async throws -> GetMarkbookResponse {
177177
try await get(queryItems: [
178178
.init(name: "action", value: APIAction.getMarkbook.rawValue),
179179
.init(name: "key", value: String(key))
@@ -182,7 +182,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
182182

183183
/// Returns the full contents of a markbook in the flat alternate format.
184184
/// - Parameter key: The markbook key from ``markbookList()``.
185-
func getMarkbookAlt(key: Int) async throws -> GetMarkbookAltResponse {
185+
public func getMarkbookAlt(key: Int) async throws -> GetMarkbookAltResponse {
186186
try await get(queryItems: [
187187
.init(name: "action", value: APIAction.getMarkbookAlt.rawValue),
188188
.init(name: "key", value: String(key))
@@ -191,7 +191,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
191191

192192
/// Returns outcome levels for all students in a markbook.
193193
/// - Parameter key: The markbook key from ``markbookList()``.
194-
func getOutcomes(key: Int) async throws -> GetOutcomesResponse {
194+
public func getOutcomes(key: Int) async throws -> GetOutcomesResponse {
195195
try await get(queryItems: [
196196
.init(name: "action", value: APIAction.getOutcomes.rawValue),
197197
.init(name: "key", value: String(key))
@@ -200,7 +200,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
200200

201201
/// Returns outcome levels in the flat alternate format.
202202
/// - Parameter key: The markbook key from ``markbookList()``.
203-
func getOutcomesAlt(key: Int) async throws -> GetOutcomesAltResponse {
203+
public func getOutcomesAlt(key: Int) async throws -> GetOutcomesAltResponse {
204204
try await get(queryItems: [
205205
.init(name: "action", value: APIAction.getOutcomesAlt.rawValue),
206206
.init(name: "key", value: String(key))
@@ -216,7 +216,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
216216
/// - taskKey: The task key from the markbook's `tasklist`.
217217
/// - taskName: The task name from the markbook's `tasklist`.
218218
/// - result: The result value to record.
219-
func putStudentResult(
219+
public func putStudentResult(
220220
markbookKey: Int,
221221
studentKey: Int,
222222
sid: String,
@@ -249,7 +249,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
249249
/// - gender: Student gender.
250250
/// - classKey: The class key from ``getMarkbook(key:)`` or ``getMarkbookAlt(key:)``.
251251
/// - Returns: The response containing the new student's key.
252-
func createStudent(
252+
public func createStudent(
253253
markbookKey: Int,
254254
sid: String,
255255
familyName: String,
@@ -281,7 +281,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
281281
/// - givenName: Student given name.
282282
/// - preferredName: Student preferred name (may be empty).
283283
/// - gender: Student gender.
284-
func updateStudent(
284+
public func updateStudent(
285285
markbookKey: Int,
286286
studentKey: Int,
287287
sid: String,
@@ -313,7 +313,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
313313
/// - studentKey: The student key from ``getMarkbook(key:)`` or ``getMarkbookAlt(key:)``.
314314
/// - sid: The student ID from the same source as `studentKey`.
315315
/// - classKey: The destination class key.
316-
func updateStudentClass(
316+
public func updateStudentClass(
317317
markbookKey: Int,
318318
studentKey: Int,
319319
sid: String,
@@ -332,13 +332,14 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
332332
}
333333

334334
/// Soft-deletes a student from a markbook.
335-
/// The student remains in the database and can be restored via ``updateStudentClass(markbookKey:studentKey:sid:classKey:)``.
335+
/// The student remains in the database and can be restored via
336+
/// ``updateStudentClass(markbookKey:studentKey:sid:classKey:)``.
336337
///
337338
/// - Parameters:
338339
/// - markbookKey: The markbook key from ``markbookList()``.
339340
/// - studentKey: The student key from ``getMarkbook(key:)`` or ``getMarkbookAlt(key:)``.
340341
/// - sid: The student ID from the same source as `studentKey`.
341-
func deleteStudent(
342+
public func deleteStudent(
342343
markbookKey: Int,
343344
studentKey: Int,
344345
sid: String
@@ -362,7 +363,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
362363
/// - teacherFamilyName: The class teacher's family name.
363364
/// - teacherGivenName: The class teacher's given name.
364365
/// - Returns: The response containing the new class key.
365-
func createClass(
366+
public func createClass(
366367
markbookKey: Int,
367368
name: String,
368369
teacherFamilyName: String,
@@ -382,7 +383,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
382383
/// Only one backup can be scheduled per day; a second call replaces the first.
383384
///
384385
/// - Parameter matching: A substring filter (minimum 2 characters) applied to markbook names.
385-
func scheduleBackup(matching: String) async throws {
386+
public func scheduleBackup(matching: String) async throws {
386387
guard matching.count >= 2 else {
387388
throw MarkbookAPIError.invalidBackupMatchingParameter
388389
}
@@ -403,7 +404,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
403404
/// - Returns: The full response, including the `url` and `status`.
404405
/// Check `status` for `.errorPending` (backup not yet ready) or `.errorNoBackup`
405406
/// (no backup has been scheduled).
406-
func getBackupURL() async throws -> GetBackupURLResponse {
407+
public func getBackupURL() async throws -> GetBackupURLResponse {
407408
try await get(queryItems: [
408409
.init(name: "action", value: APIAction.getBackupURL.rawValue)
409410
])
@@ -414,7 +415,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
414415
/// - Parameter request: The fully populated ``CreateMarkbookRequest``.
415416
/// Build it with the local class/student keys starting from 1.
416417
/// - Returns: The response containing the new markbook key and actual name used.
417-
func createMarkbook(_ request: CreateMarkbookRequest) async throws -> CreateMarkbookResponse {
418+
public func createMarkbook(_ request: CreateMarkbookRequest) async throws -> CreateMarkbookResponse {
418419
try await post(action: APIAction.createMarkbook.rawValue, body: request)
419420
}
420421

@@ -444,7 +445,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
444445
}
445446

446447
private func performAuthentication() async throws -> AuthenticationResponse {
447-
let authURL = baseURL.appendingPathComponent("authenticate.lc", isDirectory: false)
448+
let authURL = baseURL.appendingPathComponent("authenticate.lc", isDirectory: false)
448449

449450
var components = URLComponents()
450451
components.queryItems = [
@@ -534,7 +535,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
534535

535536
let decoded = try decoder.decode(T.self, from: data)
536537

537-
// For any response type that carries a status field, surface API-level errors.
538+
// Surface API-level errors uniformly for any response type that carries a status.
538539
if let statusCarrier = decoded as? any StatusCarrying, !statusCarrier.status.isOkay {
539540
throw MarkbookAPIError.apiError(statusCarrier.status)
540541
}
@@ -545,7 +546,7 @@ actor MarkbookAPIClient: MarkbookAPIClientProtocol {
545546

546547
// MARK: - StatusCarrying
547548

548-
/// Internal protocol used to extract `status` from any response type for uniform error checking.
549+
/// Internal protocol used to extract `status` from any response type for uniform error surfacing.
549550
private protocol StatusCarrying {
550551
var status: APIStatus { get }
551552
}

0 commit comments

Comments
 (0)