@@ -42,7 +42,7 @@ const getLocalHost = async () => {
4242 // Issue: https://github.com/localstack/aws-cdk-local/issues/78
4343 if ( hostname === "localhost" ) {
4444 try {
45- const options = { host : hostname , port : EDGE_PORT } ;
45+ const options = { host : hostname , port : EDGE_PORT } ;
4646 await checkTCPConnection ( options ) ;
4747 } catch ( e ) {
4848 hostname = "127.0.0.1" ;
@@ -131,14 +131,15 @@ const getTemplateBody = (params) => {
131131// small import util function
132132
133133const modulePrefix = "aws-cdk/node_modules" ;
134- const importLib = function importLib ( libPath ) {
134+ const importLib = function importLib ( libPath ) {
135135 try {
136136 return require ( path . join ( modulePrefix , libPath ) ) ;
137137 } catch ( exc ) {
138138 return require ( path . join ( libPath ) ) ;
139139 }
140140} ;
141141
142+ // this isn't doing anything for current versions (e.g. 2.167.1)
142143const setSdkOptions = async ( options , setHttpOptions ) => {
143144 if ( ! useLocal ( options ) ) {
144145 return ;
@@ -155,10 +156,13 @@ const setSdkOptions = async (options, setHttpOptions) => {
155156const patchProviderCredentials = ( provider ) => {
156157 const origConstr = provider . SdkProvider . withAwsCliCompatibleDefaults ;
157158 provider . SdkProvider . withAwsCliCompatibleDefaults = async ( options = { } ) => {
158- await setSdkOptions ( options , true ) ;
159+ const localEndpoint = await getLocalEndpoint ( ) ;
160+ await setSdkOptions ( options , true ) ; // legacy
159161 const result = await origConstr ( options ) ;
160- result . sdkOptions = result . sdkOptions || { } ;
161- await setSdkOptions ( result . sdkOptions ) ;
162+ result . sdkOptions = result . sdkOptions || { } ; // legacy
163+ await setSdkOptions ( result . sdkOptions ) ; // legacy
164+ result . requestHandler . endpoint = localEndpoint ;
165+ result . requestHandler . forcePathStyle = true ;
162166 return result ;
163167 } ;
164168
@@ -172,7 +176,7 @@ const patchCdkToolkit = (CdkToolkit) => {
172176 const CdkToolkitClass = CdkToolkit . ToolkitInfo || CdkToolkit ;
173177 getMethods ( CdkToolkitClass . prototype ) . forEach ( ( meth ) => {
174178 const original = CdkToolkitClass . prototype [ meth ] ;
175- CdkToolkitClass . prototype [ meth ] = async function methFunc ( ...args ) {
179+ CdkToolkitClass . prototype [ meth ] = async function methFunc ( ...args ) {
176180 await setSdkOptions ( this . props . sdkProvider . sdkOptions ) ;
177181 return original . bind ( this ) . apply ( this , args ) ;
178182 } ;
@@ -181,14 +185,14 @@ const patchCdkToolkit = (CdkToolkit) => {
181185
182186const patchCurrentAccount = ( SDK ) => {
183187 const currentAccountOrig = SDK . prototype . currentAccount ;
184- SDK . prototype . currentAccount = async function currentAccount ( ) {
188+ SDK . prototype . currentAccount = async function currentAccount ( ) {
185189 const { config} = this ;
186190 await setSdkOptions ( config ) ;
187191 return currentAccountOrig . bind ( this ) ( ) ;
188192 } ;
189193
190194 const forceCredentialRetrievalOrig = SDK . prototype . forceCredentialRetrieval ;
191- SDK . prototype . forceCredentialRetrieval = function forceCredentialRetrieval ( ) {
195+ SDK . prototype . forceCredentialRetrieval = function forceCredentialRetrieval ( ) {
192196 if ( ! this . _credentials . getPromise ) {
193197 this . _credentials . getPromise = ( ) => this . _credentials ;
194198 }
@@ -201,9 +205,9 @@ const patchToolkitInfo = (ToolkitInfo) => {
201205 BUCKET_NAME_OUTPUT , BUCKET_DOMAIN_NAME_OUTPUT
202206 } = require ( "aws-cdk/lib/api/bootstrap/bootstrap-props" ) ;
203207
204- const setBucketUrl = function setBucketUrl ( object ) {
208+ const setBucketUrl = function setBucketUrl ( object ) {
205209 Object . defineProperty ( object , "bucketUrl" , {
206- async get ( ) {
210+ async get ( ) {
207211 const bucket = this . requireOutput ( BUCKET_NAME_OUTPUT ) ;
208212 const domain = this . requireOutput ( BUCKET_DOMAIN_NAME_OUTPUT ) || await getLocalHost ( ) ;
209213 return `https://${ domain . replace ( `${ bucket } .` , "" ) } :${ EDGE_PORT } /${ bucket } ` ;
@@ -236,19 +240,14 @@ const patchLambdaMounting = (CdkToolkit) => {
236240 // modify asset paths to enable local Lambda code mounting
237241
238242 const lookupLambdaForAsset = ( template , paramName ) => {
239- const result = Object . keys ( template . Resources ) .
240- map ( ( key ) => template . Resources [ key ] ) .
241- filter ( ( res ) => res . Type === "AWS::Lambda::Function" ) .
242- filter ( ( res ) => JSON . stringify ( res . Properties . Code . S3Key ) . includes ( paramName ) ) ;
243+ const result = Object . keys ( template . Resources ) . map ( ( key ) => template . Resources [ key ] ) . filter ( ( res ) => res . Type === "AWS::Lambda::Function" ) . filter ( ( res ) => JSON . stringify ( res . Properties . Code . S3Key ) . includes ( paramName ) ) ;
243244 const props = result [ 0 ] . Properties ;
244245 const funcName = props . FunctionName ;
245246 if ( funcName ) {
246247 return funcName ;
247248 }
248249 const attributes = [ "Handler" , "Runtime" , "Description" , "Timeout" , "MemorySize" , "Environment" ] ;
249- const valueToHash = attributes . map ( ( attr ) => props [ attr ] ) .
250- map ( ( val ) => typeof val === "object" ? JSON . stringify ( diff . canonicalize ( val ) ) : val ? val : "" ) .
251- join ( "|" ) ;
250+ const valueToHash = attributes . map ( ( attr ) => props [ attr ] ) . map ( ( val ) => typeof val === "object" ? JSON . stringify ( diff . canonicalize ( val ) ) : val ? val : "" ) . join ( "|" ) ;
252251 return md5 ( valueToHash ) ;
253252 } ;
254253
@@ -292,13 +291,13 @@ const patchLambdaMounting = (CdkToolkit) => {
292291 // symlink local Lambda assets if "cdklocal deploy" is called with LAMBDA_MOUNT_CODE=1
293292
294293 const deployStackOrig = deployStackMod . deployStack ;
295- deployStackMod . deployStack = function deployStack ( options ) {
294+ deployStackMod . deployStack = function deployStack ( options ) {
296295 options . sdk . cloudFormationOrig = options . sdk . cloudFormationOrig || options . sdk . cloudFormation ;
297296 const state = { } ;
298297 options . sdk . cloudFormation = ( ) => state . instance ;
299298 const cfn = state . instance = options . sdk . cloudFormationOrig ( ) ;
300299 cfn . createChangeSetOrig = cfn . createChangeSetOrig || cfn . createChangeSet ;
301- const createChangeSetAsync = async function createChangeSetAsync ( params ) {
300+ const createChangeSetAsync = async function createChangeSetAsync ( params ) {
302301 if ( LAMBDA_MOUNT_CODE ) {
303302 const template = deserializeStructure ( await getTemplateBody ( params ) ) ;
304303 symlinkLambdaAssets ( template , params . Parameters ) ;
@@ -315,7 +314,7 @@ const patchLambdaMounting = (CdkToolkit) => {
315314 const { FileAssetHandler} = importLib ( "cdk-assets/lib/private/handlers/files" ) ;
316315
317316 const handlerPublish = FileAssetHandler . prototype . publish ;
318- FileAssetHandler . prototype . publish = function publish ( ) {
317+ FileAssetHandler . prototype . publish = function publish ( ) {
319318 if ( LAMBDA_MOUNT_CODE && this . asset . destination && this . asset . source ) {
320319 if ( this . asset . source . packaging === "zip" ) {
321320 // skip uploading this asset - should get mounted via `__file__` into the Lambda container later on
@@ -328,7 +327,7 @@ const patchLambdaMounting = (CdkToolkit) => {
328327 // symlink local Lambda assets if "cdklocal synth" is called with LAMBDA_MOUNT_CODE=1
329328
330329 const assemblyOrig = CdkToolkit . prototype . assembly ;
331- CdkToolkit . prototype . assembly = async function assembly ( ) {
330+ CdkToolkit . prototype . assembly = async function assembly ( ) {
332331 const result = await assemblyOrig . bind ( this ) ( ) ;
333332 if ( LAMBDA_MOUNT_CODE ) {
334333 result . assembly . artifacts . forEach ( ( art ) => {
@@ -351,7 +350,48 @@ const isEsbuildBundle = () => {
351350 }
352351} ;
353352
353+
354+ const patchSdk = ( SDK , localEndpoint ) => {
355+ getMethods ( SDK . prototype ) . forEach ( ( methodName ) => {
356+ if ( typeof SDK . prototype [ methodName ] === 'function' ) {
357+ const original = SDK . prototype [ methodName ] ;
358+ SDK . prototype [ methodName ] = function methFunc ( ...args ) {
359+ this . config . endpoint = localEndpoint ;
360+ this . config . forcePathStyle = true ;
361+ return original . apply ( this , args ) ;
362+ } ;
363+ }
364+ } ) ;
365+ } ;
366+
367+ let sdkOverwritten = false ;
368+ const patchSdkProvider = ( provider , SDK ) => {
369+ getMethods ( provider . SdkProvider . prototype ) . forEach ( ( methodName ) => {
370+ if ( typeof provider . SdkProvider . prototype [ methodName ] === 'function' ) {
371+ const original = provider . SdkProvider . prototype [ methodName ] ;
372+ provider . SdkProvider . prototype [ methodName ] = async function methFunc ( ...args ) {
373+ const localEndpoint = await getLocalEndpoint ( ) ;
374+
375+ if ( ! sdkOverwritten ) {
376+ // the goal is to support `SdkProvider.withAssumedRole`
377+ // since it instantiates a different client (i.e. not from the SDK class)
378+ this . requestHandler . endpoint = localEndpoint ;
379+ this . requestHandler . forcePathStyle = true ;
380+ // patch SDK class methods (mostly clients) to make sure the config that is created in the constructor
381+ // is updated with the correct configuration
382+ patchSdk ( SDK , localEndpoint ) ;
383+ sdkOverwritten = true ;
384+ }
385+ return await original . apply ( this , args ) ;
386+ } ;
387+ }
388+ }
389+ ) ;
390+ } ;
391+
354392const applyPatches = ( provider , CdkToolkit , SDK , ToolkitInfo , patchAssets = true ) => {
393+ patchSdkProvider ( provider , SDK ) ;
394+ // TODO: a lot of the patches are not really needed for newer versions
355395 patchProviderCredentials ( provider ) ;
356396 patchCdkToolkit ( CdkToolkit ) ;
357397 patchCurrentAccount ( SDK ) ;
@@ -366,7 +406,7 @@ const patchPre_2_14 = () => {
366406 var provider = null ;
367407 try {
368408 provider = require ( "aws-cdk/lib/api/aws-auth" ) ;
369- } catch ( e ) {
409+ } catch ( e ) {
370410 if ( e . code == "MODULE_NOT_FOUND" ) {
371411 console . log ( e ) ;
372412 console . error ( "`aws-cdk` module NOT found! Have you tried adding it to your `NODE_PATH`?" ) ;
@@ -386,7 +426,7 @@ const patchPost_2_14 = () => {
386426 var lib = null ;
387427 try {
388428 lib = require ( "aws-cdk/lib" ) ;
389- } catch ( e ) {
429+ } catch ( e ) {
390430 if ( e . code == "MODULE_NOT_FOUND" ) {
391431 console . log ( e ) ;
392432 console . log ( "`aws-cdk` module NOT found! Have you tried to add it to your `NODE_PATH`?" ) ;
0 commit comments