@fjall/deploy-core 0.89.2
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/LICENSE +21 -0
- package/dist/src/aws/AwsProvider.d.ts +39 -0
- package/dist/src/aws/AwsProvider.js +1 -0
- package/dist/src/aws/SimpleAwsProvider.d.ts +22 -0
- package/dist/src/aws/SimpleAwsProvider.js +73 -0
- package/dist/src/aws/index.d.ts +4 -0
- package/dist/src/aws/index.js +3 -0
- package/dist/src/aws/organisations/accounts.d.ts +21 -0
- package/dist/src/aws/organisations/accounts.js +99 -0
- package/dist/src/aws/organisations/backup.d.ts +12 -0
- package/dist/src/aws/organisations/backup.js +28 -0
- package/dist/src/aws/organisations/costAllocation.d.ts +12 -0
- package/dist/src/aws/organisations/costAllocation.js +26 -0
- package/dist/src/aws/organisations/identityCentre.d.ts +8 -0
- package/dist/src/aws/organisations/identityCentre.js +19 -0
- package/dist/src/aws/organisations/index.d.ts +16 -0
- package/dist/src/aws/organisations/index.js +12 -0
- package/dist/src/aws/organisations/ipam.d.ts +7 -0
- package/dist/src/aws/organisations/ipam.js +18 -0
- package/dist/src/aws/organisations/organisation.d.ts +12 -0
- package/dist/src/aws/organisations/organisation.js +94 -0
- package/dist/src/aws/organisations/organisationalUnits.d.ts +19 -0
- package/dist/src/aws/organisations/organisationalUnits.js +125 -0
- package/dist/src/aws/organisations/policies.d.ts +7 -0
- package/dist/src/aws/organisations/policies.js +36 -0
- package/dist/src/aws/organisations/ram.d.ts +7 -0
- package/dist/src/aws/organisations/ram.js +15 -0
- package/dist/src/aws/organisations/serviceAccess.d.ts +7 -0
- package/dist/src/aws/organisations/serviceAccess.js +38 -0
- package/dist/src/aws/organisations/trustedAccess.d.ts +7 -0
- package/dist/src/aws/organisations/trustedAccess.js +15 -0
- package/dist/src/aws/organisations/types.d.ts +29 -0
- package/dist/src/aws/organisations/types.js +16 -0
- package/dist/src/aws/utils/CloudFormationFailureAnalyser.d.ts +32 -0
- package/dist/src/aws/utils/CloudFormationFailureAnalyser.js +228 -0
- package/dist/src/aws/utils/cloudformationEvents.d.ts +98 -0
- package/dist/src/aws/utils/cloudformationEvents.js +596 -0
- package/dist/src/aws/utils/errors.d.ts +26 -0
- package/dist/src/aws/utils/errors.js +59 -0
- package/dist/src/aws/utils/regions.d.ts +1 -0
- package/dist/src/aws/utils/regions.js +1 -0
- package/dist/src/aws/utils/stackStatus.d.ts +23 -0
- package/dist/src/aws/utils/stackStatus.js +90 -0
- package/dist/src/index.d.ts +35 -0
- package/dist/src/index.js +45 -0
- package/dist/src/orchestration/applicationDeploy.d.ts +11 -0
- package/dist/src/orchestration/applicationDeploy.js +327 -0
- package/dist/src/orchestration/contextHelpers.d.ts +9 -0
- package/dist/src/orchestration/contextHelpers.js +14 -0
- package/dist/src/orchestration/deploy.d.ts +10 -0
- package/dist/src/orchestration/deploy.js +42 -0
- package/dist/src/orchestration/detectionPipeline.d.ts +23 -0
- package/dist/src/orchestration/detectionPipeline.js +65 -0
- package/dist/src/orchestration/dockerInterface.d.ts +56 -0
- package/dist/src/orchestration/dockerInterface.js +1 -0
- package/dist/src/orchestration/domainInterface.d.ts +37 -0
- package/dist/src/orchestration/domainInterface.js +1 -0
- package/dist/src/orchestration/index.d.ts +8 -0
- package/dist/src/orchestration/index.js +3 -0
- package/dist/src/orchestration/organisationDeploy.d.ts +16 -0
- package/dist/src/orchestration/organisationDeploy.js +382 -0
- package/dist/src/orchestration/organisationSetup.d.ts +42 -0
- package/dist/src/orchestration/organisationSetup.js +227 -0
- package/dist/src/orchestration/resolveOperation.d.ts +10 -0
- package/dist/src/orchestration/resolveOperation.js +53 -0
- package/dist/src/orchestration/serviceFactory.d.ts +15 -0
- package/dist/src/orchestration/serviceFactory.js +16 -0
- package/dist/src/services/application/ApplicationStackService.d.ts +93 -0
- package/dist/src/services/application/ApplicationStackService.js +436 -0
- package/dist/src/services/application/index.d.ts +1 -0
- package/dist/src/services/application/index.js +1 -0
- package/dist/src/services/infrastructure/CdkArgumentBuilder.d.ts +12 -0
- package/dist/src/services/infrastructure/CdkArgumentBuilder.js +67 -0
- package/dist/src/services/infrastructure/CdkCommandRunner.d.ts +30 -0
- package/dist/src/services/infrastructure/CdkCommandRunner.js +241 -0
- package/dist/src/services/infrastructure/CdkErrorFormatter.d.ts +4 -0
- package/dist/src/services/infrastructure/CdkErrorFormatter.js +194 -0
- package/dist/src/services/infrastructure/CdkEventMonitoring.d.ts +19 -0
- package/dist/src/services/infrastructure/CdkEventMonitoring.js +41 -0
- package/dist/src/services/infrastructure/CdkOutputAnalyser.d.ts +43 -0
- package/dist/src/services/infrastructure/CdkOutputAnalyser.js +125 -0
- package/dist/src/services/infrastructure/CdkOutputParser.d.ts +8 -0
- package/dist/src/services/infrastructure/CdkOutputParser.js +33 -0
- package/dist/src/services/infrastructure/CdkProcessManager.d.ts +20 -0
- package/dist/src/services/infrastructure/CdkProcessManager.js +244 -0
- package/dist/src/services/infrastructure/CdkService.d.ts +71 -0
- package/dist/src/services/infrastructure/CdkService.js +254 -0
- package/dist/src/services/infrastructure/CloudFormationService.d.ts +79 -0
- package/dist/src/services/infrastructure/CloudFormationService.js +249 -0
- package/dist/src/services/infrastructure/index.d.ts +8 -0
- package/dist/src/services/infrastructure/index.js +7 -0
- package/dist/src/services/supporting/CdkContextBuilder.d.ts +49 -0
- package/dist/src/services/supporting/CdkContextBuilder.js +44 -0
- package/dist/src/services/supporting/TemplateHashService.d.ts +67 -0
- package/dist/src/services/supporting/TemplateHashService.js +152 -0
- package/dist/src/services/supporting/helpers.d.ts +46 -0
- package/dist/src/services/supporting/helpers.js +81 -0
- package/dist/src/services/supporting/index.d.ts +3 -0
- package/dist/src/services/supporting/index.js +3 -0
- package/dist/src/types/FjallState.d.ts +50 -0
- package/dist/src/types/FjallState.js +118 -0
- package/dist/src/types/ProgressEvent.d.ts +35 -0
- package/dist/src/types/ProgressEvent.js +48 -0
- package/dist/src/types/apiClient.d.ts +34 -0
- package/dist/src/types/apiClient.js +1 -0
- package/dist/src/types/application/ApplicationServiceTypes.d.ts +56 -0
- package/dist/src/types/application/ApplicationServiceTypes.js +30 -0
- package/dist/src/types/application/index.d.ts +1 -0
- package/dist/src/types/application/index.js +1 -0
- package/dist/src/types/callbacks.d.ts +36 -0
- package/dist/src/types/callbacks.js +1 -0
- package/dist/src/types/constants.d.ts +6 -0
- package/dist/src/types/constants.js +6 -0
- package/dist/src/types/credentials.d.ts +30 -0
- package/dist/src/types/credentials.js +1 -0
- package/dist/src/types/deployment/DeploymentServiceTypes.d.ts +23 -0
- package/dist/src/types/deployment/DeploymentServiceTypes.js +1 -0
- package/dist/src/types/deployment/DeploymentTypes.d.ts +29 -0
- package/dist/src/types/deployment/DeploymentTypes.js +1 -0
- package/dist/src/types/deployment/cloudformation.d.ts +14 -0
- package/dist/src/types/deployment/cloudformation.js +1 -0
- package/dist/src/types/deployment/index.d.ts +5 -0
- package/dist/src/types/deployment/index.js +1 -0
- package/dist/src/types/deployment/parallel.d.ts +46 -0
- package/dist/src/types/deployment/parallel.js +10 -0
- package/dist/src/types/errors/CdkError.d.ts +14 -0
- package/dist/src/types/errors/CdkError.js +20 -0
- package/dist/src/types/errors/ServiceError.d.ts +86 -0
- package/dist/src/types/errors/ServiceError.js +119 -0
- package/dist/src/types/events.d.ts +40 -0
- package/dist/src/types/events.js +5 -0
- package/dist/src/types/index.d.ts +20 -0
- package/dist/src/types/index.js +9 -0
- package/dist/src/types/operations.d.ts +193 -0
- package/dist/src/types/operations.js +285 -0
- package/dist/src/types/orgConfig.d.ts +28 -0
- package/dist/src/types/orgConfig.js +11 -0
- package/dist/src/types/params.d.ts +74 -0
- package/dist/src/types/params.js +1 -0
- package/dist/src/types/patternDetection.d.ts +43 -0
- package/dist/src/types/patternDetection.js +92 -0
- package/dist/src/types/validation.d.ts +12 -0
- package/dist/src/types/validation.js +1 -0
- package/dist/src/util/fsHelpers.d.ts +4 -0
- package/dist/src/util/fsHelpers.js +16 -0
- package/dist/src/util/index.d.ts +3 -0
- package/dist/src/util/index.js +3 -0
- package/dist/src/util/securityHelpers.d.ts +31 -0
- package/dist/src/util/securityHelpers.js +124 -0
- package/dist/src/util/singleton.d.ts +2 -0
- package/dist/src/util/singleton.js +9 -0
- package/dist/src/util/sleep.d.ts +4 -0
- package/dist/src/util/sleep.js +4 -0
- package/package.json +42 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { DEFAULT_REGION, regions, AWS_REGIONS_METADATA, topRegions, commonRegions, parseRegionList, isValidRegion, isValidRegionFormat, getSuggestions, validateRegion, validateRegionList, filterDuplicateRegions, getRegionOptions, getRegionOptionsExcluding, getRegionName, createRegionFormatter } from "@fjall/generator";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CloudFormationStackStatus {
|
|
2
|
+
status: string;
|
|
3
|
+
safeToRedeploy: "Yes" | "No" | "Maybe";
|
|
4
|
+
description: string;
|
|
5
|
+
statusReason?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CloudFormationOutput {
|
|
8
|
+
OutputKey?: string;
|
|
9
|
+
OutputValue?: string;
|
|
10
|
+
ExportName?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface DetailedStackStatus extends CloudFormationStackStatus {
|
|
13
|
+
needsRedeploy: boolean;
|
|
14
|
+
isInProgress: boolean;
|
|
15
|
+
isFailed: boolean;
|
|
16
|
+
isComplete: boolean;
|
|
17
|
+
canProceed: boolean;
|
|
18
|
+
recommendation?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const stackStatusMap: Record<string, {
|
|
21
|
+
safeToRedeploy: "Yes" | "No" | "Maybe";
|
|
22
|
+
description: string;
|
|
23
|
+
}>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export const stackStatusMap = {
|
|
2
|
+
CREATE_IN_PROGRESS: {
|
|
3
|
+
safeToRedeploy: "No",
|
|
4
|
+
description: "Stack is busy with creation"
|
|
5
|
+
},
|
|
6
|
+
CREATE_COMPLETE: {
|
|
7
|
+
safeToRedeploy: "Yes",
|
|
8
|
+
description: "Stack was successfully created"
|
|
9
|
+
},
|
|
10
|
+
CREATE_FAILED: {
|
|
11
|
+
safeToRedeploy: "Maybe",
|
|
12
|
+
description: "Stack creation failed - fix issues before redeploying"
|
|
13
|
+
},
|
|
14
|
+
DELETE_IN_PROGRESS: {
|
|
15
|
+
safeToRedeploy: "No",
|
|
16
|
+
description: "Stack is busy with deletion"
|
|
17
|
+
},
|
|
18
|
+
DELETE_COMPLETE: {
|
|
19
|
+
safeToRedeploy: "Yes",
|
|
20
|
+
description: "Stack was successfully deleted"
|
|
21
|
+
},
|
|
22
|
+
DELETE_FAILED: {
|
|
23
|
+
safeToRedeploy: "Maybe",
|
|
24
|
+
description: "Stack deletion failed - investigate before redeploying"
|
|
25
|
+
},
|
|
26
|
+
ROLLBACK_IN_PROGRESS: {
|
|
27
|
+
safeToRedeploy: "No",
|
|
28
|
+
description: "Stack is rolling back due to failure"
|
|
29
|
+
},
|
|
30
|
+
ROLLBACK_COMPLETE: {
|
|
31
|
+
safeToRedeploy: "Yes",
|
|
32
|
+
description: "Stack rolled back due to failure - fix issues before redeploying"
|
|
33
|
+
},
|
|
34
|
+
ROLLBACK_FAILED: {
|
|
35
|
+
safeToRedeploy: "No",
|
|
36
|
+
description: "Rollback failed - manual intervention needed"
|
|
37
|
+
},
|
|
38
|
+
UPDATE_IN_PROGRESS: {
|
|
39
|
+
safeToRedeploy: "No",
|
|
40
|
+
description: "Stack update is in progress"
|
|
41
|
+
},
|
|
42
|
+
UPDATE_COMPLETE: {
|
|
43
|
+
safeToRedeploy: "Yes",
|
|
44
|
+
description: "Stack update completed successfully"
|
|
45
|
+
},
|
|
46
|
+
UPDATE_FAILED: {
|
|
47
|
+
safeToRedeploy: "Maybe",
|
|
48
|
+
description: "Stack update failed - fix issues before redeploying"
|
|
49
|
+
},
|
|
50
|
+
UPDATE_ROLLBACK_IN_PROGRESS: {
|
|
51
|
+
safeToRedeploy: "No",
|
|
52
|
+
description: "Stack is rolling back an update"
|
|
53
|
+
},
|
|
54
|
+
UPDATE_ROLLBACK_COMPLETE: {
|
|
55
|
+
safeToRedeploy: "Yes",
|
|
56
|
+
description: "Stack update rolled back successfully"
|
|
57
|
+
},
|
|
58
|
+
UPDATE_ROLLBACK_FAILED: {
|
|
59
|
+
safeToRedeploy: "No",
|
|
60
|
+
description: "Update rollback failed - manual fix needed"
|
|
61
|
+
},
|
|
62
|
+
IMPORT_IN_PROGRESS: {
|
|
63
|
+
safeToRedeploy: "No",
|
|
64
|
+
description: "Resource import in progress"
|
|
65
|
+
},
|
|
66
|
+
IMPORT_COMPLETE: {
|
|
67
|
+
safeToRedeploy: "Yes",
|
|
68
|
+
description: "Resource import completed successfully"
|
|
69
|
+
},
|
|
70
|
+
IMPORT_ROLLBACK_IN_PROGRESS: {
|
|
71
|
+
safeToRedeploy: "No",
|
|
72
|
+
description: "Import rollback in progress"
|
|
73
|
+
},
|
|
74
|
+
IMPORT_ROLLBACK_COMPLETE: {
|
|
75
|
+
safeToRedeploy: "Yes",
|
|
76
|
+
description: "Import rollback completed"
|
|
77
|
+
},
|
|
78
|
+
IMPORT_ROLLBACK_FAILED: {
|
|
79
|
+
safeToRedeploy: "No",
|
|
80
|
+
description: "Import rollback failed - manual fix needed"
|
|
81
|
+
},
|
|
82
|
+
REVIEW_IN_PROGRESS: {
|
|
83
|
+
safeToRedeploy: "Yes",
|
|
84
|
+
description: "Stack is in review mode"
|
|
85
|
+
},
|
|
86
|
+
UNKNOWN: {
|
|
87
|
+
safeToRedeploy: "Maybe",
|
|
88
|
+
description: "Unknown stack status"
|
|
89
|
+
}
|
|
90
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fjall/deploy-core — Shared Deployment Engine
|
|
3
|
+
*
|
|
4
|
+
* This package contains the deployment logic shared between the CLI and
|
|
5
|
+
* the webapp worker. Both callers construct a DeployParams object and
|
|
6
|
+
* call deploy(). The engine handles CDK synthesis, CloudFormation
|
|
7
|
+
* deployment, Docker builds, and multi-account cascade — reporting
|
|
8
|
+
* progress via typed callbacks.
|
|
9
|
+
*
|
|
10
|
+
* Auth, config discovery, and output formatting are the caller's
|
|
11
|
+
* responsibility. deploy-core receives credentials and a working
|
|
12
|
+
* directory; it never reads credential files or writes to the terminal.
|
|
13
|
+
*/
|
|
14
|
+
export type { AwsCredentials, DeployIdentity, DeployCallbacks, StepCompleteStatus, ProgressEvent, ProgressEventType, ResourceEvent, AwsAuthResult, CascadeDeploymentResult, CascadePhase, ApiClientInterface, EntitlementsData, DeployParams, DeployOptions, DeploymentType, DeployResult, OrgConfig, ProviderAccount, SSOSession } from "./types/index.js";
|
|
15
|
+
export type { AwsProvider, AwsProviderCredentials, AwsSdkClientConstructor } from "./aws/index.js";
|
|
16
|
+
export { SimpleAwsProvider } from "./aws/index.js";
|
|
17
|
+
export { ensureOrganisationExists, describeOrganisation, enablePolicyTypes, enableServiceAccess, enableRamSharing, activateTrustedAccess, enableIpamDelegatedAdmin, updateBackupGlobalSettings, listAccounts, findAccount, createAccount, ensureOrganisationalUnitsExist, placeAccountsInOUs, activateCostAllocationTags, checkIdentityCentreStatus } from "./aws/index.js";
|
|
18
|
+
export type { OrgDetails, OUMap, AccountPlacementResult, AccountInfo, IdentityCentreStatus, BackupGlobalSettings, CostAllocationTag, CreateAccountResult } from "./aws/index.js";
|
|
19
|
+
export type { DeploymentContext, StepOutput, ApplicationDeploymentContext, CallerIdentity, StackOutput, StackOutputsRecord, ValidationResult, ProgressCallbacks, ApplicationStack, OrganisationType, DeploymentOperation, ApplicationOperation, OrganisationOperation, DeployOrderOptions, OpenNextPattern, AppResourceFlags, ParallelDeploymentResult, ParallelDeployGroup, ParallelOperation, ParallelOperationType, ParallelOperationState, ApplicationErrorType, StackDeploymentData, StackDeploymentOptions, ApplicationDeploymentData, ApplicationDestructionData, FjallStateFile, TemplateHashEntry } from "./types/index.js";
|
|
20
|
+
export { ProgressReporter, APPLICATION_STACKS, ORGANISATION_TYPES, APPLICATION_DEPLOY_ORDER, APPLICATION_DESTROY_ORDER, OPENNEXT_DEPLOY_ORDER, OPENNEXT_DESTROY_ORDER, PARALLEL_DEPLOY_GROUPS, PARALLEL_DESTROY_GROUPS, OPENNEXT_PARALLEL_GROUPS, PARALLEL_OPERATION_TYPES, isApplicationOperation, isOrganisationOperation, getParallelDeployGroups, getParallelDestroyGroups, getApplicationDeployOrder, getApplicationDestroyOrder, getApplicationStackName, getOrganisationStackName, isApplicationStack, getApplicationStepName, getApplicationStepId, toPascalCase, isOpenNextPattern, OPENNEXT_PATTERNS, detectPattern, detectPayloadPattern, detectDatabase, deriveResourcesFromManifestStacks, STACK_NOT_FOUND_PATTERN, CDK_NO_STACKS_MATCH, INFRASTRUCTURE_FILENAME, ApplicationError, wrapApplicationError, FjallStateFileSchema, readStateFile, writeStateFile, createEmptyState, deleteStateFile, updateTemplateHash, getStateFilePath } from "./types/index.js";
|
|
21
|
+
export { CdkService, CdkArgumentBuilder, CdkProcessManager, CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS, isCdkError, formatInfrastructureError, hasCdkDifferences, parseDiffOutput, CloudFormationService, CloudFormationError } from "./services/infrastructure/index.js";
|
|
22
|
+
export type { CdkContext, CdkOptions, CdkOutput, CheckDifferencesResult, CdkServiceOptions, DiffDetails, CloudFormationCallbacks } from "./services/infrastructure/index.js";
|
|
23
|
+
export { TemplateHashService, TemplateHashError, type TemplateComparisonResult } from "./services/supporting/index.js";
|
|
24
|
+
export { CdkContextBuilder } from "./services/supporting/index.js";
|
|
25
|
+
export { emitProgress, PROGRESS_MESSAGES, parseBuildPhase, buildStepContextBuildConfig, convertCloudFormationOutputsToRecord, type CloudFormationOutput } from "./services/supporting/index.js";
|
|
26
|
+
export { ApplicationStackService } from "./services/application/index.js";
|
|
27
|
+
export { CdkError } from "./types/errors/CdkError.js";
|
|
28
|
+
export { BaseServiceError } from "./types/errors/ServiceError.js";
|
|
29
|
+
export { filterDangerousEnvVars, maskSensitiveOutput, parseShellArgs } from "./util/securityHelpers.js";
|
|
30
|
+
export { sleep } from "./util/sleep.js";
|
|
31
|
+
export { fileExists } from "./util/fsHelpers.js";
|
|
32
|
+
export { type Result, success, failure, isSuccess, isFailure } from "@fjall/generator";
|
|
33
|
+
export { deploy } from "./orchestration/index.js";
|
|
34
|
+
export { runOrganisationSetup } from "./orchestration/index.js";
|
|
35
|
+
export type { OrgSetupPhase, OrgSetupCallbacks, OrgSetupConfig, OrgSetupResult, DockerProvider, DockerBuildParams, DockerBuildResult, ECRInitParams, ECRInitResult, TagImagesParams, TagImagesResult, DomainDeployProvider, DomainConfig, DomainDeployResult, DeployServices, DetectionResult } from "./orchestration/index.js";
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fjall/deploy-core — Shared Deployment Engine
|
|
3
|
+
*
|
|
4
|
+
* This package contains the deployment logic shared between the CLI and
|
|
5
|
+
* the webapp worker. Both callers construct a DeployParams object and
|
|
6
|
+
* call deploy(). The engine handles CDK synthesis, CloudFormation
|
|
7
|
+
* deployment, Docker builds, and multi-account cascade — reporting
|
|
8
|
+
* progress via typed callbacks.
|
|
9
|
+
*
|
|
10
|
+
* Auth, config discovery, and output formatting are the caller's
|
|
11
|
+
* responsibility. deploy-core receives credentials and a working
|
|
12
|
+
* directory; it never reads credential files or writes to the terminal.
|
|
13
|
+
*/
|
|
14
|
+
export { SimpleAwsProvider } from "./aws/index.js";
|
|
15
|
+
// Organisation setup primitives
|
|
16
|
+
export { ensureOrganisationExists, describeOrganisation, enablePolicyTypes, enableServiceAccess, enableRamSharing, activateTrustedAccess, enableIpamDelegatedAdmin, updateBackupGlobalSettings, listAccounts, findAccount, createAccount, ensureOrganisationalUnitsExist, placeAccountsInOUs, activateCostAllocationTags, checkIdentityCentreStatus } from "./aws/index.js";
|
|
17
|
+
export { ProgressReporter, APPLICATION_STACKS, ORGANISATION_TYPES, APPLICATION_DEPLOY_ORDER, APPLICATION_DESTROY_ORDER, OPENNEXT_DEPLOY_ORDER, OPENNEXT_DESTROY_ORDER, PARALLEL_DEPLOY_GROUPS, PARALLEL_DESTROY_GROUPS, OPENNEXT_PARALLEL_GROUPS, PARALLEL_OPERATION_TYPES, isApplicationOperation, isOrganisationOperation, getParallelDeployGroups, getParallelDestroyGroups, getApplicationDeployOrder, getApplicationDestroyOrder, getApplicationStackName, getOrganisationStackName, isApplicationStack, getApplicationStepName, getApplicationStepId, toPascalCase, isOpenNextPattern, OPENNEXT_PATTERNS,
|
|
18
|
+
// Pattern detection
|
|
19
|
+
detectPattern, detectPayloadPattern, detectDatabase, deriveResourcesFromManifestStacks,
|
|
20
|
+
// Constants
|
|
21
|
+
STACK_NOT_FOUND_PATTERN, CDK_NO_STACKS_MATCH, INFRASTRUCTURE_FILENAME,
|
|
22
|
+
// Application errors
|
|
23
|
+
ApplicationError, wrapApplicationError,
|
|
24
|
+
// State management
|
|
25
|
+
FjallStateFileSchema, readStateFile, writeStateFile, createEmptyState, deleteStateFile, updateTemplateHash, getStateFilePath } from "./types/index.js";
|
|
26
|
+
// Infrastructure services
|
|
27
|
+
export { CdkService, CdkArgumentBuilder, CdkProcessManager, CdkEventMonitor, startStackMonitoring, DEFAULT_DEPLOY_TIMEOUT_MS, isCdkError, formatInfrastructureError, hasCdkDifferences, parseDiffOutput, CloudFormationService, CloudFormationError } from "./services/infrastructure/index.js";
|
|
28
|
+
// Supporting services
|
|
29
|
+
export { TemplateHashService, TemplateHashError } from "./services/supporting/index.js";
|
|
30
|
+
export { CdkContextBuilder } from "./services/supporting/index.js";
|
|
31
|
+
export { emitProgress, PROGRESS_MESSAGES, parseBuildPhase, buildStepContextBuildConfig, convertCloudFormationOutputsToRecord } from "./services/supporting/index.js";
|
|
32
|
+
// Application services
|
|
33
|
+
export { ApplicationStackService } from "./services/application/index.js";
|
|
34
|
+
// Error types
|
|
35
|
+
export { CdkError } from "./types/errors/CdkError.js";
|
|
36
|
+
export { BaseServiceError } from "./types/errors/ServiceError.js";
|
|
37
|
+
// Utilities
|
|
38
|
+
export { filterDangerousEnvVars, maskSensitiveOutput, parseShellArgs } from "./util/securityHelpers.js";
|
|
39
|
+
export { sleep } from "./util/sleep.js";
|
|
40
|
+
export { fileExists } from "./util/fsHelpers.js";
|
|
41
|
+
// Re-export Result from generator for convenience
|
|
42
|
+
export { success, failure, isSuccess, isFailure } from "@fjall/generator";
|
|
43
|
+
// Orchestration — primary entry point
|
|
44
|
+
export { deploy } from "./orchestration/index.js";
|
|
45
|
+
export { runOrganisationSetup } from "./orchestration/index.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Result } from "@fjall/generator";
|
|
2
|
+
import type { DeployParams, DeployResult } from "../types/params.js";
|
|
3
|
+
import type { ApplicationOperation } from "../types/operations.js";
|
|
4
|
+
import type { DeployServices } from "./serviceFactory.js";
|
|
5
|
+
/**
|
|
6
|
+
* Core application deployment orchestration.
|
|
7
|
+
*
|
|
8
|
+
* Runs detection, bootstraps AWS, then deploys stacks in order —
|
|
9
|
+
* parallelising Phase 2 stacks (Storage, Messaging, Database) when possible.
|
|
10
|
+
*/
|
|
11
|
+
export declare function deployApplication(params: DeployParams, services: DeployServices, operation: ApplicationOperation): Promise<Result<DeployResult>>;
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { success, failure } from "@fjall/generator";
|
|
2
|
+
import { logger } from "@fjall/util";
|
|
3
|
+
import { APPLICATION_STACKS, getApplicationDeployOrder, getApplicationStackName, getApplicationStepName, getApplicationStepId, PARALLEL_DEPLOY_GROUPS } from "../types/operations.js";
|
|
4
|
+
import { CdkContextBuilder } from "../services/supporting/CdkContextBuilder.js";
|
|
5
|
+
import { emitProgress } from "../services/supporting/helpers.js";
|
|
6
|
+
import { buildParamsContext } from "./contextHelpers.js";
|
|
7
|
+
import { runDetectionPipeline } from "./detectionPipeline.js";
|
|
8
|
+
import { detectPattern } from "../types/patternDetection.js";
|
|
9
|
+
/**
|
|
10
|
+
* Core application deployment orchestration.
|
|
11
|
+
*
|
|
12
|
+
* Runs detection, bootstraps AWS, then deploys stacks in order —
|
|
13
|
+
* parallelising Phase 2 stacks (Storage, Messaging, Database) when possible.
|
|
14
|
+
*/
|
|
15
|
+
export async function deployApplication(params, services, operation) {
|
|
16
|
+
const { callbacks, options } = params;
|
|
17
|
+
const startTime = Date.now();
|
|
18
|
+
// 1. Build deployment context
|
|
19
|
+
const context = CdkContextBuilder.buildDeploymentContext({
|
|
20
|
+
deployType: "application",
|
|
21
|
+
target: operation.appName,
|
|
22
|
+
path: operation.path,
|
|
23
|
+
region: services.awsProvider.getRegion(),
|
|
24
|
+
...buildParamsContext(params)
|
|
25
|
+
}, {
|
|
26
|
+
verbose: options?.verbose,
|
|
27
|
+
infraOnly: options?.infraOnly
|
|
28
|
+
}, params.orgConfig);
|
|
29
|
+
// deployOnly: skip detection pipeline, deploy all stacks unconditionally
|
|
30
|
+
if (options?.deployOnly) {
|
|
31
|
+
callbacks.onLog?.("Deploy-only mode — skipping change detection", "info");
|
|
32
|
+
return deployAllStacks(params, services, operation, context, startTime);
|
|
33
|
+
}
|
|
34
|
+
// 2. Run detection pipeline
|
|
35
|
+
callbacks.onLog?.("Analysing infrastructure…", "info");
|
|
36
|
+
const detectionResult = await runDetectionPipeline(operation, services, context, callbacks);
|
|
37
|
+
if (!detectionResult.success) {
|
|
38
|
+
callbacks.onError?.(detectionResult.error);
|
|
39
|
+
return failure(detectionResult.error);
|
|
40
|
+
}
|
|
41
|
+
const detection = detectionResult.data;
|
|
42
|
+
// 3. Early exit if no differences
|
|
43
|
+
if (!detection.hasDifferences && !options?.force) {
|
|
44
|
+
callbacks.onLog?.("No infrastructure changes detected", "info");
|
|
45
|
+
return success({
|
|
46
|
+
target: operation.appName,
|
|
47
|
+
deploymentType: "application",
|
|
48
|
+
durationMs: Date.now() - startTime
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
// 4. Bootstrap AWS environment
|
|
52
|
+
callbacks.onCDKBootstrap?.("bootstrapping");
|
|
53
|
+
const bootstrapResult = await services.cdkService.runCdkBootstrap(context, (chunk) => callbacks.onOutput?.(chunk));
|
|
54
|
+
if (!bootstrapResult.success) {
|
|
55
|
+
callbacks.onCDKBootstrap?.("failed");
|
|
56
|
+
const error = new Error(`Bootstrap failed: ${bootstrapResult.error}`);
|
|
57
|
+
callbacks.onError?.(error);
|
|
58
|
+
return failure(error);
|
|
59
|
+
}
|
|
60
|
+
callbacks.onCDKBootstrap?.("complete");
|
|
61
|
+
// 5. Determine deploy order
|
|
62
|
+
const deployOrder = getApplicationDeployOrder({
|
|
63
|
+
pattern: detection.pattern,
|
|
64
|
+
resources: detection.resources
|
|
65
|
+
});
|
|
66
|
+
const totalSteps = deployOrder.length;
|
|
67
|
+
// 6. Deploy stacks
|
|
68
|
+
const allOutputs = {};
|
|
69
|
+
const deployedHashes = new Map();
|
|
70
|
+
for (let i = 0; i < deployOrder.length; i++) {
|
|
71
|
+
const stack = deployOrder[i];
|
|
72
|
+
const stackName = getApplicationStackName(operation.appName, stack);
|
|
73
|
+
const stepId = getApplicationStepId(stack, "deploy");
|
|
74
|
+
const stepName = getApplicationStepName(stack, "deploy");
|
|
75
|
+
// Check if stack is unchanged and exists
|
|
76
|
+
const hasChanges = detection.stackChanges.get(stackName) ?? true;
|
|
77
|
+
if (!hasChanges && !options?.force) {
|
|
78
|
+
callbacks.onStepStart?.(stepId, stepName, i, totalSteps);
|
|
79
|
+
callbacks.onLog?.(`Skipping ${stack} — no changes detected`, "info");
|
|
80
|
+
callbacks.onStepComplete?.(stepId, stepName, "skipped", i, totalSteps);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
// Check for Phase 2 parallel deployment opportunity
|
|
84
|
+
const parallelStacks = getParallelPhase2Stacks(deployOrder, i, detection.stackChanges, options?.force);
|
|
85
|
+
if (parallelStacks.length >= 2) {
|
|
86
|
+
const parallelResult = await deployParallelPhase(parallelStacks, operation, services, context, callbacks, i, totalSteps, detection, allOutputs, deployedHashes);
|
|
87
|
+
if (!parallelResult.success)
|
|
88
|
+
return failure(parallelResult.error);
|
|
89
|
+
// Skip past the parallel stacks in the main loop
|
|
90
|
+
i += parallelStacks.length - 1;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
// Docker build before Compute stack
|
|
94
|
+
if (stack === APPLICATION_STACKS.COMPUTE &&
|
|
95
|
+
detection.hasDockerfile &&
|
|
96
|
+
params.dockerProvider) {
|
|
97
|
+
const dockerResult = await runDockerBuild(params, services, operation, callbacks);
|
|
98
|
+
if (!dockerResult.success)
|
|
99
|
+
return failure(dockerResult.error);
|
|
100
|
+
}
|
|
101
|
+
// Sequential deployment
|
|
102
|
+
const deployResult = await deployStackSequential(stack, services, context, callbacks, i, totalSteps, allOutputs);
|
|
103
|
+
if (!deployResult.success)
|
|
104
|
+
return failure(deployResult.error);
|
|
105
|
+
// Track deployed hashes
|
|
106
|
+
const hash = detection.currentHashes.get(stackName);
|
|
107
|
+
if (hash) {
|
|
108
|
+
deployedHashes.set(stackName, hash);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// 7. Update state file with deployed hashes
|
|
112
|
+
if (deployedHashes.size > 0) {
|
|
113
|
+
const stateResult = await services.hashService.updateStateAfterDeploy(operation.path, deployedHashes);
|
|
114
|
+
if (!stateResult.success) {
|
|
115
|
+
logger.debug("applicationDeploy", "Failed to update state file", {
|
|
116
|
+
error: stateResult.error.message
|
|
117
|
+
});
|
|
118
|
+
callbacks.onLog?.(`Warning: failed to update state file — next deploy may re-deploy unchanged stacks: ${stateResult.error.message}`, "warn");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// 8. Resolve website URL
|
|
122
|
+
const websiteUrl = await services.stackService.resolveWebsiteUrl(operation.appName);
|
|
123
|
+
if (websiteUrl) {
|
|
124
|
+
allOutputs.websiteUrl = websiteUrl;
|
|
125
|
+
}
|
|
126
|
+
return success({
|
|
127
|
+
target: operation.appName,
|
|
128
|
+
deploymentType: "application",
|
|
129
|
+
outputs: Object.keys(allOutputs).length > 0 ? allOutputs : undefined,
|
|
130
|
+
durationMs: Date.now() - startTime
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Identify Phase 2 stacks (Storage, Messaging, Database) that are consecutive
|
|
135
|
+
* in the deploy order and have changes. Returns them for parallel deployment
|
|
136
|
+
* only if there are at least 2.
|
|
137
|
+
*/
|
|
138
|
+
function getParallelPhase2Stacks(deployOrder, currentIndex, stackChanges, force) {
|
|
139
|
+
const phase2Set = new Set(PARALLEL_DEPLOY_GROUPS.PHASE_2.stacks);
|
|
140
|
+
const candidates = [];
|
|
141
|
+
for (let j = currentIndex; j < deployOrder.length; j++) {
|
|
142
|
+
if (phase2Set.has(deployOrder[j])) {
|
|
143
|
+
candidates.push(deployOrder[j]);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (candidates.length < 2)
|
|
150
|
+
return [];
|
|
151
|
+
// Only include stacks that actually have changes (unless forced)
|
|
152
|
+
if (!force) {
|
|
153
|
+
const withChanges = candidates.filter((stack) => {
|
|
154
|
+
// stackChanges is keyed by full stack name but we only have the type here;
|
|
155
|
+
// since we don't know the app name, check all entries ending with the stack type
|
|
156
|
+
for (const [key, changed] of stackChanges) {
|
|
157
|
+
if (key.endsWith(stack) && !changed)
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
161
|
+
});
|
|
162
|
+
return withChanges.length >= 2 ? withChanges : [];
|
|
163
|
+
}
|
|
164
|
+
return candidates;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Deploy a group of stacks in parallel, reporting step events for each.
|
|
168
|
+
*/
|
|
169
|
+
async function deployParallelPhase(stacks, operation, services, context, callbacks, startIndex, totalSteps, detection, allOutputs, deployedHashes) {
|
|
170
|
+
// Emit step start for each parallel stack
|
|
171
|
+
for (let k = 0; k < stacks.length; k++) {
|
|
172
|
+
const stack = stacks[k];
|
|
173
|
+
const stepId = getApplicationStepId(stack, "deploy");
|
|
174
|
+
const stepName = getApplicationStepName(stack, "deploy");
|
|
175
|
+
callbacks.onStepStart?.(stepId, stepName, startIndex + k, totalSteps);
|
|
176
|
+
}
|
|
177
|
+
emitProgress(callbacks, "Deploying infrastructure in parallel…");
|
|
178
|
+
const parallelResult = await services.stackService.deployStacksInParallel(stacks, context, {
|
|
179
|
+
onOutput: (chunk) => callbacks.onOutput?.(chunk),
|
|
180
|
+
onResourceProgress: (event) => callbacks.onResourceProgress?.(event),
|
|
181
|
+
onStackComplete: (stack, stackSuccess, _duration, error) => {
|
|
182
|
+
const stepId = getApplicationStepId(stack, "deploy");
|
|
183
|
+
const stepName = getApplicationStepName(stack, "deploy");
|
|
184
|
+
const idx = startIndex + stacks.indexOf(stack);
|
|
185
|
+
callbacks.onStepComplete?.(stepId, stepName, stackSuccess ? "completed" : "error", idx, totalSteps);
|
|
186
|
+
if (!stackSuccess && error) {
|
|
187
|
+
callbacks.onError?.(error);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
if (!parallelResult.success) {
|
|
192
|
+
return failure(parallelResult.error);
|
|
193
|
+
}
|
|
194
|
+
// Check for any failures
|
|
195
|
+
const failures = parallelResult.data.filter((r) => !r.success);
|
|
196
|
+
if (failures.length > 0) {
|
|
197
|
+
const failedStacks = failures.map((f) => f.stack).join(", ");
|
|
198
|
+
const errorDetails = failures
|
|
199
|
+
.map((f) => `${f.stack}: ${f.error?.message ?? "Unknown error"}`)
|
|
200
|
+
.join("\n");
|
|
201
|
+
return failure(new Error(`Failed to deploy stacks: ${failedStacks}\n\n${errorDetails}`));
|
|
202
|
+
}
|
|
203
|
+
// Collect outputs and track hashes for successful parallel stacks
|
|
204
|
+
for (const result of parallelResult.data) {
|
|
205
|
+
if (result.success && result.outputs) {
|
|
206
|
+
for (const [key, value] of Object.entries(result.outputs)) {
|
|
207
|
+
allOutputs[key] = String(value);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const stackName = getApplicationStackName(operation.appName, result.stack);
|
|
211
|
+
const hash = detection.currentHashes.get(stackName);
|
|
212
|
+
if (hash) {
|
|
213
|
+
deployedHashes.set(stackName, hash);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return success(undefined);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Run Docker build and push before deploying the Compute stack.
|
|
220
|
+
* Initialises ECR if needed, then builds and pushes the image.
|
|
221
|
+
*/
|
|
222
|
+
async function runDockerBuild(params, services, operation, callbacks) {
|
|
223
|
+
const dockerProvider = params.dockerProvider;
|
|
224
|
+
if (!dockerProvider)
|
|
225
|
+
return success(undefined);
|
|
226
|
+
const accountId = services.awsProvider.getAccountId();
|
|
227
|
+
if (!accountId) {
|
|
228
|
+
callbacks.onLog?.("Skipping Docker build — account ID not available", "warn");
|
|
229
|
+
return success(undefined);
|
|
230
|
+
}
|
|
231
|
+
const region = services.awsProvider.getRegion();
|
|
232
|
+
// Initialise ECR repository (non-fatal — CDK creates it if needed)
|
|
233
|
+
callbacks.onLog?.("Initialising ECR repository…", "info");
|
|
234
|
+
const ecrResult = await dockerProvider.initialiseECR({
|
|
235
|
+
appName: operation.appName,
|
|
236
|
+
region,
|
|
237
|
+
accountId
|
|
238
|
+
});
|
|
239
|
+
if (!ecrResult.success) {
|
|
240
|
+
callbacks.onLog?.(`ECR initialisation failed: ${ecrResult.error.message}`, "warn");
|
|
241
|
+
}
|
|
242
|
+
// Build and push Docker image
|
|
243
|
+
callbacks.onLog?.("Building and pushing Docker image…", "info");
|
|
244
|
+
const buildResult = await dockerProvider.buildAndPush({
|
|
245
|
+
appName: operation.appName,
|
|
246
|
+
appPath: operation.path,
|
|
247
|
+
region,
|
|
248
|
+
accountId
|
|
249
|
+
});
|
|
250
|
+
if (!buildResult.success) {
|
|
251
|
+
callbacks.onError?.(buildResult.error);
|
|
252
|
+
return failure(buildResult.error);
|
|
253
|
+
}
|
|
254
|
+
callbacks.onLog?.(`Docker image pushed: ${buildResult.data.imageUri}`, "info");
|
|
255
|
+
return success(undefined);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Deploy a single stack with step lifecycle events and output collection.
|
|
259
|
+
*/
|
|
260
|
+
async function deployStackSequential(stack, services, context, callbacks, stepIndex, totalSteps, allOutputs) {
|
|
261
|
+
const stepId = getApplicationStepId(stack, "deploy");
|
|
262
|
+
const stepName = getApplicationStepName(stack, "deploy");
|
|
263
|
+
callbacks.onStepStart?.(stepId, stepName, stepIndex, totalSteps);
|
|
264
|
+
const result = await services.stackService.deployStack(stack, context, {
|
|
265
|
+
onOutput: (chunk) => callbacks.onOutput?.(chunk),
|
|
266
|
+
onResourceProgress: (event) => callbacks.onResourceProgress?.(event)
|
|
267
|
+
});
|
|
268
|
+
if (!result.success) {
|
|
269
|
+
callbacks.onStepComplete?.(stepId, stepName, "error", stepIndex, totalSteps);
|
|
270
|
+
callbacks.onError?.(result.error);
|
|
271
|
+
return failure(result.error);
|
|
272
|
+
}
|
|
273
|
+
callbacks.onStepComplete?.(stepId, stepName, "completed", stepIndex, totalSteps);
|
|
274
|
+
if (result.data.outputs) {
|
|
275
|
+
for (const [key, value] of Object.entries(result.data.outputs)) {
|
|
276
|
+
allOutputs[key] = String(value);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return success(undefined);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Deploy all stacks unconditionally (deployOnly mode).
|
|
283
|
+
* Skips CDK synth/hash comparison — uses filesystem pattern detection only
|
|
284
|
+
* to determine deploy order, then deploys every stack sequentially.
|
|
285
|
+
*/
|
|
286
|
+
async function deployAllStacks(params, services, operation, context, startTime) {
|
|
287
|
+
const { callbacks } = params;
|
|
288
|
+
// Lightweight pattern detection (filesystem only, no CDK synth)
|
|
289
|
+
const { pattern } = detectPattern(operation.path);
|
|
290
|
+
const deployOrder = getApplicationDeployOrder({ pattern });
|
|
291
|
+
const totalSteps = deployOrder.length;
|
|
292
|
+
// Bootstrap
|
|
293
|
+
callbacks.onCDKBootstrap?.("bootstrapping");
|
|
294
|
+
const bootstrapResult = await services.cdkService.runCdkBootstrap(context, (chunk) => callbacks.onOutput?.(chunk));
|
|
295
|
+
if (!bootstrapResult.success) {
|
|
296
|
+
callbacks.onCDKBootstrap?.("failed");
|
|
297
|
+
const error = new Error(`Bootstrap failed: ${bootstrapResult.error}`);
|
|
298
|
+
callbacks.onError?.(error);
|
|
299
|
+
return failure(error);
|
|
300
|
+
}
|
|
301
|
+
callbacks.onCDKBootstrap?.("complete");
|
|
302
|
+
// Deploy all stacks sequentially
|
|
303
|
+
const allOutputs = {};
|
|
304
|
+
for (let i = 0; i < deployOrder.length; i++) {
|
|
305
|
+
const stack = deployOrder[i];
|
|
306
|
+
// Docker build before Compute stack
|
|
307
|
+
if (stack === APPLICATION_STACKS.COMPUTE && params.dockerProvider) {
|
|
308
|
+
const dockerResult = await runDockerBuild(params, services, operation, callbacks);
|
|
309
|
+
if (!dockerResult.success)
|
|
310
|
+
return failure(dockerResult.error);
|
|
311
|
+
}
|
|
312
|
+
const deployResult = await deployStackSequential(stack, services, context, callbacks, i, totalSteps, allOutputs);
|
|
313
|
+
if (!deployResult.success)
|
|
314
|
+
return failure(deployResult.error);
|
|
315
|
+
}
|
|
316
|
+
// Resolve website URL
|
|
317
|
+
const websiteUrl = await services.stackService.resolveWebsiteUrl(operation.appName);
|
|
318
|
+
if (websiteUrl) {
|
|
319
|
+
allOutputs.websiteUrl = websiteUrl;
|
|
320
|
+
}
|
|
321
|
+
return success({
|
|
322
|
+
target: operation.appName,
|
|
323
|
+
deploymentType: "application",
|
|
324
|
+
outputs: Object.keys(allOutputs).length > 0 ? allOutputs : undefined,
|
|
325
|
+
durationMs: Date.now() - startTime
|
|
326
|
+
});
|
|
327
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DeployParams } from "../types/params.js";
|
|
2
|
+
/**
|
|
3
|
+
* Build the orgConfig/identity context fields shared by all deployment paths.
|
|
4
|
+
* CdkContextBuilder expects orgConfig as a JSON string and fjallOrgId as a string.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildParamsContext(params: DeployParams): {
|
|
7
|
+
orgConfig?: string;
|
|
8
|
+
fjallOrgId?: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the orgConfig/identity context fields shared by all deployment paths.
|
|
3
|
+
* CdkContextBuilder expects orgConfig as a JSON string and fjallOrgId as a string.
|
|
4
|
+
*/
|
|
5
|
+
export function buildParamsContext(params) {
|
|
6
|
+
return {
|
|
7
|
+
...(params.orgConfig !== undefined
|
|
8
|
+
? { orgConfig: JSON.stringify(params.orgConfig) }
|
|
9
|
+
: {}),
|
|
10
|
+
...(params.identity !== undefined
|
|
11
|
+
? { fjallOrgId: params.identity.fjallOrgId }
|
|
12
|
+
: {})
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Result } from "@fjall/generator";
|
|
2
|
+
import type { DeployParams, DeployResult } from "../types/params.js";
|
|
3
|
+
/**
|
|
4
|
+
* Deploy infrastructure for a target.
|
|
5
|
+
*
|
|
6
|
+
* Primary entry point for both CLI and webapp worker. Determines whether
|
|
7
|
+
* the target is an application or organisation deployment and routes
|
|
8
|
+
* to the appropriate orchestrator.
|
|
9
|
+
*/
|
|
10
|
+
export declare function deploy(params: DeployParams): Promise<Result<DeployResult>>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { success } from "@fjall/generator";
|
|
2
|
+
import { isApplicationOperation } from "../types/operations.js";
|
|
3
|
+
import { createDeployServices } from "./serviceFactory.js";
|
|
4
|
+
import { resolveOperation } from "./resolveOperation.js";
|
|
5
|
+
import { deployApplication } from "./applicationDeploy.js";
|
|
6
|
+
import { deployOrganisation } from "./organisationDeploy.js";
|
|
7
|
+
/**
|
|
8
|
+
* Deploy infrastructure for a target.
|
|
9
|
+
*
|
|
10
|
+
* Primary entry point for both CLI and webapp worker. Determines whether
|
|
11
|
+
* the target is an application or organisation deployment and routes
|
|
12
|
+
* to the appropriate orchestrator.
|
|
13
|
+
*/
|
|
14
|
+
export async function deploy(params) {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
const services = createDeployServices(params);
|
|
17
|
+
const opResult = await resolveOperation(params.target, params.workingDirectory);
|
|
18
|
+
if (!opResult.success) {
|
|
19
|
+
params.callbacks.onError?.(opResult.error);
|
|
20
|
+
return opResult;
|
|
21
|
+
}
|
|
22
|
+
const operation = opResult.data;
|
|
23
|
+
if (isApplicationOperation(operation)) {
|
|
24
|
+
const result = await deployApplication(params, services, operation);
|
|
25
|
+
// Attach duration if not already set
|
|
26
|
+
if (result.success && result.data.durationMs === undefined) {
|
|
27
|
+
return success({
|
|
28
|
+
...result.data,
|
|
29
|
+
durationMs: Date.now() - startTime
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
const result = await deployOrganisation(params, services, operation);
|
|
35
|
+
if (result.success && result.data.durationMs === undefined) {
|
|
36
|
+
return success({
|
|
37
|
+
...result.data,
|
|
38
|
+
durationMs: Date.now() - startTime
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type Result } from "@fjall/generator";
|
|
2
|
+
import type { DeployCallbacks } from "../types/callbacks.js";
|
|
3
|
+
import type { DeploymentContext } from "../types/deployment/DeploymentTypes.js";
|
|
4
|
+
import type { ApplicationOperation } from "../types/operations.js";
|
|
5
|
+
import { type AppResourceFlags } from "../types/patternDetection.js";
|
|
6
|
+
import type { PatternType } from "@fjall/generator";
|
|
7
|
+
import type { DeployServices } from "./serviceFactory.js";
|
|
8
|
+
export interface DetectionResult {
|
|
9
|
+
pattern: PatternType | null;
|
|
10
|
+
hasDatabase: boolean;
|
|
11
|
+
hasDifferences: boolean;
|
|
12
|
+
stackChanges: Map<string, boolean>;
|
|
13
|
+
currentHashes: Map<string, string>;
|
|
14
|
+
resources: AppResourceFlags;
|
|
15
|
+
hasDockerfile: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Pre-deployment analysis pipeline.
|
|
19
|
+
*
|
|
20
|
+
* Detects the application pattern, synthesises infrastructure, computes
|
|
21
|
+
* template hashes, and determines which stacks have changed.
|
|
22
|
+
*/
|
|
23
|
+
export declare function runDetectionPipeline(operation: ApplicationOperation, services: DeployServices, context: DeploymentContext, callbacks: DeployCallbacks): Promise<Result<DetectionResult>>;
|