@fjall/deploy-core 3.10.0 → 4.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.
- package/dist/.minified +1 -1
- package/dist/src/aws/organisations/accountGlobals.js +1 -1
- package/dist/src/aws/targetReadiness.js +1 -1
- package/dist/src/aws/targetSetAdvisory.js +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +1 -1
- package/dist/src/orchestration/application/dockerBuildHelper.d.ts +1 -1
- package/dist/src/orchestration/application/dockerBuildHelper.js +1 -1
- package/dist/src/orchestration/dockerInterface.d.ts +10 -6
- package/dist/src/orchestration/domainInterface.d.ts +8 -0
- package/dist/src/orchestration/organisation/cascadeHelpers.d.ts +16 -2
- package/dist/src/orchestration/organisation/cascadeHelpers.js +1 -1
- package/dist/src/services/index.d.ts +2 -2
- package/dist/src/services/index.js +1 -1
- package/dist/src/services/infrastructure/CdkProcessManager.js +3 -3
- package/dist/src/services/infrastructure/CdkService.js +5 -5
- package/dist/src/services/infrastructure/dependencyIntegrityGate.d.ts +51 -0
- package/dist/src/services/infrastructure/dependencyIntegrityGate.js +2 -0
- package/dist/src/services/infrastructure/index.d.ts +1 -0
- package/dist/src/services/infrastructure/index.js +1 -1
- package/package.json +4 -4
- package/dist/src/services/infrastructure/synthDependencies.d.ts +0 -35
- package/dist/src/services/infrastructure/synthDependencies.js +0 -2
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
234 files minified at 2026-07-
|
|
1
|
+
234 files minified at 2026-07-24T06:41:58.672Z
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var a=Object.defineProperty;var t=(o,r)=>a(o,"name",{value:r,configurable:!0});import{GetRoleCommand as c}from"@aws-sdk/client-iam";import{success as i,failure as s}from"@fjall/generator";import{accountTier as l,getErrorMessage as u}from"@fjall/util";import{ACCOUNT_MONITORING_ROLE_NAME as p}from"@fjall/util/aws";import{composeSdkAbortSignal as g}from"./types.js";const n=p;async function E(o,r){try{return await o.send(new c({RoleName:n}),{abortSignal:g(r)}),i(!0)}catch(e){return e instanceof Error&&e.name==="NoSuchEntityException"?i(!1):s(new Error(`Failed to probe account globals (role "${n}"): ${u(e)}`))}}t(E,"describeAccountGlobalsExist");function d(o){return(o??[]).some(r=>l(r)==="organisation")}t(d,"hasOrganisationTierAccount");function O(o){const e=d(o.providerAccounts)?`run \`fjall deploy
|
|
1
|
+
var a=Object.defineProperty;var t=(o,r)=>a(o,"name",{value:r,configurable:!0});import{GetRoleCommand as c}from"@aws-sdk/client-iam";import{success as i,failure as s}from"@fjall/generator";import{accountTier as l,getErrorMessage as u}from"@fjall/util";import{ACCOUNT_MONITORING_ROLE_NAME as p}from"@fjall/util/aws";import{composeSdkAbortSignal as g}from"./types.js";const n=p;async function E(o,r){try{return await o.send(new c({RoleName:n}),{abortSignal:g(r)}),i(!0)}catch(e){return e instanceof Error&&e.name==="NoSuchEntityException"?i(!1):s(new Error(`Failed to probe account globals (role "${n}"): ${u(e)}`))}}t(E,"describeAccountGlobalsExist");function d(o){return(o??[]).some(r=>l(r)==="organisation")}t(d,"hasOrganisationTierAccount");function O(o){const e=d(o.providerAccounts)?`run \`fjall org deploy\` to provision the primary region (${o.primaryRegion}), then retry this deploy`:`target the primary region (${o.primaryRegion}) and run \`fjall account deploy\`, then retry this deploy`;return`Cannot deploy "${o.target}" into ${o.deployRegion}: the account globals (fixed-name IAM resources such as the ${n} role) are created only in the primary region (${o.primaryRegion}) and were not found in this account. Nothing has been deployed. Deploy the primary region first: ${e}.`}t(O,"buildMissingAccountGlobalsAdvisory");export{n as ACCOUNT_GLOBALS_ROLE_NAME,O as buildMissingAccountGlobalsAdvisory,E as describeAccountGlobalsExist,d as hasOrganisationTierAccount};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var _=Object.defineProperty;var s=(e,t)=>_(e,"name",{value:t,configurable:!0});import{DescribeStacksCommand as P}from"@aws-sdk/client-cloudformation";import{DescribeIpamPoolsCommand as R}from"@aws-sdk/client-ec2";import{success as c,failure as d}from"@fjall/generator";import{accountTier as E,generateTargetName as k,getErrorMessage as T}from"@fjall/util";import{formatIpamPairTagValue as w,IPAM_OPERATIONS_POOL_TAG_KEY as $,STACK_NOT_FOUND_PATTERN as L}from"@fjall/util/aws";import{getOrganisationStackName as I,ORGANISATION_TYPES as S}from"../types/operations.js";import{hasOrganisationTierAccount as h}from"./organisations/accountGlobals.js";import{composeSdkAbortSignal as N,isAborted as C}from"./organisations/types.js";const g=I(S.ACCOUNT),b=I(S.PLATFORM),v=new Set(["CREATE_FAILED","ROLLBACK_IN_PROGRESS","ROLLBACK_COMPLETE","ROLLBACK_FAILED","REVIEW_IN_PROGRESS","DELETE_IN_PROGRESS","DELETE_FAILED"]);function x(e){switch(e.kind){case"missing-account-stack":return`the ${e.stackName} stack was not found in ${e.region}`;case"missing-ipam-pool":return`no IPAM pool exists for account ${e.accountId} in ${e.region}`}}s(x,"describeTargetReadinessReason");function M(e){const t=e.accountName??e.accountId,n=e.reasons.map(x).join(" and "),o=e.accountName!==void 0?`run \`fjall target set ${k(e.accountName,e.region)}\` then \`fjall deploy
|
|
1
|
+
var _=Object.defineProperty;var s=(e,t)=>_(e,"name",{value:t,configurable:!0});import{DescribeStacksCommand as P}from"@aws-sdk/client-cloudformation";import{DescribeIpamPoolsCommand as R}from"@aws-sdk/client-ec2";import{success as c,failure as d}from"@fjall/generator";import{accountTier as E,generateTargetName as k,getErrorMessage as T}from"@fjall/util";import{formatIpamPairTagValue as w,IPAM_OPERATIONS_POOL_TAG_KEY as $,STACK_NOT_FOUND_PATTERN as L}from"@fjall/util/aws";import{getOrganisationStackName as I,ORGANISATION_TYPES as S}from"../types/operations.js";import{hasOrganisationTierAccount as h}from"./organisations/accountGlobals.js";import{composeSdkAbortSignal as N,isAborted as C}from"./organisations/types.js";const g=I(S.ACCOUNT),b=I(S.PLATFORM),v=new Set(["CREATE_FAILED","ROLLBACK_IN_PROGRESS","ROLLBACK_COMPLETE","ROLLBACK_FAILED","REVIEW_IN_PROGRESS","DELETE_IN_PROGRESS","DELETE_FAILED"]);function x(e){switch(e.kind){case"missing-account-stack":return`the ${e.stackName} stack was not found in ${e.region}`;case"missing-ipam-pool":return`no IPAM pool exists for account ${e.accountId} in ${e.region}`}}s(x,"describeTargetReadinessReason");function M(e){const t=e.accountName??e.accountId,n=e.reasons.map(x).join(" and "),o=e.accountName!==void 0?`run \`fjall target set ${k(e.accountName,e.region)}\` then \`fjall account deploy\`, then retry this deploy`:"run `fjall target list` to find the target name, `fjall target set <target>`, then `fjall account deploy`, then retry this deploy",a=h(e.providerAccounts)?"run `fjall org deploy` (the cascade provisions every account and creates the IPAM pool), then retry this deploy":o;return`Target "${t}" is not ready in ${e.region}: ${n}. Nothing has been deployed. Provision the target first: ${a}.`}s(M,"buildTargetUnreadyAdvisory");function F(e){return e instanceof Error&&e.name==="ValidationError"&&e.message.includes(L)}s(F,"isStackNotFoundError");async function D(e,t,n,o=g){try{const r=(await e.send(new P({StackName:o}),{abortSignal:N(n)})).Stacks?.[0]?.StackStatus;return c(r!==void 0&&!v.has(r))}catch(a){return F(a)?c(!1):d(new Error(`Failed to probe the ${o} stack in ${t}: ${T(a)}`))}}s(D,"probeAccountStackExists");function K(e,t,n,o){return e.Locale!==n?!1:o.side==="owner"?(e.Tags??[]).some(a=>a.Key===$&&a.Value===o.pairTagValue):e.OwnerId===t?!1:o.platformAccountId===void 0||e.OwnerId===o.platformAccountId}s(K,"matchesIpamPair");async function j(e,t,n,o,a){try{let r;do{if(C(a))return d(new Error(`Aborted: IPAM pool probe for account ${t} in ${n} cancelled by shutdown signal`));const i=await e.send(new R({...r!==void 0&&{NextToken:r}}),{abortSignal:N(a)});if((i.IpamPools??[]).some(u=>K(u,t,n,o)))return c(!0);r=i.NextToken}while(r!==void 0);return c(!1)}catch(r){return d(new Error(`Failed to probe IPAM pools for account ${t} in ${n}: ${T(r)}`))}}s(j,"probeIpamPoolExists");async function J(e,t,n,o,a){const r=[],i=o?.providerAccounts,l=(i??[]).find(f=>f.id===t.id),u=l!==void 0&&E(l)==="platform",A=u?b:g,m=await D(e.cloudFormation,n,a,A);if(!m.success)return d(m.error);if(m.data||r.push({kind:"missing-account-stack",stackName:A,region:n}),h(i)){const f=(i??[]).find(O=>E(O)==="platform")?.id,y=u?{side:"owner",pairTagValue:w(t.id,n)}:{side:"consumer",...f!==void 0&&{platformAccountId:f}},p=await j(e.ec2,t.id,n,y,a);if(!p.success)return d(p.error);p.data||r.push({kind:"missing-ipam-pool",accountId:t.id,region:n})}return r.length===0?c({ready:!0}):c({ready:!1,reasons:r,advisory:M({accountId:t.id,...t.name!==void 0&&{accountName:t.name},region:n,reasons:r,...o!==void 0&&{providerAccounts:o.providerAccounts}})})}s(J,"checkTargetReadiness");export{g as ACCOUNT_STACK_NAME,M as buildTargetUnreadyAdvisory,J as checkTargetReadiness,x as describeTargetReadinessReason,D as probeAccountStackExists};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var r=Object.defineProperty;var e=(o,n)=>r(o,"name",{value:n,configurable:!0});import{hasOrganisationTierAccount as
|
|
1
|
+
var r=Object.defineProperty;var e=(o,n)=>r(o,"name",{value:n,configurable:!0});import{hasOrganisationTierAccount as c}from"./organisations/accountGlobals.js";import{describeTargetReadinessReason as a}from"./targetReadiness.js";function l(o){const n=o.accountName??o.accountId,t=o.reasons.map(a).join(" and "),i=c(o.providerAccounts)?"Run `fjall org deploy` \u2014 the cascade provisions every account and creates the IPAM pool":"Run `fjall account deploy` to provision it";return`Target "${n}" is not ready in ${o.region}: ${t}. ${i}.`}e(l,"buildTargetSetUnreadyAdvisory");export{l as buildTargetSetUnreadyAdvisory};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -38,8 +38,8 @@ export { FjallStateFileSchema, readStateFile, writeStateFile, createEmptyState,
|
|
|
38
38
|
export { readDomainState, writeDomainState, recordDomainDeployState, deleteDomainState, hashDomainDirectory, LEGACY_DOMAIN_STATE_FILENAME, type DomainDeployState } from "./types/config/DomainState.js";
|
|
39
39
|
export { CloudFormationEventMonitor } from "./aws/index.js";
|
|
40
40
|
export type { AwsClientLike, EventLogWriter, EventFailureAnalyser, EventLogWriterFactory, EventMonitorDeps } from "./aws/index.js";
|
|
41
|
-
export { CdkService, CdkArgumentBuilder, CdkProcessManager, CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS, isCdkError, formatInfrastructureError, getStructuralHint, getSourceContext, hasCdkDifferences, parseDiffOutput, CloudFormationService, CloudFormationError, EcsService, EcsError, EcsServiceResolver, type CfnExportsClient, TemplateHashService, TemplateHashError, type TemplateComparisonResult, CdkContextBuilder, emitProgress, PROGRESS_MESSAGES, parseBuildPhase, buildStepContextBuildConfig, convertCloudFormationOutputsToRecord, type CloudFormationOutput, ApplicationStackService } from "./services/index.js";
|
|
42
|
-
export type { CdkContext, CdkOptions, CdkOutput, CheckDifferencesResult, CdkServiceOptions, ICdkProcessManager, DiffDetails, CloudFormationCallbacks, ECSServiceInfo, ECSClusterInfo, DeploymentStatus, ECSDeploymentOptions } from "./services/index.js";
|
|
41
|
+
export { CdkService, CdkArgumentBuilder, CdkProcessManager, ensureDependencyIntegrity, clearDependencyIntegrityCache, DEPENDENCY_SYNC_TIMEOUT_MS, CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS, isCdkError, formatInfrastructureError, getStructuralHint, getSourceContext, hasCdkDifferences, parseDiffOutput, CloudFormationService, CloudFormationError, EcsService, EcsError, EcsServiceResolver, type CfnExportsClient, TemplateHashService, TemplateHashError, type TemplateComparisonResult, CdkContextBuilder, emitProgress, PROGRESS_MESSAGES, parseBuildPhase, buildStepContextBuildConfig, convertCloudFormationOutputsToRecord, type CloudFormationOutput, ApplicationStackService } from "./services/index.js";
|
|
42
|
+
export type { CdkContext, CdkOptions, CdkOutput, CheckDifferencesResult, CdkServiceOptions, ICdkProcessManager, DependencyIntegrityOutcome, DependencyIntegrityStatus, EnsureDependencyIntegrityOptions, DiffDetails, CloudFormationCallbacks, ECSServiceInfo, ECSClusterInfo, DeploymentStatus, ECSDeploymentOptions } from "./services/index.js";
|
|
43
43
|
export { CdkError } from "./types/errors/index.js";
|
|
44
44
|
export { type ServiceErrorDetails, type ServiceError, BaseServiceError, ValidationError, AuthError, AwsError, DeploymentError, NetworkError, FileSystemError, ConfigError, toServiceError } from "./types/errors/index.js";
|
|
45
45
|
export { filterDangerousEnvVars, maskSensitiveOutput, parseShellArgs, sleep } from "@fjall/util";
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DeploymentEventSchema as t,DEPLOYMENT_EVENT_TYPES as o,DEPLOYMENT_EVENT_RESOURCE_CATEGORIES as i,DEPLOYMENT_EVENT_STATUS_REASON_MAX as a,DEPLOYMENT_EVENT_ERROR_MESSAGE_MAX as n,DEPLOYMENT_EVENT_TRAIL_DETAIL_MAX as s,DEPLOYMENT_ERROR_MESSAGE_MAX as E,CASCADE_PHASES as c,CASCADE_ACCOUNT_STATUSES as S,clampDeploymentEventStrings as l,truncateUtf16Safe as A}from"./types/index.js";import{DeployEventSchema as T,StepProgressSchema as _,DeployResourceSchema as p,PlanChangeSchema as m,PlanPropertyChangeSchema as d,ChangeCountsSchema as u,DEPLOY_EVENT_CONTRACT as D,DEPLOY_EVENT_CONTRACT_MAJOR as P,DEPLOY_EVENT_CONTRACT_MINOR as O,SUPPORTED_CONTRACT_MARKERS as f,DEPLOY_EVENT_ID_MAX as C,DEPLOY_EVENT_NAME_MAX as N,DEPLOY_EVENT_MESSAGE_MAX as g,DEPLOY_EVENT_STATUS_REASON_MAX as L,DEPLOY_EVENT_ERROR_MESSAGE_MAX as I,DEPLOY_EVENT_TRAIL_DETAIL_MAX as y,DEPLOY_EVENT_OUTPUT_MAX as h,DEPLOY_EVENT_ARN_MAX as M,DEPLOY_EVENT_URL_MAX as v,STEP_COMPLETE_STATUSES as x,LOG_LEVELS as F,STACK_CLEANUP_PHASES as U,CASCADE_ACCOUNT_PHASES as k,DEPLOY_RESULTS as b,DETECTION_PHASES as Y,PHASE_STATUSES as V,BUILDERS as G,CASCADE_OUTCOME_RESULTS as B,PLAN_ACTIONS as K,REPLACEMENT_MODES as X,APPROVAL_KINDS as H,APPROVAL_DECISIONS as w,ALL_PROGRESS_KINDS as J,createDeployEmitter as Q,parseDeployEvent as j,parseDeployContractVersion as W}from"./types/index.js";import{SimpleAwsProvider as q}from"./aws/index.js";import{checkTargetReadiness as $,describeTargetReadinessReason as ee,buildTargetUnreadyAdvisory as re,buildTargetSetUnreadyAdvisory as te,probeAccountStackExists as oe}from"./aws/index.js";import{checkRegionEnabled as ae,regionDisabledMessage as ne}from"./aws/index.js";import{ensureOrganisationExists as Ee,describeOrganisation as ce,enablePolicyTypes as Se,enableServiceAccess as le,SERVICE_PRINCIPALS as Ae,enableRamSharing as Re,activateTrustedAccess as Te,enableIpamDelegatedAdmin as _e,updateBackupGlobalSettings as pe,listAccounts as me,findAccount as de,createAccount as ue,ensureOrganisationalUnitsExist as De,placeAccountsInOUs as Pe,buildAccountToOUMap as Oe,findDevelopmentOuId as fe,activateCostAllocationTags as Ce,checkIdentityCentreStatus as Ne,snapshotIdentityCentre as ge,composeSdkAbortSignal as Le,extractErrorName as Ie,isAborted as ye,DEFAULT_MAX_PAGES as he,IDENTITY_STORE_PAGE_SIZE as Me,drainPages as ve,isOULeaf as xe,registerSecurityDelegates as Fe,SECURITY_SERVICE_PRINCIPALS as Ue,enableCentralisedRootAccess as ke,ROOT_ACCESS_FEATURES as be,RootAccessEnablementError as Ye}from"./aws/index.js";import{STEP_IDS as Ge,STEP_NAMES as Be,INFRASTRUCTURE_STEP_NAMES as Ke,INFRA_STEP_NAME as Xe}from"./types/index.js";import{RemediationVerbSchema as we,REMEDIATION_VERB_GLOSS as Je,DestructionFindingSchema as Qe,DestructionTicketResourceSchema as je,DestructionTicketSchema as We,DestructionConsentSchema as Ze,DestructionOutcomeSchema as qe,DESTRUCTION_FINDINGS as ze,CONSENT_VERDICTS as $e,TICKET_VERDICT_SOURCES as er,TicketVerdictSourceSchema as rr}from"./types/index.js";import{DRIFT_VERDICTS as or,DriftVerdictSchema as ir,DriftSuspectSchema as ar,DriftFindingSchema as nr,DriftJournalRecordSchema as sr,verbsForDriftVerdict as Er}from"./types/index.js";import{REMEDIATION_PHASES as Sr,RemediationPhaseSchema as lr,RemediationTargetSchema as Ar,RemediationFlipProofSchema as Rr,RemediationJournalRecordSchema as Tr,RemediationVerbWithSurgerySchema as _r,remediationPhaseRank as pr,remediationPlaceholderPhysicalId as mr,isRemediationPlaceholderPhysicalId as dr}from"./types/index.js";import{ProgressReporter as Dr,APPLICATION_STACKS as Pr,ORGANISATION_TYPES as Or,APPLICATION_DEPLOY_ORDER as fr,APPLICATION_DESTROY_ORDER as Cr,OPENNEXT_DEPLOY_ORDER as Nr,OPENNEXT_DESTROY_ORDER as gr,PARALLEL_DEPLOY_GROUPS as Lr,PARALLEL_DESTROY_GROUPS as Ir,OPENNEXT_PARALLEL_GROUPS as yr,PARALLEL_OPERATION_TYPES as hr,isApplicationOperation as Mr,isOrganisationOperation as vr,getParallelDeployGroups as xr,getParallelDestroyGroups as Fr,getApplicationDeployOrder as Ur,getApplicationDestroyOrder as kr,getApplicationStackName as br,getOrganisationStackName as Yr,isApplicationStack as Vr,isQuarantineDetail as Gr,isRetainedBucketsDetail as Br,getApplicationStepName as Kr,getApplicationStepId as Xr,toPascalCase as Hr,isOpenNextPattern as wr,OPENNEXT_PATTERNS as Jr,STACK_NOT_FOUND_PATTERN as Qr,STACK_FAILED_STATE_PATTERN as jr,CDK_NO_STACKS_MATCH as Wr,INFRASTRUCTURE_FILENAME as Zr,ApplicationError as qr,wrapApplicationError as zr,stubCallerIdentity as $r}from"./types/index.js";import{deriveResourcesFromManifestStacks as rt}from"./types/detection/patternDetection.js";import{FjallStateFileSchema as ot,readStateFile as it,writeStateFile as at,createEmptyState as nt,deleteStateFile as st,updateTemplateHash as Et,getStateFilePath as ct,regionSuffix as St}from"./types/config/FjallState.js";import{readDomainState as At,writeDomainState as Rt,recordDomainDeployState as Tt,deleteDomainState as _t,hashDomainDirectory as pt,LEGACY_DOMAIN_STATE_FILENAME as mt}from"./types/config/DomainState.js";import{CloudFormationEventMonitor as ut}from"./aws/index.js";import{CdkService as Pt,CdkArgumentBuilder as Ot,CdkProcessManager as ft,CdkEventMonitor as Ct,startStackMonitoring as Nt,DEFAULT_DEPLOY_TIMEOUT_MS as gt,isCdkError as Lt,formatInfrastructureError as It,getStructuralHint as yt,getSourceContext as ht,hasCdkDifferences as Mt,parseDiffOutput as vt,CloudFormationService as xt,CloudFormationError as Ft,EcsService as Ut,EcsError as kt,EcsServiceResolver as bt,TemplateHashService as Yt,TemplateHashError as Vt,CdkContextBuilder as Gt,emitProgress as Bt,PROGRESS_MESSAGES as Kt,parseBuildPhase as Xt,buildStepContextBuildConfig as Ht,convertCloudFormationOutputsToRecord as wt,ApplicationStackService as Jt}from"./services/index.js";import{CdkError as jt}from"./types/errors/index.js";import{BaseServiceError as Zt,ValidationError as qt,AuthError as zt,AwsError as $t,DeploymentError as eo,NetworkError as ro,FileSystemError as to,ConfigError as oo,toServiceError as io}from"./types/errors/index.js";import{filterDangerousEnvVars as no,maskSensitiveOutput as so,parseShellArgs as Eo,sleep as co}from"@fjall/util";import{artefactOutputKey as lo,DeployModeSchema as Ao,ServiceArtefactSchema as Ro,ServiceArtefactsSchema as To}from"@fjall/util";import{hasDockerfile as po}from"./util/dockerfileDetection.js";import{sleepAbortable as uo}from"./util/sleepAbortable.js";import{createSequencedCallbacks as Po}from"./util/sequencedCallbacks.js";import{fileExists as fo}from"@fjall/util/fsHelpers";import{success as No,failure as go,isSuccess as Lo,isFailure as Io}from"@fjall/generator";import{deploy as ho}from"./orchestration/index.js";import{destroy as vo}from"./orchestration/index.js";import{restart as Fo,probeSecretsDrift as Uo,computeSecretsDrift as ko,deriveStaleParameters as bo,extractConsumedSsmParameters as Yo}from"./orchestration/index.js";import{partitionAccounts as Go}from"./orchestration/index.js";import{buildRegionList as Ko,buildAccountRegionPairs as Xo,cascadeHomeRegion as Ho,cascadeOperationKey as wo}from"./orchestration/index.js";import{projectScalarSummary as Qo,projectAccountRows as jo}from"./orchestration/index.js";import{reconcileProviderAccounts as Zo,mergeReconciledProviderAccounts as qo}from"./orchestration/index.js";import{decideNextTransition as $o,reconcileTrailMigration as ei,decommissionMemberTrailStorage as ri,ORG_TRAIL_BUCKET_OUTPUT_KEY as ti,TRAIL_BUCKET_OUTPUT_KEY as oi,TRAIL_KEY_ARN_OUTPUT_KEY as ii}from"./orchestration/index.js";import{classifyDriftFailure as ni,fetchLastOperationEvents as si,DriftProbe as Ei,clearDriftSuspects as ci,defaultDriftJournalDir as Si,readDriftSuspects as li,recordDriftSuspects as Ai,detectStackDrift as Ri,runDriftPreFlight as Ti,formatDriftPreFlightBlock as _i,DRIFT_PREFLIGHT_TRIGGER_STATUSES as pi,DRIFT_PREFLIGHT_BUDGET_MS as mi,runRoute53RecordPreflight as di}from"./orchestration/index.js";import{archiveCompletedRemediationJournal as Di,computeRemediationOpId as Pi,defaultRemediationJournalDir as Oi,findRemediationJournalByOpId as fi,listActiveRemediationOps as Ci,listActiveRemediationOpsForContext as Ni,readRemediationJournal as gi,sweepExpiredRemediationJournals as Li,writeRemediationJournal as Ii,REMEDIATION_JOURNAL_RETENTION_DAYS as yi,captureRemediationForensics as hi,defaultRemediationForensicsDir as Mi,applyRetainFlip as vi,composeFlipCapabilities as xi,computeTemplateDigest as Fi,deriveRetainFlipTemplate as Ui,findMarkedResourcesByOpId as ki,proveFlipMetadataOnly as bi,readRetainFlipState as Yi,verifyRetainFlipDiff as Vi,FORGET_MARKER_KEY as Gi,FORGET_FLIP_SPEC as Bi,RECREATE_MARKER_KEY as Ki,assessForgetResumability as Xi,completeForgetAfterConverge as Hi,completeForgetAfterDeploy as wi,formatRecreateInFlightCures as Ji,partitionPreFlightByRemediation as Qi,runForgetSurgery as ji,synthTemplateDeclaresResource as Wi,runRecreateSurgery as Zi,snapshotPolicyForType as qi,SNAPSHOT_CAPABLE_RESOURCE_TYPES as zi,runRecreatePreFlight as $i,deriveRemovalTemplate as ea,findRemovalDeletionFailures as ra,findResourcesPresent as ta,proveRemovalTargetsOnly as oa,advertisableDriftVerbs as ia,buildDriftRepairTicket as aa,runDriftRepairGate as na,formatPinOutcomeDetail as sa,pinProbeCoverage as Ea,renderPinReportLines as ca,runPinRemediation as Sa,composePostFailureRepairOffer as la,formatDriftRepairOffer as Aa,DriftRepairAvailableError as Ra,checkDeployPathStackAvailability as Ta,isDeployPathBlockingStatus as _a,StackUnavailableError as pa,assertLeaseBeforeStack as ma,LeaseDeniedError as da}from"./orchestration/index.js";import{unlockBucket as Da,unlockQueue as Pa}from"./orchestration/index.js";import{triageBucketPolicy as fa,isEnforceSslStatement as Ca,toResourcePolicyStatements as Na,restoreBucketPolicy as ga,synthesiseEnforceSslDocument as La,ensureEnforceSsl as Ia,restoreAndReconcileQuarantinedBucket as ya}from"./orchestration/index.js";import{verifyOrgTrailDelivery as Ma}from"./aws/cloudtrail/orgTrailDelivery.js";import{assumeRootForTask as xa,isRootTaskPolicyArn as Fa,ROOT_TASK_POLICY_ARNS as Ua,MAX_ROOT_SESSION_SECONDS as ka}from"./aws/sts/assumeRoot.js";import{parseAccountsConfiguration as Ya,flattenAccountsToEnvironments as Va,extractAllAccountNames as Ga,accountsConfigToOUTree as Ba,isStringArray as Ka,isAccountsConfig as Xa,isOuOnlyAccountBucket as Ha,OU_ONLY_ACCOUNT_BUCKETS as wa}from"./orchestration/index.js";import{runOpenNextBuild as Qa}from"./orchestration/index.js";import{runOrganisationSetup as Wa,ORG_SETUP_PHASES as Za}from"./orchestration/index.js";import{DOMAIN_DELEGATION_ERROR_TYPES as za,DomainDelegationError as $a,DEFAULT_PUBLIC_RESOLVER_ADDRESSES as en,PUBLIC_DNS_QUERY_TIMEOUT_MS as rn,createPublicResolvers as tn,NS_PROPAGATION_DEFAULT_MAX_ATTEMPTS as on,NS_PROPAGATION_DEFAULT_INTERVAL_MS as an,waitForNsPropagation as nn,ACM_CAA_ISSUERS as sn,runCaaPreflight as En,deployDelegatedDomain as cn,CROSS_ACCOUNT_DELEGATION_RESOURCE_TYPE as Sn,templateOwnsDelegationRecord as ln,deleteChildNsFromParent as An,nsDelegationPhysicalName as Rn,runDelegatedDomainDestroy as Tn}from"./orchestration/index.js";import{classifyZoneRecords as pn,buildSatelliteRecordIndex as mn,createSystemDnsNameProbe as dn,systemDnsNameProbe as un,normaliseRecordName as Dn,isRoute53NameServer as Pn,isDelegatedToRoute53 as On}from"./orchestration/index.js";import{resolveBuildSecrets as Cn,resolveSecretRefValue as Nn,resolveBuildSecretSessionProvider as gn,sourcedRefsFromBuildArgs as Ln,resolveBuildArgs as In,buildBuildSecretSessionPolicy as yn,buildDeploySessionPolicy as hn,partitionForRegion as Mn,validateBuildGroup as vn}from"./orchestration/index.js";import{FrameworkRegistry as Fn}from"./orchestration/index.js";import{openNextBuilder as kn,staticSiteBuilder as bn,dockerBuilder as Yn}from"./orchestration/index.js";import{StepRegistry as Gn,getDestroyStepId as Bn}from"./steps/index.js";import{buildDeployPlan as Xn,computeDeployPlan as Hn,computeAssemblyDigest as wn,digestHead as Jn,classifyImpact as Qn,derivePropertyChanges as jn,isDataLoss as Wn,isStatefulResourceType as Zn,renderPlanSummary as qn,renderPlanLines as zn,toWirePlanChanges as $n,signApprovalToken as es,verifyApprovalToken as rs,DEFAULT_APPROVAL_TTL_MS as ts,APPROVAL_TOKEN_PATTERN as os,runApprovalGate as is,approvalRefusalReason as as}from"./orchestration/index.js";import{runDestructionGate as ss,buildDestructionTicket as Es,evaluateDestructionConsents as cs,computeTicketDigest as Ss,legalRemediationVerbs as ls,executableRemediationVerbs as As,advertisableRemediationVerbs as Rs,renderDestructionTicketLines as Ts,renderConsentVerdictLines as _s,loadDeployPlan as ps,createMemoisedPlanLoader as ms}from"./orchestration/index.js";export{sn as ACM_CAA_ISSUERS,J as ALL_PROGRESS_KINDS,fr as APPLICATION_DEPLOY_ORDER,Cr as APPLICATION_DESTROY_ORDER,Pr as APPLICATION_STACKS,w as APPROVAL_DECISIONS,H as APPROVAL_KINDS,os as APPROVAL_TOKEN_PATTERN,qr as ApplicationError,Jt as ApplicationStackService,zt as AuthError,$t as AwsError,G as BUILDERS,Zt as BaseServiceError,k as CASCADE_ACCOUNT_PHASES,S as CASCADE_ACCOUNT_STATUSES,B as CASCADE_OUTCOME_RESULTS,c as CASCADE_PHASES,Wr as CDK_NO_STACKS_MATCH,$e as CONSENT_VERDICTS,Sn as CROSS_ACCOUNT_DELEGATION_RESOURCE_TYPE,Ot as CdkArgumentBuilder,Gt as CdkContextBuilder,jt as CdkError,Ct as CdkEventMonitor,ft as CdkProcessManager,Pt as CdkService,u as ChangeCountsSchema,Ft as CloudFormationError,ut as CloudFormationEventMonitor,xt as CloudFormationService,oo as ConfigError,ts as DEFAULT_APPROVAL_TTL_MS,gt as DEFAULT_DEPLOY_TIMEOUT_MS,he as DEFAULT_MAX_PAGES,en as DEFAULT_PUBLIC_RESOLVER_ADDRESSES,E as DEPLOYMENT_ERROR_MESSAGE_MAX,n as DEPLOYMENT_EVENT_ERROR_MESSAGE_MAX,i as DEPLOYMENT_EVENT_RESOURCE_CATEGORIES,a as DEPLOYMENT_EVENT_STATUS_REASON_MAX,s as DEPLOYMENT_EVENT_TRAIL_DETAIL_MAX,o as DEPLOYMENT_EVENT_TYPES,M as DEPLOY_EVENT_ARN_MAX,D as DEPLOY_EVENT_CONTRACT,P as DEPLOY_EVENT_CONTRACT_MAJOR,O as DEPLOY_EVENT_CONTRACT_MINOR,I as DEPLOY_EVENT_ERROR_MESSAGE_MAX,C as DEPLOY_EVENT_ID_MAX,g as DEPLOY_EVENT_MESSAGE_MAX,N as DEPLOY_EVENT_NAME_MAX,h as DEPLOY_EVENT_OUTPUT_MAX,L as DEPLOY_EVENT_STATUS_REASON_MAX,y as DEPLOY_EVENT_TRAIL_DETAIL_MAX,v as DEPLOY_EVENT_URL_MAX,b as DEPLOY_RESULTS,ze as DESTRUCTION_FINDINGS,Y as DETECTION_PHASES,za as DOMAIN_DELEGATION_ERROR_TYPES,mi as DRIFT_PREFLIGHT_BUDGET_MS,pi as DRIFT_PREFLIGHT_TRIGGER_STATUSES,or as DRIFT_VERDICTS,T as DeployEventSchema,Ao as DeployModeSchema,p as DeployResourceSchema,eo as DeploymentError,t as DeploymentEventSchema,Ze as DestructionConsentSchema,Qe as DestructionFindingSchema,qe as DestructionOutcomeSchema,je as DestructionTicketResourceSchema,We as DestructionTicketSchema,$a as DomainDelegationError,nr as DriftFindingSchema,sr as DriftJournalRecordSchema,Ei as DriftProbe,Ra as DriftRepairAvailableError,ar as DriftSuspectSchema,ir as DriftVerdictSchema,kt as EcsError,Ut as EcsService,bt as EcsServiceResolver,Bi as FORGET_FLIP_SPEC,Gi as FORGET_MARKER_KEY,to as FileSystemError,ot as FjallStateFileSchema,Fn as FrameworkRegistry,Me as IDENTITY_STORE_PAGE_SIZE,Zr as INFRASTRUCTURE_FILENAME,Ke as INFRASTRUCTURE_STEP_NAMES,Xe as INFRA_STEP_NAME,mt as LEGACY_DOMAIN_STATE_FILENAME,F as LOG_LEVELS,da as LeaseDeniedError,ka as MAX_ROOT_SESSION_SECONDS,an as NS_PROPAGATION_DEFAULT_INTERVAL_MS,on as NS_PROPAGATION_DEFAULT_MAX_ATTEMPTS,ro as NetworkError,Nr as OPENNEXT_DEPLOY_ORDER,gr as OPENNEXT_DESTROY_ORDER,yr as OPENNEXT_PARALLEL_GROUPS,Jr as OPENNEXT_PATTERNS,Or as ORGANISATION_TYPES,Za as ORG_SETUP_PHASES,ti as ORG_TRAIL_BUCKET_OUTPUT_KEY,wa as OU_ONLY_ACCOUNT_BUCKETS,Lr as PARALLEL_DEPLOY_GROUPS,Ir as PARALLEL_DESTROY_GROUPS,hr as PARALLEL_OPERATION_TYPES,V as PHASE_STATUSES,K as PLAN_ACTIONS,Kt as PROGRESS_MESSAGES,rn as PUBLIC_DNS_QUERY_TIMEOUT_MS,m as PlanChangeSchema,d as PlanPropertyChangeSchema,Dr as ProgressReporter,Ki as RECREATE_MARKER_KEY,yi as REMEDIATION_JOURNAL_RETENTION_DAYS,Sr as REMEDIATION_PHASES,Je as REMEDIATION_VERB_GLOSS,X as REPLACEMENT_MODES,be as ROOT_ACCESS_FEATURES,Ua as ROOT_TASK_POLICY_ARNS,Rr as RemediationFlipProofSchema,Tr as RemediationJournalRecordSchema,lr as RemediationPhaseSchema,Ar as RemediationTargetSchema,we as RemediationVerbSchema,_r as RemediationVerbWithSurgerySchema,Ye as RootAccessEnablementError,Ue as SECURITY_SERVICE_PRINCIPALS,Ae as SERVICE_PRINCIPALS,zi as SNAPSHOT_CAPABLE_RESOURCE_TYPES,U as STACK_CLEANUP_PHASES,jr as STACK_FAILED_STATE_PATTERN,Qr as STACK_NOT_FOUND_PATTERN,x as STEP_COMPLETE_STATUSES,Ge as STEP_IDS,Be as STEP_NAMES,f as SUPPORTED_CONTRACT_MARKERS,Ro as ServiceArtefactSchema,To as ServiceArtefactsSchema,q as SimpleAwsProvider,pa as StackUnavailableError,_ as StepProgressSchema,Gn as StepRegistry,er as TICKET_VERDICT_SOURCES,oi as TRAIL_BUCKET_OUTPUT_KEY,ii as TRAIL_KEY_ARN_OUTPUT_KEY,Vt as TemplateHashError,Yt as TemplateHashService,rr as TicketVerdictSourceSchema,qt as ValidationError,Ba as accountsConfigToOUTree,Ce as activateCostAllocationTags,Te as activateTrustedAccess,ia as advertisableDriftVerbs,Rs as advertisableRemediationVerbs,vi as applyRetainFlip,as as approvalRefusalReason,Di as archiveCompletedRemediationJournal,lo as artefactOutputKey,ma as assertLeaseBeforeStack,Xi as assessForgetResumability,xa as assumeRootForTask,Xo as buildAccountRegionPairs,Oe as buildAccountToOUMap,yn as buildBuildSecretSessionPolicy,Xn as buildDeployPlan,hn as buildDeploySessionPolicy,Es as buildDestructionTicket,aa as buildDriftRepairTicket,Ko as buildRegionList,mn as buildSatelliteRecordIndex,Ht as buildStepContextBuildConfig,te as buildTargetSetUnreadyAdvisory,re as buildTargetUnreadyAdvisory,hi as captureRemediationForensics,Ho as cascadeHomeRegion,wo as cascadeOperationKey,Ta as checkDeployPathStackAvailability,Ne as checkIdentityCentreStatus,ae as checkRegionEnabled,$ as checkTargetReadiness,l as clampDeploymentEventStrings,ni as classifyDriftFailure,Qn as classifyImpact,pn as classifyZoneRecords,ci as clearDriftSuspects,Hi as completeForgetAfterConverge,wi as completeForgetAfterDeploy,xi as composeFlipCapabilities,la as composePostFailureRepairOffer,Le as composeSdkAbortSignal,wn as computeAssemblyDigest,Hn as computeDeployPlan,Pi as computeRemediationOpId,ko as computeSecretsDrift,Fi as computeTemplateDigest,Ss as computeTicketDigest,wt as convertCloudFormationOutputsToRecord,ue as createAccount,Q as createDeployEmitter,nt as createEmptyState,ms as createMemoisedPlanLoader,tn as createPublicResolvers,Po as createSequencedCallbacks,dn as createSystemDnsNameProbe,$o as decideNextTransition,ri as decommissionMemberTrailStorage,Si as defaultDriftJournalDir,Mi as defaultRemediationForensicsDir,Oi as defaultRemediationJournalDir,An as deleteChildNsFromParent,_t as deleteDomainState,st as deleteStateFile,ho as deploy,cn as deployDelegatedDomain,jn as derivePropertyChanges,ea as deriveRemovalTemplate,rt as deriveResourcesFromManifestStacks,Ui as deriveRetainFlipTemplate,bo as deriveStaleParameters,ce as describeOrganisation,ee as describeTargetReadinessReason,vo as destroy,Ri as detectStackDrift,Jn as digestHead,Yn as dockerBuilder,ve as drainPages,Bt as emitProgress,ke as enableCentralisedRootAccess,_e as enableIpamDelegatedAdmin,Se as enablePolicyTypes,Re as enableRamSharing,le as enableServiceAccess,Ia as ensureEnforceSsl,Ee as ensureOrganisationExists,De as ensureOrganisationalUnitsExist,cs as evaluateDestructionConsents,As as executableRemediationVerbs,Ga as extractAllAccountNames,Yo as extractConsumedSsmParameters,Ie as extractErrorName,go as failure,si as fetchLastOperationEvents,fo as fileExists,no as filterDangerousEnvVars,de as findAccount,fe as findDevelopmentOuId,ki as findMarkedResourcesByOpId,fi as findRemediationJournalByOpId,ra as findRemovalDeletionFailures,ta as findResourcesPresent,Va as flattenAccountsToEnvironments,_i as formatDriftPreFlightBlock,Aa as formatDriftRepairOffer,It as formatInfrastructureError,sa as formatPinOutcomeDetail,Ji as formatRecreateInFlightCures,Ur as getApplicationDeployOrder,kr as getApplicationDestroyOrder,br as getApplicationStackName,Xr as getApplicationStepId,Kr as getApplicationStepName,Bn as getDestroyStepId,Yr as getOrganisationStackName,xr as getParallelDeployGroups,Fr as getParallelDestroyGroups,ht as getSourceContext,ct as getStateFilePath,yt as getStructuralHint,Mt as hasCdkDifferences,po as hasDockerfile,pt as hashDomainDirectory,ye as isAborted,Xa as isAccountsConfig,Mr as isApplicationOperation,Vr as isApplicationStack,Lt as isCdkError,Wn as isDataLoss,On as isDelegatedToRoute53,_a as isDeployPathBlockingStatus,Ca as isEnforceSslStatement,Io as isFailure,xe as isOULeaf,wr as isOpenNextPattern,vr as isOrganisationOperation,Ha as isOuOnlyAccountBucket,Gr as isQuarantineDetail,dr as isRemediationPlaceholderPhysicalId,Br as isRetainedBucketsDetail,Fa as isRootTaskPolicyArn,Pn as isRoute53NameServer,Zn as isStatefulResourceType,Ka as isStringArray,Lo as isSuccess,ls as legalRemediationVerbs,me as listAccounts,Ci as listActiveRemediationOps,Ni as listActiveRemediationOpsForContext,ps as loadDeployPlan,so as maskSensitiveOutput,qo as mergeReconciledProviderAccounts,Dn as normaliseRecordName,Rn as nsDelegationPhysicalName,kn as openNextBuilder,Ya as parseAccountsConfiguration,Xt as parseBuildPhase,W as parseDeployContractVersion,j as parseDeployEvent,vt as parseDiffOutput,Eo as parseShellArgs,Go as partitionAccounts,Mn as partitionForRegion,Qi as partitionPreFlightByRemediation,Ea as pinProbeCoverage,Pe as placeAccountsInOUs,oe as probeAccountStackExists,Uo as probeSecretsDrift,jo as projectAccountRows,Qo as projectScalarSummary,bi as proveFlipMetadataOnly,oa as proveRemovalTargetsOnly,At as readDomainState,li as readDriftSuspects,gi as readRemediationJournal,Yi as readRetainFlipState,it as readStateFile,Zo as reconcileProviderAccounts,ei as reconcileTrailMigration,Tt as recordDomainDeployState,Ai as recordDriftSuspects,ne as regionDisabledMessage,St as regionSuffix,Fe as registerSecurityDelegates,pr as remediationPhaseRank,mr as remediationPlaceholderPhysicalId,_s as renderConsentVerdictLines,Ts as renderDestructionTicketLines,ca as renderPinReportLines,zn as renderPlanLines,qn as renderPlanSummary,In as resolveBuildArgs,gn as resolveBuildSecretSessionProvider,Cn as resolveBuildSecrets,Nn as resolveSecretRefValue,Fo as restart,ya as restoreAndReconcileQuarantinedBucket,ga as restoreBucketPolicy,is as runApprovalGate,En as runCaaPreflight,Tn as runDelegatedDomainDestroy,ss as runDestructionGate,Ti as runDriftPreFlight,na as runDriftRepairGate,ji as runForgetSurgery,Qa as runOpenNextBuild,Wa as runOrganisationSetup,Sa as runPinRemediation,$i as runRecreatePreFlight,Zi as runRecreateSurgery,di as runRoute53RecordPreflight,es as signApprovalToken,co as sleep,uo as sleepAbortable,ge as snapshotIdentityCentre,qi as snapshotPolicyForType,Ln as sourcedRefsFromBuildArgs,Nt as startStackMonitoring,bn as staticSiteBuilder,$r as stubCallerIdentity,No as success,Li as sweepExpiredRemediationJournals,Wi as synthTemplateDeclaresResource,La as synthesiseEnforceSslDocument,un as systemDnsNameProbe,ln as templateOwnsDelegationRecord,Hr as toPascalCase,Na as toResourcePolicyStatements,io as toServiceError,$n as toWirePlanChanges,fa as triageBucketPolicy,A as truncateUtf16Safe,Da as unlockBucket,Pa as unlockQueue,pe as updateBackupGlobalSettings,Et as updateTemplateHash,vn as validateBuildGroup,Er as verbsForDriftVerdict,rs as verifyApprovalToken,Ma as verifyOrgTrailDelivery,Vi as verifyRetainFlipDiff,nn as waitForNsPropagation,zr as wrapApplicationError,Rt as writeDomainState,Ii as writeRemediationJournal,at as writeStateFile};
|
|
1
|
+
import{DeploymentEventSchema as t,DEPLOYMENT_EVENT_TYPES as o,DEPLOYMENT_EVENT_RESOURCE_CATEGORIES as i,DEPLOYMENT_EVENT_STATUS_REASON_MAX as a,DEPLOYMENT_EVENT_ERROR_MESSAGE_MAX as n,DEPLOYMENT_EVENT_TRAIL_DETAIL_MAX as s,DEPLOYMENT_ERROR_MESSAGE_MAX as E,CASCADE_PHASES as c,CASCADE_ACCOUNT_STATUSES as S,clampDeploymentEventStrings as l,truncateUtf16Safe as T}from"./types/index.js";import{DeployEventSchema as R,StepProgressSchema as _,DeployResourceSchema as p,PlanChangeSchema as m,PlanPropertyChangeSchema as d,ChangeCountsSchema as u,DEPLOY_EVENT_CONTRACT as D,DEPLOY_EVENT_CONTRACT_MAJOR as P,DEPLOY_EVENT_CONTRACT_MINOR as O,SUPPORTED_CONTRACT_MARKERS as f,DEPLOY_EVENT_ID_MAX as C,DEPLOY_EVENT_NAME_MAX as N,DEPLOY_EVENT_MESSAGE_MAX as g,DEPLOY_EVENT_STATUS_REASON_MAX as L,DEPLOY_EVENT_ERROR_MESSAGE_MAX as I,DEPLOY_EVENT_TRAIL_DETAIL_MAX as y,DEPLOY_EVENT_OUTPUT_MAX as h,DEPLOY_EVENT_ARN_MAX as M,DEPLOY_EVENT_URL_MAX as v,STEP_COMPLETE_STATUSES as x,LOG_LEVELS as U,STACK_CLEANUP_PHASES as F,CASCADE_ACCOUNT_PHASES as k,DEPLOY_RESULTS as b,DETECTION_PHASES as Y,PHASE_STATUSES as V,BUILDERS as G,CASCADE_OUTCOME_RESULTS as B,PLAN_ACTIONS as K,REPLACEMENT_MODES as X,APPROVAL_KINDS as H,APPROVAL_DECISIONS as w,ALL_PROGRESS_KINDS as J,createDeployEmitter as Q,parseDeployEvent as j,parseDeployContractVersion as W}from"./types/index.js";import{SimpleAwsProvider as q}from"./aws/index.js";import{checkTargetReadiness as $,describeTargetReadinessReason as ee,buildTargetUnreadyAdvisory as re,buildTargetSetUnreadyAdvisory as te,probeAccountStackExists as oe}from"./aws/index.js";import{checkRegionEnabled as ae,regionDisabledMessage as ne}from"./aws/index.js";import{ensureOrganisationExists as Ee,describeOrganisation as ce,enablePolicyTypes as Se,enableServiceAccess as le,SERVICE_PRINCIPALS as Te,enableRamSharing as Ae,activateTrustedAccess as Re,enableIpamDelegatedAdmin as _e,updateBackupGlobalSettings as pe,listAccounts as me,findAccount as de,createAccount as ue,ensureOrganisationalUnitsExist as De,placeAccountsInOUs as Pe,buildAccountToOUMap as Oe,findDevelopmentOuId as fe,activateCostAllocationTags as Ce,checkIdentityCentreStatus as Ne,snapshotIdentityCentre as ge,composeSdkAbortSignal as Le,extractErrorName as Ie,isAborted as ye,DEFAULT_MAX_PAGES as he,IDENTITY_STORE_PAGE_SIZE as Me,drainPages as ve,isOULeaf as xe,registerSecurityDelegates as Ue,SECURITY_SERVICE_PRINCIPALS as Fe,enableCentralisedRootAccess as ke,ROOT_ACCESS_FEATURES as be,RootAccessEnablementError as Ye}from"./aws/index.js";import{STEP_IDS as Ge,STEP_NAMES as Be,INFRASTRUCTURE_STEP_NAMES as Ke,INFRA_STEP_NAME as Xe}from"./types/index.js";import{RemediationVerbSchema as we,REMEDIATION_VERB_GLOSS as Je,DestructionFindingSchema as Qe,DestructionTicketResourceSchema as je,DestructionTicketSchema as We,DestructionConsentSchema as Ze,DestructionOutcomeSchema as qe,DESTRUCTION_FINDINGS as ze,CONSENT_VERDICTS as $e,TICKET_VERDICT_SOURCES as er,TicketVerdictSourceSchema as rr}from"./types/index.js";import{DRIFT_VERDICTS as or,DriftVerdictSchema as ir,DriftSuspectSchema as ar,DriftFindingSchema as nr,DriftJournalRecordSchema as sr,verbsForDriftVerdict as Er}from"./types/index.js";import{REMEDIATION_PHASES as Sr,RemediationPhaseSchema as lr,RemediationTargetSchema as Tr,RemediationFlipProofSchema as Ar,RemediationJournalRecordSchema as Rr,RemediationVerbWithSurgerySchema as _r,remediationPhaseRank as pr,remediationPlaceholderPhysicalId as mr,isRemediationPlaceholderPhysicalId as dr}from"./types/index.js";import{ProgressReporter as Dr,APPLICATION_STACKS as Pr,ORGANISATION_TYPES as Or,APPLICATION_DEPLOY_ORDER as fr,APPLICATION_DESTROY_ORDER as Cr,OPENNEXT_DEPLOY_ORDER as Nr,OPENNEXT_DESTROY_ORDER as gr,PARALLEL_DEPLOY_GROUPS as Lr,PARALLEL_DESTROY_GROUPS as Ir,OPENNEXT_PARALLEL_GROUPS as yr,PARALLEL_OPERATION_TYPES as hr,isApplicationOperation as Mr,isOrganisationOperation as vr,getParallelDeployGroups as xr,getParallelDestroyGroups as Ur,getApplicationDeployOrder as Fr,getApplicationDestroyOrder as kr,getApplicationStackName as br,getOrganisationStackName as Yr,isApplicationStack as Vr,isQuarantineDetail as Gr,isRetainedBucketsDetail as Br,getApplicationStepName as Kr,getApplicationStepId as Xr,toPascalCase as Hr,isOpenNextPattern as wr,OPENNEXT_PATTERNS as Jr,STACK_NOT_FOUND_PATTERN as Qr,STACK_FAILED_STATE_PATTERN as jr,CDK_NO_STACKS_MATCH as Wr,INFRASTRUCTURE_FILENAME as Zr,ApplicationError as qr,wrapApplicationError as zr,stubCallerIdentity as $r}from"./types/index.js";import{deriveResourcesFromManifestStacks as rt}from"./types/detection/patternDetection.js";import{FjallStateFileSchema as ot,readStateFile as it,writeStateFile as at,createEmptyState as nt,deleteStateFile as st,updateTemplateHash as Et,getStateFilePath as ct,regionSuffix as St}from"./types/config/FjallState.js";import{readDomainState as Tt,writeDomainState as At,recordDomainDeployState as Rt,deleteDomainState as _t,hashDomainDirectory as pt,LEGACY_DOMAIN_STATE_FILENAME as mt}from"./types/config/DomainState.js";import{CloudFormationEventMonitor as ut}from"./aws/index.js";import{CdkService as Pt,CdkArgumentBuilder as Ot,CdkProcessManager as ft,ensureDependencyIntegrity as Ct,clearDependencyIntegrityCache as Nt,DEPENDENCY_SYNC_TIMEOUT_MS as gt,CdkEventMonitor as Lt,startStackMonitoring as It,DEFAULT_DEPLOY_TIMEOUT_MS as yt,isCdkError as ht,formatInfrastructureError as Mt,getStructuralHint as vt,getSourceContext as xt,hasCdkDifferences as Ut,parseDiffOutput as Ft,CloudFormationService as kt,CloudFormationError as bt,EcsService as Yt,EcsError as Vt,EcsServiceResolver as Gt,TemplateHashService as Bt,TemplateHashError as Kt,CdkContextBuilder as Xt,emitProgress as Ht,PROGRESS_MESSAGES as wt,parseBuildPhase as Jt,buildStepContextBuildConfig as Qt,convertCloudFormationOutputsToRecord as jt,ApplicationStackService as Wt}from"./services/index.js";import{CdkError as qt}from"./types/errors/index.js";import{BaseServiceError as $t,ValidationError as eo,AuthError as ro,AwsError as to,DeploymentError as oo,NetworkError as io,FileSystemError as ao,ConfigError as no,toServiceError as so}from"./types/errors/index.js";import{filterDangerousEnvVars as co,maskSensitiveOutput as So,parseShellArgs as lo,sleep as To}from"@fjall/util";import{artefactOutputKey as Ro,DeployModeSchema as _o,ServiceArtefactSchema as po,ServiceArtefactsSchema as mo}from"@fjall/util";import{hasDockerfile as Do}from"./util/dockerfileDetection.js";import{sleepAbortable as Oo}from"./util/sleepAbortable.js";import{createSequencedCallbacks as Co}from"./util/sequencedCallbacks.js";import{fileExists as go}from"@fjall/util/fsHelpers";import{success as Io,failure as yo,isSuccess as ho,isFailure as Mo}from"@fjall/generator";import{deploy as xo}from"./orchestration/index.js";import{destroy as Fo}from"./orchestration/index.js";import{restart as bo,probeSecretsDrift as Yo,computeSecretsDrift as Vo,deriveStaleParameters as Go,extractConsumedSsmParameters as Bo}from"./orchestration/index.js";import{partitionAccounts as Xo}from"./orchestration/index.js";import{buildRegionList as wo,buildAccountRegionPairs as Jo,cascadeHomeRegion as Qo,cascadeOperationKey as jo}from"./orchestration/index.js";import{projectScalarSummary as Zo,projectAccountRows as qo}from"./orchestration/index.js";import{reconcileProviderAccounts as $o,mergeReconciledProviderAccounts as ei}from"./orchestration/index.js";import{decideNextTransition as ti,reconcileTrailMigration as oi,decommissionMemberTrailStorage as ii,ORG_TRAIL_BUCKET_OUTPUT_KEY as ai,TRAIL_BUCKET_OUTPUT_KEY as ni,TRAIL_KEY_ARN_OUTPUT_KEY as si}from"./orchestration/index.js";import{classifyDriftFailure as ci,fetchLastOperationEvents as Si,DriftProbe as li,clearDriftSuspects as Ti,defaultDriftJournalDir as Ai,readDriftSuspects as Ri,recordDriftSuspects as _i,detectStackDrift as pi,runDriftPreFlight as mi,formatDriftPreFlightBlock as di,DRIFT_PREFLIGHT_TRIGGER_STATUSES as ui,DRIFT_PREFLIGHT_BUDGET_MS as Di,runRoute53RecordPreflight as Pi}from"./orchestration/index.js";import{archiveCompletedRemediationJournal as fi,computeRemediationOpId as Ci,defaultRemediationJournalDir as Ni,findRemediationJournalByOpId as gi,listActiveRemediationOps as Li,listActiveRemediationOpsForContext as Ii,readRemediationJournal as yi,sweepExpiredRemediationJournals as hi,writeRemediationJournal as Mi,REMEDIATION_JOURNAL_RETENTION_DAYS as vi,captureRemediationForensics as xi,defaultRemediationForensicsDir as Ui,applyRetainFlip as Fi,composeFlipCapabilities as ki,computeTemplateDigest as bi,deriveRetainFlipTemplate as Yi,findMarkedResourcesByOpId as Vi,proveFlipMetadataOnly as Gi,readRetainFlipState as Bi,verifyRetainFlipDiff as Ki,FORGET_MARKER_KEY as Xi,FORGET_FLIP_SPEC as Hi,RECREATE_MARKER_KEY as wi,assessForgetResumability as Ji,completeForgetAfterConverge as Qi,completeForgetAfterDeploy as ji,formatRecreateInFlightCures as Wi,partitionPreFlightByRemediation as Zi,runForgetSurgery as qi,synthTemplateDeclaresResource as zi,runRecreateSurgery as $i,snapshotPolicyForType as ea,SNAPSHOT_CAPABLE_RESOURCE_TYPES as ra,runRecreatePreFlight as ta,deriveRemovalTemplate as oa,findRemovalDeletionFailures as ia,findResourcesPresent as aa,proveRemovalTargetsOnly as na,advertisableDriftVerbs as sa,buildDriftRepairTicket as Ea,runDriftRepairGate as ca,formatPinOutcomeDetail as Sa,pinProbeCoverage as la,renderPinReportLines as Ta,runPinRemediation as Aa,composePostFailureRepairOffer as Ra,formatDriftRepairOffer as _a,DriftRepairAvailableError as pa,checkDeployPathStackAvailability as ma,isDeployPathBlockingStatus as da,StackUnavailableError as ua,assertLeaseBeforeStack as Da,LeaseDeniedError as Pa}from"./orchestration/index.js";import{unlockBucket as fa,unlockQueue as Ca}from"./orchestration/index.js";import{triageBucketPolicy as ga,isEnforceSslStatement as La,toResourcePolicyStatements as Ia,restoreBucketPolicy as ya,synthesiseEnforceSslDocument as ha,ensureEnforceSsl as Ma,restoreAndReconcileQuarantinedBucket as va}from"./orchestration/index.js";import{verifyOrgTrailDelivery as Ua}from"./aws/cloudtrail/orgTrailDelivery.js";import{assumeRootForTask as ka,isRootTaskPolicyArn as ba,ROOT_TASK_POLICY_ARNS as Ya,MAX_ROOT_SESSION_SECONDS as Va}from"./aws/sts/assumeRoot.js";import{parseAccountsConfiguration as Ba,flattenAccountsToEnvironments as Ka,extractAllAccountNames as Xa,accountsConfigToOUTree as Ha,isStringArray as wa,isAccountsConfig as Ja,isOuOnlyAccountBucket as Qa,OU_ONLY_ACCOUNT_BUCKETS as ja}from"./orchestration/index.js";import{runOpenNextBuild as Za}from"./orchestration/index.js";import{runOrganisationSetup as za,ORG_SETUP_PHASES as $a}from"./orchestration/index.js";import{DOMAIN_DELEGATION_ERROR_TYPES as rn,DomainDelegationError as tn,DEFAULT_PUBLIC_RESOLVER_ADDRESSES as on,PUBLIC_DNS_QUERY_TIMEOUT_MS as an,createPublicResolvers as nn,NS_PROPAGATION_DEFAULT_MAX_ATTEMPTS as sn,NS_PROPAGATION_DEFAULT_INTERVAL_MS as En,waitForNsPropagation as cn,ACM_CAA_ISSUERS as Sn,runCaaPreflight as ln,deployDelegatedDomain as Tn,CROSS_ACCOUNT_DELEGATION_RESOURCE_TYPE as An,templateOwnsDelegationRecord as Rn,deleteChildNsFromParent as _n,nsDelegationPhysicalName as pn,runDelegatedDomainDestroy as mn}from"./orchestration/index.js";import{classifyZoneRecords as un,buildSatelliteRecordIndex as Dn,createSystemDnsNameProbe as Pn,systemDnsNameProbe as On,normaliseRecordName as fn,isRoute53NameServer as Cn,isDelegatedToRoute53 as Nn}from"./orchestration/index.js";import{resolveBuildSecrets as Ln,resolveSecretRefValue as In,resolveBuildSecretSessionProvider as yn,sourcedRefsFromBuildArgs as hn,resolveBuildArgs as Mn,buildBuildSecretSessionPolicy as vn,buildDeploySessionPolicy as xn,partitionForRegion as Un,validateBuildGroup as Fn}from"./orchestration/index.js";import{FrameworkRegistry as bn}from"./orchestration/index.js";import{openNextBuilder as Vn,staticSiteBuilder as Gn,dockerBuilder as Bn}from"./orchestration/index.js";import{StepRegistry as Xn,getDestroyStepId as Hn}from"./steps/index.js";import{buildDeployPlan as Jn,computeDeployPlan as Qn,computeAssemblyDigest as jn,digestHead as Wn,classifyImpact as Zn,derivePropertyChanges as qn,isDataLoss as zn,isStatefulResourceType as $n,renderPlanSummary as es,renderPlanLines as rs,toWirePlanChanges as ts,signApprovalToken as os,verifyApprovalToken as is,DEFAULT_APPROVAL_TTL_MS as as,APPROVAL_TOKEN_PATTERN as ns,runApprovalGate as ss,approvalRefusalReason as Es}from"./orchestration/index.js";import{runDestructionGate as Ss,buildDestructionTicket as ls,evaluateDestructionConsents as Ts,computeTicketDigest as As,legalRemediationVerbs as Rs,executableRemediationVerbs as _s,advertisableRemediationVerbs as ps,renderDestructionTicketLines as ms,renderConsentVerdictLines as ds,loadDeployPlan as us,createMemoisedPlanLoader as Ds}from"./orchestration/index.js";export{Sn as ACM_CAA_ISSUERS,J as ALL_PROGRESS_KINDS,fr as APPLICATION_DEPLOY_ORDER,Cr as APPLICATION_DESTROY_ORDER,Pr as APPLICATION_STACKS,w as APPROVAL_DECISIONS,H as APPROVAL_KINDS,ns as APPROVAL_TOKEN_PATTERN,qr as ApplicationError,Wt as ApplicationStackService,ro as AuthError,to as AwsError,G as BUILDERS,$t as BaseServiceError,k as CASCADE_ACCOUNT_PHASES,S as CASCADE_ACCOUNT_STATUSES,B as CASCADE_OUTCOME_RESULTS,c as CASCADE_PHASES,Wr as CDK_NO_STACKS_MATCH,$e as CONSENT_VERDICTS,An as CROSS_ACCOUNT_DELEGATION_RESOURCE_TYPE,Ot as CdkArgumentBuilder,Xt as CdkContextBuilder,qt as CdkError,Lt as CdkEventMonitor,ft as CdkProcessManager,Pt as CdkService,u as ChangeCountsSchema,bt as CloudFormationError,ut as CloudFormationEventMonitor,kt as CloudFormationService,no as ConfigError,as as DEFAULT_APPROVAL_TTL_MS,yt as DEFAULT_DEPLOY_TIMEOUT_MS,he as DEFAULT_MAX_PAGES,on as DEFAULT_PUBLIC_RESOLVER_ADDRESSES,gt as DEPENDENCY_SYNC_TIMEOUT_MS,E as DEPLOYMENT_ERROR_MESSAGE_MAX,n as DEPLOYMENT_EVENT_ERROR_MESSAGE_MAX,i as DEPLOYMENT_EVENT_RESOURCE_CATEGORIES,a as DEPLOYMENT_EVENT_STATUS_REASON_MAX,s as DEPLOYMENT_EVENT_TRAIL_DETAIL_MAX,o as DEPLOYMENT_EVENT_TYPES,M as DEPLOY_EVENT_ARN_MAX,D as DEPLOY_EVENT_CONTRACT,P as DEPLOY_EVENT_CONTRACT_MAJOR,O as DEPLOY_EVENT_CONTRACT_MINOR,I as DEPLOY_EVENT_ERROR_MESSAGE_MAX,C as DEPLOY_EVENT_ID_MAX,g as DEPLOY_EVENT_MESSAGE_MAX,N as DEPLOY_EVENT_NAME_MAX,h as DEPLOY_EVENT_OUTPUT_MAX,L as DEPLOY_EVENT_STATUS_REASON_MAX,y as DEPLOY_EVENT_TRAIL_DETAIL_MAX,v as DEPLOY_EVENT_URL_MAX,b as DEPLOY_RESULTS,ze as DESTRUCTION_FINDINGS,Y as DETECTION_PHASES,rn as DOMAIN_DELEGATION_ERROR_TYPES,Di as DRIFT_PREFLIGHT_BUDGET_MS,ui as DRIFT_PREFLIGHT_TRIGGER_STATUSES,or as DRIFT_VERDICTS,R as DeployEventSchema,_o as DeployModeSchema,p as DeployResourceSchema,oo as DeploymentError,t as DeploymentEventSchema,Ze as DestructionConsentSchema,Qe as DestructionFindingSchema,qe as DestructionOutcomeSchema,je as DestructionTicketResourceSchema,We as DestructionTicketSchema,tn as DomainDelegationError,nr as DriftFindingSchema,sr as DriftJournalRecordSchema,li as DriftProbe,pa as DriftRepairAvailableError,ar as DriftSuspectSchema,ir as DriftVerdictSchema,Vt as EcsError,Yt as EcsService,Gt as EcsServiceResolver,Hi as FORGET_FLIP_SPEC,Xi as FORGET_MARKER_KEY,ao as FileSystemError,ot as FjallStateFileSchema,bn as FrameworkRegistry,Me as IDENTITY_STORE_PAGE_SIZE,Zr as INFRASTRUCTURE_FILENAME,Ke as INFRASTRUCTURE_STEP_NAMES,Xe as INFRA_STEP_NAME,mt as LEGACY_DOMAIN_STATE_FILENAME,U as LOG_LEVELS,Pa as LeaseDeniedError,Va as MAX_ROOT_SESSION_SECONDS,En as NS_PROPAGATION_DEFAULT_INTERVAL_MS,sn as NS_PROPAGATION_DEFAULT_MAX_ATTEMPTS,io as NetworkError,Nr as OPENNEXT_DEPLOY_ORDER,gr as OPENNEXT_DESTROY_ORDER,yr as OPENNEXT_PARALLEL_GROUPS,Jr as OPENNEXT_PATTERNS,Or as ORGANISATION_TYPES,$a as ORG_SETUP_PHASES,ai as ORG_TRAIL_BUCKET_OUTPUT_KEY,ja as OU_ONLY_ACCOUNT_BUCKETS,Lr as PARALLEL_DEPLOY_GROUPS,Ir as PARALLEL_DESTROY_GROUPS,hr as PARALLEL_OPERATION_TYPES,V as PHASE_STATUSES,K as PLAN_ACTIONS,wt as PROGRESS_MESSAGES,an as PUBLIC_DNS_QUERY_TIMEOUT_MS,m as PlanChangeSchema,d as PlanPropertyChangeSchema,Dr as ProgressReporter,wi as RECREATE_MARKER_KEY,vi as REMEDIATION_JOURNAL_RETENTION_DAYS,Sr as REMEDIATION_PHASES,Je as REMEDIATION_VERB_GLOSS,X as REPLACEMENT_MODES,be as ROOT_ACCESS_FEATURES,Ya as ROOT_TASK_POLICY_ARNS,Ar as RemediationFlipProofSchema,Rr as RemediationJournalRecordSchema,lr as RemediationPhaseSchema,Tr as RemediationTargetSchema,we as RemediationVerbSchema,_r as RemediationVerbWithSurgerySchema,Ye as RootAccessEnablementError,Fe as SECURITY_SERVICE_PRINCIPALS,Te as SERVICE_PRINCIPALS,ra as SNAPSHOT_CAPABLE_RESOURCE_TYPES,F as STACK_CLEANUP_PHASES,jr as STACK_FAILED_STATE_PATTERN,Qr as STACK_NOT_FOUND_PATTERN,x as STEP_COMPLETE_STATUSES,Ge as STEP_IDS,Be as STEP_NAMES,f as SUPPORTED_CONTRACT_MARKERS,po as ServiceArtefactSchema,mo as ServiceArtefactsSchema,q as SimpleAwsProvider,ua as StackUnavailableError,_ as StepProgressSchema,Xn as StepRegistry,er as TICKET_VERDICT_SOURCES,ni as TRAIL_BUCKET_OUTPUT_KEY,si as TRAIL_KEY_ARN_OUTPUT_KEY,Kt as TemplateHashError,Bt as TemplateHashService,rr as TicketVerdictSourceSchema,eo as ValidationError,Ha as accountsConfigToOUTree,Ce as activateCostAllocationTags,Re as activateTrustedAccess,sa as advertisableDriftVerbs,ps as advertisableRemediationVerbs,Fi as applyRetainFlip,Es as approvalRefusalReason,fi as archiveCompletedRemediationJournal,Ro as artefactOutputKey,Da as assertLeaseBeforeStack,Ji as assessForgetResumability,ka as assumeRootForTask,Jo as buildAccountRegionPairs,Oe as buildAccountToOUMap,vn as buildBuildSecretSessionPolicy,Jn as buildDeployPlan,xn as buildDeploySessionPolicy,ls as buildDestructionTicket,Ea as buildDriftRepairTicket,wo as buildRegionList,Dn as buildSatelliteRecordIndex,Qt as buildStepContextBuildConfig,te as buildTargetSetUnreadyAdvisory,re as buildTargetUnreadyAdvisory,xi as captureRemediationForensics,Qo as cascadeHomeRegion,jo as cascadeOperationKey,ma as checkDeployPathStackAvailability,Ne as checkIdentityCentreStatus,ae as checkRegionEnabled,$ as checkTargetReadiness,l as clampDeploymentEventStrings,ci as classifyDriftFailure,Zn as classifyImpact,un as classifyZoneRecords,Nt as clearDependencyIntegrityCache,Ti as clearDriftSuspects,Qi as completeForgetAfterConverge,ji as completeForgetAfterDeploy,ki as composeFlipCapabilities,Ra as composePostFailureRepairOffer,Le as composeSdkAbortSignal,jn as computeAssemblyDigest,Qn as computeDeployPlan,Ci as computeRemediationOpId,Vo as computeSecretsDrift,bi as computeTemplateDigest,As as computeTicketDigest,jt as convertCloudFormationOutputsToRecord,ue as createAccount,Q as createDeployEmitter,nt as createEmptyState,Ds as createMemoisedPlanLoader,nn as createPublicResolvers,Co as createSequencedCallbacks,Pn as createSystemDnsNameProbe,ti as decideNextTransition,ii as decommissionMemberTrailStorage,Ai as defaultDriftJournalDir,Ui as defaultRemediationForensicsDir,Ni as defaultRemediationJournalDir,_n as deleteChildNsFromParent,_t as deleteDomainState,st as deleteStateFile,xo as deploy,Tn as deployDelegatedDomain,qn as derivePropertyChanges,oa as deriveRemovalTemplate,rt as deriveResourcesFromManifestStacks,Yi as deriveRetainFlipTemplate,Go as deriveStaleParameters,ce as describeOrganisation,ee as describeTargetReadinessReason,Fo as destroy,pi as detectStackDrift,Wn as digestHead,Bn as dockerBuilder,ve as drainPages,Ht as emitProgress,ke as enableCentralisedRootAccess,_e as enableIpamDelegatedAdmin,Se as enablePolicyTypes,Ae as enableRamSharing,le as enableServiceAccess,Ct as ensureDependencyIntegrity,Ma as ensureEnforceSsl,Ee as ensureOrganisationExists,De as ensureOrganisationalUnitsExist,Ts as evaluateDestructionConsents,_s as executableRemediationVerbs,Xa as extractAllAccountNames,Bo as extractConsumedSsmParameters,Ie as extractErrorName,yo as failure,Si as fetchLastOperationEvents,go as fileExists,co as filterDangerousEnvVars,de as findAccount,fe as findDevelopmentOuId,Vi as findMarkedResourcesByOpId,gi as findRemediationJournalByOpId,ia as findRemovalDeletionFailures,aa as findResourcesPresent,Ka as flattenAccountsToEnvironments,di as formatDriftPreFlightBlock,_a as formatDriftRepairOffer,Mt as formatInfrastructureError,Sa as formatPinOutcomeDetail,Wi as formatRecreateInFlightCures,Fr as getApplicationDeployOrder,kr as getApplicationDestroyOrder,br as getApplicationStackName,Xr as getApplicationStepId,Kr as getApplicationStepName,Hn as getDestroyStepId,Yr as getOrganisationStackName,xr as getParallelDeployGroups,Ur as getParallelDestroyGroups,xt as getSourceContext,ct as getStateFilePath,vt as getStructuralHint,Ut as hasCdkDifferences,Do as hasDockerfile,pt as hashDomainDirectory,ye as isAborted,Ja as isAccountsConfig,Mr as isApplicationOperation,Vr as isApplicationStack,ht as isCdkError,zn as isDataLoss,Nn as isDelegatedToRoute53,da as isDeployPathBlockingStatus,La as isEnforceSslStatement,Mo as isFailure,xe as isOULeaf,wr as isOpenNextPattern,vr as isOrganisationOperation,Qa as isOuOnlyAccountBucket,Gr as isQuarantineDetail,dr as isRemediationPlaceholderPhysicalId,Br as isRetainedBucketsDetail,ba as isRootTaskPolicyArn,Cn as isRoute53NameServer,$n as isStatefulResourceType,wa as isStringArray,ho as isSuccess,Rs as legalRemediationVerbs,me as listAccounts,Li as listActiveRemediationOps,Ii as listActiveRemediationOpsForContext,us as loadDeployPlan,So as maskSensitiveOutput,ei as mergeReconciledProviderAccounts,fn as normaliseRecordName,pn as nsDelegationPhysicalName,Vn as openNextBuilder,Ba as parseAccountsConfiguration,Jt as parseBuildPhase,W as parseDeployContractVersion,j as parseDeployEvent,Ft as parseDiffOutput,lo as parseShellArgs,Xo as partitionAccounts,Un as partitionForRegion,Zi as partitionPreFlightByRemediation,la as pinProbeCoverage,Pe as placeAccountsInOUs,oe as probeAccountStackExists,Yo as probeSecretsDrift,qo as projectAccountRows,Zo as projectScalarSummary,Gi as proveFlipMetadataOnly,na as proveRemovalTargetsOnly,Tt as readDomainState,Ri as readDriftSuspects,yi as readRemediationJournal,Bi as readRetainFlipState,it as readStateFile,$o as reconcileProviderAccounts,oi as reconcileTrailMigration,Rt as recordDomainDeployState,_i as recordDriftSuspects,ne as regionDisabledMessage,St as regionSuffix,Ue as registerSecurityDelegates,pr as remediationPhaseRank,mr as remediationPlaceholderPhysicalId,ds as renderConsentVerdictLines,ms as renderDestructionTicketLines,Ta as renderPinReportLines,rs as renderPlanLines,es as renderPlanSummary,Mn as resolveBuildArgs,yn as resolveBuildSecretSessionProvider,Ln as resolveBuildSecrets,In as resolveSecretRefValue,bo as restart,va as restoreAndReconcileQuarantinedBucket,ya as restoreBucketPolicy,ss as runApprovalGate,ln as runCaaPreflight,mn as runDelegatedDomainDestroy,Ss as runDestructionGate,mi as runDriftPreFlight,ca as runDriftRepairGate,qi as runForgetSurgery,Za as runOpenNextBuild,za as runOrganisationSetup,Aa as runPinRemediation,ta as runRecreatePreFlight,$i as runRecreateSurgery,Pi as runRoute53RecordPreflight,os as signApprovalToken,To as sleep,Oo as sleepAbortable,ge as snapshotIdentityCentre,ea as snapshotPolicyForType,hn as sourcedRefsFromBuildArgs,It as startStackMonitoring,Gn as staticSiteBuilder,$r as stubCallerIdentity,Io as success,hi as sweepExpiredRemediationJournals,zi as synthTemplateDeclaresResource,ha as synthesiseEnforceSslDocument,On as systemDnsNameProbe,Rn as templateOwnsDelegationRecord,Hr as toPascalCase,Ia as toResourcePolicyStatements,so as toServiceError,ts as toWirePlanChanges,ga as triageBucketPolicy,T as truncateUtf16Safe,fa as unlockBucket,Ca as unlockQueue,pe as updateBackupGlobalSettings,Et as updateTemplateHash,Fn as validateBuildGroup,Er as verbsForDriftVerdict,is as verifyApprovalToken,Ua as verifyOrgTrailDelivery,Ki as verifyRetainFlipDiff,cn as waitForNsPropagation,zr as wrapApplicationError,At as writeDomainState,Mi as writeRemediationJournal,at as writeStateFile};
|
|
@@ -32,7 +32,7 @@ export declare function emptyBuildProducts(): DockerBuildProducts;
|
|
|
32
32
|
*
|
|
33
33
|
* After each group's push, the helper derives a content-hash tag from the
|
|
34
34
|
* digest (`deriveContentHashTag` at `@fjall/util`) and applies it via
|
|
35
|
-
* `tagByDigest` (manifest
|
|
35
|
+
* `tagByDigest` (flat-manifest carbon copy, no layer re-upload). The resulting
|
|
36
36
|
* `DockerBuildProducts` carries the `<service>` → `<content-hash-tag>` map
|
|
37
37
|
* (plumbed into the CDK deploy via `--parameters <Service>ImageTag=<tag>`)
|
|
38
38
|
* plus the per-service digests and repo URI for artefact collection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var J=Object.defineProperty;var g=(e,n)=>J(e,"name",{value:n,configurable:!0});import{isAbsolute as U,join as F,dirname as X,resolve as j}from"node:path";import{existsSync as H}from"node:fs";import{success as P,failure as b}from"@fjall/generator";import{deriveContentHashTag as Y,getErrorMessage as G,maskSensitiveOutput as y,toKebab as L}from"@fjall/util";import{evaluateBakeGuard as q,evaluateResolvedBuildArgValues as Q,acknowledgedBuildArgKeys as Z,createBakeWarningDeduper as ee,buildCacheRepositoryName as V,BAKE_GUARD_EXPOSURE_CLAUSE as re}from"@fjall/util/docker";import{runWithBoundedConcurrency as te,resolveBuildConcurrency as ne}from"@fjall/util/buildConcurrency";import{logger as T}from"@fjall/util/logger";import{parseDockerServicesFromManifest as oe,parseLambdaDockerServicesFromManifest as ie}from"@fjall/util/manifest";import{STEP_IDS as C}from"../../types/stepDefinitions.js";import{isAborted as W}from"../../aws/organisations/types.js";import{resolveBuildSecrets as se,resolveSecretRefValue as ae,resolveBuildSecretSessionProvider as de,sourcedRefsFromBuildArgs as ce}from"./buildSecretResolver.js";import{partitionForRegion as ue}from"./buildSecretSession.js";import{resolveBuildArgs as le}from"./buildArgResolver.js";import{validateBuildGroup as fe}from"./buildGroupValidator.js";import{ensureBuildCacheRepository as ge}from"./ecrCacheRepository.js";const I="dockerBuildHelper",D="Building and pushing Docker image";function me(e,n,t){const r=F(n,e);if(H(r))return{path:r,base:n};if(t!==""&&t!==n){const o=F(t,e);if(H(o))return{path:o,base:t}}return{path:r,base:n}}g(me,"resolveAgainstBases");function pe(e,n,t){const r=e.docker.path,o=e.docker.context;let c,s;if(U(r))c=r,s=n;else{const p=me(r,n,t);c=p.path,s=p.base}return{buildContext:o?U(o)?j(o):j(s,o):j(X(c)),dockerfilePath:c,target:e.docker.target,resolvedViaFallback:s!==n}}g(pe,"resolveBuildIdentity");function he(e){return`${e.buildContext}|${e.dockerfilePath}|${e.target??""}`}g(he,"buildIdentityKey");function be(e,n){return`Dockerfile not found for service '${e}' at ${n}. Checked the synth directory and the working directory. If your Dockerfile lives at the project root with the CDK app in a subdirectory, set an absolute docker.context (the build context must share the Dockerfile's directory).`}g(be,"dockerfileNotFoundMessage");function ye(e){return e.startsWith("cn-")?"amazonaws.com.cn":"amazonaws.com"}g(ye,"ecrDnsSuffix");function z(e,n){return`${e}.dkr.ecr.${n}.${ye(n)}`}g(z,"ecrRegistryHost");function ve(e,n,t){return`${z(e,n)}/${L(t)}`}g(ve,"ecrRepoUri");function Se(e,n,t){return`${z(e,n)}/${V(L(t))}`}g(Se,"ecrCacheRepoUri");function we(e,n,t){const r=new Map;for(const o of e){const c=pe(o,n,t),s=he(c),m=r.get(s);m?m.members.push(o):r.set(s,{identity:c,members:[o]})}return Array.from(r.values())}g(we,"groupServicesByIdentity");async function Ee(e,n,t,r,o,c){const s=await e.buildAndPush({appName:n.appName,appPath:n.path,region:t,accountId:r,...o!==void 0&&{abortSignal:o}},(m,p,S,E)=>{c.onDockerProgress?.(y(m),p,S,E)});return s.success?P({imageUri:s.data.imageUri,imageTag:s.data.imageTag}):b(s.error)}g(Ee,"buildLegacyFallback");function M(){return{contentHashTagsByService:{},imageDigestsByService:{}}}g(M,"emptyBuildProducts");async function ke(e,n,t,r,o,c,s,m,p,S,E,f,R,k){const l=e.members[0];if(!H(e.identity.dockerfilePath))return b(new Error(be(l.name,e.identity.dockerfilePath)));e.identity.resolvedViaFallback&&m.onLog?.(`Building service '${l.name}' from ${e.identity.dockerfilePath} (resolved at the project root).`,"info");const w=[...l.docker.buildSecrets??[],...R??[]],$=fe({serviceName:l.name,dockerfilePath:e.identity.dockerfilePath,buildContext:e.identity.buildContext,...e.identity.target!==void 0&&{target:e.identity.target},...l.docker.buildArgs!==void 0&&{buildArgs:l.docker.buildArgs},...w.length>0&&{buildSecrets:w},members:e.members.map(i=>({serviceName:i.name,...i.docker.buildArgs!==void 0&&{buildArgs:i.docker.buildArgs},...i.docker.buildSecrets!==void 0&&{buildSecrets:i.docker.buildSecrets}}))});if(!$.success)return b($.error);const a=q(l.docker.buildArgs,L(t.appName));for(const i of a.warnings){const v=y(i.message);k(v)&&m.onLog?.(v,"warn")}if(a.findings.length>0)return b(new Error(y(a.findings.map(i=>i.message).join(" "))));const d=w,B=ce(l.docker.buildArgs),K={appName:t.appName,region:r,accountId:o,partition:ue(r)},O=await de(p,[...d,...B],K);if(!O.success)return b(O.error);const x=O.data,A=await le({manifestBuildArgs:l.docker.buildArgs,serviceDir:e.identity.buildContext,appDir:t.path,...E!==void 0&&{stage:E},shellEnv:process.env,...f!==void 0&&{flagBuildArgs:f},resolveSourcedValue:g((i,v)=>ae(x,{id:i,...v},S),"resolveSourcedValue")});if(!A.success)return b(A.error);const N=A.data.buildArgs;for(const i of A.data.inferredDotenvKeys){const v=y(`buildArg "${i}" was auto-declared from a .env file and will be baked into the image \u2014 ${re}.`);k(v)&&m.onLog?.(v,"warn")}const u=Q(N,L(t.appName),Z(l.docker.buildArgs));if(u.length>0)return b(new Error(y(u.map(i=>i.message).join(" "))));let h;if(d.length>0){const i=await se(x,d,S);if(!i.success)return b(i.error);h=i.data}try{if(W(S))return b(new Error(`Build of service '${l.name}' was aborted before the docker build started`));const i=e.members.some(_=>_.isLambda===!0),v={appName:t.appName,appPath:e.identity.buildContext,region:r,accountId:o,buildContext:e.identity.buildContext,dockerfilePath:e.identity.dockerfilePath,pushByDigest:!0,serviceName:l.name,targetsLambda:i,...s!==void 0&&{cacheRepoUri:s},...e.identity.target!==void 0&&{target:e.identity.target},...Object.keys(N).length>0&&{buildArgs:N},...h!==void 0&&{buildSecrets:h.resolved},...S!==void 0&&{abortSignal:S}};return await Re(e,v,n,c,m)}finally{h!==void 0&&await h.cleanup().catch(()=>m.onLog?.("Build-secret cleanup failed.","warn"))}}g(ke,"buildGroup");async function Re(e,n,t,r,o){const c=await t.buildAndPush(n,(f,R,k,l)=>{o.onDockerProgress?.(y(f),R,k,l)});if(!c.success)return b(c.error);const s=c.data.imageDigest;if(typeof s!="string"||!s.startsWith("sha256:"))return b(new Error(`Buildx push succeeded but returned an invalid digest: ${y(String(s))}`));const m={},p={},S=[];for(const f of e.members){const R=f.docker.target,k=Y(s,f.name,R);if(!k.success)return b(k.error);const l=k.data,w=f.name;m[w]=l,p[w]=s,S.push(`${r}:${l}`)}const E=await t.tagByDigest({sourceImage:r,digest:s,tags:S});return E.success?P({contentHashTagsByService:m,imageDigestsByService:p}):b(E.error)}g(Re,"buildGroupWithParams");function Ae(e,n){const t=new Map(e.map(r=>[r.name,r]));for(const r of n){const o=t.get(r.name);if(o!==void 0&&JSON.stringify(o.docker)!==JSON.stringify(r.docker))throw new Error(`ECS service "${o.name}" and Lambda image key "${r.name}" share one build key but declare different docker configs \u2014 the second build would silently overwrite the first and both would deploy the same image. Rename one of them, or make the docker configs identical to deliberately share the build.`)}}g(Ae,"assertNoCrossEntityBuildKeyDivergence");async function Me(e,n,t,r){const o=e.dockerProvider;if(!o)return P(M());const c=n.awsProvider.getAccountId();if(!c)return r.onLog?.("Skipping Docker build \u2014 account ID not available","warn"),P(M());const s=n.awsProvider.getRegion(),m=F(t.path,"cdk.out");let p;try{const a=oe(m),d=ie(m);Ae(a,d),p=[...a,...d]}catch(a){const d=new Error(y(G(a)));return r.onError?.(d),b(d)}const S=ve(c,s,t.appName);if(T.debug(I,"runDockerBuild starting",{appName:t.appName,appPath:t.path,accountId:c,region:s,cdkOutPath:m,manifestServiceCount:p.length,manifestServices:p.map(a=>({name:a.name,path:a.docker.path,context:a.docker.context,target:a.docker.target})),stepId:C.DOCKER_OPERATIONS,stepName:D}),r.onStepStart?.(C.DOCKER_OPERATIONS,D),p.length===0){r.onLog?.("Initialising ECR repository\u2026","info");const a=await o.initialiseECR({appName:t.appName,region:s,accountId:c});a.success||r.onLog?.(`ECR initialisation failed: ${y(a.error.message)}`,"warn"),r.onLog?.("Building and pushing Docker image\u2026","info");const d=await Ee(o,t,s,c,e.abortSignal,r);if(!d.success){T.debug(I,"Docker buildAndPush (legacy) failed",{appName:t.appName,error:y(d.error.message)}),r.onStepComplete?.(C.DOCKER_OPERATIONS,D,"error");const B=new Error(y(d.error.message));return r.onError?.(B),b(B)}return r.onStepComplete?.(C.DOCKER_OPERATIONS,D,"completed"),r.onLog?.(`Docker image pushed: ${d.data.imageUri}`,"info"),P(M())}const E=await o.preflight?.();if(E!==void 0&&!E.success){r.onStepComplete?.(C.DOCKER_OPERATIONS,D,"error");const a=new Error(y(E.error.message));return r.onError?.(a),b(a)}const f=we(p,t.path,e.workingDirectory);let R=Se(c,s,t.appName);const k=await ge(n.awsProvider,V(L(t.appName)),e.abortSignal);k.success||(R=void 0,r.onLog?.(`Building without registry cache \u2014 ${k.error.message}`,"warn")),r.onLog?.(`Building and pushing ${p.length} service image(s) in ${f.length} group(s)\u2026`,"info");let l=!1;if(o.beginEcrSession!==void 0){const a=await o.beginEcrSession({accountId:c,region:s,...e.abortSignal!==void 0&&{abortSignal:e.abortSignal}});if(!a.success){r.onStepComplete?.(C.DOCKER_OPERATIONS,D,"error");const d=new Error(y(a.error.message));return r.onError?.(d),b(d)}l=!0}const w=new AbortController,$=g(()=>w.abort(),"onCallerAbort");e.abortSignal!==void 0&&(e.abortSignal.aborted?w.abort():e.abortSignal.addEventListener("abort",$,{once:!0}));try{const a=g(()=>W(e.abortSignal)?"the deployment was cancelled":"a sibling group failed","skipCause");let d;const B=ne(f.length),K=ee(),O=f.map((u,h)=>async()=>{const i=u.members.map(_=>_.name).join(", ");if(w.signal.aborted)throw new Error(`Build of group ${h+1}/${f.length} (${i}) was not started \u2014 ${a()}`);r.onLog?.(`Building group ${h+1}/${f.length} (${i})\u2026`,"info");const v=await ke(u,o,t,s,c,S,R,r,n.awsProvider,w.signal,e.options?.environment,e.options?.flagBuildArgs,e.options?.flagBuildSecrets,K);if(!v.success)throw d===void 0&&(d={error:v.error,leader:u.members[0]?.name,members:i}),w.abort(),v.error;return v.data}),x=await te(O,B,{abortOnFirstFailure:!0,abortSignal:w.signal});if(d===void 0)for(let u=0;u<f.length;u++){const h=x[u];if(!(h!==void 0&&h.success)){d={error:h!==void 0&&!h.success?h.error:new Error(`Build of group ${u+1}/${f.length} never ran \u2014 ${a()}`),leader:f[u].members[0]?.name,members:f[u].members.map(i=>i.name).join(", ")};break}}if(d!==void 0){T.debug(I,"Docker buildAndPush failed",{appName:t.appName,leader:d.leader,members:d.members,error:y(d.error.message)}),r.onStepComplete?.(C.DOCKER_OPERATIONS,D,"error");const u=new Error(y(d.error.message));return r.onError?.(u),b(u)}const A={},N={};for(const u of x)if(!(u===void 0||!u.success)){for(const[h,i]of Object.entries(u.data.contentHashTagsByService))A[h]=i;for(const[h,i]of Object.entries(u.data.imageDigestsByService))N[h]=i}return T.debug(I,"Docker buildAndPush succeeded",{appName:t.appName,services:p.map(u=>u.name),groupCount:f.length,contentHashTags:A}),r.onStepComplete?.(C.DOCKER_OPERATIONS,D,"completed"),r.onLog?.(`Docker images pushed for ${p.length} service(s)`,"info"),P({contentHashTagsByService:A,imageDigestsByService:N,repoUri:S})}finally{e.abortSignal?.removeEventListener("abort",$),l&&o.endEcrSession!==void 0&&await o.endEcrSession().catch(a=>{T.debug(I,"endEcrSession cleanup failed",{error:y(G(a))})})}}g(Me,"runDockerBuild");export{D as DOCKER_BUILD_STEP_NAME,ve as ecrRepoUri,M as emptyBuildProducts,Me as runDockerBuild};
|
|
1
|
+
var q=Object.defineProperty;var g=(e,n)=>q(e,"name",{value:n,configurable:!0});import{isAbsolute as V,join as F,dirname as Q,resolve as H}from"node:path";import{existsSync as M}from"node:fs";import{success as O,failure as f}from"@fjall/generator";import{deriveContentHashTag as Z,getErrorMessage as W,maskSensitiveOutput as y,toKebab as I}from"@fjall/util";import{evaluateBakeGuard as ee,evaluateResolvedBuildArgValues as re,acknowledgedBuildArgKeys as te,createBakeWarningDeduper as ne,buildCacheRepositoryName as z,dockerPlatformForArchitecture as ie,ECS_TASK_ARCHITECTURE as U,BAKE_GUARD_EXPOSURE_CLAUSE as oe}from"@fjall/util/docker";import{runWithBoundedConcurrency as se,resolveBuildConcurrency as ae}from"@fjall/util/buildConcurrency";import{logger as _}from"@fjall/util/logger";import{parseDockerServicesFromManifest as de,parseLambdaDockerServicesFromManifest as ce}from"@fjall/util/manifest";import{STEP_IDS as R}from"../../types/stepDefinitions.js";import{isAborted as J}from"../../aws/organisations/types.js";import{resolveBuildSecrets as ue,resolveSecretRefValue as le,resolveBuildSecretSessionProvider as fe,sourcedRefsFromBuildArgs as me}from"./buildSecretResolver.js";import{partitionForRegion as ge}from"./buildSecretSession.js";import{resolveBuildArgs as pe}from"./buildArgResolver.js";import{validateBuildGroup as he}from"./buildGroupValidator.js";import{ensureBuildCacheRepository as be}from"./ecrCacheRepository.js";const K="dockerBuildHelper",D="Building and pushing Docker image";function Se(e,n,t){const r=F(n,e);if(M(r))return{path:r,base:n};if(t!==""&&t!==n){const i=F(t,e);if(M(i))return{path:i,base:t}}return{path:r,base:n}}g(Se,"resolveAgainstBases");function ye(e,n,t){const r=e.docker.path,i=e.docker.context;let c,s;if(V(r))c=r,s=n;else{const h=Se(r,n,t);c=h.path,s=h.base}return{buildContext:i?V(i)?H(i):H(s,i):H(Q(c)),dockerfilePath:c,target:e.docker.target,resolvedViaFallback:s!==n}}g(ye,"resolveBuildIdentity");function ve(e){return`${e.buildContext}|${e.dockerfilePath}|${e.target??""}`}g(ve,"buildIdentityKey");function Ee(e,n){return`Dockerfile not found for service '${e}' at ${n}. Checked the synth directory and the working directory. If your Dockerfile lives at the project root with the CDK app in a subdirectory, set an absolute docker.context (the build context must share the Dockerfile's directory).`}g(Ee,"dockerfileNotFoundMessage");function we(e){return e.startsWith("cn-")?"amazonaws.com.cn":"amazonaws.com"}g(we,"ecrDnsSuffix");function X(e,n){return`${e}.dkr.ecr.${n}.${we(n)}`}g(X,"ecrRegistryHost");function ke(e,n,t){return`${X(e,n)}/${I(t)}`}g(ke,"ecrRepoUri");function Ae(e,n,t){return`${X(e,n)}/${z(I(t))}`}g(Ae,"ecrCacheRepoUri");function Ce(e,n,t){const r=new Map;for(const i of e){const c=ye(i,n,t),s=ve(c),p=r.get(s);p?p.members.push(i):r.set(s,{identity:c,members:[i]})}return Array.from(r.values())}g(Ce,"groupServicesByIdentity");async function Re(e,n,t,r,i,c){const s=await e.buildAndPush({appName:n.appName,appPath:n.path,region:t,accountId:r,...i!==void 0&&{abortSignal:i}},(p,h,v,w)=>{c.onDockerProgress?.(y(p),h,v,w)});return s.success?O({imageUri:s.data.imageUri,imageTag:s.data.imageTag}):f(s.error)}g(Re,"buildLegacyFallback");function G(){return{contentHashTagsByService:{},imageDigestsByService:{}}}g(G,"emptyBuildProducts");async function De(e,n,t,r,i,c,s,p,h,v,w,m,A,k){const l=e.members[0];if(!M(e.identity.dockerfilePath))return f(new Error(Ee(l.name,e.identity.dockerfilePath)));e.identity.resolvedViaFallback&&p.onLog?.(`Building service '${l.name}' from ${e.identity.dockerfilePath} (resolved at the project root).`,"info");const E=[...l.docker.buildSecrets??[],...A??[]],L=he({serviceName:l.name,dockerfilePath:e.identity.dockerfilePath,buildContext:e.identity.buildContext,...e.identity.target!==void 0&&{target:e.identity.target},...l.docker.buildArgs!==void 0&&{buildArgs:l.docker.buildArgs},...E.length>0&&{buildSecrets:E},members:e.members.map(o=>({serviceName:o.name,...o.docker.buildArgs!==void 0&&{buildArgs:o.docker.buildArgs},...o.docker.buildSecrets!==void 0&&{buildSecrets:o.docker.buildSecrets}}))});if(!L.success)return f(L.error);const a=ee(l.docker.buildArgs,I(t.appName));for(const o of a.warnings){const S=y(o.message);k(S)&&p.onLog?.(S,"warn")}if(a.findings.length>0)return f(new Error(y(a.findings.map(o=>o.message).join(" "))));const d=E,N=me(l.docker.buildArgs),j={appName:t.appName,region:r,accountId:i,partition:ge(r)},x=await fe(h,[...d,...N],j);if(!x.success)return f(x.error);const T=x.data,C=await pe({manifestBuildArgs:l.docker.buildArgs,serviceDir:e.identity.buildContext,appDir:t.path,...w!==void 0&&{stage:w},shellEnv:process.env,...m!==void 0&&{flagBuildArgs:m},resolveSourcedValue:g((o,S)=>le(T,{id:o,...S},v),"resolveSourcedValue")});if(!C.success)return f(C.error);const P=C.data.buildArgs;for(const o of C.data.inferredDotenvKeys){const S=y(`buildArg "${o}" was auto-declared from a .env file and will be baked into the image \u2014 ${oe}.`);k(S)&&p.onLog?.(S,"warn")}const u=re(P,I(t.appName),te(l.docker.buildArgs));if(u.length>0)return f(new Error(y(u.map(o=>o.message).join(" "))));let b;if(d.length>0){const o=await ue(T,d,v);if(!o.success)return f(o.error);b=o.data}try{if(J(v))return f(new Error(`Build of service '${l.name}' was aborted before the docker build started`));const o=e.members.some($=>$.isLambda===!0),S=new Set(e.members.map($=>$.architecture).filter($=>$!==void 0));if(S.size>1)return f(new Error(`Build group for '${l.name}' contains Lambda members targeting different architectures (${Array.from(S).join(", ")}) \u2014 members sharing one Dockerfile/context/target build as a single image and must agree on \`architecture\`. Give the differing Lambda a distinct docker.path/context/target, or align their \`architecture\` props.`));const[B]=S;if(e.members.some($=>$.isLambda!==!0)&&B!==void 0&&B!==U)return f(new Error(`Build group for '${l.name}' declares Lambda architecture '${B}' but also contains ECS service members \u2014 fjall ECS tasks always run on '${U}', so an image shared between ECS and Lambda must build for '${U}'. Give the Lambda a distinct docker.path/context/target, or align its \`architecture\` prop.`));const Y={appName:t.appName,appPath:e.identity.buildContext,region:r,accountId:i,buildContext:e.identity.buildContext,dockerfilePath:e.identity.dockerfilePath,pushByDigest:!0,serviceName:l.name,targetsLambda:o,...B!==void 0&&{platform:ie(B)},...s!==void 0&&{cacheRepoUri:s},...e.identity.target!==void 0&&{target:e.identity.target},...Object.keys(P).length>0&&{buildArgs:P},...b!==void 0&&{buildSecrets:b.resolved},...v!==void 0&&{abortSignal:v}};return await Be(e,Y,n,c,p)}finally{b!==void 0&&await b.cleanup().catch(()=>p.onLog?.("Build-secret cleanup failed.","warn"))}}g(De,"buildGroup");async function Be(e,n,t,r,i){const c=await t.buildAndPush(n,(m,A,k,l)=>{i.onDockerProgress?.(y(m),A,k,l)});if(!c.success)return f(c.error);const s=c.data.imageDigest;if(typeof s!="string"||!s.startsWith("sha256:"))return f(new Error(`Buildx push succeeded but returned an invalid digest: ${y(String(s))}`));const p={},h={},v=[];for(const m of e.members){const A=m.docker.target,k=Z(s,m.name,A);if(!k.success)return f(k.error);const l=k.data,E=m.name;p[E]=l,h[E]=s,v.push(`${r}:${l}`)}const w=await t.tagByDigest({sourceImage:r,digest:s,tags:v});return w.success?O({contentHashTagsByService:p,imageDigestsByService:h}):f(w.error)}g(Be,"buildGroupWithParams");function $e(e,n){const t=new Map(e.map(r=>[r.name,r]));for(const r of n){const i=t.get(r.name);if(i!==void 0&&JSON.stringify(i.docker)!==JSON.stringify(r.docker))throw new Error(`ECS service "${i.name}" and Lambda image key "${r.name}" share one build key but declare different docker configs \u2014 the second build would silently overwrite the first and both would deploy the same image. Rename one of them, or make the docker configs identical to deliberately share the build.`)}}g($e,"assertNoCrossEntityBuildKeyDivergence");async function ze(e,n,t,r){const i=e.dockerProvider;if(!i)return O(G());const c=n.awsProvider.getAccountId();if(!c)return r.onLog?.("Skipping Docker build \u2014 account ID not available","warn"),O(G());const s=n.awsProvider.getRegion(),p=F(t.path,"cdk.out");let h;try{const a=de(p),d=ce(p);$e(a,d),h=[...a,...d]}catch(a){const d=new Error(y(W(a)));return r.onError?.(d),f(d)}const v=ke(c,s,t.appName);if(_.debug(K,"runDockerBuild starting",{appName:t.appName,appPath:t.path,accountId:c,region:s,cdkOutPath:p,manifestServiceCount:h.length,manifestServices:h.map(a=>({name:a.name,path:a.docker.path,context:a.docker.context,target:a.docker.target})),stepId:R.DOCKER_OPERATIONS,stepName:D}),r.onStepStart?.(R.DOCKER_OPERATIONS,D),h.length===0){r.onLog?.("Initialising ECR repository\u2026","info");const a=await i.initialiseECR({appName:t.appName,region:s,accountId:c});a.success||r.onLog?.(`ECR initialisation failed: ${y(a.error.message)}`,"warn"),r.onLog?.("Building and pushing Docker image\u2026","info");const d=await Re(i,t,s,c,e.abortSignal,r);if(!d.success){_.debug(K,"Docker buildAndPush (legacy) failed",{appName:t.appName,error:y(d.error.message)}),r.onStepComplete?.(R.DOCKER_OPERATIONS,D,"error");const N=new Error(y(d.error.message));return r.onError?.(N),f(N)}return r.onStepComplete?.(R.DOCKER_OPERATIONS,D,"completed"),r.onLog?.(`Docker image pushed: ${d.data.imageUri}`,"info"),O(G())}const w=await i.preflight?.();if(w!==void 0&&!w.success){r.onStepComplete?.(R.DOCKER_OPERATIONS,D,"error");const a=new Error(y(w.error.message));return r.onError?.(a),f(a)}const m=Ce(h,t.path,e.workingDirectory);let A=Ae(c,s,t.appName);const k=await be(n.awsProvider,z(I(t.appName)),e.abortSignal);k.success||(A=void 0,r.onLog?.(`Building without registry cache \u2014 ${k.error.message}`,"warn")),r.onLog?.(`Building and pushing ${h.length} service image(s) in ${m.length} group(s)\u2026`,"info");let l=!1;if(i.beginEcrSession!==void 0){const a=await i.beginEcrSession({accountId:c,region:s,...e.abortSignal!==void 0&&{abortSignal:e.abortSignal}});if(!a.success){r.onStepComplete?.(R.DOCKER_OPERATIONS,D,"error");const d=new Error(y(a.error.message));return r.onError?.(d),f(d)}l=!0}const E=new AbortController,L=g(()=>E.abort(),"onCallerAbort");e.abortSignal!==void 0&&(e.abortSignal.aborted?E.abort():e.abortSignal.addEventListener("abort",L,{once:!0}));try{const a=g(()=>J(e.abortSignal)?"the deployment was cancelled":"a sibling group failed","skipCause");let d;const N=ae(m.length),j=ne(),x=m.map((u,b)=>async()=>{const o=u.members.map(B=>B.name).join(", ");if(E.signal.aborted)throw new Error(`Build of group ${b+1}/${m.length} (${o}) was not started \u2014 ${a()}`);r.onLog?.(`Building group ${b+1}/${m.length} (${o})\u2026`,"info");const S=await De(u,i,t,s,c,v,A,r,n.awsProvider,E.signal,e.options?.environment,e.options?.flagBuildArgs,e.options?.flagBuildSecrets,j);if(!S.success)throw d===void 0&&(d={error:S.error,leader:u.members[0]?.name,members:o}),E.abort(),S.error;return S.data}),T=await se(x,N,{abortOnFirstFailure:!0,abortSignal:E.signal});if(d===void 0)for(let u=0;u<m.length;u++){const b=T[u];if(!(b!==void 0&&b.success)){d={error:b!==void 0&&!b.success?b.error:new Error(`Build of group ${u+1}/${m.length} never ran \u2014 ${a()}`),leader:m[u].members[0]?.name,members:m[u].members.map(o=>o.name).join(", ")};break}}if(d!==void 0){_.debug(K,"Docker buildAndPush failed",{appName:t.appName,leader:d.leader,members:d.members,error:y(d.error.message)}),r.onStepComplete?.(R.DOCKER_OPERATIONS,D,"error");const u=new Error(y(d.error.message));return r.onError?.(u),f(u)}const C={},P={};for(const u of T)if(!(u===void 0||!u.success)){for(const[b,o]of Object.entries(u.data.contentHashTagsByService))C[b]=o;for(const[b,o]of Object.entries(u.data.imageDigestsByService))P[b]=o}return _.debug(K,"Docker buildAndPush succeeded",{appName:t.appName,services:h.map(u=>u.name),groupCount:m.length,contentHashTags:C}),r.onStepComplete?.(R.DOCKER_OPERATIONS,D,"completed"),r.onLog?.(`Docker images pushed for ${h.length} service(s)`,"info"),O({contentHashTagsByService:C,imageDigestsByService:P,repoUri:v})}finally{e.abortSignal?.removeEventListener("abort",L),l&&i.endEcrSession!==void 0&&await i.endEcrSession().catch(a=>{_.debug(K,"endEcrSession cleanup failed",{error:y(W(a))})})}}g(ze,"runDockerBuild");export{D as DOCKER_BUILD_STEP_NAME,ke as ecrRepoUri,G as emptyBuildProducts,ze as runDockerBuild};
|
|
@@ -146,9 +146,12 @@ export interface TagImagesResult {
|
|
|
146
146
|
/** Callback for Docker build/push progress reporting. */
|
|
147
147
|
export type DockerProgressCallback = (message: string, percentage?: number, layerId?: string, status?: string) => void;
|
|
148
148
|
/**
|
|
149
|
-
* Parameters for adding
|
|
150
|
-
*
|
|
151
|
-
*
|
|
149
|
+
* Parameters for adding tags to an already-pushed image digest without
|
|
150
|
+
* re-uploading layers. Used by the orchestrator to apply the content-hash
|
|
151
|
+
* tag derived from a buildx push. Implementations must carbon-copy the
|
|
152
|
+
* source's flat manifest (not wrap it in a new image index) — Lambda
|
|
153
|
+
* rejects an index outright, and fjall never combines multiple
|
|
154
|
+
* platform-specific digests under one tag here.
|
|
152
155
|
*/
|
|
153
156
|
export interface TagByDigestParams {
|
|
154
157
|
/** Fully-qualified ECR repository URI without a tag suffix. */
|
|
@@ -199,9 +202,10 @@ export interface DockerProvider {
|
|
|
199
202
|
buildAndPush(params: DockerBuildParams, onProgress?: DockerProgressCallback, onBuildxEvent?: (event: BuildxProgressEvent) => void): Promise<Result<DockerBuildResult>>;
|
|
200
203
|
initialiseECR(params: ECRInitParams): Promise<Result<ECRInitResult>>;
|
|
201
204
|
/**
|
|
202
|
-
* Apply additional
|
|
203
|
-
* orchestrator uses this to attach the
|
|
204
|
-
* after `buildAndPush` returns, without
|
|
205
|
+
* Apply additional tags to a pushed digest, as a flat-manifest carbon
|
|
206
|
+
* copy (never an image index). The orchestrator uses this to attach the
|
|
207
|
+
* content-hash tag immediately after `buildAndPush` returns, without
|
|
208
|
+
* re-uploading layers.
|
|
205
209
|
*/
|
|
206
210
|
tagByDigest(params: TagByDigestParams): Promise<Result<void>>;
|
|
207
211
|
/** Tag existing ECR images for ECS services (non-Dockerfile apps). Optional. */
|
|
@@ -7,6 +7,14 @@ import type { DelegatedDomainDeployer } from "./domain/delegatedDomainDeploy.js"
|
|
|
7
7
|
export interface DomainConfig {
|
|
8
8
|
name: string;
|
|
9
9
|
type: "apex" | "delegated";
|
|
10
|
+
/**
|
|
11
|
+
* Config-declared parent zone of a delegated entry. `deployDomains`
|
|
12
|
+
* orders delegated entries into parent-first waves on this key: a parent
|
|
13
|
+
* that is itself a delegated entry in the same cascade must publish its
|
|
14
|
+
* delegation-role export before its children deploy. Absent (or naming a
|
|
15
|
+
* zone outside the entry set): no intra-cascade ordering edge - wave 0.
|
|
16
|
+
*/
|
|
17
|
+
parentDomain?: string;
|
|
10
18
|
/**
|
|
11
19
|
* Self-recorded home: the 12-digit AWS account id (and region) the last
|
|
12
20
|
* successful deploy of this domain ran in, from the provider's config
|
|
@@ -4,7 +4,7 @@ import type { OrgConfig } from "../../types/config/orgConfig.js";
|
|
|
4
4
|
import type { DeployCallbacks } from "../../types/callbacks.js";
|
|
5
5
|
import type { OrganisationOperation } from "../../types/operations.js";
|
|
6
6
|
import type { DeployServices } from "../serviceFactory.js";
|
|
7
|
-
import type { DomainDeployProvider } from "../domainInterface.js";
|
|
7
|
+
import type { DomainConfig, DomainDeployProvider } from "../domainInterface.js";
|
|
8
8
|
import type { ProviderAccount } from "@fjall/util/config";
|
|
9
9
|
/**
|
|
10
10
|
* Max member accounts deployed/destroyed in parallel during a cascade. Each
|
|
@@ -148,9 +148,23 @@ export interface DeployDomainsOptions {
|
|
|
148
148
|
executingAccountId?: string;
|
|
149
149
|
executingRegion?: string;
|
|
150
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Order delegated domains into parent-first topological waves keyed on
|
|
153
|
+
* `parentDomain` depth WITHIN the supplied set: a delegated entry whose
|
|
154
|
+
* parent is another delegated entry deploys one wave after it (the parent
|
|
155
|
+
* must publish its delegation-role export before the child's NS delegation
|
|
156
|
+
* can be written). Parents outside the set - apex, foreign-account-skipped,
|
|
157
|
+
* unregistered or externally-owned - carry no intra-set ordering edge, so
|
|
158
|
+
* their children sit in wave 0; a flat topology therefore collapses to a
|
|
159
|
+
* single wave (today's behaviour). A `parentDomain` cycle has no valid
|
|
160
|
+
* order: fail closed naming the cycle so the caller can refuse pre-AWS.
|
|
161
|
+
* Input order is preserved within each wave.
|
|
162
|
+
*/
|
|
163
|
+
export declare function planDelegatedDomainWaves(delegatedDomains: readonly DomainConfig[]): Result<DomainConfig[][], Error>;
|
|
151
164
|
/**
|
|
152
165
|
* Deploy configured domains: apex domains sequentially, then delegated
|
|
153
|
-
* domains in
|
|
166
|
+
* domains in parent-first topological waves (parallel within a wave).
|
|
167
|
+
* Delegates to the caller-provided DomainDeployProvider.
|
|
154
168
|
*/
|
|
155
169
|
export declare function deployDomains(provider: DomainDeployProvider, callbacks: DeployCallbacks, options?: DeployDomainsOptions): Promise<{
|
|
156
170
|
domainsDeployed: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var z=Object.defineProperty;var p=(e,t)=>z(e,"name",{value:t,configurable:!0});import{join as B}from"path";import{success as M,failure as y}from"@fjall/generator";import{logger as $}from"@fjall/util/logger";import{maskSensitiveOutput as C,mapSettledWithConcurrency as Y}from"@fjall/util";import{ORGANISATION_TYPES as w,getOrganisationStackName as T}from"../../types/operations.js";import{CdkContextBuilder as W}from"../../services/supporting/CdkContextBuilder.js";import{stubCallerIdentity as X}from"../../types/deployment/index.js";import{CloudFormationService as H}from"../../services/infrastructure/CloudFormationService.js";import{getCascadeStateFilePath as q,regionSuffix as J}from"../../types/config/FjallState.js";import{BackupClient as Q}from"@aws-sdk/client-backup";import{accountHasDisasterRecovery as Z,describeBackupVaultExists as ee}from"../../aws/organisations/backup.js";import{buildParamsContext as te,collectStackOutputs as V,assumeCascadeRole as I,forwardOutput as E,reconcileOidcProviderIfCarried as G}from"../contextHelpers.js";import{assertLeaseBeforeStack as oe}from"../application/leaseGate.js";import{deployDelegatedDomain as ne}from"../domain/delegatedDomainDeploy.js";import{runDriftPreFlightGate as re}from"../drift/preFlightGate.js";import{accountTier as U}from"@fjall/util";import{buildBootstrapTagsIfResolved as ae}from"../bootstrapTags.js";import{hasOrganisationTierAccount as ie}from"../../aws/organisations/accountGlobals.js";import{DEFAULT_REGION as _}from"../../aws/utils/regions.js";const se=4;function Ee(e){const t=e.find(o=>U(o)==="platform"),u=e.filter(o=>U(o)==="account");return{platformAccount:t,memberAccounts:u}}p(Ee,"partitionAccounts");function ce(e){const t=e?.primaryRegion??_,u=e?.secondaryRegions??[],o=new Set([t,...u]),s=e?.disasterRecoveryRegion;return s&&o.add(s),[...o]}p(ce,"buildRegionList");function be(e){return ce(e)[0]??_}p(be,"cascadeHomeRegion");function ue(e,t){return`${e} (${t})`}p(ue,"cascadeOperationKey");function Fe(e,t){const u=[];for(const o of t)for(const s of e)u.push({account:s,region:o});return u}p(Fe,"buildAccountRegionPairs");import{buildCascadeRoleArn as He}from"../contextHelpers.js";async function Ne(e,t,u,o){u.onLog?.(`Verifying cascade role access for ${t.length} account(s)\u2026`,"info");const s=await Y(t,se,async i=>I(e.awsProvider,i.id,i.region??e.awsProvider.getRegion(),`fjall-preflight-${i.name}`,o)),n=[];return s.forEach((i,r)=>{const a=t[r];if(a){if(i.status==="rejected"){n.push({accountId:a.id,accountName:a.name,error:i.reason instanceof Error?i.reason.message:String(i.reason)});return}i.value.success||n.push({accountId:a.id,accountName:a.name,error:i.value.error.message})}}),n.length===0&&u.onLog?.(`Cascade role access verified for ${t.length} account(s)`,"info"),n}p(Ne,"probeCascadeRoles");async function je(e,t,u,o,s,n,i){const r=i?.region??o.region??t.awsProvider.getRegion(),a=ue(o.name,r),l=i?.orgConfig??e.orgConfig,f=i?.ipamPoolId;n.onCascadeAccountStart?.(a,o.id,r,s);const c=await I(t.awsProvider,o.id,r,`fjall-cascade-${o.name}`,e.abortSignal);if(!c.success)return n.onCascadeAccountComplete?.(a,!1,C(c.error.message),r),y(new Error(`Failed to assume role for ${o.name}: ${C(c.error.message)}`));const{provider:d,credentials:h}=c.data,R=B(e.workingDirectory,"fjall",s==="platform"?w.PLATFORM:w.ACCOUNT),A=B(R,`cdk.out.${o.id}.${J(r)}`),S=W.buildDeploymentContext({deployType:s,target:u.target,path:R,assemblyDir:A,environment:o.environment??void 0,region:r,accountName:o.name,callerIdentity:X(o.id),ipamPoolId:f,...te({orgConfig:l,identity:e.identity,skipOidc:e.options?.skipOidc,region:r,primaryRegion:i?.primaryRegion,trailLifecycle:o.trailLifecycle})},{verbose:e.options?.verbose},l);if(Z(o.environment,l?.disasterRecoveryRegion)){const m=await ee(d.getClient(Q),e.abortSignal);if(!m.success)return n.onCascadeAccountComplete?.(a,!1,C(m.error.message),r),y(new Error(`Backup vault probe failed for ${o.name}: ${C(m.error.message)}`));S.fjallAdoptBackupVault=m.data}n.onCascadeAccountPhaseChange?.(a,"synth",r);const O=await t.cdkService.runCdkSynth(S,E(n),h);if(!O.success)return n.onCascadeAccountComplete?.(a,!1,C(`Synth failed: ${O.error}`),r),y(new Error(`Synth failed for ${o.name}: ${C(O.error)}`));const g=T(s==="platform"?w.PLATFORM:w.ACCOUNT),b=q(R,o.id,r),P=new H(d),{changed:K,currentHash:F}=await t.hashService.compareCascadeStack(A,g,b);if(!K&&e.options?.force!==!0&&await P.stackExists(g,void 0,e.abortSignal)){const m=await P.getStackOutputs(g,void 0,e.abortSignal);m.success||$.debug("cascadeHelpers","Failed to read outputs for skipped cascade account (non-critical)",{stackName:g,account:o.name});const L=V(m);return await G(S,d,n,e.abortSignal),n.onLog?.(`${o.name}: no infrastructure changes \u2014 skipping deploy`,"info"),n.onCascadeAccountComplete?.(a,!0,void 0,r,L,!0),M({outputs:L,skipped:!0})}const k=await re(d,{stackNames:[g],cdkOutPath:A,cfnService:P,callbacks:n,...e.abortSignal!==void 0?{abortSignal:e.abortSignal}:{}});if(k.kind==="blocked")return n.onCascadeAccountComplete?.(a,!1,k.message,r),y(new Error(k.message));const x=await oe(e.assertLeaseForStack,g,e.abortSignal);if(x!==void 0)return n.onCascadeAccountComplete?.(a,!1,x.message,r),y(x);n.onCascadeAccountPhaseChange?.(a,"bootstrap",r);const v=await t.cdkService.runCdkBootstrap(S,E(n),h,void 0,ae({account:o,estate:ie(l?.providerAccounts)?"org":"solo",...i?.orgId!==void 0?{orgId:i.orgId}:{}}));if(!v.success)return n.onCascadeAccountComplete?.(a,!1,C(`Bootstrap failed: ${v.error}`),r),y(new Error(`Bootstrap failed for ${o.name}: ${C(v.error)}`));n.onCascadeAccountPhaseChange?.(a,"deploy",r);const D=await t.cdkService.runCdkDeploy(S,g,E(n),m=>n.onCascadeAccountResourceProgress?.(a,m,r),d,h);if(!D.success)return n.onCascadeAccountComplete?.(a,!1,C(D.error),r),y(new Error(C(D.error)));const N=await P.getStackOutputs(g,void 0,e.abortSignal);N.success||$.debug("cascadeHelpers","Failed to read cascade account stack outputs (non-critical)",{stackName:g,account:o.name});const j=V(N);return await G(S,d,n,e.abortSignal),F!==void 0&&((await t.hashService.persistCascadeStack(b,g,F)).success||$.debug("cascadeHelpers","Failed to persist cascade hash state (non-critical)",{stackName:g,account:o.name})),n.onCascadeAccountComplete?.(a,!0,void 0,r,j,!1),M({outputs:j,skipped:!1})}p(je,"deployCascadeAccount");async function Le(e,t,u,o){const s=new Map,n=e.awsProvider.getRegion(),i=await I(e.awsProvider,t.id,n,`fjall-ipam-read-${t.name}`,o);if(!i.success)return $.debug("organisationDeploy",`Cannot read Platform outputs: ${i.error.message}`),s;const r=new H(i.data.provider),a=T(w.PLATFORM),l=await r.getStackOutputs(a);if(!l.success)return $.debug("organisationDeploy",`Failed to read Platform stack outputs: ${l.error.message}`),s;const f=/^IpamPoolId(\d{12})(\w+)$/;for(const c of l.data){const d=c.OutputKey?.match(f);if(d&&c.OutputValue){const h=`${d[1]}-${d[2]}`;s.set(h,c.OutputValue)}}return s.size>0&&u.onLog?.(`Read ${s.size} IPAM pool ID(s) from Platform stack`,"info"),s}p(Le,"readPlatformIpamPoolIds");function de(e,t){const u=e.account!==void 0&&t?.executingAccountId!==void 0&&e.account!==t.executingAccountId,o=e.region!==void 0&&t?.executingRegion!==void 0&&e.region!==t.executingRegion;if(u)return`[${e.name}] skipped: its fjall-config.json entry records account ${e.account} as its home, but this cascade runs in account ${t?.executingAccountId} - deploy it separately with 'fjall domain deploy ${e.name} -t <target in account ${e.account}>' or run the cascade under that account.`;if(o)return`[${e.name}] skipped: its fjall-config.json entry records region ${e.region} as its home, but this cascade runs in region ${t?.executingRegion} - deploy it separately with 'fjall domain deploy ${e.name} --region ${e.region}', or update the entry's "region" key if this move is intentional.`}p(de,"foreignDomainSkipReason");async function Be(e,t,u){const o=e.getDomains();if(o.length===0)return{domainsDeployed:0,domainsSkipped:0,errors:[]};t.onCascadePhaseStart?.("domains");const s=[];let n=0;for(const f of o){const c=de(f,u);if(c!==void 0){n++,t.onProgress?.({type:"warning",message:c});continue}s.push(f)}const i=s.filter(f=>f.type==="apex"),r=s.filter(f=>f.type==="delegated");let a=0;const l=[];for(const f of i){const c=await e.deployDomain(f.name,t);c.success?a++:l.push(`${f.name}: ${c.error.message}`)}if(r.length>0){const f=await Promise.allSettled(r.map(c=>{const d=e.delegatedDeployer?.(c.name);return d!==void 0?ne({deployer:d,callbacks:t,...u?.abortSignal!==void 0?{abortSignal:u.abortSignal}:{},...u?.skipCaaPreflight!==void 0?{skipCaaPreflight:u.skipCaaPreflight}:{}}):e.deployDomain(c.name,t)}));for(let c=0;c<f.length;c++){const d=f[c],h=r[c];if(!(!d||!h))if(d.status==="fulfilled")d.value.success?a++:l.push(`${h.name}: ${d.value.error.message}`);else{const R=d.reason instanceof Error?d.reason.message:String(d.reason);l.push(`${h.name}: ${R}`)}}}return t.onCascadePhaseComplete?.("domains"),{domainsDeployed:a,domainsSkipped:n,errors:l}}p(Be,"deployDomains");export{se as CASCADE_MAX_CONCURRENCY,Fe as buildAccountRegionPairs,He as buildCascadeRoleArn,ce as buildRegionList,be as cascadeHomeRegion,ue as cascadeOperationKey,je as deployCascadeAccount,Be as deployDomains,Ee as partitionAccounts,Ne as probeCascadeRoles,Le as readPlatformIpamPoolIds};
|
|
1
|
+
var z=Object.defineProperty;var g=(e,o)=>z(e,"name",{value:o,configurable:!0});import{join as T}from"path";import{success as I,failure as w}from"@fjall/generator";import{logger as P}from"@fjall/util/logger";import{maskSensitiveOutput as S,mapSettledWithConcurrency as Y}from"@fjall/util";import{ORGANISATION_TYPES as A,getOrganisationStackName as H}from"../../types/operations.js";import{CdkContextBuilder as X}from"../../services/supporting/CdkContextBuilder.js";import{stubCallerIdentity as q}from"../../types/deployment/index.js";import{CloudFormationService as V}from"../../services/infrastructure/CloudFormationService.js";import{getCascadeStateFilePath as J,regionSuffix as Q}from"../../types/config/FjallState.js";import{BackupClient as Z}from"@aws-sdk/client-backup";import{accountHasDisasterRecovery as ee,describeBackupVaultExists as te}from"../../aws/organisations/backup.js";import{buildParamsContext as oe,collectStackOutputs as G,assumeCascadeRole as N,forwardOutput as E,reconcileOidcProviderIfCarried as U}from"../contextHelpers.js";import{assertLeaseBeforeStack as ne}from"../application/leaseGate.js";import{deployDelegatedDomain as re}from"../domain/delegatedDomainDeploy.js";import{normaliseRecordName as j}from"../domain/zoneClassifier.js";import{runDriftPreFlightGate as ae}from"../drift/preFlightGate.js";import{accountTier as _}from"@fjall/util";import{buildBootstrapTagsIfResolved as se}from"../bootstrapTags.js";import{hasOrganisationTierAccount as ie}from"../../aws/organisations/accountGlobals.js";import{DEFAULT_REGION as K}from"../../aws/utils/regions.js";const ce=4;function be(e){const o=e.find(n=>_(n)==="platform"),c=e.filter(n=>_(n)==="account");return{platformAccount:o,memberAccounts:c}}g(be,"partitionAccounts");function de(e){const o=e?.primaryRegion??K,c=e?.secondaryRegions??[],n=new Set([o,...c]),i=e?.disasterRecoveryRegion;return i&&n.add(i),[...n]}g(de,"buildRegionList");function Fe(e){return de(e)[0]??K}g(Fe,"cascadeHomeRegion");function ue(e,o){return`${e} (${o})`}g(ue,"cascadeOperationKey");function Le(e,o){const c=[];for(const n of o)for(const i of e)c.push({account:i,region:n});return c}g(Le,"buildAccountRegionPairs");import{buildCascadeRoleArn as Ue}from"../contextHelpers.js";async function Be(e,o,c,n){c.onLog?.(`Verifying cascade role access for ${o.length} account(s)\u2026`,"info");const i=await Y(o,ce,async a=>N(e.awsProvider,a.id,a.region??e.awsProvider.getRegion(),`fjall-preflight-${a.name}`,n)),t=[];return i.forEach((a,s)=>{const r=o[s];if(r){if(a.status==="rejected"){t.push({accountId:r.id,accountName:r.name,error:a.reason instanceof Error?a.reason.message:String(a.reason)});return}a.value.success||t.push({accountId:r.id,accountName:r.name,error:a.value.error.message})}}),t.length===0&&c.onLog?.(`Cascade role access verified for ${o.length} account(s)`,"info"),t}g(Be,"probeCascadeRoles");async function Me(e,o,c,n,i,t,a){const s=a?.region??n.region??o.awsProvider.getRegion(),r=ue(n.name,s),u=a?.orgConfig??e.orgConfig,m=a?.ipamPoolId;t.onCascadeAccountStart?.(r,n.id,s,i);const p=await N(o.awsProvider,n.id,s,`fjall-cascade-${n.name}`,e.abortSignal);if(!p.success)return t.onCascadeAccountComplete?.(r,!1,S(p.error.message),s),w(new Error(`Failed to assume role for ${n.name}: ${S(p.error.message)}`));const{provider:d,credentials:f}=p.data,C=T(e.workingDirectory,"fjall",i==="platform"?A.PLATFORM:A.ACCOUNT),l=T(C,`cdk.out.${n.id}.${Q(s)}`),y=X.buildDeploymentContext({deployType:i,target:c.target,path:C,assemblyDir:l,environment:n.environment??void 0,region:s,accountName:n.name,callerIdentity:q(n.id),ipamPoolId:m,...oe({orgConfig:u,identity:e.identity,skipOidc:e.options?.skipOidc,region:s,primaryRegion:a?.primaryRegion,trailLifecycle:n.trailLifecycle})},{verbose:e.options?.verbose},u);if(ee(n.environment,u?.disasterRecoveryRegion)){const R=await te(d.getClient(Z),e.abortSignal);if(!R.success)return t.onCascadeAccountComplete?.(r,!1,S(R.error.message),s),w(new Error(`Backup vault probe failed for ${n.name}: ${S(R.error.message)}`));y.fjallAdoptBackupVault=R.data}t.onCascadeAccountPhaseChange?.(r,"synth",s);const $=await o.cdkService.runCdkSynth(y,E(t),f);if(!$.success)return t.onCascadeAccountComplete?.(r,!1,S(`Synth failed: ${$.error}`),s),w(new Error(`Synth failed for ${n.name}: ${S($.error)}`));const h=H(i==="platform"?A.PLATFORM:A.ACCOUNT),b=J(C,n.id,s),D=new V(d),{changed:W,currentHash:F}=await o.hashService.compareCascadeStack(l,h,b);if(!W&&e.options?.force!==!0&&await D.stackExists(h,void 0,e.abortSignal)){const R=await D.getStackOutputs(h,void 0,e.abortSignal);R.success||P.debug("cascadeHelpers","Failed to read outputs for skipped cascade account (non-critical)",{stackName:h,account:n.name});const M=G(R);return await U(y,d,t,e.abortSignal),t.onLog?.(`${n.name}: no infrastructure changes \u2014 skipping deploy`,"info"),t.onCascadeAccountComplete?.(r,!0,void 0,s,M,!0),I({outputs:M,skipped:!0})}const v=await ae(d,{stackNames:[h],cdkOutPath:l,cfnService:D,callbacks:t,...e.abortSignal!==void 0?{abortSignal:e.abortSignal}:{}});if(v.kind==="blocked")return t.onCascadeAccountComplete?.(r,!1,v.message,s),w(new Error(v.message));const O=await ne(e.assertLeaseForStack,h,e.abortSignal);if(O!==void 0)return t.onCascadeAccountComplete?.(r,!1,O.message,s),w(O);t.onCascadeAccountPhaseChange?.(r,"bootstrap",s);const x=await o.cdkService.runCdkBootstrap(y,E(t),f,void 0,se({account:n,estate:ie(u?.providerAccounts)?"org":"solo",...a?.orgId!==void 0?{orgId:a.orgId}:{}}));if(!x.success)return t.onCascadeAccountComplete?.(r,!1,S(`Bootstrap failed: ${x.error}`),s),w(new Error(`Bootstrap failed for ${n.name}: ${S(x.error)}`));t.onCascadeAccountPhaseChange?.(r,"deploy",s);const k=await o.cdkService.runCdkDeploy(y,h,E(t),R=>t.onCascadeAccountResourceProgress?.(r,R,s),d,f);if(!k.success)return t.onCascadeAccountComplete?.(r,!1,S(k.error),s),w(new Error(S(k.error)));const L=await D.getStackOutputs(h,void 0,e.abortSignal);L.success||P.debug("cascadeHelpers","Failed to read cascade account stack outputs (non-critical)",{stackName:h,account:n.name});const B=G(L);return await U(y,d,t,e.abortSignal),F!==void 0&&((await o.hashService.persistCascadeStack(b,h,F)).success||P.debug("cascadeHelpers","Failed to persist cascade hash state (non-critical)",{stackName:h,account:n.name})),t.onCascadeAccountComplete?.(r,!0,void 0,s,B,!1),I({outputs:B,skipped:!1})}g(Me,"deployCascadeAccount");async function Te(e,o,c,n){const i=new Map,t=e.awsProvider.getRegion(),a=await N(e.awsProvider,o.id,t,`fjall-ipam-read-${o.name}`,n);if(!a.success)return P.debug("organisationDeploy",`Cannot read Platform outputs: ${a.error.message}`),i;const s=new V(a.data.provider),r=H(A.PLATFORM),u=await s.getStackOutputs(r);if(!u.success)return P.debug("organisationDeploy",`Failed to read Platform stack outputs: ${u.error.message}`),i;const m=/^IpamPoolId(\d{12})(\w+)$/;for(const p of u.data){const d=p.OutputKey?.match(m);if(d&&p.OutputValue){const f=`${d[1]}-${d[2]}`;i.set(f,p.OutputValue)}}return i.size>0&&c.onLog?.(`Read ${i.size} IPAM pool ID(s) from Platform stack`,"info"),i}g(Te,"readPlatformIpamPoolIds");function fe(e,o){const c=e.account!==void 0&&o?.executingAccountId!==void 0&&e.account!==o.executingAccountId,n=e.region!==void 0&&o?.executingRegion!==void 0&&e.region!==o.executingRegion;if(c)return`[${e.name}] skipped: its fjall-config.json entry records account ${e.account} as its home, but this cascade runs in account ${o?.executingAccountId} - deploy it separately with 'fjall domain deploy ${e.name} -t <target in account ${e.account}>' or run the cascade under that account.`;if(n)return`[${e.name}] skipped: its fjall-config.json entry records region ${e.region} as its home, but this cascade runs in region ${o?.executingRegion} - deploy it separately with 'fjall domain deploy ${e.name} --region ${e.region}', or update the entry's "region" key if this move is intentional.`}g(fe,"foreignDomainSkipReason");function le(e){const o=new Map;for(const t of e)o.set(j(t.name),t);const c=new Map,n=g((t,a)=>{const s=c.get(t);if(s!==void 0)return s;if(a.includes(t))return[...a.slice(a.indexOf(t)),t];const r=o.get(t);if(r===void 0)return-1;const u=r.parentDomain!==void 0?j(r.parentDomain):void 0,m=u===void 0?-1:n(u,[...a,t]);if(Array.isArray(m))return m;const p=m+1;return c.set(t,p),p},"resolveDepth"),i=[];for(const t of e){const a=n(j(t.name),[]);if(Array.isArray(a)){const s=a.map(r=>o.get(r)?.name??r).join(" -> ");return w(new Error(`Delegated domain ordering: fjall-config.json declares a parentDomain cycle (${s}) - no deploy order satisfies it. Nothing was deployed. Cure: correct the "parentDomain" of one entry in that cycle so parents form a chain, then re-run.`))}(i[a]??=[]).push(t)}return I(i.filter(t=>t.length>0))}g(le,"planDelegatedDomainWaves");async function He(e,o,c){const n=e.getDomains();if(n.length===0)return{domainsDeployed:0,domainsSkipped:0,errors:[]};o.onCascadePhaseStart?.("domains");const i=[];let t=0;for(const d of n){const f=fe(d,c);if(f!==void 0){t++,o.onProgress?.({type:"warning",message:f});continue}i.push(d)}const a=i.filter(d=>d.type==="apex"),s=i.filter(d=>d.type==="delegated");let r=0;const u=[],m=le(s);if(!m.success)return u.push(m.error.message),o.onCascadePhaseComplete?.("domains"),{domainsDeployed:r,domainsSkipped:t,errors:u};const p=m.data;for(const d of a){const f=await e.deployDomain(d.name,o);f.success?r++:u.push(`${d.name}: ${f.error.message}`)}for(const d of p){const f=await Promise.allSettled(d.map(C=>{const l=e.delegatedDeployer?.(C.name);return l!==void 0?re({deployer:l,callbacks:o,...c?.abortSignal!==void 0?{abortSignal:c.abortSignal}:{},...c?.skipCaaPreflight!==void 0?{skipCaaPreflight:c.skipCaaPreflight}:{}}):e.deployDomain(C.name,o)}));for(let C=0;C<f.length;C++){const l=f[C],y=d[C];if(!(!l||!y))if(l.status==="fulfilled")l.value.success?r++:u.push(`${y.name}: ${l.value.error.message}`);else{const $=l.reason instanceof Error?l.reason.message:String(l.reason);u.push(`${y.name}: ${$}`)}}}return o.onCascadePhaseComplete?.("domains"),{domainsDeployed:r,domainsSkipped:t,errors:u}}g(He,"deployDomains");export{ce as CASCADE_MAX_CONCURRENCY,Le as buildAccountRegionPairs,Ue as buildCascadeRoleArn,de as buildRegionList,Fe as cascadeHomeRegion,ue as cascadeOperationKey,Me as deployCascadeAccount,He as deployDomains,be as partitionAccounts,le as planDelegatedDomainWaves,Be as probeCascadeRoles,Te as readPlatformIpamPoolIds};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { CdkService, CdkArgumentBuilder, CdkProcessManager, CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS, isCdkError, formatInfrastructureError, getStructuralHint, getSourceContext, hasCdkDifferences, parseDiffOutput, CloudFormationService, CloudFormationError, CfnRegistryService, CFN_REGISTRY_SEED, EcsService, EcsError, EcsServiceResolver, type CfnExportsClient } from "./infrastructure/index.js";
|
|
2
|
-
export type { CdkContext, CdkOptions, CdkOutput, CheckDifferencesResult, CdkServiceOptions, ICdkProcessManager, DiffDetails, CloudFormationCallbacks, CfnRegistrySchemaSummary, CfnRegistryServiceOptions, CfnRegistrySummaryReader, ECSServiceInfo, ECSClusterInfo, DeploymentStatus, ECSDeploymentOptions } from "./infrastructure/index.js";
|
|
1
|
+
export { CdkService, CdkArgumentBuilder, CdkProcessManager, ensureDependencyIntegrity, clearDependencyIntegrityCache, DEPENDENCY_SYNC_TIMEOUT_MS, CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS, isCdkError, formatInfrastructureError, getStructuralHint, getSourceContext, hasCdkDifferences, parseDiffOutput, CloudFormationService, CloudFormationError, CfnRegistryService, CFN_REGISTRY_SEED, EcsService, EcsError, EcsServiceResolver, type CfnExportsClient } from "./infrastructure/index.js";
|
|
2
|
+
export type { CdkContext, CdkOptions, CdkOutput, CheckDifferencesResult, CdkServiceOptions, ICdkProcessManager, DependencyIntegrityOutcome, DependencyIntegrityStatus, EnsureDependencyIntegrityOptions, DiffDetails, CloudFormationCallbacks, CfnRegistrySchemaSummary, CfnRegistryServiceOptions, CfnRegistrySummaryReader, ECSServiceInfo, ECSClusterInfo, DeploymentStatus, ECSDeploymentOptions } from "./infrastructure/index.js";
|
|
3
3
|
export { TemplateHashService, TemplateHashError, type TemplateComparisonResult } from "./supporting/index.js";
|
|
4
4
|
export { CdkContextBuilder } from "./supporting/index.js";
|
|
5
5
|
export { emitProgress, PROGRESS_MESSAGES, parseBuildPhase, buildStepContextBuildConfig, convertCloudFormationOutputsToRecord, type CloudFormationOutput } from "./supporting/index.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CdkService as
|
|
1
|
+
import{CdkService as t,CdkArgumentBuilder as o,CdkProcessManager as i,ensureDependencyIntegrity as n,clearDependencyIntegrityCache as c,DEPENDENCY_SYNC_TIMEOUT_MS as a,CdkEventMonitor as E,startStackMonitoring as S,DEFAULT_DEPLOY_TIMEOUT_MS as s,isCdkError as u,formatInfrastructureError as C,getStructuralHint as d,getSourceContext as p,hasCdkDifferences as l,parseDiffOutput as f,CloudFormationService as m,CloudFormationError as g,CfnRegistryService as v,CFN_REGISTRY_SEED as k,EcsService as D,EcsError as T,EcsServiceResolver as _}from"./infrastructure/index.js";import{TemplateHashService as M,TemplateHashError as R}from"./supporting/index.js";import{CdkContextBuilder as O}from"./supporting/index.js";import{emitProgress as h,PROGRESS_MESSAGES as y,parseBuildPhase as F,buildStepContextBuildConfig as A,convertCloudFormationOutputsToRecord as B}from"./supporting/index.js";import{ApplicationStackService as Y}from"./application/index.js";export{Y as ApplicationStackService,k as CFN_REGISTRY_SEED,o as CdkArgumentBuilder,O as CdkContextBuilder,E as CdkEventMonitor,i as CdkProcessManager,t as CdkService,v as CfnRegistryService,g as CloudFormationError,m as CloudFormationService,s as DEFAULT_DEPLOY_TIMEOUT_MS,a as DEPENDENCY_SYNC_TIMEOUT_MS,T as EcsError,D as EcsService,_ as EcsServiceResolver,y as PROGRESS_MESSAGES,R as TemplateHashError,M as TemplateHashService,A as buildStepContextBuildConfig,c as clearDependencyIntegrityCache,B as convertCloudFormationOutputsToRecord,h as emitProgress,n as ensureDependencyIntegrity,C as formatInfrastructureError,p as getSourceContext,d as getStructuralHint,l as hasCdkDifferences,u as isCdkError,F as parseBuildPhase,f as parseDiffOutput,S as startStackMonitoring};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
2
|
-
${
|
|
3
|
-
${
|
|
1
|
+
var G=Object.defineProperty;var T=(h,e)=>G(h,"name",{value:e,configurable:!0});import{spawn as y}from"child_process";import{existsSync as P}from"fs";import{join as M}from"path";import{createRequire as B}from"module";import{logger as E}from"@fjall/util/logger";import{filterDangerousEnvVars as _,maskSensitiveOutput as g}from"@fjall/util";import{success as $,failure as n}from"@fjall/generator";import{getErrorMessage as H}from"@fjall/util";import{ensureDependencyIntegrity as L}from"./dependencyIntegrityGate.js";function w(){try{const e=B(import.meta.url).resolve("aws-cdk/bin/cdk");return $({command:process.execPath,prefixArgs:[e]})}catch(h){return E.error("CdkService","Failed to resolve the bundled aws-cdk CLI",{error:g(H(h))}),n("Fjall could not locate its bundled aws-cdk CLI. The deploy toolchain looks misconfigured \u2014 reinstall dependencies (npm install) or reinstall the Fjall CLI, then try again.")}}T(w,"getCdkBinaryPath");const N=5e3,R=1800*1e3;class X{static{T(this,"CdkProcessManager")}runningProcesses=new Map;processCounter=0;argBuilder;abortSignal;exitHandler;sigintHandler;sigtermHandler;constructor(e,i){this.argBuilder=e,this.abortSignal=i,this.exitHandler=()=>this.cleanup(),this.sigintHandler=()=>{this.abortSignal===void 0&&(this.cleanup(),process.exit(130))},this.sigtermHandler=()=>{this.abortSignal===void 0&&(this.cleanup(),process.exit(143))},process.on("exit",this.exitHandler),process.on("SIGINT",this.sigintHandler),process.on("SIGTERM",this.sigtermHandler)}forceKillProcess(e){e.stdout?.destroy(),e.stderr?.destroy(),e.kill("SIGTERM");const i=setTimeout(()=>{e.exitCode===null&&e.kill("SIGKILL")},N);i.unref(),e.once("exit",()=>clearTimeout(i))}cleanup(){for(const[e,i]of this.runningProcesses)i.killed||(i.stdout?.destroy(),i.stderr?.destroy(),i.kill("SIGTERM"));this.runningProcesses.clear()}dispose(){this.cleanup(),process.removeListener("exit",this.exitHandler),process.removeListener("SIGINT",this.sigintHandler),process.removeListener("SIGTERM",this.sigtermHandler)}async runCdkCommandPassthrough(e,i,t){if(!P(e))return n(`Directory not found: ${e}`);const u=M(e,"cdk.json");if(!P(u))return n(`No CDK project found in ${e}`);const o=await L(e,{onOutput:t?.outputCallback??(a=>{process.stdout.write(a)}),...this.abortSignal!==void 0?{abortSignal:this.abortSignal}:{}});return o.success?new Promise(a=>{const m=w();if(!m.success){a(n(m.error));return}const p=m.data,C=this.argBuilder.buildContextArgs(t?.context),b=[...p.prefixArgs,...i,...C],k=this.argBuilder.buildCdkEnv(t),l=y(p.command,b,{cwd:e,env:k,stdio:"inherit",shell:!1,detached:!1,...this.abortSignal!==void 0?{signal:this.abortSignal,killSignal:"SIGTERM"}:{}});if(!l.pid){l.on("error",r=>{E.debug("CdkProcess","Spawn error on failed child process",{error:r.message})}),a(n(`Failed to spawn CDK process - no PID. cwd=${e}, args=${b.join(" ")}`));return}const c=`cdk-passthrough-${++this.processCounter}`;this.runningProcesses.set(c,l);let f=!1,d=!1;const I=t?.timeout??R,S=setTimeout(()=>{l.killed||(f=!0,this.forceKillProcess(l))},I);l.on("close",r=>{if(clearTimeout(S),this.runningProcesses.delete(c),!d){if(d=!0,f){a(n("CDK command timed out"));return}r===0||t?.ignoreExitCode?a($({exitCode:r||0})):a(n(`CDK command failed with exit code ${r}`))}}),l.on("error",r=>{clearTimeout(S),this.runningProcesses.delete(c),!(d||f)&&(d=!0,a(n(`Failed to run CDK command: ${r.message}`)))})}):n(o.error)}async runCdkCommand(e,i,t){if(!P(e))return n(`Directory not found: ${e}`);if(!t?.skipProjectCheck){const u=M(e,"cdk.json");if(!P(u))return n(`No CDK project found in ${e}`);const o=await L(e,{...t?.outputCallback!==void 0?{onOutput:t.outputCallback}:{},...this.abortSignal!==void 0?{abortSignal:this.abortSignal}:{}});if(!o.success)return n(o.error)}return new Promise(u=>{let o="",a="",m=!1;const p=w();if(!p.success){u(n(p.error));return}const C=p.data,b=this.argBuilder.buildContextArgs(t?.context),k=[...C.prefixArgs,...i,...b],l={...this.argBuilder.buildCdkEnv(t),NO_COLOR:"1",...t?.extraEnv?_(t.extraEnv):{}};E.debug("CdkService","Spawning CDK process",{command:`${C.command} ${k.join(" ")}`,workingDir:e});const c=y(C.command,k,{cwd:e,env:l,stdio:["ignore","pipe","pipe"],shell:!1,detached:!1,...this.abortSignal!==void 0?{signal:this.abortSignal,killSignal:"SIGTERM"}:{}});if(!c.pid){const r=`Failed to spawn CDK process - no PID. cwd=${e}, args=${k.join(" ")}`;c.on("error",s=>{E.debug("CdkProcess","Deferred spawn error on failed child process",{error:s.message})}),u(n(r));return}const f=`cdk-${++this.processCounter}`;this.runningProcesses.set(f,c);let d=!1;const I=t?.timeout??R,S=setTimeout(()=>{c.killed||(m=!0,this.forceKillProcess(c))},I);c.stdout?.on("data",r=>{const s=r.toString();o+=s,t?.outputCallback&&t.outputCallback(g(s)),t?.cdkOutputLogger?.writeCdkOutput("stdout",g(s))}),c.stderr?.on("data",r=>{const s=r.toString();t?.cdkOutputLogger?.writeCdkOutput("stderr",g(s)),!s.includes("deprecated")&&!s.includes("npm WARN")&&!s.includes("ENOENT")&&!/\(node:\d+\)/.test(s)&&!s.includes("ExperimentalWarning")&&!s.includes("will no longer support")&&(a+=s),t?.errorCallback&&t.errorCallback(g(s))}),c.on("error",r=>{clearTimeout(S),this.runningProcesses.delete(f),!(d||m)&&(d=!0,u(n(H(r))))}),c.on("close",r=>{if(clearTimeout(S),this.runningProcesses.delete(f),d)return;if(d=!0,m){u(n("CDK command timed out"));return}const s=r===0||t?.ignoreExitCode===!0&&r===1,A=o+(a?`
|
|
2
|
+
${a}`:"");if(s){const x=t?.combineOutput?A:o;u($({output:g(x),exitCode:r||0}));return}let K=a;if(o){const x=o.match(/❌.*?Error:(.*)$/m);x&&(K=x[1]?.trim()??"")}const O=K||`CDK command failed with exit code ${r}`,j=o?`${O}
|
|
3
|
+
${o}`:O;u(n(g(j)))})})}}export{X as CdkProcessManager};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
var j=Object.defineProperty;var F=(E,e)=>j(E,"name",{value:e,configurable:!0});import{existsSync as U}from"fs";import{join as P}from"path";import{logger as T}from"@fjall/util/logger";import{success as v,failure as o}from"@fjall/generator";import{DEFAULT_REGION as S}from"../../aws/utils/regions.js";import{getErrorMessage as k,maskSensitiveOutput as
|
|
1
|
+
var j=Object.defineProperty;var F=(E,e)=>j(E,"name",{value:e,configurable:!0});import{existsSync as U}from"fs";import{join as P}from"path";import{logger as T}from"@fjall/util/logger";import{success as v,failure as o}from"@fjall/generator";import{DEFAULT_REGION as S}from"../../aws/utils/regions.js";import{getErrorMessage as k,maskSensitiveOutput as h}from"@fjall/util";import{CdkEventMonitor as G,DEFAULT_DEPLOY_TIMEOUT_MS as B,settleMonitoringAnalysis as Y,startStackMonitoring as q}from"./CdkEventMonitoring.js";import{analyseDeployOutput as X,analyseDestroyResult as z,createEnhancedOutputCallback as H,formatAnalysedDeployFailure as _}from"./CdkOutputAnalyser.js";import{recordDriftSuspects as J}from"../../orchestration/drift/driftSuspectJournal.js";import{CdkCommandRunner as Q}from"./CdkCommandRunner.js";import{CdkArgumentBuilder as V}from"./CdkArgumentBuilder.js";import{CdkProcessManager as Z}from"./CdkProcessManager.js";import{cancelInFlightStack as O}from"./cancelInFlightStack.js";import{isAborted as w}from"../../aws/organisations/types.js";import{wrapWithConstructMapEnrichment as x}from"./constructMapEnrichment.js";import{STACK_DETECTION_FALLBACK_MS as ee,resolveStackName as K,getFallbackStackName as te,buildDeploymentCdkContext as I}from"./cdkServiceHelpers.js";import{ensureDependencyIntegrity as re}from"./dependencyIntegrityGate.js";import{runInfraTypecheckPreflight as ne}from"./infraTypecheckPreflight.js";import{isTransientNetworkFailure as ae,isReattachableInProgressStatus as oe,MAX_TRANSIENT_NETWORK_RETRIES as N,TRANSIENT_RETRY_BACKOFF_MS as ie}from"./transientNetworkRecovery.js";import{sleepAbortable as se}from"../../util/sleepAbortable.js";class Fe{static{F(this,"CdkService")}commandRunner;eventMonitor;abortSignal;constructor(e){const t=e?.processManager??new Z(new V,e?.abortSignal);this.commandRunner=new Q(t),this.eventMonitor=new G({eventLogWriterFactory:e?.eventLogWriterFactory,...e?.onFailureAnalysis!==void 0?{onFailureAnalysis:e.onFailureAnalysis}:{}}),this.abortSignal=e?.abortSignal}dispose(){this.commandRunner.dispose()}async checkDifferences(e,t,r){return this.commandRunner.checkDifferences(e,t,r)}async deploy(e,t,r){return this.commandRunner.deploy(e,t,r)}async destroy(e,t,r){return this.commandRunner.destroy(e,t,r)}async runImport(e,t,r){return this.commandRunner.runImport(e,t,r)}async synth(e,t){return this.commandRunner.synth(e,t)}async bootstrap(e,t,r){return this.commandRunner.bootstrap(e,t,r)}async runCdkSynth(e,t,r){const a=e.callerIdentity?.Account;try{const n=await re(e.path,{...t!==void 0?{onOutput:t}:{},...this.abortSignal!==void 0?{abortSignal:this.abortSignal}:{}});if(!n.success)return o(n.error);const l=await ne(e.path,{...this.abortSignal!==void 0?{abortSignal:this.abortSignal}:{}});l.status==="failed"&&(t?.(`WARNING: TypeScript errors in ${e.path} \u2014 the synthesised template may be wrong. This check will block deploys in a future release.
|
|
2
2
|
${l.details}
|
|
3
|
-
`),T.warn("CdkService","Infrastructure typecheck failed",{path:e.path}));const i=await this.synth(e.path,{outputCallback:t,context:I(e,a,e.region||S),...e.assemblyDir!==void 0?{outputDir:e.assemblyDir}:{},...r!==void 0?{credentials:r}:{}});return i.success?v({message:"CloudFormation template synthesised",details:i.data.output?{synthesisTime:i.data.output}:void 0}):o(i.error||"Failed to synthesise CloudFormation template")}catch(n){return o(`CDK synth failed: ${
|
|
3
|
+
`),T.warn("CdkService","Infrastructure typecheck failed",{path:e.path}));const i=await this.synth(e.path,{outputCallback:t,context:I(e,a,e.region||S),...e.assemblyDir!==void 0?{outputDir:e.assemblyDir}:{},...r!==void 0?{credentials:r}:{}});return i.success?v({message:"CloudFormation template synthesised",details:i.data.output?{synthesisTime:i.data.output}:void 0}):o(i.error||"Failed to synthesise CloudFormation template")}catch(n){return o(`CDK synth failed: ${h(k(n))}`)}}async runCdkBootstrap(e,t,r,a,n){const l=e.callerIdentity?.Account,i=e.region||S;try{if(!l)return o("No AWS account ID available");const u=P(e.path,"node_modules");if(!U(u))return o(`Dependencies not installed. Please run 'npm install' in ${e.path} before deploying.`);const d=await this.bootstrap(l,i,{outputCallback:t,credentials:r,...a!==void 0&&a!==""?{permissionsBoundary:a}:{},...n!==void 0&&Object.keys(n).length>0?{bootstrapTags:n}:{}});return d.success?v({message:"AWS environment bootstrapped"}):o(d.error||"Failed to bootstrap AWS environment")}catch(u){return o(`CDK bootstrap failed: ${h(k(u))}`)}}async runCdkDiff(e,t){const r=e.callerIdentity?.Account;try{const a=await this.checkDifferences(e.path,void 0,{verbose:e.options?.verbose,outputCallback:t,context:I(e,r,e.region||S)});return a.success?v({message:"Diff check complete",details:{hasDifferences:a.data.hasDifferences,details:a.data.details}}):o(`CDK diff failed: ${a.error.message}`)}catch(a){return o(`CDK diff failed: ${h(k(a))}`)}}async runCdkDeploy(e,t,r,a,n,l,i,u){const d=e.callerIdentity?.Account,s=e.region||S;if(!d)return o("AWS account ID not available. Please ensure AWS credentials are properly configured.");if(!n)return o("AwsProvider is required for deployment monitoring.");const p=e.assemblyDir??P(e.path,"cdk.out"),y=x(p,a);let g=null,b;try{const f=K(t,e)??te(e),m=await this.eventMonitor.createEventMonitor("deploy",f,s,e,n);g=m,r&&(r(h(`Starting CloudFormation deployment of ${f}...
|
|
4
4
|
`)),r(`Monitoring CloudFormation events (CDK process running in background)...
|
|
5
|
-
`));const c={cdkOutput:"",actualStackName:f,stackDetected:!1,monitoringPromise:null},L=H(c,r,
|
|
5
|
+
`));const c={cdkOutput:"",actualStackName:f,stackDetected:!1,monitoringPromise:null},L=H(c,r,g,y);b=setTimeout(()=>{!c.stackDetected&&!c.monitoringPromise&&(T.debug("CdkService","Fallback monitoring STARTING",{targetStackName:f,stackDetected:c.stackDetected,hasOnResourceProgress:!!a}),c.monitoringPromise=q(m,f,y))},ee);for(let D=0;;D++){const C=await this.deploy(e.path,f,{verbose:e.options?.verbose,outputCallback:L,...e.assemblyDir!==void 0?{appDir:e.assemblyDir}:{useCdkOut:!0},cdkOutputLogger:m.getEventLogger()??void 0,context:I(e,d,s),credentials:l,...i!==void 0&&Object.keys(i).length>0&&{parameters:i},...u===!0&&{exclusively:!0}});if(w(this.abortSignal))return await O(f,s,l,r),o("Deployment cancelled");const R=X(c.cdkOutput,C,c.actualStackName);if(R.success)return R;const W=[c.cdkOutput,C.success?C.data.output??"":C.error,R.error].join(`
|
|
6
6
|
`);if(ae(W)){r?.(`Transient network failure while running CDK for ${c.actualStackName} \u2014 probing CloudFormation for an in-flight operation...
|
|
7
7
|
`);const M=await m.getStackStatus(c.actualStackName,this.abortSignal);if(M!==null&&oe(M.status))return clearTimeout(b),await this.reattachToInFlightOperation({stackName:c.actualStackName,currentStatus:M.status,region:s,accountId:d,monitor:m,state:c,credentials:l,onOutput:r,onResourceProgress:y});if(D<N){const $=ie[D]??15e3;if(r?.(`No CloudFormation operation in progress \u2014 nothing was mutated. Retrying the CDK deploy in ${$/1e3}s (retry ${D+1} of ${N})...
|
|
8
8
|
`),await se($,this.abortSignal),w(this.abortSignal))return o("Deployment cancelled");c.cdkOutput="";continue}r?.(`No CloudFormation operation in progress and the retry budget (${N}) is exhausted \u2014 giving up.
|
|
9
|
-
`)}const A=await Y(m,c.monitoringPromise);return A===null?R:(await this.journalDriftSuspects(d,s,c.actualStackName,A),o(_(A)))}}catch(f){const m=`CDK deploy failed: ${
|
|
9
|
+
`)}const A=await Y(m,c.monitoringPromise);return A===null?R:(await this.journalDriftSuspects(d,s,c.actualStackName,A),o(_(A)))}}catch(f){const m=`CDK deploy failed: ${h(k(f))}`;return T.error("CdkService","CDK deployment exception",{error:m}),o(m)}finally{clearTimeout(b),g&&g.stopMonitoring()}}async reattachToInFlightOperation(e){const{stackName:t,monitor:r,state:a,onOutput:n}=e;n?.(`CloudFormation reports ${e.currentStatus} for ${t} \u2014 the operation survived the network failure. Re-attaching and monitoring it to completion...
|
|
10
10
|
`),r.stopMonitoring(),a.monitoringPromise=null;const l=F(()=>{r.stopMonitoring()},"onAbort");this.abortSignal?.addEventListener("abort",l,{once:!0});const i=await r.waitForStackComplete(t,{timeout:B,...e.onResourceProgress!==void 0?{onResourceUpdate:e.onResourceProgress}:{}}).finally(()=>{this.abortSignal?.removeEventListener("abort",l)});if(w(this.abortSignal))return await O(t,e.region,e.credentials,n),o("Deployment cancelled");if(i.success){const s=i.status??"COMPLETE";return n?.(`${t} reached ${s} after re-attach.
|
|
11
|
-
`),v({message:`Re-attached to the in-flight CloudFormation operation after a transient network failure; ${t} reached ${s}`,details:{reattached:!0,status:s}})}const u=r.getFailureAnalysis();if(u!==null)return await this.journalDriftSuspects(e.accountId,e.region,t,u),o(_(u));const d=i.failureReason!==void 0&&i.failureReason!==""?
|
|
11
|
+
`),v({message:`Re-attached to the in-flight CloudFormation operation after a transient network failure; ${t} reached ${s}`,details:{reattached:!0,status:s}})}const u=r.getFailureAnalysis();if(u!==null)return await this.journalDriftSuspects(e.accountId,e.region,t,u),o(_(u));const d=i.failureReason!==void 0&&i.failureReason!==""?h(i.failureReason):"no failure reason reported";return o(`Re-attached to the in-flight CloudFormation operation after a transient network failure; ${t} reached ${i.status??"UNKNOWN"}: ${d}`)}async journalDriftSuspects(e,t,r,a){a.driftSuspects===void 0||a.driftSuspects.length===0||await J({accountId:e,region:t,stackName:r,recordedAt:new Date().toISOString(),suspects:a.driftSuspects.map(n=>({stackName:r,logicalId:n.logicalId,resourceType:n.resourceType,...n.physicalId!==void 0?{physicalId:n.physicalId}:{},failedStatus:n.failedStatus,statusReason:n.statusReason}))})}async runCdkDestroy(e,t,r,a,n,l,i){const u=e.callerIdentity?.Account,d=e.region||S;let s=null;try{const p=K(t,e);u&&p&&n&&(s=await this.eventMonitor.createEventMonitor("destroy",p,d,e,n),s.startMonitoring(p,g=>{a?.(g)},(g,b)=>{}));const y=await this.destroy(e.path,t,{verbose:e.options?.verbose,outputCallback:r,useCdkOut:l,cdkOutputLogger:s?.getEventLogger()??void 0,context:I(e,u,d),credentials:i});return w(this.abortSignal)?o("Destroy cancelled"):z(y)}catch(p){return o(`CDK destroy failed: ${h(k(p))}`)}finally{s&&s.stopMonitoring()}}}export{Fe as CdkService};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency-integrity gate for infrastructure declaration folders.
|
|
3
|
+
*
|
|
4
|
+
* CDK executes the customer's app (npx tsx infrastructure.ts) in the
|
|
5
|
+
* declaration dir, and Node resolves imports by walking ANCESTOR
|
|
6
|
+
* directories whenever the local node_modules is missing or incomplete -
|
|
7
|
+
* silently synthesising against stale or wrong packages. Two real
|
|
8
|
+
* incidents drive the check: a missing local install resolved a stray
|
|
9
|
+
* ancestor copy and silently dropped resources from the template (I1), and
|
|
10
|
+
* a node_modules older than the lockfile pin broke the synth (I2). The
|
|
11
|
+
* gate therefore verifies that every DECLARED dependency is satisfied
|
|
12
|
+
* locally before any CDK child is spawned, auto-heals with npm when it is
|
|
13
|
+
* not, re-verifies, and fails closed when the tree still cannot be
|
|
14
|
+
* trusted.
|
|
15
|
+
*
|
|
16
|
+
* The check is satisfaction-based, not manager-based: a correct tree
|
|
17
|
+
* passes untouched regardless of which package manager produced it
|
|
18
|
+
* (existsSync follows symlinks, so pnpm/yarn layouts pass), and a dir an
|
|
19
|
+
* ancestor manifest DECLARES as a workspace member may satisfy deps from
|
|
20
|
+
* that workspace root - explicit membership is the hoist contract, not the
|
|
21
|
+
* stray-ancestor hazard. There is deliberately no opt-out - if the
|
|
22
|
+
* declared dependencies are unsatisfiable the synth WOULD be wrong, so
|
|
23
|
+
* there is nothing legitimate to skip.
|
|
24
|
+
*/
|
|
25
|
+
import type { Result } from "@fjall/generator";
|
|
26
|
+
/** Timeout for the dependency sync (5 minutes). */
|
|
27
|
+
export declare const DEPENDENCY_SYNC_TIMEOUT_MS: number;
|
|
28
|
+
export interface EnsureDependencyIntegrityOptions {
|
|
29
|
+
onOutput?: (chunk: string) => void;
|
|
30
|
+
abortSignal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* "skipped" is minted only by callers that bypass the gate entirely
|
|
34
|
+
* (skipProjectCheck-style paths with no declaration folder to verify);
|
|
35
|
+
* ensureDependencyIntegrity itself never returns it.
|
|
36
|
+
*/
|
|
37
|
+
export type DependencyIntegrityStatus = "satisfied" | "installed" | "skipped";
|
|
38
|
+
export interface DependencyIntegrityOutcome {
|
|
39
|
+
status: DependencyIntegrityStatus;
|
|
40
|
+
}
|
|
41
|
+
export declare function clearDependencyIntegrityCache(): void;
|
|
42
|
+
/**
|
|
43
|
+
* Verify (and if needed heal) the declaration folder's dependency tree.
|
|
44
|
+
*
|
|
45
|
+
* Fails closed on: missing/unparseable package.json (the documented
|
|
46
|
+
* ancestor-resolution hole), unparseable package-lock.json, an npm sync
|
|
47
|
+
* that fails, and a tree still unsatisfied after a successful sync.
|
|
48
|
+
* Memoised per real path for the life of the process; failures are not
|
|
49
|
+
* cached.
|
|
50
|
+
*/
|
|
51
|
+
export declare function ensureDependencyIntegrity(path: string, options?: EnsureDependencyIntegrityOptions): Promise<Result<DependencyIntegrityOutcome, string>>;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var E=Object.defineProperty;var i=(t,e)=>E(t,"name",{value:e,configurable:!0});import{existsSync as m,readFileSync as O,realpathSync as T}from"fs";import{dirname as S,join as h,relative as U,resolve as C,sep as I}from"path";import{filterDangerousEnvVars as R,getErrorMessage as F,maskSensitiveOutput as $}from"@fjall/util";import{logger as A}from"@fjall/util/logger";import{success as k,failure as a}from"@fjall/generator";import{spawnWithTimeout as J}from"../../orchestration/spawnHelpers.js";const N=300*1e3,P=1500,w=new Map,b=new Map;function re(){w.clear(),b.clear()}i(re,"clearDependencyIntegrityCache");function H(t){const e=$(t.trim());return e.length>P?`...${e.slice(-P)}`:e}i(H,"maskedTail");function L(t){try{return T(t)}catch{return C(t)}}i(L,"resolveCacheKey");function j(t){try{const e=JSON.parse(O(t,"utf-8"));return e===null||typeof e!="object"||Array.isArray(e)?a("not a JSON object"):k(e)}catch(e){return a(F(e))}}i(j,"readJsonFile");function V(t){const e=new Set;for(const r of["dependencies","devDependencies"]){const o=t[r];if(o!==null&&typeof o=="object"&&!Array.isArray(o))for(const s of Object.keys(o))e.add(s)}const n=t.optionalDependencies;if(n!==null&&typeof n=="object"&&!Array.isArray(n))for(const r of Object.keys(n))e.delete(r);return[...e]}i(V,"collectDeclaredDeps");function W(t,e){const r=t.replace(/^\.\//,"").replace(/\/+$/,"").split("/").map(o=>o==="**"?".*":o.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]*")).join("/");return new RegExp(`^${r}$`).test(e)}i(W,"workspacePatternMatches");function Y(t){const e=t.workspaces,n=Array.isArray(e)?e:e!==null&&typeof e=="object"?e.packages:void 0;return Array.isArray(n)?n.filter(r=>typeof r=="string"):[]}i(Y,"workspacePatterns");function K(t){const e=C(t);let n=S(e);for(;;){const r=h(n,"package.json");if(m(r)){const s=j(r);if(s.success){const u=U(n,e).split(I).join("/");if(Y(s.data).some(f=>W(f,u)))return n}}const o=S(n);if(o===n)return;n=o}}i(K,"findWorkspaceRoot");function q(t,e){const n=t.packages,r=n!==null&&typeof n=="object"?n[`node_modules/${e}`]:z(t,e);if(r===null||typeof r!="object")return;const o=r.version;return typeof o=="string"?o:void 0}i(q,"lockfilePin");function z(t,e){const n=t.dependencies;if(!(n===null||typeof n!="object"))return n[e]}i(z,"readV1DependencyEntry");function D(t,e,n,r){const o=[];for(const s of e){let u=h(t,"node_modules",s,"package.json");if(!m(u)){const d=r!==void 0?h(r,"node_modules",s,"package.json"):void 0;if(d===void 0||!m(d)){o.push({name:s,detail:`${s} is not installed locally`});continue}u=d}if(n===void 0)continue;const f=q(n,s);if(f===void 0)continue;const y=j(u);if(!y.success)continue;const p=y.data.version;typeof p=="string"&&p!==f&&o.push({name:s,detail:`${s} is installed at ${p} but package-lock.json pins ${f}`})}return o}i(D,"findUnsatisfiedDeps");function x(t){return t.map(e=>e.detail).join("; ")}i(x,"describeUnsatisfied");async function oe(t,e={}){const n=L(t),r=w.get(n);if(r!==void 0)return k(r);const o=b.get(n);if(o!==void 0)return o;const s=B(n,t,e).finally(()=>{b.delete(n)});return b.set(n,s),s}i(oe,"ensureDependencyIntegrity");async function B(t,e,n){const r=h(e,"package.json");if(!m(r))return a(`Dependency integrity gate: no package.json in ${e}, so its declared dependencies cannot be verified and the synth could silently resolve packages from an ancestor directory. Nothing was synthesised or deployed. Cure: restore package.json in ${e} from version control (or re-scaffold the folder), then retry.`);const o=j(r);if(!o.success)return a(`Dependency integrity gate: package.json in ${e} could not be parsed (${$(o.error)}). Nothing was synthesised or deployed. Cure: fix the JSON in ${r}, then retry.`);const s=V(o.data),u=h(e,"package-lock.json"),f=m(u);let y;if(f){const l=j(u);if(!l.success)return a(`Dependency integrity gate: package-lock.json in ${e} could not be parsed (${$(l.error)}), so npm ci would fail. Nothing was synthesised or deployed. Cure: restore package-lock.json in ${e} from version control, or delete it and run npm install there to regenerate it, then retry.`);y=l.data}let p=D(e,s,y,void 0),d;if(p.length>0&&(d=K(e),d!==void 0&&(p=D(e,s,y,d))),p.length===0){const l={status:"satisfied"};return w.set(t,l),k(l)}const c=f?"ci":"install";n.onOutput?.(`Syncing infrastructure dependencies (npm ${c}) in ${e}...
|
|
2
|
+
`),A.info("CdkService","Syncing declaration-folder dependencies",{path:e,subcommand:c,unsatisfied:x(p)});const M=Date.now(),g=await J({command:"npm",args:[c,"--no-audit","--no-fund","--include=dev"],cwd:e,env:R(process.env),timeout:N,...n.abortSignal!==void 0?{abortSignal:n.abortSignal}:{}});switch(g.type){case"success":{if(g.code===0){const l=D(e,s,y,d);if(l.length>0){const _=d!==void 0?`run npm install in ${d} (the npm workspace root that declares ${e})`:`run npm ${c} in ${e}`;return a(`Dependency integrity gate: npm ${c} completed in ${e} but ${x(l)}. Nothing was synthesised or deployed. Cure: ${_} and inspect the reported packages, then retry.`)}A.info("CdkService","Declaration-folder dependencies synced",{path:e,durationMs:Date.now()-M});const v={status:"installed"};return w.set(t,v),k(v)}return a(`Dependency integrity gate: npm ${c} failed (exit ${g.code}) in ${e}. Nothing was synthesised or deployed. Cure: run npm ${c} in ${e} and fix the reported npm error, then retry. npm output: ${H(g.stderr||g.stdout)}`)}case"timeout":return a(`Dependency integrity gate: npm ${c} timed out after ${N}ms in ${e}. Nothing was synthesised or deployed. Cure: run npm ${c} in ${e} to diagnose the slow install (network or registry), then retry.`);case"aborted":return a(`Dependency integrity gate: the dependency sync (npm ${c}) in ${e} was cancelled before it completed. Nothing was synthesised or deployed. Cure: re-run the command to restart the sync.`);case"enoent":return a("npm was not found on PATH. Install Node.js 22+ (which bundles npm) on this machine or CI agent, then retry.");case"spawn_error":return a(`Dependency integrity gate: npm ${c} could not be started in ${e} (${$(g.error.message)}). Nothing was synthesised or deployed. Cure: check that the npm binary on PATH exists and is executable, then retry.`)}}i(B,"verifyUncached");export{N as DEPENDENCY_SYNC_TIMEOUT_MS,re as clearDependencyIntegrityCache,oe as ensureDependencyIntegrity};
|
|
@@ -4,6 +4,7 @@ export type { CdkContext, CdkOptions, CdkOutput, CdkServiceOptions } from "./Cdk
|
|
|
4
4
|
export type { ICdkProcessManager } from "./ICdkProcessManager.js";
|
|
5
5
|
export { CdkArgumentBuilder } from "./CdkArgumentBuilder.js";
|
|
6
6
|
export { CdkProcessManager } from "./CdkProcessManager.js";
|
|
7
|
+
export { ensureDependencyIntegrity, clearDependencyIntegrityCache, DEPENDENCY_SYNC_TIMEOUT_MS, type DependencyIntegrityOutcome, type DependencyIntegrityStatus, type EnsureDependencyIntegrityOptions } from "./dependencyIntegrityGate.js";
|
|
7
8
|
export { CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS } from "./CdkEventMonitoring.js";
|
|
8
9
|
export { isCdkError, formatInfrastructureError, getStructuralHint, getSourceContext } from "./CdkErrorFormatter.js";
|
|
9
10
|
export { hasCdkDifferences, parseDiffOutput, type DiffDetails } from "./CdkOutputParser.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{CdkService as o}from"./CdkService.js";import{CdkArgumentBuilder as
|
|
1
|
+
import{CdkService as o}from"./CdkService.js";import{CdkArgumentBuilder as c}from"./CdkArgumentBuilder.js";import{CdkProcessManager as n}from"./CdkProcessManager.js";import{ensureDependencyIntegrity as p,clearDependencyIntegrityCache as E,DEPENDENCY_SYNC_TIMEOUT_MS as m}from"./dependencyIntegrityGate.js";import{CdkEventMonitor as a,startStackMonitoring as x,DEFAULT_DEPLOY_TIMEOUT_MS as C}from"./CdkEventMonitoring.js";import{isCdkError as u,formatInfrastructureError as d,getStructuralHint as g,getSourceContext as D}from"./CdkErrorFormatter.js";import{hasCdkDifferences as I,parseDiffOutput as _}from"./CdkOutputParser.js";import{CloudFormationService as M,CloudFormationError as T}from"./CloudFormationService.js";import{CfnRegistryService as y}from"./CfnRegistryService.js";import{CFN_REGISTRY_SEED as F}from"./cfnRegistrySeed.js";import{EcsService as R,EcsError as Y}from"./EcsService.js";import{EcsServiceResolver as U}from"./EcsServiceResolver.js";import{EcrImageInspectorService as A,stripTagOrDigest as L}from"./EcrImageInspectorService.js";export{F as CFN_REGISTRY_SEED,c as CdkArgumentBuilder,a as CdkEventMonitor,n as CdkProcessManager,o as CdkService,y as CfnRegistryService,T as CloudFormationError,M as CloudFormationService,C as DEFAULT_DEPLOY_TIMEOUT_MS,m as DEPENDENCY_SYNC_TIMEOUT_MS,A as EcrImageInspectorService,Y as EcsError,R as EcsService,U as EcsServiceResolver,E as clearDependencyIntegrityCache,p as ensureDependencyIntegrity,d as formatInfrastructureError,D as getSourceContext,g as getStructuralHint,I as hasCdkDifferences,u as isCdkError,_ as parseDiffOutput,x as startStackMonitoring,L as stripTagOrDigest};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/deploy-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Shared deployment engine for Fjall — used by CLI and webapp worker",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -88,8 +88,8 @@
|
|
|
88
88
|
"@aws-sdk/client-ssm": "^3.1038.0",
|
|
89
89
|
"@aws-sdk/client-sso-admin": "^3.1038.0",
|
|
90
90
|
"@aws-sdk/client-sts": "^3.1038.0",
|
|
91
|
-
"@fjall/generator": "^
|
|
92
|
-
"@fjall/util": "^
|
|
91
|
+
"@fjall/generator": "^4.0.0",
|
|
92
|
+
"@fjall/util": "^4.0.0",
|
|
93
93
|
"@smithy/node-http-handler": "^4.6.1",
|
|
94
94
|
"aws-cdk": "^2.1128.1",
|
|
95
95
|
"tsx": "^4.21.0",
|
|
@@ -100,5 +100,5 @@
|
|
|
100
100
|
"typescript": "^6.0.3",
|
|
101
101
|
"vitest": "^4.1.5"
|
|
102
102
|
},
|
|
103
|
-
"gitHead": "
|
|
103
|
+
"gitHead": "14031063ccd2685e390b70f6a3f4efe2bac7ced9"
|
|
104
104
|
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Ensures a synth folder's npm dependencies are installed before the CDK
|
|
3
|
-
* app is executed.
|
|
4
|
-
*
|
|
5
|
-
* Fresh CI checkouts (and fresh clones generally) have no
|
|
6
|
-
* `fjall/<App>/node_modules`, so synthesis dies with a raw
|
|
7
|
-
* ERR_MODULE_NOT_FOUND from tsx before the deploy engine can produce an
|
|
8
|
-
* actionable error. The engine owns its inputs: when the synth folder has
|
|
9
|
-
* its own package.json and no node_modules, install the dependencies
|
|
10
|
-
* rather than asking every consumer (CI pipelines, local clones, the
|
|
11
|
-
* deployment worker) to remember an install step.
|
|
12
|
-
*
|
|
13
|
-
* Only the fully-missing node_modules case is handled — a present but
|
|
14
|
-
* incomplete install proceeds to synthesis as before, where npm's own
|
|
15
|
-
* resolution errors surface.
|
|
16
|
-
*/
|
|
17
|
-
import type { Result } from "@fjall/generator";
|
|
18
|
-
/** Timeout for the synth-folder dependency install (5 minutes). */
|
|
19
|
-
export declare const SYNTH_DEPS_INSTALL_TIMEOUT_MS: number;
|
|
20
|
-
export interface EnsureSynthDependenciesOptions {
|
|
21
|
-
onOutput?: (chunk: string) => void;
|
|
22
|
-
abortSignal?: AbortSignal;
|
|
23
|
-
}
|
|
24
|
-
export interface SynthDependenciesOutcome {
|
|
25
|
-
/** True when an install was performed; false when nothing was needed. */
|
|
26
|
-
installed: boolean;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Install the synth folder's dependencies when they are missing.
|
|
30
|
-
*
|
|
31
|
-
* No-op (success, installed: false) when the folder has no package.json of
|
|
32
|
-
* its own — dependencies then resolve from an ancestor node_modules — or
|
|
33
|
-
* when node_modules already exists.
|
|
34
|
-
*/
|
|
35
|
-
export declare function ensureSynthDependencies(path: string, options?: EnsureSynthDependenciesOptions): Promise<Result<SynthDependenciesOutcome, string>>;
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var g=Object.defineProperty;var o=(e,n)=>g(e,"name",{value:n,configurable:!0});import{existsSync as i}from"fs";import{join as a}from"path";import{filterDangerousEnvVars as S,maskSensitiveOutput as d}from"@fjall/util";import{logger as l}from"@fjall/util/logger";import{success as c,failure as s}from"@fjall/generator";import{spawnWithTimeout as $}from"../../orchestration/spawnHelpers.js";const u=300*1e3,m=1500;function w(e){const n=d(e.trim());return n.length>m?`\u2026${n.slice(-m)}`:n}o(w,"maskedTail");async function A(e,n={}){if(!i(a(e,"package.json")))return c({installed:!1});if(i(a(e,"node_modules")))return c({installed:!1});const t=i(a(e,"package-lock.json"))?"ci":"install",f=[t,"--no-audit","--no-fund"];n.onOutput?.(`Installing infrastructure dependencies (npm ${t}) in ${e}...
|
|
2
|
-
`),l.info("CdkService","Installing synth-folder dependencies",{path:e,subcommand:t});const p=Date.now(),r=await $({command:"npm",args:f,cwd:e,env:S(process.env),timeout:u,...n.abortSignal!==void 0?{abortSignal:n.abortSignal}:{}});switch(r.type){case"success":return r.code===0?(l.info("CdkService","Synth-folder dependencies installed",{path:e,durationMs:Date.now()-p}),c({installed:!0})):s(`npm ${t} failed (exit ${r.code}) in ${e}: ${w(r.stderr||r.stdout)}`);case"timeout":return s(`npm ${t} timed out after ${u}ms in ${e}`);case"aborted":return s("Dependency installation was cancelled");case"enoent":return s("npm was not found on PATH. Install Node.js 22+ (which bundles npm) on this machine or CI agent, then retry.");case"spawn_error":return s(`Failed to start npm ${t} in ${e}: ${d(r.error.message)}`)}}o(A,"ensureSynthDependencies");export{u as SYNTH_DEPS_INSTALL_TIMEOUT_MS,A as ensureSynthDependencies};
|