Skip to content

Commit

Permalink
Merge pull request #37 from phiHero/master
Browse files Browse the repository at this point in the history
fix: encode URL user input Id
  • Loading branch information
jasonbosco authored Aug 28, 2024
2 parents 58e996a + 6202234 commit c3be915
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 66 deletions.
37 changes: 19 additions & 18 deletions Sources/Typesense/Alias.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,47 @@ public struct Alias {
}

public func upsert(name: String, collection: CollectionAliasSchema) async throws -> (CollectionAlias?, URLResponse?) {
let schemaData: Data?

schemaData = try encoder.encode(collection)

if let validSchema = schemaData {
let (data, response) = try await apiCall.put(endPoint: "\(RESOURCEPATH)/\(name)", body: validSchema)
if let result = data {
let alias = try decoder.decode(CollectionAlias.self, from: result)
return (alias, response)
}
let schemaData = try encoder.encode(collection)
let (data, response) = try await apiCall.put(endPoint: endpointPath(name), body: schemaData)
if let result = data {
let alias = try decoder.decode(CollectionAlias.self, from: result)
return (alias, response)
}
return (nil, nil)
return (nil, response)
}

public func retrieve(name: String) async throws -> (CollectionAlias?, URLResponse?) {
let (data, response) = try await apiCall.get(endPoint: "\(RESOURCEPATH)/\(name)")
let (data, response) = try await apiCall.get(endPoint: endpointPath(name))
if let result = data {
let alias = try decoder.decode(CollectionAlias.self, from: result)
return (alias, response)
}
return (nil, nil)
return (nil, response)
}

public func retrieve() async throws -> (CollectionAliasesResponse?, URLResponse?) {
let (data, response) = try await apiCall.get(endPoint: "\(RESOURCEPATH)")
let (data, response) = try await apiCall.get(endPoint: endpointPath())
if let result = data {
let aliases = try decoder.decode(CollectionAliasesResponse.self, from: result)
return (aliases, response)
}
return (nil, nil)
return (nil, response)
}

public func delete(name: String) async throws -> (CollectionAlias?, URLResponse?) {
let (data, response) = try await apiCall.delete(endPoint: "\(RESOURCEPATH)/\(name)")
let (data, response) = try await apiCall.delete(endPoint: endpointPath(name))
if let result = data {
let alias = try decoder.decode(CollectionAlias.self, from: result)
return (alias, response)
}
return (nil, nil)
return (nil, response)
}


private func endpointPath(_ operation: String? = nil) throws -> String {
if let operation: String = operation {
return try "\(RESOURCEPATH)/\(operation.encodeURL())"
} else {
return RESOURCEPATH
}
}
}
4 changes: 2 additions & 2 deletions Sources/Typesense/AnalyticsRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public struct AnalyticsRule {
return (nil, response)
}

private func endpointPath() -> String {
return "\(AnalyticsRules.resourcePath)/\(name)"
private func endpointPath() throws -> String {
return try "\(AnalyticsRules.resourcePath)/\(name.encodeURL())"
}
}
4 changes: 2 additions & 2 deletions Sources/Typesense/AnalyticsRules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public struct AnalyticsRules {
return (nil, response)
}

private func endpointPath(_ operation: String? = nil) -> String {
private func endpointPath(_ operation: String? = nil) throws -> String {
if let operation = operation {
return "\(AnalyticsRules.resourcePath)/\(operation)"
return try "\(AnalyticsRules.resourcePath)/\(operation.encodeURL())"
} else {
return AnalyticsRules.resourcePath
}
Expand Down
10 changes: 6 additions & 4 deletions Sources/Typesense/Collection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import Foundation

public struct Collection {
var apiCall: ApiCall
let RESOURCEPATH = "collections"

var collectionName: String

init(apiCall: ApiCall, collectionName: String) {
Expand All @@ -24,7 +22,7 @@ public struct Collection {
}

public func delete() async throws -> (CollectionResponse?, URLResponse?) {
let (data, response) = try await apiCall.delete(endPoint: "\(RESOURCEPATH)/\(collectionName)")
let (data, response) = try await apiCall.delete(endPoint: endpointPath())
if let result = data {
let fetchedCollection = try decoder.decode(CollectionResponse.self, from: result)
return (fetchedCollection, response)
Expand All @@ -33,7 +31,7 @@ public struct Collection {
}

public func retrieve() async throws -> (CollectionResponse?, URLResponse?) {
let (data, response) = try await apiCall.get(endPoint: "\(RESOURCEPATH)/\(collectionName)")
let (data, response) = try await apiCall.get(endPoint: endpointPath())
if let result = data {
let fetchedCollection = try decoder.decode(CollectionResponse.self, from: result)
return (fetchedCollection, response)
Expand All @@ -52,4 +50,8 @@ public struct Collection {
public func override(_ overrideId: String) -> Override{
return Override(apiCall: self.apiCall, collectionName: self.collectionName, overrideId: overrideId)
}

private func endpointPath() throws -> String {
return "\(Collections.RESOURCEPATH)/\(try collectionName.encodeURL())"
}
}
11 changes: 6 additions & 5 deletions Sources/Typesense/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,30 @@ public struct Document {
var apiCall: ApiCall
var collectionName: String
var id: String
let RESOURCEPATH: String

init(apiCall: ApiCall, collectionName: String, id: String) {
self.apiCall = apiCall
self.collectionName = collectionName
self.id = id
self.RESOURCEPATH = "collections/\(collectionName)/documents"
}

public func delete() async throws -> (Data?, URLResponse?) {
let (data, response) = try await apiCall.delete(endPoint: "\(RESOURCEPATH)/\(self.id)")
let (data, response) = try await apiCall.delete(endPoint: endpointPath())
return (data, response)
}

public func retrieve() async throws -> (Data?, URLResponse?) {
let (data, response) = try await apiCall.get(endPoint: "\(RESOURCEPATH)/\(self.id)")
let (data, response) = try await apiCall.get(endPoint: endpointPath())
return (data, response)
}

public func update(newDocument: Data, options: DocumentIndexParameters? = nil) async throws -> (Data?, URLResponse?) {
let queryParams = try createURLQuery(forSchema: options)
let (data, response) = try await apiCall.patch(endPoint: "\(RESOURCEPATH)/\(self.id)", body: newDocument, queryParameters: queryParams)
let (data, response) = try await apiCall.patch(endPoint: endpointPath(), body: newDocument, queryParameters: queryParams)
return (data, response)
}

private func endpointPath() throws -> String {
return try "\(Collections.RESOURCEPATH)/\(collectionName.encodeURL())/documents/\(id.encodeURL())"
}
}
33 changes: 20 additions & 13 deletions Sources/Typesense/Documents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,30 @@ import Foundation
public struct Documents {
var apiCall: ApiCall
var collectionName: String
let RESOURCEPATH: String

init(apiCall: ApiCall, collectionName: String) {
self.apiCall = apiCall
self.collectionName = collectionName
self.RESOURCEPATH = "collections/\(collectionName)/documents"
}

public func create(document: Data, options: DocumentIndexParameters? = nil) async throws -> (Data?, URLResponse?) {
let queryParams = try createURLQuery(forSchema: options)
let (data, response) = try await apiCall.post(endPoint: RESOURCEPATH, body: document, queryParameters: queryParams)
let (data, response) = try await apiCall.post(endPoint: endpointPath(), body: document, queryParameters: queryParams)
return (data, response)
}

public func upsert(document: Data, options: DocumentIndexParameters? = nil) async throws -> (Data?, URLResponse?) {
var queryParams = try createURLQuery(forSchema: options)
queryParams.append(URLQueryItem(name: "action", value: "upsert"))
let (data, response) = try await apiCall.post(endPoint: RESOURCEPATH, body: document, queryParameters: queryParams)
let (data, response) = try await apiCall.post(endPoint: endpointPath(), body: document, queryParameters: queryParams)
return (data, response)
}

public func update<T: Codable>(document: T, options: DocumentIndexParameters? = nil) async throws -> (T?, URLResponse?) {
var queryParams = try createURLQuery(forSchema: options)
queryParams.append(URLQueryItem(name: "action", value: "update"))
let jsonData = try encoder.encode(document)
let (data, response) = try await apiCall.post(endPoint: RESOURCEPATH, body: jsonData, queryParameters: queryParams)
let (data, response) = try await apiCall.post(endPoint: endpointPath(), body: jsonData, queryParameters: queryParams)
if let validData = data {
let decodedData = try decoder.decode(T.self, from: validData)
return (decodedData, response)
Expand All @@ -43,7 +41,7 @@ public struct Documents {
public func update<T: Encodable>(document: T, options: UpdateDocumentsByFilterParameters) async throws -> (UpdateByFilterResponse?, URLResponse?) {
let queryParams = try createURLQuery(forSchema: options)
let jsonData = try encoder.encode(document)
let (data, response) = try await apiCall.patch(endPoint: RESOURCEPATH, body: jsonData, queryParameters: queryParams)
let (data, response) = try await apiCall.patch(endPoint: endpointPath(), body: jsonData, queryParameters: queryParams)
if let validData = data {
let decodedData = try decoder.decode(UpdateByFilterResponse.self, from: validData)
return (decodedData, response)
Expand All @@ -53,7 +51,7 @@ public struct Documents {

public func delete(options: DeleteDocumentsParameters) async throws -> (DeleteDocumentsResponse?, URLResponse?) {
let queryParams = try createURLQuery(forSchema: options)
let (data, response) = try await apiCall.delete(endPoint: "\(RESOURCEPATH)", queryParameters: queryParams)
let (data, response) = try await apiCall.delete(endPoint: endpointPath(), queryParameters: queryParams)
if let validData = data {
let decodedData = try decoder.decode(DeleteDocumentsResponse.self, from: validData)
return (decodedData, response)
Expand All @@ -70,14 +68,14 @@ public struct Documents {
if let givenBatchSize = batchSize {
deleteQueryParams.append(URLQueryItem(name: "batch_size", value: String(givenBatchSize)))
}
let (data, response) = try await apiCall.delete(endPoint: "\(RESOURCEPATH)", queryParameters: deleteQueryParams)
let (data, response) = try await apiCall.delete(endPoint: endpointPath(), queryParameters: deleteQueryParams)
return (data, response)

}

public func search(_ searchParameters: SearchParameters) async throws -> (Data?, URLResponse?) {
let queryParams = try createURLQuery(forSchema: searchParameters)
return try await apiCall.get(endPoint: "\(RESOURCEPATH)/search", queryParameters: queryParams)
return try await apiCall.get(endPoint: endpointPath("search"), queryParameters: queryParams)
}

public func search<T>(_ searchParameters: SearchParameters, for: T.Type) async throws -> (SearchResult<T>?, URLResponse?) {
Expand Down Expand Up @@ -307,7 +305,7 @@ public struct Documents {
searchQueryParams.append(URLQueryItem(name: "facet_strategy", value: facetReturnParent))
}

let (data, response) = try await apiCall.get(endPoint: "\(RESOURCEPATH)/search", queryParameters: searchQueryParams)
let (data, response) = try await apiCall.get(endPoint: endpointPath("search"), queryParameters: searchQueryParams)

if let validData = data {
let searchRes = try decoder.decode(SearchResult<T>.self, from: validData)
Expand All @@ -319,7 +317,7 @@ public struct Documents {

public func importBatch(_ documents: Data, options: ImportDocumentsParameters) async throws -> (Data?, URLResponse?) {
let queryParams = try createURLQuery(forSchema: options)
let (data, response) = try await apiCall.post(endPoint: "\(RESOURCEPATH)/import", body: documents, queryParameters: queryParams)
let (data, response) = try await apiCall.post(endPoint: endpointPath("import"), body: documents, queryParameters: queryParams)
return (data, response)
}

Expand All @@ -329,13 +327,22 @@ public struct Documents {
if let specifiedAction = action {
importAction.value = specifiedAction.rawValue
}
let (data, response) = try await apiCall.post(endPoint: "\(RESOURCEPATH)/import", body: documents, queryParameters: [importAction])
let (data, response) = try await apiCall.post(endPoint: endpointPath("import"), body: documents, queryParameters: [importAction])
return (data, response)
}

public func export(options: ExportDocumentsParameters? = nil) async throws -> (Data?, URLResponse?) {
let searchQueryParams = try createURLQuery(forSchema: options)
let (data, response) = try await apiCall.get(endPoint: "\(RESOURCEPATH)/export", queryParameters: searchQueryParams)
let (data, response) = try await apiCall.get(endPoint: endpointPath("export"), queryParameters: searchQueryParams)
return (data, response)
}

private func endpointPath(_ operation: String? = nil) throws -> String {
let baseEndpoint = try "collections/\(collectionName.encodeURL())/documents"
if let operation: String = operation {
return "\(baseEndpoint)/\(operation)"
} else {
return baseEndpoint
}
}
}
1 change: 1 addition & 0 deletions Sources/Typesense/Errors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extension HTTPError: LocalizedError {

public enum URLError: Error {
case invalidURL
case encodingError(message: String)
}

public enum DataError: Error {
Expand Down
4 changes: 2 additions & 2 deletions Sources/Typesense/Override.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public struct Override {
return (nil, response)
}

private func endpointPath() -> String {
return "\(Collections.RESOURCEPATH)/\(collectionName)/\(Overrides.RESOURCEPATH)/\(overrideId)"
private func endpointPath() throws -> String {
return try "\(Collections.RESOURCEPATH)/\(collectionName.encodeURL())/\(Overrides.RESOURCEPATH)/\(overrideId.encodeURL())"
}


Expand Down
6 changes: 3 additions & 3 deletions Sources/Typesense/Overrides.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public struct Overrides {
return (nil, nil)
}

private func endpointPath(_ operation: String? = nil) -> String {
let baseEndpoint = "\(Collections.RESOURCEPATH)/\(collectionName)/\(Overrides.RESOURCEPATH)"
private func endpointPath(_ operation: String? = nil) throws -> String {
let baseEndpoint = try "\(Collections.RESOURCEPATH)/\(collectionName.encodeURL())/\(Overrides.RESOURCEPATH)"
if let operation = operation {
return "\(baseEndpoint)/\(operation)"
return try "\(baseEndpoint)/\(operation.encodeURL())"
} else {
return baseEndpoint
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Typesense/Preset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public struct Preset {
return (nil, response)
}

private func endpointPath() -> String {
return "\(Presets.RESOURCEPATH)/\(presetName)"
private func endpointPath() throws -> String {
return try "\(Presets.RESOURCEPATH)/\(presetName.encodeURL())"
}


Expand Down
4 changes: 2 additions & 2 deletions Sources/Typesense/Presets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public struct Presets {
return (nil, response)
}

private func endpointPath(_ operation: String? = nil) -> String {
private func endpointPath(_ operation: String? = nil) throws -> String {
let baseEndpoint = "\(Presets.RESOURCEPATH)"
if let operation = operation {
return "\(baseEndpoint)/\(operation)"
return try "\(baseEndpoint)/\(operation.encodeURL())"
} else {
return baseEndpoint
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Typesense/Stopword.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public struct Stopword {
return (nil, response)
}

private func endpointPath() -> String {
return "\(Stopwords.RESOURCEPATH)/\(stopwordsSetId)"
private func endpointPath() throws -> String {
return try "\(Stopwords.RESOURCEPATH)/\(stopwordsSetId.encodeURL())"
}


Expand Down
4 changes: 2 additions & 2 deletions Sources/Typesense/Stopwords.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ public struct Stopwords {
return (nil, response)
}

private func endpointPath(_ operation: String? = nil) -> String {
private func endpointPath(_ operation: String? = nil) throws -> String {
let baseEndpoint = "\(Stopwords.RESOURCEPATH)"
if let operation = operation {
return "\(baseEndpoint)/\(operation)"
return try "\(baseEndpoint)/\(operation.encodeURL())"
} else {
return baseEndpoint
}
Expand Down
Loading

0 comments on commit c3be915

Please sign in to comment.