@fjall/util 2.34.0 → 3.0.0

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.
Files changed (71) hide show
  1. package/dist/.minified +1 -1
  2. package/dist/async/concurrency.js +1 -1
  3. package/dist/async/singleton.js +1 -1
  4. package/dist/async/sleep.js +1 -1
  5. package/dist/aws/CloudFormationFailureAnalyser.js +1 -1
  6. package/dist/aws/cloudformationTypes.js +1 -1
  7. package/dist/aws/deployProgress.js +1 -1
  8. package/dist/aws/driftSuspects.js +1 -1
  9. package/dist/aws/errors.js +1 -1
  10. package/dist/aws/ipamTags.js +1 -1
  11. package/dist/aws/maskFailureAnalysis.js +1 -1
  12. package/dist/buildConcurrency.js +1 -1
  13. package/dist/cdkTmpdirCleanup.js +1 -1
  14. package/dist/config.js +1 -1
  15. package/dist/constructMap.js +1 -1
  16. package/dist/docker/DockerCli.build.js +1 -1
  17. package/dist/docker/DockerCli.daemon.js +1 -1
  18. package/dist/docker/DockerCli.js +1 -1
  19. package/dist/docker/DockerCli.registry.js +3 -3
  20. package/dist/docker/abortHelpers.js +1 -1
  21. package/dist/docker/bakeGuard.js +1 -1
  22. package/dist/docker/buildArgInference.js +1 -1
  23. package/dist/docker/buildxArgvBuilder.js +1 -1
  24. package/dist/docker/buildxBuildMonitor.js +1 -1
  25. package/dist/docker/cacheRepository.js +1 -1
  26. package/dist/docker/dockerCliSchemas.js +1 -1
  27. package/dist/docker/ecrCredentialStore.js +1 -1
  28. package/dist/docker/metadataFileParser.js +1 -1
  29. package/dist/docker/projectBuildxResult.js +1 -1
  30. package/dist/docker/rawjsonParser.js +1 -1
  31. package/dist/docker/rawjsonToVertexEvent.js +1 -1
  32. package/dist/docker/result.js +1 -1
  33. package/dist/environments.js +1 -1
  34. package/dist/errorUtils.js +1 -1
  35. package/dist/fsHelpers.js +1 -1
  36. package/dist/index.d.ts +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/infra/deployArtefacts.js +1 -1
  39. package/dist/infra/deriveContentHashTag.js +1 -1
  40. package/dist/infra/domainExports.d.ts +28 -0
  41. package/dist/infra/domainExports.js +1 -1
  42. package/dist/infra/imageTags.js +1 -1
  43. package/dist/infra/regions.js +1 -1
  44. package/dist/insights/computePatternFingerprint.js +1 -1
  45. package/dist/logger.js +2 -2
  46. package/dist/manifest/io.js +1 -1
  47. package/dist/manifest/schemas.js +1 -1
  48. package/dist/mcpProtocol/index.js +1 -1
  49. package/dist/migration/clickhouseSqlUsers.js +1 -1
  50. package/dist/migration/compareSchemaVersion.js +1 -1
  51. package/dist/migration/pickLatestClickHouseMigration.js +1 -1
  52. package/dist/migration/pickLatestPrismaMigration.js +1 -1
  53. package/dist/migration/verifyExpectedSchemaVersion.js +1 -1
  54. package/dist/migration/verifyExpectedSchemaVersion.test.js +1 -1
  55. package/dist/naming/accountNameCollision.js +1 -1
  56. package/dist/naming/caseConversion.js +1 -1
  57. package/dist/naming/connectedAccountName.js +1 -1
  58. package/dist/naming/reservedAppNames.js +1 -1
  59. package/dist/patterns/patternTypes.js +1 -1
  60. package/dist/patterns/staticSiteForms.js +1 -1
  61. package/dist/repo/appPath.js +1 -1
  62. package/dist/repo/findInfrastructurePaths.js +1 -1
  63. package/dist/repo/findRepoRoot.js +1 -1
  64. package/dist/repo/gitRemoteParser.js +1 -1
  65. package/dist/repo/inferContainerFromCandidates.js +1 -1
  66. package/dist/repo/scanLocalRepository.js +1 -1
  67. package/dist/resourceCategorisation.js +1 -1
  68. package/dist/secrets.js +3 -3
  69. package/dist/securityHelpers.js +1 -1
  70. package/dist/targets.js +1 -1
  71. package/package.json +2 -2
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 87 files minified at 2026-07-17T22:47:13.831Z
1
+ 87 files minified at 2026-07-18T01:56:02.234Z
@@ -1 +1 @@
1
- async function h(t,c,l){const e=new Array(t.length);if(t.length===0)return e;const o=Math.max(1,Math.min(c,t.length));let a=0;const s=async()=>{for(;a<t.length;){const n=a++;try{const r=await l(t[n],n);e[n]={status:"fulfilled",value:r}}catch(r){e[n]={status:"rejected",reason:r}}}};return await Promise.all(Array.from({length:o},()=>s())),e}export{h as mapSettledWithConcurrency};
1
+ var u=Object.defineProperty;var c=(t,r)=>u(t,"name",{value:r,configurable:!0});async function f(t,r,o){const e=new Array(t.length);if(t.length===0)return e;const s=Math.max(1,Math.min(r,t.length));let l=0;const h=c(async()=>{for(;l<t.length;){const n=l++;try{const a=await o(t[n],n);e[n]={status:"fulfilled",value:a}}catch(a){e[n]={status:"rejected",reason:a}}}},"worker");return await Promise.all(Array.from({length:s},()=>h())),e}c(f,"mapSettledWithConcurrency");export{f as mapSettledWithConcurrency};
@@ -1 +1 @@
1
- function r(t){let e,n=!1;return()=>(n||(e=t(),n=!0),e)}export{r as singleton};
1
+ var s=Object.defineProperty;var r=(n,e)=>s(n,"name",{value:e,configurable:!0});function i(n){let e,t=!1;return()=>(t||(e=n(),t=!0),e)}r(i,"singleton");export{i as singleton};
@@ -1 +1 @@
1
- const s=e=>new Promise(o=>setTimeout(o,e));export{s as sleep};
1
+ var t=Object.defineProperty;var s=(e,o)=>t(e,"name",{value:o,configurable:!0});const m=s(e=>new Promise(o=>setTimeout(o,e)),"sleep");export{m as sleep};
@@ -1 +1 @@
1
- import{classifyDriftSuspectEvents as c,findCurrentOperationStart as d}from"./driftSuspects.js";class f{knownErrorPatterns=[{pattern:/AccessDenied|UnauthorizedOperation|Forbidden/i,category:"permissions",remediation:["Check IAM permissions for the deployment role","Ensure the role has necessary CloudFormation permissions","Verify service-linked roles are created if needed"]},{pattern:/Invalid.*Parameter|ValidationError|Invalid.*Value/i,category:"validation",remediation:["Review parameter values in your CDK code","Check for typos in resource names or ARNs","Ensure all required parameters are provided"]},{pattern:/Limit.*Exceeded|Quota.*Exceeded|Maximum.*reached/i,category:"limit",remediation:["Check AWS service quotas in the Service Quotas console","Request a quota increase if needed","Consider using a different region with available capacity"]},{pattern:/Timeout|Connection.*refused|Network.*unreachable/i,category:"network",remediation:["Check network connectivity and VPC settings","Verify security groups and NACLs","Ensure endpoints are accessible"]},{pattern:/already exists|Duplicate|ConflictException/i,category:"validation",remediation:["Resource with this name already exists","Consider using a different name or deleting the existing resource","Check if you are deploying to the correct account/region"]},{pattern:/Role.*not.*found|Role.*does.*not.*exist/i,category:"dependency",remediation:["Ensure IAM roles are created before dependent resources","Check role names and ARNs are correct","Verify cross-stack references are properly configured"]}];analyseFailure(e,t){const r=this.findFailedResources(e);if(r.length===0)return null;const s=this.findRootCause(r,e),n=this.buildDependencyChain(s.resource,r),i=this.classifyDriftSuspects(e,t),o=this.generateRemediation(s);i.length>0&&o.unshift("One or more resources CloudFormation still tracks appear to have been deleted outside CloudFormation","Run 'fjall drift detect' to confirm the deletion; confirmed deletions are remediated with 'fjall drift repair'");const a=this.generateSummary(s,r);return{rootCause:s,affectedResources:r,dependencyChain:n,summary:a,remediation:o,errorPattern:s.category,...i.length>0?{driftSuspects:i}:{}}}classifyDriftSuspects(e,t){const r=t!==void 0?d(e.get(t)??[],t):null;if(t!==void 0&&r===null)return[];const s=[];for(const n of e.values())for(const i of n)this.isFailedStatus(i.status)&&(r!==null&&i.timestamp.getTime()<r.getTime()||s.push(i));return c(s)}findFailedResources(e){const t=[];for(const[r,s]of e){const n=s[s.length-1];n&&this.isFailedStatus(n.status)&&t.push(n)}return t.sort((r,s)=>r.timestamp.getTime()-s.timestamp.getTime())}findRootCause(e,t){if(e.length===0)return{resource:{logicalId:"Unknown",resourceType:"Unknown",status:"FAILED",timestamp:new Date},reason:"No failed resources found",category:"unknown",isDirectCause:!1};const r=e[0],s=this.categoriseError(r.statusReason||""),n=this.isDirectCause(r,t);return{resource:r,reason:r.statusReason||"Unknown error",category:s,isDirectCause:n}}categoriseError(e){for(const t of this.knownErrorPatterns)if(t.pattern.test(e))return t.category;return"unknown"}isDirectCause(e,t){const r=e.statusReason||"";return r.includes("depends on")||r.includes("referenced by")||r.includes("required by")?!1:!(t.get(e.logicalId)||[]).some(i=>i.status.includes("COMPLETE")&&!i.status.includes("ROLLBACK"))}buildDependencyChain(e,t){const r=[];r.push(`${e.logicalId} (${e.resourceType}) - ROOT CAUSE`);for(const s of t)s.logicalId!==e.logicalId&&((s.statusReason||"").toLowerCase().includes(e.logicalId.toLowerCase())?r.push(` \u2192 ${s.logicalId} (${s.resourceType}) - Failed due to ${e.logicalId}`):r.push(` \u2192 ${s.logicalId} (${s.resourceType})`));return r}generateRemediation(e){const t=[];for(const r of this.knownErrorPatterns)if(r.category===e.category){t.push(...r.remediation);break}return e.resource.resourceType.includes("IAM")?t.push("Review IAM policies and trust relationships"):e.resource.resourceType.includes("Lambda")?t.push("Check Lambda function configuration and runtime"):e.resource.resourceType.includes("ECS")&&t.push("Verify ECS task definition and container configuration"),t.length===0&&t.push("Review the CloudFormation console for detailed error messages","Check the resource configuration in your CDK code","Ensure all dependencies are properly defined"),t}generateSummary(e,t){const r=this.simplifyResourceType(e.resource.resourceType),s=t.length;let n=`Deployment failed: ${r} "${e.resource.logicalId}" `;switch(e.category){case"permissions":n+="failed due to insufficient permissions";break;case"validation":n+="failed validation";break;case"dependency":n+="has missing or invalid dependencies";break;case"limit":n+="exceeded AWS service limits";break;case"network":n+="encountered network issues";break;default:n+="failed to create"}return s>1&&(n+=` (${s-1} dependent resources also failed)`),n}simplifyResourceType(e){return e.replace("AWS::","").replace("::"," ")}isFailedStatus(e){return e.includes("FAILED")}}export{f as CloudFormationFailureAnalyser};
1
+ var u=Object.defineProperty;var c=(o,e)=>u(o,"name",{value:e,configurable:!0});import{classifyDriftSuspectEvents as l,findCurrentOperationStart as f}from"./driftSuspects.js";class m{static{c(this,"CloudFormationFailureAnalyser")}knownErrorPatterns=[{pattern:/AccessDenied|UnauthorizedOperation|Forbidden/i,category:"permissions",remediation:["Check IAM permissions for the deployment role","Ensure the role has necessary CloudFormation permissions","Verify service-linked roles are created if needed"]},{pattern:/Invalid.*Parameter|ValidationError|Invalid.*Value/i,category:"validation",remediation:["Review parameter values in your CDK code","Check for typos in resource names or ARNs","Ensure all required parameters are provided"]},{pattern:/Limit.*Exceeded|Quota.*Exceeded|Maximum.*reached/i,category:"limit",remediation:["Check AWS service quotas in the Service Quotas console","Request a quota increase if needed","Consider using a different region with available capacity"]},{pattern:/Timeout|Connection.*refused|Network.*unreachable/i,category:"network",remediation:["Check network connectivity and VPC settings","Verify security groups and NACLs","Ensure endpoints are accessible"]},{pattern:/already exists|Duplicate|ConflictException/i,category:"validation",remediation:["Resource with this name already exists","Consider using a different name or deleting the existing resource","Check if you are deploying to the correct account/region"]},{pattern:/Role.*not.*found|Role.*does.*not.*exist/i,category:"dependency",remediation:["Ensure IAM roles are created before dependent resources","Check role names and ARNs are correct","Verify cross-stack references are properly configured"]}];analyseFailure(e,t){const r=this.findFailedResources(e);if(r.length===0)return null;const s=this.findRootCause(r,e),n=this.buildDependencyChain(s.resource,r),i=this.classifyDriftSuspects(e,t),a=this.generateRemediation(s);i.length>0&&a.unshift("One or more resources CloudFormation still tracks appear to have been deleted outside CloudFormation","Run 'fjall drift detect' to confirm the deletion; confirmed deletions are remediated with 'fjall drift repair'");const d=this.generateSummary(s,r);return{rootCause:s,affectedResources:r,dependencyChain:n,summary:d,remediation:a,errorPattern:s.category,...i.length>0?{driftSuspects:i}:{}}}classifyDriftSuspects(e,t){const r=t!==void 0?f(e.get(t)??[],t):null;if(t!==void 0&&r===null)return[];const s=[];for(const n of e.values())for(const i of n)this.isFailedStatus(i.status)&&(r!==null&&i.timestamp.getTime()<r.getTime()||s.push(i));return l(s)}findFailedResources(e){const t=[];for(const[r,s]of e){const n=s[s.length-1];n&&this.isFailedStatus(n.status)&&t.push(n)}return t.sort((r,s)=>r.timestamp.getTime()-s.timestamp.getTime())}findRootCause(e,t){if(e.length===0)return{resource:{logicalId:"Unknown",resourceType:"Unknown",status:"FAILED",timestamp:new Date},reason:"No failed resources found",category:"unknown",isDirectCause:!1};const r=e[0],s=this.categoriseError(r.statusReason||""),n=this.isDirectCause(r,t);return{resource:r,reason:r.statusReason||"Unknown error",category:s,isDirectCause:n}}categoriseError(e){for(const t of this.knownErrorPatterns)if(t.pattern.test(e))return t.category;return"unknown"}isDirectCause(e,t){const r=e.statusReason||"";return r.includes("depends on")||r.includes("referenced by")||r.includes("required by")?!1:!(t.get(e.logicalId)||[]).some(i=>i.status.includes("COMPLETE")&&!i.status.includes("ROLLBACK"))}buildDependencyChain(e,t){const r=[];r.push(`${e.logicalId} (${e.resourceType}) - ROOT CAUSE`);for(const s of t)s.logicalId!==e.logicalId&&((s.statusReason||"").toLowerCase().includes(e.logicalId.toLowerCase())?r.push(` \u2192 ${s.logicalId} (${s.resourceType}) - Failed due to ${e.logicalId}`):r.push(` \u2192 ${s.logicalId} (${s.resourceType})`));return r}generateRemediation(e){const t=[];for(const r of this.knownErrorPatterns)if(r.category===e.category){t.push(...r.remediation);break}return e.resource.resourceType.includes("IAM")?t.push("Review IAM policies and trust relationships"):e.resource.resourceType.includes("Lambda")?t.push("Check Lambda function configuration and runtime"):e.resource.resourceType.includes("ECS")&&t.push("Verify ECS task definition and container configuration"),t.length===0&&t.push("Review the CloudFormation console for detailed error messages","Check the resource configuration in your CDK code","Ensure all dependencies are properly defined"),t}generateSummary(e,t){const r=this.simplifyResourceType(e.resource.resourceType),s=t.length;let n=`Deployment failed: ${r} "${e.resource.logicalId}" `;switch(e.category){case"permissions":n+="failed due to insufficient permissions";break;case"validation":n+="failed validation";break;case"dependency":n+="has missing or invalid dependencies";break;case"limit":n+="exceeded AWS service limits";break;case"network":n+="encountered network issues";break;default:n+="failed to create"}return s>1&&(n+=` (${s-1} dependent resources also failed)`),n}simplifyResourceType(e){return e.replace("AWS::","").replace("::"," ")}isFailedStatus(e){return e.includes("FAILED")}}export{m as CloudFormationFailureAnalyser};
@@ -1 +1 @@
1
- const o="does not exist",e="No stacks match the name(s)";function i(t){if(typeof t!="object"||t===null||!("logicalId"in t)||!("resourceType"in t)||!("status"in t)||!("timestamp"in t))return!1;const s=t;return typeof s.logicalId=="string"&&typeof s.resourceType=="string"&&typeof s.status=="string"&&s.timestamp instanceof Date}export{e as CDK_NO_STACKS_MATCH,o as STACK_NOT_FOUND_PATTERN,i as isResourceEvent};
1
+ var e=Object.defineProperty;var o=(t,s)=>e(t,"name",{value:s,configurable:!0});const r="does not exist",n="No stacks match the name(s)";function c(t){if(typeof t!="object"||t===null||!("logicalId"in t)||!("resourceType"in t)||!("status"in t)||!("timestamp"in t))return!1;const s=t;return typeof s.logicalId=="string"&&typeof s.resourceType=="string"&&typeof s.status=="string"&&s.timestamp instanceof Date}o(c,"isResourceEvent");export{n as CDK_NO_STACKS_MATCH,r as STACK_NOT_FOUND_PATTERN,c as isResourceEvent};
@@ -1 +1 @@
1
- function c(e){return e.includes("COMPLETE")&&!e.includes("ROLLBACK")}function l(e){return e.includes("FAILED")||e.includes("ROLLBACK")}function u(e){return e.includes("IN_PROGRESS")}function f(e){let n=0,r=0,o=0,t=0;for(const s of e)t++,c(s)?n++:l(s)?o++:u(s)&&r++;const i=t===0?0:Math.min(100,Math.round(n/t*100));return{completed:n,inProgress:r,failed:o,total:t,percentage:i}}function a(e){const n=Math.max(0,Math.floor(e/1e3)),r=Math.floor(n/3600),o=Math.floor(n%3600/60),t=n%60;return r>0?`${r}h ${o}m ${t}s`:o>0?`${o}m ${t}s`:`${t}s`}export{f as countResourceProgress,a as formatElapsed};
1
+ var l=Object.defineProperty;var r=(e,t)=>l(e,"name",{value:t,configurable:!0});function u(e){return e.includes("COMPLETE")&&!e.includes("ROLLBACK")}r(u,"isComplete");function f(e){return e.includes("FAILED")||e.includes("ROLLBACK")}r(f,"isFailed");function a(e){return e.includes("IN_PROGRESS")}r(a,"isInProgress");function h(e){let t=0,s=0,o=0,n=0;for(const i of e)n++,u(i)?t++:f(i)?o++:a(i)&&s++;const c=n===0?0:Math.min(100,Math.round(t/n*100));return{completed:t,inProgress:s,failed:o,total:n,percentage:c}}r(h,"countResourceProgress");function m(e){const t=Math.max(0,Math.floor(e/1e3)),s=Math.floor(t/3600),o=Math.floor(t%3600/60),n=t%60;return s>0?`${s}h ${o}m ${n}s`:o>0?`${o}m ${n}s`:`${n}s`}r(m,"formatElapsed");export{h as countResourceProgress,m as formatElapsed};
@@ -1 +1 @@
1
- const o=new Set(["UPDATE_FAILED","DELETE_FAILED"]),i=[/HandlerErrorCode:\s*NotFound\b/,/does not exist \(Service:/i,/\b(?:ResourceNotFoundException|NotFoundException|NoSuchBucket|NoSuchEntity)\b/],c=/Resource (?:creation|update) cancelled/i;function u(e){return c.test(e)?!1:i.some(s=>s.test(e))}const a="AWS::CloudFormation::Stack",r=new Set(["CREATE_IN_PROGRESS","UPDATE_IN_PROGRESS","DELETE_IN_PROGRESS","IMPORT_IN_PROGRESS"]),E="User Initiated";function S(e,s){return e.resourceType===a&&e.logicalId===s&&r.has(e.status)&&e.statusReason!==void 0&&e.statusReason.includes(E)}function d(e,s){let n=null;for(const t of e)S(t,s)&&(n===null||t.timestamp.getTime()>n.getTime())&&(n=t.timestamp);return n}function R(e){const s=[],n=new Set;for(const t of e)n.has(t.logicalId)||o.has(t.status)&&(t.statusReason===void 0||t.statusReason===""||u(t.statusReason)&&(n.add(t.logicalId),s.push({logicalId:t.logicalId,resourceType:t.resourceType,...t.physicalId!==void 0&&t.physicalId!==""?{physicalId:t.physicalId}:{},failedStatus:t.status,statusReason:t.statusReason})));return s}export{R as classifyDriftSuspectEvents,d as findCurrentOperationStart,u as isDriftSuspectReason,S as isOperationOpeningEvent};
1
+ var i=Object.defineProperty;var o=(e,s)=>i(e,"name",{value:s,configurable:!0});const c=new Set(["UPDATE_FAILED","DELETE_FAILED"]),u=[/HandlerErrorCode:\s*NotFound\b/,/does not exist \(Service:/i,/\b(?:ResourceNotFoundException|NotFoundException|NoSuchBucket|NoSuchEntity)\b/],a=/Resource (?:creation|update) cancelled/i;function r(e){return a.test(e)?!1:u.some(s=>s.test(e))}o(r,"isDriftSuspectReason");const E="AWS::CloudFormation::Stack",S=new Set(["CREATE_IN_PROGRESS","UPDATE_IN_PROGRESS","DELETE_IN_PROGRESS","IMPORT_IN_PROGRESS"]),d="User Initiated";function R(e,s){return e.resourceType===E&&e.logicalId===s&&S.has(e.status)&&e.statusReason!==void 0&&e.statusReason.includes(d)}o(R,"isOperationOpeningEvent");function l(e,s){let n=null;for(const t of e)R(t,s)&&(n===null||t.timestamp.getTime()>n.getTime())&&(n=t.timestamp);return n}o(l,"findCurrentOperationStart");function f(e){const s=[],n=new Set;for(const t of e)n.has(t.logicalId)||c.has(t.status)&&(t.statusReason===void 0||t.statusReason===""||r(t.statusReason)&&(n.add(t.logicalId),s.push({logicalId:t.logicalId,resourceType:t.resourceType,...t.physicalId!==void 0&&t.physicalId!==""?{physicalId:t.physicalId}:{},failedStatus:t.status,statusReason:t.statusReason})));return s}o(f,"classifyDriftSuspectEvents");export{f as classifyDriftSuspectEvents,l as findCurrentOperationStart,r as isDriftSuspectReason,R as isOperationOpeningEvent};
@@ -1 +1 @@
1
- class e extends Error{code;constructor(t,n){super(t),this.code=n,this.name=this.constructor.name,Object.setPrototypeOf(this,new.target.prototype)}}class s extends e{constructor(t,n){const r=t?`No roles found for account ${t}`:"No roles found for this account";super(n??r,"NO_ROLES_FOUND")}}class i extends e{constructor(t){super(t,"INVALID_CREDENTIALS")}}class c extends e{constructor(){super("SSO token has expired","SSO_TOKEN_EXPIRED")}}class u extends e{constructor(){super("Region is missing in AWS configuration and environment","MISSING_REGION")}}class p extends e{constructor(t){super(`AWS profile '${t}' not found`,"PROFILE_NOT_FOUND")}}function a(o){return o instanceof e}function d(o){return o instanceof s}function E(o){return!o||typeof o!="object"?!1:"name"in o&&o.name==="UnauthorizedException"||"Code"in o&&o.Code==="UnauthorizedException"||"__type"in o&&typeof o.__type=="string"&&o.__type.includes("UnauthorizedException")}class x extends e{tip;constructor(t,n){super(t,"COMMAND_ERROR"),this.tip=n}}export{e as AWSError,x as CommandError,i as InvalidCredentialsError,u as MissingRegionError,s as NoRolesFoundError,p as ProfileNotFoundError,c as SSOTokenExpiredError,a as isAWSError,d as isNoRolesFoundError,E as isSSOUnauthorizedError};
1
+ var i=Object.defineProperty;var e=(o,t)=>i(o,"name",{value:t,configurable:!0});class n extends Error{static{e(this,"AWSError")}code;constructor(t,r){super(t),this.code=r,this.name=this.constructor.name,Object.setPrototypeOf(this,new.target.prototype)}}class c extends n{static{e(this,"NoRolesFoundError")}constructor(t,r){const s=t?`No roles found for account ${t}`:"No roles found for this account";super(r??s,"NO_ROLES_FOUND")}}class p extends n{static{e(this,"InvalidCredentialsError")}constructor(t){super(t,"INVALID_CREDENTIALS")}}class a extends n{static{e(this,"SSOTokenExpiredError")}constructor(){super("SSO token has expired","SSO_TOKEN_EXPIRED")}}class d extends n{static{e(this,"MissingRegionError")}constructor(){super("Region is missing in AWS configuration and environment","MISSING_REGION")}}class E extends n{static{e(this,"ProfileNotFoundError")}constructor(t){super(`AWS profile '${t}' not found`,"PROFILE_NOT_FOUND")}}function x(o){return o instanceof n}e(x,"isAWSError");function f(o){return o instanceof c}e(f,"isNoRolesFoundError");function l(o){return!o||typeof o!="object"?!1:"name"in o&&o.name==="UnauthorizedException"||"Code"in o&&o.Code==="UnauthorizedException"||"__type"in o&&typeof o.__type=="string"&&o.__type.includes("UnauthorizedException")}e(l,"isSSOUnauthorizedError");class O extends n{static{e(this,"CommandError")}tip;constructor(t,r){super(t,"COMMAND_ERROR"),this.tip=r}}export{n as AWSError,O as CommandError,p as InvalidCredentialsError,d as MissingRegionError,c as NoRolesFoundError,E as ProfileNotFoundError,a as SSOTokenExpiredError,x as isAWSError,f as isNoRolesFoundError,l as isSSOUnauthorizedError};
@@ -1 +1 @@
1
- const r="fjall:operations:pool";function t(o,a){return`${o}-${a}`}export{r as IPAM_OPERATIONS_POOL_TAG_KEY,t as formatIpamPairTagValue};
1
+ var t=Object.defineProperty;var r=(o,a)=>t(o,"name",{value:a,configurable:!0});const n="fjall:operations:pool";function p(o,a){return`${o}-${a}`}r(p,"formatIpamPairTagValue");export{n as IPAM_OPERATIONS_POOL_TAG_KEY,p as formatIpamPairTagValue};
@@ -1 +1 @@
1
- import{maskSensitiveOutput as t}from"../securityHelpers.js";function r(e){return e.statusReason===void 0?e:{...e,statusReason:t(e.statusReason)}}function u(e){return{...e,statusReason:t(e.statusReason)}}function n(e){const s={...e.rootCause,reason:t(e.rootCause.reason),resource:r(e.rootCause.resource)};return{...e,rootCause:s,affectedResources:e.affectedResources.map(r),...e.driftSuspects!==void 0?{driftSuspects:e.driftSuspects.map(u)}:{}}}export{n as maskFailureAnalysis};
1
+ var o=Object.defineProperty;var t=(e,r)=>o(e,"name",{value:r,configurable:!0});import{maskSensitiveOutput as s}from"../securityHelpers.js";function u(e){return e.statusReason===void 0?e:{...e,statusReason:s(e.statusReason)}}t(u,"maskResourceEvent");function n(e){return{...e,statusReason:s(e.statusReason)}}t(n,"maskDriftSuspect");function c(e){const r={...e.rootCause,reason:s(e.rootCause.reason),resource:u(e.rootCause.resource)};return{...e,rootCause:r,affectedResources:e.affectedResources.map(u),...e.driftSuspects!==void 0?{driftSuspects:e.driftSuspects.map(n)}:{}}}t(c,"maskFailureAnalysis");export{c as maskFailureAnalysis};
@@ -1 +1 @@
1
- import p from"os";import{success as y,failure as x}from"./docker/result.js";async function F(r,e,o={}){const t=r.length,i=new Array(t);if(t===0)return i;const l=Math.max(1,Math.min(e,t)),u=o.abortOnFirstFailure===!0;let c=0,s=!1;async function d(){for(;;){if(u&&s||o.abortSignal?.aborted===!0)return;const n=c;if(n>=t)return;c=n+1;const h=r[n];try{const a=await h();i[n]=y(a)}catch(a){const m=a instanceof Error?a:new Error(String(a));i[n]=x(m),u&&(s=!0)}}}const f=[];for(let n=0;n<l;n++)f.push(d());return await Promise.all(f),i}function w(r){const e=p.cpus().length;return Math.min(r,Math.max(2,Math.floor(e/2)))}function g(r){if(r<=0)return 1;const e=process.env.FJALL_BUILD_CONCURRENCY;let o=w(r);if(e!==void 0&&e!==""){const t=parseInt(e,10);Number.isInteger(t)&&t>0&&(o=t)}return Math.max(1,Math.min(o,r))}export{g as resolveBuildConcurrency,F as runWithBoundedConcurrency};
1
+ var y=Object.defineProperty;var i=(r,t)=>y(r,"name",{value:t,configurable:!0});import x from"os";import{success as w,failure as M}from"./docker/result.js";async function B(r,t,o={}){const n=r.length,u=new Array(n);if(n===0)return u;const d=Math.max(1,Math.min(t,n)),c=o.abortOnFirstFailure===!0;let s=0,f=!1;async function h(){for(;;){if(c&&f||o.abortSignal?.aborted===!0)return;const e=s;if(e>=n)return;s=e+1;const m=r[e];try{const a=await m();u[e]=w(a)}catch(a){const p=a instanceof Error?a:new Error(String(a));u[e]=M(p),c&&(f=!0)}}}i(h,"worker");const l=[];for(let e=0;e<d;e++)l.push(h());return await Promise.all(l),u}i(B,"runWithBoundedConcurrency");function C(r){const t=x.cpus().length;return Math.min(r,Math.max(2,Math.floor(t/2)))}i(C,"defaultBuildConcurrency");function I(r){if(r<=0)return 1;const t=process.env.FJALL_BUILD_CONCURRENCY;let o=C(r);if(t!==void 0&&t!==""){const n=parseInt(t,10);Number.isInteger(n)&&n>0&&(o=n)}return Math.max(1,Math.min(o,r))}i(I,"resolveBuildConcurrency");export{I as resolveBuildConcurrency,B as runWithBoundedConcurrency};
@@ -1 +1 @@
1
- import{readdir as d,stat as l,rm as h}from"fs/promises";import{tmpdir as w}from"os";import{join as m}from"path";import{logger as g}from"./logger.js";const B="cdkTmpdirCleanup";function o(e,t,r={}){g.debug(B,e,{error:t instanceof Error?t.message:String(t),...r})}const T="cdk.out",x=1440*60*1e3;async function u(e){let t=0,r;try{r=await d(e,{withFileTypes:!0})}catch(i){return o("readdir failed",i,{path:e}),0}for(const i of r){const a=m(e,i.name);if(i.isDirectory())t+=await u(a);else if(i.isFile())try{const n=await l(a);t+=n.size}catch(n){o("stat failed",n,{path:a})}}return t}async function D(e={}){const t=e.tmpdirPath??w(),r=e.maxAgeMs??x,i=Date.now()-r;let a;try{a=await d(t)}catch(s){return o("tmpdir readdir failed",s,{root:t}),[]}const n=[];for(const s of a){if(!s.startsWith(T))continue;const c=m(t,s);let f;try{f=await l(c)}catch(y){o("stat failed",y,{path:c});continue}if(!f.isDirectory()||f.mtimeMs>i)continue;const p=await u(c);n.push({path:c,sizeBytes:p,mtime:f.mtime})}return n}async function M(e){let t=0,r=0,i=0;for(const a of e)try{await h(a.path,{recursive:!0,force:!0}),t+=1,i+=a.sizeBytes}catch(n){o("rm failed",n,{path:a.path}),r+=1}return{removed:t,failed:r,bytesReclaimed:i}}async function E(e={}){const t=await D(e);return M(t)}function F(e){const t=["B","KB","MB","GB","TB"];let r=e,i=0;for(;r>=1024&&i<t.length-1;)r/=1024,i+=1;return`${r.toFixed(r<10?2:1)} ${t[i]}`}export{E as cleanupStaleCdkTmpdirs,D as findStaleCdkTmpdirs,F as formatBytes,M as removeStaleCdkTmpdirs};
1
+ var w=Object.defineProperty;var o=(e,t)=>w(e,"name",{value:t,configurable:!0});import{readdir as l,stat as m,rm as g}from"fs/promises";import{tmpdir as B}from"os";import{join as u}from"path";import{logger as T}from"./logger.js";const x="cdkTmpdirCleanup";function s(e,t,r={}){T.debug(x,e,{error:t instanceof Error?t.message:String(t),...r})}o(s,"debugError");const D="cdk.out",M=1440*60*1e3;async function p(e){let t=0,r;try{r=await l(e,{withFileTypes:!0})}catch(i){return s("readdir failed",i,{path:e}),0}for(const i of r){const a=u(e,i.name);if(i.isDirectory())t+=await p(a);else if(i.isFile())try{const n=await m(a);t+=n.size}catch(n){s("stat failed",n,{path:a})}}return t}o(p,"getDirSize");async function S(e={}){const t=e.tmpdirPath??B(),r=e.maxAgeMs??M,i=Date.now()-r;let a;try{a=await l(t)}catch(c){return s("tmpdir readdir failed",c,{root:t}),[]}const n=[];for(const c of a){if(!c.startsWith(D))continue;const f=u(t,c);let d;try{d=await m(f)}catch(h){s("stat failed",h,{path:f});continue}if(!d.isDirectory()||d.mtimeMs>i)continue;const y=await p(f);n.push({path:f,sizeBytes:y,mtime:d.mtime})}return n}o(S,"findStaleCdkTmpdirs");async function k(e){let t=0,r=0,i=0;for(const a of e)try{await g(a.path,{recursive:!0,force:!0}),t+=1,i+=a.sizeBytes}catch(n){s("rm failed",n,{path:a.path}),r+=1}return{removed:t,failed:r,bytesReclaimed:i}}o(k,"removeStaleCdkTmpdirs");async function v(e={}){const t=await S(e);return k(t)}o(v,"cleanupStaleCdkTmpdirs");function z(e){const t=["B","KB","MB","GB","TB"];let r=e,i=0;for(;r>=1024&&i<t.length-1;)r/=1024,i+=1;return`${r.toFixed(r<10?2:1)} ${t[i]}`}o(z,"formatBytes");export{v as cleanupStaleCdkTmpdirs,S as findStaleCdkTmpdirs,z as formatBytes,k as removeStaleCdkTmpdirs};
package/dist/config.js CHANGED
@@ -1 +1 @@
1
- import*as i from"fs";import*as f from"path";import{z as s}from"zod";import{failure as l,success as T}from"./docker/result.js";import{getErrorMessage as p}from"./errorUtils.js";import{logger as h}from"./logger.js";import{maskSensitiveOutput as g}from"./securityHelpers.js";const E=10,u="fjall-config.json",F=["compliance","governance","none"],R=["enforced","off"],K=["centralised","off"],M=["account","draining","org"],N="managementEvents",b="organisationManagementEvents",k=["active","draining","removed"],I="FjallTrailBucketName",L="FjallTrailKeyArn",U="OrganisationTrailBucketName",w=s.object({name:s.string(),type:s.enum(["apex","delegated"]),parentDomain:s.string().optional(),account:s.string().optional()}).strict(),y=s.object({activeTarget:s.string().optional(),domains:s.array(w).optional()}).strict(),S=s.object({activeTarget:s.string().optional(),domains:s.array(w).optional()});function v(C={}){return JSON.stringify(C,null,2)}const O=y.keyof().options;function A(C,e,t){const n=e[t];n!==void 0&&(C[t]=n)}class a{rootConfig;configPath=null;loadFailed=!1;clearedKeys=new Set;constructor(e,t){this.rootConfig=e??{},this.configPath=t??null}static findConfigDirectory(e){let t=e!==void 0&&e!==""?e:process.cwd();for(let n=0;n<E;n++){const r=f.join(t,"fjall"),c=f.join(r,u);if(i.existsSync(c))return r;const o=f.join(t,u);if(i.existsSync(o))return t;const d=f.dirname(t);if(d===t)break;t=d}return null}static loadConfigFile(e){try{return i.accessSync(e,i.constants.R_OK),i.readFileSync(e,{encoding:"utf8"})}catch(t){return h.warn("Config",`Config file at ${e} could not be read; using defaults`,{file:e,error:g(p(t))}),null}}static loadConfig(e){const t=a.findConfigDirectory(e);if(!t)return new a;const n=f.join(t,u),r=a.loadConfigFile(n);if(r===null){const o=new a(void 0,n);return o.loadFailed=!0,o}let c;if(r!==""){let o;try{o=JSON.parse(r)}catch(m){throw a.formatZodError(m,u)}const d=y.safeParse(o);if(d.success)c=d.data;else{const m=S.safeParse(o);c=m.success?m.data:{},h.warn("Config","fjall-config.json contains keys this version does not recognise; they were ignored (only activeTarget and domains are read). If this is an old config, regenerate it with `fjall create ...` or re-run `fjall connect`.",{file:n})}}return new a(c,n)}static formatZodError(e,t){if(e instanceof s.ZodError&&e.issues.length>0){const c=e.issues.map(o=>`${o.path.join(".")}: ${o.message}`).join("; ");return new Error(`Failed to parse ${t}: ${c}`)}const r=(e instanceof Error?e.message:String(e)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${r}`)}saveConfig(){let e=this.configPath;if(!e){const o=a.findConfigDirectory()||f.join(process.cwd(),"fjall");e=f.join(o,u)}if(this.loadFailed)return l(new Error(`Refusing to save ${e}: the file exists but could not be read when this config loaded, so saving would replace its contents with state that never included them. Fix the file permissions (e.g. chmod u+rw ${e}) and retry.`));const t=f.dirname(e);try{i.mkdirSync(t,{recursive:!0})}catch(o){return l(new Error(`Cannot create config directory ${t}: ${g(p(o))}`))}const n=a.assertWritable(e,t);if(!n.success)return n;const r=v(this.mergeWithDisk(e)),c=`${e}.tmp-${process.pid}`;try{i.writeFileSync(c,r,{mode:384}),i.renameSync(c,e)}catch(o){return l(new Error(`Failed to save ${e}: ${g(p(o))}`))}return T(void 0)}static assertWritable(e,t){if(i.existsSync(e))try{i.accessSync(e,i.constants.W_OK)}catch{return l(new Error(`Cannot save ${e}: the file is read-only. Make it writable (e.g. chmod u+w ${e}) and retry.`))}try{i.accessSync(t,i.constants.W_OK)}catch{return l(new Error(`Cannot save ${e}: the directory ${t} is not writable. Make it writable (e.g. chmod u+w ${t}) and retry.`))}return T(void 0)}mergeWithDisk(e){const t=a.readDiskConfigForMerge(e);if(t===void 0)return this.rootConfig;const n={...t};for(const r of O)A(n,this.rootConfig,r);for(const r of this.clearedKeys)delete n[r];return n}static readDiskConfigForMerge(e){if(!i.existsSync(e))return;let t;try{t=JSON.parse(i.readFileSync(e,{encoding:"utf8"}))}catch(r){h.warn("Config",`Could not re-read ${e} before saving; writing in-memory state without merging`,{file:e,error:g(p(r))});return}const n=y.safeParse(t);if(!n.success){h.warn("Config",`On-disk ${e} failed validation before saving; writing in-memory state without merging`,{file:e,error:g(n.error.message)});return}return n.data}static getConfigDirectory(e){return a.findConfigDirectory(e)}getActiveTarget(){return this.rootConfig.activeTarget}setActiveTarget(e){this.rootConfig.activeTarget=e,this.clearedKeys.delete("activeTarget")}clearActiveTarget(){this.rootConfig.activeTarget=void 0,this.clearedKeys.add("activeTarget")}getDomains(){return this.rootConfig.domains??[]}setDomains(e){this.rootConfig.domains=e}addDomain(e){this.rootConfig.domains||(this.rootConfig.domains=[]),this.rootConfig.domains.push(e)}getDomain(e){return this.rootConfig.domains?.find(t=>t.name.toLowerCase()===e.toLowerCase())}removeDomain(e){if(!this.rootConfig.domains)return!1;const t=this.rootConfig.domains.findIndex(n=>n.name.toLowerCase()===e.toLowerCase());return t===-1?!1:(this.rootConfig.domains.splice(t,1),!0)}}export{N as ACCOUNT_TRAIL_NAME,k as ACCOUNT_TRAIL_STATES,a as Config,b as ORGANISATION_TRAIL_NAME,U as ORG_TRAIL_BUCKET_OUTPUT_KEY,K as ROOT_ACCESS_MANAGEMENT_MODES,u as ROOT_CONFIG_FILENAME,y as RootConfigSchema,R as S3_BPA_MODES,I as TRAIL_BUCKET_OUTPUT_KEY,L as TRAIL_KEY_ARN_OUTPUT_KEY,M as TRAIL_LIFECYCLE_STATES,F as VAULT_LOCK_MODES,v as serialiseRootConfig};
1
+ var S=Object.defineProperty;var h=(d,e)=>S(d,"name",{value:e,configurable:!0});import*as i from"fs";import*as f from"path";import{z as s}from"zod";import{failure as g,success as w}from"./docker/result.js";import{getErrorMessage as C}from"./errorUtils.js";import{logger as y}from"./logger.js";import{maskSensitiveOutput as u}from"./securityHelpers.js";const v=10,m="fjall-config.json",M=["compliance","governance","none"],N=["enforced","off"],b=["centralised","off"],k=["account","draining","org"],I="managementEvents",L="organisationManagementEvents",U=["active","draining","removed"],J="FjallTrailBucketName",G="FjallTrailKeyArn",W="OrganisationTrailBucketName",E=s.object({name:s.string(),type:s.enum(["apex","delegated"]),parentDomain:s.string().optional(),account:s.string().optional()}).strict(),T=s.object({activeTarget:s.string().optional(),domains:s.array(E).optional()}).strict(),O=s.object({activeTarget:s.string().optional(),domains:s.array(E).optional()});function A(d={}){return JSON.stringify(d,null,2)}h(A,"serialiseRootConfig");const _=T.keyof().options;function D(d,e,t){const n=e[t];n!==void 0&&(d[t]=n)}h(D,"copyDefinedKey");class a{static{h(this,"Config")}rootConfig;configPath=null;loadFailed=!1;clearedKeys=new Set;constructor(e,t){this.rootConfig=e??{},this.configPath=t??null}static findConfigDirectory(e){let t=e!==void 0&&e!==""?e:process.cwd();for(let n=0;n<v;n++){const r=f.join(t,"fjall"),c=f.join(r,m);if(i.existsSync(c))return r;const o=f.join(t,m);if(i.existsSync(o))return t;const l=f.dirname(t);if(l===t)break;t=l}return null}static loadConfigFile(e){try{return i.accessSync(e,i.constants.R_OK),i.readFileSync(e,{encoding:"utf8"})}catch(t){return y.warn("Config",`Config file at ${e} could not be read; using defaults`,{file:e,error:u(C(t))}),null}}static loadConfig(e){const t=a.findConfigDirectory(e);if(!t)return new a;const n=f.join(t,m),r=a.loadConfigFile(n);if(r===null){const o=new a(void 0,n);return o.loadFailed=!0,o}let c;if(r!==""){let o;try{o=JSON.parse(r)}catch(p){throw a.formatZodError(p,m)}const l=T.safeParse(o);if(l.success)c=l.data;else{const p=O.safeParse(o);c=p.success?p.data:{},y.warn("Config","fjall-config.json contains keys this version does not recognise; they were ignored (only activeTarget and domains are read). If this is an old config, regenerate it with `fjall create ...` or re-run `fjall connect`.",{file:n})}}return new a(c,n)}static formatZodError(e,t){if(e instanceof s.ZodError&&e.issues.length>0){const c=e.issues.map(o=>`${o.path.join(".")}: ${o.message}`).join("; ");return new Error(`Failed to parse ${t}: ${c}`)}const r=(e instanceof Error?e.message:String(e)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${r}`)}saveConfig(){let e=this.configPath;if(!e){const o=a.findConfigDirectory()||f.join(process.cwd(),"fjall");e=f.join(o,m)}if(this.loadFailed)return g(new Error(`Refusing to save ${e}: the file exists but could not be read when this config loaded, so saving would replace its contents with state that never included them. Fix the file permissions (e.g. chmod u+rw ${e}) and retry.`));const t=f.dirname(e);try{i.mkdirSync(t,{recursive:!0})}catch(o){return g(new Error(`Cannot create config directory ${t}: ${u(C(o))}`))}const n=a.assertWritable(e,t);if(!n.success)return n;const r=A(this.mergeWithDisk(e)),c=`${e}.tmp-${process.pid}`;try{i.writeFileSync(c,r,{mode:384}),i.renameSync(c,e)}catch(o){return g(new Error(`Failed to save ${e}: ${u(C(o))}`))}return w(void 0)}static assertWritable(e,t){if(i.existsSync(e))try{i.accessSync(e,i.constants.W_OK)}catch{return g(new Error(`Cannot save ${e}: the file is read-only. Make it writable (e.g. chmod u+w ${e}) and retry.`))}try{i.accessSync(t,i.constants.W_OK)}catch{return g(new Error(`Cannot save ${e}: the directory ${t} is not writable. Make it writable (e.g. chmod u+w ${t}) and retry.`))}return w(void 0)}mergeWithDisk(e){const t=a.readDiskConfigForMerge(e);if(t===void 0)return this.rootConfig;const n={...t};for(const r of _)D(n,this.rootConfig,r);for(const r of this.clearedKeys)delete n[r];return n}static readDiskConfigForMerge(e){if(!i.existsSync(e))return;let t;try{t=JSON.parse(i.readFileSync(e,{encoding:"utf8"}))}catch(r){y.warn("Config",`Could not re-read ${e} before saving; writing in-memory state without merging`,{file:e,error:u(C(r))});return}const n=T.safeParse(t);if(!n.success){y.warn("Config",`On-disk ${e} failed validation before saving; writing in-memory state without merging`,{file:e,error:u(n.error.message)});return}return n.data}static getConfigDirectory(e){return a.findConfigDirectory(e)}getActiveTarget(){return this.rootConfig.activeTarget}setActiveTarget(e){this.rootConfig.activeTarget=e,this.clearedKeys.delete("activeTarget")}clearActiveTarget(){this.rootConfig.activeTarget=void 0,this.clearedKeys.add("activeTarget")}getDomains(){return this.rootConfig.domains??[]}setDomains(e){this.rootConfig.domains=e}addDomain(e){this.rootConfig.domains||(this.rootConfig.domains=[]),this.rootConfig.domains.push(e)}getDomain(e){return this.rootConfig.domains?.find(t=>t.name.toLowerCase()===e.toLowerCase())}removeDomain(e){if(!this.rootConfig.domains)return!1;const t=this.rootConfig.domains.findIndex(n=>n.name.toLowerCase()===e.toLowerCase());return t===-1?!1:(this.rootConfig.domains.splice(t,1),!0)}}export{I as ACCOUNT_TRAIL_NAME,U as ACCOUNT_TRAIL_STATES,a as Config,L as ORGANISATION_TRAIL_NAME,W as ORG_TRAIL_BUCKET_OUTPUT_KEY,b as ROOT_ACCESS_MANAGEMENT_MODES,m as ROOT_CONFIG_FILENAME,T as RootConfigSchema,N as S3_BPA_MODES,J as TRAIL_BUCKET_OUTPUT_KEY,G as TRAIL_KEY_ARN_OUTPUT_KEY,k as TRAIL_LIFECYCLE_STATES,M as VAULT_LOCK_MODES,A as serialiseRootConfig};
@@ -1 +1 @@
1
- import{FJALL_MANIFEST_FILENAME as _,MANIFEST_SCHEMA_VERSION as w}from"./manifest/schemas.js";import{readFileSync as p}from"fs";import{join as l}from"path";import{logger as g}from"./logger.js";import{categoriseResource as d,getFriendlyResourceType as y}from"./resourceCategorisation.js";const N=Object.freeze({CloudTrail:"monitoring",MonitoringRole:"monitoring",AuditRole:"security",OidcConnector:"security",EcrDefaultImage:"registry",EventBus:"events",DisasterRecovery:"backup"}),h=Object.freeze({Network:"network",Database:"database",Compute:"compute",Storage:"storage",Messaging:"events",Cdn:"dns"});function C(o,e){const t=o.split("/").filter(Boolean);if(t.length<2)return;const r=t[1];return e[r]}function T(o){const e=o.split("/").filter(Boolean);return e.length<2?o:(e.length>2&&e[e.length-1]==="Resource"?e[e.length-2]:e[e.length-1]).replace(/([a-z])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2")}function j(o,e){const t=new Map;let r;try{const n=p(l(o,"manifest.json"),"utf-8"),s=JSON.parse(n);if(typeof s!="object"||s===null)return t;r=s}catch(n){return g.debug("ConstructMap","Could not read CDK manifest",{error:n instanceof Error?n.message:String(n)}),t}if(!r.artifacts)return t;for(const n of Object.values(r.artifacts)){if(n.type!=="aws:cloudformation:stack"||!n.metadata)continue;const s=b(o,n.properties?.templateFile);for(const[a,c]of Object.entries(n.metadata))for(const u of c){if(u.type!=="aws:cdk:logicalId")continue;const i=u.data,f=s.get(i)??"",m=C(a,e)??d(f);t.set(i,{constructPath:a,group:m,resourceType:f})}}return t}function b(o,e){const t=new Map;if(!e)return t;try{const r=p(l(o,e),"utf-8"),n=JSON.parse(r);if(typeof n!="object"||n===null)return t;const s=n;if(s.Resources&&typeof s.Resources=="object")for(const[a,c]of Object.entries(s.Resources))typeof c=="object"&&c!==null&&c.Type&&t.set(a,c.Type)}catch(r){g.debug("ConstructMap","Could not read template file",{templateFile:e,error:r instanceof Error?r.message:String(r)})}return t}function A(o){const e={};for(const[t,r]of o)e[t]=r;return e}function E(o){const e=new Map;if(!o)return e;for(const[t,r]of Object.entries(o))e.set(t,r);return e}function v(o,e,t){const r=t?.get(o);return r?{group:r.group,constructPath:r.constructPath,displayName:T(r.constructPath)}:{displayName:y(e)}}export{N as ACCOUNT_CONSTRUCT_GROUPS,h as APP_CONSTRUCT_GROUPS,_ as FJALL_MANIFEST_FILENAME,w as MANIFEST_SCHEMA_VERSION,j as buildConstructMap,A as constructMapToRecord,T as deriveDisplayName,C as deriveGroupFromPath,v as enrichFromConstructMap,E as recordToConstructMap};
1
+ var y=Object.defineProperty;var c=(o,e)=>y(o,"name",{value:e,configurable:!0});import{FJALL_MANIFEST_FILENAME as P,MANIFEST_SCHEMA_VERSION as k}from"./manifest/schemas.js";import{readFileSync as l}from"fs";import{join as g}from"path";import{logger as m}from"./logger.js";import{categoriseResource as C,getFriendlyResourceType as T}from"./resourceCategorisation.js";const A=Object.freeze({CloudTrail:"monitoring",MonitoringRole:"monitoring",AuditRole:"security",OidcConnector:"security",EcrDefaultImage:"registry",EventBus:"events",DisasterRecovery:"backup"}),E=Object.freeze({Network:"network",Database:"database",Compute:"compute",Storage:"storage",Messaging:"events",Cdn:"dns"});function b(o,e){const t=o.split("/").filter(Boolean);if(t.length<2)return;const r=t[1];return e[r]}c(b,"deriveGroupFromPath");function R(o){const e=o.split("/").filter(Boolean);return e.length<2?o:(e.length>2&&e[e.length-1]==="Resource"?e[e.length-2]:e[e.length-1]).replace(/([a-z])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2")}c(R,"deriveDisplayName");function v(o,e){const t=new Map;let r;try{const n=l(g(o,"manifest.json"),"utf-8"),s=JSON.parse(n);if(typeof s!="object"||s===null)return t;r=s}catch(n){return m.debug("ConstructMap","Could not read CDK manifest",{error:n instanceof Error?n.message:String(n)}),t}if(!r.artifacts)return t;for(const n of Object.values(r.artifacts)){if(n.type!=="aws:cloudformation:stack"||!n.metadata)continue;const s=S(o,n.properties?.templateFile);for(const[u,a]of Object.entries(n.metadata))for(const i of a){if(i.type!=="aws:cdk:logicalId")continue;const f=i.data,p=s.get(f)??"",d=b(u,e)??C(p);t.set(f,{constructPath:u,group:d,resourceType:p})}}return t}c(v,"buildConstructMap");function S(o,e){const t=new Map;if(!e)return t;try{const r=l(g(o,e),"utf-8"),n=JSON.parse(r);if(typeof n!="object"||n===null)return t;const s=n;if(s.Resources&&typeof s.Resources=="object")for(const[u,a]of Object.entries(s.Resources))typeof a=="object"&&a!==null&&a.Type&&t.set(u,a.Type)}catch(r){m.debug("ConstructMap","Could not read template file",{templateFile:e,error:r instanceof Error?r.message:String(r)})}return t}c(S,"readTemplateResourceTypes");function x(o){const e={};for(const[t,r]of o)e[t]=r;return e}c(x,"constructMapToRecord");function I(o){const e=new Map;if(!o)return e;for(const[t,r]of Object.entries(o))e.set(t,r);return e}c(I,"recordToConstructMap");function _(o,e,t){const r=t?.get(o);return r?{group:r.group,constructPath:r.constructPath,displayName:R(r.constructPath)}:{displayName:T(e)}}c(_,"enrichFromConstructMap");export{A as ACCOUNT_CONSTRUCT_GROUPS,E as APP_CONSTRUCT_GROUPS,P as FJALL_MANIFEST_FILENAME,k as MANIFEST_SCHEMA_VERSION,v as buildConstructMap,x as constructMapToRecord,R as deriveDisplayName,b as deriveGroupFromPath,_ as enrichFromConstructMap,I as recordToConstructMap};
@@ -1 +1 @@
1
- import{rm as L}from"node:fs/promises";import{buildxArgvBuilder as A}from"./buildxArgvBuilder.js";import{BuildxBuildArgsSchema as R}from"./dockerCliSchemas.js";import{DEFAULT_INSPECT_TIMEOUT_MS as S,DOCKER_CLI_BUILDX_LOG_CATEGORY as B}from"./dockerCliConstants.js";import{BuildxBuildMonitor as j,buildPhaseTimeoutMessage as N,publishStallTimeoutMessage as U,resolveBuildxBudgets as G}from"./buildxBuildMonitor.js";import{parseMetadataFile as J}from"./metadataFileParser.js";import{parseRawjsonLine as P}from"./rawjsonParser.js";import{rawjsonToVertexEvent as H}from"./rawjsonToVertexEvent.js";import{maskSensitiveOutput as x}from"../securityHelpers.js";import{failure as t,makeError as a,maskOutput as b,runDocker as M,spawnFailureToError as K,streamDocker as V,success as C}from"./DockerCli.js";function F(s){return s instanceof Error?s.message:String(s)}async function ae(s,c,e,l){const r=R.safeParse(c);if(!r.success){const n=x(r.error.message);return t(a("validation",`Invalid BuildxBuildArgs: ${n}`,{issues:r.error.issues}))}const o=G(s.env);if(!o.success)return t(a("validation",x(o.error.message)));const g=o.data,u=A(r.data);let f=0,_=0;const k=new Set;let w,T;try{const n=new j(g);w=n,T=r.data.metadataFile;const O=p=>{const D=P(p);if(D===null){p.trim()!==""&&s.logger.debug(B,"Skipping malformed rawjson line",{line:x(p)});return}const m=H(D);if(m===null)return;const y=n.observe(m);y!==void 0&&e({type:"status",message:b(y.message),...y.percentage!==void 0&&{percentage:y.percentage}});for(const i of m.vertexes)i.completed!==void 0&&!k.has(i.digest)&&(k.add(i.digest),i.cached===!0?f++:_++),e({type:"vertex",message:b(i.name),vertex:i.digest});for(const i of m.logs)e({type:"log",message:b(i.data),vertex:i.vertex});for(const i of m.statuses)e({type:"status",message:b(`${i.name} ${i.current}`),vertex:i.vertex});for(const i of m.warnings)e({type:"warning",message:b(i.short),vertex:i.vertex})},I=l!==void 0?AbortSignal.any([n.signal,l]):n.signal,d=await V(s,{args:u,abortSignal:I},O);if(d.spawnError!==void 0)return t(a("daemon_unreachable",`Docker CLI is not available: ${d.spawnError}`,{stderrTail:d.stderrTail}));if(d.aborted||d.exitCode===null)return n.timedOutPhase==="build"?t(a("timeout",N(g),{stderrTail:d.stderrTail})):n.timedOutPhase==="publish"?t(a("timeout",U(g,n.progressSummary()),{stderrTail:d.stderrTail})):t(a("abort","docker buildx build was aborted",{stderrTail:d.stderrTail}));if(d.exitCode!==0)return t(a("build_failed",`docker buildx build failed (exit ${d.exitCode})`,{stderrTail:d.stderrTail}));const h=await J(r.data.metadataFile);if(!h.success)return h;const E=h.data,v=E["containerimage.digest"];if(typeof v!="string"||v==="")return t(a("metadata_missing_digest","Buildx metadata file does not contain containerimage.digest",{metadataFile:r.data.metadataFile}));const $={};for(const p of r.data.tags)$[p]=v;return C({digest:v,imageDigests:$,metadata:E,platforms:r.data.platforms,cacheHits:f,cacheMisses:_})}finally{w!==void 0&&w.dispose(),T!==void 0&&await L(T,{force:!0}).catch(n=>{s.logger.warn(B,"Failed to clean up buildx metadata file",{path:T,error:x(F(n))})})}}async function ie(s,c,e,l){if(c.trim()==="")return t(a("validation","tagByDigest: sourceImage must be non-empty"));if(!e.startsWith("sha256:"))return t(a("validation",`tagByDigest: expected sha256:... digest, got ${e.slice(0,32)}`));if(l.length===0)return t(a("validation","tagByDigest: tags must be a non-empty list"));for(const f of l)if(typeof f!="string"||f.trim()==="")return t(a("validation","tagByDigest: every tag must be non-empty"));const r=`${c}@${e}`,o=[];for(const f of l)o.push("--tag",f);const g=["buildx","imagetools","create",...o,r],u=await M(s,{args:g,timeoutMs:S});return u.spawnError!==void 0?t(K(u)):u.exitCode===null?t(a("abort",`docker buildx imagetools create for ${r} was aborted`,{stderrTail:u.stderrTail})):u.exitCode!==0?t(a("tag_failed",`docker buildx imagetools create for ${r} failed (exit ${u.exitCode})`,{stderrTail:u.stderrTail})):C(void 0)}async function se(s,c){const e=await M(s,{args:["buildx","imagetools","inspect",c,"--raw"],timeoutMs:S});if(e.spawnError!==void 0)return t(a("daemon_unreachable",`Docker CLI is not available: ${e.spawnError}`,{stderrTail:e.stderrTail}));if(e.exitCode===null)return t(a("abort",`docker buildx imagetools inspect ${c} was aborted`,{stderrTail:e.stderrTail}));if(e.exitCode!==0)return t(a("inspect_failed",`docker buildx imagetools inspect ${c} failed (exit ${e.exitCode})`,{stderrTail:e.stderrTail}));let l,r;try{const o=JSON.parse(e.stdout);typeof o.mediaType=="string"&&(l=o.mediaType),typeof o.digest=="string"&&(r=o.digest)}catch(o){s.logger.debug(B,"imagetools inspect output is not JSON; preserving raw",{error:x(F(o))})}return C({raw:e.stdout,...l!==void 0&&{mediaType:l},...r!==void 0&&{digest:r}})}export{ae as _buildxBuild,se as _imagetoolsInspect,ie as _tagByDigest};
1
+ var A=Object.defineProperty;var g=(s,l)=>A(s,"name",{value:l,configurable:!0});import{rm as R}from"node:fs/promises";import{buildxArgvBuilder as j}from"./buildxArgvBuilder.js";import{BuildxBuildArgsSchema as N}from"./dockerCliSchemas.js";import{DEFAULT_INSPECT_TIMEOUT_MS as M,DOCKER_CLI_BUILDX_LOG_CATEGORY as C}from"./dockerCliConstants.js";import{BuildxBuildMonitor as U,buildPhaseTimeoutMessage as G,publishStallTimeoutMessage as J,resolveBuildxBudgets as P}from"./buildxBuildMonitor.js";import{parseMetadataFile as H}from"./metadataFileParser.js";import{parseRawjsonLine as K}from"./rawjsonParser.js";import{rawjsonToVertexEvent as V}from"./rawjsonToVertexEvent.js";import{maskSensitiveOutput as b}from"../securityHelpers.js";import{failure as t,makeError as a,maskOutput as T,runDocker as F,spawnFailureToError as W,streamDocker as X,success as _}from"./DockerCli.js";function O(s){return s instanceof Error?s.message:String(s)}g(O,"getErrorMessage");async function oe(s,l,e,u){const r=N.safeParse(l);if(!r.success){const n=b(r.error.message);return t(a("validation",`Invalid BuildxBuildArgs: ${n}`,{issues:r.error.issues}))}const o=P(s.env);if(!o.success)return t(a("validation",b(o.error.message)));const p=o.data,c=j(r.data);let f=0,k=0;const E=new Set;let h,v;try{const n=new U(p);h=n,v=r.data.metadataFile;const I=g(x=>{const S=K(x);if(S===null){x.trim()!==""&&s.logger.debug(C,"Skipping malformed rawjson line",{line:b(x)});return}const m=V(S);if(m===null)return;const w=n.observe(m);w!==void 0&&e({type:"status",message:T(w.message),...w.percentage!==void 0&&{percentage:w.percentage}});for(const i of m.vertexes)i.completed!==void 0&&!E.has(i.digest)&&(E.add(i.digest),i.cached===!0?f++:k++),e({type:"vertex",message:T(i.name),vertex:i.digest});for(const i of m.logs)e({type:"log",message:T(i.data),vertex:i.vertex});for(const i of m.statuses)e({type:"status",message:T(`${i.name} ${i.current}`),vertex:i.vertex});for(const i of m.warnings)e({type:"warning",message:T(i.short),vertex:i.vertex})},"onStdoutLine"),L=u!==void 0?AbortSignal.any([n.signal,u]):n.signal,d=await X(s,{args:c,abortSignal:L},I);if(d.spawnError!==void 0)return t(a("daemon_unreachable",`Docker CLI is not available: ${d.spawnError}`,{stderrTail:d.stderrTail}));if(d.aborted||d.exitCode===null)return n.timedOutPhase==="build"?t(a("timeout",G(p),{stderrTail:d.stderrTail})):n.timedOutPhase==="publish"?t(a("timeout",J(p,n.progressSummary()),{stderrTail:d.stderrTail})):t(a("abort","docker buildx build was aborted",{stderrTail:d.stderrTail}));if(d.exitCode!==0)return t(a("build_failed",`docker buildx build failed (exit ${d.exitCode})`,{stderrTail:d.stderrTail}));const B=await H(r.data.metadataFile);if(!B.success)return B;const $=B.data,y=$["containerimage.digest"];if(typeof y!="string"||y==="")return t(a("metadata_missing_digest","Buildx metadata file does not contain containerimage.digest",{metadataFile:r.data.metadataFile}));const D={};for(const x of r.data.tags)D[x]=y;return _({digest:y,imageDigests:D,metadata:$,platforms:r.data.platforms,cacheHits:f,cacheMisses:k})}finally{h!==void 0&&h.dispose(),v!==void 0&&await R(v,{force:!0}).catch(n=>{s.logger.warn(C,"Failed to clean up buildx metadata file",{path:v,error:b(O(n))})})}}g(oe,"_buildxBuild");async function ne(s,l,e,u){if(l.trim()==="")return t(a("validation","tagByDigest: sourceImage must be non-empty"));if(!e.startsWith("sha256:"))return t(a("validation",`tagByDigest: expected sha256:... digest, got ${e.slice(0,32)}`));if(u.length===0)return t(a("validation","tagByDigest: tags must be a non-empty list"));for(const f of u)if(typeof f!="string"||f.trim()==="")return t(a("validation","tagByDigest: every tag must be non-empty"));const r=`${l}@${e}`,o=[];for(const f of u)o.push("--tag",f);const p=["buildx","imagetools","create",...o,r],c=await F(s,{args:p,timeoutMs:M});return c.spawnError!==void 0?t(W(c)):c.exitCode===null?t(a("abort",`docker buildx imagetools create for ${r} was aborted`,{stderrTail:c.stderrTail})):c.exitCode!==0?t(a("tag_failed",`docker buildx imagetools create for ${r} failed (exit ${c.exitCode})`,{stderrTail:c.stderrTail})):_(void 0)}g(ne,"_tagByDigest");async function de(s,l){const e=await F(s,{args:["buildx","imagetools","inspect",l,"--raw"],timeoutMs:M});if(e.spawnError!==void 0)return t(a("daemon_unreachable",`Docker CLI is not available: ${e.spawnError}`,{stderrTail:e.stderrTail}));if(e.exitCode===null)return t(a("abort",`docker buildx imagetools inspect ${l} was aborted`,{stderrTail:e.stderrTail}));if(e.exitCode!==0)return t(a("inspect_failed",`docker buildx imagetools inspect ${l} failed (exit ${e.exitCode})`,{stderrTail:e.stderrTail}));let u,r;try{const o=JSON.parse(e.stdout);typeof o.mediaType=="string"&&(u=o.mediaType),typeof o.digest=="string"&&(r=o.digest)}catch(o){s.logger.debug(C,"imagetools inspect output is not JSON; preserving raw",{error:b(O(o))})}return _({raw:e.stdout,...u!==void 0&&{mediaType:u},...r!==void 0&&{digest:r}})}g(de,"_imagetoolsInspect");export{oe as _buildxBuild,de as _imagetoolsInspect,ne as _tagByDigest};
@@ -1 +1 @@
1
- import{maskSensitiveOutput as p}from"../securityHelpers.js";import{BUILDX_VERSION_FLOOR as l,DEFAULT_DAEMON_PROBE_TIMEOUT_MS as x,DEFAULT_INSPECT_TIMEOUT_MS as c,DOCKER_CLI_BUILDX_LOG_CATEGORY as _,DOCKER_CLI_LOG_CATEGORY as g}from"./dockerCliConstants.js";import{failure as t,makeError as u,runDocker as s,spawnFailureToError as d,success as b}from"./DockerCli.js";function v(n){const e=n.startsWith("v")?n.slice(1):n,r=/^(\d+)\.(\d+)\.(\d+)/.exec(e);return r===null?null:[parseInt(r[1]??"0",10),parseInt(r[2]??"0",10),parseInt(r[3]??"0",10)]}function T(n,e){for(let r=0;r<3;r++){const i=n[r]??0,o=e[r]??0;if(i!==o)return i-o}return 0}function E(n){const e=/github\.com\/docker\/buildx\s+(v?\d+\.\d+\.\d+)/.exec(n);return e!==null&&e[1]!==void 0?e[1]:/(\d+\.\d+\.\d+)/.exec(n)?.[1]??null}async function O(n){const e=await s(n,{args:["buildx","version"],timeoutMs:c});if(e.spawnError!==void 0)return t(d(e));if(e.exitCode===null)return t(u("abort","docker buildx version was aborted",{stderrTail:e.stderrTail}));if(e.exitCode!==0){const a=await s(n,{args:["version","--format","{{.Server.Version}}"],timeoutMs:x});return a.spawnError!==void 0?t(d(a)):a.exitCode!==0?t(u("daemon_unreachable","Docker daemon is not running or not installed",{stderrTail:a.stderrTail})):t(u("buildx_unavailable",`Docker Buildx plugin is not installed (need >= ${l})`,{stderrTail:e.stderrTail}))}const r=E(e.stdout);if(r===null)return t(u("buildx_unavailable","Could not parse docker buildx version output",{stdout:e.stdout}));const i=v(r),o=v(l);return i===null||o===null?t(u("buildx_unavailable",`Could not parse buildx version "${r}"`,{stdout:e.stdout})):T(i,o)<0?t(u("buildx_unavailable",`Docker Buildx ${r} is below the required ${l} floor`,{observed:r,floor:l})):(n.logger.debug(_,"buildx available",{version:r}),b({version:r}))}async function D(n){const e=await s(n,{args:["version","--format","json"],timeoutMs:x});if(e.spawnError!==void 0)return t(d(e));if(e.exitCode===null)return t(u("abort","docker version was aborted",{stderrTail:e.stderrTail}));if(e.exitCode!==0)return t(u("daemon_unreachable","Docker daemon is not running or not installed",{stderrTail:e.stderrTail}));let r;try{r=JSON.parse(e.stdout)}catch(f){const m=p(f instanceof Error?f.message:String(f));return t(u("daemon_unreachable",`docker version output is not valid JSON: ${m}`,{stdout:e.stdout}))}if(r===null||typeof r!="object")return t(u("daemon_unreachable","docker version did not return a JSON object"));const i=r,o=i.Server?.Name??"Docker",a=i.Server?.Version??"unknown";return o==="Podman Engine"?t(u("buildx_unavailable","Podman is not supported; install Docker Engine 23+ with the buildx plugin")):b({serverName:o,serverVersion:a})}async function S(n,e){const r=await s(n,{args:["buildx","inspect",e],timeoutMs:c});if(r.spawnError!==void 0)return t(d(r));if(r.exitCode===0){if(/Driver:\s*docker-container/.test(r.stdout))return b({created:!1});n.logger.warn(g,"Replacing buildx builder with wrong driver",{name:e});const o=await s(n,{args:["buildx","rm",e],timeoutMs:c});if(o.spawnError!==void 0)return t(d(o));if(o.exitCode!==0)return t(u("buildx_unavailable",`Failed to remove existing buildx builder ${e}`,{stderrTail:o.stderrTail}))}const i=await s(n,{args:["buildx","create","--name",e,"--driver","docker-container","--use"],timeoutMs:c});return i.spawnError!==void 0?t(d(i)):i.exitCode!==0?t(u("buildx_unavailable",`Failed to create buildx builder ${e}`,{stderrTail:i.stderrTail})):b({created:!0})}export{O as _assertBuildxAvailable,D as _detectDaemon,S as _ensureBuilder};
1
+ var _=Object.defineProperty;var a=(n,e)=>_(n,"name",{value:e,configurable:!0});import{maskSensitiveOutput as g}from"../securityHelpers.js";import{BUILDX_VERSION_FLOOR as c,DEFAULT_DAEMON_PROBE_TIMEOUT_MS as v,DEFAULT_INSPECT_TIMEOUT_MS as b,DOCKER_CLI_BUILDX_LOG_CATEGORY as T,DOCKER_CLI_LOG_CATEGORY as E}from"./dockerCliConstants.js";import{failure as t,makeError as u,runDocker as d,spawnFailureToError as l,success as f}from"./DockerCli.js";function m(n){const e=n.startsWith("v")?n.slice(1):n,r=/^(\d+)\.(\d+)\.(\d+)/.exec(e);return r===null?null:[parseInt(r[1]??"0",10),parseInt(r[2]??"0",10),parseInt(r[3]??"0",10)]}a(m,"parseSemver");function k(n,e){for(let r=0;r<3;r++){const i=n[r]??0,o=e[r]??0;if(i!==o)return i-o}return 0}a(k,"compareSemver");function w(n){const e=/github\.com\/docker\/buildx\s+(v?\d+\.\d+\.\d+)/.exec(n);return e!==null&&e[1]!==void 0?e[1]:/(\d+\.\d+\.\d+)/.exec(n)?.[1]??null}a(w,"extractBuildxVersion");async function h(n){const e=await d(n,{args:["buildx","version"],timeoutMs:b});if(e.spawnError!==void 0)return t(l(e));if(e.exitCode===null)return t(u("abort","docker buildx version was aborted",{stderrTail:e.stderrTail}));if(e.exitCode!==0){const s=await d(n,{args:["version","--format","{{.Server.Version}}"],timeoutMs:v});return s.spawnError!==void 0?t(l(s)):s.exitCode!==0?t(u("daemon_unreachable","Docker daemon is not running or not installed",{stderrTail:s.stderrTail})):t(u("buildx_unavailable",`Docker Buildx plugin is not installed (need >= ${c})`,{stderrTail:e.stderrTail}))}const r=w(e.stdout);if(r===null)return t(u("buildx_unavailable","Could not parse docker buildx version output",{stdout:e.stdout}));const i=m(r),o=m(c);return i===null||o===null?t(u("buildx_unavailable",`Could not parse buildx version "${r}"`,{stdout:e.stdout})):k(i,o)<0?t(u("buildx_unavailable",`Docker Buildx ${r} is below the required ${c} floor`,{observed:r,floor:c})):(n.logger.debug(T,"buildx available",{version:r}),f({version:r}))}a(h,"_assertBuildxAvailable");async function I(n){const e=await d(n,{args:["version","--format","json"],timeoutMs:v});if(e.spawnError!==void 0)return t(l(e));if(e.exitCode===null)return t(u("abort","docker version was aborted",{stderrTail:e.stderrTail}));if(e.exitCode!==0)return t(u("daemon_unreachable","Docker daemon is not running or not installed",{stderrTail:e.stderrTail}));let r;try{r=JSON.parse(e.stdout)}catch(x){const p=g(x instanceof Error?x.message:String(x));return t(u("daemon_unreachable",`docker version output is not valid JSON: ${p}`,{stdout:e.stdout}))}if(r===null||typeof r!="object")return t(u("daemon_unreachable","docker version did not return a JSON object"));const i=r,o=i.Server?.Name??"Docker",s=i.Server?.Version??"unknown";return o==="Podman Engine"?t(u("buildx_unavailable","Podman is not supported; install Docker Engine 23+ with the buildx plugin")):f({serverName:o,serverVersion:s})}a(I,"_detectDaemon");async function M(n,e){const r=await d(n,{args:["buildx","inspect",e],timeoutMs:b});if(r.spawnError!==void 0)return t(l(r));if(r.exitCode===0){if(/Driver:\s*docker-container/.test(r.stdout))return f({created:!1});n.logger.warn(E,"Replacing buildx builder with wrong driver",{name:e});const o=await d(n,{args:["buildx","rm",e],timeoutMs:b});if(o.spawnError!==void 0)return t(l(o));if(o.exitCode!==0)return t(u("buildx_unavailable",`Failed to remove existing buildx builder ${e}`,{stderrTail:o.stderrTail}))}const i=await d(n,{args:["buildx","create","--name",e,"--driver","docker-container","--use"],timeoutMs:b});return i.spawnError!==void 0?t(l(i)):i.exitCode!==0?t(u("buildx_unavailable",`Failed to create buildx builder ${e}`,{stderrTail:i.stderrTail})):f({created:!0})}a(M,"_ensureBuilder");export{h as _assertBuildxAvailable,I as _detectDaemon,M as _ensureBuilder};
@@ -1 +1 @@
1
- import{spawn as h}from"node:child_process";import{filterDangerousEnvVars as k,maskSensitiveOutput as E}from"../securityHelpers.js";import{abortChildProcess as b}from"./abortHelpers.js";import{DEFAULT_DOCKER_BIN as x,DOCKER_CLI_LOG_CATEGORY as A,STDERR_TAIL_LINE_MAX_CHARS as y,STDERR_TAIL_LINES as S}from"./dockerCliConstants.js";import{_buildxBuild as D,_imagetoolsInspect as C,_tagByDigest as I}from"./DockerCli.build.js";import{_assertBuildxAvailable as L,_detectDaemon as R,_ensureBuilder as O}from"./DockerCli.daemon.js";import{_imageInspect as P,_loginEcr as N,_pull as F,_push as G,_tag as K}from"./DockerCli.registry.js";import{failure as v,success as M}from"./result.js";class Q{state;constructor(e){const r=e.dockerBin!==void 0&&e.dockerBin!==""?e.dockerBin:x,t=k(e.env??process.env);this.state={logger:e.logger,dockerBin:r,env:t,abortSignal:e.abortSignal,ecrSession:void 0}}async buildxBuild(e,r,t){return D(this.state,e,r,t)}async tag(e,r){return K(this.state,e,r)}async tagByDigest(e,r,t){return I(this.state,e,r,t)}async push(e,r){return G(this.state,e,r)}async pull(e,r,t){return F(this.state,e,r,t)}async imageInspect(e){return P(this.state,e)}async imagetoolsInspect(e){return C(this.state,e)}async loginEcr(e){return N(this.state,e)}async logoutEcr(){const e=this.state.ecrSession;this.state.ecrSession=void 0,e!==void 0&&await e.dispose()}async withEcrSession(e,r,t){const o=await this.loginEcr(e);if(!o.success)return v(t(o.error));try{return await r()}finally{await this.logoutEcr().catch(()=>{})}}async ensureBuilder(e){return O(this.state,e)}async assertBuildxAvailable(){return L(this.state)}async detectDaemon(){return R(this.state)}}function j(n){const e=E(n);return e.length>y?e.slice(0,y)+"\u2026":e}function H(n,e,r){let t,o=r;if(r!==void 0&&Array.isArray(r.stderrTail)&&r.stderrTail.every(a=>typeof a=="string")){t=r.stderrTail.map(j);const{stderrTail:a,...i}=r;o=Object.keys(i).length>0?i:void 0}return{kind:n,message:e,...t!==void 0&&{stderrTail:t},...o!==void 0&&{details:o}}}function W(n){return H("daemon_unreachable",`Docker CLI is not available: ${n.spawnError??"unknown spawn failure"}`,{stderrTail:n.stderrTail})}function _(n,e){if(n==="")return[];const r=n.split(/\r?\n/);for(;r.length>0&&r[r.length-1]==="";)r.pop();return r.slice(-e)}function Z(n){return E(n)}function T(n){return n.ecrSession!==void 0?{...n.env,...n.ecrSession.env}:n.env}function ee(n,e){return new Promise(r=>{let t=!1,o=!1;const a=w(n.abortSignal,e.timeoutMs,e.abortSignal);let i;try{i=h(n.dockerBin,e.args,{shell:!1,env:T(n)})}catch(s){const d=s instanceof Error?s.message:String(s);r({exitCode:null,stdout:"",stderr:d,stderrTail:[d],aborted:!1,spawnError:d});return}let c="",l="";i.stdout?.on("data",s=>{c+=s.toString()}),i.stderr?.on("data",s=>{l+=s.toString()}),e.stdin!==void 0&&(i.stdin?.on("error",s=>{n.logger.debug(A,"stdin write error (typically EPIPE on early child exit)",{error:s.message})}),i.stdin?.write(e.stdin),i.stdin?.end());const g=()=>{t=!0,b(i)};a!==void 0&&(a.aborted?g():a.addEventListener("abort",g,{once:!0})),i.once("error",s=>{if(o)return;o=!0,a!==void 0&&a.removeEventListener("abort",g);const d=s instanceof Error?s.message:String(s);r({exitCode:null,stdout:c,stderr:d,stderrTail:[d],aborted:t,spawnError:d})}),i.once("close",s=>{o||(o=!0,a!==void 0&&a.removeEventListener("abort",g),r({exitCode:s,stdout:c,stderr:l,stderrTail:_(l,S),aborted:t}))})})}function re(n,e,r,t){return new Promise(o=>{let a=!1,i=!1;const c=w(n.abortSignal,e.timeoutMs,e.abortSignal);let l;try{l=h(n.dockerBin,e.args,{shell:!1,env:T(n)})}catch(u){const f=u instanceof Error?u.message:String(u);o({exitCode:null,stderrTail:[f],aborted:!1,spawnError:f,child:null});return}let g="",s="",d="";l.stdout?.on("data",u=>{g+=u.toString();const f=g.split(/\r?\n/);g=f.pop()??"";for(const p of f)r(p)}),l.stderr?.on("data",u=>{const f=u.toString();if(s+=f,t!==void 0){d+=f;const p=d.split(/\r?\n/);d=p.pop()??"";for(const B of p)t(B)}});const m=()=>{a=!0,b(l)};c!==void 0&&(c.aborted?m():c.addEventListener("abort",m,{once:!0})),l.once("error",u=>{if(i)return;i=!0,c!==void 0&&c.removeEventListener("abort",m);const f=u instanceof Error?u.message:String(u);o({exitCode:null,stderrTail:[f],aborted:a,spawnError:f,child:l})}),l.once("close",u=>{i||(i=!0,g!==""&&r(g),t!==void 0&&d!==""&&t(d),c!==void 0&&c.removeEventListener("abort",m),o({exitCode:u,stderrTail:_(s,S),aborted:a,child:l}))})})}function w(n,e,r){const t=[];if(n!==void 0&&t.push(n),r!==void 0&&t.push(r),e!==void 0&&t.push(AbortSignal.timeout(e)),t.length!==0)return t.length===1?t[0]:AbortSignal.any(t)}export{Q as DockerCli,v as failure,H as makeError,Z as maskOutput,ee as runDocker,W as spawnFailureToError,re as streamDocker,M as success,_ as tailLines};
1
+ var x=Object.defineProperty;var l=(t,e)=>x(t,"name",{value:e,configurable:!0});import{spawn as E}from"node:child_process";import{filterDangerousEnvVars as A,maskSensitiveOutput as b}from"../securityHelpers.js";import{abortChildProcess as y}from"./abortHelpers.js";import{DEFAULT_DOCKER_BIN as D,DOCKER_CLI_LOG_CATEGORY as C,STDERR_TAIL_LINE_MAX_CHARS as S,STDERR_TAIL_LINES as v}from"./dockerCliConstants.js";import{_buildxBuild as I,_imagetoolsInspect as L,_tagByDigest as R}from"./DockerCli.build.js";import{_assertBuildxAvailable as O,_detectDaemon as P,_ensureBuilder as N}from"./DockerCli.daemon.js";import{_imageInspect as F,_loginEcr as G,_pull as K,_push as M,_tag as j}from"./DockerCli.registry.js";import{failure as _,success as H}from"./result.js";class ee{static{l(this,"DockerCli")}state;constructor(e){const r=e.dockerBin!==void 0&&e.dockerBin!==""?e.dockerBin:D,n=A(e.env??process.env);this.state={logger:e.logger,dockerBin:r,env:n,abortSignal:e.abortSignal,ecrSession:void 0}}async buildxBuild(e,r,n){return I(this.state,e,r,n)}async tag(e,r){return j(this.state,e,r)}async tagByDigest(e,r,n){return R(this.state,e,r,n)}async push(e,r){return M(this.state,e,r)}async pull(e,r,n){return K(this.state,e,r,n)}async imageInspect(e){return F(this.state,e)}async imagetoolsInspect(e){return L(this.state,e)}async loginEcr(e){return G(this.state,e)}async logoutEcr(){const e=this.state.ecrSession;this.state.ecrSession=void 0,e!==void 0&&await e.dispose()}async withEcrSession(e,r,n){const o=await this.loginEcr(e);if(!o.success)return _(n(o.error));try{return await r()}finally{await this.logoutEcr().catch(()=>{})}}async ensureBuilder(e){return N(this.state,e)}async assertBuildxAvailable(){return O(this.state)}async detectDaemon(){return P(this.state)}}function U(t){const e=b(t);return e.length>S?e.slice(0,S)+"\u2026":e}l(U,"maskAndBoundStderrTailLine");function V(t,e,r){let n,o=r;if(r!==void 0&&Array.isArray(r.stderrTail)&&r.stderrTail.every(a=>typeof a=="string")){n=r.stderrTail.map(U);const{stderrTail:a,...i}=r;o=Object.keys(i).length>0?i:void 0}return{kind:t,message:e,...n!==void 0&&{stderrTail:n},...o!==void 0&&{details:o}}}l(V,"makeError");function re(t){return V("daemon_unreachable",`Docker CLI is not available: ${t.spawnError??"unknown spawn failure"}`,{stderrTail:t.stderrTail})}l(re,"spawnFailureToError");function T(t,e){if(t==="")return[];const r=t.split(/\r?\n/);for(;r.length>0&&r[r.length-1]==="";)r.pop();return r.slice(-e)}l(T,"tailLines");function te(t){return b(t)}l(te,"maskOutput");function w(t){return t.ecrSession!==void 0?{...t.env,...t.ecrSession.env}:t.env}l(w,"spawnEnv");function ne(t,e){return new Promise(r=>{let n=!1,o=!1;const a=B(t.abortSignal,e.timeoutMs,e.abortSignal);let i;try{i=E(t.dockerBin,e.args,{shell:!1,env:w(t)})}catch(s){const d=s instanceof Error?s.message:String(s);r({exitCode:null,stdout:"",stderr:d,stderrTail:[d],aborted:!1,spawnError:d});return}let f="",c="";i.stdout?.on("data",s=>{f+=s.toString()}),i.stderr?.on("data",s=>{c+=s.toString()}),e.stdin!==void 0&&(i.stdin?.on("error",s=>{t.logger.debug(C,"stdin write error (typically EPIPE on early child exit)",{error:s.message})}),i.stdin?.write(e.stdin),i.stdin?.end());const m=l(()=>{n=!0,y(i)},"onAbort");a!==void 0&&(a.aborted?m():a.addEventListener("abort",m,{once:!0})),i.once("error",s=>{if(o)return;o=!0,a!==void 0&&a.removeEventListener("abort",m);const d=s instanceof Error?s.message:String(s);r({exitCode:null,stdout:f,stderr:d,stderrTail:[d],aborted:n,spawnError:d})}),i.once("close",s=>{o||(o=!0,a!==void 0&&a.removeEventListener("abort",m),r({exitCode:s,stdout:f,stderr:c,stderrTail:T(c,v),aborted:n}))})})}l(ne,"runDocker");function se(t,e,r,n){return new Promise(o=>{let a=!1,i=!1;const f=B(t.abortSignal,e.timeoutMs,e.abortSignal);let c;try{c=E(t.dockerBin,e.args,{shell:!1,env:w(t)})}catch(u){const g=u instanceof Error?u.message:String(u);o({exitCode:null,stderrTail:[g],aborted:!1,spawnError:g,child:null});return}let m="",s="",d="";c.stdout?.on("data",u=>{m+=u.toString();const g=m.split(/\r?\n/);m=g.pop()??"";for(const h of g)r(h)}),c.stderr?.on("data",u=>{const g=u.toString();if(s+=g,n!==void 0){d+=g;const h=d.split(/\r?\n/);d=h.pop()??"";for(const k of h)n(k)}});const p=l(()=>{a=!0,y(c)},"onAbort");f!==void 0&&(f.aborted?p():f.addEventListener("abort",p,{once:!0})),c.once("error",u=>{if(i)return;i=!0,f!==void 0&&f.removeEventListener("abort",p);const g=u instanceof Error?u.message:String(u);o({exitCode:null,stderrTail:[g],aborted:a,spawnError:g,child:c})}),c.once("close",u=>{i||(i=!0,m!==""&&r(m),n!==void 0&&d!==""&&n(d),f!==void 0&&f.removeEventListener("abort",p),o({exitCode:u,stderrTail:T(s,v),aborted:a,child:c}))})})}l(se,"streamDocker");function B(t,e,r){const n=[];if(t!==void 0&&n.push(t),r!==void 0&&n.push(r),e!==void 0&&n.push(AbortSignal.timeout(e)),n.length!==0)return n.length===1?n[0]:AbortSignal.any(n)}l(B,"composeAbortSignal");export{ee as DockerCli,_ as failure,V as makeError,te as maskOutput,ne as runDocker,re as spawnFailureToError,se as streamDocker,H as success,T as tailLines};
@@ -1,3 +1,3 @@
1
- import{maskSensitiveOutput as T}from"../securityHelpers.js";import{DEFAULT_INSPECT_TIMEOUT_MS as x,DEFAULT_PULL_TIMEOUT_MS as m,DEFAULT_PUSH_TIMEOUT_MS as E,DOCKER_CLI_LOG_CATEGORY as w}from"./dockerCliConstants.js";import{createEcrAuthSession as $}from"./ecrCredentialStore.js";import{failure as i,makeError as a,maskOutput as g,runDocker as _,spawnFailureToError as f,streamDocker as h,success as u}from"./DockerCli.js";async function M(n,r,e){const t=await _(n,{args:["tag",r,e],timeoutMs:x});return t.spawnError!==void 0?i(f(t)):t.exitCode===null?i(a("abort",`docker tag ${r} ${e} was aborted`,{stderrTail:t.stderrTail})):t.exitCode!==0?i(a("tag_failed",`docker tag ${r} ${e} failed (exit ${t.exitCode})`,{stderrTail:t.stderrTail})):u(void 0)}async function S(n,r,e){let t;const s=await h(n,{args:["push",r],timeoutMs:E},c=>{if(c==="")return;let d;try{d=JSON.parse(c)}catch{n.logger.debug(w,"Skipping malformed push progress line",{line:T(c)});return}if(d===null||typeof d!="object")return;const o=d;o.aux?.digest!==void 0&&(t=o.aux.digest),e!==void 0&&o.id!==void 0&&o.status!==void 0&&e({id:o.id,status:g(o.status),...o.progressDetail?.current!==void 0&&{current:o.progressDetail.current},...o.progressDetail?.total!==void 0&&{total:o.progressDetail.total}})});return s.spawnError!==void 0?i(f(s)):s.aborted||s.exitCode===null?i(a("abort",`docker push ${r} was aborted`,{stderrTail:s.stderrTail})):s.exitCode!==0?s.stderrTail.join(`
2
- `).toLowerCase().includes("unauthorized")?i(a("auth_failed",`docker push ${r} unauthorized`,{stderrTail:s.stderrTail})):i(a("push_failed",`docker push ${r} failed (exit ${s.exitCode})`,{stderrTail:s.stderrTail})):t===void 0?i(a("push_failed",`docker push ${r} succeeded but no digest was reported`,{stderrTail:s.stderrTail})):u({digest:t})}async function y(n,r,e,t){const l=["pull"];e!==void 0&&e!==""&&l.push("--platform",e),l.push(r);let s="";const d=await h(n,{args:l,timeoutMs:m},p=>{s+=`${p}
3
- `,!(t===void 0||p==="")&&t({id:r,status:g(p)})});if(d.spawnError!==void 0)return i(f(d));if(d.aborted||d.exitCode===null)return i(a("abort",`docker pull ${r} was aborted`,{stderrTail:d.stderrTail}));if(d.exitCode!==0)return i(a("pull_failed",`docker pull ${r} failed (exit ${d.exitCode})`,{stderrTail:d.stderrTail}));const o=/sha256:[0-9a-f]{64}/.exec(s);return u({imageId:o?.[0]??r})}async function D(n,r){const e=await _(n,{args:["image","inspect","--format","{{json .}}",r],timeoutMs:x});if(e.spawnError!==void 0)return i(f(e));if(e.exitCode===null)return i(a("abort",`docker image inspect ${r} was aborted`,{stderrTail:e.stderrTail}));if(e.exitCode!==0)return e.stderr.includes("No such image:")?u({exists:!1}):i(a("inspect_failed",`docker image inspect ${r} failed (exit ${e.exitCode})`,{stderrTail:e.stderrTail}));const t=/"Id":"(sha256:[0-9a-f]{64})"/.exec(e.stdout);return u({exists:!0,...t?.[1]!==void 0&&{digest:t[1]}})}async function O(n,r){try{const e=await $({registry:r.registry,username:r.username,password:r.password,baseEnv:n.env,logger:n.logger}),t=n.ecrSession;return n.ecrSession=e,t!==void 0&&await t.dispose(),u(void 0)}catch(e){return i(a("auth_failed",`Failed to configure ECR credentials for ${r.registry}: ${T(e instanceof Error?e.message:String(e))}`))}}export{D as _imageInspect,O as _loginEcr,y as _pull,S as _push,M as _tag};
1
+ var E=Object.defineProperty;var u=(i,e)=>E(i,"name",{value:e,configurable:!0});import{maskSensitiveOutput as x}from"../securityHelpers.js";import{DEFAULT_INSPECT_TIMEOUT_MS as g,DEFAULT_PULL_TIMEOUT_MS as w,DEFAULT_PUSH_TIMEOUT_MS as $,DOCKER_CLI_LOG_CATEGORY as C}from"./dockerCliConstants.js";import{createEcrAuthSession as k}from"./ecrCredentialStore.js";import{failure as s,makeError as a,maskOutput as _,runDocker as h,spawnFailureToError as p,streamDocker as m,success as l}from"./DockerCli.js";async function D(i,e,r){const t=await h(i,{args:["tag",e,r],timeoutMs:g});return t.spawnError!==void 0?s(p(t)):t.exitCode===null?s(a("abort",`docker tag ${e} ${r} was aborted`,{stderrTail:t.stderrTail})):t.exitCode!==0?s(a("tag_failed",`docker tag ${e} ${r} failed (exit ${t.exitCode})`,{stderrTail:t.stderrTail})):l(void 0)}u(D,"_tag");async function O(i,e,r){let t;const n=await m(i,{args:["push",e],timeoutMs:$},u(f=>{if(f==="")return;let d;try{d=JSON.parse(f)}catch{i.logger.debug(C,"Skipping malformed push progress line",{line:x(f)});return}if(d===null||typeof d!="object")return;const o=d;o.aux?.digest!==void 0&&(t=o.aux.digest),r!==void 0&&o.id!==void 0&&o.status!==void 0&&r({id:o.id,status:_(o.status),...o.progressDetail?.current!==void 0&&{current:o.progressDetail.current},...o.progressDetail?.total!==void 0&&{total:o.progressDetail.total}})},"onLine"));return n.spawnError!==void 0?s(p(n)):n.aborted||n.exitCode===null?s(a("abort",`docker push ${e} was aborted`,{stderrTail:n.stderrTail})):n.exitCode!==0?n.stderrTail.join(`
2
+ `).toLowerCase().includes("unauthorized")?s(a("auth_failed",`docker push ${e} unauthorized`,{stderrTail:n.stderrTail})):s(a("push_failed",`docker push ${e} failed (exit ${n.exitCode})`,{stderrTail:n.stderrTail})):t===void 0?s(a("push_failed",`docker push ${e} succeeded but no digest was reported`,{stderrTail:n.stderrTail})):l({digest:t})}u(O,"_push");async function I(i,e,r,t){const c=["pull"];r!==void 0&&r!==""&&c.push("--platform",r),c.push(e);let n="";const d=await m(i,{args:c,timeoutMs:w},u(T=>{n+=`${T}
3
+ `,!(t===void 0||T==="")&&t({id:e,status:_(T)})},"onLine"));if(d.spawnError!==void 0)return s(p(d));if(d.aborted||d.exitCode===null)return s(a("abort",`docker pull ${e} was aborted`,{stderrTail:d.stderrTail}));if(d.exitCode!==0)return s(a("pull_failed",`docker pull ${e} failed (exit ${d.exitCode})`,{stderrTail:d.stderrTail}));const o=/sha256:[0-9a-f]{64}/.exec(n);return l({imageId:o?.[0]??e})}u(I,"_pull");async function U(i,e){const r=await h(i,{args:["image","inspect","--format","{{json .}}",e],timeoutMs:g});if(r.spawnError!==void 0)return s(p(r));if(r.exitCode===null)return s(a("abort",`docker image inspect ${e} was aborted`,{stderrTail:r.stderrTail}));if(r.exitCode!==0)return r.stderr.includes("No such image:")?l({exists:!1}):s(a("inspect_failed",`docker image inspect ${e} failed (exit ${r.exitCode})`,{stderrTail:r.stderrTail}));const t=/"Id":"(sha256:[0-9a-f]{64})"/.exec(r.stdout);return l({exists:!0,...t?.[1]!==void 0&&{digest:t[1]}})}u(U,"_imageInspect");async function A(i,e){try{const r=await k({registry:e.registry,username:e.username,password:e.password,baseEnv:i.env,logger:i.logger}),t=i.ecrSession;return i.ecrSession=r,t!==void 0&&await t.dispose(),l(void 0)}catch(r){return s(a("auth_failed",`Failed to configure ECR credentials for ${e.registry}: ${x(r instanceof Error?r.message:String(r))}`))}}u(A,"_loginEcr");export{U as _imageInspect,A as _loginEcr,I as _pull,O as _push,D as _tag};
@@ -1 +1 @@
1
- import{spawnSync as o}from"node:child_process";import{SIGTERM_GRACE_MS as s}from"./dockerCliConstants.js";function f(t,r=process.platform){if(t.pid===void 0)return;if(t.stdout&&t.stdout.destroy(),t.stderr&&t.stderr.destroy(),r==="win32"){o("taskkill",["/T","/F","/PID",String(t.pid)],{shell:!1});return}t.kill("SIGTERM");const e=setTimeout(()=>{t.killed||t.kill("SIGKILL")},s);t.once("exit",()=>clearTimeout(e))}export{f as abortChildProcess};
1
+ var s=Object.defineProperty;var e=(t,r)=>s(t,"name",{value:r,configurable:!0});import{spawnSync as i}from"node:child_process";import{SIGTERM_GRACE_MS as n}from"./dockerCliConstants.js";function u(t,r=process.platform){if(t.pid===void 0)return;if(t.stdout&&t.stdout.destroy(),t.stderr&&t.stderr.destroy(),r==="win32"){i("taskkill",["/T","/F","/PID",String(t.pid)],{shell:!1});return}t.kill("SIGTERM");const o=setTimeout(()=>{t.killed||t.kill("SIGKILL")},n);t.once("exit",()=>clearTimeout(o))}e(u,"abortChildProcess");export{u as abortChildProcess};
@@ -1 +1 @@
1
- import{maskSensitiveOutput as o}from"../securityHelpers.js";import{PUBLIC_BUILD_ARG_PREFIXES as l,isPublicBuildVarName as s}from"./buildArgInference.js";const u="baked values are world-readable in `docker history`, image provenance/SBOM, and the `<app>-cache` mode=max ECR cache repo";function p(){const e=new Set;return n=>e.has(n)?!1:(e.add(n),!0)}function g(e,n){const a=[],i=[];if(e===void 0)return{findings:a,warnings:i};for(const[t,r]of Object.entries(e)){if(typeof r=="object"){if(r.acknowledgePublic===!0)continue;if(r.ssm!==void 0||r.secretsManager!==void 0){a.push({key:t,reason:"sourced-ref",message:`buildArg "${t}" (app "${n}") is sourced from a secret store (SSM/Secrets Manager) but baked via --build-arg \u2014 ${u}. Move it to docker.buildSecrets (BuildKit --secret mount, never baked), or, if the value is genuinely public-but-sensitive and must ship in the client bundle, set acknowledgePublic: true to bake it deliberately.`});continue}s(t)||i.push({key:t,message:d(t)});continue}if(o(r)!==r){a.push({key:t,reason:"credential-shape",message:c(t,n)});continue}s(t)||i.push({key:t,message:d(t)})}return{findings:a,warnings:i}}function d(e){return`buildArg "${e}" does not start with a public prefix (${l.join(", ")}) and is frozen into the image at build time \u2014 ${u}. If this value should vary per deploy, use a runtime env var (ECS task environment) instead of baking it.`}function c(e,n){return`buildArg "${e}" (app "${n}") has a value that looks like a credential but would be baked via --build-arg \u2014 ${u}. Move it to docker.buildSecrets (BuildKit --secret mount, never baked). If it is a genuinely public-but-sensitive value, use the object form { ssm/secretsManager/env, acknowledgePublic: true } to bake it deliberately.`}function k(e){const n=new Set;if(e===void 0)return n;for(const[a,i]of Object.entries(e))typeof i=="object"&&i.acknowledgePublic===!0&&n.add(a);return n}function v(e,n,a){const i=[];for(const[t,r]of Object.entries(e))a.has(t)||o(r)!==r&&i.push({key:t,reason:"credential-shape",message:c(t,n)});return i}export{u as BAKE_GUARD_EXPOSURE_CLAUSE,k as acknowledgedBuildArgKeys,p as createBakeWarningDeduper,g as evaluateBakeGuard,v as evaluateResolvedBuildArgValues};
1
+ var f=Object.defineProperty;var u=(e,t)=>f(e,"name",{value:t,configurable:!0});import{maskSensitiveOutput as s}from"../securityHelpers.js";import{PUBLIC_BUILD_ARG_PREFIXES as b,isPublicBuildVarName as d}from"./buildArgInference.js";const o="baked values are world-readable in `docker history`, image provenance/SBOM, and the `<app>-cache` mode=max ECR cache repo";function v(){const e=new Set;return t=>e.has(t)?!1:(e.add(t),!0)}u(v,"createBakeWarningDeduper");function h(e,t){const a=[],i=[];if(e===void 0)return{findings:a,warnings:i};for(const[n,r]of Object.entries(e)){if(typeof r=="object"){if(r.acknowledgePublic===!0)continue;if(r.ssm!==void 0||r.secretsManager!==void 0){a.push({key:n,reason:"sourced-ref",message:`buildArg "${n}" (app "${t}") is sourced from a secret store (SSM/Secrets Manager) but baked via --build-arg \u2014 ${o}. Move it to docker.buildSecrets (BuildKit --secret mount, never baked), or, if the value is genuinely public-but-sensitive and must ship in the client bundle, set acknowledgePublic: true to bake it deliberately.`});continue}d(n)||i.push({key:n,message:c(n)});continue}if(s(r)!==r){a.push({key:n,reason:"credential-shape",message:l(n,t)});continue}d(n)||i.push({key:n,message:c(n)})}return{findings:a,warnings:i}}u(h,"evaluateBakeGuard");function c(e){return`buildArg "${e}" does not start with a public prefix (${b.join(", ")}) and is frozen into the image at build time \u2014 ${o}. If this value should vary per deploy, use a runtime env var (ECS task environment) instead of baking it.`}u(c,"nonPrefixedWarning");function l(e,t){return`buildArg "${e}" (app "${t}") has a value that looks like a credential but would be baked via --build-arg \u2014 ${o}. Move it to docker.buildSecrets (BuildKit --secret mount, never baked). If it is a genuinely public-but-sensitive value, use the object form { ssm/secretsManager/env, acknowledgePublic: true } to bake it deliberately.`}u(l,"credentialShapeMessage");function m(e){const t=new Set;if(e===void 0)return t;for(const[a,i]of Object.entries(e))typeof i=="object"&&i.acknowledgePublic===!0&&t.add(a);return t}u(m,"acknowledgedBuildArgKeys");function S(e,t,a){const i=[];for(const[n,r]of Object.entries(e))a.has(n)||s(r)!==r&&i.push({key:n,reason:"credential-shape",message:l(n,t)});return i}u(S,"evaluateResolvedBuildArgValues");export{o as BAKE_GUARD_EXPOSURE_CLAUSE,m as acknowledgedBuildArgKeys,v as createBakeWarningDeduper,h as evaluateBakeGuard,S as evaluateResolvedBuildArgValues};
@@ -1 +1 @@
1
- const c=["VITE_","NEXT_PUBLIC_","PUBLIC_"];function i(e){return c.some(t=>e.startsWith(t))}function s(e){const t=e.explicitBuildArgs??{},r=new Set([...Object.keys(e.declaredEnv??{}),...e.dotenvKeys??[]]),o=[];for(const n of r)i(n)&&(Object.prototype.hasOwnProperty.call(t,n)||o.push(n));return o}export{c as PUBLIC_BUILD_ARG_PREFIXES,s as inferPublicBuildArgKeys,i as isPublicBuildVarName};
1
+ var i=Object.defineProperty;var o=(e,t)=>i(e,"name",{value:t,configurable:!0});const s=["VITE_","NEXT_PUBLIC_","PUBLIC_"];function l(e){return s.some(t=>e.startsWith(t))}o(l,"isPublicBuildVarName");function d(e){const t=e.explicitBuildArgs??{},c=new Set([...Object.keys(e.declaredEnv??{}),...e.dotenvKeys??[]]),r=[];for(const n of c)l(n)&&(Object.prototype.hasOwnProperty.call(t,n)||r.push(n));return r}o(d,"inferPublicBuildArgKeys");export{s as PUBLIC_BUILD_ARG_PREFIXES,d as inferPublicBuildArgKeys,l as isPublicBuildVarName};
@@ -1 +1 @@
1
- import{DEFAULT_BUILDER_NAME as i}from"./dockerCliConstants.js";function c(e){const t=["buildx","build"];t.push("--builder",e.builder??i),t.push("--progress=rawjson"),t.push("--metadata-file",e.metadataFile),t.push("--platform",e.platforms.join(","));for(const u of e.tags)t.push("-t",u);t.push("-f",e.dockerfilePath),e.pushByDigest===!0&&e.imageName!==void 0&&t.push("--output",`type=image,name=${e.imageName},push-by-digest=true,push=true`);for(const[u,o]of Object.entries(e.buildArgs))t.push("--build-arg",`${u}=${o}`);if(e.target!==void 0&&t.push("--target",e.target),e.cacheFrom!==void 0)for(const u of e.cacheFrom)t.push("--cache-from",u);if(e.cacheTo!==void 0)for(const u of e.cacheTo)t.push("--cache-to",u);if(e.secrets!==void 0)for(const u of e.secrets){const o=u.source.kind==="file"?`src=${u.source.path}`:`env=${u.source.name}`;t.push("--secret",`id=${u.id},${o}`)}return t.push(`--provenance=${e.provenance?"true":"false"}`),t.push(`--sbom=${e.sbom?"true":"false"}`),e.pushByDigest!==!0&&(e.push&&t.push("--push"),e.load&&t.push("--load")),t.push(e.contextPath),t}export{c as buildxArgvBuilder};
1
+ var f=Object.defineProperty;var i=(e,t)=>f(e,"name",{value:t,configurable:!0});import{DEFAULT_BUILDER_NAME as c}from"./dockerCliConstants.js";function n(e){const t=["buildx","build"];t.push("--builder",e.builder??c),t.push("--progress=rawjson"),t.push("--metadata-file",e.metadataFile),t.push("--platform",e.platforms.join(","));for(const u of e.tags)t.push("-t",u);t.push("-f",e.dockerfilePath),e.pushByDigest===!0&&e.imageName!==void 0&&t.push("--output",`type=image,name=${e.imageName},push-by-digest=true,push=true`);for(const[u,o]of Object.entries(e.buildArgs))t.push("--build-arg",`${u}=${o}`);if(e.target!==void 0&&t.push("--target",e.target),e.cacheFrom!==void 0)for(const u of e.cacheFrom)t.push("--cache-from",u);if(e.cacheTo!==void 0)for(const u of e.cacheTo)t.push("--cache-to",u);if(e.secrets!==void 0)for(const u of e.secrets){const o=u.source.kind==="file"?`src=${u.source.path}`:`env=${u.source.name}`;t.push("--secret",`id=${u.id},${o}`)}return t.push(`--provenance=${e.provenance?"true":"false"}`),t.push(`--sbom=${e.sbom?"true":"false"}`),e.pushByDigest!==!0&&(e.push&&t.push("--push"),e.load&&t.push("--load")),t.push(e.contextPath),t}i(n,"buildxArgvBuilder");export{n as buildxArgvBuilder};
@@ -1 +1 @@
1
- import{DEFAULT_BUILD_TIMEOUT_MS as g,DEFAULT_PUSH_STALL_TIMEOUT_MS as T}from"./dockerCliConstants.js";import{failure as h,success as u}from"./result.js";const d="FJALL_BUILD_TIMEOUT_MS",m="FJALL_PUSH_STALL_TIMEOUT_MS",c=2147483647,M=2e3;function f(r,e,t){const i=r[e];if(i===void 0)return u(t);if(!/^\d+$/.test(i)||parseInt(i,10)<=0)return h(new Error(`${e} must be a positive integer number of milliseconds (got ${JSON.stringify(i)}) \u2014 fix or unset it (default ${t} ms)`));const s=parseInt(i,10);return s>c?h(new Error(`${e} must be at most ${c} ms (got ${s})`)):u(s)}function w(r){const e=f(r,d,g);if(!e.success)return e;const t=f(r,m,T);return t.success?u({compilePhaseTimeoutMs:e.data,publishStallTimeoutMs:t.data}):t}function b(r){const e=r.toLowerCase();return e.startsWith("exporting")||e.startsWith("pushing")}function y(r){const e=r.toLowerCase();return e.startsWith("pushing")||e.startsWith("writing layer")}function l(r){const e=["B","kB","MB","GB","TB"];let t=r,i=0;for(;t>=1e3&&i<e.length-1;)t/=1e3,i+=1;return`${t.toFixed(t<10&&i>0?1:0)} ${e[i]}`}class _{budgets;controller=new AbortController;now;compileTimer;stallTimer;lastActivityAt;lastEmitAt;lastEmitMessage;pendingPhaseFlipMessage;publishStartedFlag=!1;disposed=!1;timedOutPhaseValue;statusMemos=new Map;vertexStamps=new Map;transfers=new Map;constructor(e,t){this.budgets=e,this.now=t?.now??Date.now,this.lastActivityAt=this.now(),this.compileTimer=setTimeout(()=>{this.trip("build")},e.compilePhaseTimeoutMs)}get signal(){return this.controller.signal}get timedOutPhase(){return this.timedOutPhaseValue}get publishStarted(){return this.publishStartedFlag}observe(e){if(this.disposed)return;let t=!1,i=!1;for(const s of e.vertexes){const n=`${s.started??""}|${s.completed??""}|${s.error??""}`;this.vertexStamps.get(s.digest)!==n&&(this.vertexStamps.set(s.digest,n),t=!0),s.started!==void 0&&b(s.name)&&(i=!0)}for(const s of e.statuses){const n=`${s.vertex}|${s.id}`,a=this.statusMemos.get(n),o={current:s.current,total:s.total,completed:s.completed!==void 0};(a===void 0||a.current!==o.current||a.total!==o.total||a.completed!==o.completed)&&(this.statusMemos.set(n,o),t=!0),y(s.name)&&(i=!0,this.transfers.set(n,o))}return(e.logs.length>0||e.warnings.length>0)&&(t=!0),i&&!this.publishStartedFlag&&this.beginPublishPhase(),t&&(this.lastActivityAt=this.now()),this.maybeSyntheticProgress()}progressSummary(){if(this.transfers.size===0)return;const e=this.aggregateTransfers(),t=`${e.completedTransfers}/${e.knownTransfers} layers complete`;if(e.totalBytes>0){const i=Math.min(100,Math.round(e.currentBytes/e.totalBytes*100));return`${l(e.currentBytes)} of ${l(e.totalBytes)} pushed (${i}%), ${t}`}return`${l(e.currentBytes)} pushed, ${t}`}dispose(){this.disposed=!0,this.compileTimer!==void 0&&(clearTimeout(this.compileTimer),this.compileTimer=void 0),this.clearStallTimer()}aggregateTransfers(){let e=0,t=0,i=0;for(const s of this.transfers.values())s.total!==void 0&&s.total>0?(t+=s.total,e+=Math.min(s.current,s.total)):e+=s.current,s.completed&&(i+=1);return{currentBytes:e,totalBytes:t,completedTransfers:i,knownTransfers:this.transfers.size}}maybeSyntheticProgress(){if(this.pendingPhaseFlipMessage!==void 0){const a=this.pendingPhaseFlipMessage;return this.pendingPhaseFlipMessage=void 0,this.lastEmitAt=this.now(),{message:a}}if(!this.publishStartedFlag||this.transfers.size===0)return;const e=this.now();if(this.lastEmitAt!==void 0&&e-this.lastEmitAt<M)return;const t=this.aggregateTransfers(),i=`${t.completedTransfers}/${t.knownTransfers} layers`;let s,n;if(t.totalBytes>0?(n=Math.min(100,Math.round(t.currentBytes/t.totalBytes*100)),s=`Pushing to registry: ${l(t.currentBytes)} of ${l(t.totalBytes)} \u2014 ${i}`):s=`Pushing to registry: ${l(t.currentBytes)} transferred \u2014 ${i}`,s!==this.lastEmitMessage)return this.lastEmitAt=e,this.lastEmitMessage=s,{message:s,...n!==void 0&&{percentage:n}}}beginPublishPhase(){this.publishStartedFlag=!0,this.compileTimer!==void 0&&(clearTimeout(this.compileTimer),this.compileTimer=void 0),this.lastActivityAt=this.now(),this.armStallTimer(this.budgets.publishStallTimeoutMs),this.pendingPhaseFlipMessage="Image build complete \u2014 pushing image and exporting build cache to the registry\u2026"}armStallTimer(e){this.clearStallTimer(),this.stallTimer=setTimeout(()=>{this.stallTimer=void 0;const t=this.now()-this.lastActivityAt;t>=this.budgets.publishStallTimeoutMs?this.trip("publish"):this.armStallTimer(this.budgets.publishStallTimeoutMs-t)},e)}clearStallTimer(){this.stallTimer!==void 0&&(clearTimeout(this.stallTimer),this.stallTimer=void 0)}trip(e){this.timedOutPhaseValue===void 0&&(this.timedOutPhaseValue=e,this.dispose(),this.controller.abort())}}function p(r){const e=r/6e4;return`${Number.isInteger(e)?e:e.toFixed(1)} minute${e===1?"":"s"}`}function P(r){return`docker buildx build exceeded the ${p(r.compilePhaseTimeoutMs)} build budget before the image finished compiling \u2014 nothing was pushed. If this build legitimately needs longer, set ${d} to a higher millisecond value.`}function A(r,e){const t=e!==void 0?`Progress before the stall: ${e}.`:"No upload progress was observed.";return`docker buildx push stalled \u2014 no upload progress for ${p(r.publishStallTimeoutMs)} while pushing the image and exporting the build cache. ${t} The image compiled successfully, so retrying is cheap: layers already pushed are deduplicated by the registry and the build cache is warm. If your connection is slow with long quiet spells, set ${m} to a higher millisecond value.`}export{d as BUILD_TIMEOUT_ENV_VAR,_ as BuildxBuildMonitor,m as PUSH_STALL_TIMEOUT_ENV_VAR,P as buildPhaseTimeoutMessage,A as publishStallTimeoutMessage,w as resolveBuildxBudgets};
1
+ var T=Object.defineProperty;var a=(r,e)=>T(r,"name",{value:e,configurable:!0});import{DEFAULT_BUILD_TIMEOUT_MS as M,DEFAULT_PUSH_STALL_TIMEOUT_MS as b}from"./dockerCliConstants.js";import{failure as d,success as h}from"./result.js";const m="FJALL_BUILD_TIMEOUT_MS",c="FJALL_PUSH_STALL_TIMEOUT_MS",f=2147483647,y=2e3;function p(r,e,t){const i=r[e];if(i===void 0)return h(t);if(!/^\d+$/.test(i)||parseInt(i,10)<=0)return d(new Error(`${e} must be a positive integer number of milliseconds (got ${JSON.stringify(i)}) \u2014 fix or unset it (default ${t} ms)`));const s=parseInt(i,10);return s>f?d(new Error(`${e} must be at most ${f} ms (got ${s})`)):h(s)}a(p,"parseMsOverride");function A(r){const e=p(r,m,M);if(!e.success)return e;const t=p(r,c,b);return t.success?h({compilePhaseTimeoutMs:e.data,publishStallTimeoutMs:t.data}):t}a(A,"resolveBuildxBudgets");function S(r){const e=r.toLowerCase();return e.startsWith("exporting")||e.startsWith("pushing")}a(S,"isPublishVertexName");function $(r){const e=r.toLowerCase();return e.startsWith("pushing")||e.startsWith("writing layer")}a($,"isTransferStatusName");function o(r){const e=["B","kB","MB","GB","TB"];let t=r,i=0;for(;t>=1e3&&i<e.length-1;)t/=1e3,i+=1;return`${t.toFixed(t<10&&i>0?1:0)} ${e[i]}`}a(o,"formatByteSize");class B{static{a(this,"BuildxBuildMonitor")}budgets;controller=new AbortController;now;compileTimer;stallTimer;lastActivityAt;lastEmitAt;lastEmitMessage;pendingPhaseFlipMessage;publishStartedFlag=!1;disposed=!1;timedOutPhaseValue;statusMemos=new Map;vertexStamps=new Map;transfers=new Map;constructor(e,t){this.budgets=e,this.now=t?.now??Date.now,this.lastActivityAt=this.now(),this.compileTimer=setTimeout(()=>{this.trip("build")},e.compilePhaseTimeoutMs)}get signal(){return this.controller.signal}get timedOutPhase(){return this.timedOutPhaseValue}get publishStarted(){return this.publishStartedFlag}observe(e){if(this.disposed)return;let t=!1,i=!1;for(const s of e.vertexes){const n=`${s.started??""}|${s.completed??""}|${s.error??""}`;this.vertexStamps.get(s.digest)!==n&&(this.vertexStamps.set(s.digest,n),t=!0),s.started!==void 0&&S(s.name)&&(i=!0)}for(const s of e.statuses){const n=`${s.vertex}|${s.id}`,l=this.statusMemos.get(n),u={current:s.current,total:s.total,completed:s.completed!==void 0};(l===void 0||l.current!==u.current||l.total!==u.total||l.completed!==u.completed)&&(this.statusMemos.set(n,u),t=!0),$(s.name)&&(i=!0,this.transfers.set(n,u))}return(e.logs.length>0||e.warnings.length>0)&&(t=!0),i&&!this.publishStartedFlag&&this.beginPublishPhase(),t&&(this.lastActivityAt=this.now()),this.maybeSyntheticProgress()}progressSummary(){if(this.transfers.size===0)return;const e=this.aggregateTransfers(),t=`${e.completedTransfers}/${e.knownTransfers} layers complete`;if(e.totalBytes>0){const i=Math.min(100,Math.round(e.currentBytes/e.totalBytes*100));return`${o(e.currentBytes)} of ${o(e.totalBytes)} pushed (${i}%), ${t}`}return`${o(e.currentBytes)} pushed, ${t}`}dispose(){this.disposed=!0,this.compileTimer!==void 0&&(clearTimeout(this.compileTimer),this.compileTimer=void 0),this.clearStallTimer()}aggregateTransfers(){let e=0,t=0,i=0;for(const s of this.transfers.values())s.total!==void 0&&s.total>0?(t+=s.total,e+=Math.min(s.current,s.total)):e+=s.current,s.completed&&(i+=1);return{currentBytes:e,totalBytes:t,completedTransfers:i,knownTransfers:this.transfers.size}}maybeSyntheticProgress(){if(this.pendingPhaseFlipMessage!==void 0){const l=this.pendingPhaseFlipMessage;return this.pendingPhaseFlipMessage=void 0,this.lastEmitAt=this.now(),{message:l}}if(!this.publishStartedFlag||this.transfers.size===0)return;const e=this.now();if(this.lastEmitAt!==void 0&&e-this.lastEmitAt<y)return;const t=this.aggregateTransfers(),i=`${t.completedTransfers}/${t.knownTransfers} layers`;let s,n;if(t.totalBytes>0?(n=Math.min(100,Math.round(t.currentBytes/t.totalBytes*100)),s=`Pushing to registry: ${o(t.currentBytes)} of ${o(t.totalBytes)} \u2014 ${i}`):s=`Pushing to registry: ${o(t.currentBytes)} transferred \u2014 ${i}`,s!==this.lastEmitMessage)return this.lastEmitAt=e,this.lastEmitMessage=s,{message:s,...n!==void 0&&{percentage:n}}}beginPublishPhase(){this.publishStartedFlag=!0,this.compileTimer!==void 0&&(clearTimeout(this.compileTimer),this.compileTimer=void 0),this.lastActivityAt=this.now(),this.armStallTimer(this.budgets.publishStallTimeoutMs),this.pendingPhaseFlipMessage="Image build complete \u2014 pushing image and exporting build cache to the registry\u2026"}armStallTimer(e){this.clearStallTimer(),this.stallTimer=setTimeout(()=>{this.stallTimer=void 0;const t=this.now()-this.lastActivityAt;t>=this.budgets.publishStallTimeoutMs?this.trip("publish"):this.armStallTimer(this.budgets.publishStallTimeoutMs-t)},e)}clearStallTimer(){this.stallTimer!==void 0&&(clearTimeout(this.stallTimer),this.stallTimer=void 0)}trip(e){this.timedOutPhaseValue===void 0&&(this.timedOutPhaseValue=e,this.dispose(),this.controller.abort())}}function g(r){const e=r/6e4;return`${Number.isInteger(e)?e:e.toFixed(1)} minute${e===1?"":"s"}`}a(g,"formatMinutes");function x(r){return`docker buildx build exceeded the ${g(r.compilePhaseTimeoutMs)} build budget before the image finished compiling \u2014 nothing was pushed. If this build legitimately needs longer, set ${m} to a higher millisecond value.`}a(x,"buildPhaseTimeoutMessage");function E(r,e){const t=e!==void 0?`Progress before the stall: ${e}.`:"No upload progress was observed.";return`docker buildx push stalled \u2014 no upload progress for ${g(r.publishStallTimeoutMs)} while pushing the image and exporting the build cache. ${t} The image compiled successfully, so retrying is cheap: layers already pushed are deduplicated by the registry and the build cache is warm. If your connection is slow with long quiet spells, set ${c} to a higher millisecond value.`}a(E,"publishStallTimeoutMessage");export{m as BUILD_TIMEOUT_ENV_VAR,B as BuildxBuildMonitor,c as PUSH_STALL_TIMEOUT_ENV_VAR,x as buildPhaseTimeoutMessage,E as publishStallTimeoutMessage,A as resolveBuildxBudgets};
@@ -1 +1 @@
1
- import{failure as i,success as o}from"./result.js";function u(e){return`${e}-cache`}const n="FJALL_BUILD_CACHE_MODE",c=["max","min","off"],s=new Set(c);function f(e){const r=e[n];return r===void 0?o("max"):s.has(r)?o(r):i(new Error(`${n} must be one of ${c.join(", ")} (got ${JSON.stringify(r)}) \u2014 fix or unset it`))}function d(e){if(e.cacheRepoUri===void 0)return;const r=(e.serviceName??e.appName).toLowerCase(),t=`type=registry,ref=${e.cacheRepoUri}:${r}`;return{cacheFrom:[t],...e.mode!=="off"&&{cacheTo:[`${t},mode=${e.mode}`]}}}const m=14;function E(e){return JSON.stringify({rules:[{rulePriority:1,description:`Expire untagged images after ${e} days`,selection:{tagStatus:"untagged",countType:"sinceImagePushed",countUnit:"days",countNumber:e},action:{type:"expire"}}]})}export{c as BUILD_CACHE_MODES,n as BUILD_CACHE_MODE_ENV_VAR,m as CACHE_REPO_UNTAGGED_RETENTION_DAYS,u as buildCacheRepositoryName,d as buildRegistryCacheRefs,f as resolveBuildCacheMode,E as untaggedLifecyclePolicyText};
1
+ var s=Object.defineProperty;var t=(e,r)=>s(e,"name",{value:r,configurable:!0});import{failure as a,success as n}from"./result.js";function m(e){return`${e}-cache`}t(m,"buildCacheRepositoryName");const c="FJALL_BUILD_CACHE_MODE",i=["max","min","off"],u=new Set(i);function E(e){const r=e[c];return r===void 0?n("max"):u.has(r)?n(r):a(new Error(`${c} must be one of ${i.join(", ")} (got ${JSON.stringify(r)}) \u2014 fix or unset it`))}t(E,"resolveBuildCacheMode");function _(e){if(e.cacheRepoUri===void 0)return;const r=(e.serviceName??e.appName).toLowerCase(),o=`type=registry,ref=${e.cacheRepoUri}:${r}`;return{cacheFrom:[o],...e.mode!=="off"&&{cacheTo:[`${o},mode=${e.mode}`]}}}t(_,"buildRegistryCacheRefs");const g=14;function C(e){return JSON.stringify({rules:[{rulePriority:1,description:`Expire untagged images after ${e} days`,selection:{tagStatus:"untagged",countType:"sinceImagePushed",countUnit:"days",countNumber:e},action:{type:"expire"}}]})}t(C,"untaggedLifecyclePolicyText");export{i as BUILD_CACHE_MODES,c as BUILD_CACHE_MODE_ENV_VAR,g as CACHE_REPO_UNTAGGED_RETENTION_DAYS,m as buildCacheRepositoryName,_ as buildRegistryCacheRefs,E as resolveBuildCacheMode,C as untaggedLifecyclePolicyText};
@@ -1 +1 @@
1
- import{z as e}from"zod";const i=e.enum(["buildx_unavailable","daemon_unreachable","build_failed","push_failed","pull_failed","tag_failed","inspect_failed","auth_failed","abort","timeout","validation","metadata_missing","metadata_malformed","metadata_missing_digest"]),n=new Set(i.options);function r(t){return n.has(t)}const s=e.object({contextPath:e.string().min(1),dockerfilePath:e.string().min(1),target:e.string().min(1).optional(),platforms:e.array(e.string().min(1)).min(1),tags:e.array(e.string().min(1)),buildArgs:e.record(e.string(),e.string()),cacheFrom:e.array(e.string().min(1)).optional(),cacheTo:e.array(e.string().min(1)).optional(),secrets:e.array(e.object({id:e.string().min(1),source:e.discriminatedUnion("kind",[e.object({kind:e.literal("file"),path:e.string().min(1)}).strict(),e.object({kind:e.literal("env"),name:e.string().min(1)}).strict()])}).strict()).optional(),provenance:e.boolean(),sbom:e.boolean(),push:e.boolean(),load:e.boolean(),pushByDigest:e.boolean().optional(),imageName:e.string().min(1).optional(),builder:e.string().min(1,"Builder name cannot be empty").optional(),metadataFile:e.string().min(1)}).strict().refine(t=>!(t.platforms.length>1&&t.load),{message:"Multi-arch builds cannot use load:true (Docker limitation); use push:true or omit both for cache-only"}).refine(t=>!(t.push&&t.load),{message:"push and load are mutually exclusive"}).refine(t=>t.pushByDigest!==!0||t.imageName!==void 0,{message:"pushByDigest requires imageName (the registry repo to push to)"}).refine(t=>t.pushByDigest===!0||t.tags.length>=1,{message:"tags must be non-empty unless pushByDigest is set"}),o=e.object({digest:e.string(),imageDigests:e.record(e.string(),e.string()),metadata:e.record(e.string(),e.unknown()),platforms:e.array(e.string()),cacheHits:e.number().int().nonnegative(),cacheMisses:e.number().int().nonnegative()}).strict(),l=e.object({kind:i,message:e.string(),stderrTail:e.array(e.string()).optional(),details:e.unknown().optional()}).strict();export{s as BuildxBuildArgsSchema,o as BuildxBuildResultSchema,i as DockerCliErrorKindSchema,l as DockerCliErrorSchema,r as isDockerCliErrorKind};
1
+ var r=Object.defineProperty;var i=(t,a)=>r(t,"name",{value:a,configurable:!0});import{z as e}from"zod";const n=e.enum(["buildx_unavailable","daemon_unreachable","build_failed","push_failed","pull_failed","tag_failed","inspect_failed","auth_failed","abort","timeout","validation","metadata_missing","metadata_malformed","metadata_missing_digest"]),s=new Set(n.options);function m(t){return s.has(t)}i(m,"isDockerCliErrorKind");const g=e.object({contextPath:e.string().min(1),dockerfilePath:e.string().min(1),target:e.string().min(1).optional(),platforms:e.array(e.string().min(1)).min(1),tags:e.array(e.string().min(1)),buildArgs:e.record(e.string(),e.string()),cacheFrom:e.array(e.string().min(1)).optional(),cacheTo:e.array(e.string().min(1)).optional(),secrets:e.array(e.object({id:e.string().min(1),source:e.discriminatedUnion("kind",[e.object({kind:e.literal("file"),path:e.string().min(1)}).strict(),e.object({kind:e.literal("env"),name:e.string().min(1)}).strict()])}).strict()).optional(),provenance:e.boolean(),sbom:e.boolean(),push:e.boolean(),load:e.boolean(),pushByDigest:e.boolean().optional(),imageName:e.string().min(1).optional(),builder:e.string().min(1,"Builder name cannot be empty").optional(),metadataFile:e.string().min(1)}).strict().refine(t=>!(t.platforms.length>1&&t.load),{message:"Multi-arch builds cannot use load:true (Docker limitation); use push:true or omit both for cache-only"}).refine(t=>!(t.push&&t.load),{message:"push and load are mutually exclusive"}).refine(t=>t.pushByDigest!==!0||t.imageName!==void 0,{message:"pushByDigest requires imageName (the registry repo to push to)"}).refine(t=>t.pushByDigest===!0||t.tags.length>=1,{message:"tags must be non-empty unless pushByDigest is set"}),c=e.object({digest:e.string(),imageDigests:e.record(e.string(),e.string()),metadata:e.record(e.string(),e.unknown()),platforms:e.array(e.string()),cacheHits:e.number().int().nonnegative(),cacheMisses:e.number().int().nonnegative()}).strict(),u=e.object({kind:n,message:e.string(),stderrTail:e.array(e.string()).optional(),details:e.unknown().optional()}).strict();export{g as BuildxBuildArgsSchema,c as BuildxBuildResultSchema,n as DockerCliErrorKindSchema,u as DockerCliErrorSchema,m as isDockerCliErrorKind};
@@ -1 +1 @@
1
- import{mkdtemp as S,readFile as F,rm as g,stat as C,symlink as y,writeFile as _}from"node:fs/promises";import{homedir as j,tmpdir as H}from"node:os";import{join as o}from"node:path";import{maskSensitiveOutput as I}from"../securityHelpers.js";import{DOCKER_CLI_LOG_CATEGORY as s}from"./dockerCliConstants.js";function u(e){return I(e instanceof Error?e.message:String(e))}function N(e){let r=e.replace(/^https?:\/\//i,"");const t=r.indexOf("/");return t!==-1&&(r=r.slice(0,t)),r}function G(e){const r=e.DOCKER_CONFIG;if(r!==void 0&&r!=="")return r;const t=e.HOME!==void 0&&e.HOME!==""?e.HOME:j();return o(t,".docker")}function A(e,r){const t=e.BUILDX_CONFIG;return t!==void 0&&t!==""?t:o(r,"buildx")}async function B(e,r){let t;try{t=await F(o(e,"config.json"),"utf8")}catch{return{}}try{const i=JSON.parse(t);return i===null||typeof i!="object"||Array.isArray(i)?{}:i}catch(i){return r.warn(s,"Real docker config.json is not valid JSON; using a minimal ephemeral config",{error:u(i)}),{}}}async function L(e,r,t){const i=o(e,"contexts");try{if(!(await C(i)).isDirectory())return}catch{return}try{await y(i,o(r,"contexts"),"dir")}catch(a){t.warn(s,"Could not link docker contexts into the ephemeral config; a non-default docker context may not resolve for this build",{error:u(a)})}}async function J(e,r,t){const i=o(e,"cli-plugins");try{if(!(await C(i)).isDirectory())return}catch{return}try{await y(i,o(r,"cli-plugins"),"dir")}catch(a){t.warn(s,"Could not link docker cli-plugins into the ephemeral config; `docker buildx` may be unavailable for this build",{error:u(a)})}}async function $(e){const{registry:r,username:t,password:i,baseEnv:a,logger:c}=e,d=N(r),l=G(a),h=A(a,l),w=await B(l,c),{credsStore:k,credHelpers:O,auths:D,...x}=w,f={...O??{}};delete f[d];const E=Buffer.from(`${t}:${i}`,"utf8").toString("base64"),b={...D??{},[d]:{auth:E}},R={...x,auths:b,...Object.keys(f).length>0?{credHelpers:f}:{}};let p;try{const n=await S(o(H(),"fjall-ecr-auth-"));p=n,await _(o(n,"config.json"),JSON.stringify(R),{mode:384}),await L(l,n,c),await J(l,n,c),c.debug(s,"Established ephemeral ECR credential context",{registry:d,dockerConfig:n,buildxConfig:h});let m=!1;return{env:{DOCKER_CONFIG:n,BUILDX_CONFIG:h},async dispose(){m||(m=!0,await g(n,{recursive:!0,force:!0}).catch(v=>{c.warn(s,"Failed to remove ephemeral ECR credential dir",{path:n,error:u(v)})}))}}}catch(n){throw p!==void 0&&await g(p,{recursive:!0,force:!0}).catch(()=>{}),n}}export{$ as createEcrAuthSession};
1
+ var F=Object.defineProperty;var o=(e,r)=>F(e,"name",{value:r,configurable:!0});import{mkdtemp as _,readFile as j,rm as C,stat as y,symlink as w,writeFile as H}from"node:fs/promises";import{homedir as I,tmpdir as N}from"node:os";import{join as a}from"node:path";import{maskSensitiveOutput as G}from"../securityHelpers.js";import{DOCKER_CLI_LOG_CATEGORY as l}from"./dockerCliConstants.js";function d(e){return G(e instanceof Error?e.message:String(e))}o(d,"maskError");function A(e){let r=e.replace(/^https?:\/\//i,"");const t=r.indexOf("/");return t!==-1&&(r=r.slice(0,t)),r}o(A,"registryHost");function B(e){const r=e.DOCKER_CONFIG;if(r!==void 0&&r!=="")return r;const t=e.HOME!==void 0&&e.HOME!==""?e.HOME:I();return a(t,".docker")}o(B,"resolveRealDockerConfigDir");function L(e,r){const t=e.BUILDX_CONFIG;return t!==void 0&&t!==""?t:a(r,"buildx")}o(L,"resolveRealBuildxDir");async function J(e,r){let t;try{t=await j(a(e,"config.json"),"utf8")}catch{return{}}try{const i=JSON.parse(t);return i===null||typeof i!="object"||Array.isArray(i)?{}:i}catch(i){return r.warn(l,"Real docker config.json is not valid JSON; using a minimal ephemeral config",{error:d(i)}),{}}}o(J,"readRealConfig");async function K(e,r,t){const i=a(e,"contexts");try{if(!(await y(i)).isDirectory())return}catch{return}try{await w(i,a(r,"contexts"),"dir")}catch(c){t.warn(l,"Could not link docker contexts into the ephemeral config; a non-default docker context may not resolve for this build",{error:d(c)})}}o(K,"linkContextsDir");async function M(e,r,t){const i=a(e,"cli-plugins");try{if(!(await y(i)).isDirectory())return}catch{return}try{await w(i,a(r,"cli-plugins"),"dir")}catch(c){t.warn(l,"Could not link docker cli-plugins into the ephemeral config; `docker buildx` may be unavailable for this build",{error:d(c)})}}o(M,"linkCliPluginsDir");async function Y(e){const{registry:r,username:t,password:i,baseEnv:c,logger:s}=e,f=A(r),u=B(c),m=L(c,u),k=await J(u,s),{credsStore:O,credHelpers:D,auths:x,...E}=k,p={...D??{}};delete p[f];const b=Buffer.from(`${t}:${i}`,"utf8").toString("base64"),R={...x??{},[f]:{auth:b}},v={...E,auths:R,...Object.keys(p).length>0?{credHelpers:p}:{}};let h;try{const n=await _(a(N(),"fjall-ecr-auth-"));h=n,await H(a(n,"config.json"),JSON.stringify(v),{mode:384}),await K(u,n,s),await M(u,n,s),s.debug(l,"Established ephemeral ECR credential context",{registry:f,dockerConfig:n,buildxConfig:m});let g=!1;return{env:{DOCKER_CONFIG:n,BUILDX_CONFIG:m},async dispose(){g||(g=!0,await C(n,{recursive:!0,force:!0}).catch(S=>{s.warn(l,"Failed to remove ephemeral ECR credential dir",{path:n,error:d(S)})}))}}}catch(n){throw h!==void 0&&await C(h,{recursive:!0,force:!0}).catch(()=>{}),n}}o(Y,"createEcrAuthSession");export{Y as createEcrAuthSession};
@@ -1 +1 @@
1
- import{readFile as n}from"node:fs/promises";import{maskSensitiveOutput as m}from"../securityHelpers.js";import{makeError as a}from"./DockerCli.js";import{failure as i,success as f}from"./result.js";async function S(e){let o;try{o=await n(e,"utf8")}catch(r){if(r?.code==="ENOENT")return i(a("metadata_missing",`Buildx metadata file not found at ${e}`,{path:e}));const s=m(r instanceof Error?r.message:String(r));return i(a("inspect_failed",`Failed to read buildx metadata file at ${e}: ${s}`,{path:e}))}let t;try{t=JSON.parse(o)}catch(r){const d=m(r instanceof Error?r.message:String(r));return i(a("metadata_malformed",`Buildx metadata file at ${e} is not valid JSON: ${d}`,{path:e}))}return t===null||typeof t!="object"||Array.isArray(t)?i(a("metadata_malformed",`Buildx metadata file at ${e} is not a JSON object`,{path:e})):f(t)}export{S as parseMetadataFile};
1
+ var f=Object.defineProperty;var m=(e,a)=>f(e,"name",{value:a,configurable:!0});import{readFile as l}from"node:fs/promises";import{maskSensitiveOutput as s}from"../securityHelpers.js";import{makeError as i}from"./DockerCli.js";import{failure as o,success as c}from"./result.js";async function x(e){let a;try{a=await l(e,"utf8")}catch(r){if(r?.code==="ENOENT")return o(i("metadata_missing",`Buildx metadata file not found at ${e}`,{path:e}));const n=s(r instanceof Error?r.message:String(r));return o(i("inspect_failed",`Failed to read buildx metadata file at ${e}: ${n}`,{path:e}))}let t;try{t=JSON.parse(a)}catch(r){const d=s(r instanceof Error?r.message:String(r));return o(i("metadata_malformed",`Buildx metadata file at ${e} is not valid JSON: ${d}`,{path:e}))}return t===null||typeof t!="object"||Array.isArray(t)?o(i("metadata_malformed",`Buildx metadata file at ${e} is not a JSON object`,{path:e})):c(t)}m(x,"parseMetadataFile");export{x as parseMetadataFile};
@@ -1 +1 @@
1
- import{makeError as n}from"./DockerCli.js";import{failure as g,success as o}from"./result.js";function c(s){const e=s.lastIndexOf(":");return e===-1||s.lastIndexOf("/")>e?s:s.slice(e+1)}function l(s){const{result:e,primaryTag:t,services:a}=s;if(e.imageDigests[t]===void 0)return g(n("metadata_missing_digest",`Buildx result has no digest for primary tag ${t}`,{primaryTag:t,availableTags:Object.keys(e.imageDigests)}));const r=[];if(a!==void 0)for(const i of a){if(e.imageDigests[i.tag]===void 0)return g(n("metadata_missing_digest",`Buildx result has no digest for service ${i.name} tag ${i.tag}`,{service:i.name,tag:i.tag,availableTags:Object.keys(e.imageDigests)}));r.push({name:i.name,imageUri:i.tag})}return o({imageUri:t,imageTag:c(t),...r.length>0&&{services:r}})}export{l as projectBuildxResult};
1
+ var c=Object.defineProperty;var a=(s,e)=>c(s,"name",{value:e,configurable:!0});import{makeError as g}from"./DockerCli.js";import{failure as o,success as m}from"./result.js";function d(s){const e=s.lastIndexOf(":");return e===-1||s.lastIndexOf("/")>e?s:s.slice(e+1)}a(d,"extractTagSuffix");function v(s){const{result:e,primaryTag:t,services:n}=s;if(e.imageDigests[t]===void 0)return o(g("metadata_missing_digest",`Buildx result has no digest for primary tag ${t}`,{primaryTag:t,availableTags:Object.keys(e.imageDigests)}));const r=[];if(n!==void 0)for(const i of n){if(e.imageDigests[i.tag]===void 0)return o(g("metadata_missing_digest",`Buildx result has no digest for service ${i.name} tag ${i.tag}`,{service:i.name,tag:i.tag,availableTags:Object.keys(e.imageDigests)}));r.push({name:i.name,imageUri:i.tag})}return m({imageUri:t,imageTag:d(t),...r.length>0&&{services:r}})}a(v,"projectBuildxResult");export{v as projectBuildxResult};
@@ -1 +1 @@
1
- const o=new Set(["vertexes","statuses","logs","warnings"]);function l(a){const e=a.trim();if(e==="")return null;let s;try{s=JSON.parse(e)}catch{return null}if(s===null||typeof s!="object"||Array.isArray(s))return null;const r=s,t={};for(const[n,i]of Object.entries(r))o.has(n)||(t[n]=i);return{...Array.isArray(r.vertexes)&&{vertexes:r.vertexes},...Array.isArray(r.statuses)&&{statuses:r.statuses},...Array.isArray(r.logs)&&{logs:r.logs},...Array.isArray(r.warnings)&&{warnings:r.warnings},extra:t}}export{l as parseRawjsonLine};
1
+ var l=Object.defineProperty;var i=(t,e)=>l(t,"name",{value:e,configurable:!0});const u=new Set(["vertexes","statuses","logs","warnings"]);function c(t){const e=t.trim();if(e==="")return null;let s;try{s=JSON.parse(e)}catch{return null}if(s===null||typeof s!="object"||Array.isArray(s))return null;const r=s,n={};for(const[a,o]of Object.entries(r))u.has(a)||(n[a]=o);return{...Array.isArray(r.vertexes)&&{vertexes:r.vertexes},...Array.isArray(r.statuses)&&{statuses:r.statuses},...Array.isArray(r.logs)&&{logs:r.logs},...Array.isArray(r.warnings)&&{warnings:r.warnings},extra:n}}i(c,"parseRawjsonLine");export{c as parseRawjsonLine};
@@ -1 +1 @@
1
- function u(t){return typeof t.digest!="string"||t.digest===""||typeof t.name!="string"||t.name===""?null:{digest:t.digest,name:t.name,...typeof t.started=="string"&&{started:t.started},...typeof t.completed=="string"&&{completed:t.completed},...typeof t.cached=="boolean"&&{cached:t.cached},...typeof t.error=="string"&&{error:t.error},...Array.isArray(t.inputs)&&{inputs:t.inputs}}}function f(t){return typeof t.id!="string"||t.id===""||typeof t.vertex!="string"||t.vertex===""||typeof t.name!="string"||typeof t.current!="number"?null:{id:t.id,vertex:t.vertex,name:t.name,current:t.current,...typeof t.total=="number"&&{total:t.total},...typeof t.started=="string"&&{started:t.started},...typeof t.completed=="string"&&{completed:t.completed}}}function l(t){if(typeof t.vertex!="string"||t.vertex===""||typeof t.data!="string")return null;const n=t.stream===2?"stderr":"stdout";return{vertex:t.vertex,stream:n,data:t.data,...typeof t.timestamp=="string"&&{timestamp:t.timestamp}}}function a(t){return typeof t.vertex!="string"||t.vertex===""||typeof t.short!="string"?null:{vertex:t.vertex,level:typeof t.level=="string"?t.level:"warning",short:t.short}}function c(t){const n=[];for(const r of t.vertexes??[]){const e=u(r);e!==null&&n.push(e)}const o=[];for(const r of t.statuses??[]){const e=f(r);e!==null&&o.push(e)}const s=[];for(const r of t.logs??[]){const e=l(r);e!==null&&s.push(e)}const i=[];for(const r of t.warnings??[]){const e=a(r);e!==null&&i.push(e)}return n.length===0&&o.length===0&&s.length===0&&i.length===0?null:{vertexes:n,statuses:o,logs:s,warnings:i}}export{c as rawjsonToVertexEvent};
1
+ var f=Object.defineProperty;var o=(t,r)=>f(t,"name",{value:r,configurable:!0});function l(t){return typeof t.digest!="string"||t.digest===""||typeof t.name!="string"||t.name===""?null:{digest:t.digest,name:t.name,...typeof t.started=="string"&&{started:t.started},...typeof t.completed=="string"&&{completed:t.completed},...typeof t.cached=="boolean"&&{cached:t.cached},...typeof t.error=="string"&&{error:t.error},...Array.isArray(t.inputs)&&{inputs:t.inputs}}}o(l,"normaliseVertex");function a(t){return typeof t.id!="string"||t.id===""||typeof t.vertex!="string"||t.vertex===""||typeof t.name!="string"||typeof t.current!="number"?null:{id:t.id,vertex:t.vertex,name:t.name,current:t.current,...typeof t.total=="number"&&{total:t.total},...typeof t.started=="string"&&{started:t.started},...typeof t.completed=="string"&&{completed:t.completed}}}o(a,"normaliseStatus");function c(t){if(typeof t.vertex!="string"||t.vertex===""||typeof t.data!="string")return null;const r=t.stream===2?"stderr":"stdout";return{vertex:t.vertex,stream:r,data:t.data,...typeof t.timestamp=="string"&&{timestamp:t.timestamp}}}o(c,"normaliseLog");function p(t){return typeof t.vertex!="string"||t.vertex===""||typeof t.short!="string"?null:{vertex:t.vertex,level:typeof t.level=="string"?t.level:"warning",short:t.short}}o(p,"normaliseWarning");function d(t){const r=[];for(const n of t.vertexes??[]){const e=l(n);e!==null&&r.push(e)}const s=[];for(const n of t.statuses??[]){const e=a(n);e!==null&&s.push(e)}const i=[];for(const n of t.logs??[]){const e=c(n);e!==null&&i.push(e)}const u=[];for(const n of t.warnings??[]){const e=p(n);e!==null&&u.push(e)}return r.length===0&&s.length===0&&i.length===0&&u.length===0?null:{vertexes:r,statuses:s,logs:i,warnings:u}}o(d,"rawjsonToVertexEvent");export{d as rawjsonToVertexEvent};
@@ -1 +1 @@
1
- function e(s){return s.success===!0}function u(s){return s.success===!1}function c(s){return{success:!0,data:s}}function r(s){return{success:!1,error:s}}export{r as failure,u as isFailure,e as isSuccess,c as success};
1
+ var c=Object.defineProperty;var e=(s,u)=>c(s,"name",{value:u,configurable:!0});function t(s){return s.success===!0}e(t,"isSuccess");function n(s){return s.success===!1}e(n,"isFailure");function i(s){return{success:!0,data:s}}e(i,"success");function o(s){return{success:!1,error:s}}e(o,"failure");export{o as failure,n as isFailure,t as isSuccess,i as success};
@@ -1 +1 @@
1
- import{z as c}from"zod";const n=["production","staging","development","platform","compliance"],T={production:"Production",staging:"Staging",development:"Development",platform:"Platform",compliance:"Compliance"},i=new Set(n);function e(t){return i.has(t)}const o={ROOT:"root",PLATFORM:"platform"},C=[...n,o.ROOT];function s(t){return e(t)?T[t]:t.charAt(0).toUpperCase()+t.slice(1)}const u=["organisation","platform","account"],l=c.enum(u),r={ORGANISATION:"organisation",PLATFORM:"platform",ACCOUNT:"account"},O={[r.ORGANISATION]:!0,[r.PLATFORM]:!0,[r.ACCOUNT]:!0},a=new Set(Object.keys(O));function S(t){return a.has(t)}function p(t){return t===o.ROOT?"organisation":t===o.PLATFORM?"platform":"account"}function R(t){return t==null||t===""||t===o.ROOT?null:e(t)?t:null}function E(t){return t.tier??p(t.environment)}export{r as ACCOUNT_ROLES,n as ACCOUNT_STAGES,C as ACCOUNT_STAGES_WITH_ROOT,T as ACCOUNT_STAGE_LABELS,u as ACCOUNT_TIERS,l as AccountTierSchema,o as STRUCTURAL_ENVIRONMENTS,E as accountTier,p as environmentToTier,s as getEnvironmentLabel,e as isAccountStage,S as isAccountTier,R as stageFromWireEnvironment};
1
+ var i=Object.defineProperty;var o=(t,T)=>i(t,"name",{value:T,configurable:!0});import{z as u}from"zod";const e=["production","staging","development","platform","compliance"],O={production:"Production",staging:"Staging",development:"Development",platform:"Platform",compliance:"Compliance"},a=new Set(e);function c(t){return a.has(t)}o(c,"isAccountStage");const r={ROOT:"root",PLATFORM:"platform"},R=[...e,r.ROOT];function E(t){return c(t)?O[t]:t.charAt(0).toUpperCase()+t.slice(1)}o(E,"getEnvironmentLabel");const p=["organisation","platform","account"],f=u.enum(p),n={ORGANISATION:"organisation",PLATFORM:"platform",ACCOUNT:"account"},A={[n.ORGANISATION]:!0,[n.PLATFORM]:!0,[n.ACCOUNT]:!0},C=new Set(Object.keys(A));function N(t){return C.has(t)}o(N,"isAccountTier");function s(t){return t===r.ROOT?"organisation":t===r.PLATFORM?"platform":"account"}o(s,"environmentToTier");function m(t){return t==null||t===""||t===r.ROOT?null:c(t)?t:null}o(m,"stageFromWireEnvironment");function _(t){return t.tier??s(t.environment)}o(_,"accountTier");export{n as ACCOUNT_ROLES,e as ACCOUNT_STAGES,R as ACCOUNT_STAGES_WITH_ROOT,O as ACCOUNT_STAGE_LABELS,p as ACCOUNT_TIERS,f as AccountTierSchema,r as STRUCTURAL_ENVIRONMENTS,_ as accountTier,s as environmentToTier,E as getEnvironmentLabel,c as isAccountStage,N as isAccountTier,m as stageFromWireEnvironment};
@@ -1 +1 @@
1
- function f(n){return n instanceof Error?n:new Error(String(n))}function o(n){return n instanceof Error?n.message:typeof n=="string"?n:n&&typeof n=="object"&&"message"in n?String(n.message):"An unknown error occurred"}function c(n,t){return!n||typeof n!="object"?!1:"code"in n&&n.code===t}function i(n){if(!(!n||typeof n!="object")&&"code"in n&&typeof n.code=="string")return n.code}function u(n){return n instanceof Error?n.stack:void 0}function s(n){const t=o(n),e=i(n);return e&&e!=="UNKNOWN_ERROR"?`[${e}] ${t}`:t}export{s as formatErrorString,i as getErrorCode,o as getErrorMessage,u as getErrorStack,c as hasErrorCode,f as normaliseError};
1
+ var i=Object.defineProperty;var t=(n,e)=>i(n,"name",{value:e,configurable:!0});function s(n){return n instanceof Error?n:new Error(String(n))}t(s,"normaliseError");function f(n){return n instanceof Error?n.message:typeof n=="string"?n:n&&typeof n=="object"&&"message"in n?String(n.message):"An unknown error occurred"}t(f,"getErrorMessage");function r(n,e){return!n||typeof n!="object"?!1:"code"in n&&n.code===e}t(r,"hasErrorCode");function c(n){if(!(!n||typeof n!="object")&&"code"in n&&typeof n.code=="string")return n.code}t(c,"getErrorCode");function d(n){return n instanceof Error?n.stack:void 0}t(d,"getErrorStack");function a(n){const e=f(n),o=c(n);return o&&o!=="UNKNOWN_ERROR"?`[${o}] ${e}`:e}t(a,"formatErrorString");export{a as formatErrorString,c as getErrorCode,f as getErrorMessage,d as getErrorStack,r as hasErrorCode,s as normaliseError};
package/dist/fsHelpers.js CHANGED
@@ -1 +1 @@
1
- import{access as i,constants as m}from"fs/promises";import{renameSync as s,unlinkSync as f,writeFileSync as p}from"node:fs";import{randomBytes as u}from"node:crypto";async function d(t){try{return await i(t,m.F_OK),!0}catch(r){if(r instanceof Error&&"code"in r&&r.code==="ENOENT")return!1;throw r}}function l(t,r,n={}){const o=`${t}.${u(6).toString("hex")}.tmp`,e=n.mode??420;try{p(o,r,{mode:e}),s(o,t)}catch(c){try{f(o)}catch(a){n.onCleanupError?.(a)}throw c}}export{l as atomicWrite,d as fileExists};
1
+ var m=Object.defineProperty;var n=(t,r)=>m(t,"name",{value:r,configurable:!0});import{access as s,constants as f}from"fs/promises";import{renameSync as p,unlinkSync as u,writeFileSync as y}from"node:fs";import{randomBytes as h}from"node:crypto";async function x(t){try{return await s(t,f.F_OK),!0}catch(r){if(r instanceof Error&&"code"in r&&r.code==="ENOENT")return!1;throw r}}n(x,"fileExists");function S(t,r,e={}){const o=`${t}.${h(6).toString("hex")}.tmp`,c=e.mode??420;try{y(o,r,{mode:c}),p(o,t)}catch(a){try{u(o)}catch(i){e.onCleanupError?.(i)}throw a}}n(S,"atomicWrite");export{S as atomicWrite,x as fileExists};
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { DNS_APEX, getDomainExportNames, type ManagedDomainExports } from "./infra/domainExports.js";
1
+ export { DNS_APEX, getDomainExportNames, isManagedDomainBinding, type ManagedDomainBinding, type ManagedDomainExports } from "./infra/domainExports.js";
2
2
  export { BACKUP_VAULT_NAME } from "./infra/backupVault.js";
3
3
  export { APPROVAL_TOKEN_OUTPUT_PREFIX, TOKEN_STDERR_PREFIX } from "./deploy/approvalTokenOutput.js";
4
4
  export { imageTagParameterName } from "./infra/imageTags.js";