@pwrdrvr/microapps-cdk 0.3.4-rc1 → 0.3.5-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +2 -2
- package/changelog.md +1 -1
- package/lib/MicroApps.js +1 -1
- package/lib/MicroAppsAPIGwy.js +1 -1
- package/lib/MicroAppsCF.js +1 -1
- package/lib/MicroAppsEdgeToOrigin.js +1 -1
- package/lib/MicroAppsS3.js +1 -1
- package/lib/MicroAppsSvcs.js +4 -4
- package/lib/MicroAppsTable.js +1 -1
- package/lib/microapps-deployer/index.js +1 -1
- package/lib/microapps-deployer/index.js.map +2 -2
- package/lib/microapps-edge-to-origin/index.js +1 -1
- package/lib/microapps-edge-to-origin/index.js.map +2 -2
- package/package.json +1 -1
- package/releasetag.txt +1 -1
- package/version.txt +1 -1
|
@@ -78,7 +78,7 @@ For more information please go to https://github.com/aws/aws-sdk-js-v3#functiona
|
|
|
78
78
|
`+e.slice(i,s),i=s+1),d=a;return c+=`
|
|
79
79
|
`,e.length-i>t&&d>i?c+=e.slice(i,d)+`
|
|
80
80
|
`+e.slice(d+1):c+=e.slice(i),c.slice(1)}function H8e(e){for(var t="",n=0,r,i=0;i<e.length;n>=65536?i+=2:i++)n=fm(e,i),r=Ln[n],!r&&wm(n)?(t+=e[i],n>=65536&&(t+=e[i+1])):t+=r||M8e(n);return t}function J8e(e,t,n){var r="",i=e.tag,s,d,a;for(s=0,d=n.length;s<d;s+=1)a=n[s],e.replacer&&(a=e.replacer.call(n,String(s),a)),(ds(e,t,a,!1,!1)||typeof a>"u"&&ds(e,t,null,!1,!1))&&(r!==""&&(r+=","+(e.condenseFlow?"":" ")),r+=e.dump);e.tag=i,e.dump="["+r+"]"}function AY(e,t,n,r){var i="",s=e.tag,d,a,c;for(d=0,a=n.length;d<a;d+=1)c=n[d],e.replacer&&(c=e.replacer.call(n,String(d),c)),(ds(e,t+1,c,!0,!0,!1,!0)||typeof c>"u"&&ds(e,t+1,null,!0,!0,!1,!0))&&((!r||i!=="")&&(i+=$q(e,t)),e.dump&&gm===e.dump.charCodeAt(0)?i+="-":i+="- ",i+=e.dump);e.tag=s,e.dump=i||"[]"}function X8e(e,t,n){var r="",i=e.tag,s=Object.keys(n),d,a,c,l,u;for(d=0,a=s.length;d<a;d+=1)u="",r!==""&&(u+=", "),e.condenseFlow&&(u+='"'),c=s[d],l=n[c],e.replacer&&(l=e.replacer.call(n,c,l)),ds(e,t,c,!1,!1)&&(e.dump.length>1024&&(u+="? "),u+=e.dump+(e.condenseFlow?'"':"")+":"+(e.condenseFlow?"":" "),ds(e,t,l,!1,!1)&&(u+=e.dump,r+=u));e.tag=i,e.dump="{"+r+"}"}function K8e(e,t,n,r){var i="",s=e.tag,d=Object.keys(n),a,c,l,u,w,E;if(e.sortKeys===!0)d.sort();else if(typeof e.sortKeys=="function")d.sort(e.sortKeys);else if(e.sortKeys)throw new Qn("sortKeys must be a boolean or a function");for(a=0,c=d.length;a<c;a+=1)E="",(!r||i!=="")&&(E+=$q(e,t)),l=d[a],u=n[l],e.replacer&&(u=e.replacer.call(n,l,u)),ds(e,t+1,l,!0,!0,!0)&&(w=e.tag!==null&&e.tag!=="?"||e.dump&&e.dump.length>1024,w&&(e.dump&&gm===e.dump.charCodeAt(0)?E+="?":E+="? "),E+=e.dump,w&&(E+=$q(e,t)),ds(e,t+1,u,!0,w)&&(e.dump&&gm===e.dump.charCodeAt(0)?E+=":":E+=": ",E+=e.dump,i+=E));e.tag=s,e.dump=i||"{}"}function xY(e,t,n){var r,i,s,d,a,c;for(i=n?e.explicitTypes:e.implicitTypes,s=0,d=i.length;s<d;s+=1)if(a=i[s],(a.instanceOf||a.predicate)&&(!a.instanceOf||typeof t=="object"&&t instanceof a.instanceOf)&&(!a.predicate||a.predicate(t))){if(n?a.multi&&a.representName?e.tag=a.representName(t):e.tag=a.tag:e.tag="?",a.represent){if(c=e.styleMap[a.tag]||a.defaultStyle,FY.call(a.represent)==="[object Function]")r=a.represent(t,c);else if(jY.call(a.represent,c))r=a.represent[c](t,c);else throw new Qn("!<"+a.tag+'> tag resolver accepts not "'+c+'" style');e.dump=r}return!0}return!1}function ds(e,t,n,r,i,s,d){e.tag=null,e.dump=n,xY(e,n,!1)||xY(e,n,!0);var a=FY.call(e.dump),c=r,l;r&&(r=e.flowLevel<0||e.flowLevel>t);var u=a==="[object Object]"||a==="[object Array]",w,E;if(u&&(w=e.duplicates.indexOf(n),E=w!==-1),(e.tag!==null&&e.tag!=="?"||E||e.indent!==2&&t>0)&&(i=!1),E&&e.usedDuplicates[w])e.dump="*ref_"+w;else{if(u&&E&&!e.usedDuplicates[w]&&(e.usedDuplicates[w]=!0),a==="[object Object]")r&&Object.keys(e.dump).length!==0?(K8e(e,t,e.dump,i),E&&(e.dump="&ref_"+w+e.dump)):(X8e(e,t,e.dump),E&&(e.dump="&ref_"+w+" "+e.dump));else if(a==="[object Array]")r&&e.dump.length!==0?(e.noArrayIndent&&!d&&t>0?AY(e,t-1,e.dump,i):AY(e,t,e.dump,i),E&&(e.dump="&ref_"+w+e.dump)):(J8e(e,t,e.dump),E&&(e.dump="&ref_"+w+" "+e.dump));else if(a==="[object String]")e.tag!=="?"&&V8e(e,e.dump,t,s,c);else{if(a==="[object Undefined]")return!1;if(e.skipInvalid)return!1;throw new Qn("unacceptable kind of an object to dump "+a)}e.tag!==null&&e.tag!=="?"&&(l=encodeURI(e.tag[0]==="!"?e.tag.slice(1):e.tag).replace(/!/g,"%21"),e.tag[0]==="!"?l="!"+l:l.slice(0,18)==="tag:yaml.org,2002:"?l="!!"+l.slice(18):l="!<"+l+">",e.dump=l+" "+e.dump)}return!0}function W8e(e,t){var n=[],r=[],i,s;for(Jq(e,n,r),i=0,s=r.length;i<s;i+=1)t.duplicates.push(n[r[i]]);t.usedDuplicates=new Array(s)}function Jq(e,t,n){var r,i,s;if(e!==null&&typeof e=="object")if(i=t.indexOf(e),i!==-1)n.indexOf(i)===-1&&n.push(i);else if(t.push(e),Array.isArray(e))for(i=0,s=e.length;i<s;i+=1)Jq(e[i],t,n);else for(r=Object.keys(e),i=0,s=r.length;i<s;i+=1)Jq(e[r[i]],t,n)}function Q8e(e,t){t=t||{};var n=new B8e(t);n.noRefs||W8e(e,n);var r=e;return n.replacer&&(r=n.replacer.call({"":r},"",r)),ds(n,0,r,!0,!0)?n.dump+`
|
|
81
|
-
`:""}var Y8e=Q8e,Z8e={dump:Y8e};function Yq(e,t){return function(){throw new Error("Function yaml."+e+" is removed in js-yaml 4. Use yaml."+t+" instead, which is now safe by default.")}}var QY=BY.load,L4t=BY.loadAll,D4t=Z8e.dump;var M4t=Yq("safeLoad","load"),O4t=Yq("safeLoadAll","loadAll"),B4t=Yq("safeDump","dump");var Gr=pn(Yd()),yne=pn(Yd());var sE=pn(gne()),iE=class{static async getExistingFiles(t){let n=[];for(let r of t)await(0,sE.pathExists)(r)&&n.push(r);return n}static getExistingFilesSync(t){let n=[];for(let r of t)(0,sE.pathExistsSync)(r)&&n.push(r);return n}};var hne=pn(Yd()),Lm=class{};En([(0,hne.Property)({doc:"ID of API Gateway to integrate with",nullable:!1,default:"none",env:"APIGWY_ID"})],Lm.prototype,"apiId",2);var wne=pn(Yd()),Dm=class{};En([(0,wne.Property)({doc:"DynamoDB Table Name",default:"MicroApps",env:"DATABASE_TABLE_NAME"})],Dm.prototype,"tableName",2);var JL=pn(Yd()),sc=class{};En([(0,JL.Property)({doc:"Staging bucket to copy staged apps from",default:"microapps-staging",env:"FILESTORE_STAGING_BUCKET"})],sc.prototype,"stagingBucket",2),En([(0,JL.Property)({doc:"Destination bucket to copy staged apps to",default:"microapps",env:"FILESTORE_DEST_BUCKET"})],sc.prototype,"destinationBucket",2);var Gt=class{static configFiles(){let t=["./configs/config.yaml","./configs/config.yml",`./configs/config-${Gt.envLevel}.yaml`,`./configs/config-${Gt.envLevel}.yml`];return iE.getExistingFilesSync(t)}static get instance(){if(Gt._instance===void 0){let t=new yne.TSConvict(Gt);Gt._instance=t.load(Gt.configFiles())}return Gt._instance}static get envLevel(){let t=process.env.NODE_ENV||"dev";return t.startsWith("prod")?"prod":t==="qa"?"qa":t==="local"?"local":"dev"}};En([Gr.Property(Dm)],Gt.prototype,"db",2),En([Gr.Property(Lm)],Gt.prototype,"apigwy",2),En([Gr.Property(sc)],Gt.prototype,"filestore",2),En([Gr.Property({doc:"AWS Account ID for app Lambda function",default:0,env:"AWS_ACCOUNT_ID"})],Gt.prototype,"awsAccountID",2),En([Gr.Property({doc:"AWS Region for app Lambda function",default:"us-east-1",env:"AWS_REGION"})],Gt.prototype,"awsRegion",2),En([Gr.Property({doc:"Role name to be used for temp STS upload tokens",default:"microapps-deployer-upload-dev",env:"UPLOAD_ROLE_NAME"})],Gt.prototype,"uploadRoleName",2),En([Gr.Property({doc:"Path prefix for this deployment",default:"",env:"ROOT_PATH_PREFIX"})],Gt.prototype,"rootPathPrefix",2),En([Gr.Property({doc:"Require IAM Authorization on all created routes",default:!0,env:"REQUIRE_IAM_AUTHORIZATION"})],Gt.prototype,"requireIAMAuthorization",2),Gt=En([Gr.Config({file:"config.yml",validationMethod:"strict",parser:{extension:["yml","yaml"],parse:QY},formats:{url:oE.url,ipaddress:oE.ipaddress}})],Gt);var KL=pn(SC());function XL(e){return e==null||e===""}var Mm=class{static async CreateApp(t){let{dbManager:n,app:r}=t;return XL(r.appName)||XL(r.displayName)||XL(r.type)?{statusCode:400}:await KL.Application.Load({dbManager:n,key:{AppName:r.appName}})!==void 0?{statusCode:200}:(await new KL.Application({AppName:r.appName,DisplayName:r.displayName}).Save(n),{statusCode:201})}};var w2=pn(require("crypto")),vn=pn(mse()),Zt=pn(Bde()),$r=pn(xge()),VT=pn(Cd()),Es=pn(SC()),Kge=pn(Lge());var Xge=pn(Jge()),it=class{};it.Instance=new Xge.LambdaLog({silent:process.env.JEST_WORKER_ID!==void 0});var ji=new Zt.LambdaClient({maxAttempts:8}),gp=new $r.S3Client({maxAttempts:16}),O$t=new VT.STSClient({maxAttempts:8}),hp=new vn.ApiGatewayV2Client({maxAttempts:8}),fn=class{static async DeployVersionPreflight(t){var u,w,E;let{dbManager:n,request:r,config:i}=t,{appName:s,semVer:d,needS3Creds:a=!0,overwrite:c=!1}=r,l=await Es.Version.LoadVersion({dbManager:n,key:{AppName:s,SemVer:d}});if(l!==void 0&&l.Status!=="pending")if(c)it.Instance.info("Warning: App/Version already exists",{appName:r.appName,semVer:r.semVer});else return it.Instance.info("Error: App/Version already exists",{appName:r.appName,semVer:r.semVer}),{statusCode:200};if(it.Instance.info("App/Version does not exist",{appName:s,semVer:d}),a){let T={Statement:[{Effect:"Allow",Action:["s3:PutObject","s3:GetObject","s3:AbortMultipartUpload"],Resource:[`arn:aws:s3:::${i.filestore.stagingBucket}/*`]},{Effect:"Allow",Action:["s3:ListBucket"],Resource:[`arn:aws:s3:::${i.filestore.stagingBucket}`]}],Version:"2012-10-17"};it.Instance.debug("Temp IAM Policy",{policy:JSON.stringify(T)});let P=await O$t.send(new VT.AssumeRoleCommand({RoleArn:`arn:aws:iam::${i.awsAccountID}:role/${i.uploadRoleName}`,DurationSeconds:60*60,RoleSessionName:fn.SHA1Hash(fn.GetBucketPrefix(r,i)),Policy:JSON.stringify(T)}));return it.Instance.info("finished request - returning s3 creds"),{statusCode:404,s3UploadUrl:`s3://${i.filestore.stagingBucket}/${fn.GetBucketPrefix(r,i)}`,awsCredentials:{accessKeyId:(u=P.Credentials)==null?void 0:u.AccessKeyId,secretAccessKey:(w=P.Credentials)==null?void 0:w.SecretAccessKey,sessionToken:(E=P.Credentials)==null?void 0:E.SessionToken}}}else return it.Instance.info("finished request - not returning s3 creds"),{statusCode:404}}static async DeployVersion(t){let{dbManager:n,request:r,config:i}=t,{appType:s="lambda",overwrite:d=!1,startupType:a="iframe"}=r;it.Instance.debug("Got Body:",r);let c=await Es.Version.LoadVersion({dbManager:n,key:{AppName:r.appName,SemVer:r.semVer}});if(c!==void 0&&c.Status==="routed")if(d)it.Instance.info("Warning: App/Version already exists",{appName:r.appName,semVer:r.semVer});else return it.Instance.info("Error: App/Version already exists",{appName:r.appName,semVer:r.semVer}),{statusCode:409};if(a==="direct"&&["lambda"].includes(s))return it.Instance.info("Error: Incompatible app type and startup type",{appType:s,startupType:a}),{statusCode:400};if(d&&c&&(c.DefaultFile=r.defaultFile,c.Type=s,c.StartupType=a,r.lambdaARN&&(c.LambdaARN=r.lambdaARN)),c===void 0&&(c=new Es.Version(o({AppName:r.appName,SemVer:r.semVer,Type:s,Status:"pending",DefaultFile:r.defaultFile,StartupType:a},r.lambdaARN?{LambdaARN:r.lambdaARN}:{})),await c.Save(n)),d||c.Status==="pending"){let{stagingBucket:u}=i.filestore,w=fn.GetBucketPrefix(r,i)+"/";await fn.CopyToProdBucket(u,w,fn.GetBucketPrefix(r,i),i),c.DefaultFile=r.defaultFile,c.Status="assets-copied",await c.Save(n)}if(s==="lambda"){let u=i.apigwy.apiId;if(d||c.Status==="assets-copied"){let E=i.awsAccountID,T=i.awsRegion,P=!0;try{let I=await ji.send(new Zt.GetPolicyCommand({FunctionName:r.lambdaARN}));if(I.Policy!==void 0){let F=JSON.parse(I.Policy);F.Statement!==void 0&&F.Statement.filter(G=>G.Sid==="microapps-version-root"||G.Sid==="microapps-version").length===2&&(P=!1)}}catch(I){if(I.name!=="ResourceNotFoundException")throw I}P&&(await ji.send(new Zt.AddPermissionCommand({Principal:"apigateway.amazonaws.com",StatementId:"microapps-version-root",Action:"lambda:InvokeFunction",FunctionName:r.lambdaARN,SourceArn:`arn:aws:execute-api:${T}:${E}:${u}/*/*/${r.appName}/${r.semVer}`})),await ji.send(new Zt.AddPermissionCommand({Principal:"apigateway.amazonaws.com",StatementId:"microapps-version",Action:"lambda:InvokeFunction",FunctionName:r.lambdaARN,SourceArn:`arn:aws:execute-api:${T}:${E}:${u}/*/*/${r.appName}/${r.semVer}/{proxy+}`}))),c.Status="permissioned",await c.Save(n)}let w="";if(d||c.Status==="permissioned")if(c.IntegrationID!==void 0&&c.IntegrationID!=="")w=c.IntegrationID,it.Instance.info("integration already created, skipping creation",{IntegrationId:w});else{try{w=(await hp.send(new vn.CreateIntegrationCommand({ApiId:u,IntegrationType:vn.IntegrationType.AWS_PROXY,IntegrationMethod:"POST",PayloadFormatVersion:"2.0",IntegrationUri:r.lambdaARN}))).IntegrationId}catch(E){if(E.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException adding integration to API Gateway",{error:E}),{statusCode:401}}c.IntegrationID=w,c.Status="integrated",await c.Save(n)}if(d||c.Status==="integrated"){if(c.RouteIDAppVersion!==void 0&&c.RouteIDAppVersion!=="")it.Instance.info("route app/version already created, skipping creation",{IntegrationId:w,RouteIDAppVersion:c.RouteIDAppVersion});else try{let E=await hp.send(new vn.CreateRouteCommand({ApiId:u,Target:`integrations/${w}`,RouteKey:`ANY /${r.appName}/${r.semVer}`,AuthorizationType:i.requireIAMAuthorization?vn.AuthorizationType.AWS_IAM:vn.AuthorizationType.NONE}));it.Instance.info("created RouteIDAppVersion",{result:E}),c.RouteIDAppVersion=`${E.RouteId}`}catch(E){if(E.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException adding route to API Gateway",{error:E}),{statusCode:401};it.Instance.error("Caught unexpected error on app/ver route add"),it.Instance.error(E)}if(c.RouteIDAppVersionSplat!==void 0&&c.RouteIDAppVersionSplat!=="")it.Instance.info("route app/version/* already created, skipping creation",{IntegrationId:w,RouteIDAppVersionSplat:c.RouteIDAppVersionSplat});else try{let E=await hp.send(new vn.CreateRouteCommand({ApiId:u,Target:`integrations/${w}`,RouteKey:`ANY /${r.appName}/${r.semVer}/{proxy+}`,AuthorizationType:i.requireIAMAuthorization?vn.AuthorizationType.AWS_IAM:vn.AuthorizationType.NONE}));it.Instance.info("created RouteIDAppVersionSplat",{result:E}),c.RouteIDAppVersionSplat=`${E.RouteId}`}catch(E){if(E.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException adding route to API Gateway",{error:E}),{statusCode:401};it.Instance.error("Caught unexpected error on {proxy+} route add"),it.Instance.error(E)}c.Status="routed",await c.Save(n)}}else if(s==="lambda-url"){if(!r.lambdaARN)throw new Error("Missing lambdaARN for lambda-url app type");let{lambdaARNBase:u,lambdaARNAlias:w}=fn.ExtractARNandAlias(r.lambdaARN);if(d||c.Status==="assets-copied"){let E=await ji.send(new Zt.ListTagsCommand({Resource:u}));(E.Tags===void 0||E.Tags["microapp-managed"]!=="true")&&await ji.send(new Zt.TagResourceCommand({Resource:u,Tags:{"microapp-managed":"true"}})),c.Status="permissioned",await c.Save(n)}if(d||c.Status==="permissioned"){let E,T;try{T=await ji.send(new Zt.GetFunctionUrlConfigCommand({FunctionName:u,Qualifier:w})),T.FunctionUrl&&(E=T.FunctionUrl)}catch(P){if(P.name!=="ResourceNotFoundException")throw P}T!=null&&T.FunctionUrl||(E=(await ji.send(new Zt.CreateFunctionUrlConfigCommand({FunctionName:u,Qualifier:w,AuthType:"AWS_IAM"}))).FunctionUrl),c.Status="routed",E&&(c.URL=E),await c.Save(n)}}else if(s==="static")c.Status==="assets-copied"&&(c.Status="routed",await c.Save(n));else throw new Error(`Unknown app type: ${s}`);let l=await Es.Rules.Load({dbManager:n,key:{AppName:r.appName}});return l===void 0&&(l=new Es.Rules({AppName:r.appName,RuleSet:{},Version:1}),l.RuleSet.default={SemVer:r.semVer,AttributeName:"",AttributeValue:""},await l.Save(n)),it.Instance.info("finished request"),{statusCode:201}}static ExtractARNandAlias(t){let n=t==null?void 0:t.substring(0,t.lastIndexOf(":")),r=t==null?void 0:t.substring(t.lastIndexOf(":")+1);return{lambdaARNBase:n,lambdaARNAlias:r}}static async DeleteVersion(t){let{dbManager:n,request:r,config:i}=t;it.Instance.debug("Got Body:",r);let s=await Es.Version.LoadVersion({dbManager:n,key:{AppName:r.appName,SemVer:r.semVer}});if(s===void 0)return it.Instance.info("Error: App/Version does not exist",{appName:r.appName,semVer:r.semVer}),{statusCode:404};let d=fn.GetBucketPrefix(r,i)+"/";if(await this.DeleteFromDestinationBucket(d,i),s.Type==="lambda"){let a=i.apigwy.apiId;if(s.RouteIDAppVersion===""&&s.RouteIDAppVersionSplat==="")it.Instance.warn("no RouteIDs to delete");else{for(let c of[s.RouteIDAppVersion,s.RouteIDAppVersionSplat])try{await hp.send(new vn.DeleteRouteCommand({ApiId:a,RouteId:c}))}catch(l){if(l.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException removing route from API Gateway",{error:l,apiId:a,routeId:c}),{statusCode:401};it.Instance.error("Caught unexpected error on app/ver route remove",{error:l,apiId:a,routeId:c})}if(s.IntegrationID!==void 0&&s.IntegrationID!=="")try{await hp.send(new vn.DeleteIntegrationCommand({ApiId:a,IntegrationId:s.IntegrationID}))}catch(c){if(c.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException removing integration from API Gateway",{error:c,apiId:a,integrationId:s.IntegrationID}),{statusCode:401};it.Instance.error("Caught unexpected error removing integration from API Gateway",{error:c,apiId:a,integrationId:s.IntegrationID})}}}if((s.Type==="lambda"||s.Type==="lambda-url")&&s.LambdaARN){let{lambdaARNBase:a,lambdaARNAlias:c}=fn.ExtractARNandAlias(s.LambdaARN);try{let l=await ji.send(new Zt.GetAliasCommand({FunctionName:a,Name:c}));if(await ji.send(new Zt.DeleteAliasCommand({FunctionName:a,Name:c})),l.FunctionVersion)try{await ji.send(new Zt.DeleteFunctionCommand({FunctionName:a,Qualifier:l.FunctionVersion}))}catch(u){if(u.name!=="ResourceConflictException")throw u;it.Instance.info("Version is still in use by another alias, not deleting")}}catch(l){if(l.name!=="ResourceNotFoundException")throw l}}return await Es.Version.DeleteVersion({dbManager:n,key:{AppName:r.appName,SemVer:r.semVer}}),it.Instance.info("finished request"),{statusCode:200}}static SHA256Hash(t){return w2.default.createHash("sha256").update(t).digest("hex")}static SHA1Hash(t){return w2.default.createHash("sha1").update(t).digest("hex")}static async CopyFilesInList(t,n,r,i,s){t===void 0||t.Contents===void 0||await(0,Kge.default)(t.Contents,async d=>{var c;let a=(c=d.Key)==null?void 0:c.slice(r.length);await gp.send(new $r.CopyObjectCommand({CopySource:`${n}/${d.Key}`,Bucket:s.filestore.destinationBucket,Key:`${i}/${a}`})),await gp.send(new $r.DeleteObjectCommand({Bucket:n,Key:d.Key}))},{concurrency:4})}static async CopyToProdBucket(t,n,r,i){let s;do{let d=(s==null?void 0:s.NextContinuationToken)!==void 0?{ContinuationToken:s.NextContinuationToken}:{};s=await gp.send(new $r.ListObjectsV2Command(o({Bucket:t,Prefix:n},d))),await fn.CopyFilesInList(s,t,n,r,i)}while(s.IsTruncated)}static async DeleteFromDestinationBucket(t,n){var i;let r;do{let s=(r==null?void 0:r.NextContinuationToken)!==void 0?{ContinuationToken:r.NextContinuationToken}:{};r=await gp.send(new $r.ListObjectsV2Command(o({Bucket:n.filestore.destinationBucket,Prefix:t},s)));let d=[];(i=r.Contents)==null||i.map(a=>{d.push({Key:a.Key})}),d.length>0&&await gp.send(new $r.DeleteObjectsCommand({Bucket:n.filestore.destinationBucket,Delete:{Objects:d}}))}while(r.IsTruncated)}static GetBucketPrefix(t,n){return`${n.rootPathPrefix===""?"":`${n.rootPathPrefix}/`}${fn.GetAppNameOrRootTrailingSlash(t)}${t.semVer}`.toLowerCase()}static GetAppNameOrRootTrailingSlash(t){return t.appName==="[root]"?"":`${t.appName}/`}};var B$t=it.Instance,qo,S2=new Wge.DynamoDBClient({maxAttempts:8});function F$t(e){qo=e.dbManager,S2=e.dynamoClient}qo=new y2.DBManager({dynamoClient:S2,tableName:Gt.instance.db.tableName});var wp=Gt.instance;async function j$t(e,t){if(B$t.options.meta={awsRequestId:t==null?void 0:t.awsRequestId,requestType:e.type},qo===void 0&&(qo=new y2.DBManager({dynamoClient:S2,tableName:Gt.instance.db.tableName})),wp.awsAccountID===0&&(t==null?void 0:t.invokedFunctionArn)!==void 0){let r=t.invokedFunctionArn.split(":")[4];r!==""&&(wp.awsAccountID=parseInt(r,10))}it.Instance.info("received request",{request:e});try{switch(e.type){case"createApp":{let n=e;return await Mm.CreateApp({dbManager:qo,app:n})}case"deleteVersion":{let n=e;return await fn.DeleteVersion({dbManager:qo,request:n,config:wp})}case"deployVersionPreflight":{let n=e;return await fn.DeployVersionPreflight({dbManager:qo,request:n,config:wp})}case"deployVersion":{let n=e;return await fn.DeployVersion({dbManager:qo,request:n,config:wp})}default:return{statusCode:400}}}catch(n){return it.Instance.error("Caught unexpected exception in handler"),it.Instance.error(n),{statusCode:500}}}0&&(module.exports={handler,overrideDBManager});
|
|
81
|
+
`:""}var Y8e=Q8e,Z8e={dump:Y8e};function Yq(e,t){return function(){throw new Error("Function yaml."+e+" is removed in js-yaml 4. Use yaml."+t+" instead, which is now safe by default.")}}var QY=BY.load,L4t=BY.loadAll,D4t=Z8e.dump;var M4t=Yq("safeLoad","load"),O4t=Yq("safeLoadAll","loadAll"),B4t=Yq("safeDump","dump");var Gr=pn(Yd()),yne=pn(Yd());var sE=pn(gne()),iE=class{static async getExistingFiles(t){let n=[];for(let r of t)await(0,sE.pathExists)(r)&&n.push(r);return n}static getExistingFilesSync(t){let n=[];for(let r of t)(0,sE.pathExistsSync)(r)&&n.push(r);return n}};var hne=pn(Yd()),Lm=class{};En([(0,hne.Property)({doc:"ID of API Gateway to integrate with",nullable:!1,default:"none",env:"APIGWY_ID"})],Lm.prototype,"apiId",2);var wne=pn(Yd()),Dm=class{};En([(0,wne.Property)({doc:"DynamoDB Table Name",default:"MicroApps",env:"DATABASE_TABLE_NAME"})],Dm.prototype,"tableName",2);var JL=pn(Yd()),sc=class{};En([(0,JL.Property)({doc:"Staging bucket to copy staged apps from",default:"microapps-staging",env:"FILESTORE_STAGING_BUCKET"})],sc.prototype,"stagingBucket",2),En([(0,JL.Property)({doc:"Destination bucket to copy staged apps to",default:"microapps",env:"FILESTORE_DEST_BUCKET"})],sc.prototype,"destinationBucket",2);var Gt=class{static configFiles(){let t=["./configs/config.yaml","./configs/config.yml",`./configs/config-${Gt.envLevel}.yaml`,`./configs/config-${Gt.envLevel}.yml`];return iE.getExistingFilesSync(t)}static get instance(){if(Gt._instance===void 0){let t=new yne.TSConvict(Gt);Gt._instance=t.load(Gt.configFiles())}return Gt._instance}static get envLevel(){let t=process.env.NODE_ENV||"dev";return t.startsWith("prod")?"prod":t==="qa"?"qa":t==="local"?"local":"dev"}};En([Gr.Property(Dm)],Gt.prototype,"db",2),En([Gr.Property(Lm)],Gt.prototype,"apigwy",2),En([Gr.Property(sc)],Gt.prototype,"filestore",2),En([Gr.Property({doc:"AWS Account ID for app Lambda function",default:"",env:"AWS_ACCOUNT_ID"})],Gt.prototype,"awsAccountID",2),En([Gr.Property({doc:"AWS Region for app Lambda function",default:"us-east-1",env:"AWS_REGION"})],Gt.prototype,"awsRegion",2),En([Gr.Property({doc:"Role name to be used for temp STS upload tokens",default:"microapps-deployer-upload-dev",env:"UPLOAD_ROLE_NAME"})],Gt.prototype,"uploadRoleName",2),En([Gr.Property({doc:"Path prefix for this deployment",default:"",env:"ROOT_PATH_PREFIX"})],Gt.prototype,"rootPathPrefix",2),En([Gr.Property({doc:"Require IAM Authorization on all created routes",default:!0,env:"REQUIRE_IAM_AUTHORIZATION"})],Gt.prototype,"requireIAMAuthorization",2),Gt=En([Gr.Config({file:"config.yml",validationMethod:"strict",parser:{extension:["yml","yaml"],parse:QY},formats:{url:oE.url,ipaddress:oE.ipaddress}})],Gt);var KL=pn(SC());function XL(e){return e==null||e===""}var Mm=class{static async CreateApp(t){let{dbManager:n,app:r}=t;return XL(r.appName)||XL(r.displayName)||XL(r.type)?{statusCode:400}:await KL.Application.Load({dbManager:n,key:{AppName:r.appName}})!==void 0?{statusCode:200}:(await new KL.Application({AppName:r.appName,DisplayName:r.displayName}).Save(n),{statusCode:201})}};var w2=pn(require("crypto")),vn=pn(mse()),Zt=pn(Bde()),$r=pn(xge()),VT=pn(Cd()),Es=pn(SC()),Kge=pn(Lge());var Xge=pn(Jge()),it=class{};it.Instance=new Xge.LambdaLog({silent:process.env.JEST_WORKER_ID!==void 0});var ji=new Zt.LambdaClient({maxAttempts:8}),gp=new $r.S3Client({maxAttempts:16}),O$t=new VT.STSClient({maxAttempts:8}),hp=new vn.ApiGatewayV2Client({maxAttempts:8}),fn=class{static async DeployVersionPreflight(t){var u,w,E;let{dbManager:n,request:r,config:i}=t,{appName:s,semVer:d,needS3Creds:a=!0,overwrite:c=!1}=r,l=await Es.Version.LoadVersion({dbManager:n,key:{AppName:s,SemVer:d}});if(l!==void 0&&l.Status!=="pending")if(c)it.Instance.info("Warning: App/Version already exists",{appName:r.appName,semVer:r.semVer});else return it.Instance.info("Error: App/Version already exists",{appName:r.appName,semVer:r.semVer}),{statusCode:200};if(it.Instance.info("App/Version does not exist",{appName:s,semVer:d}),a){let T={Statement:[{Effect:"Allow",Action:["s3:PutObject","s3:GetObject","s3:AbortMultipartUpload"],Resource:[`arn:aws:s3:::${i.filestore.stagingBucket}/*`]},{Effect:"Allow",Action:["s3:ListBucket"],Resource:[`arn:aws:s3:::${i.filestore.stagingBucket}`]}],Version:"2012-10-17"};it.Instance.debug("Temp IAM Policy",{policy:JSON.stringify(T)});let P=await O$t.send(new VT.AssumeRoleCommand({RoleArn:`arn:aws:iam::${i.awsAccountID}:role/${i.uploadRoleName}`,DurationSeconds:60*60,RoleSessionName:fn.SHA1Hash(fn.GetBucketPrefix(r,i)),Policy:JSON.stringify(T)}));return it.Instance.info("finished request - returning s3 creds"),{statusCode:404,s3UploadUrl:`s3://${i.filestore.stagingBucket}/${fn.GetBucketPrefix(r,i)}`,awsCredentials:{accessKeyId:(u=P.Credentials)==null?void 0:u.AccessKeyId,secretAccessKey:(w=P.Credentials)==null?void 0:w.SecretAccessKey,sessionToken:(E=P.Credentials)==null?void 0:E.SessionToken}}}else return it.Instance.info("finished request - not returning s3 creds"),{statusCode:404}}static async DeployVersion(t){let{dbManager:n,request:r,config:i}=t,{appType:s="lambda",overwrite:d=!1,startupType:a="iframe"}=r;it.Instance.debug("Got Body:",r);let c=await Es.Version.LoadVersion({dbManager:n,key:{AppName:r.appName,SemVer:r.semVer}});if(c!==void 0&&c.Status==="routed")if(d)it.Instance.info("Warning: App/Version already exists",{appName:r.appName,semVer:r.semVer});else return it.Instance.info("Error: App/Version already exists",{appName:r.appName,semVer:r.semVer}),{statusCode:409};if(a==="direct"&&["lambda"].includes(s))return it.Instance.info("Error: Incompatible app type and startup type",{appType:s,startupType:a}),{statusCode:400};if(d&&c&&(c.DefaultFile=r.defaultFile,c.Type=s,c.StartupType=a,r.lambdaARN&&(c.LambdaARN=r.lambdaARN)),c===void 0&&(c=new Es.Version(o({AppName:r.appName,SemVer:r.semVer,Type:s,Status:"pending",DefaultFile:r.defaultFile,StartupType:a},r.lambdaARN?{LambdaARN:r.lambdaARN}:{})),await c.Save(n)),d||c.Status==="pending"){let{stagingBucket:u}=i.filestore,w=fn.GetBucketPrefix(r,i)+"/";await fn.CopyToProdBucket(u,w,fn.GetBucketPrefix(r,i),i),c.DefaultFile=r.defaultFile,c.Status="assets-copied",await c.Save(n)}if(s==="lambda"){let u=i.apigwy.apiId;if(d||c.Status==="assets-copied"){let E=i.awsAccountID,T=i.awsRegion,P=!0;try{let I=await ji.send(new Zt.GetPolicyCommand({FunctionName:r.lambdaARN}));if(I.Policy!==void 0){let F=JSON.parse(I.Policy);F.Statement!==void 0&&F.Statement.filter(G=>G.Sid==="microapps-version-root"||G.Sid==="microapps-version").length===2&&(P=!1)}}catch(I){if(I.name!=="ResourceNotFoundException")throw I}P&&(await ji.send(new Zt.AddPermissionCommand({Principal:"apigateway.amazonaws.com",StatementId:"microapps-version-root",Action:"lambda:InvokeFunction",FunctionName:r.lambdaARN,SourceArn:`arn:aws:execute-api:${T}:${E}:${u}/*/*/${r.appName}/${r.semVer}`})),await ji.send(new Zt.AddPermissionCommand({Principal:"apigateway.amazonaws.com",StatementId:"microapps-version",Action:"lambda:InvokeFunction",FunctionName:r.lambdaARN,SourceArn:`arn:aws:execute-api:${T}:${E}:${u}/*/*/${r.appName}/${r.semVer}/{proxy+}`}))),c.Status="permissioned",await c.Save(n)}let w="";if(d||c.Status==="permissioned")if(c.IntegrationID!==void 0&&c.IntegrationID!=="")w=c.IntegrationID,it.Instance.info("integration already created, skipping creation",{IntegrationId:w});else{try{w=(await hp.send(new vn.CreateIntegrationCommand({ApiId:u,IntegrationType:vn.IntegrationType.AWS_PROXY,IntegrationMethod:"POST",PayloadFormatVersion:"2.0",IntegrationUri:r.lambdaARN}))).IntegrationId}catch(E){if(E.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException adding integration to API Gateway",{error:E}),{statusCode:401}}c.IntegrationID=w,c.Status="integrated",await c.Save(n)}if(d||c.Status==="integrated"){if(c.RouteIDAppVersion!==void 0&&c.RouteIDAppVersion!=="")it.Instance.info("route app/version already created, skipping creation",{IntegrationId:w,RouteIDAppVersion:c.RouteIDAppVersion});else try{let E=await hp.send(new vn.CreateRouteCommand({ApiId:u,Target:`integrations/${w}`,RouteKey:`ANY /${r.appName}/${r.semVer}`,AuthorizationType:i.requireIAMAuthorization?vn.AuthorizationType.AWS_IAM:vn.AuthorizationType.NONE}));it.Instance.info("created RouteIDAppVersion",{result:E}),c.RouteIDAppVersion=`${E.RouteId}`}catch(E){if(E.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException adding route to API Gateway",{error:E}),{statusCode:401};it.Instance.error("Caught unexpected error on app/ver route add"),it.Instance.error(E)}if(c.RouteIDAppVersionSplat!==void 0&&c.RouteIDAppVersionSplat!=="")it.Instance.info("route app/version/* already created, skipping creation",{IntegrationId:w,RouteIDAppVersionSplat:c.RouteIDAppVersionSplat});else try{let E=await hp.send(new vn.CreateRouteCommand({ApiId:u,Target:`integrations/${w}`,RouteKey:`ANY /${r.appName}/${r.semVer}/{proxy+}`,AuthorizationType:i.requireIAMAuthorization?vn.AuthorizationType.AWS_IAM:vn.AuthorizationType.NONE}));it.Instance.info("created RouteIDAppVersionSplat",{result:E}),c.RouteIDAppVersionSplat=`${E.RouteId}`}catch(E){if(E.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException adding route to API Gateway",{error:E}),{statusCode:401};it.Instance.error("Caught unexpected error on {proxy+} route add"),it.Instance.error(E)}c.Status="routed",await c.Save(n)}}else if(s==="lambda-url"){if(!r.lambdaARN)throw new Error("Missing lambdaARN for lambda-url app type");let{lambdaARNBase:u,lambdaARNAlias:w}=fn.ExtractARNandAlias(r.lambdaARN);if(d||c.Status==="assets-copied"){let E=await ji.send(new Zt.ListTagsCommand({Resource:u}));(E.Tags===void 0||E.Tags["microapp-managed"]!=="true")&&await ji.send(new Zt.TagResourceCommand({Resource:u,Tags:{"microapp-managed":"true"}})),c.Status="permissioned",await c.Save(n)}if(d||c.Status==="permissioned"){let E,T;try{T=await ji.send(new Zt.GetFunctionUrlConfigCommand({FunctionName:u,Qualifier:w})),T.FunctionUrl&&(E=T.FunctionUrl)}catch(P){if(P.name!=="ResourceNotFoundException")throw P}T!=null&&T.FunctionUrl||(E=(await ji.send(new Zt.CreateFunctionUrlConfigCommand({FunctionName:u,Qualifier:w,AuthType:"AWS_IAM"}))).FunctionUrl),c.Status="routed",E&&(c.URL=E),await c.Save(n)}}else if(s==="static")c.Status==="assets-copied"&&(c.Status="routed",await c.Save(n));else throw new Error(`Unknown app type: ${s}`);let l=await Es.Rules.Load({dbManager:n,key:{AppName:r.appName}});return l===void 0&&(l=new Es.Rules({AppName:r.appName,RuleSet:{},Version:1}),l.RuleSet.default={SemVer:r.semVer,AttributeName:"",AttributeValue:""},await l.Save(n)),it.Instance.info("finished request"),{statusCode:201}}static ExtractARNandAlias(t){let n=t==null?void 0:t.substring(0,t.lastIndexOf(":")),r=t==null?void 0:t.substring(t.lastIndexOf(":")+1);return{lambdaARNBase:n,lambdaARNAlias:r}}static async DeleteVersion(t){let{dbManager:n,request:r,config:i}=t;it.Instance.debug("Got Body:",r);let s=await Es.Version.LoadVersion({dbManager:n,key:{AppName:r.appName,SemVer:r.semVer}});if(s===void 0)return it.Instance.info("Error: App/Version does not exist",{appName:r.appName,semVer:r.semVer}),{statusCode:404};let d=fn.GetBucketPrefix(r,i)+"/";if(await this.DeleteFromDestinationBucket(d,i),s.Type==="lambda"){let a=i.apigwy.apiId;if(s.RouteIDAppVersion===""&&s.RouteIDAppVersionSplat==="")it.Instance.warn("no RouteIDs to delete");else{for(let c of[s.RouteIDAppVersion,s.RouteIDAppVersionSplat])try{await hp.send(new vn.DeleteRouteCommand({ApiId:a,RouteId:c}))}catch(l){if(l.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException removing route from API Gateway",{error:l,apiId:a,routeId:c}),{statusCode:401};it.Instance.error("Caught unexpected error on app/ver route remove",{error:l,apiId:a,routeId:c})}if(s.IntegrationID!==void 0&&s.IntegrationID!=="")try{await hp.send(new vn.DeleteIntegrationCommand({ApiId:a,IntegrationId:s.IntegrationID}))}catch(c){if(c.name==="AccessDeniedException")return it.Instance.error("AccessDeniedException removing integration from API Gateway",{error:c,apiId:a,integrationId:s.IntegrationID}),{statusCode:401};it.Instance.error("Caught unexpected error removing integration from API Gateway",{error:c,apiId:a,integrationId:s.IntegrationID})}}}if((s.Type==="lambda"||s.Type==="lambda-url")&&s.LambdaARN){let{lambdaARNBase:a,lambdaARNAlias:c}=fn.ExtractARNandAlias(s.LambdaARN);try{let l=await ji.send(new Zt.GetAliasCommand({FunctionName:a,Name:c}));if(await ji.send(new Zt.DeleteAliasCommand({FunctionName:a,Name:c})),l.FunctionVersion)try{await ji.send(new Zt.DeleteFunctionCommand({FunctionName:a,Qualifier:l.FunctionVersion}))}catch(u){if(u.name!=="ResourceConflictException")throw u;it.Instance.info("Version is still in use by another alias, not deleting")}}catch(l){if(l.name!=="ResourceNotFoundException")throw l}}return await Es.Version.DeleteVersion({dbManager:n,key:{AppName:r.appName,SemVer:r.semVer}}),it.Instance.info("finished request"),{statusCode:200}}static SHA256Hash(t){return w2.default.createHash("sha256").update(t).digest("hex")}static SHA1Hash(t){return w2.default.createHash("sha1").update(t).digest("hex")}static async CopyFilesInList(t,n,r,i,s){t===void 0||t.Contents===void 0||await(0,Kge.default)(t.Contents,async d=>{var c;let a=(c=d.Key)==null?void 0:c.slice(r.length);await gp.send(new $r.CopyObjectCommand({CopySource:`${n}/${d.Key}`,Bucket:s.filestore.destinationBucket,Key:`${i}/${a}`})),await gp.send(new $r.DeleteObjectCommand({Bucket:n,Key:d.Key}))},{concurrency:4})}static async CopyToProdBucket(t,n,r,i){let s;do{let d=(s==null?void 0:s.NextContinuationToken)!==void 0?{ContinuationToken:s.NextContinuationToken}:{};s=await gp.send(new $r.ListObjectsV2Command(o({Bucket:t,Prefix:n},d))),await fn.CopyFilesInList(s,t,n,r,i)}while(s.IsTruncated)}static async DeleteFromDestinationBucket(t,n){var i;let r;do{let s=(r==null?void 0:r.NextContinuationToken)!==void 0?{ContinuationToken:r.NextContinuationToken}:{};r=await gp.send(new $r.ListObjectsV2Command(o({Bucket:n.filestore.destinationBucket,Prefix:t},s)));let d=[];(i=r.Contents)==null||i.map(a=>{d.push({Key:a.Key})}),d.length>0&&await gp.send(new $r.DeleteObjectsCommand({Bucket:n.filestore.destinationBucket,Delete:{Objects:d}}))}while(r.IsTruncated)}static GetBucketPrefix(t,n){return`${n.rootPathPrefix===""?"":`${n.rootPathPrefix}/`}${fn.GetAppNameOrRootTrailingSlash(t)}${t.semVer}`.toLowerCase()}static GetAppNameOrRootTrailingSlash(t){return t.appName==="[root]"?"":`${t.appName}/`}};var B$t=it.Instance,qo,S2=new Wge.DynamoDBClient({maxAttempts:8});function F$t(e){qo=e.dbManager,S2=e.dynamoClient}qo=new y2.DBManager({dynamoClient:S2,tableName:Gt.instance.db.tableName});var wp=Gt.instance;async function j$t(e,t){if(B$t.options.meta={awsRequestId:t==null?void 0:t.awsRequestId,requestType:e.type},qo===void 0&&(qo=new y2.DBManager({dynamoClient:S2,tableName:Gt.instance.db.tableName})),wp.awsAccountID===""&&(t==null?void 0:t.invokedFunctionArn)!==void 0){let r=t.invokedFunctionArn.split(":")[4];r!==""&&(wp.awsAccountID=r)}it.Instance.info("received request",{request:e});try{switch(e.type){case"createApp":{let n=e;return await Mm.CreateApp({dbManager:qo,app:n})}case"deleteVersion":{let n=e;return await fn.DeleteVersion({dbManager:qo,request:n,config:wp})}case"deployVersionPreflight":{let n=e;return await fn.DeployVersionPreflight({dbManager:qo,request:n,config:wp})}case"deployVersion":{let n=e;return await fn.DeployVersion({dbManager:qo,request:n,config:wp})}default:return{statusCode:400}}}catch(n){return it.Instance.error("Caught unexpected exception in handler"),it.Instance.error(n),{statusCode:500}}}0&&(module.exports={handler,overrideDBManager});
|
|
82
82
|
/*! *****************************************************************************
|
|
83
83
|
Copyright (C) Microsoft. All rights reserved.
|
|
84
84
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|