UNPKG

3.46 kBJavaScriptView Raw
1'use strict'
2
3const crypto = require('crypto')
4// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#createBucket-property
5const S3_LOCATION_POSSIBLE_VALUES = [
6 'EU',
7 'ap-northeast-1',
8 'ap-south-1',
9 'ap-southeast-1',
10 'ap-southeast-2',
11 'cn-north-1',
12 'eu-central-1',
13 'eu-west-1',
14 'sa-east-1',
15 'us-west-1',
16 'us-west-2'
17]
18
19class S3Deploy {
20 constructor (aws, region) {
21 // Authenticated `aws` object in `lib/main.js`
22 this.s3 = new aws.S3({
23 region: region,
24 apiVersion: '2006-03-01'
25 })
26 }
27
28 _md5 (str) {
29 return crypto
30 .createHash('md5')
31 .update(str, 'utf8')
32 .digest('hex')
33 }
34
35 _convertRegionStringToEnvVarName (region) {
36 if (region == null) return 'undefined'
37 return region.replace(/-/g, '_').toUpperCase()
38 }
39
40 _getBucketNameFromEnvVar (region) {
41 const key = [
42 'S3',
43 this._convertRegionStringToEnvVarName(region),
44 'BUCKET'
45 ].join('_')
46 return process.env[key]
47 }
48
49 _getS3KeyPrefixFromEnvVar (region) {
50 const key = [
51 'S3',
52 this._convertRegionStringToEnvVarName(region),
53 'PREFIX'
54 ].join('_')
55 return process.env[key]
56 }
57
58 _bucketName (params) {
59 const bucketNameFromEnvVar = this._getBucketNameFromEnvVar(params.region)
60 if (bucketNameFromEnvVar != null) return bucketNameFromEnvVar
61
62 return [
63 params.FunctionName,
64 params.region,
65 this._md5(params.FunctionName + params.region)
66 ]
67 .join('-')
68 .substr(0, 63)
69 }
70
71 _s3Key (params) {
72 const s3Prefix = this._getS3KeyPrefixFromEnvVar(params.region)
73 const keys = [`deploy-package-${params.FunctionName}.zip`]
74 if (s3Prefix != null) {
75 keys.unshift(s3Prefix.replace(/\/$/, ''))
76 }
77 return keys.join('/')
78 }
79
80 _getS3Location (region) {
81 return S3_LOCATION_POSSIBLE_VALUES.includes(region) ? region : null
82 }
83
84 _createBucket (params) {
85 const _params = {
86 Bucket: params.bucketName
87 }
88 const s3Locatoin = this._getS3Location(params.region)
89 if (s3Locatoin != null) {
90 _params.CreateBucketConfiguration = {
91 LocationConstraint: s3Locatoin
92 }
93 }
94 return new Promise((resolve, reject) => {
95 this.s3.createBucket(_params, (err, data) => {
96 if (err) {
97 // Ignored created
98 if (err.code === 'BucketAlreadyOwnedByYou') return resolve({})
99 return reject(err)
100 }
101 resolve(data)
102 })
103 })
104 }
105
106 _putObject (params, buffer) {
107 const _params = {
108 Body: buffer,
109 Bucket: params.bucketName,
110 Key: params.s3Key
111 }
112 return new Promise((resolve, reject) => {
113 this.s3.putObject(_params, (err, data) => {
114 if (err) reject(err)
115 resolve(data)
116 })
117 })
118 }
119
120 putPackage (params, region, buffer) {
121 const _params = Object.assign({region: region}, params)
122 _params.bucketName = this._bucketName(_params)
123 _params.s3Key = this._s3Key(_params)
124
125 return this._createBucket(_params).then((result) => {
126 if (result.Location != null) {
127 console.log('=> S3 Bucket created:')
128 console.log(`===> ${_params.bucketName}`)
129 }
130 return this._putObject(_params, buffer)
131 }).then((result) => {
132 console.log('=> Deploy the zip file to S3:')
133 console.log(`===> ${_params.bucketName}/${_params.s3Key}`)
134 return {
135 S3Bucket: _params.bucketName,
136 S3Key: _params.s3Key
137 }
138 })
139 }
140}
141
142module.exports = S3Deploy