@go-to-k/cdkd 0.115.1 → 0.115.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/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-CuHRHcyW.js";
3
- import { A as resolveApp, B as CdkdError, C as AssetPublisher, D as Synthesizer, E as buildDockerImage, F as warnDeprecatedNoPrefixCliFlag, G as PartialFailureError, I as AssemblyReader, J as ResourceUpdateNotSupportedError, K as ProvisioningError, M as resolveSkipPrefix, N as resolveStateBucketWithDefault, O as getDefaultStateBucketName, P as resolveStateBucketWithDefaultAndSource, R as resolveBucketRegion, S as shouldRetainResource, T as WorkGraph, U as LocalInvokeBuildError, X as StackHasActiveImportsError, Y as RouteDiscoveryError, Z as StackTerminationProtectionError, _ as DiffCalculator, a as withRetry, at as getLogger, b as LockManager, c as collectInlinePolicyNamesManagedBySiblings, ct as getLiveRenderer, d as normalizeAwsTagsToCfn, dt as generateResourceName, f as resolveExplicitPhysicalId, ft as generateResourceNameWithFallback, g as IntrinsicFunctionResolver, h as assertRegionMatch, i as withResourceDeadline, j as resolveCaptureObservedState, k as getLegacyStateBucketName, l as CDK_PATH_TAG, lt as PATTERN_B_NAME_PROPERTIES, m as CloudControlProvider, mt as withStackName, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as normalizeAwsError, o as IMPLICIT_DELETE_DEPENDENCIES, p as ProviderRegistry, pt as withSkipPrefix, q as ResourceTimeoutError, r as DeployEngine, rt as withErrorHandling, s as IAMRoleProvider, st as runStackBuffered, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as matchesCdkPath, ut as PATTERN_B_RESOURCE_TYPES, v as DagBuilder, w as stringifyValue, x as S3StateBackend, y as TemplateParser } from "./deploy-engine-CAg_d5uX.js";
3
+ import { $ as StackTerminationProtectionError, A as getDefaultStateBucketName, B as resolveBucketRegion, C as AssetPublisher, D as getDockerCmd, E as buildDockerImage, F as resolveStateBucketWithDefault, G as LocalInvokeBuildError, H as CdkdError, I as resolveStateBucketWithDefaultAndSource, J as ProvisioningError, L as warnDeprecatedNoPrefixCliFlag, M as resolveApp, N as resolveCaptureObservedState, O as runDockerStreaming, P as resolveSkipPrefix, Q as StackHasActiveImportsError, R as AssemblyReader, S as shouldRetainResource, T as WorkGraph, X as ResourceUpdateNotSupportedError, Y as ResourceTimeoutError, Z as RouteDiscoveryError, _ as DiffCalculator, a as withRetry, at as withErrorHandling, b as LockManager, c as collectInlinePolicyNamesManagedBySiblings, d as normalizeAwsTagsToCfn, dt as PATTERN_B_NAME_PROPERTIES, f as resolveExplicitPhysicalId, ft as PATTERN_B_RESOURCE_TYPES, g as IntrinsicFunctionResolver, gt as withStackName, h as assertRegionMatch, ht as withSkipPrefix, i as withResourceDeadline, it as normalizeAwsError, j as getLegacyStateBucketName, k as Synthesizer, l as CDK_PATH_TAG, lt as runStackBuffered, m as CloudControlProvider, mt as generateResourceNameWithFallback, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as IMPLICIT_DELETE_DEPENDENCIES, p as ProviderRegistry, pt as generateResourceName, q as PartialFailureError, r as DeployEngine, s as IAMRoleProvider, st as getLogger, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as matchesCdkPath, ut as getLiveRenderer, v as DagBuilder, w as stringifyValue, x as S3StateBackend, y as TemplateParser } from "./deploy-engine-AoZgViZN.js";
4
4
  import { createHash, createPublicKey, createVerify, randomBytes, randomUUID } from "node:crypto";
5
5
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
6
6
  import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachUserPolicyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachUserPolicyCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListInstanceProfilesCommand, ListUserPoliciesCommand, ListUserTagsCommand, ListUsersCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagUserCommand, UntagUserCommand, UpdateLoginProfileCommand } from "@aws-sdk/client-iam";
@@ -27,7 +27,6 @@ import { tmpdir } from "node:os";
27
27
  import { AssociateVPCWithHostedZoneCommand, ChangeResourceRecordSetsCommand, ChangeTagsForResourceCommand, CreateHostedZoneCommand, CreateQueryLoggingConfigCommand, DeleteHostedZoneCommand, DeleteQueryLoggingConfigCommand, DisassociateVPCFromHostedZoneCommand, GetHostedZoneCommand, ListHostedZonesByNameCommand, ListHostedZonesCommand, ListQueryLoggingConfigsCommand, ListResourceRecordSetsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$6, Route53Client, UpdateHostedZoneCommentCommand } from "@aws-sdk/client-route-53";
28
28
  import { AddTagsCommand, CreateListenerCommand, CreateLoadBalancerCommand, CreateTargetGroupCommand, DeleteListenerCommand, DeleteLoadBalancerCommand, DeleteTargetGroupCommand, DescribeListenersCommand, DescribeLoadBalancerAttributesCommand, DescribeLoadBalancersCommand, DescribeTagsCommand, DescribeTargetGroupsCommand, ElasticLoadBalancingV2Client, ModifyListenerCommand, ModifyLoadBalancerAttributesCommand, ModifyTargetGroupCommand, RemoveTagsCommand, SetIpAddressTypeCommand, SetSecurityGroupsCommand, SetSubnetsCommand } from "@aws-sdk/client-elastic-load-balancing-v2";
29
29
  import { CreateAliasCommand, CreateKeyCommand, DeleteAliasCommand, DescribeKeyCommand, DisableKeyCommand, DisableKeyRotationCommand, EnableKeyCommand, EnableKeyRotationCommand, GetKeyPolicyCommand, GetKeyRotationStatusCommand, KMSClient, ListAliasesCommand, ListKeysCommand, ListResourceTagsCommand, NotFoundException as NotFoundException$2, PutKeyPolicyCommand, ScheduleKeyDeletionCommand, TagResourceCommand as TagResourceCommand$8, UntagResourceCommand as UntagResourceCommand$8, UpdateAliasCommand, UpdateKeyDescriptionCommand } from "@aws-sdk/client-kms";
30
- import { promisify } from "node:util";
31
30
  import { CreateRepositoryCommand, DeleteLifecyclePolicyCommand, DeleteRepositoryCommand, DeleteRepositoryPolicyCommand, DescribeRepositoriesCommand, ECRClient, GetAuthorizationTokenCommand, GetLifecyclePolicyCommand, LifecyclePolicyNotFoundException, ListTagsForResourceCommand as ListTagsForResourceCommand$7, PutImageScanningConfigurationCommand, PutImageTagMutabilityCommand, PutLifecyclePolicyCommand, RepositoryNotFoundException, SetRepositoryPolicyCommand, TagResourceCommand as TagResourceCommand$9 } from "@aws-sdk/client-ecr";
32
31
  import graphlib from "graphlib";
33
32
  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";
@@ -58,6 +57,7 @@ import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as
58
57
  import { AttachTrafficSourcesCommand, AutoScalingClient, CreateAutoScalingGroupCommand, DeleteAutoScalingGroupCommand, DeleteLifecycleHookCommand, DeleteNotificationConfigurationCommand, DescribeAutoScalingGroupsCommand, DescribeLifecycleHooksCommand, DescribeNotificationConfigurationsCommand, DescribeTrafficSourcesCommand, DetachTrafficSourcesCommand, DisableMetricsCollectionCommand, EnableMetricsCollectionCommand, PutLifecycleHookCommand, PutNotificationConfigurationCommand, UpdateAutoScalingGroupCommand } from "@aws-sdk/client-auto-scaling";
59
58
  import * as readline from "node:readline/promises";
60
59
  import { createServer } from "node:net";
60
+ import { promisify } from "node:util";
61
61
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
62
62
  import { readFile } from "fs/promises";
63
63
  import { createServer as createServer$1 } from "node:http";
@@ -37331,7 +37331,7 @@ function resolveRuntimeCodeMountPath(runtime) {
37331
37331
 
37332
37332
  //#endregion
37333
37333
  //#region src/local/docker-runner.ts
37334
- const execFileAsync$3 = promisify(execFile);
37334
+ const execFileAsync$2 = promisify(execFile);
37335
37335
  /**
37336
37336
  * Wraps `docker pull` / `docker run` / `docker rm` for `cdkd local invoke`.
37337
37337
  *
@@ -37366,11 +37366,11 @@ async function pullImage(image, skipPull) {
37366
37366
  }
37367
37367
  if (getLogger().getLevel() === "debug") {
37368
37368
  logger.info(`Pulling ${image}...`);
37369
- await runForeground$1("docker", ["pull", image]);
37369
+ await runForeground$1(getDockerCmd(), ["pull", image]);
37370
37370
  return;
37371
37371
  }
37372
37372
  logger.debug(`Pulling ${image} (silent — pass --verbose to stream progress)`);
37373
- await runCaptured("docker", ["pull", image], image);
37373
+ await runCaptured(getDockerCmd(), ["pull", image], image);
37374
37374
  }
37375
37375
  /**
37376
37376
  * Run a child process with stdout / stderr captured (not inherited).
@@ -37441,9 +37441,9 @@ async function runDetached(opts) {
37441
37441
  entryPointTail = opts.entryPoint.slice(1);
37442
37442
  }
37443
37443
  args.push(opts.image, ...entryPointTail, ...opts.cmd);
37444
- getLogger().child("docker").debug(`docker ${redactAwsCredentialsInArgs(args).join(" ")}`);
37444
+ getLogger().child("docker").debug(`${getDockerCmd()} ${redactAwsCredentialsInArgs(args).join(" ")}`);
37445
37445
  try {
37446
- const { stdout } = await execFileAsync$3("docker", args, { maxBuffer: 10 * 1024 * 1024 });
37446
+ const { stdout } = await execFileAsync$2(getDockerCmd(), args, { maxBuffer: 10 * 1024 * 1024 });
37447
37447
  return stdout.trim();
37448
37448
  } catch (error) {
37449
37449
  const err = error;
@@ -37455,7 +37455,7 @@ async function runDetached(opts) {
37455
37455
  * stops the stream (used by the caller in a `finally` block).
37456
37456
  */
37457
37457
  function streamLogs(containerId) {
37458
- const proc = spawn("docker", [
37458
+ const proc = spawn(getDockerCmd(), [
37459
37459
  "logs",
37460
37460
  "-f",
37461
37461
  containerId
@@ -37480,7 +37480,7 @@ async function removeContainer(containerId) {
37480
37480
  if (!containerId) return;
37481
37481
  const logger = getLogger().child("docker");
37482
37482
  try {
37483
- await execFileAsync$3("docker", [
37483
+ await execFileAsync$2(getDockerCmd(), [
37484
37484
  "rm",
37485
37485
  "-f",
37486
37486
  containerId
@@ -37497,16 +37497,17 @@ async function removeContainer(containerId) {
37497
37497
  * otherwise see at the first run call. Called once up front.
37498
37498
  */
37499
37499
  async function ensureDockerAvailable() {
37500
+ const cmd = getDockerCmd();
37500
37501
  try {
37501
- await execFileAsync$3("docker", [
37502
+ await execFileAsync$2(cmd, [
37502
37503
  "version",
37503
37504
  "--format",
37504
37505
  "{{.Server.Version}}"
37505
37506
  ]);
37506
37507
  } catch (error) {
37507
37508
  const err = error;
37508
- if (err.code === "ENOENT") throw new DockerRunnerError("docker is not installed or not on PATH. cdkd local invoke needs Docker install Docker Desktop or the docker CLI and retry.");
37509
- throw new DockerRunnerError(`docker daemon is not reachable: ${err.stderr?.trim() || err.message || String(error)}. Start Docker Desktop / the docker daemon and retry.`);
37509
+ if (err.code === "ENOENT") throw new DockerRunnerError(`${cmd} is not installed or not on PATH. cdkd local invoke needs Docker (or a compatible CLI specified via CDK_DOCKER) install it and retry.`);
37510
+ throw new DockerRunnerError(`${cmd} daemon is not reachable: ${err.stderr?.trim() || err.message || String(error)}. Start Docker Desktop / the docker daemon and retry.`);
37510
37511
  }
37511
37512
  }
37512
37513
  /**
@@ -37593,7 +37594,6 @@ function runForeground$1(cmd, args) {
37593
37594
 
37594
37595
  //#endregion
37595
37596
  //#region src/local/ecr-puller.ts
37596
- const execFileAsync$2 = promisify(execFile);
37597
37597
  /**
37598
37598
  * ECR pull fallback for `cdkd local invoke` against deployed container
37599
37599
  * Lambdas (PR 5, D5.2). When `Code.ImageUri` resolves to an ECR URI but
@@ -37665,7 +37665,7 @@ async function pullEcrImage(imageUri, options) {
37665
37665
  ecr.destroy();
37666
37666
  }
37667
37667
  logger.info(`Pulling ${imageUri}...`);
37668
- await runForeground("docker", ["pull", imageUri]);
37668
+ await runForeground(getDockerCmd(), ["pull", imageUri]);
37669
37669
  return imageUri;
37670
37670
  }
37671
37671
  /**
@@ -37679,33 +37679,20 @@ async function ecrLogin(client, accountId, region) {
37679
37679
  const authData = (await client.send(new GetAuthorizationTokenCommand({}))).authorizationData?.[0];
37680
37680
  if (!authData?.authorizationToken) throw new LocalInvokeBuildError("Failed to get ECR authorization token");
37681
37681
  const [username, password] = Buffer.from(authData.authorizationToken, "base64").toString().split(":");
37682
+ if (!username || password === void 0) throw new LocalInvokeBuildError("ECR authorization token has unexpected shape (missing username/password)");
37682
37683
  const endpoint = authData.proxyEndpoint || `https://${accountId}.dkr.ecr.${region}.amazonaws.com`;
37683
- await new Promise((resolve, reject) => {
37684
- const proc = spawn("docker", [
37684
+ try {
37685
+ await runDockerStreaming([
37685
37686
  "login",
37686
37687
  "--username",
37687
37688
  username,
37688
37689
  "--password-stdin",
37689
37690
  endpoint
37690
- ], { stdio: [
37691
- "pipe",
37692
- "pipe",
37693
- "pipe"
37694
- ] });
37695
- let stderr = "";
37696
- proc.stderr?.on("data", (data) => {
37697
- stderr += data.toString();
37698
- });
37699
- proc.on("close", (code) => {
37700
- if (code === 0) resolve();
37701
- else reject(new LocalInvokeBuildError(`ECR login failed: ${stderr.trim()}`));
37702
- });
37703
- proc.on("error", (err) => {
37704
- reject(new LocalInvokeBuildError(`ECR login failed: ${err.message}`));
37705
- });
37706
- proc.stdin?.write(password);
37707
- proc.stdin?.end();
37708
- });
37691
+ ], { input: password });
37692
+ } catch (err) {
37693
+ const e = err;
37694
+ throw new LocalInvokeBuildError(`ECR login failed: ${e.stderr?.trim() || e.message || String(err)}`);
37695
+ }
37709
37696
  }
37710
37697
  /**
37711
37698
  * `docker image inspect <uri>` returns non-zero when the image is not in
@@ -37714,7 +37701,7 @@ async function ecrLogin(client, accountId, region) {
37714
37701
  */
37715
37702
  async function verifyImageInLocalCache(imageUri) {
37716
37703
  try {
37717
- await execFileAsync$2("docker", [
37704
+ await runDockerStreaming([
37718
37705
  "image",
37719
37706
  "inspect",
37720
37707
  imageUri
@@ -37732,7 +37719,7 @@ async function verifyImageInLocalCache(imageUri) {
37732
37719
  */
37733
37720
  async function isImageInLocalCache(imageRef) {
37734
37721
  try {
37735
- await execFileAsync$2("docker", [
37722
+ await runDockerStreaming([
37736
37723
  "image",
37737
37724
  "inspect",
37738
37725
  imageRef
@@ -37782,10 +37769,24 @@ async function buildContainerImage(asset, cdkOutDir, options) {
37782
37769
  }
37783
37770
  logger.info(`Building container image (platform=${platform})...`);
37784
37771
  logger.debug(`Local tag: ${tag}`);
37785
- await buildDockerImage(asset, cdkOutDir, tag, {
37772
+ const actualTag = await buildDockerImage(asset, cdkOutDir, {
37773
+ tag,
37786
37774
  platform,
37787
- wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for container Lambda asset (${asset.source.directory}): ${stderr}`)
37775
+ wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for container Lambda asset (${asset.source.directory ?? asset.source.executable?.join(" ")}): ${stderr}`)
37788
37776
  });
37777
+ if (actualTag !== tag) {
37778
+ logger.debug(`Re-tagging executable-built image '${actualTag}' → '${tag}'`);
37779
+ try {
37780
+ await runDockerStreaming([
37781
+ "tag",
37782
+ actualTag,
37783
+ tag
37784
+ ]);
37785
+ } catch (err) {
37786
+ const e = err;
37787
+ throw new LocalInvokeBuildError(`docker tag failed re-tagging '${actualTag}' → '${tag}': ${e.stderr?.trim() || e.message || String(err)}`);
37788
+ }
37789
+ }
37789
37790
  return tag;
37790
37791
  }
37791
37792
  /**
@@ -37800,27 +37801,49 @@ function architectureToPlatform(architecture) {
37800
37801
  return architecture === "arm64" ? "linux/arm64" : "linux/amd64";
37801
37802
  }
37802
37803
  /**
37803
- * Build a stable local tag derived from the asset's build context. We
37804
- * fingerprint `directory + dockerFile + dockerBuildTarget + dockerBuildArgs`
37805
- * so an iteration that doesn't change those fields hits Docker's layer
37806
- * cache; an iteration that DOES change them gets a fresh tag (the old
37807
- * tag stays around in `docker images` but harmlessly).
37804
+ * Build a stable local tag derived from the asset's build context.
37805
+ *
37806
+ * Fingerprints every field that affects the produced image so an iteration
37807
+ * that doesn't change those fields hits Docker's layer cache; an iteration
37808
+ * that DOES change them gets a fresh tag (the old tag stays around in
37809
+ * `docker images` but harmlessly). The fingerprint covers the full CDK
37810
+ * `DockerImageSource` schema so `dockerBuildSecrets` / `dockerBuildContexts`
37811
+ * / `cacheFrom` / etc. changes also bust the local cache as expected.
37808
37812
  */
37809
37813
  function computeLocalTag(source) {
37810
37814
  const hash = createHash("sha256");
37811
- hash.update(source.directory);
37812
- hash.update("\0");
37813
- hash.update(source.dockerFile ?? "");
37814
- hash.update("\0");
37815
- hash.update(source.dockerBuildTarget ?? "");
37815
+ pushField(hash, "directory", source.directory ?? "");
37816
+ pushField(hash, "executable", (source.executable ?? []).join(" "));
37817
+ pushField(hash, "dockerFile", source.dockerFile ?? "");
37818
+ pushField(hash, "dockerBuildTarget", source.dockerBuildTarget ?? "");
37819
+ pushField(hash, "networkMode", source.networkMode ?? "");
37820
+ pushField(hash, "platform", source.platform ?? "");
37821
+ pushField(hash, "dockerBuildSsh", source.dockerBuildSsh ?? "");
37822
+ pushField(hash, "cacheDisabled", source.cacheDisabled ? "1" : "0");
37823
+ pushMap(hash, "dockerBuildArgs", source.dockerBuildArgs);
37824
+ pushMap(hash, "dockerBuildContexts", source.dockerBuildContexts);
37825
+ pushMap(hash, "dockerBuildSecrets", source.dockerBuildSecrets);
37826
+ pushField(hash, "dockerOutputs", (source.dockerOutputs ?? []).join(""));
37827
+ pushField(hash, "cacheFrom", (source.cacheFrom ?? []).map((o) => JSON.stringify(o)).join(""));
37828
+ pushField(hash, "cacheTo", source.cacheTo ? JSON.stringify(source.cacheTo) : "");
37829
+ return `cdkd-local-invoke-${hash.digest("hex").slice(0, 16)}`;
37830
+ }
37831
+ function pushField(hash, name, value) {
37832
+ hash.update(name);
37833
+ hash.update("=");
37834
+ hash.update(value);
37816
37835
  hash.update("\0");
37817
- if (source.dockerBuildArgs) for (const [k, v] of Object.entries(source.dockerBuildArgs)) {
37836
+ }
37837
+ function pushMap(hash, name, value) {
37838
+ hash.update(name);
37839
+ hash.update("={");
37840
+ if (value) for (const [k, v] of Object.entries(value)) {
37818
37841
  hash.update(k);
37819
37842
  hash.update("=");
37820
37843
  hash.update(v);
37821
- hash.update("\0");
37844
+ hash.update(";");
37822
37845
  }
37823
- return `cdkd-local-invoke-${hash.digest("hex").slice(0, 16)}`;
37846
+ hash.update("}\0");
37824
37847
  }
37825
37848
 
37826
37849
  //#endregion
@@ -42767,7 +42790,7 @@ async function createTaskNetwork(options = {}) {
42767
42790
  await pullImage(METADATA_ENDPOINT_IMAGE, options.skipPull ?? false);
42768
42791
  logger.info(`Creating docker network ${networkName} (subnet ${METADATA_ENDPOINT_SUBNET})...`);
42769
42792
  try {
42770
- await execFileAsync$1("docker", [
42793
+ await execFileAsync$1(getDockerCmd(), [
42771
42794
  "network",
42772
42795
  "create",
42773
42796
  "--driver",
@@ -42803,7 +42826,7 @@ async function createTaskNetwork(options = {}) {
42803
42826
  logger.info("Starting ECS local-container-endpoints sidecar at 169.254.170.2...");
42804
42827
  let sidecarContainerId;
42805
42828
  try {
42806
- const { stdout } = await execFileAsync$1("docker", sidecarArgs, { maxBuffer: 10 * 1024 * 1024 });
42829
+ const { stdout } = await execFileAsync$1(getDockerCmd(), sidecarArgs, { maxBuffer: 10 * 1024 * 1024 });
42807
42830
  sidecarContainerId = stdout.trim();
42808
42831
  } catch (err) {
42809
42832
  await destroyNetworkOnly(networkName);
@@ -42849,7 +42872,7 @@ async function destroyNetworkOnly(networkName) {
42849
42872
  if (!networkName) return;
42850
42873
  const logger = getLogger().child("ecs-network");
42851
42874
  try {
42852
- await execFileAsync$1("docker", [
42875
+ await execFileAsync$1(getDockerCmd(), [
42853
42876
  "network",
42854
42877
  "rm",
42855
42878
  networkName
@@ -43042,7 +43065,7 @@ async function cleanupEcsRun(state, options) {
43042
43065
  await destroyTaskNetwork(state.network);
43043
43066
  state.network = void 0;
43044
43067
  for (const v of state.dockerVolumeNames) try {
43045
- await execFileAsync("docker", [
43068
+ await execFileAsync(getDockerCmd(), [
43046
43069
  "volume",
43047
43070
  "rm",
43048
43071
  v
@@ -43106,7 +43129,7 @@ async function runEcsTask(task, options, state) {
43106
43129
  logger.info(`Starting container '${container.name}' (image=${imagePlan.get(container.name)})`);
43107
43130
  let id;
43108
43131
  try {
43109
- const { stdout } = await execFileAsync("docker", args, { maxBuffer: 10 * 1024 * 1024 });
43132
+ const { stdout } = await execFileAsync(getDockerCmd(), args, { maxBuffer: 10 * 1024 * 1024 });
43110
43133
  id = stdout.trim();
43111
43134
  } catch (err) {
43112
43135
  const e = err;
@@ -43215,7 +43238,7 @@ async function waitForContainerHealthy(containerId, displayName) {
43215
43238
  let lastStatus = "";
43216
43239
  while (Date.now() < deadline) {
43217
43240
  try {
43218
- const { stdout } = await execFileAsync("docker", [
43241
+ const { stdout } = await execFileAsync(getDockerCmd(), [
43219
43242
  "inspect",
43220
43243
  "--format",
43221
43244
  "{{.State.Health.Status}}",
@@ -43238,7 +43261,7 @@ async function waitForContainerHealthy(containerId, displayName) {
43238
43261
  }
43239
43262
  async function waitForContainerExit(containerId) {
43240
43263
  try {
43241
- const { stdout } = await execFileAsync("docker", ["wait", containerId], { maxBuffer: 1024 * 1024 });
43264
+ const { stdout } = await execFileAsync(getDockerCmd(), ["wait", containerId], { maxBuffer: 1024 * 1024 });
43242
43265
  const code = Number.parseInt(stdout.trim(), 10);
43243
43266
  return Number.isFinite(code) ? code : 1;
43244
43267
  } catch (err) {
@@ -43248,7 +43271,7 @@ async function waitForContainerExit(containerId) {
43248
43271
  }
43249
43272
  async function stopContainer(containerId, graceSeconds) {
43250
43273
  try {
43251
- await execFileAsync("docker", [
43274
+ await execFileAsync(getDockerCmd(), [
43252
43275
  "stop",
43253
43276
  "-t",
43254
43277
  String(graceSeconds),
@@ -43264,7 +43287,7 @@ function sleep(ms) {
43264
43287
  * every line. Returns a stop function for the caller's `finally`.
43265
43288
  */
43266
43289
  function streamContainerLogs(containerName, containerId) {
43267
- const proc = spawn("docker", [
43290
+ const proc = spawn(getDockerCmd(), [
43268
43291
  "logs",
43269
43292
  "-f",
43270
43293
  containerId
@@ -43331,10 +43354,21 @@ async function prepareOneImage(task, container, options) {
43331
43354
  else if (entries.length === 1) asset = entries[0][1];
43332
43355
  if (!asset) throw new EcsTaskRunnerError(`Container '${container.name}' references a CDK asset image but no matching entry was found in cdk.out. Re-synthesize the CDK app and retry.`);
43333
43356
  const tag = `cdkd-local-run-task-${(image.assetHash ?? "single").slice(0, 16)}`;
43334
- await buildDockerImage(asset, cdkOutDir, tag, {
43357
+ const actualTag = await buildDockerImage(asset, cdkOutDir, {
43358
+ tag,
43335
43359
  ...options.platformOverride !== void 0 && { platform: options.platformOverride },
43336
- wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for ECS container '${container.name}' (${asset.source.directory}): ${stderr}`)
43360
+ wrapError: (stderr) => new LocalInvokeBuildError(`docker build failed for ECS container '${container.name}' (${asset.source.directory ?? asset.source.executable?.join(" ")}): ${stderr}`)
43337
43361
  });
43362
+ if (actualTag !== tag) try {
43363
+ await runDockerStreaming([
43364
+ "tag",
43365
+ actualTag,
43366
+ tag
43367
+ ]);
43368
+ } catch (err) {
43369
+ const e = err;
43370
+ throw new LocalInvokeBuildError(`docker tag failed re-tagging '${actualTag}' → '${tag}' for ECS container '${container.name}': ${e.stderr?.trim() || e.message || String(err)}`);
43371
+ }
43338
43372
  return tag;
43339
43373
  }
43340
43374
  }
@@ -43361,7 +43395,7 @@ async function realizeDockerVolumes(volumes, state) {
43361
43395
  const dockerVolumeName = `cdkd-local-${v.name}-${randHex(4)}`;
43362
43396
  args.push(dockerVolumeName);
43363
43397
  try {
43364
- await execFileAsync("docker", args);
43398
+ await execFileAsync(getDockerCmd(), args);
43365
43399
  state.dockerVolumeNames.push(dockerVolumeName);
43366
43400
  logger.debug(`Created docker volume ${dockerVolumeName} for task volume '${v.name}'`);
43367
43401
  } catch (err) {
@@ -45560,7 +45594,7 @@ function reorderArgs(argv) {
45560
45594
  */
45561
45595
  async function main() {
45562
45596
  const program = new Command();
45563
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.115.1");
45597
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.115.2");
45564
45598
  program.addCommand(createBootstrapCommand());
45565
45599
  program.addCommand(createSynthCommand());
45566
45600
  program.addCommand(createListCommand());