@go-to-k/cdkd 0.226.0 → 0.227.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +152 -137
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-DM557Qjg.js → deploy-engine-Bl_Ka0hj.js} +184 -11
- package/dist/deploy-engine-Bl_Ka0hj.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-DM557Qjg.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { A as withErrorHandling, B as generateResourceNameWithFallback, C as StackHasActiveImportsError, F as getLiveRenderer, H as withStackName, I as PATTERN_B_NAME_PROPERTIES, L as PATTERN_B_RESOURCE_TYPES, M as getLogger, P as runStackBuffered, S as ResourceUpdateNotSupportedError, V as withSkipPrefix, _ as MissingCdkCliError, a as assertRegionMatch, b as ProvisioningError, f as LocalInvokeBuildError$1, i as resolveExplicitPhysicalId, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as matchesCdkPath, o as disableInstanceApiTermination, p as LocalMigrateError, r as normalizeAwsTagsToCfn, s as isTerminationProtectionPropagationError, t as CDK_PATH_TAG, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError, z as generateResourceName } from "./import-helpers-wLipXr5g.js";
|
|
3
3
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
|
|
4
|
-
import { $ as
|
|
4
|
+
import { $ as findLargeInlineResources, A as shouldRetainResource, B as getDockerImageBySourceHash, C as applyRoleArnIfSet, D as LockManager, E as TemplateParser, F as formatDockerLoginError, G as resolveCaptureObservedState, H as getDefaultStateBucketName, I as getDockerCmd, J as resolveStateBucketWithDefaultAndSource, K as resolveSkipPrefix, L as runDockerForeground, M as stringifyValue, N as WorkGraph, O as S3StateBackend, P as buildDockerImage, Q as MIGRATE_TMP_PREFIX, R as runDockerStreaming, S as IntrinsicFunctionResolver, T as DagBuilder, U as getLegacyStateBucketName, V as Synthesizer, W as resolveApp, X as CFN_TEMPLATE_BODY_LIMIT, Y as warnDeprecatedNoPrefixCliFlag, Z as CFN_TEMPLATE_URL_LIMIT, _ as IAMRoleProvider, a as withRetry, b as findActionableSilentDrops, c as computeImplicitDeleteEdges, d as bold, et as uploadCfnTemplate, f as cyan, g as yellow, h as red, i as withResourceDeadline, j as AssetPublisher, k as rebuildClientForBucketRegion, l as extractDeploymentEventError, m as green, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as gray, q as resolveStateBucketWithDefault, r as DeployEngine, rt as resolveBucketRegion, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as AssemblyReader, u as formatResourceLine, v as collectInlinePolicyNamesManagedBySiblings, w as DiffCalculator, x as CloudControlProvider, y as ProviderRegistry, z as AssetManifestLoader } from "./deploy-engine-Bl_Ka0hj.js";
|
|
5
5
|
import { t as ASGProvider } from "./asg-provider-B_hrCxRx.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
@@ -32,13 +32,13 @@ import { tmpdir } from "node:os";
|
|
|
32
32
|
import { AssociateVPCWithHostedZoneCommand, ChangeResourceRecordSetsCommand, ChangeTagsForResourceCommand, CreateHostedZoneCommand, CreateQueryLoggingConfigCommand, DeleteHostedZoneCommand, DeleteQueryLoggingConfigCommand, DisassociateVPCFromHostedZoneCommand, GetHostedZoneCommand, ListHostedZonesByNameCommand, ListHostedZonesCommand, ListQueryLoggingConfigsCommand, ListResourceRecordSetsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$6, Route53Client, UpdateHostedZoneCommentCommand, UpdateHostedZoneFeaturesCommand } from "@aws-sdk/client-route-53";
|
|
33
33
|
import { AddTagsCommand, CreateListenerCommand, CreateLoadBalancerCommand, CreateTargetGroupCommand, DeleteListenerCommand, DeleteLoadBalancerCommand, DeleteTargetGroupCommand, DescribeListenerAttributesCommand, DescribeListenersCommand, DescribeLoadBalancerAttributesCommand, DescribeLoadBalancersCommand, DescribeTagsCommand, DescribeTargetGroupsCommand, ElasticLoadBalancingV2Client, ModifyListenerAttributesCommand, ModifyListenerCommand, ModifyLoadBalancerAttributesCommand, ModifyTargetGroupCommand, RemoveTagsCommand, SetIpAddressTypeCommand, SetSecurityGroupsCommand, SetSubnetsCommand } from "@aws-sdk/client-elastic-load-balancing-v2";
|
|
34
34
|
import { CreateAliasCommand, CreateKeyCommand, DeleteAliasCommand, DescribeKeyCommand, DisableKeyCommand, DisableKeyRotationCommand, EnableKeyCommand, EnableKeyRotationCommand, GetKeyPolicyCommand, GetKeyRotationStatusCommand, KMSClient, ListAliasesCommand, ListKeysCommand, ListResourceTagsCommand, NotFoundException as NotFoundException$2, PutKeyPolicyCommand, ScheduleKeyDeletionCommand, TagResourceCommand as TagResourceCommand$9, UntagResourceCommand as UntagResourceCommand$9, UpdateAliasCommand, UpdateKeyDescriptionCommand } from "@aws-sdk/client-kms";
|
|
35
|
+
import { join as join$1 } from "path";
|
|
35
36
|
import { CreateRepositoryCommand, DeleteLifecyclePolicyCommand, DeleteRepositoryCommand, DeleteRepositoryPolicyCommand, DescribeRepositoriesCommand, ECRClient, GetAuthorizationTokenCommand, GetLifecyclePolicyCommand, LifecyclePolicyNotFoundException, ListTagsForResourceCommand as ListTagsForResourceCommand$7, PutImageScanningConfigurationCommand, PutImageTagMutabilityCommand, PutLifecyclePolicyCommand, RepositoryNotFoundException, SetRepositoryPolicyCommand, TagResourceCommand as TagResourceCommand$10 } from "@aws-sdk/client-ecr";
|
|
36
37
|
import graphlib from "graphlib";
|
|
37
38
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$1, CreateDBClusterCommand, CreateDBInstanceCommand, CreateDBProxyCommand, CreateDBProxyEndpointCommand, CreateDBSubnetGroupCommand, DBProxyEndpointNotFoundFault, DBProxyNotFoundFault, DBProxyTargetGroupNotFoundFault, DBProxyTargetNotFoundFault, DeleteDBClusterCommand, DeleteDBInstanceCommand, DeleteDBProxyCommand, DeleteDBProxyEndpointCommand, DeleteDBSubnetGroupCommand, DeregisterDBProxyTargetsCommand, DescribeDBClustersCommand, DescribeDBInstancesCommand, DescribeDBProxiesCommand, DescribeDBProxyEndpointsCommand, DescribeDBProxyTargetGroupsCommand, DescribeDBProxyTargetsCommand, DescribeDBSubnetGroupsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$8, ModifyDBClusterCommand, ModifyDBInstanceCommand, ModifyDBProxyCommand, ModifyDBProxyEndpointCommand, ModifyDBProxyTargetGroupCommand, ModifyDBSubnetGroupCommand, RDSClient, RegisterDBProxyTargetsCommand, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$1 } from "@aws-sdk/client-rds";
|
|
38
39
|
import { AddTagsToResourceCommand as AddTagsToResourceCommand$2, CreateCacheClusterCommand, CreateCacheSubnetGroupCommand, DeleteCacheClusterCommand, DeleteCacheSubnetGroupCommand, DescribeCacheClustersCommand, DescribeCacheSubnetGroupsCommand, ElastiCacheClient, ListTagsForResourceCommand as ListTagsForResourceCommand$9, ModifyCacheClusterCommand, ModifyCacheSubnetGroupCommand, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$2 } from "@aws-sdk/client-elasticache";
|
|
39
40
|
import { Command, Option } from "commander";
|
|
40
41
|
import { writeFileSync as writeFileSync$1 } from "fs";
|
|
41
|
-
import { join as join$1 } from "path";
|
|
42
42
|
import * as readline$1 from "node:readline/promises";
|
|
43
43
|
import readline from "node:readline/promises";
|
|
44
44
|
import * as zlib from "node:zlib";
|
|
@@ -67,7 +67,6 @@ import { A2A_CONTAINER_PORT, A2A_PATH, AGENTCORE_A2A_PROTOCOL, AGENTCORE_AGUI_PR
|
|
|
67
67
|
import { createServer } from "node:net";
|
|
68
68
|
import { promisify } from "node:util";
|
|
69
69
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
70
|
-
import { readFile } from "fs/promises";
|
|
71
70
|
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
72
71
|
import { WebSocketServer } from "ws";
|
|
73
72
|
|
|
@@ -1553,7 +1552,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
1553
1552
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
1554
1553
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
1555
1554
|
function getCdkdVersion() {
|
|
1556
|
-
return "0.
|
|
1555
|
+
return "0.227.1";
|
|
1557
1556
|
}
|
|
1558
1557
|
/**
|
|
1559
1558
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -9758,6 +9757,7 @@ var DynamoDBTableProvider = class {
|
|
|
9758
9757
|
this.logger.debug(`Updated WarmThroughput on DynamoDB table ${physicalId}`);
|
|
9759
9758
|
}
|
|
9760
9759
|
}
|
|
9760
|
+
if (JSON.stringify(properties["GlobalSecondaryIndexes"]) !== JSON.stringify(previousProperties["GlobalSecondaryIndexes"])) await this.applyGsiUpdates(physicalId, resourceType, logicalId, previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"], properties["AttributeDefinitions"]);
|
|
9761
9761
|
if (JSON.stringify(properties["PointInTimeRecoverySpecification"]) !== JSON.stringify(previousProperties["PointInTimeRecoverySpecification"])) await this.applyPointInTimeRecovery(physicalId, properties["PointInTimeRecoverySpecification"], previousProperties["PointInTimeRecoverySpecification"]);
|
|
9762
9762
|
if (JSON.stringify(properties["TimeToLiveSpecification"]) !== JSON.stringify(previousProperties["TimeToLiveSpecification"])) await this.applyTimeToLive(physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
|
|
9763
9763
|
if (JSON.stringify(properties["ResourcePolicy"]) !== JSON.stringify(previousProperties["ResourcePolicy"])) {
|
|
@@ -10083,6 +10083,79 @@ var DynamoDBTableProvider = class {
|
|
|
10083
10083
|
throw new Error(`Table ${tableName} did not reach ACTIVE status within ${maxAttempts} seconds after UpdateTable`);
|
|
10084
10084
|
}
|
|
10085
10085
|
/**
|
|
10086
|
+
* Poll DescribeTable until the table is ACTIVE AND every Global Secondary
|
|
10087
|
+
* Index is ACTIVE (not CREATING / UPDATING / DELETING / BACKFILLING). Used
|
|
10088
|
+
* between GSI mutations because a freshly-created index keeps backfilling
|
|
10089
|
+
* after the table itself returns to ACTIVE, and AWS rejects the next GSI op
|
|
10090
|
+
* until the prior index settles.
|
|
10091
|
+
*/
|
|
10092
|
+
async waitForTableAndIndexesActive(tableName, maxAttempts = 1800) {
|
|
10093
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
10094
|
+
const table = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: tableName }))).Table;
|
|
10095
|
+
const tableActive = table?.TableStatus === "ACTIVE";
|
|
10096
|
+
const indexesActive = (table?.GlobalSecondaryIndexes ?? []).every((gsi) => gsi.IndexStatus === "ACTIVE");
|
|
10097
|
+
if (tableActive && indexesActive) return;
|
|
10098
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
10099
|
+
}
|
|
10100
|
+
throw new Error(`Table ${tableName} and its global secondary indexes did not reach ACTIVE within ${maxAttempts} seconds after UpdateTable`);
|
|
10101
|
+
}
|
|
10102
|
+
/**
|
|
10103
|
+
* Apply Global Secondary Index add / remove / per-index throughput changes
|
|
10104
|
+
* via UpdateTable's `GlobalSecondaryIndexUpdates`.
|
|
10105
|
+
*
|
|
10106
|
+
* AWS constraints mirrored here:
|
|
10107
|
+
* - At most ONE GSI Create or Delete per UpdateTable call; a second
|
|
10108
|
+
* mutation while the table / an index is still building is rejected. Each
|
|
10109
|
+
* op therefore runs in its own UpdateTable and waits for ACTIVE before the
|
|
10110
|
+
* next (creating GSIs also go through a BACKFILLING phase that ACTIVE
|
|
10111
|
+
* covers).
|
|
10112
|
+
* - A GSI `Create` must carry the AttributeDefinitions for the new index's
|
|
10113
|
+
* key attributes — the full desired AttributeDefinitions array is passed
|
|
10114
|
+
* so every newly-referenced attribute is defined.
|
|
10115
|
+
* - On an existing same-name index, only a PROVISIONED `ProvisionedThroughput`
|
|
10116
|
+
* (RCU/WCU) change is mutable in place and is issued as an `Update`. A
|
|
10117
|
+
* `KeySchema` / `Projection` change is immutable in place (AWS models it as
|
|
10118
|
+
* a delete + re-create); since the diff keys GSIs by name it would not emit
|
|
10119
|
+
* a remove-then-add pair, so this method throws on such a change rather than
|
|
10120
|
+
* silently dropping it.
|
|
10121
|
+
*/
|
|
10122
|
+
async applyGsiUpdates(physicalId, resourceType, logicalId, previousGsis, desiredGsis, desiredAttributeDefinitions) {
|
|
10123
|
+
const prev = previousGsis ?? [];
|
|
10124
|
+
const desired = desiredGsis ?? [];
|
|
10125
|
+
const prevByName = new Map(prev.filter((g) => g.IndexName).map((g) => [g.IndexName, g]));
|
|
10126
|
+
const desiredByName = new Map(desired.filter((g) => g.IndexName).map((g) => [g.IndexName, g]));
|
|
10127
|
+
const ops = [];
|
|
10128
|
+
for (const name of prevByName.keys()) if (!desiredByName.has(name)) ops.push({ Delete: { IndexName: name } });
|
|
10129
|
+
for (const [name, gsi] of desiredByName) if (!prevByName.has(name)) {
|
|
10130
|
+
if (!gsi.KeySchema) throw new ProvisioningError(`GlobalSecondaryIndex ${name} on DynamoDB table ${logicalId} is missing KeySchema`, resourceType, logicalId, physicalId);
|
|
10131
|
+
ops.push({ Create: {
|
|
10132
|
+
IndexName: name,
|
|
10133
|
+
KeySchema: gsi.KeySchema,
|
|
10134
|
+
Projection: gsi.Projection,
|
|
10135
|
+
...gsi.ProvisionedThroughput ? { ProvisionedThroughput: gsi.ProvisionedThroughput } : {},
|
|
10136
|
+
...gsi.OnDemandThroughput ? { OnDemandThroughput: gsi.OnDemandThroughput } : {}
|
|
10137
|
+
} });
|
|
10138
|
+
} else {
|
|
10139
|
+
const before = prevByName.get(name);
|
|
10140
|
+
if (JSON.stringify(before.KeySchema) !== JSON.stringify(gsi.KeySchema) || JSON.stringify(before.Projection) !== JSON.stringify(gsi.Projection)) throw new ProvisioningError(`GlobalSecondaryIndex ${name} on DynamoDB table ${logicalId} changed its KeySchema or Projection, which DynamoDB cannot modify in place. Rename the index (so it is dropped and re-created) or replace the table.`, resourceType, logicalId, physicalId);
|
|
10141
|
+
if (gsi.ProvisionedThroughput && JSON.stringify(before.ProvisionedThroughput) !== JSON.stringify(gsi.ProvisionedThroughput)) ops.push({ Update: {
|
|
10142
|
+
IndexName: name,
|
|
10143
|
+
ProvisionedThroughput: gsi.ProvisionedThroughput
|
|
10144
|
+
} });
|
|
10145
|
+
}
|
|
10146
|
+
for (const op of ops) {
|
|
10147
|
+
const input = {
|
|
10148
|
+
TableName: physicalId,
|
|
10149
|
+
GlobalSecondaryIndexUpdates: [op]
|
|
10150
|
+
};
|
|
10151
|
+
if (op.Create && desiredAttributeDefinitions) input.AttributeDefinitions = desiredAttributeDefinitions;
|
|
10152
|
+
await this.dynamoDBClient.send(new UpdateTableCommand(input));
|
|
10153
|
+
await this.waitForTableAndIndexesActive(physicalId);
|
|
10154
|
+
const verb = op.Create ? "created" : op.Delete ? "deleted" : "updated";
|
|
10155
|
+
this.logger.debug(`${verb} GSI ${op.Create?.IndexName ?? op.Delete?.IndexName ?? op.Update?.IndexName} on DynamoDB table ${physicalId}`);
|
|
10156
|
+
}
|
|
10157
|
+
}
|
|
10158
|
+
/**
|
|
10086
10159
|
* Resolve a single `Fn::GetAtt` attribute for an existing DynamoDB table.
|
|
10087
10160
|
*
|
|
10088
10161
|
* CloudFormation's `AWS::DynamoDB::Table` exposes `Arn`, `StreamArn`
|
|
@@ -12093,6 +12166,21 @@ var CloudWatchAlarmProvider = class {
|
|
|
12093
12166
|
"EvaluateLowSampleCountPercentile",
|
|
12094
12167
|
"ThresholdMetricId"
|
|
12095
12168
|
])]]);
|
|
12169
|
+
/**
|
|
12170
|
+
* Properties this provider deliberately does NOT wire through to the SDK,
|
|
12171
|
+
* with a one-line rationale per entry (consumed by the property-coverage
|
|
12172
|
+
* check, issue #391).
|
|
12173
|
+
*
|
|
12174
|
+
* `EvaluationCriteria` / `EvaluationInterval` appear in the CloudFormation
|
|
12175
|
+
* `AWS::CloudWatch::Alarm` registry schema but are absent from BOTH the AWS
|
|
12176
|
+
* SDK `PutMetricAlarm` input (`@aws-sdk/client-cloudwatch`) AND the
|
|
12177
|
+
* aws-cdk-lib `CfnAlarm` L1 — a newer CFn-schema surface ahead of SDK / CDK
|
|
12178
|
+
* support, so there is no wire path to forward them and no CDK app can emit
|
|
12179
|
+
* them. Per the #609 backfillability rule (a property absent from EITHER the
|
|
12180
|
+
* SDK create input OR the CDK L1 is not backfillable), they are classified
|
|
12181
|
+
* unhandled-by-design rather than left as a "not yet implemented" TODO.
|
|
12182
|
+
*/
|
|
12183
|
+
unhandledByDesign = new Map([["AWS::CloudWatch::Alarm", new Map([["EvaluationCriteria", "Absent from both the SDK PutMetricAlarm input and the aws-cdk-lib CfnAlarm L1 (a newer CFn-schema-only property ahead of SDK/CDK support); no wire path to forward it and no CDK app can emit it."], ["EvaluationInterval", "Absent from both the SDK PutMetricAlarm input and the aws-cdk-lib CfnAlarm L1 (a newer CFn-schema-only property ahead of SDK/CDK support); no wire path to forward it and no CDK app can emit it."]])]]);
|
|
12096
12184
|
constructor() {
|
|
12097
12185
|
const awsClients = getAwsClients();
|
|
12098
12186
|
this.cloudWatchClient = awsClients.cloudWatch;
|
|
@@ -19294,6 +19382,7 @@ var AgentCoreRuntimeProvider = class {
|
|
|
19294
19382
|
*/
|
|
19295
19383
|
var StepFunctionsProvider = class {
|
|
19296
19384
|
sfnClient;
|
|
19385
|
+
s3Client;
|
|
19297
19386
|
providerRegion = process.env["AWS_REGION"];
|
|
19298
19387
|
logger = getLogger().child("StepFunctionsProvider");
|
|
19299
19388
|
handledProperties = new Map([["AWS::StepFunctions::StateMachine", new Set([
|
|
@@ -19305,6 +19394,7 @@ var StepFunctionsProvider = class {
|
|
|
19305
19394
|
"Tags",
|
|
19306
19395
|
"DefinitionString",
|
|
19307
19396
|
"Definition",
|
|
19397
|
+
"DefinitionS3Location",
|
|
19308
19398
|
"DefinitionSubstitutions",
|
|
19309
19399
|
"EncryptionConfiguration"
|
|
19310
19400
|
])]]);
|
|
@@ -19312,6 +19402,10 @@ var StepFunctionsProvider = class {
|
|
|
19312
19402
|
if (!this.sfnClient) this.sfnClient = new SFNClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
19313
19403
|
return this.sfnClient;
|
|
19314
19404
|
}
|
|
19405
|
+
getS3Client() {
|
|
19406
|
+
if (!this.s3Client) this.s3Client = new S3Client(this.providerRegion ? { region: this.providerRegion } : {});
|
|
19407
|
+
return this.s3Client;
|
|
19408
|
+
}
|
|
19315
19409
|
/**
|
|
19316
19410
|
* Create a Step Functions state machine
|
|
19317
19411
|
*/
|
|
@@ -19321,7 +19415,7 @@ var StepFunctionsProvider = class {
|
|
|
19321
19415
|
const roleArn = properties["RoleArn"];
|
|
19322
19416
|
if (!roleArn) throw new ProvisioningError(`RoleArn is required for Step Functions state machine ${logicalId}`, resourceType, logicalId);
|
|
19323
19417
|
try {
|
|
19324
|
-
const definitionString = this.buildDefinitionString(properties);
|
|
19418
|
+
const definitionString = await this.buildDefinitionString(properties);
|
|
19325
19419
|
let tags;
|
|
19326
19420
|
if (properties["Tags"]) tags = properties["Tags"].map((tag) => ({
|
|
19327
19421
|
key: tag.Key,
|
|
@@ -19364,7 +19458,7 @@ var StepFunctionsProvider = class {
|
|
|
19364
19458
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
19365
19459
|
this.logger.debug(`Updating Step Functions state machine ${logicalId}: ${physicalId}`);
|
|
19366
19460
|
try {
|
|
19367
|
-
const definitionString = this.buildDefinitionString(properties);
|
|
19461
|
+
const definitionString = await this.buildDefinitionString(properties);
|
|
19368
19462
|
const encryptionConfiguration = mapEncryptionConfiguration(properties["EncryptionConfiguration"]);
|
|
19369
19463
|
const loggingConfiguration = mapLoggingConfiguration(properties["LoggingConfiguration"]);
|
|
19370
19464
|
const tracingConfiguration = mapTracingConfiguration(properties["TracingConfiguration"]);
|
|
@@ -19564,10 +19658,22 @@ var StepFunctionsProvider = class {
|
|
|
19564
19658
|
return false;
|
|
19565
19659
|
}
|
|
19566
19660
|
/**
|
|
19567
|
-
* Build definition string from CDK properties.
|
|
19568
|
-
*
|
|
19661
|
+
* Build the state-machine definition string from CDK properties.
|
|
19662
|
+
*
|
|
19663
|
+
* Precedence (mirrors CloudFormation): an inline `DefinitionString` /
|
|
19664
|
+
* `Definition` wins over `DefinitionS3Location`. The inline forms are
|
|
19665
|
+
* returned verbatim — any `DefinitionSubstitutions` they need are already
|
|
19666
|
+
* folded into the template as `Fn::Sub` and resolved by cdkd's intrinsic
|
|
19667
|
+
* resolver before the provider sees them.
|
|
19668
|
+
*
|
|
19669
|
+
* `DefinitionS3Location` ({@link https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stepfunctions-statemachine-s3location.html S3Location})
|
|
19670
|
+
* has no SDK `CreateStateMachine` field — CloudFormation reads the S3 object
|
|
19671
|
+
* and inlines its contents as the `definition`. cdkd does the same: fetch
|
|
19672
|
+
* the object body, then apply `DefinitionSubstitutions` ourselves because
|
|
19673
|
+
* the intrinsic resolver cannot reach into S3 content (unlike the inline
|
|
19674
|
+
* path, where substitutions arrive pre-resolved).
|
|
19569
19675
|
*/
|
|
19570
|
-
buildDefinitionString(properties) {
|
|
19676
|
+
async buildDefinitionString(properties) {
|
|
19571
19677
|
const definitionString = properties["DefinitionString"];
|
|
19572
19678
|
const definition = properties["Definition"];
|
|
19573
19679
|
if (definitionString !== void 0) {
|
|
@@ -19578,8 +19684,44 @@ var StepFunctionsProvider = class {
|
|
|
19578
19684
|
if (typeof definition === "string") return definition;
|
|
19579
19685
|
return JSON.stringify(definition);
|
|
19580
19686
|
}
|
|
19687
|
+
const s3Location = properties["DefinitionS3Location"];
|
|
19688
|
+
if (s3Location?.Bucket && s3Location.Key) {
|
|
19689
|
+
const body = await this.fetchDefinitionFromS3(s3Location.Bucket, s3Location.Key, s3Location.Version);
|
|
19690
|
+
return this.applyDefinitionSubstitutions(body, properties["DefinitionSubstitutions"]);
|
|
19691
|
+
}
|
|
19581
19692
|
return "{}";
|
|
19582
19693
|
}
|
|
19694
|
+
/**
|
|
19695
|
+
* Fetch a state-machine definition (Amazon States Language JSON/YAML) from
|
|
19696
|
+
* S3 and return its body as a UTF-8 string. Honors an optional object
|
|
19697
|
+
* version for versioning-enabled buckets.
|
|
19698
|
+
*/
|
|
19699
|
+
async fetchDefinitionFromS3(bucket, key, version) {
|
|
19700
|
+
this.logger.debug(`Fetching state-machine definition from s3://${bucket}/${key}${version ? `?versionId=${version}` : ""}`);
|
|
19701
|
+
const resp = await this.getS3Client().send(new GetObjectCommand({
|
|
19702
|
+
Bucket: bucket,
|
|
19703
|
+
Key: key,
|
|
19704
|
+
...version && { VersionId: version }
|
|
19705
|
+
}));
|
|
19706
|
+
if (!resp.Body) throw new Error(`DefinitionS3Location object s3://${bucket}/${key} returned no body`);
|
|
19707
|
+
const body = await resp.Body.transformToString();
|
|
19708
|
+
if (body.length === 0) throw new Error(`DefinitionS3Location object s3://${bucket}/${key} returned an empty body`);
|
|
19709
|
+
return body;
|
|
19710
|
+
}
|
|
19711
|
+
/**
|
|
19712
|
+
* Apply CloudFormation `DefinitionSubstitutions` (a `{ name: value }` map) to
|
|
19713
|
+
* a definition body by replacing each `${name}` token with its value.
|
|
19714
|
+
* Returns the body unchanged when no substitutions are supplied.
|
|
19715
|
+
*/
|
|
19716
|
+
applyDefinitionSubstitutions(body, substitutions) {
|
|
19717
|
+
if (substitutions === null || typeof substitutions !== "object" || Array.isArray(substitutions)) return body;
|
|
19718
|
+
let result = body;
|
|
19719
|
+
for (const [name, value] of Object.entries(substitutions)) {
|
|
19720
|
+
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") continue;
|
|
19721
|
+
result = result.split(`\${${name}}`).join(String(value));
|
|
19722
|
+
}
|
|
19723
|
+
return result;
|
|
19724
|
+
}
|
|
19583
19725
|
};
|
|
19584
19726
|
/**
|
|
19585
19727
|
* Translate a CFn-shape `EncryptionConfiguration` (PascalCase) into the SDK's
|
|
@@ -47532,133 +47674,6 @@ const STREAM_PRELUDE_SEPARATOR = Buffer.from([
|
|
|
47532
47674
|
0
|
|
47533
47675
|
]);
|
|
47534
47676
|
|
|
47535
|
-
//#endregion
|
|
47536
|
-
//#region src/assets/asset-manifest-loader.ts
|
|
47537
|
-
/**
|
|
47538
|
-
* Asset manifest loader
|
|
47539
|
-
*
|
|
47540
|
-
* Loads and parses CDK asset manifests from the CDK output directory
|
|
47541
|
-
*/
|
|
47542
|
-
var AssetManifestLoader = class {
|
|
47543
|
-
logger = getLogger().child("AssetManifestLoader");
|
|
47544
|
-
/**
|
|
47545
|
-
* Load asset manifest from CDK output directory
|
|
47546
|
-
*
|
|
47547
|
-
* @param cdkOutputDir CDK output directory (e.g., "cdk.out")
|
|
47548
|
-
* @param stackName Stack name
|
|
47549
|
-
* @returns Asset manifest or null if not found
|
|
47550
|
-
*/
|
|
47551
|
-
async loadManifest(cdkOutputDir, stackName) {
|
|
47552
|
-
const manifestPath = join$1(cdkOutputDir, `${stackName}.assets.json`);
|
|
47553
|
-
try {
|
|
47554
|
-
this.logger.debug(`Loading asset manifest from: ${manifestPath}`);
|
|
47555
|
-
const content = await readFile(manifestPath, "utf-8");
|
|
47556
|
-
const manifest = JSON.parse(content);
|
|
47557
|
-
this.logger.debug(`Loaded asset manifest: ${Object.keys(manifest.files).length} file assets, ${Object.keys(manifest.dockerImages).length} docker image assets`);
|
|
47558
|
-
return manifest;
|
|
47559
|
-
} catch (error) {
|
|
47560
|
-
if (error.code === "ENOENT") {
|
|
47561
|
-
this.logger.debug(`Asset manifest not found: ${manifestPath}`);
|
|
47562
|
-
return null;
|
|
47563
|
-
}
|
|
47564
|
-
throw new Error(`Failed to load asset manifest from ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
47565
|
-
}
|
|
47566
|
-
}
|
|
47567
|
-
/**
|
|
47568
|
-
* Get file assets from manifest (excludes CloudFormation templates)
|
|
47569
|
-
*
|
|
47570
|
-
* @param manifest Asset manifest
|
|
47571
|
-
* @returns Map of asset hash to file asset
|
|
47572
|
-
*/
|
|
47573
|
-
getFileAssets(manifest) {
|
|
47574
|
-
const fileAssets = /* @__PURE__ */ new Map();
|
|
47575
|
-
for (const [assetHash, asset] of Object.entries(manifest.files)) {
|
|
47576
|
-
if (asset.source.path.endsWith(".json") || asset.source.path.endsWith(".template.json")) {
|
|
47577
|
-
this.logger.debug(`Skipping CloudFormation template asset: ${asset.displayName}`);
|
|
47578
|
-
continue;
|
|
47579
|
-
}
|
|
47580
|
-
fileAssets.set(assetHash, asset);
|
|
47581
|
-
}
|
|
47582
|
-
this.logger.debug(`Found ${fileAssets.size} file assets (excluding templates)`);
|
|
47583
|
-
return fileAssets;
|
|
47584
|
-
}
|
|
47585
|
-
/**
|
|
47586
|
-
* Get asset source path (absolute path)
|
|
47587
|
-
*
|
|
47588
|
-
* @param cdkOutputDir CDK output directory
|
|
47589
|
-
* @param asset File asset
|
|
47590
|
-
* @returns Absolute path to asset source
|
|
47591
|
-
*/
|
|
47592
|
-
getAssetSourcePath(cdkOutputDir, asset) {
|
|
47593
|
-
return join$1(cdkOutputDir, asset.source.path);
|
|
47594
|
-
}
|
|
47595
|
-
/**
|
|
47596
|
-
* Resolve asset destination values (replace ${AWS::AccountId}, ${AWS::Region}, etc.)
|
|
47597
|
-
*
|
|
47598
|
-
* @param value Value with placeholders
|
|
47599
|
-
* @param accountId AWS account ID
|
|
47600
|
-
* @param region AWS region
|
|
47601
|
-
* @param partition AWS partition (default: "aws")
|
|
47602
|
-
* @returns Resolved value
|
|
47603
|
-
*/
|
|
47604
|
-
resolveAssetDestinationValue(value, accountId, region, partition = "aws") {
|
|
47605
|
-
return value.replace(/\$\{AWS::AccountId\}/g, accountId).replace(/\$\{AWS::Region\}/g, region).replace(/\$\{AWS::Partition\}/g, partition);
|
|
47606
|
-
}
|
|
47607
|
-
};
|
|
47608
|
-
/**
|
|
47609
|
-
* Look up the docker-image asset that backs a Lambda's `Code.ImageUri`.
|
|
47610
|
-
*
|
|
47611
|
-
* The CDK template synthesizes `Code.ImageUri` as a `Fn::Sub` whose body
|
|
47612
|
-
* references the bootstrap ECR repo and ends in `:<hash>` — that hash is
|
|
47613
|
-
* the same key used in `manifest.dockerImages[<hash>]`. cdkd extracts the
|
|
47614
|
-
* hash by walking known image-URI shapes; on miss, when the manifest has
|
|
47615
|
-
* exactly one Docker image, we fall back to it (single-asset heuristic) so
|
|
47616
|
-
* locally-built non-bootstrapped images still work. This is documented as
|
|
47617
|
-
* a v1 limitation; immutable digest pins (`@sha256:<digest>`) hit the same
|
|
47618
|
-
* fallback path.
|
|
47619
|
-
*
|
|
47620
|
-
* Returns the `(hash, asset)` pair when matched, or `undefined` when both
|
|
47621
|
-
* the regex AND the single-asset fallback miss (typically: 0 docker assets,
|
|
47622
|
-
* or 2+ docker assets with no hash match — the caller should treat this as
|
|
47623
|
-
* "fall through to the ECR-pull path").
|
|
47624
|
-
*
|
|
47625
|
-
* Exported as a free function (not a method) so the local-invoke modules
|
|
47626
|
-
* can reuse it without depending on the `AssetManifestLoader` instance —
|
|
47627
|
-
* the manifest itself is a plain JSON shape.
|
|
47628
|
-
*/
|
|
47629
|
-
function getDockerImageBySourceHash(manifest, imageUri) {
|
|
47630
|
-
const dockerImages = manifest.dockerImages ?? {};
|
|
47631
|
-
const entries = Object.entries(dockerImages);
|
|
47632
|
-
if (entries.length === 0) return void 0;
|
|
47633
|
-
const hash = extractHashFromImageUri(imageUri);
|
|
47634
|
-
if (hash !== void 0) {
|
|
47635
|
-
const asset = dockerImages[hash];
|
|
47636
|
-
if (asset) return {
|
|
47637
|
-
hash,
|
|
47638
|
-
asset
|
|
47639
|
-
};
|
|
47640
|
-
}
|
|
47641
|
-
if (entries.length === 1) {
|
|
47642
|
-
const [singleHash, singleAsset] = entries[0];
|
|
47643
|
-
return {
|
|
47644
|
-
hash: singleHash,
|
|
47645
|
-
asset: singleAsset
|
|
47646
|
-
};
|
|
47647
|
-
}
|
|
47648
|
-
}
|
|
47649
|
-
/**
|
|
47650
|
-
* Extract the source hash from a Lambda `Code.ImageUri` string. CDK's
|
|
47651
|
-
* bootstrap layout ends every image URI in `:<hex-hash>`, and that hash
|
|
47652
|
-
* is the same key used in the asset manifest's `dockerImages` map.
|
|
47653
|
-
*
|
|
47654
|
-
* Returns `undefined` for shapes we can't parse (digest pins, missing tag,
|
|
47655
|
-
* etc.) — the caller falls back to the single-asset heuristic.
|
|
47656
|
-
*/
|
|
47657
|
-
function extractHashFromImageUri(imageUri) {
|
|
47658
|
-
if (imageUri.includes("@sha256:")) return void 0;
|
|
47659
|
-
return /:([a-f0-9]{8,})$/.exec(imageUri)?.[1];
|
|
47660
|
-
}
|
|
47661
|
-
|
|
47662
47677
|
//#endregion
|
|
47663
47678
|
//#region src/utils/single-flight.ts
|
|
47664
47679
|
/**
|
|
@@ -54681,7 +54696,7 @@ function reorderArgs(argv) {
|
|
|
54681
54696
|
async function main() {
|
|
54682
54697
|
installPipeCloseHandler();
|
|
54683
54698
|
const program = new Command();
|
|
54684
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
54699
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.227.1");
|
|
54685
54700
|
program.addCommand(createBootstrapCommand());
|
|
54686
54701
|
program.addCommand(createSynthCommand());
|
|
54687
54702
|
program.addCommand(createListCommand());
|