@aws-amplify/amplify-category-api
Version:
Amplify CLI API Category Plugin
111 lines (100 loc) • 4.54 kB
text/typescript
import * as path from 'path';
import { AmplifyCategories, JSONUtilities, pathManager, ResourceDoesNotExistError, stateManager } from '@aws-amplify/amplify-cli-core';
import { printer } from '@aws-amplify/amplify-prompts';
import * as fs from 'fs-extra';
import { ResolverConfig } from 'graphql-transformer-core';
import _ from 'lodash';
import { v4 as uuid } from 'uuid';
import { AppSyncCLIInputs } from '../service-walkthrough-types/appsync-user-input-types';
import { authConfigToAppSyncAuthType } from './auth-config-to-app-sync-auth-type-bi-di-mapper';
import { resolverConfigToConflictResolution } from './resolver-config-to-conflict-resolution-bi-di-mapper';
type ApiMetaData = {
resourceName: string;
authConfig: any;
resolverConfig: ResolverConfig;
};
export const migrateResourceToSupportOverride = async (resourceName: string) => {
printer.debug('Starting Migration Process');
/**
* backup resource folder
* get parameters.json
* generate and save cliInputs
* return cliInputs
* */
const projectPath = pathManager.findProjectRoot();
if (!projectPath) {
// New project, hence not able to find the amplify dir
throw new Error('Project not initialized');
}
const apiresourceDirPath = pathManager.getResourceDirectoryPath(undefined, AmplifyCategories.API, resourceName);
const backupApiResourceFolder = backup(apiresourceDirPath, projectPath, resourceName);
try {
let resolverConfig = {};
const transformConfig =
JSONUtilities.readJson<any>(path.join(apiresourceDirPath, 'transform.conf.json'), { throwIfNotExist: false }) ?? {};
if (!_.isEmpty(transformConfig) && !_.isEmpty(transformConfig!.ResolverConfig)) {
resolverConfig = transformConfig!.ResolverConfig;
}
const authConfig = stateManager.getMeta()[AmplifyCategories.API][resourceName].output.authConfig;
if (_.isEmpty(authConfig)) {
throw new ResourceDoesNotExistError(
`auth configuration not present for ${resourceName}. Try amplify pull to sync your folder structure`,
);
}
const parameters: ApiMetaData = {
authConfig,
resolverConfig,
resourceName,
};
// convert parameters.json to cli-inputs.json
const cliInputs = generateCliInputs(parameters);
const cliInputsPath = path.join(apiresourceDirPath, 'cli-inputs.json');
JSONUtilities.writeJson(cliInputsPath, cliInputs);
printer.debug('Migration is Successful');
} catch (e) {
printer.error('There was an error migrating your project.');
rollback(apiresourceDirPath, backupApiResourceFolder);
printer.debug('migration operations are rolled back.');
throw e;
} finally {
cleanUp(backupApiResourceFolder);
}
};
function backup(authresourcePath: string, projectPath: string, resourceName: string) {
if (fs.existsSync(authresourcePath)) {
const backupauthResourceDirName = `${resourceName}-BACKUP-${uuid().split('-')[0]}`;
const backupauthResourceDirPath = path.join(projectPath, backupauthResourceDirName);
if (fs.existsSync(backupauthResourceDirPath)) {
const error = new Error(`Backup folder at ${backupauthResourceDirPath} already exists, remove the folder and retry the operation.`);
error.name = 'BackupFolderAlreadyExist';
error.stack = undefined;
throw error;
}
fs.copySync(authresourcePath, backupauthResourceDirPath);
return backupauthResourceDirPath;
}
}
function rollback(authresourcePath: string, backupauthResourceDirPath: string) {
if (fs.existsSync(authresourcePath) && fs.existsSync(backupauthResourceDirPath)) {
fs.removeSync(authresourcePath);
fs.moveSync(backupauthResourceDirPath, authresourcePath);
}
}
function cleanUp(authresourcePath: string | undefined) {
if (!!authresourcePath && fs.existsSync(authresourcePath)) fs.removeSync(authresourcePath);
}
const generateCliInputs = (parameters: ApiMetaData): AppSyncCLIInputs => {
return {
version: 1,
serviceConfiguration: {
serviceName: 'AppSync',
defaultAuthType: authConfigToAppSyncAuthType(parameters.authConfig ? parameters.authConfig.defaultAuthentication : undefined),
additionalAuthTypes:
!_.isEmpty(parameters.authConfig) && !_.isEmpty(parameters.authConfig.additionalAuthenticationProviders)
? parameters.authConfig.additionalAuthenticationProviders.map(authConfigToAppSyncAuthType)
: undefined,
conflictResolution: resolverConfigToConflictResolution(parameters.resolverConfig),
apiName: parameters.resourceName,
},
};
};