@fjall/deploy-core 1.1.0 → 2.2.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 CHANGED
@@ -1 +1 @@
1
- 116 files minified at 2026-05-23T21:30:04.260Z
1
+ 116 files minified at 2026-05-25T07:02:47.580Z
@@ -1 +1 @@
1
- import{success as k,failure as w}from"@fjall/generator";import{logger as y}from"@fjall/util/logger";import{getApplicationDestroyOrder as b,getApplicationStepName as h,getApplicationStepId as S}from"../types/operations.js";import{stubCallerIdentity as N}from"../types/deployment/index.js";import{deriveResourcesFromManifestStacks as x}from"../types/patternDetection.js";import{CdkContextBuilder as D}from"../services/supporting/CdkContextBuilder.js";import{buildParamsContext as R}from"./contextHelpers.js";import{deleteStateFile as I,readStateFile as O}from"../types/FjallState.js";async function H(n,c,r){const{callbacks:o}=n,P=Date.now(),f=c.frameworkRegistry.resolve({appPath:r.path})?.detection.pattern??null;let p;try{const e=await O(r.path);if(e!==null){const t=Object.keys(e.templateHashes);t.length>0&&(p=x(t))}}catch(e){y.debug("applicationDestroy","Could not read state file for resource detection",{error:e instanceof Error?e.message:String(e)}),o.onLog?.("Could not read state file for resource detection \u2014 falling back to pattern detection","warn")}const C=D.buildDeploymentContext({deployType:"application",target:r.appName,path:r.path,region:c.awsProvider.getRegion(),callerIdentity:N(c.awsProvider.getAccountId()),...R({orgConfig:n.orgConfig,identity:n.identity})},{verbose:n.options?.verbose},n.orgConfig),d=b({pattern:f,resources:p}),s=d.length;o.onLog?.(`Destroying ${r.appName} (${s} stacks, ${f??"standard"} pattern)`,"info");const g=[],u=[],m=await c.stackService.destroyAllStacks(C,{onOutput:e=>{o.onOutput?.(e)},onResourceProgress:(e,t)=>{o.onResourceProgress?.(e),t&&o.onParallelStackResourceProgress?.(t,e)},onStackStart:(e,t)=>{const a=S(e,"destroy"),l=h(e,"destroy"),i=d.indexOf(e);o.onStepStart?.(a,l,i,s)},onStackComplete:async(e,t)=>{const a=S(e,"destroy"),l=h(e,"destroy"),i=d.indexOf(e);t.success?t.data?.skipped?(u.push(t.data.stackName||e),o.onStepComplete?.(a,l,"skipped",i,s)):(g.push(t.data?.stackName||e),o.onStepComplete?.(a,l,"completed",i,s)):(o.onStepComplete?.(a,l,"error",i,s),o.onError?.(t.error))},onParallelPhaseStart:(e,t)=>{o.onLog?.(`Parallel phase: ${t}`,"info"),o.onParallelPhaseStart?.(e,t)},onParallelPhaseComplete:e=>{const t=e.filter(a=>!a.success);t.length>0&&o.onLog?.(`Parallel phase completed with ${t.length} failure(s)`,"warn"),o.onParallelPhaseComplete?.(e)}},p);if(!m.success)return o.onError?.(m.error),w(m.error);try{await I(r.path)}catch(e){y.debug("applicationDestroy","Failed to delete state file (non-critical)",{error:e instanceof Error?e.message:String(e)}),o.onLog?.("Failed to delete state file (non-critical)","warn")}return k({target:r.appName,deploymentType:"application",stacksDestroyed:g,skippedStacks:u,durationMs:Date.now()-P})}export{H as destroyApplication};
1
+ import{success as w,failure as b}from"@fjall/generator";import{getErrorMessage as y}from"@fjall/util";import{logger as h}from"@fjall/util/logger";import{getApplicationDestroyOrder as N,getApplicationStepName as S,getApplicationStepId as P}from"../types/operations.js";import{stubCallerIdentity as x}from"../types/deployment/index.js";import{deriveResourcesFromManifestStacks as D}from"../types/patternDetection.js";import{CdkContextBuilder as R}from"../services/supporting/CdkContextBuilder.js";import{buildParamsContext as I}from"./contextHelpers.js";import{deleteStateFile as O,readStateFile as A}from"../types/FjallState.js";async function q(s,c,r){const{callbacks:o}=s,C=Date.now(),f=c.frameworkRegistry.resolve({appPath:r.path})?.detection.pattern??null;let p;try{const e=await A(r.path);if(e!==null){const t=Object.keys(e.templateHashes);t.length>0&&(p=D(t))}}catch(e){h.debug("applicationDestroy","Could not read state file for resource detection",{error:y(e)}),o.onLog?.("Could not read state file for resource detection \u2014 falling back to pattern detection","warn")}const k=R.buildDeploymentContext({deployType:"application",target:r.appName,path:r.path,region:c.awsProvider.getRegion(),callerIdentity:x(c.awsProvider.getAccountId()),...I({orgConfig:s.orgConfig,identity:s.identity})},{verbose:s.options?.verbose},s.orgConfig),d=N({pattern:f,resources:p}),n=d.length;o.onLog?.(`Destroying ${r.appName} (${n} stacks, ${f??"standard"} pattern)`,"info");const g=[],u=[],m=await c.stackService.destroyAllStacks(k,{onOutput:e=>{o.onOutput?.(e)},onResourceProgress:(e,t)=>{o.onResourceProgress?.(e),t&&o.onParallelStackResourceProgress?.(t,e)},onStackStart:(e,t)=>{const a=P(e,"destroy"),l=S(e,"destroy"),i=d.indexOf(e);o.onStepStart?.(a,l,i,n)},onStackComplete:async(e,t)=>{const a=P(e,"destroy"),l=S(e,"destroy"),i=d.indexOf(e);t.success?t.data?.skipped?(u.push(t.data.stackName||e),o.onStepComplete?.(a,l,"skipped",i,n)):(g.push(t.data?.stackName||e),o.onStepComplete?.(a,l,"completed",i,n)):(o.onStepComplete?.(a,l,"error",i,n),o.onError?.(t.error))},onParallelPhaseStart:(e,t)=>{o.onLog?.(`Parallel phase: ${t}`,"info"),o.onParallelPhaseStart?.(e,t)},onParallelPhaseComplete:e=>{const t=e.filter(a=>!a.success);t.length>0&&o.onLog?.(`Parallel phase completed with ${t.length} failure(s)`,"warn"),o.onParallelPhaseComplete?.(e)}},p);if(!m.success)return o.onError?.(m.error),b(m.error);try{await O(r.path)}catch(e){h.debug("applicationDestroy","Failed to delete state file (non-critical)",{error:y(e)}),o.onLog?.("Failed to delete state file (non-critical)","warn")}return w({target:r.appName,deploymentType:"application",stacksDestroyed:g,skippedStacks:u,durationMs:Date.now()-C})}export{q as destroyApplication};
@@ -1,2 +1,2 @@
1
- import{tmpdir as l}from"os";import{logger as d}from"@fjall/util/logger";import{success as p,failure as n}from"@fjall/generator";import{CdkError as m}from"../../types/errors/CdkError.js";import{DEFAULT_REGION as C}from"../../aws/utils/regions.js";import{CdkArgumentBuilder as E}from"./CdkArgumentBuilder.js";import{isCdkError as O,formatInfrastructureError as c}from"./CdkErrorFormatter.js";import{hasCdkDifferences as A,parseDiffOutput as P}from"./CdkOutputParser.js";import{DEFAULT_DEPLOY_TIMEOUT_MS as f}from"./CdkEventMonitoring.js";import{analyseBootstrapError as g}from"./CdkOutputAnalyser.js";const _=3e5,R=18e4,L=12e5,o=Object.freeze({APP:"--app",CI:"--ci",REQUIRE_APPROVAL:"--require-approval",APPROVAL_NEVER:"never",VERBOSE:"--verbose",NO_LOOKUPS:"--no-lookups",ALL:"--all"});class U{processManager;argumentBuilder=new E;constructor(u){this.processManager=u}dispose(){this.processManager.dispose()}async checkDifferences(u,t,r){const e=["diff"];t?e.push(t):e.push(o.ALL),e.push("--no-color"),r?.noLookups&&e.push(o.NO_LOOKUPS);const s=await this.processManager.runCdkCommand(u,e,{...r,ignoreExitCode:!0,combineOutput:!0});if(!s.success)return n(new m(c(s.error,u),"diff_failed",void 0,void 0,s.error,void 0,!1));const a=s.data.output||"";if(O(a))return n(new m(c(a,u),"diff_failed",void 0,void 0,a,void 0,!1));const i=A(a),h=P(a);return p({hasDifferences:i,output:a,details:h})}async deploy(u,t,r){const e=["deploy"];r?.appDir?e.push(o.APP,r.appDir):r?.useCdkOut&&e.push(o.APP,"cdk.out"),t?e.push(t):e.push(o.ALL),e.push(o.REQUIRE_APPROVAL,o.APPROVAL_NEVER),e.push(o.CI),e.push("--no-version-reporting"),e.push("--no-path-metadata"),e.push("--no-asset-metadata"),r?.verbose?e.push(o.VERBOSE):e.push("--progress","events"),e.push(...this.argumentBuilder.buildParameterArgs(r?.parameters));const s={...r,timeout:r?.timeout||f};return r?.passThroughCDK?this.processManager.runCdkCommandPassthrough(u,e,s):this.processManager.runCdkCommand(u,e,s)}async destroy(u,t,r){const e=["destroy"];r?.appDir?e.push(o.APP,r.appDir):r?.useCdkOut&&e.push(o.APP,"cdk.out"),t?e.push(t):e.push(o.ALL),e.push("--force"),r?.verbose&&e.push(o.VERBOSE);const s={...r,timeout:r?.timeout||f};return this.processManager.runCdkCommand(u,e,s)}async runImport(u,t,r){const e=["import"];r?.stacks&&r.stacks.length>0&&e.push(...r.stacks),t&&e.push("--resource-mapping",t),e.push(o.REQUIRE_APPROVAL,o.APPROVAL_NEVER),e.push(o.CI),r?.noLookups&&e.push(o.NO_LOOKUPS),r?.verbose&&(e.push(o.VERBOSE),e.push("--trace"),e.push("--debug"));const s={...r,timeout:r?.timeout||L};return r?.passThroughCDK?this.processManager.runCdkCommandPassthrough(u,e,s):this.processManager.runCdkCommand(u,e,s)}async synth(u,t){t?.outputCallback?.(`Synthesising CloudFormation template...
2
- `);const r=t?.noLookups?[o.NO_LOOKUPS]:[],e=t?.outputDir?["--output",t.outputDir]:[],s=t?.context?.region||C,a=await this.processManager.runCdkCommand(u,["synth",...r,...e,o.CI,"--quiet"],{...t,context:{...t?.context,region:s},timeout:t?.timeout||_});if(!a.success){const i=a.error?c(a.error,u):"Failed to synthesise CloudFormation template";return n(i)}return a}async bootstrap(u,t,r){const e=l();d.debug("CdkService","Starting CDK bootstrap",{accountId:u,region:t,bootstrapPath:e,target:`aws://${u}/${t}`});const s=await this.processManager.runCdkCommand(e,["bootstrap",`aws://${u}/${t}`,"--cloudformation-execution-policies","arn:aws:iam::aws:policy/AdministratorAccess","-c",`accountId=${u}`,o.REQUIRE_APPROVAL,o.APPROVAL_NEVER,o.CI,"--quiet","--force"],{...r,timeout:r?.timeout||R,context:{region:t,accountId:u},credentials:r?.credentials,skipProjectCheck:!0,extraEnv:{TERM:"dumb",CDK_DISABLE_NOTICES:"true",CDK_DISABLE_PROGRESS_BAR:"true"}});return d.debug("CdkService",s.success?"Bootstrap completed successfully":"Bootstrap exited with non-zero code",{accountId:u,region:t,exitCode:s.success?s.data.exitCode:void 0,output:s.success&&s.data.output?.trim()||"(empty)",error:s.success?"(empty)":s.error.trim()||"(empty)"}),s.success?p({output:"AWS environment bootstrapped",exitCode:0}):s.error.includes("already bootstrapped")?p({output:"Environment is already bootstrapped",exitCode:0}):n(g(s.error))}}export{R as BOOTSTRAP_TIMEOUT_MS,U as CdkCommandRunner,L as IMPORT_TIMEOUT_MS,_ as SYNTH_TIMEOUT_MS};
1
+ import{tmpdir as l}from"os";import{join as C}from"path";import{logger as m}from"@fjall/util/logger";import{success as c,failure as i}from"@fjall/generator";import{CdkError as f}from"../../types/errors/CdkError.js";import{DEFAULT_REGION as O}from"../../aws/utils/regions.js";import{CdkArgumentBuilder as E}from"./CdkArgumentBuilder.js";import{isCdkError as A,formatInfrastructureError as d}from"./CdkErrorFormatter.js";import{hasCdkDifferences as P,parseDiffOutput as _}from"./CdkOutputParser.js";import{DEFAULT_DEPLOY_TIMEOUT_MS as h}from"./CdkEventMonitoring.js";import{analyseBootstrapError as g}from"./CdkOutputAnalyser.js";const R=3e5,k=18e4,L=12e5,y="cdk.out",u=Object.freeze({APP:"--app",CI:"--ci",REQUIRE_APPROVAL:"--require-approval",APPROVAL_NEVER:"never",VERBOSE:"--verbose",NO_LOOKUPS:"--no-lookups",ALL:"--all"});class K{processManager;argumentBuilder=new E;constructor(o){this.processManager=o}dispose(){this.processManager.dispose()}async checkDifferences(o,t,r){const e=["diff"];t?e.push(t):e.push(u.ALL),e.push("--no-color"),r?.noLookups&&e.push(u.NO_LOOKUPS);const s=await this.processManager.runCdkCommand(o,e,{...r,ignoreExitCode:!0,combineOutput:!0});if(!s.success)return i(new f(d(s.error,o),"diff_failed",void 0,void 0,s.error,void 0,!1));const a=s.data.output||"";if(A(a))return i(new f(d(a,o),"diff_failed",void 0,void 0,a,void 0,!1));const n=P(a),p=_(a);return c({hasDifferences:n,output:a,details:p})}async deploy(o,t,r){const e=["deploy"];r?.appDir?e.push(u.APP,r.appDir):r?.useCdkOut&&e.push(u.APP,"cdk.out"),t?e.push(t):e.push(u.ALL),e.push(u.REQUIRE_APPROVAL,u.APPROVAL_NEVER),e.push(u.CI),e.push("--no-version-reporting"),e.push("--no-path-metadata"),e.push("--no-asset-metadata"),r?.verbose?e.push(u.VERBOSE):e.push("--progress","events"),e.push(...this.argumentBuilder.buildParameterArgs(r?.parameters));const s={...r,timeout:r?.timeout||h};return r?.passThroughCDK?this.processManager.runCdkCommandPassthrough(o,e,s):this.processManager.runCdkCommand(o,e,s)}async destroy(o,t,r){const e=["destroy"];r?.appDir?e.push(u.APP,r.appDir):r?.useCdkOut&&e.push(u.APP,"cdk.out"),t?e.push(t):e.push(u.ALL),e.push("--force"),r?.verbose&&e.push(u.VERBOSE);const s={...r,timeout:r?.timeout||h};return this.processManager.runCdkCommand(o,e,s)}async runImport(o,t,r){const e=["import"];r?.stacks&&r.stacks.length>0&&e.push(...r.stacks),t&&e.push("--resource-mapping",t),e.push(u.REQUIRE_APPROVAL,u.APPROVAL_NEVER),e.push(u.CI),r?.noLookups&&e.push(u.NO_LOOKUPS),r?.verbose&&(e.push(u.VERBOSE),e.push("--trace"),e.push("--debug"));const s={...r,timeout:r?.timeout||L};return r?.passThroughCDK?this.processManager.runCdkCommandPassthrough(o,e,s):this.processManager.runCdkCommand(o,e,s)}async synth(o,t){t?.outputCallback?.(`Synthesising CloudFormation template...
2
+ `);const r=t?.noLookups?[u.NO_LOOKUPS]:[],s=["--output",t?.outputDir??C(o,y)],a=t?.context?.region||O,n=await this.processManager.runCdkCommand(o,["synth",...r,...s,u.CI,"--quiet"],{...t,context:{...t?.context,region:a},timeout:t?.timeout||R});if(!n.success){const p=n.error?d(n.error,o):"Failed to synthesise CloudFormation template";return i(p)}return n}async bootstrap(o,t,r){const e=l();m.debug("CdkService","Starting CDK bootstrap",{accountId:o,region:t,bootstrapPath:e,target:`aws://${o}/${t}`});const s=await this.processManager.runCdkCommand(e,["bootstrap",`aws://${o}/${t}`,"--cloudformation-execution-policies","arn:aws:iam::aws:policy/AdministratorAccess","-c",`accountId=${o}`,u.REQUIRE_APPROVAL,u.APPROVAL_NEVER,u.CI,"--quiet","--force"],{...r,timeout:r?.timeout||k,context:{region:t,accountId:o},credentials:r?.credentials,skipProjectCheck:!0,extraEnv:{TERM:"dumb",CDK_DISABLE_NOTICES:"true",CDK_DISABLE_PROGRESS_BAR:"true"}});return m.debug("CdkService",s.success?"Bootstrap completed successfully":"Bootstrap exited with non-zero code",{accountId:o,region:t,exitCode:s.success?s.data.exitCode:void 0,output:s.success&&s.data.output?.trim()||"(empty)",error:s.success?"(empty)":s.error.trim()||"(empty)"}),s.success?c({output:"AWS environment bootstrapped",exitCode:0}):s.error.includes("already bootstrapped")?c({output:"Environment is already bootstrapped",exitCode:0}):i(g(s.error))}}export{k as BOOTSTRAP_TIMEOUT_MS,K as CdkCommandRunner,L as IMPORT_TIMEOUT_MS,R as SYNTH_TIMEOUT_MS};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/deploy-core",
3
- "version": "1.1.0",
3
+ "version": "2.2.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",
@@ -73,7 +73,7 @@
73
73
  "@aws-sdk/client-s3": "^3.1038.0",
74
74
  "@aws-sdk/client-sso-admin": "^3.1038.0",
75
75
  "@aws-sdk/client-sts": "^3.1038.0",
76
- "@fjall/generator": "^1.1.0",
76
+ "@fjall/generator": "^2.2.0",
77
77
  "@fjall/util": "^0.100.0",
78
78
  "@smithy/node-http-handler": "^4.6.1",
79
79
  "zod": "^4.4.3"
@@ -82,5 +82,5 @@
82
82
  "@types/node": "^25.6.0",
83
83
  "vitest": "^4.1.5"
84
84
  },
85
- "gitHead": "437ec726425bd7610b83a57c12c1a4e1980bbb01"
85
+ "gitHead": "cd83079d6ed53b131e4c97b5966dc0d8715c8735"
86
86
  }