UNPKG

22.2 kBJavaScriptView Raw
1(function webpackUniversalModuleDefinition(root, factory) {
2 if(typeof exports === 'object' && typeof module === 'object')
3 module.exports = factory(require("http"), require("https"), require("s3"), require("fs"), require("path"), require("progress"), require("cdnizer"), require("lodash"), require("aws-sdk"), require("recursive-readdir"));
4 else if(typeof define === 'function' && define.amd)
5 define(["http", "https", "s3", "fs", "path", "progress", "cdnizer", "lodash", "aws-sdk", "recursive-readdir"], factory);
6 else if(typeof exports === 'object')
7 exports["webpack-s3-plugin"] = factory(require("http"), require("https"), require("s3"), require("fs"), require("path"), require("progress"), require("cdnizer"), require("lodash"), require("aws-sdk"), require("recursive-readdir"));
8 else
9 root["webpack-s3-plugin"] = factory(root["http"], root["https"], root["s3"], root["fs"], root["path"], root["progress"], root["cdnizer"], root["lodash"], root["aws-sdk"], root["recursive-readdir"]);
10})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_5__, __WEBPACK_EXTERNAL_MODULE_6__, __WEBPACK_EXTERNAL_MODULE_7__, __WEBPACK_EXTERNAL_MODULE_8__, __WEBPACK_EXTERNAL_MODULE_9__, __WEBPACK_EXTERNAL_MODULE_11__) {
11return /******/ (function(modules) { // webpackBootstrap
12/******/ // The module cache
13/******/ var installedModules = {};
14
15/******/ // The require function
16/******/ function __webpack_require__(moduleId) {
17
18/******/ // Check if module is in cache
19/******/ if(installedModules[moduleId])
20/******/ return installedModules[moduleId].exports;
21
22/******/ // Create a new module (and put it into the cache)
23/******/ var module = installedModules[moduleId] = {
24/******/ exports: {},
25/******/ id: moduleId,
26/******/ loaded: false
27/******/ };
28
29/******/ // Execute the module function
30/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
31
32/******/ // Flag the module as loaded
33/******/ module.loaded = true;
34
35/******/ // Return the exports of the module
36/******/ return module.exports;
37/******/ }
38
39
40/******/ // expose the modules object (__webpack_modules__)
41/******/ __webpack_require__.m = modules;
42
43/******/ // expose the module cache
44/******/ __webpack_require__.c = installedModules;
45
46/******/ // __webpack_public_path__
47/******/ __webpack_require__.p = "";
48
49/******/ // Load entry module and return exports
50/******/ return __webpack_require__(0);
51/******/ })
52/************************************************************************/
53/******/ ([
54/* 0 */
55/***/ function(module, exports, __webpack_require__) {
56
57 'use strict';
58
59 var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
60
61 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
62
63 var _http = __webpack_require__(1);
64
65 var _http2 = _interopRequireDefault(_http);
66
67 var _https = __webpack_require__(2);
68
69 var _https2 = _interopRequireDefault(_https);
70
71 var _s2 = __webpack_require__(3);
72
73 var _s3 = _interopRequireDefault(_s2);
74
75 var _fs = __webpack_require__(4);
76
77 var _fs2 = _interopRequireDefault(_fs);
78
79 var _path = __webpack_require__(5);
80
81 var _path2 = _interopRequireDefault(_path);
82
83 var _progress = __webpack_require__(6);
84
85 var _progress2 = _interopRequireDefault(_progress);
86
87 var _cdnizer = __webpack_require__(7);
88
89 var _cdnizer2 = _interopRequireDefault(_cdnizer);
90
91 var _lodash = __webpack_require__(8);
92
93 var _lodash2 = _interopRequireDefault(_lodash);
94
95 var _awsSdk = __webpack_require__(9);
96
97 var _awsSdk2 = _interopRequireDefault(_awsSdk);
98
99 var _helpers = __webpack_require__(10);
100
101 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
102
103 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
104
105 _http2.default.globalAgent.maxSockets = _https2.default.globalAgent.maxSockets = 50;
106
107 var compileError = function compileError(compilation, error) {
108 compilation.errors.push(new Error(error));
109 };
110
111 module.exports = function () {
112 function S3Plugin() {
113 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
114
115 _classCallCheck(this, S3Plugin);
116
117 var include = options.include,
118 exclude = options.exclude,
119 progress = options.progress,
120 basePath = options.basePath,
121 directory = options.directory,
122 htmlFiles = options.htmlFiles,
123 _options$basePathTran = options.basePathTransform,
124 basePathTransform = _options$basePathTran === undefined ? _helpers.DEFAULT_TRANSFORM : _options$basePathTran,
125 _options$s3Options = options.s3Options,
126 s3Options = _options$s3Options === undefined ? {} : _options$s3Options,
127 _options$cdnizerOptio = options.cdnizerOptions,
128 cdnizerOptions = _options$cdnizerOptio === undefined ? {} : _options$cdnizerOptio,
129 _options$s3UploadOpti = options.s3UploadOptions,
130 s3UploadOptions = _options$s3UploadOpti === undefined ? {} : _options$s3UploadOpti,
131 _options$cloudfrontIn = options.cloudfrontInvalidateOptions,
132 cloudfrontInvalidateOptions = _options$cloudfrontIn === undefined ? {} : _options$cloudfrontIn;
133
134
135 this.uploadOptions = s3UploadOptions;
136 this.cloudfrontInvalidateOptions = cloudfrontInvalidateOptions;
137 this.isConnected = false;
138 this.cdnizerOptions = cdnizerOptions;
139 this.urlMappings = [];
140 this.uploadTotal = 0;
141 this.uploadProgress = 0;
142 this.basePathTransform = basePathTransform;
143 basePath = basePath ? (0, _helpers.addTrailingS3Sep)(basePath) : '';
144
145 this.options = {
146 directory: directory,
147 include: include,
148 exclude: exclude,
149 basePath: basePath,
150 htmlFiles: typeof htmlFiles === 'string' ? [htmlFiles] : htmlFiles,
151 progress: _lodash2.default.isBoolean(progress) ? progress : true
152 };
153
154 this.clientConfig = {
155 s3Options: s3Options,
156 maxAsyncS3: 50
157 };
158
159 this.noCdnizer = !Object.keys(this.cdnizerOptions).length;
160
161 if (!this.noCdnizer && !this.cdnizerOptions.files) this.cdnizerOptions.files = [];
162 }
163
164 _createClass(S3Plugin, [{
165 key: 'apply',
166 value: function apply(compiler) {
167 var _this = this;
168
169 this.connect();
170
171 var isDirectoryUpload = !!this.options.directory,
172 hasRequiredUploadOpts = _lodash2.default.every(_helpers.REQUIRED_S3_UP_OPTS, function (type) {
173 return _this.uploadOptions[type];
174 });
175
176 // Set directory to output dir or custom
177 this.options.directory = this.options.directory || compiler.options.output.path || compiler.options.output.context || '.';
178
179 compiler.plugin('after-emit', function (compilation, cb) {
180 var error;
181
182 if (!hasRequiredUploadOpts) error = 'S3Plugin-RequiredS3UploadOpts: ' + _helpers.REQUIRED_S3_UP_OPTS.join(', ');
183
184 if (error) {
185 compileError(compilation, error);
186 cb();
187 }
188
189 if (isDirectoryUpload) {
190 var dPath = (0, _helpers.addSeperatorToPath)(_this.options.directory);
191
192 _this.getAllFilesRecursive(dPath).then(function (files) {
193 return _this.handleFiles(files, cb);
194 }).then(function () {
195 return cb();
196 }).catch(function (e) {
197 return _this.handleErrors(e, compilation, cb);
198 });
199 } else {
200 _this.getAssetFiles(compilation).then(function (files) {
201 return _this.handleFiles(files);
202 }).then(function () {
203 return cb();
204 }).catch(function (e) {
205 return _this.handleErrors(e, compilation, cb);
206 });
207 }
208 });
209 }
210 }, {
211 key: 'handleFiles',
212 value: function handleFiles(files) {
213 var _this2 = this;
214
215 return this.changeUrls(files).then(function (files) {
216 return _this2.filterAllowedFiles(files);
217 }).then(function (files) {
218 return _this2.uploadFiles(files);
219 }).then(function () {
220 return _this2.invalidateCloudfront();
221 });
222 }
223 }, {
224 key: 'handleErrors',
225 value: function handleErrors(error, compilation, cb) {
226 compileError(compilation, 'S3Plugin: ' + error);
227 cb();
228 }
229 }, {
230 key: 'getAllFilesRecursive',
231 value: function getAllFilesRecursive(fPath) {
232 return (0, _helpers.getDirectoryFilesRecursive)(fPath);
233 }
234 }, {
235 key: 'addPathToFiles',
236 value: function addPathToFiles(files, fPath) {
237 return files.map(function (file) {
238 return { name: file, path: _path2.default.resolve(fPath, file) };
239 });
240 }
241 }, {
242 key: 'getFileName',
243 value: function getFileName() {
244 var file = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
245
246 if (_lodash2.default.includes(file, _helpers.PATH_SEP)) return file.substring(_lodash2.default.lastIndexOf(file, _helpers.PATH_SEP) + 1);else return file;
247 }
248 }, {
249 key: 'getAssetFiles',
250 value: function getAssetFiles(_ref) {
251 var assets = _ref.assets;
252
253 var files = _lodash2.default.map(assets, function (value, name) {
254 return { name: name, path: value.existsAt };
255 });
256
257 return Promise.resolve(files);
258 }
259 }, {
260 key: 'cdnizeHtml',
261 value: function cdnizeHtml(file) {
262 var _this3 = this;
263
264 return new Promise(function (resolve, reject) {
265 _fs2.default.readFile(file.path, function (err, data) {
266 if (err) return reject(err);
267
268 _fs2.default.writeFile(file.path, _this3.cdnizer(data.toString()), function (err) {
269 if (err) return reject(err);
270
271 resolve(file);
272 });
273 });
274 });
275 }
276 }, {
277 key: 'changeUrls',
278 value: function changeUrls() {
279 var _this4 = this;
280
281 var files = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
282
283 if (this.noCdnizer) return Promise.resolve(files);
284
285 var allHtml;
286
287 var _options = this.options,
288 directory = _options.directory,
289 _options$htmlFiles = _options.htmlFiles,
290 htmlFiles = _options$htmlFiles === undefined ? [] : _options$htmlFiles;
291
292
293 if (htmlFiles.length) allHtml = this.addPathToFiles(htmlFiles, directory).concat(files);else allHtml = files;
294
295 this.cdnizerOptions.files = allHtml.map(function (_ref2) {
296 var name = _ref2.name;
297 return '*' + name + '*';
298 });
299 this.cdnizer = (0, _cdnizer2.default)(this.cdnizerOptions);
300
301 var _$uniq$partition$valu = (0, _lodash2.default)(allHtml).uniq('name').partition(function (file) {
302 return (/\.(html|css)/.test(file.name)
303 );
304 }).value(),
305 _$uniq$partition$valu2 = _slicedToArray(_$uniq$partition$valu, 2),
306 cdnizeFiles = _$uniq$partition$valu2[0],
307 otherFiles = _$uniq$partition$valu2[1];
308
309 return Promise.all(cdnizeFiles.map(function (file) {
310 return _this4.cdnizeHtml(file);
311 }).concat(otherFiles));
312 }
313 }, {
314 key: 'filterAllowedFiles',
315 value: function filterAllowedFiles(files) {
316 var _this5 = this;
317
318 return files.reduce(function (res, file) {
319 if (_this5.isIncludeAndNotExclude(file.name) && !_this5.isIgnoredFile(file.name)) res.push(file);
320
321 return res;
322 }, []);
323 }
324 }, {
325 key: 'isIgnoredFile',
326 value: function isIgnoredFile(file) {
327 return _lodash2.default.some(_helpers.UPLOAD_IGNORES, function (ignore) {
328 return new RegExp(ignore).test(file);
329 });
330 }
331 }, {
332 key: 'isIncludeAndNotExclude',
333 value: function isIncludeAndNotExclude(file) {
334 var isExclude,
335 isInclude,
336 _options2 = this.options,
337 include = _options2.include,
338 exclude = _options2.exclude;
339
340
341 isInclude = include ? (0, _helpers.testRule)(include, file) : true;
342 isExclude = exclude ? (0, _helpers.testRule)(exclude, file) : false;
343
344 return isInclude && !isExclude;
345 }
346 }, {
347 key: 'connect',
348 value: function connect() {
349 if (this.isConnected) return;
350
351 this.client = _s3.default.createClient(this.clientConfig);
352 this.isConnected = true;
353 }
354 }, {
355 key: 'transformBasePath',
356 value: function transformBasePath() {
357 var _this6 = this;
358
359 return Promise.resolve(this.basePathTransform(this.options.basePath)).then(_helpers.addTrailingS3Sep).then(function (nPath) {
360 return _this6.options.basePath = nPath;
361 });
362 }
363 }, {
364 key: 'setupProgressBar',
365 value: function setupProgressBar(uploadFiles) {
366 var progressAmount = Array(uploadFiles.length);
367 var progressTotal = Array(uploadFiles.length);
368 var progressTracker = 0;
369 var calculateProgress = function calculateProgress() {
370 return _lodash2.default.sum(progressAmount) / _lodash2.default.sum(progressTotal);
371 };
372 var countUndefined = function countUndefined(array) {
373 return _lodash2.default.reduce(array, function (res, value) {
374 return res += _lodash2.default.isUndefined(value) ? 1 : 0;
375 }, 0);
376 };
377
378 var progressBar = new _progress2.default('Uploading [:bar] :percent :etas', {
379 complete: '>',
380 incomplete: '∆',
381 total: 100
382 });
383
384 uploadFiles.forEach(function (_ref3, i) {
385 var upload = _ref3.upload;
386
387 upload.on('progress', function () {
388 var definedModifier, progressValue;
389
390 progressTotal[i] = this.progressTotal;
391 progressAmount[i] = this.progressAmount;
392 definedModifier = countUndefined(progressTotal) / 10;
393 progressValue = calculateProgress() - definedModifier;
394
395 if (progressValue !== progressTracker) {
396 progressBar.update(progressValue);
397 progressTracker = progressValue;
398 }
399 });
400 });
401 }
402 }, {
403 key: 'uploadFiles',
404 value: function uploadFiles() {
405 var _this7 = this;
406
407 var files = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
408
409 return this.transformBasePath().then(function () {
410 var uploadFiles = files.map(function (file) {
411 return _this7.uploadFile(file.name, file.path);
412 });
413
414 if (_this7.options.progress) {
415 _this7.setupProgressBar(uploadFiles);
416 }
417
418 return Promise.all(uploadFiles.map(function (_ref4) {
419 var promise = _ref4.promise;
420 return promise;
421 }));
422 });
423 }
424 }, {
425 key: 'uploadFile',
426 value: function uploadFile(fileName, file) {
427 var Key = this.options.basePath + fileName;
428 var s3Params = _lodash2.default.mapValues(this.uploadOptions, function (optionConfig) {
429 return _lodash2.default.isFunction(optionConfig) ? optionConfig(fileName, file) : optionConfig;
430 });
431
432 // Remove Gzip from encoding if ico
433 if (/\.ico/.test(fileName) && s3Params.ContentEncoding === 'gzip') delete s3Params.ContentEncoding;
434
435 var upload = this.client.uploadFile({
436 localFile: file,
437 s3Params: _lodash2.default.merge({ Key: Key }, _helpers.DEFAULT_UPLOAD_OPTIONS, s3Params)
438 });
439
440 if (!this.noCdnizer) this.cdnizerOptions.files.push('*' + fileName + '*');
441
442 var promise = new Promise(function (resolve, reject) {
443 upload.on('error', reject);
444 upload.on('end', function () {
445 return resolve(file);
446 });
447 });
448
449 return { upload: upload, promise: promise };
450 }
451 }, {
452 key: 'invalidateCloudfront',
453 value: function invalidateCloudfront() {
454 var clientConfig = this.clientConfig,
455 cloudfrontInvalidateOptions = this.cloudfrontInvalidateOptions;
456
457
458 return new Promise(function (resolve, reject) {
459 if (cloudfrontInvalidateOptions.DistributionId) {
460 var _clientConfig$s3Optio = clientConfig.s3Options,
461 accessKeyId = _clientConfig$s3Optio.accessKeyId,
462 secretAccessKey = _clientConfig$s3Optio.secretAccessKey;
463
464 var cloudfront = new _awsSdk2.default.CloudFront();
465
466 if (accessKeyId && secretAccessKey) cloudfront.config.update({ accessKeyId: accessKeyId, secretAccessKey: secretAccessKey });
467
468 cloudfront.createInvalidation({
469 DistributionId: cloudfrontInvalidateOptions.DistributionId,
470 InvalidationBatch: {
471 CallerReference: Date.now().toString(),
472 Paths: {
473 Quantity: cloudfrontInvalidateOptions.Items.length,
474 Items: cloudfrontInvalidateOptions.Items
475 }
476 }
477 }, function (err, res) {
478 return err ? reject(err) : resolve(res.Id);
479 });
480 } else {
481 return resolve(null);
482 }
483 });
484 }
485 }]);
486
487 return S3Plugin;
488 }();
489
490/***/ },
491/* 1 */
492/***/ function(module, exports) {
493
494 module.exports = require("http");
495
496/***/ },
497/* 2 */
498/***/ function(module, exports) {
499
500 module.exports = require("https");
501
502/***/ },
503/* 3 */
504/***/ function(module, exports) {
505
506 module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
507
508/***/ },
509/* 4 */
510/***/ function(module, exports) {
511
512 module.exports = require("fs");
513
514/***/ },
515/* 5 */
516/***/ function(module, exports) {
517
518 module.exports = require("path");
519
520/***/ },
521/* 6 */
522/***/ function(module, exports) {
523
524 module.exports = __WEBPACK_EXTERNAL_MODULE_6__;
525
526/***/ },
527/* 7 */
528/***/ function(module, exports) {
529
530 module.exports = __WEBPACK_EXTERNAL_MODULE_7__;
531
532/***/ },
533/* 8 */
534/***/ function(module, exports) {
535
536 module.exports = __WEBPACK_EXTERNAL_MODULE_8__;
537
538/***/ },
539/* 9 */
540/***/ function(module, exports) {
541
542 module.exports = __WEBPACK_EXTERNAL_MODULE_9__;
543
544/***/ },
545/* 10 */
546/***/ function(module, exports, __webpack_require__) {
547
548 'use strict';
549
550 Object.defineProperty(exports, "__esModule", {
551 value: true
552 });
553 exports.testRule = exports.getDirectoryFilesRecursive = exports.translatePathFromFiles = exports.addSeperatorToPath = exports.addTrailingS3Sep = exports.DEFAULT_TRANSFORM = exports.S3_PATH_SEP = exports.PATH_SEP = exports.REQUIRED_S3_UP_OPTS = exports.DEFAULT_UPLOAD_OPTIONS = exports.UPLOAD_IGNORES = undefined;
554
555 var _lodash = __webpack_require__(8);
556
557 var _lodash2 = _interopRequireDefault(_lodash);
558
559 var _path = __webpack_require__(5);
560
561 var _path2 = _interopRequireDefault(_path);
562
563 var _recursiveReaddir = __webpack_require__(11);
564
565 var _recursiveReaddir2 = _interopRequireDefault(_recursiveReaddir);
566
567 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
568
569 var UPLOAD_IGNORES = exports.UPLOAD_IGNORES = ['.DS_Store'];
570
571 var DEFAULT_UPLOAD_OPTIONS = exports.DEFAULT_UPLOAD_OPTIONS = {
572 ACL: 'public-read'
573 };
574
575 var REQUIRED_S3_UP_OPTS = exports.REQUIRED_S3_UP_OPTS = ['Bucket'];
576 var PATH_SEP = exports.PATH_SEP = _path2.default.sep;
577 var S3_PATH_SEP = exports.S3_PATH_SEP = '/';
578 var DEFAULT_TRANSFORM = exports.DEFAULT_TRANSFORM = function DEFAULT_TRANSFORM(item) {
579 return Promise.resolve(item);
580 };
581
582 var addTrailingS3Sep = exports.addTrailingS3Sep = function addTrailingS3Sep(fPath) {
583 return fPath ? fPath.replace(/\/?(\?|#|$)/, '/$1') : fPath;
584 };
585
586 var addSeperatorToPath = exports.addSeperatorToPath = function addSeperatorToPath(fPath) {
587 if (!fPath) return fPath;
588
589 return _lodash2.default.endsWith(fPath, PATH_SEP) ? fPath : fPath + PATH_SEP;
590 };
591
592 var translatePathFromFiles = exports.translatePathFromFiles = function translatePathFromFiles(rootPath) {
593 return function (files) {
594 return _lodash2.default.map(files, function (file) {
595 return {
596 path: file,
597 name: file.replace(rootPath, '').split(PATH_SEP).join(S3_PATH_SEP)
598 };
599 });
600 };
601 };
602
603 var getDirectoryFilesRecursive = exports.getDirectoryFilesRecursive = function getDirectoryFilesRecursive(dir) {
604 var ignores = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
605
606 return new Promise(function (resolve, reject) {
607 (0, _recursiveReaddir2.default)(dir, ignores, function (err, files) {
608 return err ? reject(err) : resolve(files);
609 });
610 }).then(translatePathFromFiles(dir));
611 };
612
613 var testRule = exports.testRule = function testRule(rule, subject) {
614 if (_lodash2.default.isRegExp(rule)) {
615 return rule.test(subject);
616 } else if (_lodash2.default.isFunction(rule)) {
617 return !!rule(subject);
618 } else if (_lodash2.default.isArray(rule)) {
619 return _lodash2.default.every(rule, function (condition) {
620 return testRule(condition, subject);
621 });
622 } else if (_lodash2.default.isString(rule)) {
623 return new RegExp(rule).test(subject);
624 } else {
625 throw new Error('Invalid include / exclude rule');
626 }
627 };
628
629/***/ },
630/* 11 */
631/***/ function(module, exports) {
632
633 module.exports = __WEBPACK_EXTERNAL_MODULE_11__;
634
635/***/ }
636/******/ ])
637});
638;
\No newline at end of file