sst 2.0.0-rc.19 → 2.0.0-rc.20

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.
@@ -229,8 +229,10 @@ export declare class SsrSite extends Construct implements SSTConstruct {
229
229
  private buildApp;
230
230
  protected validateBuildOutput(): void;
231
231
  private runBuild;
232
- private createStaticsS3Assets;
233
- private createStaticsS3AssetsWithStub;
232
+ private createS3Assets;
233
+ private createS3AssetFileOptions;
234
+ private createS3AssetsForStub;
235
+ private createS3AssetFileOptionsForStub;
234
236
  private createS3Bucket;
235
237
  private createS3Deployment;
236
238
  protected createFunctionForRegional(): lambda.Function;
@@ -94,9 +94,12 @@ export class SsrSite extends Construct {
94
94
  this.cdk.certificate = this.createCertificate();
95
95
  // Create S3 Deployment
96
96
  const assets = this.isPlaceholder
97
- ? this.createStaticsS3AssetsWithStub()
98
- : this.createStaticsS3Assets();
99
- const s3deployCR = this.createS3Deployment(assets);
97
+ ? this.createS3AssetsForStub()
98
+ : this.createS3Assets();
99
+ const assetFileOptions = this.isPlaceholder
100
+ ? this.createS3AssetFileOptionsForStub()
101
+ : this.createS3AssetFileOptions();
102
+ const s3deployCR = this.createS3Deployment(assets, assetFileOptions);
100
103
  // Create CloudFront
101
104
  this.validateCloudFrontDistributionSettings();
102
105
  if (this.props.edge) {
@@ -272,7 +275,7 @@ export class SsrSite extends Construct {
272
275
  /////////////////////
273
276
  // Bundle S3 Assets
274
277
  /////////////////////
275
- createStaticsS3Assets() {
278
+ createS3Assets() {
276
279
  // Create temp folder, clean up if exists
277
280
  const zipOutDir = path.resolve(path.join(this.sstBuildDir, `Site-${this.node.id}-${this.node.addr}`));
278
281
  fs.rmSync(zipOutDir, { recursive: true, force: true });
@@ -308,13 +311,49 @@ export class SsrSite extends Construct {
308
311
  }
309
312
  return assets;
310
313
  }
311
- createStaticsS3AssetsWithStub() {
314
+ createS3AssetFileOptions() {
315
+ // Build file options
316
+ const fileOptions = [];
317
+ const clientPath = path.join(this.props.path, this.buildConfig.clientBuildOutputDir);
318
+ for (const item of fs.readdirSync(clientPath)) {
319
+ // Versioned files will be cached for 1 year (immutable) both at
320
+ // CDN and browser level.
321
+ if (item === this.buildConfig.clientBuildVersionedSubDir) {
322
+ fileOptions.push({
323
+ exclude: "*",
324
+ include: `${this.buildConfig.clientBuildVersionedSubDir}/*`,
325
+ cacheControl: "public,max-age=31536000,immutable",
326
+ });
327
+ }
328
+ // Un-versioned files will be cached for 1 year at the CDN level.
329
+ // But not at the browser level. CDN cache will be invalidated on deploy.
330
+ else {
331
+ const itemPath = path.join(clientPath, item);
332
+ fileOptions.push({
333
+ exclude: "*",
334
+ include: fs.statSync(itemPath).isDirectory()
335
+ ? `${item}/*`
336
+ : `${item}`,
337
+ cacheControl: "public,max-age=0,s-maxage=31536000,must-revalidate",
338
+ });
339
+ }
340
+ }
341
+ return fileOptions;
342
+ }
343
+ createS3AssetsForStub() {
312
344
  return [
313
345
  new s3Assets.Asset(this, "Asset", {
314
346
  path: this.buildConfig.siteStub,
315
347
  }),
316
348
  ];
317
349
  }
350
+ createS3AssetFileOptionsForStub() {
351
+ return [{
352
+ exclude: "*",
353
+ include: "*",
354
+ cacheControl: "public,max-age=0,s-maxage=31536000,must-revalidate",
355
+ }];
356
+ }
318
357
  createS3Bucket() {
319
358
  const { cdk } = this.props;
320
359
  // cdk.bucket is an imported construct
@@ -332,7 +371,7 @@ export class SsrSite extends Construct {
332
371
  });
333
372
  }
334
373
  }
335
- createS3Deployment(assets) {
374
+ createS3Deployment(assets, fileOptions) {
336
375
  // Create a Lambda function that will be doing the uploading
337
376
  const uploader = new lambda.Function(this, "S3Uploader", {
338
377
  code: lambda.Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
@@ -358,32 +397,6 @@ export class SsrSite extends Construct {
358
397
  });
359
398
  this.cdk.bucket.grantReadWrite(handler);
360
399
  uploader.grantInvoke(handler);
361
- // Build file options
362
- const fileOptions = [];
363
- const clientPath = path.join(this.props.path, this.buildConfig.clientBuildOutputDir);
364
- for (const item of fs.readdirSync(clientPath)) {
365
- // Versioned files will be cached for 1 year (immutable) both at
366
- // CDN and browser level.
367
- if (item === this.buildConfig.clientBuildVersionedSubDir) {
368
- fileOptions.push({
369
- exclude: "*",
370
- include: `${this.buildConfig.clientBuildVersionedSubDir}/*`,
371
- cacheControl: "public,max-age=31536000,immutable",
372
- });
373
- }
374
- // Un-versioned files will be cached for 1 year at the CDN level.
375
- // But not at the browser level. CDN cache will be invalidated on deploy.
376
- else {
377
- const itemPath = path.join(clientPath, item);
378
- fileOptions.push({
379
- exclude: "*",
380
- include: fs.statSync(itemPath).isDirectory()
381
- ? `${item}/*`
382
- : `${item}`,
383
- cacheControl: "public,max-age=0,s-maxage=31536000,must-revalidate",
384
- });
385
- }
386
- }
387
400
  // Create custom resource
388
401
  return new CustomResource(this, "S3Deployment", {
389
402
  serviceToken: handler.functionArn,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sst",
3
- "version": "2.0.0-rc.19",
3
+ "version": "2.0.0-rc.20",
4
4
  "bin": {
5
5
  "sst": "cli/sst.js"
6
6
  },
@@ -106469,7 +106469,7 @@ async function ssmPutParameter(params) {
106469
106469
  }
106470
106470
  __name(ssmPutParameter, "ssmPutParameter");
106471
106471
  function isRetryableException(e) {
106472
- return e.code === "ThrottlingException" && e.message === "Rate exceeded" || e.code === "Throttling" && e.message === "Rate exceeded" || e.code === "TooManyRequestsException" && e.message === "Too Many Requests" || e.code === "TooManyUpdates" || e.code === "OperationAbortedException" || e.code === "TimeoutError" || e.code === "NetworkingError";
106472
+ return e.code === "ThrottlingException" && e.message === "Rate exceeded" || e.code === "Throttling" && e.message === "Rate exceeded" || e.code === "TooManyRequestsException" && e.message === "Too Many Requests" || e.code === "TooManyUpdates" || e.code === "OperationAbortedException" || e.code === "TimeoutError" || e.code === "NetworkingError" || e.code === "ResourceConflictException";
106473
106473
  }
106474
106474
  __name(isRetryableException, "isRetryableException");
106475
106475
 
@@ -1,3 +1,3 @@
1
1
  import { createRequire as topLevelCreateRequire } from 'module';const require = topLevelCreateRequire(import.meta.url);
2
- var h=Object.defineProperty;var s=(o,e)=>h(o,"name",{value:e,configurable:!0});import{createRequire as E}from"module";function t(o,...e){console.log("[provider-framework]",o,...e.map(n=>typeof n=="object"?JSON.stringify(n,void 0,2):n))}s(t,"log");import C from"https";import R from"url";var y="AWSCDK::CustomResourceProviderFramework::CREATE_FAILED",f="AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID";async function d(o,e,n={}){let r={Status:o,Reason:n.reason||o,StackId:e.StackId,RequestId:e.RequestId,PhysicalResourceId:e.PhysicalResourceId||f,LogicalResourceId:e.LogicalResourceId,NoEcho:n.noEcho,Data:e.Data};t("submit response to cloudformation",r);let a=JSON.stringify(r),i=R.parse(e.ResponseURL);await S({hostname:i.hostname,path:i.path,method:"PUT",headers:{"content-type":"","content-length":a.length}},a)}s(d,"submitResponse");function m(o){return async e=>{if(e.RequestType==="Delete"&&e.PhysicalResourceId===y){t("ignoring DELETE event caused by a failed CREATE event"),await d("SUCCESS",e);return}try{await o(e)}catch(n){if(t(n),n instanceof u)throw t("retry requested by handler"),n;e.PhysicalResourceId||(e.RequestType==="Create"?(t("CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored"),e.PhysicalResourceId=y):t(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(e)}`));let r=[n.message,`Logs: https://${process.env.AWS_REGION}.console.aws.amazon.com/cloudwatch/home?region=${process.env.AWS_REGION}#logsV2:log-groups/log-group/${encodeURIComponent(process.env.AWS_LAMBDA_LOG_GROUP_NAME)}/log-events/${encodeURIComponent(process.env.AWS_LAMBDA_LOG_STREAM_NAME)}`].join(`
3
- `);await d("FAILED",e,{reason:r})}}}s(m,"safeHandler");var u=class extends Error{};s(u,"Retry");async function S(o,e){return new Promise((n,r)=>{try{let a=C.request(o,n);a.on("error",r),a.write(e),a.end()}catch(a){r(a)}})}s(S,"httpRequest");var F=E(import.meta.url),p=F("aws-sdk");p.config.logger=console;var w=new p.S3({region:"us-east-1"}),l=new p.Lambda({region:"us-east-1"}),K=m(async o=>{t("onEventHandler",o);let e=o.RequestType==="Create"?I(o.ResourceProperties.FunctionNamePrefix):o.PhysicalResourceId.split(":").pop(),n,r,a=o.ResourceProperties.FunctionBucket,i=o.ResourceProperties.FunctionParams;switch(o.RequestType){case"Create":{await g(a,i);let c=await P(e,i);n=c.FunctionArn,r={FunctionArn:c.FunctionArn};break}case"Update":{let c=o.OldResourceProperties.FunctionParams;b(i,c)&&await L(e,i),k(i,c)&&(await g(a,i),await _(e,i)),n=o.PhysicalResourceId,r={FunctionArn:o.PhysicalResourceId};break}case"Delete":{await N(e);break}default:throw new Error("Unsupported request type")}return d("SUCCESS",{...o,PhysicalResourceId:n,Data:r})});function I(o){let r="abcdefghijklmnopqrstuvwxyz",a=r.length,i=`${o.toLowerCase().slice(0,64-20-1)}-`;for(let c=0;c<20;c++)i+=r.charAt(Math.floor(Math.random()*a));return i}s(I,"generateFunctionName");async function g(o,e){t("copyAsset() called with params",o,e),t("copy");let n=await w.copyObject({Bucket:o,CopySource:`/${e.Code.S3Bucket}/${e.Code.S3Key}`,Key:e.Code.S3Key}).promise();t("response",n),e.Code.S3Bucket=o}s(g,"copyAsset");async function P(o,e){t("createFunction() called with params",e);let n=await l.createFunction({...e,FunctionName:o}).promise();return t("response",n),{FunctionArn:n.FunctionArn}}s(P,"createFunction");async function L(o,e){t("updateFunctionConfiguration() called with params",e);let n=await l.updateFunctionConfiguration({FunctionName:o,...e,Code:void 0}).promise();t("response",n)}s(L,"updateFunctionConfiguration");async function _(o,e){t("updateFunctionCode() called with params",e);let n=await l.updateFunctionCode({FunctionName:o,Publish:!1,...e.Code}).promise();t("response",n)}s(_,"updateFunctionCode");async function N(o){t("deleteFunction() called with functionName",o);let e=await l.deleteFunction({FunctionName:o}).promise();t("response",e)}s(N,"deleteFunction");function b(o,e){return Object.keys(o).length!==Object.keys(o).length||["Description","Handler","Runtime","MemorySize","Timeout","Role"].some(n=>o[n]!==e[n])}s(b,"isConfigurationChanged");function k(o,e){return o.Code.S3Bucket!==e.Code.S3Bucket||o.Code.S3Key!==e.Code.S3Key}s(k,"isCodeChanged");export{K as handler};
2
+ var E=Object.defineProperty;var r=(e,o)=>E(e,"name",{value:o,configurable:!0});import{createRequire as I}from"module";function n(e,...o){console.log("[provider-framework]",e,...o.map(t=>typeof t=="object"?JSON.stringify(t,void 0,2):t))}r(n,"log");import f from"https";import S from"url";var y="AWSCDK::CustomResourceProviderFramework::CREATE_FAILED",w="AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID";async function d(e,o,t={}){let s={Status:e,Reason:t.reason||e,StackId:o.StackId,RequestId:o.RequestId,PhysicalResourceId:o.PhysicalResourceId||w,LogicalResourceId:o.LogicalResourceId,NoEcho:t.noEcho,Data:o.Data};n("submit response to cloudformation",s);let a=JSON.stringify(s),i=S.parse(o.ResponseURL);await A({hostname:i.hostname,path:i.path,method:"PUT",headers:{"content-type":"","content-length":a.length}},a)}r(d,"submitResponse");function g(e){return async o=>{if(o.RequestType==="Delete"&&o.PhysicalResourceId===y){n("ignoring DELETE event caused by a failed CREATE event"),await d("SUCCESS",o);return}try{await e(o)}catch(t){if(n(t),t instanceof u)throw n("retry requested by handler"),t;o.PhysicalResourceId||(o.RequestType==="Create"?(n("CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored"),o.PhysicalResourceId=y):n(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(o)}`));let s=[t.message,`Logs: https://${process.env.AWS_REGION}.console.aws.amazon.com/cloudwatch/home?region=${process.env.AWS_REGION}#logsV2:log-groups/log-group/${encodeURIComponent(process.env.AWS_LAMBDA_LOG_GROUP_NAME)}/log-events/${encodeURIComponent(process.env.AWS_LAMBDA_LOG_STREAM_NAME)}`].join(`
3
+ `);await d("FAILED",o,{reason:s})}}}r(g,"safeHandler");var u=class extends Error{};r(u,"Retry");async function A(e,o){return new Promise((t,s)=>{try{let a=f.request(e,t);a.on("error",s),a.write(o),a.end()}catch(a){s(a)}})}r(A,"httpRequest");var P=I(import.meta.url),p=P("aws-sdk");p.config.logger=console;var L=new p.S3({region:"us-east-1"}),l=new p.Lambda({region:"us-east-1"}),K=g(async e=>{n("onEventHandler",e);let o=e.RequestType==="Create"?_(e.ResourceProperties.FunctionNamePrefix):e.PhysicalResourceId.split(":").pop(),t,s,a=e.ResourceProperties.FunctionBucket,i=e.ResourceProperties.FunctionParams;switch(e.RequestType){case"Create":{await h(a,i);let c=await b(o,i);t=c.FunctionArn,s={FunctionArn:c.FunctionArn};break}case"Update":{let c=e.OldResourceProperties.FunctionParams;k(i,c)&&await m(o,i),x(i,c)&&(await h(a,i),await R(o,i)),t=e.PhysicalResourceId,s={FunctionArn:e.PhysicalResourceId};break}case"Delete":{await T(o);break}default:throw new Error("Unsupported request type")}return d("SUCCESS",{...e,PhysicalResourceId:t,Data:s})});function _(e){let s="abcdefghijklmnopqrstuvwxyz",a=s.length,i=`${e.toLowerCase().slice(0,64-20-1)}-`;for(let c=0;c<20;c++)i+=s.charAt(Math.floor(Math.random()*a));return i}r(_,"generateFunctionName");async function h(e,o){n("copyAsset() called with params",e,o),n("copy");let t=await L.copyObject({Bucket:e,CopySource:`/${o.Code.S3Bucket}/${o.Code.S3Key}`,Key:o.Code.S3Key}).promise();n("response",t),o.Code.S3Bucket=e}r(h,"copyAsset");async function b(e,o){n("createFunction() called with params",o);let t=await l.createFunction({...o,FunctionName:e}).promise();return n("response",t),{FunctionArn:t.FunctionArn}}r(b,"createFunction");async function m(e,o){n("updateFunctionConfiguration() called with params",o);try{let t=await l.updateFunctionConfiguration({FunctionName:e,...o,Code:void 0}).promise();n("response",t);return}catch(t){if(C(t)){await m(e,o);return}throw t}}r(m,"updateFunctionConfiguration");async function R(e,o){n("updateFunctionCode() called with params",o);try{let t=await l.updateFunctionCode({FunctionName:e,Publish:!1,...o.Code}).promise();n("response",t);return}catch(t){if(C(t)){await R(e,o);return}throw t}}r(R,"updateFunctionCode");async function T(e){n("deleteFunction() called with functionName",e);let o=await l.deleteFunction({FunctionName:e}).promise();n("response",o)}r(T,"deleteFunction");function k(e,o){return Object.keys(e).length!==Object.keys(e).length||["Description","Handler","Runtime","MemorySize","Timeout","Role"].some(t=>e[t]!==o[t])}r(k,"isConfigurationChanged");function x(e,o){return e.Code.S3Bucket!==o.Code.S3Bucket||e.Code.S3Key!==o.Code.S3Key}r(x,"isCodeChanged");function C(e){return e.code==="ThrottlingException"&&e.message==="Rate exceeded"||e.code==="Throttling"&&e.message==="Rate exceeded"||e.code==="TooManyRequestsException"&&e.message==="Too Many Requests"||e.code==="TooManyUpdates"||e.code==="OperationAbortedException"||e.code==="TimeoutError"||e.code==="NetworkingError"||e.code==="ResourceConflictException"}r(C,"isRetryableException");export{K as handler};