Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ $ awslocal sns list-topics

## Change Log

* 3.0.4: Fix asset publishing failures for CDK >= 2.177.0 against remote LocalStack endpoints (e.g. `*.sandbox.localstack.cloud`)
* 3.0.3: Add missing `semver` dependency
* 3.0.2: Add support for `aws-cdk` versions after 2026-03-01 (see https://github.com/aws/aws-cdk-cli/issues/310)
* 3.0.1: Using the `-v`/`--version` flag prints the cdklocal version and the version of the underlying `aws-cdk` package (if possible)
Expand Down
41 changes: 41 additions & 0 deletions bin/cdklocal
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,28 @@ const useLocal = () => {
return true;
};

// require("aws-cdk/lib") resolves to legacy-exports.js which re-exports SdkProvider as a thin
// wrapper with only static methods. The real SdkProvider (with _makeSdk and other instance
// methods) lives in index.js. Load it directly by resolving the package root and bypassing
// the exports field.
const loadRealSdkProvider = () => {
const cdkRoot = path.dirname(require.resolve("aws-cdk/package.json"));
const indexLib = require(path.join(cdkRoot, "lib", "index.js"));
return indexLib.SdkProvider;
};
Comment on lines +118 to +126
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't convinced this was going to work with aws-cdk@^2.1114.0 because they removed all exports from the package except for a few, making it illegal to access most of the files and forbidding monkey-patching, BUT turns out that importing a module using an absolute path avoids this restriction. This behavior might be a bug in the node resolution algorithm but if it works temporarily, there's no reason not to accept it.

Just be mindful that this patch could stop working anytime. Any future errors are already swallowed so that's good.


const shouldForcePathStyle = () => {
if (isEnvTrue(process.env.AWS_S3_FORCE_PATH_STYLE)) {
return true;
}
const endpointUrl = process.env.AWS_ENDPOINT_URL || "";
try {
return new URL(endpointUrl).hostname.includes(".sandbox.");
} catch {
return false;
}
};

const md5 = s => crypto.createHash("md5").update(s).digest("hex");

const getMethods = (obj) => {
Expand Down Expand Up @@ -485,6 +507,25 @@ const patchPost_2_14 = () => {
case "ERR_PACKAGE_PATH_NOT_EXPORTED":
// post 2.177
configureEnvironment(process.env, AWS_ENVAR_ALLOWLIST);
try {
const RealSdkProvider = loadRealSdkProvider();
if (RealSdkProvider && typeof RealSdkProvider.prototype._makeSdk === "function") {
const origMakeSdk = RealSdkProvider.prototype._makeSdk;
RealSdkProvider.prototype._makeSdk = function patchedMakeSdk(...args) {
const sdk = origMakeSdk.apply(this, args);
// S3 assets are uploaded using path-style URLs (e.g. https://<host>/<bucket>/...)
// rather than virtual-hosted-style (e.g. https://<bucket>.<host>/...).
// This is required for sandbox endpoints whose wildcard TLS cert only covers
// one subdomain level, and can also be opted into via AWS_S3_FORCE_PATH_STYLE.
if (sdk && sdk.config && shouldForcePathStyle()) {
sdk.config.forcePathStyle = true;
}
return sdk;
};
}
} catch (patchErr) {
// swallow - patch is best-effort for endpoints that don't need path-style
}
break;
default:
// a different error
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "aws-cdk-local",
"description": "CDK Toolkit for use with LocalStack",
"version": "3.0.3",
"version": "3.0.4",
"main": "src/index.js",
"bin": {
"cdklocal": "bin/cdklocal"
Expand Down
Loading