UNPKG

@aws-amplify/amplify-category-api

Version:
108 lines (99 loc) 4.38 kB
import { ConflictResolution, PerModelResolutionstrategy, ResolutionStrategy, LambdaResolutionStrategy } from 'amplify-headless-interface'; import { ResolverConfig, SyncConfig, ConflictHandlerType, SyncConfigLAMBDA } from 'graphql-transformer-core'; import _ from 'lodash'; export const conflictResolutionToResolverConfig = (conflictResolution: ConflictResolution = {}): ResolverConfig => { const result: ResolverConfig = {}; if (_.isEmpty(conflictResolution)) return undefined; if (conflictResolution.defaultResolutionStrategy) { result.project = resolutionStrategyToSyncConfig(conflictResolution.defaultResolutionStrategy); } if (conflictResolution.perModelResolutionStrategy) { result.models = modelSyncConfigTransformer(conflictResolution.perModelResolutionStrategy); } return result; }; export const resolverConfigToConflictResolution = (resolverConfig: ResolverConfig = {}): ConflictResolution => { const result: ConflictResolution = {}; if (resolverConfig.project) { result.defaultResolutionStrategy = syncConfigToResolutionStrategy(resolverConfig.project); } if (resolverConfig.models) { result.perModelResolutionStrategy = modelResolutionStrategyTransformer(resolverConfig.models); } return result; }; const modelSyncConfigTransformer = (perModelResolutionStrategy: PerModelResolutionstrategy[]): { [key: string]: SyncConfig } => { const result: { [key: string]: SyncConfig } = {}; perModelResolutionStrategy.forEach( (strategy) => (result[strategy.entityName] = resolutionStrategyToSyncConfig(strategy.resolutionStrategy)), ); return result; }; const modelResolutionStrategyTransformer = (modelSyncConfig: { [key: string]: SyncConfig }): PerModelResolutionstrategy[] => { const result: PerModelResolutionstrategy[] = []; Object.entries(modelSyncConfig) .map( ([key, value]): PerModelResolutionstrategy => ({ resolutionStrategy: syncConfigToResolutionStrategy(value), entityName: key, }), ) .forEach((modelStrategy) => result.push(modelStrategy)); return result; }; const resolutionStrategyToSyncConfig = (resolutionStrategy: ResolutionStrategy, newFunctionMap?: Record<string, string>): SyncConfig => { const defaultMapper = () => undefined; return _.get(resolutionStrategyToSyncConfigMap, resolutionStrategy.type, defaultMapper)(resolutionStrategy); }; const resolutionStrategyToSyncConfigMap: Record<string, (rs: ResolutionStrategy) => SyncConfig> = { AUTOMERGE: () => ({ ConflictHandler: ConflictHandlerType.AUTOMERGE, ConflictDetection: 'VERSION', }), OPTIMISTIC_CONCURRENCY: () => ({ ConflictHandler: ConflictHandlerType.OPTIMISTIC, ConflictDetection: 'VERSION', }), LAMBDA: (resolutionStrategy: LambdaResolutionStrategy) => { switch (resolutionStrategy.resolver.type) { case 'EXISTING': { const { name, region, arn } = resolutionStrategy.resolver; return { ConflictHandler: ConflictHandlerType.LAMBDA, ConflictDetection: 'VERSION', LambdaConflictHandler: { name, region, lambdaArn: arn }, }; } case 'NEW': throw new Error( 'Tried to convert LambdaResolutionStrategy "NEW" to SyncConfig. New resources must be generated prior to this conversion and then replaced with a LambdaResolutionStrategy of type "EXISTING"', ); } }, }; const syncConfigToResolutionStrategy = (syncConfig: SyncConfig): ResolutionStrategy => { const defaultMapper = (): ResolutionStrategy => ({ type: 'NONE' }); return _.get(syncConfigToResolutionStrategyMap, syncConfig.ConflictHandler, defaultMapper)(syncConfig); }; const syncConfigToResolutionStrategyMap: Record<ConflictHandlerType, (sc: SyncConfig) => ResolutionStrategy> = { AUTOMERGE: () => ({ type: 'AUTOMERGE', }), OPTIMISTIC_CONCURRENCY: () => ({ type: 'OPTIMISTIC_CONCURRENCY', }), LAMBDA: (syncConfig: SyncConfigLAMBDA) => ({ type: 'LAMBDA', resolver: (syncConfig.LambdaConflictHandler as any).new ? { // this is a hack to pass the "new" flag into the ResolutionStrategy type: 'NEW', } : { type: 'EXISTING', name: syncConfig.LambdaConflictHandler.name, region: syncConfig.LambdaConflictHandler.region, arn: syncConfig.LambdaConflictHandler.lambdaArn, }, }), };