diff --git a/OutlineKit/Sources/OutlineKit/Core/OutlineAPIClient.swift b/OutlineKit/Sources/OutlineKit/Core/OutlineAPIClient.swift index a1e2707..6fa7a12 100644 --- a/OutlineKit/Sources/OutlineKit/Core/OutlineAPIClient.swift +++ b/OutlineKit/Sources/OutlineKit/Core/OutlineAPIClient.swift @@ -8,7 +8,7 @@ public protocol OutlineAPIClient: Sendable { func authInfo() async throws -> OutlineAuthInfo func documentInfo(id: String) async throws -> OutlineDocument - func listDocuments(collectionId: String?, offset: Int, limit: Int) async throws -> [OutlineDocument] + func listDocuments(collectionId: String?, parentDocumentId: String?, offset: Int, limit: Int) async throws -> [OutlineDocument] /// Full-text search with snippets/ranking. Backed by `documents.search`. func searchDocuments(_ request: DocumentSearchRequest) async throws -> [OutlineDocumentSearchResult] /// Title-only search — faster, no snippets. Backed by `documents.search_titles`. diff --git a/OutlineKit/Sources/OutlineKit/LiveOutlineAPIClient.swift b/OutlineKit/Sources/OutlineKit/LiveOutlineAPIClient.swift index 17623db..ef96a74 100644 --- a/OutlineKit/Sources/OutlineKit/LiveOutlineAPIClient.swift +++ b/OutlineKit/Sources/OutlineKit/LiveOutlineAPIClient.swift @@ -34,10 +34,20 @@ public actor LiveOutlineAPIClient: OutlineAPIClient { try await post("documents.info", body: DocumentInfoParams(id: id)) } - public func listDocuments(collectionId: String?, offset: Int, limit: Int) async throws -> [OutlineDocument] { + public func listDocuments( + collectionId: String?, + parentDocumentId: String?, + offset: Int, + limit: Int + ) async throws -> [OutlineDocument] { try await post( "documents.list", - body: DocumentListParams(collectionId: collectionId, offset: offset, limit: limit) + body: DocumentListParams( + collectionId: collectionId, + parentDocumentId: parentDocumentId, + offset: offset, + limit: limit + ) ) } @@ -188,6 +198,7 @@ private struct DocumentInfoParams: Encodable { private struct DocumentListParams: Encodable { let collectionId: String? + let parentDocumentId: String? let offset: Int let limit: Int } diff --git a/OutlineKit/Tests/OutlineKitTests/LiveOutlineAPIClientTests.swift b/OutlineKit/Tests/OutlineKitTests/LiveOutlineAPIClientTests.swift index d4c44ad..06c8a08 100644 --- a/OutlineKit/Tests/OutlineKitTests/LiveOutlineAPIClientTests.swift +++ b/OutlineKit/Tests/OutlineKitTests/LiveOutlineAPIClientTests.swift @@ -257,6 +257,29 @@ final class LiveOutlineAPIClientTests: XCTestCase { XCTAssertEqual(decodedBody.description, "Updated overview text.") } + func testListDocumentsSendsParentDocumentIdFilter() async throws { + let httpClient = MockHTTPClient() + httpClient.responseData = """ + { "data": [] } + """.data(using: .utf8)! + + let client = LiveOutlineAPIClient( + configuration: OutlineConfiguration(baseURL: URL(string: "https://outline.example.com")!), + tokenStore: StaticTokenStore(), + httpClient: httpClient + ) + + _ = try await client.listDocuments(collectionId: nil, parentDocumentId: "doc-1", offset: 0, limit: 100) + + struct SentBody: Decodable { + let parentDocumentId: String? + } + + let sentBody = try XCTUnwrap(httpClient.lastRequest?.httpBody) + let decodedBody = try JSONDecoder().decode(SentBody.self, from: sentBody) + XCTAssertEqual(decodedBody.parentDocumentId, "doc-1") + } + func testDocumentInfoDecodesEnvelopeAndSetsAuthHeader() async throws { let httpClient = MockHTTPClient() httpClient.responseData = """