sst 2.30.3 → 2.31.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.
- package/constructs/BaseSite.d.ts +2 -13
- package/constructs/NextjsSite.d.ts +144 -18
- package/constructs/NextjsSite.js +120 -28
- package/constructs/RDS.js +2 -2
- package/constructs/SsrSite.d.ts +19 -73
- package/constructs/SsrSite.js +93 -205
- package/constructs/StaticSite.d.ts +46 -33
- package/constructs/StaticSite.js +57 -74
- package/constructs/deprecated/NextjsSite.js +57 -71
- package/package.json +5 -4
- package/support/base-site-archiver.mjs +18 -18
- package/support/custom-resources/index.mjs +8426 -383
- package/support/base-site-custom-resource/s3-handler.py +0 -195
- package/support/base-site-custom-resource/s3-upload.py +0 -89
package/constructs/SsrSite.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import url from "url";
|
|
3
3
|
import fs from "fs";
|
|
4
|
-
import
|
|
4
|
+
import { globSync } from "glob";
|
|
5
5
|
import crypto from "crypto";
|
|
6
6
|
import spawn from "cross-spawn";
|
|
7
7
|
import { execSync } from "child_process";
|
|
@@ -12,7 +12,6 @@ import { Effect, Role, Policy, PolicyStatement, AccountPrincipal, ServicePrincip
|
|
|
12
12
|
import { Function as CdkFunction, Code, Runtime, FunctionUrlAuthType, InvokeMode, } from "aws-cdk-lib/aws-lambda";
|
|
13
13
|
import { Asset } from "aws-cdk-lib/aws-s3-assets";
|
|
14
14
|
import { ViewerProtocolPolicy, AllowedMethods, CachedMethods, LambdaEdgeEventType, CachePolicy, CacheQueryStringBehavior, CacheHeaderBehavior, CacheCookieBehavior, OriginRequestPolicy, Function as CfFunction, FunctionCode as CfFunctionCode, FunctionEventType as CfFunctionEventType, } from "aws-cdk-lib/aws-cloudfront";
|
|
15
|
-
import { AwsCliLayer } from "aws-cdk-lib/lambda-layer-awscli";
|
|
16
15
|
import { S3Origin, HttpOrigin, OriginGroup, } from "aws-cdk-lib/aws-cloudfront-origins";
|
|
17
16
|
import { Rule, Schedule } from "aws-cdk-lib/aws-events";
|
|
18
17
|
import { LambdaFunction } from "aws-cdk-lib/aws-events-targets";
|
|
@@ -67,10 +66,11 @@ export class SsrSite extends Construct {
|
|
|
67
66
|
const app = scope.node.root;
|
|
68
67
|
const stack = Stack.of(this);
|
|
69
68
|
const self = this;
|
|
70
|
-
const { path: sitePath, typesPath, buildCommand, runtime, timeout, memorySize, edge, regional, dev,
|
|
69
|
+
const { path: sitePath, typesPath, buildCommand, runtime, timeout, memorySize, edge, regional, dev, assets, nodejs, permissions, environment, bind, customDomain, waitForInvalidation, warm, cdk, } = props;
|
|
71
70
|
this.doNotDeploy = !stack.isActive || (app.mode === "dev" && !dev?.deploy);
|
|
72
71
|
validateSiteExists();
|
|
73
72
|
validateTimeout();
|
|
73
|
+
validateDeprecatedFileOptions();
|
|
74
74
|
writeTypesFile(typesPath);
|
|
75
75
|
useSites().add(stack.stackName, id, this.constructor.name, props);
|
|
76
76
|
if (this.doNotDeploy) {
|
|
@@ -82,7 +82,6 @@ export class SsrSite extends Construct {
|
|
|
82
82
|
}
|
|
83
83
|
let s3DeployCRs = [];
|
|
84
84
|
let ssrFunctions = [];
|
|
85
|
-
let singletonAwsCliLayer;
|
|
86
85
|
let singletonUrlSigner;
|
|
87
86
|
let singletonCachePolicy;
|
|
88
87
|
let singletonOriginRequestPolicy;
|
|
@@ -110,7 +109,7 @@ export class SsrSite extends Construct {
|
|
|
110
109
|
app.registerTypes(this);
|
|
111
110
|
function validateSiteExists() {
|
|
112
111
|
if (!fs.existsSync(sitePath)) {
|
|
113
|
-
throw new
|
|
112
|
+
throw new VisibleError(`No site found at "${path.resolve(sitePath)}"`);
|
|
114
113
|
}
|
|
115
114
|
}
|
|
116
115
|
function validateTimeout() {
|
|
@@ -119,9 +118,15 @@ export class SsrSite extends Construct {
|
|
|
119
118
|
: toCdkDuration(timeout).toSeconds();
|
|
120
119
|
const limit = edge ? 30 : 180;
|
|
121
120
|
if (num > limit) {
|
|
122
|
-
throw new
|
|
123
|
-
? `
|
|
124
|
-
: `
|
|
121
|
+
throw new VisibleError(edge
|
|
122
|
+
? `In the "${id}" construct, timeout must be less than or equal to 30 seconds when the "edge" flag is enabled.`
|
|
123
|
+
: `In the "${id}" construct, timeout must be less than or equal to 180 seconds.`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function validateDeprecatedFileOptions() {
|
|
127
|
+
// @ts-expect-error
|
|
128
|
+
if (props.fileOptions) {
|
|
129
|
+
throw new VisibleError(`In the "${id}" construct, the "fileOptions" property has been replaced by "assets.fileOptions". More details on upgrading - https://docs.sst.dev/upgrade-guide#upgrade-to-v2310`);
|
|
125
130
|
}
|
|
126
131
|
}
|
|
127
132
|
function writeTypesFile(typesPath) {
|
|
@@ -411,8 +416,7 @@ function handler(event) {
|
|
|
411
416
|
originPath: "/" + (props.originPath ?? ""),
|
|
412
417
|
});
|
|
413
418
|
const assets = createS3OriginAssets(props.copy);
|
|
414
|
-
const
|
|
415
|
-
const s3deployCR = createS3OriginDeployment(assets, assetFileOptions);
|
|
419
|
+
const s3deployCR = createS3OriginDeployment(props.copy, assets);
|
|
416
420
|
s3DeployCRs.push(s3deployCR);
|
|
417
421
|
return s3Origin;
|
|
418
422
|
}
|
|
@@ -562,185 +566,44 @@ function handler(event) {
|
|
|
562
566
|
}
|
|
563
567
|
return assets;
|
|
564
568
|
}
|
|
565
|
-
function
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
css: { mime: "text/css", isText: true },
|
|
585
|
-
js: { mime: "text/javascript", isText: true },
|
|
586
|
-
mjs: { mime: "text/javascript", isText: true },
|
|
587
|
-
apng: { mime: "image/apng", isText: false },
|
|
588
|
-
avif: { mime: "image/avif", isText: false },
|
|
589
|
-
gif: { mime: "image/gif", isText: false },
|
|
590
|
-
jpeg: { mime: "image/jpeg", isText: false },
|
|
591
|
-
jpg: { mime: "image/jpeg", isText: false },
|
|
592
|
-
png: { mime: "image/png", isText: false },
|
|
593
|
-
svg: { mime: "image/svg+xml", isText: true },
|
|
594
|
-
bmp: { mime: "image/bmp", isText: false },
|
|
595
|
-
tiff: { mime: "image/tiff", isText: false },
|
|
596
|
-
webp: { mime: "image/webp", isText: false },
|
|
597
|
-
ico: { mime: "image/vnd.microsoft.icon", isText: false },
|
|
598
|
-
eot: { mime: "application/vnd.ms-fontobject", isText: false },
|
|
599
|
-
ttf: { mime: "font/ttf", isText: false },
|
|
600
|
-
otf: { mime: "font/otf", isText: false },
|
|
601
|
-
woff: { mime: "font/woff", isText: false },
|
|
602
|
-
woff2: { mime: "font/woff2", isText: false },
|
|
603
|
-
json: { mime: "application/json", isText: true },
|
|
604
|
-
jsonld: { mime: "application/ld+json", isText: true },
|
|
605
|
-
xml: { mime: "application/xml", isText: true },
|
|
606
|
-
pdf: { mime: "application/pdf", isText: false },
|
|
607
|
-
zip: { mime: "application/zip", isText: false },
|
|
608
|
-
};
|
|
609
|
-
copy.forEach((files) => {
|
|
610
|
-
if (!files.cached)
|
|
611
|
-
return;
|
|
612
|
-
for (const [extension, contentType] of Object.entries(commonWebFileExtensions)) {
|
|
613
|
-
// Create a file option for: common extension + unversioned files
|
|
614
|
-
fileOptions.push({
|
|
615
|
-
filters: [
|
|
616
|
-
{ exclude: "*" },
|
|
617
|
-
{ include: `${path.posix.join(files.to, "*")}.${extension}` },
|
|
618
|
-
...(files.versionedSubDir
|
|
619
|
-
? [
|
|
620
|
-
{
|
|
621
|
-
exclude: path.posix.join(files.to, files.versionedSubDir, "*"),
|
|
622
|
-
},
|
|
623
|
-
]
|
|
624
|
-
: []),
|
|
625
|
-
],
|
|
626
|
-
cacheControl: nonVersionedFilesCacheHeader,
|
|
627
|
-
contentType: `${contentType.mime}${contentType.isText && textEncoding !== "none"
|
|
628
|
-
? `;charset=${textEncoding}`
|
|
629
|
-
: ""}`,
|
|
630
|
-
});
|
|
631
|
-
// Create a file option for: common extension + versioned files
|
|
632
|
-
if (files.versionedSubDir) {
|
|
633
|
-
fileOptions.push({
|
|
634
|
-
filters: [
|
|
635
|
-
{ exclude: "*" },
|
|
636
|
-
{
|
|
637
|
-
include: path.posix.join(files.to, files.versionedSubDir, `*.${extension}`),
|
|
638
|
-
},
|
|
639
|
-
],
|
|
640
|
-
cacheControl: versionedFilesCacheHeader,
|
|
641
|
-
contentType: `${contentType.mime}${contentType.isText && textEncoding !== "none"
|
|
642
|
-
? `;charset=${textEncoding}`
|
|
643
|
-
: ""}`,
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
// Create a file option for: other extensions + unversioned files
|
|
648
|
-
fileOptions.push({
|
|
649
|
-
filters: [
|
|
650
|
-
{ include: "*" },
|
|
651
|
-
...(files.versionedSubDir
|
|
652
|
-
? [
|
|
653
|
-
{
|
|
654
|
-
exclude: path.posix.join(files.to, files.versionedSubDir, "*"),
|
|
655
|
-
},
|
|
656
|
-
]
|
|
657
|
-
: []),
|
|
658
|
-
...Object.entries(commonWebFileExtensions).map(([ext]) => ({
|
|
659
|
-
exclude: `*.${ext}`,
|
|
660
|
-
})),
|
|
661
|
-
],
|
|
662
|
-
cacheControl: nonVersionedFilesCacheHeader,
|
|
663
|
-
});
|
|
664
|
-
// Create a file option for: other extensions + versioned files
|
|
665
|
-
if (files.versionedSubDir) {
|
|
666
|
-
fileOptions.push({
|
|
667
|
-
filters: [
|
|
668
|
-
{
|
|
669
|
-
include: path.posix.join(files.to, files.versionedSubDir, "*"),
|
|
670
|
-
},
|
|
671
|
-
...Object.entries(commonWebFileExtensions).map(([ext]) => ({
|
|
672
|
-
exclude: `*.${ext}`,
|
|
673
|
-
})),
|
|
674
|
-
],
|
|
675
|
-
cacheControl: versionedFilesCacheHeader,
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
});
|
|
679
|
-
if (cache?.fileOptions) {
|
|
680
|
-
fileOptions.push(...cache.fileOptions);
|
|
681
|
-
}
|
|
682
|
-
return fileOptions;
|
|
683
|
-
}
|
|
684
|
-
function createS3OriginDeployment(assets, fileOptions) {
|
|
685
|
-
// Create a Lambda function that will be doing the uploading
|
|
686
|
-
const uploader = new CdkFunction(self, "S3Uploader", {
|
|
687
|
-
code: Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
688
|
-
layers: [useAwsCliLayer()],
|
|
689
|
-
runtime: Runtime.PYTHON_3_11,
|
|
690
|
-
handler: "s3-upload.handler",
|
|
691
|
-
timeout: CdkDuration.minutes(15),
|
|
692
|
-
memorySize: 1024,
|
|
693
|
-
});
|
|
694
|
-
bucket.grantReadWrite(uploader);
|
|
695
|
-
assets.forEach((asset) => asset.grantRead(uploader));
|
|
696
|
-
// Create the custom resource function
|
|
697
|
-
const handler = new CdkFunction(self, "S3Handler", {
|
|
698
|
-
code: Code.fromAsset(path.join(__dirname, "../support/base-site-custom-resource")),
|
|
699
|
-
layers: [useAwsCliLayer()],
|
|
700
|
-
runtime: Runtime.PYTHON_3_11,
|
|
701
|
-
handler: "s3-handler.handler",
|
|
702
|
-
timeout: CdkDuration.minutes(15),
|
|
703
|
-
memorySize: 1024,
|
|
704
|
-
environment: {
|
|
705
|
-
UPLOADER_FUNCTION_NAME: uploader.functionName,
|
|
706
|
-
},
|
|
569
|
+
function createS3OriginDeployment(copy, s3Assets) {
|
|
570
|
+
const policy = new Policy(self, "S3UploaderPolicy", {
|
|
571
|
+
statements: [
|
|
572
|
+
new PolicyStatement({
|
|
573
|
+
effect: Effect.ALLOW,
|
|
574
|
+
actions: ["lambda:InvokeFunction"],
|
|
575
|
+
resources: [stack.customResourceHandler.functionArn],
|
|
576
|
+
}),
|
|
577
|
+
new PolicyStatement({
|
|
578
|
+
effect: Effect.ALLOW,
|
|
579
|
+
actions: ["s3:ListBucket", "s3:PutObject", "s3:DeleteObject"],
|
|
580
|
+
resources: [bucket.bucketArn, `${bucket.bucketArn}/*`],
|
|
581
|
+
}),
|
|
582
|
+
new PolicyStatement({
|
|
583
|
+
effect: Effect.ALLOW,
|
|
584
|
+
actions: ["s3:GetObject"],
|
|
585
|
+
resources: [`${s3Assets[0].bucket.bucketArn}/*`],
|
|
586
|
+
}),
|
|
587
|
+
],
|
|
707
588
|
});
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
serviceToken: handler.functionArn,
|
|
713
|
-
resourceType: "Custom::SSTBucketDeployment",
|
|
589
|
+
stack.customResourceHandler.role?.attachInlinePolicy(policy);
|
|
590
|
+
const resource = new CustomResource(self, "S3Uploader", {
|
|
591
|
+
serviceToken: stack.customResourceHandler.functionArn,
|
|
592
|
+
resourceType: "Custom::S3Uploader",
|
|
714
593
|
properties: {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
594
|
+
sources: s3Assets.map((s3Asset) => ({
|
|
595
|
+
bucketName: s3Asset.s3BucketName,
|
|
596
|
+
objectKey: s3Asset.s3ObjectKey,
|
|
718
597
|
})),
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
...(typeof exclude === "string" ? [exclude] : exclude ?? [])
|
|
725
|
-
.map((entry) => ["--exclude", entry])
|
|
726
|
-
.flat(2),
|
|
727
|
-
...(typeof include === "string" ? [include] : include ?? [])
|
|
728
|
-
.map((entry) => ["--include", entry])
|
|
729
|
-
.flat(2),
|
|
730
|
-
...(filters || [])
|
|
731
|
-
.map((filter) => Object.entries(filter).map(([key, value]) => [
|
|
732
|
-
`--${key}`,
|
|
733
|
-
value,
|
|
734
|
-
]))
|
|
735
|
-
.flat(2),
|
|
736
|
-
cacheControl ? ["--cache-control", cacheControl] : [],
|
|
737
|
-
contentType ? ["--content-type", contentType] : [],
|
|
738
|
-
contentEncoding ? ["--content-encoding", contentEncoding] : [],
|
|
739
|
-
].flat();
|
|
740
|
-
}),
|
|
741
|
-
ReplaceValues: getS3ContentReplaceValues(),
|
|
598
|
+
destinationBucketName: bucket.bucketName,
|
|
599
|
+
concurrency: assets?._uploadConcurrency,
|
|
600
|
+
textEncoding: assets?.textEncoding ?? "utf-8",
|
|
601
|
+
fileOptions: getS3FileOptions(copy),
|
|
602
|
+
replaceValues: getS3ContentReplaceValues(),
|
|
742
603
|
},
|
|
743
604
|
});
|
|
605
|
+
resource.node.addDependency(policy);
|
|
606
|
+
return resource;
|
|
744
607
|
}
|
|
745
608
|
function useFunctionUrlSigningFunction() {
|
|
746
609
|
singletonUrlSigner =
|
|
@@ -768,10 +631,40 @@ function handler(event) {
|
|
|
768
631
|
OriginRequestPolicy.fromOriginRequestPolicyId(self, "ServerOriginRequestPolicy", "b689b0a8-53d0-40ab-baf2-68738e2966ac");
|
|
769
632
|
return singletonOriginRequestPolicy;
|
|
770
633
|
}
|
|
771
|
-
function
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
634
|
+
function getS3FileOptions(copy) {
|
|
635
|
+
const fileOptions = [];
|
|
636
|
+
const nonVersionedFilesTTL = typeof assets?.nonVersionedFilesTTL === "number"
|
|
637
|
+
? assets.nonVersionedFilesTTL
|
|
638
|
+
: toCdkDuration(assets?.nonVersionedFilesTTL ?? "1 day").toSeconds();
|
|
639
|
+
const staleWhileRevalidateTTL = Math.max(Math.floor(nonVersionedFilesTTL / 10), 30);
|
|
640
|
+
const versionedFilesTTL = typeof assets?.versionedFilesTTL === "number"
|
|
641
|
+
? assets.versionedFilesTTL
|
|
642
|
+
: toCdkDuration(assets?.versionedFilesTTL ?? "365 days").toSeconds();
|
|
643
|
+
copy.forEach(({ cached, to, versionedSubDir }) => {
|
|
644
|
+
if (!cached)
|
|
645
|
+
return;
|
|
646
|
+
// Create a default file option for: unversioned files
|
|
647
|
+
fileOptions.push({
|
|
648
|
+
files: "**",
|
|
649
|
+
ignore: versionedSubDir
|
|
650
|
+
? path.posix.join(to, versionedSubDir, "**")
|
|
651
|
+
: undefined,
|
|
652
|
+
cacheControl: assets?.nonVersionedFilesCacheHeader ??
|
|
653
|
+
`public,max-age=0,s-maxage=${nonVersionedFilesTTL},stale-while-revalidate=${staleWhileRevalidateTTL}`,
|
|
654
|
+
});
|
|
655
|
+
// Create a default file option for: versioned files
|
|
656
|
+
if (versionedSubDir) {
|
|
657
|
+
fileOptions.push({
|
|
658
|
+
files: path.posix.join(to, versionedSubDir, "**"),
|
|
659
|
+
cacheControl: assets?.versionedFilesCacheHeader ??
|
|
660
|
+
`public,max-age=${versionedFilesTTL},immutable`,
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
if (assets?.fileOptions) {
|
|
665
|
+
fileOptions.push(...assets.fileOptions);
|
|
666
|
+
}
|
|
667
|
+
return fileOptions;
|
|
775
668
|
}
|
|
776
669
|
function getS3ContentReplaceValues() {
|
|
777
670
|
const replaceValues = [];
|
|
@@ -796,7 +689,7 @@ function handler(event) {
|
|
|
796
689
|
return replaceValues;
|
|
797
690
|
}
|
|
798
691
|
function createDistributionInvalidation() {
|
|
799
|
-
const cdnInvalidationStrategy =
|
|
692
|
+
const cdnInvalidationStrategy = assets?.cdnInvalidationStrategy ?? "all";
|
|
800
693
|
if (cdnInvalidationStrategy === "never")
|
|
801
694
|
return;
|
|
802
695
|
if (plan.buildId) {
|
|
@@ -833,31 +726,26 @@ function handler(event) {
|
|
|
833
726
|
// The below options are needed to support following symlinks when building zip files:
|
|
834
727
|
// - nodir: This will prevent symlinks themselves from being copied into the zip.
|
|
835
728
|
// - follow: This will follow symlinks and copy the files within.
|
|
836
|
-
const globOptions = {
|
|
837
|
-
dot: true,
|
|
838
|
-
nodir: true,
|
|
839
|
-
follow: true,
|
|
840
|
-
cwd: path.resolve(sitePath, item.from),
|
|
841
|
-
};
|
|
842
729
|
// For versioned files, use file path for digest since file version in name should change on content change
|
|
843
730
|
if (item.versionedSubDir) {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
731
|
+
globSync("**", {
|
|
732
|
+
dot: true,
|
|
733
|
+
nodir: true,
|
|
734
|
+
follow: true,
|
|
847
735
|
cwd: path.resolve(sitePath, item.from, item.versionedSubDir),
|
|
848
|
-
})
|
|
849
|
-
.forEach((filePath) => hash.update(filePath));
|
|
736
|
+
}).forEach((filePath) => hash.update(filePath));
|
|
850
737
|
}
|
|
851
738
|
// For non-versioned files, use file content for digest
|
|
852
739
|
if (cdnInvalidationStrategy === "all") {
|
|
853
|
-
|
|
854
|
-
.sync("**", {
|
|
855
|
-
...globOptions,
|
|
740
|
+
globSync("**", {
|
|
856
741
|
ignore: item.versionedSubDir
|
|
857
742
|
? [path.posix.join(item.versionedSubDir, "**")]
|
|
858
743
|
: undefined,
|
|
859
|
-
|
|
860
|
-
|
|
744
|
+
dot: true,
|
|
745
|
+
nodir: true,
|
|
746
|
+
follow: true,
|
|
747
|
+
cwd: path.resolve(sitePath, item.from),
|
|
748
|
+
}).forEach((filePath) => hash.update(fs.readFileSync(path.resolve(sitePath, item.from, filePath))));
|
|
861
749
|
}
|
|
862
750
|
});
|
|
863
751
|
const buildId = hash.digest("hex");
|
|
@@ -2,7 +2,7 @@ import { Construct } from "constructs";
|
|
|
2
2
|
import { Bucket, BucketProps, IBucket } from "aws-cdk-lib/aws-s3";
|
|
3
3
|
import { IDistribution } from "aws-cdk-lib/aws-cloudfront";
|
|
4
4
|
import { DistributionDomainProps } from "./Distribution.js";
|
|
5
|
-
import { BaseSiteFileOptions,
|
|
5
|
+
import { BaseSiteFileOptions, BaseSiteReplaceProps, BaseSiteCdkDistributionProps } from "./BaseSite.js";
|
|
6
6
|
import { SSTConstruct } from "./Construct.js";
|
|
7
7
|
import { FunctionBindingProps } from "./util/functionBinding.js";
|
|
8
8
|
export interface StaticSiteProps {
|
|
@@ -67,33 +67,6 @@ export interface StaticSiteProps {
|
|
|
67
67
|
* ```
|
|
68
68
|
*/
|
|
69
69
|
buildOutput?: string;
|
|
70
|
-
/**
|
|
71
|
-
* Pass in a list of file options to configure cache control for different files. Behind the scenes, the `StaticSite` construct uses a combination of the `s3 cp` and `s3 sync` commands to upload the website content to the S3 bucket. An `s3 cp` command is run for each file option block, and the options are passed in as the command options.
|
|
72
|
-
* @default No cache control for HTML files, and a 1 year cache control for JS/CSS files.
|
|
73
|
-
* ```js
|
|
74
|
-
* [
|
|
75
|
-
* {
|
|
76
|
-
* filters: [{ exclude: "*" }, { include: "*.html" }],
|
|
77
|
-
* cacheControl: "max-age=0,no-cache,no-store,must-revalidate",
|
|
78
|
-
* },
|
|
79
|
-
* {
|
|
80
|
-
* filters: [{ exclude: "*" }, { include: "*.js" }, { include: "*.css" }],
|
|
81
|
-
* cacheControl: "max-age=31536000,public,immutable",
|
|
82
|
-
* },
|
|
83
|
-
* ]
|
|
84
|
-
* ```
|
|
85
|
-
* @example
|
|
86
|
-
* ```js
|
|
87
|
-
* new StaticSite(stack, "Site", {
|
|
88
|
-
* buildOutput: "dist",
|
|
89
|
-
* fileOptions: [{
|
|
90
|
-
* filters: [{ exclude: "*" }, { include: "*.js" }],
|
|
91
|
-
* cacheControl: "max-age=31536000,public,immutable",
|
|
92
|
-
* }]
|
|
93
|
-
* });
|
|
94
|
-
* ```
|
|
95
|
-
*/
|
|
96
|
-
fileOptions?: StaticSiteFileOptions[] | StaticSiteFileOptionsDeprecated[];
|
|
97
70
|
/**
|
|
98
71
|
* Pass in a list of placeholder values to be replaced in the website content. For example, the follow configuration:
|
|
99
72
|
*
|
|
@@ -169,6 +142,50 @@ export interface StaticSiteProps {
|
|
|
169
142
|
* ```
|
|
170
143
|
*/
|
|
171
144
|
purgeFiles?: boolean;
|
|
145
|
+
assets?: {
|
|
146
|
+
/**
|
|
147
|
+
* Character encoding for text based assets uploaded to S3 (ex: html, css, js, etc.). If "none" is specified, no charset will be returned in header.
|
|
148
|
+
* @default utf-8
|
|
149
|
+
* @example
|
|
150
|
+
* ```js
|
|
151
|
+
* assets: {
|
|
152
|
+
* textEncoding: "iso-8859-1"
|
|
153
|
+
* }
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
textEncoding?: "utf-8" | "iso-8859-1" | "windows-1252" | "ascii" | "none";
|
|
157
|
+
/**
|
|
158
|
+
* Pass in a list of file options to configure cache control for different files. Behind the scenes, the `StaticSite` construct uses a combination of the `s3 cp` and `s3 sync` commands to upload the website content to the S3 bucket. An `s3 cp` command is run for each file option block, and the options are passed in as the command options.
|
|
159
|
+
* @default No cache control for HTML files, and a 1 year cache control for JS/CSS files.
|
|
160
|
+
* ```js
|
|
161
|
+
* assets: {
|
|
162
|
+
* fileOptions: [
|
|
163
|
+
* {
|
|
164
|
+
* files: "**",
|
|
165
|
+
* cacheControl: "max-age=0,no-cache,no-store,must-revalidate",
|
|
166
|
+
* },
|
|
167
|
+
* {
|
|
168
|
+
* files: "**\/*.{js,css}",
|
|
169
|
+
* cacheControl: "max-age=31536000,public,immutable",
|
|
170
|
+
* },
|
|
171
|
+
* ],
|
|
172
|
+
* }
|
|
173
|
+
* ```
|
|
174
|
+
* @example
|
|
175
|
+
* ```js
|
|
176
|
+
* assets: {
|
|
177
|
+
* fileOptions: [
|
|
178
|
+
* {
|
|
179
|
+
* files: "**\/*.zip",
|
|
180
|
+
* cacheControl: "private,no-cache,no-store,must-revalidate",
|
|
181
|
+
* contentType: "application/zip",
|
|
182
|
+
* },
|
|
183
|
+
* ],
|
|
184
|
+
* }
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
fileOptions?: StaticSiteFileOptions[];
|
|
188
|
+
};
|
|
172
189
|
dev?: {
|
|
173
190
|
/**
|
|
174
191
|
* When running `sst dev, site is not deployed. This is to ensure `sst dev` can start up quickly.
|
|
@@ -263,12 +280,7 @@ export interface StaticSiteProps {
|
|
|
263
280
|
}
|
|
264
281
|
export interface StaticSiteDomainProps extends DistributionDomainProps {
|
|
265
282
|
}
|
|
266
|
-
export interface StaticSiteFileOptionsFilter extends BaseSiteFileOptionsFilter {
|
|
267
|
-
}
|
|
268
283
|
export interface StaticSiteFileOptions extends BaseSiteFileOptions {
|
|
269
|
-
filters: StaticSiteFileOptionsFilter[];
|
|
270
|
-
}
|
|
271
|
-
export interface StaticSiteFileOptionsDeprecated extends BaseSiteFileOptionsDeprecated {
|
|
272
284
|
}
|
|
273
285
|
export interface StaticSiteReplaceProps extends BaseSiteReplaceProps {
|
|
274
286
|
}
|
|
@@ -327,6 +339,7 @@ export declare class StaticSite extends Construct implements SSTConstruct {
|
|
|
327
339
|
};
|
|
328
340
|
/** @internal */
|
|
329
341
|
getFunctionBinding(): FunctionBindingProps;
|
|
342
|
+
private validateDeprecatedFileOptions;
|
|
330
343
|
private generateViteTypes;
|
|
331
344
|
private buildApp;
|
|
332
345
|
private createS3Assets;
|