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.
package/constructs/SsrSite.d.ts
CHANGED
|
@@ -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
|
|
233
|
-
private
|
|
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;
|
package/constructs/SsrSite.js
CHANGED
|
@@ -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.
|
|
98
|
-
: this.
|
|
99
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
@@ -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
|
|
3
|
-
`);await d("FAILED",
|
|
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};
|