Skip to content

Commit

Permalink
chore: resolve swiftlint errors and warnings for Amplify API plugin (#…
Browse files Browse the repository at this point in the history
…3441)

* chore: resolve swiftlint errors

* chore: resolve swiftlint warnings

* chore: resolve swiftlint warnings
  • Loading branch information
phantumcode authored Jan 3, 2024
1 parent cf7fd9e commit 8f12e40
Show file tree
Hide file tree
Showing 18 changed files with 87 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func query<R: Decodable>(request: GraphQLRequest<R>) async throws -> GraphQLTask<R>.Success {
let operation = AWSGraphQLOperation(request: request.toOperationRequest(operationType: .query),
session: session,
Expand All @@ -41,7 +41,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func mutate<R: Decodable>(request: GraphQLRequest<R>) async throws -> GraphQLTask<R>.Success {
let operation = AWSGraphQLOperation(request: request.toOperationRequest(operationType: .mutation),
session: session,
Expand Down Expand Up @@ -69,7 +69,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func subscribe<R>(request: GraphQLRequest<R>) -> AmplifyAsyncThrowingSequence<GraphQLSubscriptionEvent<R>> {
let request = request.toOperationRequest(operationType: .subscription)
let runner = AWSGraphQLSubscriptionTaskRunner(request: request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func get(request: RESTRequest) async throws -> RESTTask.Success {
let operationRequest = RESTOperationRequest(request: request,
operationType: .get)
Expand Down Expand Up @@ -52,7 +52,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func put(request: RESTRequest) async throws -> RESTTask.Success {
let operationRequest = RESTOperationRequest(request: request,
operationType: .put)
Expand Down Expand Up @@ -81,7 +81,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func post(request: RESTRequest) async throws -> RESTTask.Success {
let operationRequest = RESTOperationRequest(request: request,
operationType: .post)
Expand Down Expand Up @@ -109,7 +109,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func patch(request: RESTRequest) async throws -> RESTTask.Success {
let operationRequest = RESTOperationRequest(request: request, operationType: .patch)

Expand Down Expand Up @@ -137,7 +137,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func delete(request: RESTRequest) async throws -> RESTTask.Success {
let operationRequest = RESTOperationRequest(request: request,
operationType: .delete)
Expand Down Expand Up @@ -166,7 +166,7 @@ public extension AWSAPIPlugin {
queue.addOperation(operation)
return operation
}

func head(request: RESTRequest) async throws -> RESTTask.Success {
let operationRequest = RESTOperationRequest(request: request,
operationType: .head)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ public struct AppSyncListDecoder: ModelListDecoder {
let appSyncAssociatedFields: [String]
let apiName: String?
}

/// Used by the custom decoder implemented in the `List` type to detect if the payload can be
/// decoded to an AppSyncListProvider.
public static func decode<ModelType: Model>(modelType: ModelType.Type, decoder: Decoder) -> AnyModelListProvider<ModelType>? {
self.shouldDecodeToAppSyncListProvider(modelType: modelType, decoder: decoder)?.eraseToAnyModelListProvider()
}

static func shouldDecodeToAppSyncListProvider<ModelType: Model>(modelType: ModelType.Type, decoder: Decoder) -> AppSyncListProvider<ModelType>? {
if let listPayload = try? AppSyncListPayload.init(from: decoder) {
log.verbose("Creating loaded list of \(modelType.modelName)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
return .loaded(elements)
}
}

public func load() async throws -> [Element] {
switch loadedState {
case .loaded(let elements, _, _):
Expand All @@ -101,7 +101,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
return try await load(associatedIdentifiers: associatedIdentifiers, associatedFields: associatedFields)
}
}

//// Internal `load` to perform the retrieval of the first page and storing it in memory
func load(associatedIdentifiers: [String],
associatedFields: [String]) async throws -> [Element] {
Expand All @@ -113,7 +113,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
filter = predicate.graphQLFilter(for: Element.schema)
} else {
var queryPredicates: [QueryPredicateOperation] = []

let columnNames = columnNames(fields: associatedFields, Element.schema)
let predicateValues = zip(columnNames, associatedIdentifiers)
for (identifierName, identifierValue) in predicateValues {
Expand All @@ -123,8 +123,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
let groupedQueryPredicates = QueryPredicateGroup(type: .and, predicates: queryPredicates)
filter = groupedQueryPredicates.graphQLFilter(for: Element.schema)
}



let request = GraphQLRequest<JSONValue>.listQuery(responseType: JSONValue.self,
modelSchema: Element.schema,
filter: filter,
Expand All @@ -142,7 +141,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
AWSAppSyncListResponse from: \(graphQLData)
""", "", nil)
}

self.loadedState = .loaded(elements: listResponse.items,
nextToken: listResponse.nextToken,
filter: filter)
Expand All @@ -163,7 +162,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
throw error
}
}

public func hasNextPage() -> Bool {
switch loadedState {
case .loaded(_, let nextToken, _):
Expand All @@ -172,7 +171,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
return false
}
}

public func getNextPage() async throws -> List<Element> {
guard case .loaded(_, let nextTokenOptional, let filter) = loadedState else {
throw CoreError.clientValidation("""
Expand Down Expand Up @@ -219,7 +218,7 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
throw error
}
}

public func encode(to encoder: Encoder) throws {
switch loadedState {
case .notLoaded(let associatedIdentifiers, let associatedFields):
Expand All @@ -239,9 +238,9 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
try elements.encode(to: encoder)
}
}

// MARK: - Helpers

/// Retrieve the column names for the specified field `field` for this schema.
func columnNames(fields: [String], _ modelSchema: ModelSchema) -> [String] {
// Associated field names have already been resolved from the parent model's has-many targetNames
Expand All @@ -257,14 +256,14 @@ public class AppSyncListProvider<Element: Model>: ModelListProvider {
case .belongsTo(_, let targetNames), .hasOne(_, let targetNames):
guard !targetNames.isEmpty else {
return [defaultFieldName]

}
return targetNames
default:
return fields
}
}

}

extension AppSyncListProvider: DefaultLogger {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ import Amplify
/// inside an `AppSyncModelProvider` when decoding to the `LazyReference` as a "not yet loaded" Reference. If the data payload
/// can be decoded to the Model, then the model provider is created as a "loaded" reference.
public struct AppSyncModelDecoder: ModelProviderDecoder {

public static let AppSyncSource = "AppSync"

/// Metadata that contains metadata of a model, specifically the identifiers used to hydrate the model.
struct Metadata: Codable {
let identifiers: [LazyReferenceIdentifier]
let apiName: String?
let source: String

init(identifiers: [LazyReferenceIdentifier], apiName: String?, source: String = AppSyncSource) {
self.identifiers = identifiers
self.apiName = apiName
self.source = source
}
}

public static func decode<ModelType: Model>(modelType: ModelType.Type, decoder: Decoder) -> AnyModelProvider<ModelType>? {
if let metadata = try? Metadata(from: decoder) {
if metadata.source == AppSyncSource {
Expand All @@ -37,12 +37,12 @@ public struct AppSyncModelDecoder: ModelProviderDecoder {
return nil
}
}

if let model = try? ModelType.init(from: decoder) {
log.verbose("Creating loaded model \(model)")
return AppSyncModelProvider(model: model).eraseToAnyModelProvider()
}

return nil
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

/// Holds the methods to traverse and maniupulate the response data object by injecting
public struct AppSyncModelMetadataUtils {

// A fairly light check to make sure the payload is an object and we have the schema for `addMetadata`.
// Note: `addMetadata` should be very tightly checking the associated fields to determine when it should add
// metadata. Do we still need to do this anymore?
Expand Down Expand Up @@ -65,12 +65,12 @@ public struct AppSyncModelMetadataUtils {
encoder.dateEncodingStrategy = ModelDateFormatting.encodingStrategy
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = ModelDateFormatting.decodingStrategy

// Iterate over the associations of the model and for each association, either create the identifier metadata
// for lazy loading belongs-to or create the model association metadata for lazy loading has-many.
// The metadata gets decoded to the LazyReference and List implementations respectively.
for modelField in modelSchema.fields.values {

// Scenario: Belongs-to associations. For the current `modelField` that is a belongs-to association,
// retrieve the data and attempt to decode to the association's modelType. If it can be decoded,
// this means it is eager loaded and does not need to be lazy loaded. If it cannot, extract the
Expand All @@ -81,7 +81,7 @@ public struct AppSyncModelMetadataUtils {
case .object(let modelObject) = nestedModelJSON,
let associatedModelName = modelField.associatedModelName,
let associatedModelType = ModelRegistry.modelType(from: associatedModelName) {

// Scenario: Belongs-To Primary Keys only are available for lazy loading
if let modelIdentifierMetadata = createModelIdentifierMetadata(associatedModelType,
modelObject: modelObject,
Expand All @@ -105,11 +105,11 @@ public struct AppSyncModelMetadataUtils {
}
// otherwise do nothing to the data.
}

// Scenario: Has-Many eager loaded or empty payloads.
if modelField.isArray && modelField.hasAssociation,
let associatedModelName = modelField.associatedModelName {

// Scenario: Has-many items array is missing.
// Store the association data (parent's identifier and field name)
// This allows the list to perform lazy loading of child items using parent identifier as the predicate
Expand All @@ -127,25 +127,25 @@ public struct AppSyncModelMetadataUtils {
""")
}
}

// Scenario: Has-Many items array is eager loaded as `nestedModelJSON`
// If the model types allow for lazy loading, inject the metadata at each item of `nestedModelJSON`
else if let nestedModelJSON = modelJSON[modelField.name],
case .object(var graphQLDataObject) = nestedModelJSON,
case .array(var graphQLDataArray) = graphQLDataObject["items"],
let associatedModelType = ModelRegistry.modelType(from: associatedModelName),
associatedModelType.rootPath != nil {

for (index, item) in graphQLDataArray.enumerated() {
let modelJSON = AppSyncModelMetadataUtils.addMetadata(toModel: item, apiName: apiName)
graphQLDataArray[index] = modelJSON
}

graphQLDataObject["items"] = JSONValue.array(graphQLDataArray)
let payload = AppSyncListPayload(graphQLData: JSONValue.object(graphQLDataObject),
apiName: apiName,
variables: nil)

if let serializedPayload = try? encoder.encode(payload),
let payloadJSON = try? decoder.decode(JSONValue.self, from: serializedPayload) {
log.verbose("Adding [\(modelField.name): \(payloadJSON)]")
Expand All @@ -159,7 +159,7 @@ public struct AppSyncModelMetadataUtils {

return JSONValue.object(modelJSON)
}

/// Extract the identifiers from the `modelObject`. The number of identifiers extracted compared to the number of
/// fields on the `modelObject` is useful determining if the `modelOject` is eager or lazy loaded. If the identifiers
/// plus one additional field (`__typename`) doesn't match the number of keys on the `modelObject` then there
Expand All @@ -185,7 +185,7 @@ public struct AppSyncModelMetadataUtils {
return nil
}
}

/// Retrieve just the identifiers from the current model. These identifiers are later used
/// for creating `AppSyncListDecoder.Metadata` payloads for decoding.
static func retrieveIdentifiers(_ modelJSON: [String: JSONValue], _ schema: ModelSchema) -> [String]? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,27 @@ import Amplify
import AWSPluginsCore

public class AppSyncModelProvider<ModelType: Model>: ModelProvider {

let apiName: String?

var loadedState: ModelProviderState<ModelType>

// Creates a "not loaded" provider
init(metadata: AppSyncModelDecoder.Metadata) {
self.loadedState = .notLoaded(identifiers: metadata.identifiers)
self.apiName = metadata.apiName
}

// Creates a "loaded" provider
init(model: ModelType?) {
self.loadedState = .loaded(model: model)
self.apiName = nil
}

// MARK: - APIs

public func load() async throws -> ModelType? {

switch loadedState {
case .notLoaded(let identifiers):
guard let identifiers = identifiers else {
Expand All @@ -54,11 +54,11 @@ public class AppSyncModelProvider<ModelType: Model>: ModelProvider {
return element
}
}

public func getState() -> ModelProviderState<ModelType> {
loadedState
}

public func encode(to encoder: Encoder) throws {
switch loadedState {
case .notLoaded(let identifiers):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class AuthTokenProviderWrapper: AuthTokenProvider {
init(tokenAuthProvider: AmplifyAuthTokenProvider) {
self.wrappedAuthTokenProvider = tokenAuthProvider
}

func getUserPoolAccessToken() async throws -> String {
try await wrappedAuthTokenProvider.getLatestAuthToken()
}
Expand Down
Loading

0 comments on commit 8f12e40

Please sign in to comment.