UNPKG

aws-cdk-lib

Version:

Version 2 of the AWS Cloud Development Kit library

3 lines (2 loc) 12.6 kB
"use strict";var _a;Object.defineProperty(exports,"__esModule",{value:!0}),exports.AssetStaging=void 0;var jsiiDeprecationWarnings=()=>{var tmp=require("../../.warnings.jsii.js");return jsiiDeprecationWarnings=()=>tmp,tmp};const JSII_RTTI_SYMBOL_1=Symbol.for("jsii.rtti");var crypto=()=>{var tmp=require("crypto");return crypto=()=>tmp,tmp},path=()=>{var tmp=require("path");return path=()=>tmp,tmp},constructs_1=()=>{var tmp=require("constructs");return constructs_1=()=>tmp,tmp},fs=()=>{var tmp=require("fs-extra");return fs=()=>tmp,tmp},assets_1=()=>{var tmp=require("./assets");return assets_1=()=>tmp,tmp},bundling_1=()=>{var tmp=require("./bundling");return bundling_1=()=>tmp,tmp},errors_1=()=>{var tmp=require("./errors");return errors_1=()=>tmp,tmp},fs_1=()=>{var tmp=require("./fs");return fs_1=()=>tmp,tmp},fingerprint_1=()=>{var tmp=require("./fs/fingerprint");return fingerprint_1=()=>tmp,tmp},names_1=()=>{var tmp=require("./names");return names_1=()=>tmp,tmp},asset_staging_1=()=>{var tmp=require("./private/asset-staging");return asset_staging_1=()=>tmp,tmp},cache_1=()=>{var tmp=require("./private/cache");return cache_1=()=>tmp,tmp},stack_1=()=>{var tmp=require("./stack");return stack_1=()=>tmp,tmp},stage_1=()=>{var tmp=require("./stage");return stage_1=()=>tmp,tmp},cxapi=()=>{var tmp=require("../../cx-api");return cxapi=()=>tmp,tmp};const ARCHIVE_EXTENSIONS=[".tar.gz",".zip",".jar",".tar",".tgz"],ASSET_SALT_CONTEXT_KEY="@aws-cdk/core:assetHashSalt";class AssetStaging extends constructs_1().Construct{static clearAssetHashCache(){this.assetCache.clear(),(0,fingerprint_1().clearLargeFileFingerprintCache)()}constructor(scope,id,props){super(scope,id);try{jsiiDeprecationWarnings().aws_cdk_lib_AssetStagingProps(props)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,AssetStaging),error}const salt=this.node.tryGetContext(ASSET_SALT_CONTEXT_KEY);if(this.sourcePath=path().resolve(props.sourcePath),this.fingerprintOptions={...props,exclude:[".is_custom_resource",...props.exclude??[]],extraHash:props.extraHash||salt?`${props.extraHash??""}${salt??""}`:void 0},!fs().existsSync(this.sourcePath))throw new(errors_1()).ValidationError(`Cannot find asset at ${this.sourcePath}`,this);this.sourceStats=fs().statSync(this.sourcePath);const outdir=stage_1().Stage.of(this)?.assetOutdir;if(!outdir)throw new(errors_1()).ValidationError('unable to determine cloud assembly asset output directory. Assets must be defined indirectly within a "Stage" or an "App" scope',this);this.assetOutdir=outdir,this.customSourceFingerprint=props.assetHash,this.hashType=determineHashType(this,props.assetHashType,this.customSourceFingerprint);let stageThisAsset,skip=!1;if(props.bundling){skip=!stack_1().Stack.of(this).bundlingRequired;const bundling=props.bundling;stageThisAsset=()=>this.stageByBundling(bundling,skip)}else stageThisAsset=()=>this.stageByCopying();this.cacheKey=calculateCacheKey({outdir:this.assetOutdir,sourcePath:path().resolve(props.sourcePath),bundling:props.bundling,assetHashType:this.hashType,customFingerprint:this.customSourceFingerprint,extraHash:props.extraHash,exclude:props.exclude,ignoreMode:props.ignoreMode,skip});const staged=AssetStaging.assetCache.obtain(this.cacheKey,stageThisAsset);this.stagedPath=staged.stagedPath,this.absoluteStagedPath=staged.stagedPath,this.assetHash=staged.assetHash,this.packaging=staged.packaging,this.isArchive=staged.isArchive}get sourceHash(){return this.assetHash}relativeStagedPath(stack){try{jsiiDeprecationWarnings().aws_cdk_lib_Stack(stack)}catch(error){throw process.env.JSII_DEBUG!=="1"&&error.name==="DeprecationError"&&Error.captureStackTrace(error,this.relativeStagedPath),error}const asmManifestDir=stage_1().Stage.of(stack)?.outdir;return asmManifestDir?path().relative(this.assetOutdir,this.stagedPath).startsWith("..")||this.stagingDisabled?this.stagedPath:path().relative(asmManifestDir,this.stagedPath):this.stagedPath}stageByCopying(){const assetHash=this.calculateHash(this.hashType),targetPath=this.stagingDisabled?this.sourcePath:path().resolve(this.assetOutdir,renderAssetFilename(assetHash,getExtension(this.sourcePath))),stagedPath=this.renderStagedPath(this.sourcePath,targetPath);if(!this.sourceStats.isDirectory()&&!this.sourceStats.isFile())throw new(errors_1()).ValidationError(`Asset ${this.sourcePath} is expected to be either a directory or a regular file`,this);return this.stageAsset(this.sourcePath,stagedPath,"copy"),{assetHash,stagedPath,packaging:this.sourceStats.isDirectory()?assets_1().FileAssetPackaging.ZIP_DIRECTORY:assets_1().FileAssetPackaging.FILE,isArchive:this.sourceStats.isDirectory()||ARCHIVE_EXTENSIONS.includes(getExtension(this.sourcePath).toLowerCase())}}stageByBundling(bundling,skip){if(!this.sourceStats.isDirectory())throw new(errors_1()).ValidationError(`Asset ${this.sourcePath} is expected to be a directory when bundling`,this);if(skip){let hashType=this.hashType;return(hashType===assets_1().AssetHashType.OUTPUT||hashType===assets_1().AssetHashType.BUNDLE)&&(this.customSourceFingerprint=names_1().Names.uniqueId(this),hashType=assets_1().AssetHashType.CUSTOM),{assetHash:this.calculateHash(hashType,bundling),stagedPath:this.sourcePath,packaging:assets_1().FileAssetPackaging.ZIP_DIRECTORY,isArchive:!0}}let assetHash=this.hashType===assets_1().AssetHashType.SOURCE||this.hashType===assets_1().AssetHashType.CUSTOM?this.calculateHash(this.hashType,bundling):void 0;const bundleDir=this.determineBundleDir(this.assetOutdir,assetHash);this.bundle(bundling,bundleDir);const bundlingOutputType=bundling.outputType??bundling_1().BundlingOutput.AUTO_DISCOVER,bundledAsset=determineBundledAsset(this,bundleDir,bundlingOutputType);assetHash=assetHash??this.calculateHash(this.hashType,bundling,bundledAsset.path);const stagedPath=this.renderStagedPath(bundledAsset.path,path().resolve(this.assetOutdir,renderAssetFilename(assetHash,bundledAsset.extension)));return this.stageAsset(bundledAsset.path,stagedPath,"move"),bundledAsset.packaging===assets_1().FileAssetPackaging.FILE&&(this.hashType===assets_1().AssetHashType.OUTPUT||this.hashType===assets_1().AssetHashType.BUNDLE?fs().removeSync(path().dirname(bundledAsset.path)):fs().closeSync(fs().openSync(bundledAsset.path,"w"))),{assetHash,stagedPath,packaging:bundledAsset.packaging,isArchive:bundlingOutputType!==bundling_1().BundlingOutput.SINGLE_FILE}}get stagingDisabled(){return!!this.node.tryGetContext(cxapi().DISABLE_ASSET_STAGING_CONTEXT)}stageAsset(sourcePath,targetPath,style){if(fs().existsSync(targetPath)){style==="move"&&sourcePath!==targetPath&&fs().removeSync(sourcePath);return}if(style==="move"){fs().renameSync(sourcePath,targetPath);return}if(this.sourceStats.isFile())fs().copyFileSync(sourcePath,targetPath);else if(this.sourceStats.isDirectory())fs().mkdirSync(targetPath),fs_1().FileSystem.copyDirectory(sourcePath,targetPath,this.fingerprintOptions);else throw new(errors_1()).ValidationError(`Unknown file type: ${sourcePath}`,this)}determineBundleDir(outdir,sourceHash){return sourceHash?path().resolve(outdir,renderAssetFilename(sourceHash)):path().resolve(outdir,`bundling-temp-${this.cacheKey}`)}bundle(options,bundleDir){if(fs().existsSync(bundleDir))return;const tempDir=`${bundleDir}-building`;fs().rmSync(tempDir,{recursive:!0,force:!0}),fs().ensureDirSync(tempDir),fs().chmodSync(tempDir,511);let localBundling;try{if(process.stderr.write(`Bundling asset ${this.node.path}... `),localBundling=options.local?.tryBundle(tempDir,options),!localBundling){const assetStagingOptions={sourcePath:this.sourcePath,bundleDir:tempDir,...options};switch(options.bundlingFileAccess){case bundling_1().BundlingFileAccess.VOLUME_COPY:new(asset_staging_1()).AssetBundlingVolumeCopy(assetStagingOptions).run();break;case bundling_1().BundlingFileAccess.BIND_MOUNT:default:new(asset_staging_1()).AssetBundlingBindMount(assetStagingOptions).run();break}}fs().renameSync(tempDir,bundleDir)}catch(err){throw new(errors_1()).ValidationError(`Failed to bundle asset ${this.node.path}, bundle output is located at ${tempDir}: ${err}`,this)}if(fs_1().FileSystem.isEmpty(bundleDir)){const outputDir=localBundling?bundleDir:AssetStaging.BUNDLING_OUTPUT_DIR;throw new(errors_1()).ValidationError(`Bundling did not produce any output. Check that content is written to ${outputDir}.`,this)}}calculateHash(hashType,bundling,outputDir){if(hashType==assets_1().AssetHashType.CUSTOM||hashType==assets_1().AssetHashType.SOURCE&&bundling){const hash=crypto().createHash("sha256");return hash.update(this.customSourceFingerprint??fs_1().FileSystem.fingerprint(this.sourcePath,this.fingerprintOptions)),bundling&&hash.update(JSON.stringify(bundling,sanitizeHashValue)),hash.digest("hex")}switch(hashType){case assets_1().AssetHashType.SOURCE:return fs_1().FileSystem.fingerprint(this.sourcePath,this.fingerprintOptions);case assets_1().AssetHashType.BUNDLE:case assets_1().AssetHashType.OUTPUT:if(!outputDir)throw new(errors_1()).ValidationError(`Cannot use \`${hashType}\` hash type when \`bundling\` is not specified.`,this);return fs_1().FileSystem.fingerprint(outputDir,this.fingerprintOptions);default:throw new(errors_1()).ValidationError("Unknown asset hash type.",this)}}renderStagedPath(sourcePath,targetPath){return this.hashType!==assets_1().AssetHashType.OUTPUT&&path().dirname(sourcePath)===targetPath&&(targetPath=targetPath+"_noext"),targetPath}}exports.AssetStaging=AssetStaging,_a=JSII_RTTI_SYMBOL_1,AssetStaging[_a]={fqn:"aws-cdk-lib.AssetStaging",version:"2.202.0"},AssetStaging.BUNDLING_INPUT_DIR="/asset-input",AssetStaging.BUNDLING_OUTPUT_DIR="/asset-output",AssetStaging.assetCache=new(cache_1()).Cache;function renderAssetFilename(assetHash,extension=""){return`asset.${assetHash}${extension}`}function determineHashType(scope,assetHashType,customSourceFingerprint){const hashType=customSourceFingerprint?assetHashType??assets_1().AssetHashType.CUSTOM:assetHashType??assets_1().AssetHashType.SOURCE;if(customSourceFingerprint&&hashType!==assets_1().AssetHashType.CUSTOM)throw new(errors_1()).ValidationError(`Cannot specify \`${assetHashType}\` for \`assetHashType\` when \`assetHash\` is specified. Use \`CUSTOM\` or leave \`undefined\`.`,scope);if(hashType===assets_1().AssetHashType.CUSTOM&&!customSourceFingerprint)throw new(errors_1()).ValidationError("`assetHash` must be specified when `assetHashType` is set to `AssetHashType.CUSTOM`.",scope);return hashType}function calculateCacheKey(props){return crypto().createHash("sha256").update(JSON.stringify(sortObject(props),sanitizeHashValue)).digest("hex")}function sortObject(object){if(typeof object!="object"||object instanceof Array)return object;const ret={};for(const key of Object.keys(object).sort())ret[key]=sortObject(object[key]);return ret}function sanitizeHashValue(key,value){if(key==="PIP_INDEX_URL"||key==="PIP_EXTRA_INDEX_URL")try{let url=new URL(value);if(url.password)return url.password="",url.toString()}catch(e){throw e.name==="TypeError"?new(errors_1()).AssumptionError(`${key} must be a valid URL, got ${value}.`):e}return value}function findSingleFile(scope,directory,archiveOnly){if(!fs().existsSync(directory))throw new(errors_1()).ValidationError(`Directory ${directory} does not exist.`,scope);if(!fs().statSync(directory).isDirectory())throw new(errors_1()).ValidationError(`${directory} is not a directory.`,scope);const content=fs().readdirSync(directory);if(content.length===1){const file=path().join(directory,content[0]),extension=getExtension(content[0]).toLowerCase();if(fs().statSync(file).isFile()&&(!archiveOnly||ARCHIVE_EXTENSIONS.includes(extension)))return file}}function determineBundledAsset(scope,bundleDir,outputType){const archiveFile=findSingleFile(scope,bundleDir,outputType!==bundling_1().BundlingOutput.SINGLE_FILE);switch(outputType===bundling_1().BundlingOutput.AUTO_DISCOVER&&(outputType=archiveFile?bundling_1().BundlingOutput.ARCHIVED:bundling_1().BundlingOutput.NOT_ARCHIVED),outputType){case bundling_1().BundlingOutput.NOT_ARCHIVED:return{path:bundleDir,packaging:assets_1().FileAssetPackaging.ZIP_DIRECTORY};case bundling_1().BundlingOutput.ARCHIVED:case bundling_1().BundlingOutput.SINGLE_FILE:if(!archiveFile)throw new(errors_1()).ValidationError("Bundling output directory is expected to include only a single file when `output` is set to `ARCHIVED` or `SINGLE_FILE`",scope);return{path:archiveFile,packaging:assets_1().FileAssetPackaging.FILE,extension:getExtension(archiveFile)}}}function getExtension(source){for(const ext of ARCHIVE_EXTENSIONS)if(source.toLowerCase().endsWith(ext))return ext;return path().extname(source)}