@aws-amplify/cli-internal
Version:
Amplify CLI
121 lines • 7.22 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DynamoDBGenerator = void 0;
const node_path_1 = __importDefault(require("node:path"));
const promises_1 = __importDefault(require("node:fs/promises"));
const amplify_cli_core_1 = require("@aws-amplify/amplify-cli-core");
const dynamodb_renderer_1 = require("./dynamodb.renderer");
const ts_1 = require("../../ts");
class DynamoDBGenerator {
constructor(gen1App, backendGenerator, outputDir, resource, logger) {
this.gen1App = gen1App;
this.backendGenerator = backendGenerator;
this.outputDir = outputDir;
this.resource = resource;
this.renderer = new dynamodb_renderer_1.DynamoDBRenderer(resource.resourceName);
this.logger = logger;
}
async plan() {
const table = await this.fetchTable();
return [
{
resource: this.resource,
validate: () => undefined,
describe: async () => [`Generate amplify/storage/${this.resource.resourceName}/resource.ts`],
execute: async () => {
const capitalizedName = this.resource.resourceName.charAt(0).toUpperCase() + this.resource.resourceName.slice(1);
const functionName = `defineStorage${capitalizedName}`;
const storageAlias = `storage${capitalizedName}`;
const resourceDir = node_path_1.default.join(this.outputDir, 'amplify', 'storage', this.resource.resourceName);
this.logger.info(`Rendering storage/${this.resource.resourceName}/resource.ts`);
const nodes = this.renderer.render(table);
const content = ts_1.TS.printNodes(nodes);
await promises_1.default.mkdir(resourceDir, { recursive: true });
await promises_1.default.writeFile(node_path_1.default.join(resourceDir, 'resource.ts'), content, 'utf-8');
this.backendGenerator.addNamespaceImport(storageAlias, `./storage/${this.resource.resourceName}/resource`);
this.backendGenerator.addPostDefineBackendCall(this.resource.resourceName, `${storageAlias}.${functionName}(backend)`);
this.backendGenerator.addPostRefactorCall(`${storageAlias}.postRefactor(${this.resource.resourceName});`);
},
},
];
}
async fetchTable() {
var _a, _b, _c, _d, _e, _f, _g;
const actualTableName = this.gen1App.resourceMetaOutput(this.resource, 'Name');
this.logger.debug(`Fetching DynamoDB table '${actualTableName}'`);
const table = await this.gen1App.aws.fetchTableDescription(actualTableName);
if (!table) {
throw new amplify_cli_core_1.AmplifyError('DynamoDBTableNotFoundError', {
message: `DynamoDB table '${actualTableName}' not found`,
resolution: 'Verify the DynamoDB table exists and the CLI has the correct AWS credentials and region configured.',
});
}
const partitionKey = extractKey(table, 'HASH');
const sortKey = ((_a = table.KeySchema) === null || _a === void 0 ? void 0 : _a.some((k) => k.KeyType === 'RANGE')) ? extractKey(table, 'RANGE') : undefined;
const gsis = ((_b = table.GlobalSecondaryIndexes) !== null && _b !== void 0 ? _b : []).map((gsi) => {
var _a, _b, _c, _d, _e;
const keySchema = (_a = gsi.KeySchema) !== null && _a !== void 0 ? _a : [];
const gsiPartitionKey = extractKeyFromSchema(keySchema, (_b = table.AttributeDefinitions) !== null && _b !== void 0 ? _b : [], 'HASH', (_c = gsi.IndexName) !== null && _c !== void 0 ? _c : 'unknown');
const gsiSortKeySchema = keySchema.find((k) => k.KeyType === 'RANGE');
const gsiSortKey = gsiSortKeySchema
? extractKeyFromSchema(keySchema, (_d = table.AttributeDefinitions) !== null && _d !== void 0 ? _d : [], 'RANGE', (_e = gsi.IndexName) !== null && _e !== void 0 ? _e : 'unknown')
: undefined;
if (!gsi.IndexName) {
throw new amplify_cli_core_1.AmplifyError('DynamoDBSchemaError', {
message: `GSI on table '${actualTableName}' has no IndexName`,
resolution: 'Verify the DynamoDB table GSI configuration is valid.',
});
}
return { indexName: gsi.IndexName, partitionKey: gsiPartitionKey, sortKey: gsiSortKey };
});
return {
tableName: actualTableName,
partitionKey,
sortKey,
gsis: gsis.length > 0 ? gsis : undefined,
billingMode: ((_c = table.BillingModeSummary) === null || _c === void 0 ? void 0 : _c.BillingMode) === 'PAY_PER_REQUEST' ? 'PAY_PER_REQUEST' : 'PROVISIONED',
readCapacity: ((_d = table.ProvisionedThroughput) === null || _d === void 0 ? void 0 : _d.ReadCapacityUnits) || 5,
writeCapacity: ((_e = table.ProvisionedThroughput) === null || _e === void 0 ? void 0 : _e.WriteCapacityUnits) || 5,
streamEnabled: !!((_f = table.StreamSpecification) === null || _f === void 0 ? void 0 : _f.StreamEnabled),
streamViewType: (_g = table.StreamSpecification) === null || _g === void 0 ? void 0 : _g.StreamViewType,
};
}
}
exports.DynamoDBGenerator = DynamoDBGenerator;
function extractKey(table, keyType) {
var _a, _b, _c;
return extractKeyFromSchema((_a = table.KeySchema) !== null && _a !== void 0 ? _a : [], (_b = table.AttributeDefinitions) !== null && _b !== void 0 ? _b : [], keyType, (_c = table.TableName) !== null && _c !== void 0 ? _c : 'unknown');
}
function extractKeyFromSchema(keySchema, attributeDefinitions, keyType, context) {
const keyElement = keySchema.find((k) => k.KeyType === keyType);
if (!(keyElement === null || keyElement === void 0 ? void 0 : keyElement.AttributeName)) {
throw new amplify_cli_core_1.AmplifyError('DynamoDBSchemaError', {
message: `${keyType} key not found in KeySchema for '${context}'`,
resolution: 'Verify the DynamoDB table key schema is valid.',
});
}
const attrDef = attributeDefinitions.find((a) => a.AttributeName === keyElement.AttributeName);
if (!(attrDef === null || attrDef === void 0 ? void 0 : attrDef.AttributeType)) {
throw new amplify_cli_core_1.AmplifyError('DynamoDBSchemaError', {
message: `Attribute definition for '${keyElement.AttributeName}' not found in '${context}'`,
resolution: 'Verify the DynamoDB table attribute definitions match the key schema.',
});
}
return { name: keyElement.AttributeName, type: mapAttributeType(attrDef.AttributeType) };
}
function mapAttributeType(dynamoType) {
switch (dynamoType) {
case 'S':
return 'STRING';
case 'N':
return 'NUMBER';
case 'B':
return 'BINARY';
default:
return 'STRING';
}
}
//# sourceMappingURL=dynamodb.generator.js.map