1+ import AWS from "aws-sdk" ;
12import path from "path" ;
23import fse from "fs-extra" ;
3- import mime from "mime-types" ;
4- import AWS from "aws-sdk" ;
54import readDirectoryFiles from "./lib/readDirectoryFiles" ;
5+ import filterOutDirectories from "./lib/filterOutDirectories" ;
6+ import { IMMUTABLE_CACHE_CONTROL_HEADER } from "./lib/constants" ;
7+ import S3ClientFactory , { S3Client } from "./lib/s3" ;
68
79type UploadStaticAssetsOptions = {
810 bucketName : string ;
911 nextConfigDir : string ;
1012} ;
1113
14+ const uploadPublicOrStaticDirectory = async (
15+ s3 : S3Client ,
16+ directory : "public" | "static" ,
17+ nextConfigDir : string
18+ ) : Promise < Promise < AWS . S3 . ManagedUpload . SendData > [ ] > => {
19+ const files = await readDirectoryFiles ( path . join ( nextConfigDir , directory ) ) ;
20+
21+ return files . filter ( filterOutDirectories ) . map ( fileItem =>
22+ s3 . uploadFile ( {
23+ filePath : fileItem . path ,
24+ s3Key : path . posix . relative ( path . resolve ( nextConfigDir ) , fileItem . path )
25+ } )
26+ ) ;
27+ } ;
28+
1229const filePathToS3Key = ( filePath : string ) : string => {
1330 const relevantFilePathPart = filePath . substring (
1431 filePath . indexOf ( ".next" + path . sep )
@@ -18,10 +35,12 @@ const filePathToS3Key = (filePath: string): string => {
1835
1936const uploadStaticAssets = async (
2037 options : UploadStaticAssetsOptions
21- ) : Promise < void > => {
38+ ) : Promise < AWS . S3 . ManagedUpload . SendData > => {
2239 const { bucketName, nextConfigDir } = options ;
2340
24- const s3 = new AWS . S3 ( ) ;
41+ const s3 = S3ClientFactory ( {
42+ bucketName
43+ } ) ;
2544
2645 const dotNextDirectory = path . join ( nextConfigDir , ".next" ) ;
2746
@@ -33,54 +52,56 @@ const uploadStaticAssets = async (
3352 path . join ( dotNextDirectory , "static" , BUILD_ID )
3453 ) ;
3554
36- const uploadTasks = buildStaticFiles
37- . filter ( item => ! item . stats . isDirectory ( ) )
55+ const nextBuildFileUploads = buildStaticFiles
56+ . filter ( filterOutDirectories )
3857 . map ( async fileItem => {
39- const fileBody = await fse . readFile ( fileItem . path ) ;
40-
4158 const s3Key = filePathToS3Key ( fileItem . path ) ;
4259
43- return s3
44- . upload ( {
45- Bucket : bucketName ,
46- Key : s3Key ,
47- Body : fileBody ,
48- ContentType :
49- mime . lookup ( path . basename ( fileItem . path ) ) ||
50- "application/octet-stream" ,
51- CacheControl : "public, max-age=31536000, immutable"
52- } )
53- . promise ( ) ;
60+ return s3 . uploadFile ( {
61+ s3Key,
62+ filePath : fileItem . path ,
63+ cacheControl : IMMUTABLE_CACHE_CONTROL_HEADER
64+ } ) ;
5465 } ) ;
5566
5667 const pagesManifest = await fse . readJSON (
5768 path . join ( dotNextDirectory , "serverless/pages-manifest.json" )
5869 ) ;
5970
60- const htmlPageUploadTasks = Object . values ( pagesManifest )
71+ const htmlPageUploads = Object . values ( pagesManifest )
6172 . filter ( pageFile => ( pageFile as string ) . endsWith ( ".html" ) )
62- . map ( async pageFile => {
63- const fileBody = await fse . readFile (
64- path . join ( dotNextDirectory , `serverless/${ pageFile } ` )
73+ . map ( relativePageFilePath => {
74+ const pageFilePath = path . join (
75+ dotNextDirectory ,
76+ `serverless/${ relativePageFilePath } `
6577 ) ;
6678
67- return s3
68- . upload ( {
69- Bucket : bucketName ,
70- Key : `static-pages/${ ( pageFile as string ) . replace ( / ^ p a g e s \/ / , "" ) } ` ,
71- Body : fileBody ,
72- ContentType : "text/html" ,
73- CacheControl : undefined
74- } )
75- . promise ( ) ;
79+ return s3 . uploadFile ( {
80+ s3Key : `static-pages/${ relativePageFilePath . replace ( / ^ p a g e s \/ / , "" ) } ` ,
81+ filePath : pageFilePath
82+ } ) ;
7683 } ) ;
7784
78- uploadTasks . concat ( htmlPageUploadTasks ) ;
85+ const publicDirUploads = await uploadPublicOrStaticDirectory (
86+ s3 ,
87+ "public" ,
88+ nextConfigDir
89+ ) ;
90+
91+ const staticDirUploads = await uploadPublicOrStaticDirectory (
92+ s3 ,
93+ "static" ,
94+ nextConfigDir
95+ ) ;
96+
97+ const allUploads = [
98+ ...nextBuildFileUploads ,
99+ ...htmlPageUploads ,
100+ ...publicDirUploads ,
101+ ...staticDirUploads
102+ ] ;
79103
80- await Promise . all ( uploadTasks ) ;
81- // read public/ folder and upload files
82- // read static/ folder and upload files
83- // get JSON data files from prerender manifest
104+ return Promise . all ( allUploads ) ;
84105} ;
85106
86107export default uploadStaticAssets ;
0 commit comments