Files
personal_site/frontend/node_modules/@aws-amplify/backend-function/lib/layer_parser.js
T

89 lines
11 KiB
JavaScript

import { AmplifyUserError } from '@aws-amplify/platform-core';
/**
* Parses Lambda Layer ARNs for a function
*/
export class FunctionLayerArnParser {
region;
account;
arnPattern = new RegExp('arn:[a-zA-Z0-9-]+:lambda:[a-zA-Z0-9-]+:\\d{12}:layer:[a-zA-Z0-9-_]+:[0-9]+');
nameVersionPattern = new RegExp('^[a-zA-Z0-9-_]+:[0-9]+$');
/**
* Creates a new FunctionLayerArnParser
* @param region - AWS region
* @param account - AWS account ID
*/
constructor(region, account) {
this.region = region;
this.account = account;
}
/**
* Parse the layers for a function
* @param layers - Layers to be attached to the function. Each layer can be specified as either:
* - A full ARN (arn:aws:lambda:<region>:<account>:layer:<name>:<version>)
* - A name:version format (e.g., "my-layer:1")
* @param functionName - Name of the function
* @returns Valid layers for the function with resolved ARNs
* @throws AmplifyUserError if the layer ARN or name:version format is invalid
* @throws AmplifyUserError if the number of layers exceeds the limit
*/
parseLayers(layers, functionName) {
const validLayers = {};
const uniqueArns = new Set();
for (const [key, value] of Object.entries(layers)) {
let arn;
if (this.isValidLayerArn(value)) {
// If it's already a valid ARN, use it as is
arn = value;
}
else if (this.isValidNameVersion(value)) {
// If it's in name:version format, construct the ARN using provided region and account
const [name, version] = value.split(':');
arn = `arn:aws:lambda:${this.region}:${this.account}:layer:${name}:${version}`;
}
else {
throw new AmplifyUserError('InvalidLayerFormatError', {
message: `Invalid format for layer: ${value}`,
resolution: `Layer must be either a full ARN (arn:aws:lambda:<region>:<account>:layer:<name>:<version>) or name:version format for function: ${functionName}`,
});
}
// Ensure we don't add duplicate ARNs
if (!uniqueArns.has(arn)) {
uniqueArns.add(arn);
validLayers[key] = arn;
}
}
this.validateLayerCount(uniqueArns);
return validLayers;
}
/**
* Validate the ARN format for a Lambda Layer
* @param arn - The ARN string to validate
* @returns boolean indicating if the ARN format is valid
*/
isValidLayerArn(arn) {
return this.arnPattern.test(arn);
}
/**
* Validate the name:version format for a Lambda Layer
* @param value - The string to validate in format "name:version"
* @returns boolean indicating if the format is valid
*/
isValidNameVersion(value) {
return this.nameVersionPattern.test(value);
}
/**
* Validate the number of layers attached to a function
* @param uniqueArns - Set of unique layer ARNs
* @throws AmplifyUserError if the number of layers exceeds 5
* @see https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html#function-configuration-deployment-and-execution
*/
validateLayerCount(uniqueArns) {
if (uniqueArns.size > 5) {
throw new AmplifyUserError('MaximumLayersReachedError', {
message: 'A maximum of 5 unique layers can be attached to a function.',
resolution: 'Remove unused layers in your function',
});
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGF5ZXJfcGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2xheWVyX3BhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUU5RDs7R0FFRztBQUNILE1BQU0sT0FBTyxzQkFBc0I7SUFZZDtJQUNBO0lBWlgsVUFBVSxHQUFHLElBQUksTUFBTSxDQUM3Qiw0RUFBNEUsQ0FDN0UsQ0FBQztJQUNNLGtCQUFrQixHQUFHLElBQUksTUFBTSxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFFbkU7Ozs7T0FJRztJQUNILFlBQ21CLE1BQWMsRUFDZCxPQUFlO1FBRGYsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUNkLFlBQU8sR0FBUCxPQUFPLENBQVE7SUFDL0IsQ0FBQztJQUVKOzs7Ozs7Ozs7T0FTRztJQUNILFdBQVcsQ0FDVCxNQUE4QixFQUM5QixZQUFvQjtRQUVwQixNQUFNLFdBQVcsR0FBMkIsRUFBRSxDQUFDO1FBQy9DLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFFckMsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUNsRCxJQUFJLEdBQVcsQ0FBQztZQUVoQixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDaEMsNENBQTRDO2dCQUM1QyxHQUFHLEdBQUcsS0FBSyxDQUFDO1lBQ2QsQ0FBQztpQkFBTSxJQUFJLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxQyxzRkFBc0Y7Z0JBQ3RGLE1BQU0sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDekMsR0FBRyxHQUFHLGtCQUFrQixJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLFVBQVUsSUFBSSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ2pGLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLElBQUksZ0JBQWdCLENBQUMseUJBQXlCLEVBQUU7b0JBQ3BELE9BQU8sRUFBRSw2QkFBNkIsS0FBSyxFQUFFO29CQUM3QyxVQUFVLEVBQUUsbUlBQW1JLFlBQVksRUFBRTtpQkFDOUosQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELHFDQUFxQztZQUNyQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN6QixVQUFVLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNwQixXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ3pCLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sV0FBVyxDQUFDO0lBQ3JCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssZUFBZSxDQUFDLEdBQVc7UUFDakMsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLGtCQUFrQixDQUFDLEtBQWE7UUFDdEMsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLGtCQUFrQixDQUFDLFVBQXVCO1FBQ2hELElBQUksVUFBVSxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixNQUFNLElBQUksZ0JBQWdCLENBQUMsMkJBQTJCLEVBQUU7Z0JBQ3RELE9BQU8sRUFBRSw2REFBNkQ7Z0JBQ3RFLFVBQVUsRUFBRSx1Q0FBdUM7YUFDcEQsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFtcGxpZnlVc2VyRXJyb3IgfSBmcm9tICdAYXdzLWFtcGxpZnkvcGxhdGZvcm0tY29yZSc7XG5cbi8qKlxuICogUGFyc2VzIExhbWJkYSBMYXllciBBUk5zIGZvciBhIGZ1bmN0aW9uXG4gKi9cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkxheWVyQXJuUGFyc2VyIHtcbiAgcHJpdmF0ZSBhcm5QYXR0ZXJuID0gbmV3IFJlZ0V4cChcbiAgICAnYXJuOlthLXpBLVowLTktXSs6bGFtYmRhOlthLXpBLVowLTktXSs6XFxcXGR7MTJ9OmxheWVyOlthLXpBLVowLTktX10rOlswLTldKycsXG4gICk7XG4gIHByaXZhdGUgbmFtZVZlcnNpb25QYXR0ZXJuID0gbmV3IFJlZ0V4cCgnXlthLXpBLVowLTktX10rOlswLTldKyQnKTtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBGdW5jdGlvbkxheWVyQXJuUGFyc2VyXG4gICAqIEBwYXJhbSByZWdpb24gLSBBV1MgcmVnaW9uXG4gICAqIEBwYXJhbSBhY2NvdW50IC0gQVdTIGFjY291bnQgSURcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBhY2NvdW50OiBzdHJpbmcsXG4gICkge31cblxuICAvKipcbiAgICogUGFyc2UgdGhlIGxheWVycyBmb3IgYSBmdW5jdGlvblxuICAgKiBAcGFyYW0gbGF5ZXJzIC0gTGF5ZXJzIHRvIGJlIGF0dGFjaGVkIHRvIHRoZSBmdW5jdGlvbi4gRWFjaCBsYXllciBjYW4gYmUgc3BlY2lmaWVkIGFzIGVpdGhlcjpcbiAgICogICAgICAgICAgICAgICAgLSBBIGZ1bGwgQVJOIChhcm46YXdzOmxhbWJkYTo8cmVnaW9uPjo8YWNjb3VudD46bGF5ZXI6PG5hbWU+Ojx2ZXJzaW9uPilcbiAgICogICAgICAgICAgICAgICAgLSBBIG5hbWU6dmVyc2lvbiBmb3JtYXQgKGUuZy4sIFwibXktbGF5ZXI6MVwiKVxuICAgKiBAcGFyYW0gZnVuY3Rpb25OYW1lIC0gTmFtZSBvZiB0aGUgZnVuY3Rpb25cbiAgICogQHJldHVybnMgVmFsaWQgbGF5ZXJzIGZvciB0aGUgZnVuY3Rpb24gd2l0aCByZXNvbHZlZCBBUk5zXG4gICAqIEB0aHJvd3MgQW1wbGlmeVVzZXJFcnJvciBpZiB0aGUgbGF5ZXIgQVJOIG9yIG5hbWU6dmVyc2lvbiBmb3JtYXQgaXMgaW52YWxpZFxuICAgKiBAdGhyb3dzIEFtcGxpZnlVc2VyRXJyb3IgaWYgdGhlIG51bWJlciBvZiBsYXllcnMgZXhjZWVkcyB0aGUgbGltaXRcbiAgICovXG4gIHBhcnNlTGF5ZXJzKFxuICAgIGxheWVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgICBmdW5jdGlvbk5hbWU6IHN0cmluZyxcbiAgKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgY29uc3QgdmFsaWRMYXllcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBjb25zdCB1bmlxdWVBcm5zID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhsYXllcnMpKSB7XG4gICAgICBsZXQgYXJuOiBzdHJpbmc7XG5cbiAgICAgIGlmICh0aGlzLmlzVmFsaWRMYXllckFybih2YWx1ZSkpIHtcbiAgICAgICAgLy8gSWYgaXQncyBhbHJlYWR5IGEgdmFsaWQgQVJOLCB1c2UgaXQgYXMgaXNcbiAgICAgICAgYXJuID0gdmFsdWU7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaXNWYWxpZE5hbWVWZXJzaW9uKHZhbHVlKSkge1xuICAgICAgICAvLyBJZiBpdCdzIGluIG5hbWU6dmVyc2lvbiBmb3JtYXQsIGNvbnN0cnVjdCB0aGUgQVJOIHVzaW5nIHByb3ZpZGVkIHJlZ2lvbiBhbmQgYWNjb3VudFxuICAgICAgICBjb25zdCBbbmFtZSwgdmVyc2lvbl0gPSB2YWx1ZS5zcGxpdCgnOicpO1xuICAgICAgICBhcm4gPSBgYXJuOmF3czpsYW1iZGE6JHt0aGlzLnJlZ2lvbn06JHt0aGlzLmFjY291bnR9OmxheWVyOiR7bmFtZX06JHt2ZXJzaW9ufWA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgQW1wbGlmeVVzZXJFcnJvcignSW52YWxpZExheWVyRm9ybWF0RXJyb3InLCB7XG4gICAgICAgICAgbWVzc2FnZTogYEludmFsaWQgZm9ybWF0IGZvciBsYXllcjogJHt2YWx1ZX1gLFxuICAgICAgICAgIHJlc29sdXRpb246IGBMYXllciBtdXN0IGJlIGVpdGhlciBhIGZ1bGwgQVJOIChhcm46YXdzOmxhbWJkYTo8cmVnaW9uPjo8YWNjb3VudD46bGF5ZXI6PG5hbWU+Ojx2ZXJzaW9uPikgb3IgbmFtZTp2ZXJzaW9uIGZvcm1hdCBmb3IgZnVuY3Rpb246ICR7ZnVuY3Rpb25OYW1lfWAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBFbnN1cmUgd2UgZG9uJ3QgYWRkIGR1cGxpY2F0ZSBBUk5zXG4gICAgICBpZiAoIXVuaXF1ZUFybnMuaGFzKGFybikpIHtcbiAgICAgICAgdW5pcXVlQXJucy5hZGQoYXJuKTtcbiAgICAgICAgdmFsaWRMYXllcnNba2V5XSA9IGFybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlTGF5ZXJDb3VudCh1bmlxdWVBcm5zKTtcbiAgICByZXR1cm4gdmFsaWRMYXllcnM7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIEFSTiBmb3JtYXQgZm9yIGEgTGFtYmRhIExheWVyXG4gICAqIEBwYXJhbSBhcm4gLSBUaGUgQVJOIHN0cmluZyB0byB2YWxpZGF0ZVxuICAgKiBAcmV0dXJucyBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIEFSTiBmb3JtYXQgaXMgdmFsaWRcbiAgICovXG4gIHByaXZhdGUgaXNWYWxpZExheWVyQXJuKGFybjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYXJuUGF0dGVybi50ZXN0KGFybik7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIG5hbWU6dmVyc2lvbiBmb3JtYXQgZm9yIGEgTGFtYmRhIExheWVyXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBzdHJpbmcgdG8gdmFsaWRhdGUgaW4gZm9ybWF0IFwibmFtZTp2ZXJzaW9uXCJcbiAgICogQHJldHVybnMgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBmb3JtYXQgaXMgdmFsaWRcbiAgICovXG4gIHByaXZhdGUgaXNWYWxpZE5hbWVWZXJzaW9uKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uYW1lVmVyc2lvblBhdHRlcm4udGVzdCh2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhlIG51bWJlciBvZiBsYXllcnMgYXR0YWNoZWQgdG8gYSBmdW5jdGlvblxuICAgKiBAcGFyYW0gdW5pcXVlQXJucyAtIFNldCBvZiB1bmlxdWUgbGF5ZXIgQVJOc1xuICAgKiBAdGhyb3dzIEFtcGxpZnlVc2VyRXJyb3IgaWYgdGhlIG51bWJlciBvZiBsYXllcnMgZXhjZWVkcyA1XG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2xhbWJkYS9sYXRlc3QvZGcvZ2V0dGluZ3N0YXJ0ZWQtbGltaXRzLmh0bWwjZnVuY3Rpb24tY29uZmlndXJhdGlvbi1kZXBsb3ltZW50LWFuZC1leGVjdXRpb25cbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVMYXllckNvdW50KHVuaXF1ZUFybnM6IFNldDxzdHJpbmc+KTogdm9pZCB7XG4gICAgaWYgKHVuaXF1ZUFybnMuc2l6ZSA+IDUpIHtcbiAgICAgIHRocm93IG5ldyBBbXBsaWZ5VXNlckVycm9yKCdNYXhpbXVtTGF5ZXJzUmVhY2hlZEVycm9yJywge1xuICAgICAgICBtZXNzYWdlOiAnQSBtYXhpbXVtIG9mIDUgdW5pcXVlIGxheWVycyBjYW4gYmUgYXR0YWNoZWQgdG8gYSBmdW5jdGlvbi4nLFxuICAgICAgICByZXNvbHV0aW9uOiAnUmVtb3ZlIHVudXNlZCBsYXllcnMgaW4geW91ciBmdW5jdGlvbicsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==