@go-to-k/cdkd 0.246.0 → 0.247.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,11 +4,11 @@
4
4
  [![Downloads](https://img.shields.io/npm/dw/@go-to-k/cdkd.svg)](https://www.npmjs.com/package/@go-to-k/cdkd)
5
5
  [![License: Apache-2.0](https://img.shields.io/npm/l/@go-to-k/cdkd.svg)](./LICENSE)
6
6
 
7
- Drop-in CDK CLI for existing CDK apps faster deploys via AWS SDK instead of CloudFormation, plus local emulation for Lambda, API Gateway, and ECS.
7
+ Drop-in CDK CLI for existing CDK apps: up to 15x faster deploys via AWS SDK instead of CloudFormation.
8
8
 
9
- - **Drop-in CDK compatible** your existing CDK app code runs as-is.
10
- - **Up to 15x faster deploys than the AWS CDK CLI (CloudFormation)**
11
- - **Local dev for any CDK app** invoke Lambdas, serve API Gateway routes, run ECS tasks/services directly from your CDK code. Works against both `cdkd deploy`-managed AND `cdk deploy`-managed (CloudFormation) stacks via `--from-state` / `--from-cfn-stack` — no migration, no `cdk synth → sam local` round-trip.
9
+ - **Drop-in CDK compatible**: your existing CDK app code runs as-is.
10
+ - **Up to 15x faster deploys**: direct SDK calls, aggressive parallelization, and `--no-wait` to skip slow stabilization waits.
11
+ - **Local execution**: run your functions and APIs locally, with env vars, secrets, and resource references resolved from your deployed stack instead of hand-written `.env` files.
12
12
 
13
13
  ![cdk deploy vs cdkd deploy — side-by-side, 35s recording, real AWS deploy. cdkd finishes while cdk is still creating its CloudFormation changeset.](assets/cdk-vs-cdkd.gif)
14
14
 
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BzO-joNR.js";
3
3
  import { A as withErrorHandling, C as StackHasActiveImportsError, S as ResourceUpdateNotSupportedError, _ as MissingCdkCliError, a as normalizeAwsTagsToCfn, b as ProvisioningError, f as LocalInvokeBuildError$1, i as matchesCdkPath, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as isTerminationProtectionPropagationError, o as resolveExplicitPhysicalId, p as LocalMigrateError, r as CDK_PATH_TAG, s as assertRegionMatch, t as disableInstanceApiTermination, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError } from "./ec2-termination-protection-q-WGWgxa.js";
4
4
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-B15NAPbL.js";
5
- import { $ as getDockerCmd, A as DiffCalculator, B as buildAssetRedirectMap, C as findActionableSilentDrops, Ct as resolveBucketRegion, D as refStateLookupFromResource, E as cfnRefValueFromPhysicalId, F as rebuildClientForBucketRegion, G as BOOTSTRAP_MARKER_PREFIX, H as loadPublishableAssetManifest, I as shouldRetainResource, J as parseBootstrapMarker, K as ensureAssetStorage, L as AssetPublisher, M as TemplateParser, N as LockManager, O as WAFv2WebACLProvider, P as S3StateBackend, Q as formatDockerLoginError, R as stringifyValue, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as rewriteTemplateAssetReferences, V as createAssetRedirectResolver, W as AssetModeResolver, X as validateContainerRepoName, Y as validateAssetBucketName, Z as buildDockerImage, _ as green, _t as CFN_TEMPLATE_URL_LIMIT, a as withRetry, at as synthesisStatusMessage, b as IAMRoleProvider, bt as uploadCfnTemplate, c as computeImplicitDeleteEdges, ct as resolveApp, d as isStatefulRecreateTargetSync, dt as resolveSkipPrefix, et as runDockerForeground, f as renderStatefulReason, ft as resolveStateBucketWithDefault, g as gray, gt as CFN_TEMPLATE_BODY_LIMIT, h as cyan, ht as warnDeprecatedNoPrefixCliFlag, i as withResourceDeadline, it as Synthesizer, j as DagBuilder, k as applyRoleArnIfSet, l as extractDeploymentEventError, lt as resolveAutoAssetStorage, m as bold, mt as resolveUseCdkBootstrapAssets, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as AssetManifestLoader, o as isRetryableTransientError, ot as getDefaultStateBucketName, p as formatResourceLine, pt as resolveStateBucketWithDefaultAndSource, q as getBootstrapMarkerKey, r as DeployEngine, rt as getDockerImageBySourceHash, s as IMPLICIT_DELETE_DEPENDENCIES, st as getLegacyStateBucketName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as runDockerStreaming, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as resolveCaptureObservedState, v as red, vt as MIGRATE_TMP_PREFIX, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, xt as AssemblyReader, y as yellow, yt as findLargeInlineResources, z as WorkGraph } from "./deploy-engine-Ci_7Y2ol.js";
5
+ import { $ as getDockerCmd, A as DiffCalculator, B as buildAssetRedirectMap, C as findActionableSilentDrops, Ct as resolveBucketRegion, D as refStateLookupFromResource, E as cfnRefValueFromPhysicalId, F as rebuildClientForBucketRegion, G as BOOTSTRAP_MARKER_PREFIX, H as loadPublishableAssetManifest, I as shouldRetainResource, J as parseBootstrapMarker, K as ensureAssetStorage, L as AssetPublisher, M as TemplateParser, N as LockManager, O as WAFv2WebACLProvider, P as S3StateBackend, Q as formatDockerLoginError, R as stringifyValue, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as rewriteTemplateAssetReferences, V as createAssetRedirectResolver, W as AssetModeResolver, X as validateContainerRepoName, Y as validateAssetBucketName, Z as buildDockerImage, _ as green, _t as CFN_TEMPLATE_URL_LIMIT, a as withRetry, at as synthesisStatusMessage, b as IAMRoleProvider, bt as uploadCfnTemplate, c as computeImplicitDeleteEdges, ct as resolveApp, d as isStatefulRecreateTargetSync, dt as resolveSkipPrefix, et as runDockerForeground, f as renderStatefulReason, ft as resolveStateBucketWithDefault, g as gray, gt as CFN_TEMPLATE_BODY_LIMIT, h as cyan, ht as warnDeprecatedNoPrefixCliFlag, i as withResourceDeadline, it as Synthesizer, j as DagBuilder, k as applyRoleArnIfSet, l as extractDeploymentEventError, lt as resolveAutoAssetStorage, m as bold, mt as resolveUseCdkBootstrapAssets, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as AssetManifestLoader, o as isRetryableTransientError, ot as getDefaultStateBucketName, p as formatResourceLine, pt as resolveStateBucketWithDefaultAndSource, q as getBootstrapMarkerKey, r as DeployEngine, rt as getDockerImageBySourceHash, s as IMPLICIT_DELETE_DEPENDENCIES, st as getLegacyStateBucketName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as runDockerStreaming, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as resolveCaptureObservedState, v as red, vt as MIGRATE_TMP_PREFIX, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, xt as AssemblyReader, y as yellow, yt as findLargeInlineResources, z as WorkGraph } from "./deploy-engine-D6U-Cm8B.js";
6
6
  import { t as expectedOwnerParam } from "./expected-bucket-owner-BjEfUnkA.js";
7
7
  import { t as ASGProvider } from "./asg-provider-Dbl1_mwT.js";
8
8
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -64,7 +64,8 @@ import { AddTagsCommand as AddTagsCommand$1, DescribeClusterCommand, EMRClient,
64
64
  import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListDeliveryStreamsCommand, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$10, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
65
65
  import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$1, ListTrailsCommand, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
66
66
  import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ListProjectsCommand, ResourceNotFoundException as ResourceNotFoundException$11, UpdateProjectCommand } from "@aws-sdk/client-codebuild";
67
- import { CodeCommitClient, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, ListRepositoriesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$19, UntagResourceCommand as UntagResourceCommand$19, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
67
+ import { CodeCommitClient, CreateCommitCommand, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, ListRepositoriesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, PutRepositoryTriggersCommand, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$19, UntagResourceCommand as UntagResourceCommand$19, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
68
+ import AdmZip from "adm-zip";
68
69
  import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$12, TagResourceCommand as TagResourceCommand$20, UntagResourceCommand as UntagResourceCommand$20, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
69
70
  import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$20, ListVectorBucketsCommand, S3VectorsClient, TagResourceCommand as TagResourceCommand$21, UntagResourceCommand as UntagResourceCommand$21 } from "@aws-sdk/client-s3vectors";
70
71
  import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand as ListTablesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$21, NotFoundException as NotFoundException$6, S3TablesClient, TagResourceCommand as TagResourceCommand$22, UntagResourceCommand as UntagResourceCommand$22 } from "@aws-sdk/client-s3tables";
@@ -1890,7 +1891,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1890
1891
  const FLUSH_EVENT_THRESHOLD = 50;
1891
1892
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1892
1893
  function getCdkdVersion() {
1893
- return "0.246.0";
1894
+ return "0.247.0";
1894
1895
  }
1895
1896
  /**
1896
1897
  * Generate a time-sortable unique run id, e.g.
@@ -37608,6 +37609,54 @@ function tagMapsEqual(a, b) {
37608
37609
  if (aKeys.length !== Object.keys(b).length) return false;
37609
37610
  return aKeys.every((k) => b[k] === a[k]);
37610
37611
  }
37612
+ /** Default branch for the `Code` seed commit when `BranchName` is omitted. */
37613
+ const DEFAULT_SEED_BRANCH = "main";
37614
+ /**
37615
+ * Coerce a CFn scalar value to a string. Post-intrinsic-resolution values are
37616
+ * strings in practice; numbers / booleans are stringified and any other shape
37617
+ * (object / null / undefined) collapses to `''` — avoids stringifying an
37618
+ * object to the useless `'[object Object]'`.
37619
+ */
37620
+ function scalarToString(value) {
37621
+ if (typeof value === "string") return value;
37622
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
37623
+ return "";
37624
+ }
37625
+ /**
37626
+ * Convert the CFn `Triggers` list shape to the CodeCommit SDK's
37627
+ * `RepositoryTrigger[]` (PascalCase → camelCase). `Branches` is ALWAYS
37628
+ * emitted (defaulting to `[]` when the template omits it) — CodeCommit's
37629
+ * `PutRepositoryTriggers` rejects a trigger whose `branches` is null with
37630
+ * "Repository trigger branch name list cannot be null", and an empty array
37631
+ * means "all branches" (matching CFn's default when `Branches` is absent).
37632
+ * `CustomData` is truly optional (emitted only when present) so a re-order /
37633
+ * equality comparison stays stable. `Events` / `Branches` are coerced to
37634
+ * string arrays.
37635
+ */
37636
+ function toSdkTriggers(triggers) {
37637
+ if (!Array.isArray(triggers) || triggers.length === 0) return [];
37638
+ return triggers.map((t) => {
37639
+ const events = Array.isArray(t?.Events) ? t.Events : [];
37640
+ const branches = Array.isArray(t?.Branches) ? t.Branches : [];
37641
+ const trigger = {
37642
+ name: scalarToString(t?.Name),
37643
+ destinationArn: scalarToString(t?.DestinationArn),
37644
+ events: events.map((e) => scalarToString(e)),
37645
+ branches: branches.map((b) => scalarToString(b))
37646
+ };
37647
+ if (t?.CustomData !== void 0 && t.CustomData !== null) trigger.customData = scalarToString(t.CustomData);
37648
+ return trigger;
37649
+ });
37650
+ }
37651
+ /**
37652
+ * Order-sensitive structural equality for two mapped SDK trigger lists, used
37653
+ * to skip a redundant `PutRepositoryTriggers` when the template `Triggers`
37654
+ * block is unchanged. Compared as canonical JSON so `undefined` optional
37655
+ * fields (`customData` / `branches`) collapse identically on both sides.
37656
+ */
37657
+ function triggersEqual(a, b) {
37658
+ return JSON.stringify(a) === JSON.stringify(b);
37659
+ }
37611
37660
  /**
37612
37661
  * AWS CodeCommit Repository Provider
37613
37662
  *
@@ -37626,19 +37675,25 @@ function tagMapsEqual(a, b) {
37626
37675
  */
37627
37676
  var CodeCommitRepositoryProvider = class {
37628
37677
  client;
37678
+ s3Client;
37629
37679
  providerRegion = process.env["AWS_REGION"];
37630
37680
  logger = getLogger().child("CodeCommitRepositoryProvider");
37631
37681
  handledProperties = new Map([["AWS::CodeCommit::Repository", new Set([
37632
37682
  "RepositoryName",
37633
37683
  "RepositoryDescription",
37634
37684
  "KmsKeyId",
37635
- "Tags"
37685
+ "Tags",
37686
+ "Code",
37687
+ "Triggers"
37636
37688
  ])]]);
37637
- unhandledByDesign = new Map([["AWS::CodeCommit::Repository", new Map([["Code", "CFn-only seed-content orchestration (S3 zip unpacked into an initial commit on a chosen branch); not wired in v1 — pre-flight rejects templates carrying it so nothing is silently dropped; a follow-up could implement it via CreateCommit/PutFile"], ["Triggers", "repository trigger management not wired in v1 — pre-flight rejects templates carrying it so nothing is silently dropped; a follow-up could implement it via PutRepositoryTriggers"]])]]);
37638
37689
  getClient() {
37639
37690
  if (!this.client) this.client = new CodeCommitClient(this.providerRegion ? { region: this.providerRegion } : {});
37640
37691
  return this.client;
37641
37692
  }
37693
+ getS3Client() {
37694
+ if (!this.s3Client) this.s3Client = new S3Client(this.providerRegion ? { region: this.providerRegion } : {});
37695
+ return this.s3Client;
37696
+ }
37642
37697
  /**
37643
37698
  * Build the `Fn::GetAtt` attribute map from a `RepositoryMetadata`
37644
37699
  * response. `RepositoryId` is additionally stored so the intrinsic
@@ -37671,9 +37726,26 @@ var CodeCommitRepositoryProvider = class {
37671
37726
  ...tags ? { tags } : {}
37672
37727
  }))).repositoryMetadata;
37673
37728
  if (!metadata?.repositoryName) throw new Error("CreateRepository did not return repository metadata");
37674
- this.logger.debug(`Successfully created CodeCommit Repository ${logicalId}: ${metadata.repositoryName}`);
37729
+ const createdName = metadata.repositoryName;
37730
+ try {
37731
+ const code = properties["Code"];
37732
+ if (code) await this.seedInitialCommit(createdName, code);
37733
+ const triggers = properties["Triggers"];
37734
+ if (Array.isArray(triggers) && triggers.length > 0) {
37735
+ await this.getClient().send(new PutRepositoryTriggersCommand({
37736
+ repositoryName: createdName,
37737
+ triggers: toSdkTriggers(triggers)
37738
+ }));
37739
+ this.logger.debug(`Applied ${triggers.length} trigger(s) to ${createdName}`);
37740
+ }
37741
+ } catch (postCreateError) {
37742
+ this.logger.warn(`Post-create step failed for CodeCommit Repository ${logicalId}; deleting the just-created repository ${createdName} to avoid an orphan`);
37743
+ await this.bestEffortDelete(createdName);
37744
+ throw postCreateError;
37745
+ }
37746
+ this.logger.debug(`Successfully created CodeCommit Repository ${logicalId}: ${createdName}`);
37675
37747
  return {
37676
- physicalId: metadata.repositoryName,
37748
+ physicalId: createdName,
37677
37749
  attributes: this.toAttributes(metadata)
37678
37750
  };
37679
37751
  } catch (error) {
@@ -37691,7 +37763,11 @@ var CodeCommitRepositoryProvider = class {
37691
37763
  * CFn's `Ref` value — survives the rename), RepositoryDescription
37692
37764
  * (UpdateRepositoryDescription), KmsKeyId (UpdateRepositoryEncryptionKey),
37693
37765
  * Tags (TagResource / UntagResource — full tag removal handled explicitly,
37694
- * see the ECR Tags regression class in issue #981).
37766
+ * see the ECR Tags regression class in issue #981), Triggers
37767
+ * (PutRepositoryTriggers — a full-set replace, so a dropped or fully-removed
37768
+ * `Triggers` property is applied by putting the new/empty set; issue #1066).
37769
+ * `Code` is create-only seed content (CFn ignores it on update) and is NOT
37770
+ * re-applied here.
37695
37771
  *
37696
37772
  * A rename returns the NEW repository name as `physicalId` with
37697
37773
  * `wasReplaced: false`; the deploy engine persists the returned physical
@@ -37753,6 +37829,14 @@ var CodeCommitRepositoryProvider = class {
37753
37829
  this.logger.debug(`Updated tags for ${currentName}`);
37754
37830
  } else this.logger.warn(`Could not resolve ARN for CodeCommit Repository ${currentName}; tag update skipped`);
37755
37831
  }
37832
+ const newSdkTriggers = toSdkTriggers(properties["Triggers"]);
37833
+ if (!triggersEqual(newSdkTriggers, toSdkTriggers(previousProperties["Triggers"]))) {
37834
+ await this.getClient().send(new PutRepositoryTriggersCommand({
37835
+ repositoryName: currentName,
37836
+ triggers: newSdkTriggers
37837
+ }));
37838
+ this.logger.debug(`Updated triggers for ${currentName} (${newSdkTriggers.length} trigger(s))`);
37839
+ }
37756
37840
  metadata = await this.getRepositoryMetadata(currentName);
37757
37841
  return {
37758
37842
  physicalId: currentName,
@@ -37882,12 +37966,15 @@ var CodeCommitRepositoryProvider = class {
37882
37966
  * State property paths this provider cannot read back from AWS, skipped by
37883
37967
  * the drift comparator to avoid a guaranteed false positive.
37884
37968
  *
37885
- * `Code` (create-only S3-zip seed content unpacked into an initial commit)
37886
- * and `Triggers` (repository trigger management, not wired) are both
37887
- * `unhandledByDesign` normally rejected pre-flight, but a state written
37888
- * under `--allow-unsupported-properties` could still carry them, and neither
37889
- * is read back by `readCurrentState`, so exclude both defensively to avoid a
37890
- * guaranteed false-positive drift on every run.
37969
+ * `Code` is create-only S3-zip seed content unpacked into the initial
37970
+ * commit there is no read-back to compare against (the commit is git
37971
+ * history, not a repository attribute), so it can never meaningfully drift.
37972
+ * `Triggers` IS wired on the write side (create + update via
37973
+ * `PutRepositoryTriggers`), but `readCurrentState` does not yet fetch
37974
+ * `GetRepositoryTriggers`, so comparing a state that carries `Triggers`
37975
+ * against an `observedProperties` that omits it would be a guaranteed false
37976
+ * positive. Both are therefore excluded here; a follow-up can add
37977
+ * `GetRepositoryTriggers` read-back and drop `Triggers` from this list.
37891
37978
  */
37892
37979
  getDriftUnknownPaths(_resourceType) {
37893
37980
  return ["Code", "Triggers"];
@@ -37938,6 +38025,67 @@ var CodeCommitRepositoryProvider = class {
37938
38025
  return null;
37939
38026
  }
37940
38027
  /**
38028
+ * Seed the repository's initial commit from the CFn `Code` property.
38029
+ *
38030
+ * CFn's `Code` orchestration downloads the S3 ZIP, unpacks it, and creates
38031
+ * the repository's first commit on `BranchName` (default `main`). cdkd
38032
+ * reproduces that here: `GetObject` the ZIP, unpack every file entry
38033
+ * (directories are implied by file paths — CodeCommit has no empty-dir
38034
+ * concept), and issue a single `CreateCommit` carrying all files as
38035
+ * `putFiles`. This is create-only: CFn ignores `Code` on update, and so
38036
+ * does cdkd (`update()` never calls this).
38037
+ *
38038
+ * A ZIP with no file entries is a no-op (warn + skip) rather than a hard
38039
+ * failure — CodeCommit rejects a `CreateCommit` with an empty `putFiles`.
38040
+ */
38041
+ async seedInitialCommit(repositoryName, code) {
38042
+ const bucket = code.S3?.Bucket;
38043
+ const key = code.S3?.Key;
38044
+ if (typeof bucket !== "string" || typeof key !== "string" || !bucket || !key) throw new Error("Code.S3 requires string Bucket and Key");
38045
+ const versionId = typeof code.S3?.ObjectVersion === "string" ? code.S3.ObjectVersion : void 0;
38046
+ const branchName = typeof code.BranchName === "string" && code.BranchName ? code.BranchName : DEFAULT_SEED_BRANCH;
38047
+ const obj = await this.getS3Client().send(new GetObjectCommand({
38048
+ Bucket: bucket,
38049
+ Key: key,
38050
+ ...versionId && { VersionId: versionId }
38051
+ }));
38052
+ if (!obj.Body) throw new Error(`Code.S3 object s3://${bucket}/${key} returned an empty body`);
38053
+ const zipBytes = await obj.Body.transformToByteArray();
38054
+ const zip = new AdmZip(Buffer.from(zipBytes));
38055
+ const putFiles = [];
38056
+ for (const entry of zip.getEntries()) {
38057
+ if (entry.isDirectory) continue;
38058
+ putFiles.push({
38059
+ filePath: entry.entryName,
38060
+ fileContent: entry.getData()
38061
+ });
38062
+ }
38063
+ if (putFiles.length === 0) {
38064
+ this.logger.warn(`Code.S3 object s3://${bucket}/${key} contained no files; skipping seed commit for ${repositoryName}`);
38065
+ return;
38066
+ }
38067
+ await this.getClient().send(new CreateCommitCommand({
38068
+ repositoryName,
38069
+ branchName,
38070
+ commitMessage: "Initial commit",
38071
+ putFiles
38072
+ }));
38073
+ this.logger.debug(`Seeded ${repositoryName} with ${putFiles.length} file(s) on branch ${branchName}`);
38074
+ }
38075
+ /**
38076
+ * Best-effort delete used to roll back a just-created repository when a
38077
+ * post-create step (`Code` seed / `Triggers`) fails. Never throws — the
38078
+ * original post-create error is what the caller re-throws; a cleanup
38079
+ * failure is logged so the orphan is surfaced.
38080
+ */
38081
+ async bestEffortDelete(repositoryName) {
38082
+ try {
38083
+ await this.getClient().send(new DeleteRepositoryCommand$1({ repositoryName }));
38084
+ } catch (cleanupError) {
38085
+ this.logger.warn(`Failed to clean up CodeCommit Repository ${repositoryName} after a post-create failure: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
38086
+ }
38087
+ }
38088
+ /**
37941
38089
  * Fetch the repository's metadata via `GetRepository`. Throws
37942
38090
  * `RepositoryDoesNotExistException` through to the caller.
37943
38091
  */
@@ -60264,7 +60412,7 @@ function reorderArgs(argv) {
60264
60412
  async function main() {
60265
60413
  installPipeCloseHandler();
60266
60414
  const program = new Command();
60267
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.246.0");
60415
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.247.0");
60268
60416
  program.addCommand(createBootstrapCommand());
60269
60417
  program.addCommand(createSynthCommand());
60270
60418
  program.addCommand(createListCommand());