@aws-amplify/amplify-category-api
Version:
Amplify CLI API Category Plugin
180 lines (143 loc) • 6.69 kB
text/typescript
import { join } from 'path';
import {
$TSContext,
AmplifyCategories,
AmplifySupportedService,
CLIInputSchemaValidator,
getMigrateResourceMessageForOverride,
isResourceNameUnique,
JSONUtilities,
PathConstants,
pathManager,
stateManager,
} from '@aws-amplify/amplify-cli-core';
import { prompter } from '@aws-amplify/amplify-prompts';
import * as fs from 'fs-extra';
import { ApigwInputs, ApigwStackTransform, CrudOperation, Path, PermissionSetting } from './cdk-stack-builder';
import { convertDeperecatedRestApiPaths } from './convert-deprecated-apigw-paths';
import { ApigwWalkthroughReturnPromise } from './service-walkthrough-types/apigw-types';
export class ApigwInputState {
projectRootPath: string;
resourceName: string;
paths: { [pathName: string]: Path };
constructor(private readonly context: $TSContext, resourceName?: string) {
this.projectRootPath = pathManager.findProjectRoot();
this.resourceName = resourceName;
}
public addAdminQueriesResource = async (adminQueriesProps: AdminQueriesProps) => {
this.resourceName = adminQueriesProps.apiName;
this.paths = {
'/{proxy+}': {
lambdaFunction: adminQueriesProps.functionName,
permissions: {
setting: PermissionSetting.PRIVATE,
auth: [CrudOperation.CREATE, CrudOperation.READ, CrudOperation.UPDATE, CrudOperation.DELETE],
},
},
};
await this.createApigwArtifacts();
// Update amplify-meta and backend-config
const backendConfigs = {
service: AmplifySupportedService.APIGW,
providerPlugin: 'awscloudformation',
authorizationType: 'AMAZON_COGNITO_USER_POOLS',
dependsOn: adminQueriesProps.dependsOn,
};
this.context.amplify.updateamplifyMetaAfterResourceAdd(AmplifyCategories.API, adminQueriesProps.apiName, backendConfigs);
};
public updateAdminQueriesResource = async (adminQueriesProps: AdminQueriesProps) => {
this.resourceName = adminQueriesProps.apiName;
this.paths = {
'/{proxy+}': {
lambdaFunction: adminQueriesProps.functionName,
permissions: {
setting: PermissionSetting.PRIVATE,
auth: [CrudOperation.CREATE, CrudOperation.READ, CrudOperation.UPDATE, CrudOperation.DELETE],
},
},
};
await this.createApigwArtifacts();
this.context.amplify.updateamplifyMetaAfterResourceUpdate(
AmplifyCategories.API,
adminQueriesProps.apiName,
'dependsOn',
adminQueriesProps.dependsOn,
);
};
public addApigwResource = async (serviceWalkthroughPromise: ApigwWalkthroughReturnPromise, options: Record<string, any>) => {
const { answers } = await serviceWalkthroughPromise;
this.resourceName = answers.resourceName;
this.paths = answers.paths;
options.dependsOn = answers.dependsOn;
isResourceNameUnique(AmplifyCategories.API, this.resourceName);
await this.createApigwArtifacts();
this.context.amplify.updateamplifyMetaAfterResourceAdd(AmplifyCategories.API, this.resourceName, options);
return this.resourceName;
};
public updateApigwResource = async (updateWalkthroughPromise: Promise<Record<string, any>>) => {
const { answers } = await updateWalkthroughPromise;
this.resourceName = answers.resourceName;
this.paths = answers.paths;
await this.createApigwArtifacts();
this.context.amplify.updateamplifyMetaAfterResourceUpdate(AmplifyCategories.API, this.resourceName, 'dependsOn', answers.dependsOn);
return this.resourceName;
};
public migrateAdminQueries = async (adminQueriesProps: AdminQueriesProps) => {
this.resourceName = this.resourceName ?? adminQueriesProps.apiName;
if (!(await prompter.yesOrNo(getMigrateResourceMessageForOverride(AmplifyCategories.API, this.resourceName, true), true))) {
return;
}
const resourceDirPath = pathManager.getResourceDirectoryPath(this.projectRootPath, AmplifyCategories.API, this.resourceName);
fs.removeSync(join(resourceDirPath, PathConstants.ParametersJsonFileName));
fs.removeSync(join(resourceDirPath, 'admin-queries-cloudformation-template.json'));
return this.updateAdminQueriesResource(adminQueriesProps);
};
public migrateApigwResource = async (resourceName: string) => {
this.resourceName = this.resourceName ?? resourceName;
if (!(await prompter.yesOrNo(getMigrateResourceMessageForOverride(AmplifyCategories.API, this.resourceName, true), true))) {
return;
}
const deprecatedParametersFileName = 'api-params.json';
const resourceDirPath = pathManager.getResourceDirectoryPath(this.projectRootPath, AmplifyCategories.API, this.resourceName);
const deprecatedParametersFilePath = join(resourceDirPath, deprecatedParametersFileName);
this.paths = convertDeperecatedRestApiPaths(deprecatedParametersFileName, deprecatedParametersFilePath, this.resourceName);
fs.removeSync(deprecatedParametersFilePath);
fs.removeSync(join(resourceDirPath, PathConstants.ParametersJsonFileName));
fs.removeSync(join(resourceDirPath, `${this.resourceName}-cloudformation-template.json`));
await this.createApigwArtifacts();
};
public cliInputsFileExists() {
return stateManager.resourceInputsJsonExists(this.projectRootPath, AmplifyCategories.API, this.resourceName);
}
public getCliInputPayload() {
return stateManager.getResourceInputsJson(this.projectRootPath, AmplifyCategories.API, this.resourceName);
}
public async isCLIInputsValid(cliInputs?: ApigwInputs) {
if (!cliInputs) {
cliInputs = this.getCliInputPayload();
}
const schemaValidator = new CLIInputSchemaValidator(
this.context,
AmplifySupportedService.APIGW,
AmplifyCategories.API,
'APIGatewayCLIInputs',
);
await schemaValidator.validateInput(JSONUtilities.stringify(cliInputs));
}
private async createApigwArtifacts() {
const resourceDirPath = pathManager.getResourceDirectoryPath(this.projectRootPath, AmplifyCategories.API, this.resourceName);
fs.ensureDirSync(resourceDirPath);
const buildDirPath = join(resourceDirPath, PathConstants.BuildDirName);
fs.ensureDirSync(buildDirPath);
stateManager.setResourceInputsJson(this.projectRootPath, AmplifyCategories.API, this.resourceName, { version: 1, paths: this.paths });
stateManager.setResourceParametersJson(this.projectRootPath, AmplifyCategories.API, this.resourceName, {});
const stack = new ApigwStackTransform(this.context, this.resourceName, this);
await stack.transform();
}
}
export type AdminQueriesProps = {
apiName: string;
functionName: string;
authResourceName: string;
dependsOn: Record<string, any>[];
};