@go-to-k/cdkd 0.290.42 → 0.290.43

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,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as isVersionOnlyInvocation, t as getCdkdVersion } from "./version-Divizw1k.js";
2
+ import { n as isVersionOnlyInvocation, t as getCdkdVersion } from "./version-ChfV4K6h.js";
3
3
 
4
4
  //#region src/cli/pipe-close-handler.ts
5
5
  /**
@@ -74,7 +74,7 @@ async function main() {
74
74
  console.log(getCdkdVersion());
75
75
  return;
76
76
  }
77
- const { buildProgram } = await import("./program-HtHlEaZm.js");
77
+ const { buildProgram } = await import("./program-Bh8a5wjj.js");
78
78
  const program = buildProgram();
79
79
  const args = reorderArgs(process.argv);
80
80
  await program.parseAsync(args);
@@ -1,6 +1,6 @@
1
1
  import { C as displayAwsMessage, D as truncateCodePoints, E as isPasteableIdent, S as UNRENDERABLE, T as displaySafe, d as applyDefaultNameForFallback, f as explicitNamePropertyFor, g as looksLikeCdkdGeneratedName, h as getCurrentStackName, m as generateResourceNameWithFallback, n as getLogger, p as generateResourceName, r as isStdoutReservedForPayload, s as getLiveRenderer, v as withStackName, w as displayIdent, x as STACK_REF_MAX_CODE_POINTS, y as withoutGeneratedFallbackName } from "./logger-D-2HeLmd.js";
2
2
  import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-BoIxyCir.js";
3
- import { t as getCdkdVersion } from "./version-Divizw1k.js";
3
+ import { t as getCdkdVersion } from "./version-ChfV4K6h.js";
4
4
  import { AsyncLocalStorage } from "node:async_hooks";
5
5
  import { createHash, randomUUID } from "node:crypto";
6
6
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -25,7 +25,9 @@ import { CreateClusterSnapshotCommand, DescribeClusterSnapshotsCommand, Describe
25
25
  import { CreateSnapshotCommand as CreateSnapshotCommand$1, DescribeReplicationGroupsCommand, DescribeSnapshotsCommand as DescribeSnapshotsCommand$1, ElastiCacheClient } from "@aws-sdk/client-elasticache";
26
26
  import { ACMClient } from "@aws-sdk/client-acm";
27
27
  import { LambdaMicrovmsClient } from "@aws-sdk/client-lambda-microvms";
28
+ import * as fs from "node:fs";
28
29
  import { createReadStream, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
30
+ import * as path from "node:path";
29
31
  import { basename, isAbsolute, join, resolve } from "node:path";
30
32
  import { spawn } from "node:child_process";
31
33
  import { homedir, tmpdir } from "node:os";
@@ -33,7 +35,6 @@ import { GetHostedZoneCommand, ListHostedZonesByNameCommand, Route53Client } fro
33
35
  import { DescribeListenersCommand, DescribeLoadBalancersCommand, ElasticLoadBalancingV2Client } from "@aws-sdk/client-elastic-load-balancing-v2";
34
36
  import { KMSClient, ListAliasesCommand } from "@aws-sdk/client-kms";
35
37
  import { readFile } from "fs/promises";
36
- import { join as join$1 } from "path";
37
38
  import { CreateRepositoryCommand, DescribeImagesCommand as DescribeImagesCommand$1, DescribeRepositoriesCommand, ECRClient, GetAuthorizationTokenCommand, PutImageTagMutabilityCommand } from "@aws-sdk/client-ecr";
38
39
  import { inspect } from "node:util";
39
40
  import { hostname } from "os";
@@ -2803,6 +2804,231 @@ function parseEnvironment(env) {
2803
2804
  };
2804
2805
  }
2805
2806
 
2807
+ //#endregion
2808
+ //#region src/utils/assembly-path.ts
2809
+ /**
2810
+ * `true` when `candidate` names something strictly beneath `base`, both given
2811
+ * as already-resolved absolute paths.
2812
+ *
2813
+ * The `..` test is SEPARATOR-AWARE rather than a bare `startsWith('..')`,
2814
+ * which would also reject a legitimate sibling named `..foo`. The empty-string
2815
+ * case is `base` itself: a directory is never a template, a manifest or a
2816
+ * metadata side file, so `.` and `./` are refused rather than read.
2817
+ */
2818
+ function isInside(base, candidate) {
2819
+ const rel = path.relative(base, candidate);
2820
+ if (rel === "" || rel === "..") return false;
2821
+ if (rel.startsWith(`..${path.sep}`)) return false;
2822
+ return !path.isAbsolute(rel);
2823
+ }
2824
+ /**
2825
+ * `realpath(3)`, or `undefined` for a path that does not fully resolve.
2826
+ *
2827
+ * `.native` IS load-bearing and must not be simplified to `fs.realpathSync`.
2828
+ * The plain form is a JavaScript walker that folds `..` LEXICALLY — the same
2829
+ * mistake this module's own model branch is careful not to make — so it
2830
+ * disagrees with the kernel on a target carrying a `..` after a symlinked
2831
+ * component, in both directions:
2832
+ *
2833
+ * - It answers `ENOENT` for a path the kernel resolves and `readFileSync`
2834
+ * then reads. With `cdk.out/a -> <outside>/sub` and
2835
+ * `cdk.out/LINK.json -> a/../c.json` (both live), the JS walker folds to
2836
+ * `cdk.out/c.json`, finds nothing, and the verdict falls through to the
2837
+ * model — which folds the same way and calls it CONTAINED while the read
2838
+ * returns `<outside>/c.json`. That is go-to-k/cdkd#3489's original defect,
2839
+ * reopened by the guard meant to close it.
2840
+ * - On a case-insensitive filesystem (APFS by default) the same shape can make
2841
+ * it SPIN. A `try`/`catch` cannot catch a spin, so a hand-modified assembly
2842
+ * hung the very commands this check protects.
2843
+ *
2844
+ * `.native` is libuv's `realpath(3)` (`GetFinalPathNameByHandle` on Windows),
2845
+ * available since Node 8 against a floor of 22, and throws the same
2846
+ * `ENOENT` / `ELOOP` / `EACCES`. Using it is what makes the "exact whenever
2847
+ * the path resolves" claim above TRUE rather than aspirational.
2848
+ */
2849
+ function tryRealpath(p) {
2850
+ try {
2851
+ return fs.realpathSync.native(p);
2852
+ } catch {
2853
+ return;
2854
+ }
2855
+ }
2856
+ /** `fs.readlinkSync`, or `undefined` when `p` is not a symbolic link. */
2857
+ function tryReadlink(p) {
2858
+ try {
2859
+ return fs.readlinkSync(p);
2860
+ } catch {
2861
+ return;
2862
+ }
2863
+ }
2864
+ /**
2865
+ * Link follows before the walk gives up and reports the path as unresolvable.
2866
+ * It does NOT refuse: an exhausted budget answers `undefined`, which leaves
2867
+ * the symlink arm silent and the lexical verdict standing. That is safe
2868
+ * because the OS gives up first — macOS caps at 32 (`ELOOP`) — so a chain that
2869
+ * reaches this cap is one nothing can read or create through anyway.
2870
+ */
2871
+ const MAX_LINK_HOPS = 40;
2872
+ /**
2873
+ * Unresolvable path COMPONENTS the climb walks before giving up. Bounds the
2874
+ * recursion below, which is one frame per component: 20 000 components raised
2875
+ * an uncaught `RangeError` and 5 000 cost ~200 ms per call. Like the hop cap
2876
+ * this gives up rather than refusing, which is safe for the same reason —
2877
+ * nothing can read or create through a path that deep.
2878
+ */
2879
+ const MAX_PATH_COMPONENTS = 1e3;
2880
+ /**
2881
+ * Where `target` REALLY points, for a path that may not exist yet.
2882
+ *
2883
+ * `fs.realpathSync` answers only for a path that fully resolves, and it throws
2884
+ * `ENOENT` for a DANGLING symbolic link exactly as it does for an absent file
2885
+ * — the two are indistinguishable from its result. That difference is the
2886
+ * whole point here: a write FOLLOWS a dangling link and creates the file at
2887
+ * its target, so `cdk.out/Foo.template.json -> ~/.ssh/authorized_keys` (target
2888
+ * absent) is an out-of-directory write that a realpath-only check reports as
2889
+ * contained. Measured: `cdkd synth --verbose` created the victim file.
2890
+ *
2891
+ * So each unresolvable component is handled by hand: climb to the deepest
2892
+ * ancestor that DOES resolve, then re-apply the remaining components,
2893
+ * following any symbolic link with `readlink` and re-resolving its target.
2894
+ * `undefined` means the walk could not resolve the path at all, which for
2895
+ * every caller means their own open fails too.
2896
+ *
2897
+ * KNOW WHAT THIS IS EXACT ABOUT, because the distinction is what bounds it:
2898
+ *
2899
+ * - For a path that FULLY RESOLVES, the answer is `fs.realpathSync`'s and is
2900
+ * therefore exact. Every READ site is in this case by construction — a file
2901
+ * that does not resolve cannot be read — so the containment verdict there is
2902
+ * the kernel's, not this function's. The BASE side is exact there too: every
2903
+ * one is either user-supplied (`-a`, `--output`, `cdkOutDir`) or the
2904
+ * `dirname` of a file cdkd has just read successfully, so neither operand of
2905
+ * a read is in the model's territory.
2906
+ * - For a path that does NOT exist yet, this is a best-effort MODEL of kernel
2907
+ * resolution, and a model can be wrong at an edge. The known one: `..` INSIDE
2908
+ * an unresolvable link's target is folded lexically here, while the kernel
2909
+ * folds it only after following each preceding component, so a target of
2910
+ * `a/../c.json` under a symlinked `a` diverges.
2911
+ *
2912
+ * That edge decides which of the TWO sites that WRITE needs a second check,
2913
+ * and the difference is the BASE rather than the act of writing:
2914
+ *
2915
+ * - `resolveVerboseTemplatePath` (`src/cli/commands/synth.ts`) writes into
2916
+ * `--output`, which may be a pre-existing directory the assembly's author
2917
+ * supplied, so the leaf CAN already be a symbolic link. It therefore asks
2918
+ * the kernel directly with `lstat` and refuses one whatever it points at. A
2919
+ * path-string model can be argued around; `lstat` cannot.
2920
+ * - `resolveInlineCodeFilePath` (`src/cli/commands/local-invoke.ts`) writes
2921
+ * into a `mkdtemp` cdkd has just created, mode 0700 and empty, so no
2922
+ * component of the candidate can be a symbolic link at all and the edge is
2923
+ * unreachable. It needs no `lstat`.
2924
+ *
2925
+ * **A third write site over a base cdkd did not create needs the `lstat`**,
2926
+ * and inherits nothing from this function that would give it one.
2927
+ *
2928
+ * That second site is also the repo's first caller to `mkdirSync(...,
2929
+ * { recursive: true })` through a resolved path, which an earlier revision of
2930
+ * this comment leaned on not existing. It is still safe: the climb charges no
2931
+ * hop for a component, and exhausting `MAX_PATH_COMPONENTS` gives up into the
2932
+ * lexical verdict, which a freshly created directory has no link to defeat.
2933
+ */
2934
+ function resolveThroughLinks(target, hops = 0, climbs = 0) {
2935
+ const direct = tryRealpath(target);
2936
+ if (direct !== void 0) return direct;
2937
+ if (hops >= MAX_LINK_HOPS) return void 0;
2938
+ if (climbs >= MAX_PATH_COMPONENTS) return void 0;
2939
+ const parent = path.dirname(target);
2940
+ if (parent === target) return void 0;
2941
+ const realParent = resolveThroughLinks(parent, hops, climbs + 1);
2942
+ if (realParent === void 0) return void 0;
2943
+ const link = tryReadlink(target);
2944
+ if (link === void 0) return path.join(realParent, path.basename(target));
2945
+ return resolveThroughLinks(path.resolve(realParent, link), hops + 1, climbs);
2946
+ }
2947
+ /**
2948
+ * Resolve an assembly-supplied `candidate` against `dir` and report whether
2949
+ * the result stays inside it.
2950
+ *
2951
+ * The lexical arm joins exactly the way the call sites used to
2952
+ * (`path.join`, NOT `path.resolve`), so the verdict is about the path the
2953
+ * caller will actually open. `join`'s handling of an absolute candidate makes
2954
+ * this arm strictly more permissive than a `resolve`-based one would be; an
2955
+ * absolute value therefore stays a matter for each site's own tripwire.
2956
+ *
2957
+ * The SYMLINK arm exists because the lexical arm alone leaves an equivalent
2958
+ * hole: `cdk.out/link -> /etc` plus a candidate of `link/passwd` is lexically
2959
+ * contained and still reads `/etc/passwd`. Both sides go through
2960
+ * {@link resolveThroughLinks}, so an assembly directory REACHED through a link
2961
+ * (macOS spells `/tmp` as `/private/tmp`; a user may symlink `cdk.out` itself)
2962
+ * is unaffected, while a candidate that does not exist YET — the shape
2963
+ * `cdkd synth --verbose` writes, and the shape a DANGLING link presents — is
2964
+ * still resolved to where it would actually land. A real `cdk synth` writes no symbolic link
2965
+ * along any of these paths (measured against a CDK 2.268 assembly carrying a
2966
+ * Stage, two nesting levels and an asset manifest), so the arm costs a
2967
+ * legitimate assembly nothing.
2968
+ *
2969
+ * Windows shapes need no special case HERE: `path.relative` is the platform's
2970
+ * own, so a drive-relative or UNC candidate is judged by `path.win32` on
2971
+ * Windows, while on POSIX `C:\evil` and `..\..\evil` are single filename
2972
+ * components that no `readFileSync` can follow out of the directory.
2973
+ *
2974
+ * The verdict is about the assembly AS IT SITS ON DISK, which is the whole
2975
+ * threat model: a hand-modified or third-party `cdk.out` the user then points
2976
+ * cdkd at. It is NOT a defence against a process rewriting that directory
2977
+ * concurrently — the caller opens by path after this returns, so a link
2978
+ * swapped in between is outside what any check here can see.
2979
+ */
2980
+ function resolveAssemblyPath(dir, candidate, options) {
2981
+ const base = path.resolve(dir);
2982
+ const bound = options?.containWithin === void 0 ? base : path.resolve(options.containWithin);
2983
+ const joined = path.resolve(path.join(base, candidate));
2984
+ if (!isInside(bound, joined)) return {
2985
+ contained: false,
2986
+ escape: "lexical",
2987
+ path: joined
2988
+ };
2989
+ const realBase = resolveThroughLinks(bound);
2990
+ if (realBase !== void 0) {
2991
+ const realTarget = resolveThroughLinks(joined);
2992
+ if (realTarget !== void 0 && !isInside(realBase, realTarget)) return {
2993
+ contained: false,
2994
+ escape: "symlink",
2995
+ path: joined,
2996
+ realPath: realTarget
2997
+ };
2998
+ }
2999
+ return {
3000
+ contained: true,
3001
+ path: joined
3002
+ };
3003
+ }
3004
+ /**
3005
+ * The shared tail of every containment refusal: what the value resolved to,
3006
+ * what it escaped, and why that means the assembly is not CDK-generated. Each
3007
+ * call site supplies its own subject ("Stack 'X' has templateFile='...' which
3008
+ * ") and its own error class, because the sites throw four different types.
3009
+ * `action` completes "Refusing to ..." for a caller that declines something
3010
+ * other than loading the file — `renderNestedTemplateTreeDefect` says "deploy"
3011
+ * or "diff", matching its own sibling refusals.
3012
+ *
3013
+ * Every interpolation goes through `displaySafe` for the reason
3014
+ * `AssemblyReader`'s own refusals give (go-to-k/cdkd#3277): this text exists
3015
+ * FOR a hand-modified assembly, so the candidate, the resolved path and even
3016
+ * `dir` (below a Stage it derives from the manifest's `directoryName`) are all
3017
+ * attacker-chosen, and `formatError` sanitizes only an error's `cause`, never
3018
+ * its own `message`.
3019
+ */
3020
+ function renderAssemblyPathEscape(escape, dir, action = "load", provenanceOverride) {
3021
+ const provenance = provenanceOverride ?? `CDK emits assembly paths that stay inside the assembly directory; one that leaves it indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to ${action}.`;
3022
+ const base = path.resolve(dir);
3023
+ const realBase = resolveThroughLinks(base) ?? base;
3024
+ if (escape.escape === "symlink") {
3025
+ if (escape.realPath === realBase) return `resolves to '${displaySafe(escape.path)}', a symbolic link to the directory '${displaySafe(base)}' itself rather than to a file inside it. ${provenance}`;
3026
+ return `resolves to '${displaySafe(escape.path)}', which leads through a symbolic link to '${displaySafe(escape.realPath)}', outside '${displaySafe(base)}'. ${provenance}`;
3027
+ }
3028
+ if (escape.path === base) return `names the directory '${displaySafe(base)}' itself rather than a file inside it. ${provenance}`;
3029
+ return `resolves to '${displaySafe(escape.path)}', outside '${displaySafe(base)}'. ${provenance}`;
3030
+ }
3031
+
2806
3032
  //#endregion
2807
3033
  //#region src/synthesis/stack-messages.ts
2808
3034
  /**
@@ -2833,7 +3059,9 @@ const MESSAGE_ENTRY_TYPES = {
2833
3059
  function collectStackMessages(assemblyDir, artifact) {
2834
3060
  const merged = { ...artifact.metadata ?? {} };
2835
3061
  if (artifact.additionalMetadataFile) {
2836
- const metadataPath = join(assemblyDir, artifact.additionalMetadataFile);
3062
+ const resolved = resolveAssemblyPath(assemblyDir, artifact.additionalMetadataFile);
3063
+ if (!resolved.contained) throw new SynthesisError(`Stack metadata file '${displaySafe(artifact.additionalMetadataFile)}' ${renderAssemblyPathEscape(resolved, assemblyDir)}`);
3064
+ const metadataPath = resolved.path;
2837
3065
  let sideFile;
2838
3066
  try {
2839
3067
  sideFile = JSON.parse(readFileSync(metadataPath, "utf-8"));
@@ -2935,7 +3163,7 @@ var AssemblyReader = class {
2935
3163
  /**
2936
3164
  * Get all stacks from assembly (recursively traverses nested assemblies / Stages)
2937
3165
  */
2938
- getAllStacks(assemblyDir, manifest) {
3166
+ getAllStacks(assemblyDir, manifest, assetOutdir = assemblyDir) {
2939
3167
  if (!manifest.artifacts) {
2940
3168
  this.logger.warn("No artifacts found in manifest");
2941
3169
  return [];
@@ -2943,15 +3171,17 @@ var AssemblyReader = class {
2943
3171
  const assetManifestMap = this.buildAssetManifestMap(assemblyDir, manifest);
2944
3172
  const stacks = [];
2945
3173
  for (const [artifactId, artifact] of Object.entries(manifest.artifacts)) if (artifact.type === "aws:cloudformation:stack") {
2946
- const stackInfo = this.extractStackInfo(assemblyDir, artifactId, artifact, manifest, assetManifestMap);
3174
+ const stackInfo = this.extractStackInfo(assemblyDir, artifactId, artifact, manifest, assetManifestMap, assetOutdir);
2947
3175
  stacks.push(stackInfo);
2948
3176
  } else if (artifact.type === "cdk:cloud-assembly") {
2949
3177
  const props = artifact.properties;
2950
3178
  if (props?.directoryName) {
2951
- const nestedDir = join(assemblyDir, props.directoryName);
3179
+ const resolved = resolveAssemblyPath(assemblyDir, props.directoryName);
3180
+ if (!resolved.contained) throw new SynthesisError(`Nested assembly '${displaySafe(props.directoryName)}' ${renderAssemblyPathEscape(resolved, assemblyDir)}`);
3181
+ const nestedDir = resolved.path;
2952
3182
  try {
2953
3183
  const nestedManifest = this.readManifest(nestedDir);
2954
- const nestedStacks = this.getAllStacks(nestedDir, nestedManifest);
3184
+ const nestedStacks = this.getAllStacks(nestedDir, nestedManifest, assetOutdir);
2955
3185
  stacks.push(...nestedStacks);
2956
3186
  } catch (error) {
2957
3187
  this.logger.warn(`Failed to read nested assembly '${displaySafe(props.directoryName)}': ${displaySafe(error instanceof Error ? error.message : String(error))}`);
@@ -2985,19 +3215,25 @@ var AssemblyReader = class {
2985
3215
  for (const [artifactId, artifact] of Object.entries(manifest.artifacts)) {
2986
3216
  if (artifact.type !== "cdk:asset-manifest") continue;
2987
3217
  const props = artifact.properties;
2988
- if (props?.file) map.set(artifactId, join(assemblyDir, props.file));
3218
+ if (props?.file) {
3219
+ const resolved = resolveAssemblyPath(assemblyDir, props.file);
3220
+ if (!resolved.contained) throw new SynthesisError(`Asset manifest artifact '${displaySafe(artifactId)}' has file='${displaySafe(props.file)}' which ${renderAssemblyPathEscape(resolved, assemblyDir)}`);
3221
+ map.set(artifactId, resolved.path);
3222
+ }
2989
3223
  }
2990
3224
  return map;
2991
3225
  }
2992
3226
  /**
2993
3227
  * Extract stack info from artifact
2994
3228
  */
2995
- extractStackInfo(assemblyDir, artifactId, artifact, manifest, assetManifestMap) {
3229
+ extractStackInfo(assemblyDir, artifactId, artifact, manifest, assetManifestMap, assetOutdir) {
2996
3230
  const props = artifact.properties;
2997
3231
  const stackName = props?.stackName || artifactId;
2998
3232
  const templateFile = props?.templateFile;
2999
3233
  if (!templateFile) throw new SynthesisError(`Stack '${displaySafe(stackName)}' has no templateFile property`);
3000
- const templatePath = join(assemblyDir, templateFile);
3234
+ const resolvedTemplate = resolveAssemblyPath(assemblyDir, templateFile);
3235
+ if (!resolvedTemplate.contained) throw new SynthesisError(`Stack '${displaySafe(stackName)}' has templateFile='${displaySafe(templateFile)}' which ${renderAssemblyPathEscape(resolvedTemplate, assemblyDir)}`);
3236
+ const templatePath = resolvedTemplate.path;
3001
3237
  let template;
3002
3238
  try {
3003
3239
  const content = readFileSync(templatePath, "utf-8");
@@ -3031,7 +3267,9 @@ var AssemblyReader = class {
3031
3267
  const assetPath = resource.Metadata?.["aws:asset:path"];
3032
3268
  if (typeof assetPath !== "string" || assetPath.length === 0) continue;
3033
3269
  if (isAbsolute(assetPath) || /^[a-zA-Z]:[\\/]/.test(assetPath) || assetPath.startsWith("\\\\")) throw new SynthesisError(`Stack '${displaySafe(stackName)}' nested-stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which is absolute. CDK emits relative asset paths for nested templates; an absolute path indicates the synth output was hand-modified or generated by a non-CDK toolchain. Refusing to load.`);
3034
- nestedTemplates[logicalId] = join(assemblyDir, assetPath);
3270
+ const resolvedNested = resolveAssemblyPath(assemblyDir, assetPath);
3271
+ if (!resolvedNested.contained) throw new SynthesisError(`Stack '${displaySafe(stackName)}' nested-stack '${displaySafe(logicalId)}' has Metadata['aws:asset:path']='${displaySafe(assetPath)}' which ${renderAssemblyPathEscape(resolvedNested, assemblyDir)}`);
3272
+ nestedTemplates[logicalId] = resolvedNested.path;
3035
3273
  }
3036
3274
  return {
3037
3275
  stackName,
@@ -3039,6 +3277,7 @@ var AssemblyReader = class {
3039
3277
  artifactId,
3040
3278
  template,
3041
3279
  assetManifestPath,
3280
+ assetOutdir,
3042
3281
  dependencyNames,
3043
3282
  region: env?.region !== "unknown-region" ? env?.region : void 0,
3044
3283
  account: env?.account !== "unknown-account" ? env?.account : void 0,
@@ -6366,6 +6605,24 @@ function setsEqual(a, b) {
6366
6605
  //#endregion
6367
6606
  //#region src/assets/asset-manifest-loader.ts
6368
6607
  /**
6608
+ * THE one spelling of "where does this file asset's source live", shared by
6609
+ * {@link AssetManifestLoader.getAssetSourcePath} and `FileAssetPublisher`
6610
+ * (issue [#3489](https://github.com/go-to-k/cdkd/issues/3489)).
6611
+ *
6612
+ * Both used to `join(cdkOutputDir, asset.source.path)` independently. The
6613
+ * manifest is chosen by whoever wrote the assembly, `path.join` folds `..`,
6614
+ * and the publisher ZIPs whatever it finds and `PutObject`s it to a bucket the
6615
+ * same manifest names — so an unchecked `source.path` is an exfiltration
6616
+ * primitive with the caller's own credentials, which is the harm the manifest
6617
+ * FILE's own containment check cites. One function so the loader and the
6618
+ * publisher cannot disagree about which file is published.
6619
+ */
6620
+ function resolveFileAssetSourcePath(manifestDir, asset, assetOutdir = manifestDir) {
6621
+ const resolved = resolveAssemblyPath(manifestDir, asset.source.path, { containWithin: assetOutdir });
6622
+ if (!resolved.contained) throw new Error(`File asset '${displaySafe(asset.displayName)}' has source.path='${displaySafe(asset.source.path)}' which ${renderAssemblyPathEscape(resolved, assetOutdir, "publish it")}`);
6623
+ return resolved.path;
6624
+ }
6625
+ /**
6369
6626
  * Whether a file asset's `source.path` is a CloudFormation template asset
6370
6627
  * (the stack template `<Stack>.template.json` or a nested-stack template
6371
6628
  * `<Stack>.<Nested>.nested.template.json`). cdkd deploys templates itself and
@@ -6397,7 +6654,9 @@ var AssetManifestLoader = class {
6397
6654
  * @returns Asset manifest or null if not found
6398
6655
  */
6399
6656
  async loadManifest(cdkOutputDir, stackName) {
6400
- const manifestPath = join$1(cdkOutputDir, `${stackName}.assets.json`);
6657
+ const resolved = resolveAssemblyPath(cdkOutputDir, `${stackName}.assets.json`);
6658
+ if (!resolved.contained) throw new Error(`Asset manifest for stack '${displaySafe(stackName)}' ${renderAssemblyPathEscape(resolved, cdkOutputDir)}`);
6659
+ const manifestPath = resolved.path;
6401
6660
  try {
6402
6661
  this.logger.debug(`Loading asset manifest from: ${manifestPath}`);
6403
6662
  const content = await readFile(manifestPath, "utf-8");
@@ -6433,12 +6692,18 @@ var AssetManifestLoader = class {
6433
6692
  /**
6434
6693
  * Get asset source path (absolute path)
6435
6694
  *
6695
+ * Refuses a `source.path` resolving outside `cdkOutputDir` (issue
6696
+ * [#3489](https://github.com/go-to-k/cdkd/issues/3489)). The manifest is
6697
+ * assembly-supplied and `cdkd deploy -a <dir>` consumes a pre-synthesized
6698
+ * one, so a `source.path` of `../../../home/<user>/.aws` would otherwise be
6699
+ * packaged and uploaded to a bucket the SAME manifest names.
6700
+ *
6436
6701
  * @param cdkOutputDir CDK output directory
6437
6702
  * @param asset File asset
6438
6703
  * @returns Absolute path to asset source
6439
6704
  */
6440
- getAssetSourcePath(cdkOutputDir, asset) {
6441
- return join$1(cdkOutputDir, asset.source.path);
6705
+ getAssetSourcePath(cdkOutputDir, asset, assetOutdir) {
6706
+ return resolveFileAssetSourcePath(cdkOutputDir, asset, assetOutdir ?? cdkOutputDir);
6442
6707
  }
6443
6708
  /**
6444
6709
  * Resolve asset destination values (replace ${AWS::AccountId}, ${AWS::Region}, etc.)
@@ -6530,7 +6795,8 @@ var FileAssetPublisher = class {
6530
6795
  * @param region AWS region
6531
6796
  * @param profile AWS profile (optional)
6532
6797
  */
6533
- async publish(assetHash, asset, cdkOutputDir, accountId, region, _profile) {
6798
+ async publish(assetHash, asset, cdkOutputDir, accountId, region, _profile, assetOutdir) {
6799
+ const sourcePath = resolveFileAssetSourcePath(cdkOutputDir, asset, assetOutdir ?? cdkOutputDir);
6534
6800
  for (const [, dest] of Object.entries(asset.destinations)) {
6535
6801
  const bucketName = this.resolvePlaceholders(dest.bucketName, accountId, region);
6536
6802
  const objectKey = this.resolvePlaceholders(dest.objectKey, accountId, region);
@@ -6545,7 +6811,6 @@ var FileAssetPublisher = class {
6545
6811
  this.logger.debug(`Asset already exists, skipping: s3://${bucketName}/${objectKey}`);
6546
6812
  continue;
6547
6813
  }
6548
- const sourcePath = join(cdkOutputDir, asset.source.path);
6549
6814
  if (asset.source.packaging === "zip") await this.uploadZip(client, sourcePath, bucketName, objectKey);
6550
6815
  else await this.uploadFile(client, sourcePath, bucketName, objectKey);
6551
6816
  this.logger.debug(`✅ Published: s3://${bucketName}/${objectKey}`);
@@ -7865,6 +8130,28 @@ function describeDockerCapturedOutput(error, args, fallback) {
7865
8130
  //#endregion
7866
8131
  //#region src/assets/docker-build.ts
7867
8132
  /**
8133
+ * Where a Docker asset's build context lives, refusing a `source.directory`
8134
+ * that resolves outside `cdkOutDir` (issue
8135
+ * [#3489](https://github.com/go-to-k/cdkd/issues/3489)).
8136
+ *
8137
+ * The field is assembly-supplied and used BOTH as the executable's cwd and as
8138
+ * the `docker build` cwd, so an escaping value sends a directory from outside
8139
+ * `cdk.out` to BuildKit and bakes it into the image pushed to a repository the
8140
+ * same manifest names. Both sites used raw `${a}/${b}` concatenation, which
8141
+ * honours `..` exactly as `join` does; this is the one spelling they share.
8142
+ *
8143
+ * It throws through the CALLER's `wrapError` so each consumer keeps its own
8144
+ * typed error class, exactly as this module's other pre-docker refusals do.
8145
+ *
8146
+ * Twin of `resolveFileAssetSourcePath` and `resolveVerboseTemplatePath`.
8147
+ * Exported for unit testing.
8148
+ */
8149
+ function resolveDockerContextDirectory(manifestDir, directory, wrapError, assetOutdir = manifestDir) {
8150
+ const resolved = resolveAssemblyPath(manifestDir, directory, { containWithin: assetOutdir });
8151
+ if (!resolved.contained) throw wrapError(`asset source.directory='${displaySafe(directory)}' which ${renderAssemblyPathEscape(resolved, assetOutdir, "build it")}`);
8152
+ return resolved.path;
8153
+ }
8154
+ /**
7868
8155
  * Build a Docker image from a CDK asset source. Returns the local image
7869
8156
  * tag the caller should use for `docker tag` / `docker push` (publisher)
7870
8157
  * or `docker run` (local-invoke).
@@ -7882,10 +8169,11 @@ function describeDockerCapturedOutput(error, args, fallback) {
7882
8169
  async function buildDockerImage(asset, cdkOutDir, options) {
7883
8170
  const source = asset.source;
7884
8171
  const logger = getLogger().child("docker-build");
8172
+ const contextDirectory = (directory) => resolveDockerContextDirectory(cdkOutDir, directory, options.wrapError, options.assetOutdir);
7885
8173
  if (source.executable && source.executable.length > 0) {
7886
8174
  const [cmd, ...args] = source.executable;
7887
8175
  if (!cmd) throw options.wrapError("asset source.executable[] is empty");
7888
- const cwd = source.directory ? `${cdkOutDir}/${source.directory}` : cdkOutDir;
8176
+ const cwd = source.directory ? contextDirectory(source.directory) : cdkOutDir;
7889
8177
  const shownExecutable = redactDockerArgvValues(source.executable).join(" ");
7890
8178
  logger.debug(`Building Docker image via executable: ${shownExecutable} (cwd=${cwd})`);
7891
8179
  let result;
@@ -7909,9 +8197,9 @@ async function buildDockerImage(asset, cdkOutDir, options) {
7909
8197
  }
7910
8198
  if (!options.tag) throw options.wrapError("buildDockerImage(directory mode) requires options.tag");
7911
8199
  const buildArgs = buildDockerBuildCommand(source, options.tag, options.platform);
7912
- const contextDir = `${cdkOutDir}/${source.directory}`;
8200
+ const contextDir = contextDirectory(source.directory);
7913
8201
  buildArgs.push(".");
7914
- logger.debug(`${getDockerCmd()} ${redactDockerArgvValues(buildArgs).join(" ")} (cwd=${contextDir})`);
8202
+ logger.debug(`${getDockerCmd()} ${redactDockerArgvValues(buildArgs).join(" ")} (cwd=${displaySafe(contextDir)})`);
7915
8203
  try {
7916
8204
  await runDockerStreaming(buildArgs, {
7917
8205
  cwd: contextDir,
@@ -8041,8 +8329,8 @@ var DockerAssetPublisher = class {
8041
8329
  * via `docker tag` so the downstream `push()` step (which is wired to
8042
8330
  * `localTag` at graph-construction time) keeps working unchanged.
8043
8331
  */
8044
- async build(asset, cdkOutputDir, localTag) {
8045
- await this.buildImage(asset, cdkOutputDir, localTag);
8332
+ async build(asset, cdkOutputDir, localTag, assetOutdir) {
8333
+ await this.buildImage(asset, cdkOutputDir, localTag, assetOutdir);
8046
8334
  }
8047
8335
  /**
8048
8336
  * Push a pre-built Docker image to ECR (public, used by WorkGraph asset-publish nodes)
@@ -8098,9 +8386,10 @@ var DockerAssetPublisher = class {
8098
8386
  * downstream push step finds the image under the deterministic
8099
8387
  * `cdkd-asset-<hash>` name it expects.
8100
8388
  */
8101
- async buildImage(asset, cdkOutputDir, tag) {
8389
+ async buildImage(asset, cdkOutputDir, tag, assetOutdir) {
8102
8390
  const actualTag = await buildDockerImage(asset, cdkOutputDir, {
8103
8391
  tag,
8392
+ ...assetOutdir !== void 0 && { assetOutdir },
8104
8393
  wrapError: (stderr) => new AssetError(`Docker build failed: ${stderr}`)
8105
8394
  });
8106
8395
  if (actualTag !== tag) {
@@ -9473,6 +9762,7 @@ var AssetPublisher = class {
9473
9762
  const content = readFileSync(manifestPath, "utf-8");
9474
9763
  const manifest = JSON.parse(content);
9475
9764
  const cdkOutputDir = manifestPath.replace(/\/[^/]+$/, "");
9765
+ const assetOutdir = options.assetOutdir ?? cdkOutputDir;
9476
9766
  const prefix = options.nodePrefix || "";
9477
9767
  const redirect = options.redirect;
9478
9768
  const nodeIds = [];
@@ -9489,6 +9779,7 @@ var AssetPublisher = class {
9489
9779
  hash,
9490
9780
  asset,
9491
9781
  cdkOutputDir,
9782
+ assetOutdir,
9492
9783
  accountId: options.accountId,
9493
9784
  region: options.region,
9494
9785
  ...options.profile && { profile: options.profile }
@@ -9511,6 +9802,7 @@ var AssetPublisher = class {
9511
9802
  hash,
9512
9803
  asset,
9513
9804
  cdkOutputDir,
9805
+ assetOutdir,
9514
9806
  localTag
9515
9807
  }
9516
9808
  });
@@ -9537,8 +9829,8 @@ var AssetPublisher = class {
9537
9829
  */
9538
9830
  async executeNode(node) {
9539
9831
  const data = node.data;
9540
- if (data.kind === "file") await this.filePublisher.publish(data.hash, data.asset, data.cdkOutputDir, data.accountId, data.region, data.profile);
9541
- else if (data.kind === "docker-build") await this.dockerPublisher.build(data.asset, data.cdkOutputDir, data.localTag);
9832
+ if (data.kind === "file") await this.filePublisher.publish(data.hash, data.asset, data.cdkOutputDir, data.accountId, data.region, data.profile, data.assetOutdir);
9833
+ else if (data.kind === "docker-build") await this.dockerPublisher.build(data.asset, data.cdkOutputDir, data.localTag, data.assetOutdir);
9542
9834
  else if (data.kind === "docker-publish") await this.dockerPublisher.push(data.asset, data.accountId, data.region, data.localTag);
9543
9835
  this.logger.debug(`✅ ${node.id}`);
9544
9836
  }
@@ -33683,7 +33975,7 @@ var CloudControlProvider = class {
33683
33975
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
33684
33976
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
33685
33977
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
33686
- const { ASGProvider } = await import("./asg-provider-Cms9Daqn.js").then((n) => n.n);
33978
+ const { ASGProvider } = await import("./asg-provider-C9R-ND4b.js").then((n) => n.n);
33687
33979
  const asgProvider = new ASGProvider();
33688
33980
  return withIndeterminateGuard(await asgProvider.delete(logicalId, physicalId, resourceType, _properties, context), indeterminateGuard);
33689
33981
  }
@@ -47391,5 +47683,5 @@ var DeployEngine = class DeployEngine {
47391
47683
  };
47392
47684
 
47393
47685
  //#endregion
47394
- export { yellow as $, AssetError as $i, STATE_SOURCED_BASELINE_RULES as $n, validateContainerRepoName as $r, requireConfigObject as $t, createPreDeleteFinalSnapshot as A, retryClassificationText as Aa, CFN_TEMPLATE_BODY_LIMIT as Ai, malformedResourcePropertiesWarning as An, hasUnverifiableParameterRefusal as Ar, carriesDynamicReference as At, isStatefulRecreateTargetSync as B, decodeListingKey as Bi, refuseMalformedState as Bn, buildAssetRedirectMap as Br, isSettledInstanceState as Bt, namesAnyDeclaredParameter as C, withErrorHandling as Ca, resolveSkipPrefix as Ci, malformedExportSourceWarning as Cn, formatLockExpiry as Cr, slowCcOperationTimeoutMs as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, isTransientServerError as Da, stateBucketExistenceConfirmed as Di, malformedOutputsWarning as Dn, exportNamesCarriedFrom as Dr, disableInstanceApiTermination as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, isThrottlingError as Ea, resolveUseCdkBootstrapAssets as Ei, malformedOutputsRefusalMessage as En, DEFAULT_STATE_PREFIX as Er, deleteSkipReason as Et, extractDeploymentEventError as F, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Fi, refuseMalformedOutputs as Fn, orphansCarriedFrom as Fr, isImpossibleEmptyStoredAttribute as Ft, toCfnInteger as G, AssemblyReader as Gi, safeRegion as Gn, BOOTSTRAP_MARKER_PREFIX as Gr, coerceCfnBoolean as Gt, WARM_THROUGHPUT_MEMBERS as H, PARTITION_TABLE as Hi, repairMalformedResourceEntriesForReadOnly as Hn, loadPublishableAssetManifest as Hr, normalizeAwsTagsToCfn as Ht, makeSiblingClaimReader as I, injectiveKey as Ii, refuseMalformedOutputsForDestroy as In, shouldRetainResource as Ir, isNamelessDynamicReferenceError as It, bold as J, resolveBucketRegion as Ji, findSilentDropProperties as Jn, getBootstrapMarkerKey as Jr, configIntegerRefusal as Jt, toFiniteNumber as K, processStackMessages as Ki, safeStackName as Kn, assertAssetBucketRegion as Kr, coerceCfnInteger as Kt, planOrphanAdoption as L, injectiveKeyPrefix as Li, refuseMalformedResourceEntries as Ln, AssetPublisher as Lr, isUnboundTemplateParameter as Lt, refusesFinalSnapshot as M, safeStringify$1 as Ma, MIGRATE_TMP_PREFIX as Mi, malformedStateRefusalMessage as Mn, importableOutputs as Mr, cfnRefValueFromPhysicalId as Mt, unsupportedFinalSnapshotError as N, __exportAll as Na, findLargeInlineResources as Ni, refuseDivergentRecordRegionForDestroy as Nn, isReadableBag as Nr, coerceParameterTypedValue as Nt, buildFinalSnapshotIdentifier as O, markNonRetryable as Oa, warnDeprecatedNoPrefixCliFlag as Oi, malformedRenderedContainersWarning as On, hasReadableExportSet as Or, isTerminationProtectionPropagationError as Ot, makeCanonicalizePropertiesFn as P, uploadCfnTemplate as Pi, refuseMalformedNestedChildOutputs as Pn, orphansAfterRollback as Pr, getAccountInfo as Pt, red as Q, setAwsClients as Qi, TemplateParser as Qn, validateAssetBucketName as Qr, requireConfigArray as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, producerCoordinateKey as Ri, refuseMalformedResourcePropertiesForOrphan as Rn, stringifyValue as Rr, parameterTypeMayLoseSecretIdentity as Rt, computeParameterTaint as S, normalizeAwsError as Sa, resolveCaptureObservedState as Si, malformedExportNamesWarning as Sn, forceQuitRecoveryClause as Sr, isWaitAbandonedError as St, resourcesNamingDeclaredParameter as T, isRetryableTransientError as Ta, resolveStateBucketWithDefaultAndSource as Ti, malformedOrphanRecordsWarning as Tn, CUSTOM_RESOURCE_RESPONSE_PREFIX as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, canonicalizeRegion as Ui, repairMalformedResourcePropertiesForReadOnly as Un, rewriteTemplateAssetReferences as Ur, resolveExplicitPhysicalId as Ut, renderStatefulReason as V, expectedOwnerParam as Vi, repairMalformedOutputsForReadOnly as Vn, createAssetRedirectResolver as Vr, WAFv2WebACLProvider as Vt, isWarmThroughputDecrease as W, derivePartitionAndUrlSuffix as Wi, repairMalformedResourcesForReadOnly as Wn, AssetModeResolver as Wr, assertRegionMatch as Wt, gray as X, getAwsClients as Xi, withRetry as Xn, parseBootstrapMarker as Xr, readConfigString as Xt, cyan as Y, AwsClients as Yi, describeTypeWithThrottleRetry as Yn, isCrossRegionRedirect as Yr, configStringRefusal as Yt, green as Z, resetAwsClients as Zi, DagBuilder as Zn, readBootstrapMarkerBody as Zr, replayWarn as Zt, bagHoldsSecretExpression as _, StackTerminationProtectionError as _a, synthesisStatusMessage as _i, UNREADABLE_RESOURCES_MAP_ROW as _n, S3StateBackend as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, DynamicReferenceRegionAmbiguousError as aa, dockerSpawnEnvWithSensitive as ai, s3BucketDomainName as an, dynamicReferenceTokens as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, formatError as ba, resolveApp as bi, hasReadableResources as bn, buildForceUnlockCommand as br, startInterruptWatch as bt, replayFailedOperations as c, LocalStartServiceError as ca, partitionSensitiveEnv as ci, s3BucketWebsiteUrl as cn, isSingleDynamicReferenceToken as cr, IAMRoleProvider as ct, updatePartialMessage as d, NestedStackChildDirectDestroyError as da, runDockerStreaming as di, applyCallerIdentityCredentials as dn, maskSecretsInText as dr, ProviderRegistry as dt, CdkdError as ea, buildDenyExternalAccessPolicy as ei, requireConfigString as en, STATE_SOURCED_CROSS_GENERATION_RULES as er, collectDeclaredOutputNames as et, updatePartialReason as f, PartialFailureError as fa, escapeRegExp$1 as fi, callerEnvCredentials as fn, recordMaskOnlyValue as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, StackHasActiveImportsError as ga, Synthesizer as gi, STATE_RESOURCES_MALFORMED as gn, LockManager as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, ResourceUpdateNotSupportedError as ha, getDockerImageBySourceHash as hi, INTRINSIC_KEYS as hn, scrubResourceRecord as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, DeployCancelledError as ia, describeDockerFailure as ii, s3BucketArn as in, createSecretMasker as ir, secretBearing as it, isFinalSnapshotError as j, describeAwsFailure as ja, CFN_TEMPLATE_URL_LIMIT as ji, malformedResourcesWarning as jn, importableOutputKeys as jr, carriesFetchableDynamicReference as jt, ccRoutedFinalSnapshotError as k, markRedactedCause as ka, ssmResolvedValueType as ki, malformedResourceEntriesWarning as kn, hasReasonlessBaselineRefusal as kr, IntrinsicFunctionResolver as kt, replayRollback as l, LockError as la, redactDockerArgvValues as li, applyRoleArnIfSet as ln, markSameGenerationBag as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, ResourceTimeoutError as ma, AssetManifestLoader as mi, DiffCalculator as mn, redactSecretsForState as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, CrossAccountSecretRefusalError as na, describeDockerCapturedOutput as ni, producerRegionsFromState as nn, TEMPLATE_SOURCED_RULES as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, IntrinsicResolutionRefusalError as oa, formatDockerLoginError as oi, s3BucketDualStackDomainName as on, errorCauseChain as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, ProvisioningError as pa, stripControlChars as pi, envCredentialsAreAssumedRole as pn, recoverMaskedOutput as pr, createMaskedRetryLogger as pt, formatResourceLine as q, clearBucketRegionCache as qi, findActionableSilentDrops as qn, ensureAssetStorage as qr, configBooleanRefusal as qt, DeployEngine as r, DependencyError as ra, describeDockerExecFailure as ri, withSharedDrainBudget as rn, carriesSecretMask as rr, isExportAliasCollision as rt, planRollback as s, LocalInvokeBuildError as sa, getDockerCmd as si, s3BucketRegionalDomainName as sn, identityKeyFor as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, ConfigError as ta, buildDockerImage as ti, classifyReplaySecretRegion as tn, STATE_SOURCED_READBACK_RULES as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, MalformedProducerRecordRefusalError as ua, runDockerForeground as ui, AWS_CREDENTIAL_ENV_KEYS as un, maskSecretsInError as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, StateError as va, getDefaultStateBucketName as vi, displayLogicalId as vn, rebuildClientForBucketRegion as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, isMarkedNonRetryable as wa, resolveStateBucketWithDefault as wi, malformedLocalOutputsWarning as wn, shellQuote as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, isCdkdError as xa, resolveAutoAssetStorage as xi, isReadableResourceEntry as xn, buildLockContentionMessage as xr, CloudControlProvider as xt, keptWholeReasonText as y, SynthesisError as ya, getLegacyStateBucketName as yi, hasReadableOutputs as yn, UNREPRODUCIBLE_LOCK_CLAUSE as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, producerRecordKey as zi, refuseMalformedResourcesForDestroy as zn, WorkGraph as zr, refStateLookupFromResource as zt };
47395
- //# sourceMappingURL=deploy-engine-C1dgx124.js.map
47686
+ export { yellow as $, getAwsClients as $i, STATE_SOURCED_BASELINE_RULES as $n, validateContainerRepoName as $r, requireConfigObject as $t, createPreDeleteFinalSnapshot as A, isTransientServerError as Aa, ssmResolvedValueType as Ai, malformedResourcePropertiesWarning as An, hasUnverifiableParameterRefusal as Ar, carriesDynamicReference as At, isStatefulRecreateTargetSync as B, producerRecordKey as Bi, refuseMalformedState as Bn, buildAssetRedirectMap as Br, isSettledInstanceState as Bt, namesAnyDeclaredParameter as C, formatError as Ca, resolveCaptureObservedState as Ci, malformedExportSourceWarning as Cn, formatLockExpiry as Cr, slowCcOperationTimeoutMs as Ct, PRE_DELETE_SNAPSHOT_TYPES as D, isMarkedNonRetryable as Da, resolveUseCdkBootstrapAssets as Di, malformedOutputsWarning as Dn, exportNamesCarriedFrom as Dr, disableInstanceApiTermination as Dt, ATOMIC_FINAL_SNAPSHOT_TYPES as E, withErrorHandling as Ea, resolveStateBucketWithDefaultAndSource as Ei, malformedOutputsRefusalMessage as En, DEFAULT_STATE_PREFIX as Er, deleteSkipReason as Et, extractDeploymentEventError as F, safeStringify$1 as Fa, uploadCfnTemplate as Fi, refuseMalformedOutputs as Fn, orphansCarriedFrom as Fr, isImpossibleEmptyStoredAttribute as Ft, toCfnInteger as G, derivePartitionAndUrlSuffix as Gi, safeRegion as Gn, BOOTSTRAP_MARKER_PREFIX as Gr, coerceCfnBoolean as Gt, WARM_THROUGHPUT_MEMBERS as H, expectedOwnerParam as Hi, repairMalformedResourceEntriesForReadOnly as Hn, loadPublishableAssetManifest as Hr, normalizeAwsTagsToCfn as Ht, makeSiblingClaimReader as I, __exportAll as Ia, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Ii, refuseMalformedOutputsForDestroy as In, shouldRetainResource as Ir, isNamelessDynamicReferenceError as It, bold as J, renderAssemblyPathEscape as Ji, findSilentDropProperties as Jn, getBootstrapMarkerKey as Jr, configIntegerRefusal as Jt, toFiniteNumber as K, AssemblyReader as Ki, safeStackName as Kn, assertAssetBucketRegion as Kr, coerceCfnInteger as Kt, planOrphanAdoption as L, injectiveKey as Li, refuseMalformedResourceEntries as Ln, AssetPublisher as Lr, isUnboundTemplateParameter as Lt, refusesFinalSnapshot as M, markRedactedCause as Ma, CFN_TEMPLATE_URL_LIMIT as Mi, malformedStateRefusalMessage as Mn, importableOutputs as Mr, cfnRefValueFromPhysicalId as Mt, unsupportedFinalSnapshotError as N, retryClassificationText as Na, MIGRATE_TMP_PREFIX as Ni, refuseDivergentRecordRegionForDestroy as Nn, isReadableBag as Nr, coerceParameterTypedValue as Nt, buildFinalSnapshotIdentifier as O, isRetryableTransientError as Oa, stateBucketExistenceConfirmed as Oi, malformedRenderedContainersWarning as On, hasReadableExportSet as Or, isTerminationProtectionPropagationError as Ot, makeCanonicalizePropertiesFn as P, describeAwsFailure as Pa, findLargeInlineResources as Pi, refuseMalformedNestedChildOutputs as Pn, orphansAfterRollback as Pr, getAccountInfo as Pt, red as Q, AwsClients as Qi, TemplateParser as Qn, validateAssetBucketName as Qr, requireConfigArray as Qt, MULTI_REGION_RECREATE_BLOCKED_TYPES as R, injectiveKeyPrefix as Ri, refuseMalformedResourcePropertiesForOrphan as Rn, stringifyValue as Rr, parameterTypeMayLoseSecretIdentity as Rt, computeParameterTaint as S, SynthesisError as Sa, resolveAutoAssetStorage as Si, malformedExportNamesWarning as Sn, forceQuitRecoveryClause as Sr, isWaitAbandonedError as St, resourcesNamingDeclaredParameter as T, normalizeAwsError as Ta, resolveStateBucketWithDefault as Ti, malformedOrphanRecordsWarning as Tn, CUSTOM_RESOURCE_RESPONSE_PREFIX as Tr, deleteIndeterminateGuards as Tt, coerceWarmThroughput as U, PARTITION_TABLE as Ui, repairMalformedResourcePropertiesForReadOnly as Un, rewriteTemplateAssetReferences as Ur, resolveExplicitPhysicalId as Ut, renderStatefulReason as V, decodeListingKey as Vi, repairMalformedOutputsForReadOnly as Vn, createAssetRedirectResolver as Vr, WAFv2WebACLProvider as Vt, isWarmThroughputDecrease as W, canonicalizeRegion as Wi, repairMalformedResourcesForReadOnly as Wn, AssetModeResolver as Wr, assertRegionMatch as Wt, gray as X, clearBucketRegionCache as Xi, withRetry as Xn, parseBootstrapMarker as Xr, readConfigString as Xt, cyan as Y, resolveAssemblyPath as Yi, describeTypeWithThrottleRetry as Yn, isCrossRegionRedirect as Yr, configStringRefusal as Yt, green as Z, resolveBucketRegion as Zi, DagBuilder as Zn, readBootstrapMarkerBody as Zr, replayWarn as Zt, bagHoldsSecretExpression as _, ResourceTimeoutError as _a, Synthesizer as _i, UNREADABLE_RESOURCES_MAP_ROW as _n, S3StateBackend as _r, endCommandInterruptScope as _t, DeploymentEventsStore as a, CrossAccountSecretRefusalError as aa, describeDockerFailure as ai, s3BucketDomainName as an, dynamicReferenceTokens as ar, secretBearingStateKeyWarning as at, mergeNoChangeOutputs as b, StackTerminationProtectionError as ba, getLegacyStateBucketName as bi, hasReadableResources as bn, buildForceUnlockCommand as br, startInterruptWatch as bt, replayFailedOperations as c, DynamicReferenceRegionAmbiguousError as ca, getDockerCmd as ci, s3BucketWebsiteUrl as cn, isSingleDynamicReferenceToken as cr, IAMRoleProvider as ct, updatePartialMessage as d, LocalStartServiceError as da, runDockerForeground as di, applyCallerIdentityCredentials as dn, maskSecretsInText as dr, ProviderRegistry as dt, resetAwsClients as ea, buildDenyExternalAccessPolicy as ei, requireConfigString as en, STATE_SOURCED_CROSS_GENERATION_RULES as er, collectDeclaredOutputNames as et, updatePartialReason as f, LockError as fa, runDockerStreaming as fi, callerEnvCredentials as fn, recordMaskOnlyValue as fr, wouldReturnToSdkProvider as ft, computeImplicitDeleteEdges as g, ProvisioningError as ga, getDockerImageBySourceHash as gi, STATE_RESOURCES_MALFORMED as gn, LockManager as gr, beginCommandInterruptScope as gt, IMPLICIT_DELETE_DEPENDENCIES as h, PartialFailureError as ha, AssetManifestLoader as hi, INTRINSIC_KEYS as hn, scrubResourceRecord as hr, maskerOrIdentity as ht, DeploymentEventsReader as i, ConfigError as ia, describeDockerExecFailure as ii, s3BucketArn as in, createSecretMasker as ir, secretBearing as it, isFinalSnapshotError as j, markNonRetryable as ja, CFN_TEMPLATE_BODY_LIMIT as ji, malformedResourcesWarning as jn, importableOutputKeys as jr, carriesFetchableDynamicReference as jt, ccRoutedFinalSnapshotError as k, isThrottlingError as ka, warnDeprecatedNoPrefixCliFlag as ki, malformedResourceEntriesWarning as kn, hasReasonlessBaselineRefusal as kr, IntrinsicFunctionResolver as kt, replayRollback as l, IntrinsicResolutionRefusalError as la, partitionSensitiveEnv as li, applyRoleArnIfSet as ln, markSameGenerationBag as lr, collectInlinePolicyNamesManagedBySiblings as lt, maskingRetryLogger as m, NestedStackChildDirectDestroyError as ma, stripControlChars as mi, DiffCalculator as mn, redactSecretsForState as mr, maskDeep as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, AssetError as na, resolveDockerContextDirectory as ni, producerRegionsFromState as nn, TEMPLATE_SOURCED_RULES as nr, exportAliasCollisionScrubWarning as nt, planFailedOps as o, DependencyError as oa, dockerSpawnEnvWithSensitive as oi, s3BucketDualStackDomainName as on, errorCauseChain as or, secretSafeKeyDisplay as ot, withResourceDeadline as p, MalformedProducerRecordRefusalError as pa, escapeRegExp$1 as pi, envCredentialsAreAssumedRole as pn, recoverMaskedOutput as pr, createMaskedRetryLogger as pt, formatResourceLine as q, processStackMessages as qi, findActionableSilentDrops as qn, ensureAssetStorage as qr, configBooleanRefusal as qt, DeployEngine as r, CdkdError as ra, describeDockerCapturedOutput as ri, withSharedDrainBudget as rn, carriesSecretMask as rr, isExportAliasCollision as rt, planRollback as s, DeployCancelledError as sa, formatDockerLoginError as si, s3BucketRegionalDomainName as sn, identityKeyFor as sr, getCurrentResourceSecrets as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, setAwsClients as ta, buildDockerImage as ti, classifyReplaySecretRegion as tn, STATE_SOURCED_READBACK_RULES as tr, collectPublishedOutputNames as tt, resolveReplacementOldType as u, LocalInvokeBuildError as ua, redactDockerArgvValues as ui, AWS_CREDENTIAL_ENV_KEYS as un, maskSecretsInError as ur, clearOnUpdateRemoval as ut, isSecretBearingReferenceString as v, ResourceUpdateNotSupportedError as va, synthesisStatusMessage as vi, displayLogicalId as vn, rebuildClientForBucketRegion as vr, interruptWatchListenerCount as vt, reachableDivergentParameters as w, isCdkdError as wa, resolveSkipPrefix as wi, malformedLocalOutputsWarning as wn, shellQuote as wr, UNSPECIFIED_SKIP_REASON as wt, bindingSkippedOutputs as x, StateError as xa, resolveApp as xi, isReadableResourceEntry as xn, buildLockContentionMessage as xr, CloudControlProvider as xt, keptWholeReasonText as y, StackHasActiveImportsError as ya, getDefaultStateBucketName as yi, hasReadableOutputs as yn, UNREPRODUCIBLE_LOCK_CLAUSE as yr, isInterruptedWaitError as yt, isStatefulRecreateTargetForReplace as z, producerCoordinateKey as zi, refuseMalformedResourcesForDestroy as zn, WorkGraph as zr, refStateLookupFromResource as zt };
47687
+ //# sourceMappingURL=deploy-engine-Bw8VoyEi.js.map