This repository was archived by the owner on Apr 15, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
126 lines (116 loc) · 3.23 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const got = require(`got`);
const { S3 } = require(`@aws-sdk/client-s3-node/S3`);
const {
accessKeyId,
secretAccessKey,
assetsDirectory,
bucketName,
assetsServerUri,
assetsManifests,
cacheControl,
region,
} = require(`./config`);
const s3 = new S3({
region,
credentials: {
accessKeyId,
secretAccessKey,
},
});
const calculateNewAssets = (assetsPathFromManifest, existsAssetsMap) => {
return assetsPathFromManifest.filter(
(name) => !existsAssetsMap.includes(name)
);
};
async function getListOfFiles({ continuationToken, directory }) {
const stripDirectoryReg = new RegExp(`^${directory}/`);
return await s3
.listObjectsV2({
Bucket: bucketName,
Prefix: directory,
...(continuationToken ? { ContinuationToken: continuationToken } : {}),
})
.then(
({ Contents: items, NextContinuationToken: nextContinuationToken }) => {
return {
items: items.map(({ Key: assetName }) =>
assetName.replace(stripDirectoryReg, ``)
),
nextContinuationToken,
};
}
);
}
async function getExistAssetsMap({ directory }) {
const assetsMap = [];
const firstRes = await getListOfFiles({ directory });
assetsMap.push(...firstRes.items);
let nextContinuationToken = firstRes.nextContinuationToken;
while (true) {
if (!nextContinuationToken) {
return assetsMap;
}
// eslint-disable-next-line no-await-in-loop
const res = await getListOfFiles({
continuationToken: nextContinuationToken,
directory,
});
assetsMap.push(...res.items);
nextContinuationToken = res.nextContinuationToken;
}
}
async function uploadAsset({ assetName, stream, ContentType, ContentLength }) {
return s3.putObject({
Bucket: bucketName,
ContentType,
Key: `${assetsDirectory}/${assetName}`,
Body: stream,
CacheControl: cacheControl,
ContentLength,
});
}
async function uploadAssetsFromRemoteService({ assets, serviceUri, logger }) {
logger.log(`${assets.length} assets will be uploaded to S3`);
for (const assetName of assets) {
logger.log(`start upload ${assetName}`);
const assetUrl = `${serviceUri}/${assetName}`;
const info = await got(assetUrl, { method: `HEAD` });
await uploadAsset({
stream: got.stream(assetUrl),
assetName,
ContentType: info.headers[`content-type`],
ContentLength: info.headers[`content-length`],
});
logger.log(`finish upload ${assetName}`);
}
return `${assets.length} assets were uploaded to S3`;
}
async function upload() {
const assetsPathFromManifest = await Promise.all(
assetsManifests.map((manifestPath) =>
got(`${assetsServerUri}/${manifestPath}`, {
responseType: `json`,
resolveBodyOnly: true,
})
)
).then((results) =>
results.reduce((flatted, item) => flatted.concat(item), [])
);
const existsAssetsMap = await getExistAssetsMap({
directory: assetsDirectory,
});
const assets = calculateNewAssets(assetsPathFromManifest, existsAssetsMap);
return uploadAssetsFromRemoteService({
assets,
serviceUri: assetsServerUri,
logger: console,
});
}
upload()
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err);
process.exit(1);
});