Skip to content

fix(API): pass authMode used for lazy loading functionality #3690

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Foundation
import Amplify
import AWSPluginsCore

/// This decoder is registered and used to detect various data payloads objects to store
/// inside an AppSyncListProvider when decoding to the Lazy `List` type as a "not yet loaded" List. If the data payload
Expand All @@ -18,6 +19,7 @@ public struct AppSyncListDecoder: ModelListDecoder {
let appSyncAssociatedIdentifiers: [String]
let appSyncAssociatedFields: [String]
let apiName: String?
let authMode: AWSAuthorizationType?
}

/// Used by the custom decoder implemented in the `List` type to detect if the payload can be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ public struct AppSyncListPayload: Codable {

let graphQLData: JSONValue
let apiName: String?
let authMode: AWSAuthorizationType?

public init(graphQLData: JSONValue,
apiName: String?,
authMode: AWSAuthorizationType?,
variables: [String: JSONValue]?) {
self.apiName = apiName
self.authMode = authMode
self.variables = variables
self.graphQLData = graphQLData
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
/// The API friendly name used to reference the API to call
let apiName: String?

/// The auth mode used for this API call
let authMode: AWSAuthorizationType?

/// The limit for each page size
var limit: Int? = 1_000

Expand Down Expand Up @@ -42,7 +45,8 @@
convenience init(payload: AppSyncListPayload) throws {
let listResponse = try AppSyncListResponse.initWithMetadata(type: Element.self,
graphQLData: payload.graphQLData,
apiName: payload.apiName)
apiName: payload.apiName,
authMode: payload.authMode)

self.init(elements: listResponse.items,
nextToken: listResponse.nextToken,
Expand All @@ -59,27 +63,34 @@
convenience init(metadata: AppSyncListDecoder.Metadata) {
self.init(associatedIdentifiers: metadata.appSyncAssociatedIdentifiers,
associatedFields: metadata.appSyncAssociatedFields,
apiName: metadata.apiName)
apiName: metadata.apiName,
authMode: metadata.authMode)
}

// Internal initializer for testing
init(elements: [Element],
nextToken: String? = nil,
apiName: String? = nil,
authMode: AWSAuthorizationType? = nil,
limit: Int? = nil,
filter: [String: Any]? = nil) {
self.loadedState = .loaded(elements: elements,
nextToken: nextToken,
filter: filter)
self.apiName = apiName
self.authMode = authMode
self.limit = limit
}

// Internal initializer for testing
init(associatedIdentifiers: [String], associatedFields: [String], apiName: String? = nil) {
init(associatedIdentifiers: [String],
associatedFields: [String],
apiName: String? = nil,
authMode: AWSAuthorizationType? = nil) {
self.loadedState = .notLoaded(associatedIdentifiers: associatedIdentifiers,
associatedFields: associatedFields)
self.apiName = apiName
self.authMode = authMode
}

// MARK: APIs
Expand Down Expand Up @@ -128,14 +139,16 @@
modelSchema: Element.schema,
filter: filter,
limit: limit,
apiName: apiName)
apiName: apiName,
authMode: authMode)
do {
let graphQLResponse = try await Amplify.API.query(request: request)
switch graphQLResponse {
case .success(let graphQLData):
guard let listResponse = try? AppSyncListResponse.initWithMetadata(type: Element.self,
graphQLData: graphQLData,
apiName: self.apiName) else {
apiName: self.apiName,
authMode: self.authMode) else {
throw CoreError.listOperation("""
The AppSync response return successfully, but could not decode to
AWSAppSyncListResponse from: \(graphQLData)
Expand Down Expand Up @@ -196,7 +209,8 @@
filter: filter,
limit: limit,
nextToken: nextToken,
apiName: apiName)
apiName: apiName,
authMode: authMode)
do {
let graphQLResponse = try await Amplify.API.query(request: request)
switch graphQLResponse {
Expand Down Expand Up @@ -225,7 +239,8 @@
let metadata = AppSyncListDecoder.Metadata.init(
appSyncAssociatedIdentifiers: associatedIdentifiers,
appSyncAssociatedFields: associatedFields,
apiName: apiName)
apiName: apiName,
authMode: authMode)

Check warning on line 243 in AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncListProvider.swift

View check run for this annotation

Codecov / codecov/patch

AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncListProvider.swift#L242-L243

Added lines #L242 - L243 were not covered by tests
var container = encoder.singleValueContainer()
try container.encode(metadata)
case .loaded(let elements, _, _):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Amplify
import Foundation
import AWSPluginsCore

/// Resembles the AppSync's GraphQL response for a list operation.
struct AppSyncListResponse<Element: Model>: Codable {
Expand All @@ -25,10 +26,14 @@ extension AppSyncListResponse {
/// model metadata on its array associations.
static func initWithMetadata(type: Element.Type,
graphQLData: JSONValue,
apiName: String?) throws -> AppSyncListResponse<Element> {
apiName: String?,
authMode: AWSAuthorizationType?) throws -> AppSyncListResponse<Element> {
var elements = [Element]()
if case let .array(jsonArray) = graphQLData["items"] {
let jsonArrayWithMetadata = AppSyncModelMetadataUtils.addMetadata(toModelArray: jsonArray, apiName: apiName)
let jsonArrayWithMetadata = AppSyncModelMetadataUtils.addMetadata(
toModelArray: jsonArray,
apiName: apiName,
authMode: authMode)

let encoder = JSONEncoder()
encoder.dateEncodingStrategy = ModelDateFormatting.encodingStrategy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Foundation
import Amplify
import AWSPluginsCore

/// This decoder is registered and used to detect various data payloads to store
/// inside an `AppSyncModelProvider` when decoding to the `LazyReference` as a "not yet loaded" Reference. If the data payload
Expand All @@ -17,11 +18,16 @@ public struct AppSyncModelDecoder: ModelProviderDecoder {
struct Metadata: Codable {
let identifiers: [LazyReferenceIdentifier]
let apiName: String?
let authMode: AWSAuthorizationType?
let source: String

init(identifiers: [LazyReferenceIdentifier], apiName: String?, source: String = ModelProviderRegistry.DecoderSource.appSync) {
init(identifiers: [LazyReferenceIdentifier],
apiName: String?,
authMode: AWSAuthorizationType?,
source: String = ModelProviderRegistry.DecoderSource.appSync) {
self.identifiers = identifiers
self.apiName = apiName
self.authMode = authMode
self.source = source
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import Amplify
import Foundation
import AWSPluginsCore

/// Holds the methods to traverse and maniupulate the response data object by injecting
public struct AppSyncModelMetadataUtils {
Expand All @@ -25,15 +26,17 @@
}

static func addMetadata(toModelArray graphQLDataArray: [JSONValue],
apiName: String?) -> [JSONValue] {
apiName: String?,
authMode: AWSAuthorizationType?) -> [JSONValue] {
return graphQLDataArray.map { (graphQLData) -> JSONValue in
addMetadata(toModel: graphQLData, apiName: apiName)
addMetadata(toModel: graphQLData, apiName: apiName, authMode: authMode)
}
}

static func addMetadata(
toModel graphQLData: JSONValue,
apiName: String?,
authMode: AWSAuthorizationType?,
source: String = ModelProviderRegistry.DecoderSource.appSync) -> JSONValue {

guard case var .object(modelJSON) = graphQLData else {
Expand Down Expand Up @@ -89,6 +92,7 @@
if let modelIdentifierMetadata = createModelIdentifierMetadata(associatedModelType,
modelObject: modelObject,
apiName: apiName,
authMode: authMode,
source: source) {
if let serializedMetadata = try? encoder.encode(modelIdentifierMetadata),
let metadataJSON = try? decoder.decode(JSONValue.self, from: serializedMetadata) {
Expand All @@ -104,7 +108,9 @@
// add metadata to its fields, to create not loaded LazyReference objects
// only if the model type allowsfor lazy loading functionality
else if associatedModelType.rootPath != nil {
let nestedModelWithMetadata = addMetadata(toModel: nestedModelJSON, apiName: apiName)
let nestedModelWithMetadata = addMetadata(toModel: nestedModelJSON,
apiName: apiName,
authMode: authMode)

Check warning on line 113 in AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelMetadata.swift

View check run for this annotation

Codecov / codecov/patch

AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelMetadata.swift#L111-L113

Added lines #L111 - L113 were not covered by tests
modelJSON.updateValue(nestedModelWithMetadata, forKey: modelField.name)
}
// otherwise do nothing to the data.
Expand All @@ -120,7 +126,8 @@
if modelJSON[modelField.name] == nil {
let appSyncModelMetadata = AppSyncListDecoder.Metadata(appSyncAssociatedIdentifiers: identifiers,
appSyncAssociatedFields: modelField.associatedFieldNames,
apiName: apiName)
apiName: apiName,
authMode: authMode)
if let serializedMetadata = try? encoder.encode(appSyncModelMetadata),
let metadataJSON = try? decoder.decode(JSONValue.self, from: serializedMetadata) {
log.verbose("Adding [\(modelField.name): \(metadataJSON)]")
Expand All @@ -141,13 +148,16 @@
associatedModelType.rootPath != nil {

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

Check warning on line 153 in AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelMetadata.swift

View check run for this annotation

Codecov / codecov/patch

AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelMetadata.swift#L151-L153

Added lines #L151 - L153 were not covered by tests
graphQLDataArray[index] = modelJSON
}

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

Check warning on line 160 in AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelMetadata.swift

View check run for this annotation

Codecov / codecov/patch

AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelMetadata.swift#L160

Added line #L160 was not covered by tests
variables: nil)

if let serializedPayload = try? encoder.encode(payload),
Expand All @@ -171,6 +181,7 @@
static func createModelIdentifierMetadata(_ associatedModel: Model.Type,
modelObject: [String: JSONValue],
apiName: String?,
authMode: AWSAuthorizationType?,
source: String) -> AppSyncModelDecoder.Metadata? {
let primarykeys = associatedModel.schema.primaryKey
var identifiers = [LazyReferenceIdentifier]()
Expand All @@ -188,6 +199,7 @@
return AppSyncModelDecoder.Metadata(
identifiers: identifiers,
apiName: apiName,
authMode: authMode,
source: source)
} else {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
public class AppSyncModelProvider<ModelType: Model>: ModelProvider {

let apiName: String?
let authMode: AWSAuthorizationType?
let source: String
var loadedState: ModelProviderState<ModelType>

Expand All @@ -20,12 +21,14 @@
self.loadedState = .notLoaded(identifiers: metadata.identifiers)
self.apiName = metadata.apiName
self.source = metadata.source
self.authMode = metadata.authMode
}

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

Expand All @@ -41,7 +44,8 @@
}
let request = GraphQLRequest<ModelType?>.getRequest(ModelType.self,
byIdentifiers: identifiers,
apiName: apiName)
apiName: apiName,
authMode: authMode)

Check warning on line 48 in AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelProvider.swift

View check run for this annotation

Codecov / codecov/patch

AmplifyPlugins/API/Sources/AWSAPIPlugin/Core/AppSyncModelProvider.swift#L47-L48

Added lines #L47 - L48 were not covered by tests
log.verbose("Loading \(ModelType.modelName) with \(identifiers)")
let graphQLResponse = try await Amplify.API.query(request: request)
switch graphQLResponse {
Expand All @@ -67,6 +71,7 @@
let metadata = AppSyncModelDecoder.Metadata(
identifiers: identifiers ?? [],
apiName: apiName,
authMode: authMode,
source: source)
try metadata.encode(to: encoder)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,26 @@
modelJSON = AppSyncModelMetadataUtils.addMetadata(
toModel: item,
apiName: request.apiName,
authMode: request.authMode as? AWSAuthorizationType,

Check warning on line 55 in AmplifyPlugins/API/Sources/AWSAPIPlugin/Support/Decode/GraphQLResponseDecoder+DecodeData.swift

View check run for this annotation

Codecov / codecov/patch

AmplifyPlugins/API/Sources/AWSAPIPlugin/Support/Decode/GraphQLResponseDecoder+DecodeData.swift#L55

Added line #L55 was not covered by tests
source: ModelProviderRegistry.DecoderSource.dataStore)
} else {
modelJSON = AppSyncModelMetadataUtils.addMetadata(
toModel: item,
apiName: request.apiName)
apiName: request.apiName,
authMode: request.authMode as? AWSAuthorizationType)
}
graphQLDataArray[index] = modelJSON
}
graphQLDataObject["items"] = JSONValue.array(graphQLDataArray)
let payload = AppSyncListPayload(graphQLData: JSONValue.object(graphQLDataObject),
apiName: request.apiName,
authMode: request.authMode as? AWSAuthorizationType,
variables: try getVariablesJSON())
serializedJSON = try encoder.encode(payload)
} else if AppSyncModelMetadataUtils.shouldAddMetadata(toModel: graphQLData) { // 4
let modelJSON = AppSyncModelMetadataUtils.addMetadata(toModel: graphQLData,
apiName: request.apiName)
apiName: request.apiName,
authMode: request.authMode as? AWSAuthorizationType)
serializedJSON = try encoder.encode(modelJSON)
} else { // 5
serializedJSON = try encoder.encode(graphQLData)
Expand Down
Loading
Loading