sst 2.39.12 → 2.40.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.
@@ -1,15 +1,10 @@
1
1
  import * as cxapi from "@aws-cdk/cx-api";
2
2
  import { Tag } from "sst-aws-cdk/lib/cdk-toolkit.js";
3
- import { AssetManifestBuilder } from "sst-aws-cdk/lib/util/asset-manifest-builder.js";
4
3
  import { ISDK, SdkProvider } from "sst-aws-cdk/lib/api/aws-auth/index.js";
5
4
  import { EnvironmentResources } from "sst-aws-cdk/lib/api/environment-resources.js";
6
5
  import { HotswapMode } from "sst-aws-cdk/lib/api/hotswap/common.js";
7
6
  import { ResourcesToImport } from "sst-aws-cdk/lib/api/util/cloudformation.js";
8
7
  import { StackActivityProgress } from "sst-aws-cdk/lib/api/util/cloudformation/stack-activity-monitor.js";
9
- type TemplateBodyParameter = {
10
- TemplateBody?: string;
11
- TemplateURL?: string;
12
- };
13
8
  export interface DeployStackResult {
14
9
  readonly noOp: boolean;
15
10
  readonly outputs: {
@@ -187,27 +182,6 @@ export interface ChangeSetDeploymentMethod {
187
182
  readonly changeSetName?: string;
188
183
  }
189
184
  export declare function deployStack(options: DeployStackOptions): Promise<DeployStackResult | undefined>;
190
- /**
191
- * Prepares the body parameter for +CreateChangeSet+.
192
- *
193
- * If the template is small enough to be inlined into the API call, just return
194
- * it immediately.
195
- *
196
- * Otherwise, add it to the asset manifest to get uploaded to the staging
197
- * bucket and return its coordinates. If there is no staging bucket, an error
198
- * is thrown.
199
- *
200
- * @param stack the synthesized stack that provides the CloudFormation template
201
- * @param toolkitInfo information about the toolkit stack
202
- */
203
- export declare function makeBodyParameter(stack: cxapi.CloudFormationStackArtifact, resolvedEnvironment: cxapi.Environment, assetManifest: AssetManifestBuilder, resources: EnvironmentResources, sdk: ISDK, overrideTemplate?: any): Promise<TemplateBodyParameter>;
204
- /**
205
- * Prepare a body parameter for CFN, performing the upload
206
- *
207
- * Return it as-is if it is small enough to pass in the API call,
208
- * upload to S3 and return the coordinates if it is not.
209
- */
210
- export declare function makeBodyParameterAndUpload(stack: cxapi.CloudFormationStackArtifact, resolvedEnvironment: cxapi.Environment, resources: EnvironmentResources, sdkProvider: SdkProvider, sdk: ISDK, overrideTemplate?: any): Promise<TemplateBodyParameter>;
211
185
  export interface DestroyStackOptions {
212
186
  /**
213
187
  * The stack to be destroyed
@@ -220,4 +194,3 @@ export interface DestroyStackOptions {
220
194
  ci?: boolean;
221
195
  }
222
196
  export declare function destroyStack(options: DestroyStackOptions): Promise<void>;
223
- export {};
@@ -1,19 +1,14 @@
1
- import * as cxapi from "@aws-cdk/cx-api";
2
- import fs from "fs/promises";
3
1
  import * as uuid from "uuid";
2
+ import { makeBodyParameter, } from "sst-aws-cdk/lib/api/util/template-body-parameter.js";
4
3
  import { addMetadataAssetsToManifest } from "sst-aws-cdk/lib/assets.js";
5
- import { debug, error, print } from "sst-aws-cdk/lib/logging.js";
6
- import { toYAML } from "sst-aws-cdk/lib/serialize.js";
4
+ import { debug, print, warning } from "sst-aws-cdk/lib/logging.js";
7
5
  import { AssetManifestBuilder } from "sst-aws-cdk/lib/util/asset-manifest-builder.js";
8
6
  import { publishAssets } from "sst-aws-cdk/lib/util/asset-publishing.js";
9
- import { contentHash } from "sst-aws-cdk/lib/util/content-hash.js";
10
7
  import { CfnEvaluationException } from "sst-aws-cdk/lib/api/evaluate-cloudformation-template.js";
11
8
  import { HotswapMode } from "sst-aws-cdk/lib/api/hotswap/common.js";
12
9
  import { tryHotswapDeployment } from "sst-aws-cdk/lib/api/hotswap-deployments.js";
13
10
  import { changeSetHasNoChanges, CloudFormationStack, TemplateParameters, waitForChangeSet, waitForStackDeploy, waitForStackDelete, } from "sst-aws-cdk/lib/api/util/cloudformation.js";
14
- import { blue } from "colorette";
15
11
  import { callWithRetry } from "./util.js";
16
- const LARGE_TEMPLATE_SIZE_KB = 50;
17
12
  export async function deployStack(options) {
18
13
  const stackArtifact = options.stack;
19
14
  const stackEnv = options.resolvedEnvironment;
@@ -153,6 +148,15 @@ class FullCloudFormationDeployment {
153
148
  })
154
149
  .promise();
155
150
  }
151
+ if (this.options.force) {
152
+ warning([
153
+ "You used the --force flag, but CloudFormation reported that the deployment would not make any changes.",
154
+ "According to CloudFormation, all resources are already up-to-date with the state in your CDK app.",
155
+ "",
156
+ "You cannot use the --force flag to get rid of changes you made in the console. Try using",
157
+ "CloudFormation drift detection instead: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html",
158
+ ].join("\n"));
159
+ }
156
160
  return {
157
161
  noOp: true,
158
162
  outputs: this.cloudFormationStack.outputs,
@@ -238,19 +242,29 @@ class FullCloudFormationDeployment {
238
242
  async directDeployment() {
239
243
  const startTime = new Date();
240
244
  if (this.update) {
241
- await this.cfn
242
- .updateStack({
243
- StackName: this.stackName,
244
- ClientRequestToken: `update${this.uuid}`,
245
- ...this.commonPrepareOptions(),
246
- ...this.commonExecuteOptions(),
247
- })
248
- .promise();
249
- if (this.options.noMonitor)
250
- return;
251
- const ret = await this.monitorDeployment(startTime, undefined);
252
245
  await this.updateTerminationProtection();
253
- return ret;
246
+ try {
247
+ await this.cfn
248
+ .updateStack({
249
+ StackName: this.stackName,
250
+ ClientRequestToken: `update${this.uuid}`,
251
+ ...this.commonPrepareOptions(),
252
+ ...this.commonExecuteOptions(),
253
+ })
254
+ .promise();
255
+ }
256
+ catch (err) {
257
+ if (err.message === "No updates are to be performed.") {
258
+ debug("No updates are to be performed for stack %s", this.stackName);
259
+ return {
260
+ noOp: true,
261
+ outputs: this.cloudFormationStack.outputs,
262
+ stackArn: this.cloudFormationStack.stackId,
263
+ };
264
+ }
265
+ throw err;
266
+ }
267
+ return this.monitorDeployment(startTime, undefined);
254
268
  }
255
269
  else {
256
270
  // Take advantage of the fact that we can set termination protection during create
@@ -339,76 +353,6 @@ class FullCloudFormationDeployment {
339
353
  };
340
354
  }
341
355
  }
342
- /**
343
- * Prepares the body parameter for +CreateChangeSet+.
344
- *
345
- * If the template is small enough to be inlined into the API call, just return
346
- * it immediately.
347
- *
348
- * Otherwise, add it to the asset manifest to get uploaded to the staging
349
- * bucket and return its coordinates. If there is no staging bucket, an error
350
- * is thrown.
351
- *
352
- * @param stack the synthesized stack that provides the CloudFormation template
353
- * @param toolkitInfo information about the toolkit stack
354
- */
355
- export async function makeBodyParameter(stack, resolvedEnvironment, assetManifest, resources, sdk, overrideTemplate) {
356
- // If the template has already been uploaded to S3, just use it from there.
357
- if (stack.stackTemplateAssetObjectUrl && !overrideTemplate) {
358
- return {
359
- TemplateURL: restUrlFromManifest(stack.stackTemplateAssetObjectUrl, resolvedEnvironment, sdk),
360
- };
361
- }
362
- // Otherwise, pass via API call (if small) or upload here (if large)
363
- const templateJson = toYAML(overrideTemplate ?? stack.template);
364
- if (templateJson.length <= LARGE_TEMPLATE_SIZE_KB * 1024) {
365
- return { TemplateBody: templateJson };
366
- }
367
- const toolkitInfo = await resources.lookupToolkit();
368
- if (!toolkitInfo.found) {
369
- error(`The template for stack "${stack.displayName}" is ${Math.round(templateJson.length / 1024)}KiB. ` +
370
- `Templates larger than ${LARGE_TEMPLATE_SIZE_KB}KiB must be uploaded to S3.\n` +
371
- "Run the following command in order to setup an S3 bucket in this environment, and then re-deploy:\n\n", blue(`\t$ cdk bootstrap ${resolvedEnvironment.name}\n`));
372
- throw new Error('Template too large to deploy ("cdk bootstrap" is required)');
373
- }
374
- const templateHash = contentHash(templateJson);
375
- const key = `cdk/${stack.id}/${templateHash}.yml`;
376
- let templateFile = stack.templateFile;
377
- if (overrideTemplate) {
378
- // Add a variant of this template
379
- templateFile = `${stack.templateFile}-${templateHash}.yaml`;
380
- await fs.writeFile(templateFile, templateJson, { encoding: "utf-8" });
381
- }
382
- assetManifest.addFileAsset(templateHash, {
383
- path: templateFile,
384
- }, {
385
- bucketName: toolkitInfo.bucketName,
386
- objectKey: key,
387
- });
388
- const templateURL = `${toolkitInfo.bucketUrl}/${key}`;
389
- debug("Storing template in S3 at:", templateURL);
390
- return { TemplateURL: templateURL };
391
- }
392
- /**
393
- * Prepare a body parameter for CFN, performing the upload
394
- *
395
- * Return it as-is if it is small enough to pass in the API call,
396
- * upload to S3 and return the coordinates if it is not.
397
- */
398
- export async function makeBodyParameterAndUpload(stack, resolvedEnvironment, resources, sdkProvider, sdk, overrideTemplate) {
399
- // We don't have access to the actual asset manifest here, so pretend that the
400
- // stack doesn't have a pre-published URL.
401
- const forceUploadStack = Object.create(stack, {
402
- stackTemplateAssetObjectUrl: { value: undefined },
403
- });
404
- const builder = new AssetManifestBuilder();
405
- const bodyparam = await makeBodyParameter(forceUploadStack, resolvedEnvironment, builder, resources, sdk, overrideTemplate);
406
- const manifest = builder.toManifest(stack.assembly.directory);
407
- await publishAssets(manifest, sdkProvider, resolvedEnvironment, {
408
- quiet: true,
409
- });
410
- return bodyparam;
411
- }
412
356
  export async function destroyStack(options) {
413
357
  const deployName = options.deployName || options.stack.stackName;
414
358
  const cfn = options.sdk.cloudFormation();
@@ -527,37 +471,6 @@ function compareTags(a, b) {
527
471
  }
528
472
  return true;
529
473
  }
530
- /**
531
- * Format an S3 URL in the manifest for use with CloudFormation
532
- *
533
- * Replaces environment placeholders (which this field may contain),
534
- * and reformats s3://.../... urls into S3 REST URLs (which CloudFormation
535
- * expects)
536
- */
537
- function restUrlFromManifest(url, environment, sdk) {
538
- const doNotUseMarker = "**DONOTUSE**";
539
- // This URL may contain placeholders, so still substitute those.
540
- url = cxapi.EnvironmentPlaceholders.replace(url, {
541
- accountId: environment.account,
542
- region: environment.region,
543
- partition: doNotUseMarker,
544
- });
545
- // Yes, this is extremely crude, but we don't actually need this so I'm not inclined to spend
546
- // a lot of effort trying to thread the right value to this location.
547
- if (url.indexOf(doNotUseMarker) > -1) {
548
- throw new Error("Cannot use '${AWS::Partition}' in the 'stackTemplateAssetObjectUrl' field");
549
- }
550
- const s3Url = url.match(/s3:\/\/([^/]+)\/(.*)$/);
551
- if (!s3Url) {
552
- return url;
553
- }
554
- // We need to pass an 'https://s3.REGION.amazonaws.com[.cn]/bucket/object' URL to CloudFormation, but we
555
- // got an 's3://bucket/object' URL instead. Construct the rest API URL here.
556
- const bucketName = s3Url[1];
557
- const objectKey = s3Url[2];
558
- const urlSuffix = sdk.getEndpointSuffix(environment.region);
559
- return `https://s3.${environment.region}.${urlSuffix}/${bucketName}/${objectKey}`;
560
- }
561
474
  function suffixWithErrors(msg, errors) {
562
475
  return errors && errors.length > 0 ? `${msg}: ${errors.join(", ")}` : msg;
563
476
  }
@@ -6,8 +6,8 @@ import { Mode } from "sst-aws-cdk/lib/api/aws-auth/credentials.js";
6
6
  import { addMetadataAssetsToManifest } from "sst-aws-cdk/lib/assets.js";
7
7
  import { publishAssets } from "sst-aws-cdk/lib/util/asset-publishing.js";
8
8
  import { AssetManifestBuilder } from "sst-aws-cdk/lib/util/asset-manifest-builder.js";
9
+ import { makeBodyParameter } from "sst-aws-cdk/lib/api/util/template-body-parameter.js";
9
10
  import { Deployments, } from "./deployments.js";
10
- import { makeBodyParameter } from "./deploy-stack.js";
11
11
  import { lazy } from "../util/lazy.js";
12
12
  export async function publishDeployAssets(sdkProvider, options) {
13
13
  const { deployment, envResources, stackSdk, resolvedEnvironment, cloudFormationRoleArn, } = await useDeployment().get(sdkProvider, options);
@@ -163,6 +163,12 @@ export interface DeployStackOptions {
163
163
  * @default true To remain backward compatible.
164
164
  */
165
165
  readonly assetParallelism?: boolean;
166
+ /**
167
+ * Whether to deploy if the app contains no stacks.
168
+ *
169
+ * @default false
170
+ */
171
+ ignoreNoStacks?: boolean;
166
172
  }
167
173
  interface AssetOptions {
168
174
  /**
@@ -256,12 +262,17 @@ export declare class Deployments {
256
262
  private readonly publisherCache;
257
263
  private readonly environmentResources;
258
264
  constructor(props: DeploymentsProps);
265
+ /**
266
+ * Resolves the environment for a stack.
267
+ */
268
+ resolveEnvironment(stack: cxapi.CloudFormationStackArtifact): Promise<cxapi.Environment>;
259
269
  readCurrentTemplateWithNestedStacks(rootStackArtifact: cxapi.CloudFormationStackArtifact, retrieveProcessedTemplate?: boolean): Promise<Template>;
260
270
  readCurrentTemplate(stackArtifact: cxapi.CloudFormationStackArtifact): Promise<Template>;
261
271
  resourceIdentifierSummaries(stackArtifact: cxapi.CloudFormationStackArtifact): Promise<ResourceIdentifierSummaries>;
262
272
  deployStack(options: DeployStackOptions): Promise<DeployStackResult | undefined>;
263
273
  destroyStack(options: DestroyStackOptions): Promise<void>;
264
274
  stackExists(options: StackExistsOptions): Promise<boolean>;
275
+ prepareSdkWithDeployRole(stackArtifact: cxapi.CloudFormationStackArtifact): Promise<PreparedSdkForEnvironment>;
265
276
  private prepareSdkWithLookupOrDeployRole;
266
277
  /**
267
278
  * Get the environment necessary for touching the given stack
@@ -5,11 +5,12 @@ import { AssetManifest } from "cdk-assets";
5
5
  import { debug, warning } from "sst-aws-cdk/lib/logging.js";
6
6
  import { buildAssets, publishAssets, PublishingAws, EVENT_TO_LOGGER, } from "sst-aws-cdk/lib/util/asset-publishing.js";
7
7
  import { Mode } from "sst-aws-cdk/lib/api/aws-auth/credentials.js";
8
- import { deployStack, destroyStack, makeBodyParameterAndUpload, } from "./deploy-stack.js";
8
+ import { deployStack, destroyStack, } from "./deploy-stack.js";
9
9
  import { EnvironmentResourcesRegistry, } from "sst-aws-cdk/lib/api/environment-resources.js";
10
10
  import { loadCurrentTemplateWithNestedStacks, loadCurrentTemplate, flattenNestedStackNames, } from "sst-aws-cdk/lib/api/nested-stack-helpers.js";
11
11
  import { CloudFormationStack, } from "sst-aws-cdk/lib/api/util/cloudformation.js";
12
12
  import { replaceEnvPlaceholders } from "sst-aws-cdk/lib/api/util/placeholders.js";
13
+ import { makeBodyParameterAndUpload } from "sst-aws-cdk/lib/api/util/template-body-parameter.js";
13
14
  /**
14
15
  * Scope for a single set of deployments from a set of Cloud Assembly Artifacts
15
16
  *
@@ -26,6 +27,12 @@ export class Deployments {
26
27
  this.sdkProvider = props.sdkProvider;
27
28
  this.environmentResources = new EnvironmentResourcesRegistry(props.toolkitStackName);
28
29
  }
30
+ /**
31
+ * Resolves the environment for a stack.
32
+ */
33
+ async resolveEnvironment(stack) {
34
+ return this.sdkProvider.resolveEnvironment(stack.environment);
35
+ }
29
36
  async readCurrentTemplateWithNestedStacks(rootStackArtifact, retrieveProcessedTemplate = false) {
30
37
  const sdk = (await this.prepareSdkWithLookupOrDeployRole(rootStackArtifact))
31
38
  .stackSdk;
@@ -123,6 +130,9 @@ export class Deployments {
123
130
  const stack = await CloudFormationStack.lookup(stackSdk.cloudFormation(), options.deployName ?? options.stack.stackName);
124
131
  return stack.exists;
125
132
  }
133
+ async prepareSdkWithDeployRole(stackArtifact) {
134
+ return this.prepareSdkFor(stackArtifact, undefined, Mode.ForWriting);
135
+ }
126
136
  async prepareSdkWithLookupOrDeployRole(stackArtifact) {
127
137
  // try to assume the lookup role
128
138
  try {
@@ -152,7 +162,7 @@ export class Deployments {
152
162
  if (!stack.environment) {
153
163
  throw new Error(`The stack ${stack.displayName} does not have an environment`);
154
164
  }
155
- const resolvedEnvironment = await this.sdkProvider.resolveEnvironment(stack.environment);
165
+ const resolvedEnvironment = await this.resolveEnvironment(stack);
156
166
  // Substitute any placeholders with information about the current environment
157
167
  const arns = await replaceEnvPlaceholders({
158
168
  assumeRoleArn: stack.assumeRoleArn,
@@ -88,7 +88,7 @@ export const update = (program) => program.command("update [version]", "Update y
88
88
  oldPackages.add([pkg, existing]);
89
89
  return;
90
90
  }
91
- return metadata.dependencies["@aws-cdk/aws-apigatewayv2-alpha"];
91
+ return metadata.dependencies["@aws-cdk/aws-lambda-python-alpha"];
92
92
  }
93
93
  })();
94
94
  if (!desired || existing === desired)
@@ -1,5 +1,7 @@
1
1
  import { Construct } from "constructs";
2
- import { HttpUrlIntegrationProps, HttpAlbIntegrationProps, HttpNlbIntegrationProps } from "@aws-cdk/aws-apigatewayv2-integrations-alpha";
2
+ import { DomainName, HttpApi, HttpApiProps, HttpRouteIntegration, HttpStageProps, IHttpApi } from "aws-cdk-lib/aws-apigatewayv2";
3
+ import { HttpUrlIntegrationProps, HttpAlbIntegrationProps, HttpNlbIntegrationProps } from "aws-cdk-lib/aws-apigatewayv2-integrations";
4
+ import { HttpJwtAuthorizer, HttpLambdaAuthorizer, HttpLambdaResponseType, HttpUserPoolAuthorizer } from "aws-cdk-lib/aws-apigatewayv2-authorizers";
3
5
  import { HttpAwsIntegrationProps } from "./cdk/HttpAwsIntegration.js";
4
6
  import { SSTConstruct } from "./Construct.js";
5
7
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
@@ -9,8 +11,6 @@ import { Permissions } from "./util/permission.js";
9
11
  import * as apigV2Cors from "./util/apiGatewayV2Cors.js";
10
12
  import * as apigV2Domain from "./util/apiGatewayV2Domain.js";
11
13
  import * as apigV2AccessLog from "./util/apiGatewayV2AccessLog.js";
12
- import { DomainName, HttpApi, HttpApiProps, HttpRouteIntegration, HttpStageProps, IHttpApi } from "@aws-cdk/aws-apigatewayv2-alpha";
13
- import { HttpJwtAuthorizer, HttpLambdaAuthorizer, HttpLambdaResponseType, HttpUserPoolAuthorizer } from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
14
14
  import { IFunction } from "aws-cdk-lib/aws-lambda";
15
15
  import { IApplicationListener, INetworkListener } from "aws-cdk-lib/aws-elasticloadbalancingv2";
16
16
  import { LogGroup } from "aws-cdk-lib/aws-logs";
@@ -363,7 +363,7 @@ export interface ApiProps<Authorizers extends Record<string, ApiAuthorizer> = Re
363
363
  *
364
364
  * @example
365
365
  * ```js
366
- * import { HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha";
366
+ * import { HttpApi } from "aws-cdk-lib/aws-apigatewayv2";
367
367
  *
368
368
  * new Api(stack, "Api", {
369
369
  * cdk: {
@@ -382,7 +382,7 @@ export interface ApiProps<Authorizers extends Record<string, ApiAuthorizer> = Re
382
382
  *
383
383
  * @example
384
384
  * ```js
385
- * import { HttpApi } from "@aws-cdk/aws-apigatewayv2-alpha";
385
+ * import { HttpApi } from "aws-cdk-lib/aws-apigatewayv2";
386
386
  *
387
387
  * new Api(stack, "Api", {
388
388
  * cdk: {
package/constructs/Api.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { Construct } from "constructs";
2
2
  import { Role, ServicePrincipal, PolicyDocument, PolicyStatement, } from "aws-cdk-lib/aws-iam";
3
- import { HttpUrlIntegration, HttpAlbIntegration, HttpNlbIntegration, HttpLambdaIntegration, } from "@aws-cdk/aws-apigatewayv2-integrations-alpha";
3
+ import { HttpApi, HttpMethod, HttpNoneAuthorizer, HttpRoute, HttpRouteKey, HttpStage, IntegrationCredentials, PayloadFormatVersion, } from "aws-cdk-lib/aws-apigatewayv2";
4
+ import { HttpUrlIntegration, HttpAlbIntegration, HttpNlbIntegration, HttpLambdaIntegration, } from "aws-cdk-lib/aws-apigatewayv2-integrations";
5
+ import { HttpIamAuthorizer, HttpJwtAuthorizer, HttpLambdaAuthorizer, HttpLambdaResponseType, HttpUserPoolAuthorizer, } from "aws-cdk-lib/aws-apigatewayv2-authorizers";
4
6
  import { HttpAwsIntegration, } from "./cdk/HttpAwsIntegration.js";
5
7
  import { Stack } from "./Stack.js";
6
8
  import { getFunctionRef, isCDKConstruct } from "./Construct.js";
@@ -9,8 +11,6 @@ import { toCdkDuration } from "./util/duration.js";
9
11
  import * as apigV2Cors from "./util/apiGatewayV2Cors.js";
10
12
  import * as apigV2Domain from "./util/apiGatewayV2Domain.js";
11
13
  import * as apigV2AccessLog from "./util/apiGatewayV2AccessLog.js";
12
- import { HttpApi, HttpMethod, HttpNoneAuthorizer, HttpRoute, HttpRouteKey, HttpStage, IntegrationCredentials, PayloadFormatVersion, } from "@aws-cdk/aws-apigatewayv2-alpha";
13
- import { HttpIamAuthorizer, HttpJwtAuthorizer, HttpLambdaAuthorizer, HttpLambdaResponseType, HttpUserPoolAuthorizer, } from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
14
14
  import { UserPool, UserPoolClient } from "aws-cdk-lib/aws-cognito";
15
15
  const PayloadFormatVersions = ["1.0", "2.0"];
16
16
  /////////////////////
@@ -71,7 +71,7 @@ export class ApiGatewayV1Api extends Construct {
71
71
  */
72
72
  get url() {
73
73
  const app = this.node.root;
74
- return (this.cdk.restApi.url ??
74
+ return ((this.cdk.restApi.deploymentStage && this.cdk.restApi.url) ??
75
75
  `https://${this.cdk.restApi.restApiId}.execute-api.${app.region}.amazonaws.com/${app.stage}/`);
76
76
  }
77
77
  /**
@@ -9,7 +9,7 @@ import { Permissions } from "./util/permission.js";
9
9
  import * as functionUrlCors from "./util/functionUrlCors.js";
10
10
  import { Architecture, Function as CDKFunction, FunctionOptions, ILayerVersion, Runtime as CDKRuntime, Tracing } from "aws-cdk-lib/aws-lambda";
11
11
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
12
- import { Size as CDKSize, Duration as CDKDuration } from "aws-cdk-lib/core";
12
+ import { Size as CDKSize, Duration as CDKDuration, DockerCacheOption } from "aws-cdk-lib/core";
13
13
  import { Asset } from "aws-cdk-lib/aws-s3-assets";
14
14
  declare const supportedRuntimes: {
15
15
  container: CDKRuntime;
@@ -37,6 +37,28 @@ export type FunctionInlineDefinition = string | Function;
37
37
  export type FunctionDefinition = string | Function | FunctionProps;
38
38
  export interface FunctionUrlCorsProps extends functionUrlCors.CorsProps {
39
39
  }
40
+ export interface FunctionDockerBuildCacheProps extends DockerCacheOption {
41
+ }
42
+ export interface FunctionDockerBuildProps {
43
+ /**
44
+ * Cache from options to pass to the `docker build` command.
45
+ * @default - no cache from args are passed
46
+ * @example
47
+ * ```js
48
+ * cacheFrom: [{type: "gha"}],
49
+ * ```
50
+ */
51
+ cacheFrom?: FunctionDockerBuildCacheProps[];
52
+ /**
53
+ * Cache to options to pass to the `docker build` command.
54
+ * @default - no cache to args are passed
55
+ * @example
56
+ * ```js
57
+ * cacheTo: {type: "gha"},
58
+ * ```
59
+ */
60
+ cacheTo?: FunctionDockerBuildCacheProps;
61
+ }
40
62
  export interface FunctionHooks {
41
63
  /**
42
64
  * Hook to run before build
@@ -534,6 +556,10 @@ export interface PythonProps {
534
556
  * your own build processes, and you are doing this for the sake of build optimization.
535
557
  */
536
558
  noDocker?: boolean;
559
+ /**
560
+ * Build options to pass to the docker build command.
561
+ */
562
+ dockerBuild?: FunctionDockerBuildProps;
537
563
  }
538
564
  /**
539
565
  * Used to configure Go bundling options
@@ -1,8 +1,8 @@
1
1
  import { Construct } from "constructs";
2
2
  import * as logs from "aws-cdk-lib/aws-logs";
3
3
  import * as acm from "aws-cdk-lib/aws-certificatemanager";
4
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
5
- import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
4
+ import * as apig from "aws-cdk-lib/aws-apigatewayv2";
5
+ import * as apigAuthorizers from "aws-cdk-lib/aws-apigatewayv2-authorizers";
6
6
  import { SSTConstruct } from "./Construct.js";
7
7
  import { Function as Fn, FunctionProps, FunctionInlineDefinition, FunctionDefinition } from "./Function.js";
8
8
  import { FunctionBindingProps } from "./util/functionBinding.js";
@@ -1,15 +1,15 @@
1
1
  import { Construct } from "constructs";
2
2
  import { CustomResource } from "aws-cdk-lib/core";
3
3
  import * as iam from "aws-cdk-lib/aws-iam";
4
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
5
- import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers-alpha";
4
+ import * as apig from "aws-cdk-lib/aws-apigatewayv2";
5
+ import * as apigAuthorizers from "aws-cdk-lib/aws-apigatewayv2-authorizers";
6
+ import { WebSocketLambdaIntegration } from "aws-cdk-lib/aws-apigatewayv2-integrations";
6
7
  import { Effect, Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
7
8
  import { Stack } from "./Stack.js";
8
9
  import { getFunctionRef, isCDKConstruct } from "./Construct.js";
9
10
  import { Function as Fn, } from "./Function.js";
10
11
  import * as apigV2Domain from "./util/apiGatewayV2Domain.js";
11
12
  import * as apigV2AccessLog from "./util/apiGatewayV2AccessLog.js";
12
- import { WebSocketLambdaIntegration } from "@aws-cdk/aws-apigatewayv2-integrations-alpha/lib/websocket/index.js";
13
13
  /////////////////////
14
14
  // Construct
15
15
  /////////////////////
@@ -1,4 +1,4 @@
1
- import { HttpIntegrationSubtype, HttpRouteIntegrationBindOptions, HttpRouteIntegrationConfig, HttpRouteIntegration, ParameterMapping, IntegrationCredentials } from "@aws-cdk/aws-apigatewayv2-alpha";
1
+ import { HttpIntegrationSubtype, HttpRouteIntegrationBindOptions, HttpRouteIntegrationConfig, HttpRouteIntegration, ParameterMapping, IntegrationCredentials } from "aws-cdk-lib/aws-apigatewayv2";
2
2
  /**
3
3
  * Properties to initialize a new `HttpProxyIntegration`.
4
4
  */
@@ -1,4 +1,4 @@
1
- import { HttpIntegrationType, HttpRouteIntegration, PayloadFormatVersion, } from "@aws-cdk/aws-apigatewayv2-alpha";
1
+ import { HttpIntegrationType, HttpRouteIntegration, PayloadFormatVersion, } from "aws-cdk-lib/aws-apigatewayv2";
2
2
  /**
3
3
  * The HTTP Proxy integration resource for HTTP API
4
4
  */
@@ -1,10 +1,10 @@
1
1
  import { Construct } from "constructs";
2
2
  import * as logs from "aws-cdk-lib/aws-logs";
3
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
3
+ import { WebSocketStage, HttpStage } from "aws-cdk-lib/aws-apigatewayv2";
4
4
  export interface AccessLogProps {
5
5
  format?: string;
6
6
  destinationArn?: string;
7
7
  retention?: Lowercase<keyof typeof logs.RetentionDays>;
8
8
  }
9
- export declare function buildAccessLogData(scope: Construct, accessLog: boolean | string | AccessLogProps | undefined, apiStage: apig.WebSocketStage | apig.HttpStage, isDefaultStage: boolean): logs.LogGroup | undefined;
9
+ export declare function buildAccessLogData(scope: Construct, accessLog: boolean | string | AccessLogProps | undefined, apiStage: WebSocketStage | HttpStage, isDefaultStage: boolean): logs.LogGroup | undefined;
10
10
  export declare function cleanupLogGroupName(str: string): string;
@@ -1,5 +1,5 @@
1
1
  import * as logs from "aws-cdk-lib/aws-logs";
2
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
2
+ import { WebSocketStage, } from "aws-cdk-lib/aws-apigatewayv2";
3
3
  const defaultHttpFields = [
4
4
  // request info
5
5
  `"requestTime":"$context.requestTime"`,
@@ -43,7 +43,7 @@ export function buildAccessLogData(scope, accessLog, apiStage, isDefaultStage) {
43
43
  if (accessLog === false) {
44
44
  return;
45
45
  }
46
- const isWebSocketApi = apiStage instanceof apig.WebSocketStage;
46
+ const isWebSocketApi = apiStage instanceof WebSocketStage;
47
47
  // note: Access log configuration is not supported by L2 constructs as of CDK v1.85.0. We
48
48
  // need to define it at L1 construct level.
49
49
  // create log group
@@ -1,4 +1,4 @@
1
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
1
+ import { CorsHttpMethod, CorsPreflightOptions } from "aws-cdk-lib/aws-apigatewayv2";
2
2
  import { Duration } from "./duration.js";
3
3
  export interface CorsProps {
4
4
  /**
@@ -33,7 +33,7 @@ export interface CorsProps {
33
33
  * allowMethods: ["GET", "POST"]
34
34
  * ```
35
35
  */
36
- allowMethods?: (keyof typeof apig.CorsHttpMethod)[];
36
+ allowMethods?: (keyof typeof CorsHttpMethod)[];
37
37
  /**
38
38
  * The collection of allowed origins.
39
39
  * @default Allow all origins.
@@ -64,4 +64,4 @@ export interface CorsProps {
64
64
  */
65
65
  maxAge?: Duration;
66
66
  }
67
- export declare function buildCorsConfig(cors?: boolean | CorsProps): apig.CorsPreflightOptions | undefined;
67
+ export declare function buildCorsConfig(cors?: boolean | CorsProps): CorsPreflightOptions | undefined;
@@ -1,4 +1,4 @@
1
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
1
+ import { CorsHttpMethod, } from "aws-cdk-lib/aws-apigatewayv2";
2
2
  import { toCdkDuration } from "./duration.js";
3
3
  export function buildCorsConfig(cors) {
4
4
  // Handle cors: false
@@ -13,7 +13,7 @@ export function buildCorsConfig(cors) {
13
13
  return {
14
14
  allowCredentials: cors.allowCredentials || false,
15
15
  allowHeaders: cors.allowHeaders || ["*"],
16
- allowMethods: (cors.allowMethods || ["ANY"]).map((method) => apig.CorsHttpMethod[method]),
16
+ allowMethods: (cors.allowMethods || ["ANY"]).map((method) => CorsHttpMethod[method]),
17
17
  allowOrigins: cors.allowOrigins || ["*"],
18
18
  exposeHeaders: cors.exposeHeaders,
19
19
  maxAge: cors.maxAge && toCdkDuration(cors.maxAge),
@@ -1,5 +1,5 @@
1
1
  import { Construct } from "constructs";
2
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
2
+ import { IDomainName } from "aws-cdk-lib/aws-apigatewayv2";
3
3
  import * as route53 from "aws-cdk-lib/aws-route53";
4
4
  import * as acm from "aws-cdk-lib/aws-certificatemanager";
5
5
  export interface CustomDomainProps {
@@ -25,7 +25,7 @@ export interface CustomDomainProps {
25
25
  /**
26
26
  * Override the internally created domain name
27
27
  */
28
- domainName?: apig.IDomainName;
28
+ domainName?: IDomainName;
29
29
  /**
30
30
  * Override the internally created hosted zone
31
31
  */
@@ -37,7 +37,7 @@ export interface CustomDomainProps {
37
37
  };
38
38
  }
39
39
  export interface CustomDomainData {
40
- readonly apigDomain: apig.IDomainName;
40
+ readonly apigDomain: IDomainName;
41
41
  readonly mappingKey?: string;
42
42
  readonly certificate?: acm.ICertificate;
43
43
  readonly isApigDomainCreated: boolean;
@@ -1,5 +1,5 @@
1
1
  import { Token } from "aws-cdk-lib/core";
2
- import * as apig from "@aws-cdk/aws-apigatewayv2-alpha";
2
+ import { DomainName } from "aws-cdk-lib/aws-apigatewayv2";
3
3
  import * as route53 from "aws-cdk-lib/aws-route53";
4
4
  import * as route53Targets from "aws-cdk-lib/aws-route53-targets";
5
5
  import * as acm from "aws-cdk-lib/aws-certificatemanager";
@@ -160,7 +160,7 @@ function createCertificate(scope, domainName, hostedZone) {
160
160
  });
161
161
  }
162
162
  function createApigDomain(scope, domainName, certificate) {
163
- return new apig.DomainName(scope, "DomainName", {
163
+ return new DomainName(scope, "DomainName", {
164
164
  domainName,
165
165
  certificate,
166
166
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.39.12",
4
+ "version": "2.40.0",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -25,12 +25,10 @@
25
25
  },
26
26
  "homepage": "https://sst.dev",
27
27
  "dependencies": {
28
- "@aws-cdk/aws-apigatewayv2-alpha": "^2.110.1-alpha.0",
29
- "@aws-cdk/aws-apigatewayv2-authorizers-alpha": "^2.110.1-alpha.0",
30
- "@aws-cdk/aws-apigatewayv2-integrations-alpha": "^2.110.1-alpha.0",
31
- "@aws-cdk/cloud-assembly-schema": "2.110.1",
32
- "@aws-cdk/cloudformation-diff": "2.110.1",
33
- "@aws-cdk/cx-api": "2.110.1",
28
+ "@aws-cdk/aws-lambda-python-alpha": "2.124.0-alpha.0",
29
+ "@aws-cdk/cloud-assembly-schema": "2.124.0",
30
+ "@aws-cdk/cloudformation-diff": "2.124.0",
31
+ "@aws-cdk/cx-api": "2.124.0",
34
32
  "@aws-crypto/sha256-js": "^5.2.0",
35
33
  "@aws-sdk/client-cloudformation": "^3.454.0",
36
34
  "@aws-sdk/client-ecs": "^3.454.0",
@@ -55,11 +53,11 @@
55
53
  "@smithy/signature-v4": "^2.0.16",
56
54
  "@trpc/server": "9.16.0",
57
55
  "adm-zip": "^0.5.10",
58
- "aws-cdk-lib": "2.110.1",
56
+ "aws-cdk-lib": "2.124.0",
59
57
  "aws-iot-device-sdk": "^2.2.13",
60
58
  "aws-sdk": "^2.1501.0",
61
59
  "builtin-modules": "3.2.0",
62
- "cdk-assets": "2.110.1",
60
+ "cdk-assets": "2.124.0",
63
61
  "chalk": "^5.2.0",
64
62
  "chokidar": "^3.5.3",
65
63
  "ci-info": "^3.7.0",
@@ -87,7 +85,7 @@
87
85
  "ora": "^6.1.2",
88
86
  "react": "^18.0.0",
89
87
  "remeda": "^1.3.0",
90
- "sst-aws-cdk": "2.110.1-1",
88
+ "sst-aws-cdk": "2.124.0",
91
89
  "tree-kill": "^1.2.2",
92
90
  "undici": "^5.12.0",
93
91
  "uuid": "^9.0.0",
@@ -120,7 +118,7 @@
120
118
  "@types/ws": "^8.5.3",
121
119
  "@types/yargs": "^17.0.13",
122
120
  "archiver": "^5.3.1",
123
- "astro-sst": "2.39.12",
121
+ "astro-sst": "2.40.0",
124
122
  "async": "^3.2.4",
125
123
  "tsx": "^3.12.1",
126
124
  "typescript": "^5.2.2",
package/project.js CHANGED
@@ -30,6 +30,8 @@ const CONFIG_EXTENSIONS = [
30
30
  ".config.js",
31
31
  ];
32
32
  export async function initProject(globals) {
33
+ // Suppress warnings about deprecated CDK props.
34
+ process.env.JSII_DEPRECATED = "quiet";
33
35
  // Logger.debug("initing project");
34
36
  const root = globals.root || (await findRoot());
35
37
  const out = path.join(root, ".sst");
@@ -96,6 +96,7 @@ export const usePythonHandler = () => {
96
96
  architecture: input.props.architecture,
97
97
  outputPathSuffix: ".",
98
98
  out: input.out,
99
+ dockerBuild: input.props.python?.dockerBuild,
99
100
  });
100
101
  }
101
102
  await fs.cp(src, input.out, {
@@ -1,5 +1,5 @@
1
1
  import { Runtime } from "aws-cdk-lib/aws-lambda";
2
- import { FunctionProps } from "../../constructs/Function.js";
2
+ import { FunctionDockerBuildProps, FunctionProps } from "../../constructs/Function.js";
3
3
  import { AssetHashType } from "aws-cdk-lib/core";
4
4
  /**
5
5
  * Dependency files to exclude from the asset hash.
@@ -68,6 +68,7 @@ export interface BundlingOptions {
68
68
  */
69
69
  readonly assetHash?: string;
70
70
  readonly installCommands?: string[];
71
+ readonly dockerBuild?: FunctionDockerBuildProps;
71
72
  }
72
73
  /**
73
74
  * Produce bundled Lambda asset code
@@ -40,6 +40,8 @@ export function bundle(options) {
40
40
  (architecture == "arm_64" ? ":latest-arm64" : ""),
41
41
  },
42
42
  file: dockerfile,
43
+ cacheFrom: options.dockerBuild?.cacheFrom,
44
+ cacheTo: options.dockerBuild?.cacheTo,
43
45
  });
44
46
  const outputPath = path.join(options.out, outputPathSuffix);
45
47
  // Copy dependencies to the bundle if applicable.
package/stacks/diff.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export async function diff(stack, oldTemplate) {
2
- const { diffTemplate, formatDifferences, TemplateDiff } = await import("@aws-cdk/cloudformation-diff");
2
+ const { fullDiff, formatDifferences, TemplateDiff } = await import("@aws-cdk/cloudformation-diff");
3
3
  // Generate diff
4
- const diff = diffTemplate(oldTemplate, stack.template);
4
+ const diff = fullDiff(oldTemplate, stack.template);
5
5
  if (diff.isEmpty) {
6
6
  return { count: 0 };
7
7
  }
@@ -153441,8 +153441,8 @@ glob.glob = glob;
153441
153441
  var import_adm_zip2 = __toESM(require_adm_zip(), 1);
153442
153442
  var import_client_s33 = __toESM(require_dist_cjs70(), 1);
153443
153443
  var import_client_lambda2 = __toESM(require_dist_cjs82(), 1);
153444
- var s33 = new import_client_s33.S3Client({ logger: sdkLogger });
153445
- var lambda2 = new import_client_lambda2.LambdaClient({ logger: sdkLogger });
153444
+ var s33 = useAWSClient(import_client_s33.S3Client);
153445
+ var lambda2 = useAWSClient(import_client_lambda2.LambdaClient);
153446
153446
  async function S3Uploader(cfnRequest) {
153447
153447
  switch (cfnRequest.RequestType) {
153448
153448
  case "Create":