"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const s3 = require("@aws-cdk/aws-s3");
const cdk = require("@aws-cdk/cdk");
const cxapi = require("@aws-cdk/cx-api");
const fs = require("fs");
const path = require("path");
/**
 * Defines the way an asset is packaged before it is uploaded to S3.
 */
var AssetPackaging;
(function (AssetPackaging) {
    /**
     * Path refers to a directory on disk, the contents of the directory is
     * archived into a .zip.
     */
    AssetPackaging["ZipDirectory"] = "zip";
    /**
     * Path refers to a single file on disk. The file is uploaded as-is.
     */
    AssetPackaging["File"] = "file";
})(AssetPackaging = exports.AssetPackaging || (exports.AssetPackaging = {}));
/**
 * An asset represents a local file or directory, which is automatically uploaded to S3
 * and then can be referenced within a CDK application.
 */
class Asset extends cdk.Construct {
    constructor(parent, id, props) {
        super(parent, id);
        // resolve full path
        this.assetPath = path.resolve(props.path);
        validateAssetOnDisk(this.assetPath, props.packaging);
        // add parameters for s3 bucket and s3 key. those will be set by
        // the toolkit or by CI/CD when the stack is deployed and will include
        // the name of the bucket and the S3 key where the code lives.
        const bucketParam = new cdk.Parameter(this, 'S3Bucket', {
            type: 'String',
            description: `S3 bucket for asset "${this.path}"`,
        });
        const keyParam = new cdk.Parameter(this, 'S3ObjectKey', {
            type: 'String',
            description: `S3 object for asset "${this.path}"`
        });
        this.s3BucketName = bucketParam.value;
        this.s3ObjectKey = keyParam.value;
        // grant the lambda's role read permissions on the code s3 object
        this.bucket = s3.BucketRef.import(parent, 'AssetBucket', {
            bucketName: this.s3BucketName
        });
        // form the s3 URL of the object key
        this.s3Url = this.bucket.urlForObject(this.s3ObjectKey);
        // attach metadata to the lambda function which includes information
        // for tooling to be able to package and upload a directory to the
        // s3 bucket and plug in the bucket name and key in the correct
        // parameters.
        const asset = {
            path: this.assetPath,
            packaging: props.packaging,
            s3BucketParameter: bucketParam.logicalId,
            s3KeyParameter: keyParam.logicalId,
        };
        this.addMetadata(cxapi.ASSET_METADATA, asset);
        for (const reader of (props.readers || [])) {
            this.grantRead(reader);
        }
    }
    /**
     * Grants read permissions to the principal on the asset's S3 object.
     */
    grantRead(principal) {
        this.bucket.grantRead(principal, this.s3ObjectKey);
    }
}
exports.Asset = Asset;
/**
 * An asset that represents a file on disk.
 */
class FileAsset extends Asset {
    constructor(parent, id, props) {
        super(parent, id, Object.assign({ packaging: AssetPackaging.File }, props));
    }
}
exports.FileAsset = FileAsset;
/**
 * An asset that represents a ZIP archive of a directory on disk.
 */
class ZipDirectoryAsset extends Asset {
    constructor(parent, id, props) {
        super(parent, id, Object.assign({ packaging: AssetPackaging.ZipDirectory }, props));
    }
}
exports.ZipDirectoryAsset = ZipDirectoryAsset;
function validateAssetOnDisk(assetPath, packaging) {
    if (!fs.existsSync(assetPath)) {
        throw new Error(`Cannot find asset at ${assetPath}`);
    }
    switch (packaging) {
        case AssetPackaging.ZipDirectory:
            if (!fs.statSync(assetPath).isDirectory()) {
                throw new Error(`${assetPath} is expected to be a directory when asset packaging is 'zip'`);
            }
            break;
        case AssetPackaging.File:
            if (!fs.statSync(assetPath).isFile()) {
                throw new Error(`${assetPath} is expected to be a regular file when asset packaging is 'file'`);
            }
            break;
        default:
            throw new Error(`Unsupported asset packaging format: ${packaging}`);
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhc3NldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLHNDQUF1QztBQUN2QyxvQ0FBcUM7QUFDckMseUNBQTBDO0FBQzFDLHlCQUEwQjtBQUMxQiw2QkFBOEI7QUFFOUI7O0dBRUc7QUFDSCxJQUFZLGNBV1g7QUFYRCxXQUFZLGNBQWM7SUFDdEI7OztPQUdHO0lBQ0gsc0NBQW9CLENBQUE7SUFFcEI7O09BRUc7SUFDSCwrQkFBYSxDQUFBO0FBQ2pCLENBQUMsRUFYVyxjQUFjLEdBQWQsc0JBQWMsS0FBZCxzQkFBYyxRQVd6QjtBQW9CRDs7O0dBR0c7QUFDSCxNQUFhLEtBQU0sU0FBUSxHQUFHLENBQUMsU0FBUztJQXdCcEMsWUFBWSxNQUFxQixFQUFFLEVBQVUsRUFBRSxLQUF3QjtRQUNuRSxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWxCLG9CQUFvQjtRQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRTFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRXJELGdFQUFnRTtRQUNoRSxzRUFBc0U7UUFDdEUsOERBQThEO1FBRTlELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3BELElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUFFLHdCQUF3QixJQUFJLENBQUMsSUFBSSxHQUFHO1NBQ3BELENBQUMsQ0FBQztRQUVILE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFO1lBQ3BELElBQUksRUFBRSxRQUFRO1lBQ2QsV0FBVyxFQUFFLHdCQUF3QixJQUFJLENBQUMsSUFBSSxHQUFHO1NBQ3BE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