@aws-amplify/cli-internal
Version:
Amplify CLI
199 lines • 12.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.S3Renderer = void 0;
const typescript_1 = __importDefault(require("typescript"));
const ts_1 = require("../../ts");
const resource_types_1 = require("../../../_common/resource-types");
const factory = typescript_1.default.factory;
class S3Renderer {
render(opts) {
const propertyAssignments = [];
const namedImports = { '@aws-amplify/backend': new Set(['defineStorage']) };
const postImportStatements = [];
postImportStatements.push(ts_1.TS.createBranchNameDeclaration());
this.renderName(propertyAssignments, opts.name);
this.renderAccessPatterns(propertyAssignments, namedImports, postImportStatements, opts);
this.renderTriggers(propertyAssignments, namedImports, opts);
const nodes = [
...this.renderImportStatements(namedImports),
ts_1.TS.namedImport('aws-cdk-lib', 'CfnResource'),
this.renderBackendTypeImport(),
ts_1.newLineIdentifier,
...postImportStatements,
ts_1.newLineIdentifier,
this.renderDefineStorageExport(propertyAssignments),
ts_1.newLineIdentifier,
this.renderPostRefactor(opts.bucketName),
ts_1.newLineIdentifier,
this.renderApplyEscapeHatches(opts),
];
return factory.createNodeArray(nodes);
}
renderImportStatements(namedImports) {
const imports = [];
for (const [source, identifiers] of Object.entries(namedImports)) {
imports.push(ts_1.TS.namedImport(source, ...Array.from(identifiers)));
}
return imports;
}
renderBackendTypeImport() {
return ts_1.TS.typeImport('../backend', 'Backend');
}
renderDefineStorageExport(propertyAssignments) {
return factory.createVariableStatement([factory.createModifier(typescript_1.default.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([
factory.createVariableDeclaration('storage', undefined, undefined, factory.createCallExpression(factory.createIdentifier('defineStorage'), undefined, [
factory.createObjectLiteralExpression(propertyAssignments),
])),
], typescript_1.default.NodeFlags.Const));
}
renderPostRefactor(bucketName) {
const s3BucketDeclaration = this.createCfnBucketDeclaration();
const assignment = factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('s3Bucket'), factory.createIdentifier('bucketName')), factory.createStringLiteral(bucketName)));
return ts_1.TS.exportedFunction('postRefactor', [s3BucketDeclaration, assignment]);
}
renderApplyEscapeHatches(opts) {
var _a, _b;
const statements = [this.createCfnBucketDeclaration()];
if (opts.accelerateStatus) {
statements.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('s3Bucket'), factory.createIdentifier('accelerateConfiguration')), factory.createObjectLiteralExpression([ts_1.TS.stringProp('accelerationStatus', opts.accelerateStatus)]))));
}
if (opts.versioningStatus) {
statements.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('s3Bucket'), factory.createIdentifier('versioningConfiguration')), factory.createObjectLiteralExpression([ts_1.TS.stringProp('status', opts.versioningStatus)]))));
}
if ((_b = (_a = opts.encryption) === null || _a === void 0 ? void 0 : _a.Rules) === null || _b === void 0 ? void 0 : _b[0]) {
statements.push(this.renderEncryption(opts.encryption.Rules[0]));
}
statements.push(ts_1.TS.retentionLoop(ts_1.TS.propAccess('backend', 'storage', 'stack', 'node'), resource_types_1.STORAGE_S3_RESOURCES_TO_RETAIN));
return ts_1.TS.exportedFunction('applyEscapeHatches', statements);
}
renderEncryption(rule) {
const sseProps = [];
if (rule.ApplyServerSideEncryptionByDefault) {
const sseDefaultProps = [];
if (rule.ApplyServerSideEncryptionByDefault.SSEAlgorithm) {
sseDefaultProps.push(ts_1.TS.stringProp('sseAlgorithm', rule.ApplyServerSideEncryptionByDefault.SSEAlgorithm));
}
if (rule.ApplyServerSideEncryptionByDefault.KMSMasterKeyID) {
sseDefaultProps.push(ts_1.TS.stringProp('kmsMasterKeyId', rule.ApplyServerSideEncryptionByDefault.KMSMasterKeyID));
}
sseProps.push(factory.createPropertyAssignment('serverSideEncryptionByDefault', factory.createObjectLiteralExpression(sseDefaultProps, true)));
}
if (rule.BucketKeyEnabled !== undefined) {
sseProps.push(factory.createPropertyAssignment('bucketKeyEnabled', rule.BucketKeyEnabled ? factory.createTrue() : factory.createFalse()));
}
return factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('s3Bucket'), factory.createIdentifier('bucketEncryption')), factory.createObjectLiteralExpression([
factory.createPropertyAssignment('serverSideEncryptionConfiguration', factory.createArrayLiteralExpression([factory.createObjectLiteralExpression(sseProps, true)], true)),
], true)));
}
createCfnBucketDeclaration() {
return ts_1.TS.declareConst('s3Bucket', ts_1.TS.propAccess('backend', 'storage', 'resources', 'cfnResources', 'cfnBucket'));
}
renderName(target, storageIdentifier) {
const parts = storageIdentifier.split('-');
const nameWithoutEnv = parts.slice(0, -1).join('-');
const nameExpression = factory.createTemplateExpression(factory.createTemplateHead(`${nameWithoutEnv}-`), [
factory.createTemplateSpan(factory.createIdentifier('branchName'), factory.createTemplateTail('')),
]);
target.push(factory.createPropertyAssignment(factory.createIdentifier('name'), nameExpression));
}
renderAccessPatterns(target, namedImports, postImportStatements, opts) {
if (!opts.access)
return;
target.push(this.buildAccessProperty(opts.access));
if (opts.access.functions && opts.access.functions.length > 0) {
for (const functionAccess of opts.access.functions) {
const functionImportPath = `../function/${functionAccess.functionName}/resource`;
if (!namedImports[functionImportPath]) {
namedImports[functionImportPath] = new Set();
}
namedImports[functionImportPath].add(functionAccess.functionName);
}
}
if (opts.access.groups) {
postImportStatements.push(factory.createJSDocComment(factory.createNodeArray([
factory.createJSDocText('TODO: Your project uses group permissions. Group permissions have changed in Gen 2. '),
factory.createJSDocText('In order to grant permissions to groups in Gen 2, please refer to https://docs.amplify.aws/react/build-a-backend/storage/authorization/#for-gen-1-public-protected-and-private-access-pattern.'),
])));
}
}
renderTriggers(target, namedImports, opts) {
const triggers = opts.triggers;
if (!triggers || Object.keys(triggers).length === 0)
return;
const triggerProps = Object.entries(triggers).map(([key, functionName]) => {
return factory.createPropertyAssignment(factory.createIdentifier(key), factory.createIdentifier(functionName));
});
target.push(factory.createPropertyAssignment('triggers', factory.createObjectLiteralExpression(triggerProps, true)));
for (const functionName of Object.values(triggers)) {
const functionImportPath = `../function/${functionName}/resource`;
if (!namedImports[functionImportPath]) {
namedImports[functionImportPath] = new Set();
}
namedImports[functionImportPath].add(functionName);
}
}
buildAccessProperty(accessPatterns) {
const allowIdentifier = factory.createIdentifier('allow');
const publicPathAccess = [];
const privatePathAccess = [];
const protectedPathAccess = [];
if (accessPatterns.guest && accessPatterns.guest.length > 0) {
publicPathAccess.push(this.createAllowPattern(allowIdentifier, 'guest', accessPatterns.guest));
}
if (accessPatterns.auth && accessPatterns.auth.length > 0) {
const pattern = this.createAllowPattern(allowIdentifier, 'authenticated', accessPatterns.auth);
publicPathAccess.push(pattern);
protectedPathAccess.push(pattern);
privatePathAccess.push(pattern);
}
if (accessPatterns.groups) {
for (const [groupName, permissions] of Object.entries(accessPatterns.groups)) {
const pattern = this.createAllowPattern(allowIdentifier, `groups(['${groupName}'])`, permissions);
publicPathAccess.push(pattern);
privatePathAccess.push(pattern);
protectedPathAccess.push(pattern);
}
}
if (accessPatterns.functions && accessPatterns.functions.length > 0) {
const consolidated = {};
for (const { functionName, permissions } of accessPatterns.functions) {
if (!consolidated[functionName]) {
consolidated[functionName] = new Set(permissions);
}
else {
for (const p of permissions)
consolidated[functionName].add(p);
}
}
for (const [functionName, permissions] of Object.entries(consolidated)) {
const pattern = this.createResourcePattern(allowIdentifier, functionName, Array.from(permissions));
publicPathAccess.push(pattern);
privatePathAccess.push(pattern);
protectedPathAccess.push(pattern);
}
}
const allowAssignments = [];
if (publicPathAccess.length > 0) {
allowAssignments.push(factory.createPropertyAssignment(factory.createStringLiteral('public/*'), factory.createArrayLiteralExpression(publicPathAccess)));
}
if (protectedPathAccess.length > 0) {
allowAssignments.push(factory.createPropertyAssignment(factory.createStringLiteral('protected/{entity_id}/*'), factory.createArrayLiteralExpression(protectedPathAccess)));
}
if (privatePathAccess.length > 0) {
allowAssignments.push(factory.createPropertyAssignment(factory.createStringLiteral('private/{entity_id}/*'), factory.createArrayLiteralExpression(privatePathAccess)));
}
const accessFunction = factory.createArrowFunction(undefined, undefined, [factory.createParameterDeclaration(undefined, undefined, allowIdentifier)], undefined, undefined, factory.createParenthesizedExpression(factory.createObjectLiteralExpression(allowAssignments, true)));
return factory.createPropertyAssignment(factory.createIdentifier('access'), accessFunction);
}
createAllowPattern(allowIdentifier, userLevel, permissions) {
return factory.createCallExpression(factory.createPropertyAccessExpression(allowIdentifier, factory.createIdentifier(`${userLevel}.to`)), undefined, [factory.createArrayLiteralExpression(permissions.map((p) => factory.createStringLiteral(p)))]);
}
createResourcePattern(allowIdentifier, functionName, permissions) {
return factory.createCallExpression(factory.createPropertyAccessExpression(factory.createCallExpression(factory.createPropertyAccessExpression(allowIdentifier, factory.createIdentifier('resource')), undefined, [factory.createIdentifier(functionName)]), factory.createIdentifier('to')), undefined, [factory.createArrayLiteralExpression(permissions.map((p) => factory.createStringLiteral(p)))]);
}
}
exports.S3Renderer = S3Renderer;
//# sourceMappingURL=s3.renderer.js.map