1 | 'use strict';
|
2 |
|
3 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
4 |
|
5 | var commander = _interopDefault(require('commander'));
|
6 | var chalk = _interopDefault(require('chalk'));
|
7 | var React = require('react');
|
8 | var React__default = _interopDefault(React);
|
9 | var ink = require('ink');
|
10 | var semver = require('semver');
|
11 | var semver__default = _interopDefault(semver);
|
12 | var execa = _interopDefault(require('execa'));
|
13 | var axios = _interopDefault(require('axios'));
|
14 | var path$1 = require('path');
|
15 | var path$1__default = _interopDefault(path$1);
|
16 | var lodash = require('lodash');
|
17 | var codeFrame = require('@babel/code-frame');
|
18 | var resolve = _interopDefault(require('resolve-from'));
|
19 | var Worker = _interopDefault(require('jest-worker'));
|
20 | var PQueue = _interopDefault(require('p-queue'));
|
21 | var fs = require('fs');
|
22 | var fs__default = _interopDefault(fs);
|
23 | require('core-js/modules/es.array.iterator');
|
24 | var jsYaml = require('js-yaml');
|
25 | var ora = _interopDefault(require('ora'));
|
26 | var slugify = _interopDefault(require('slugify'));
|
27 | var inquirer = require('inquirer');
|
28 | var util = require('util');
|
29 | var prettierConfig$1 = _interopDefault(require('@burst/prettier-config'));
|
30 | var stylelint = _interopDefault(require('stylelint'));
|
31 | var client = require('@slack/client');
|
32 | var xml2js = _interopDefault(require('xml2js'));
|
33 | var rimrafWithCallback = _interopDefault(require('rimraf'));
|
34 | var stagedFilesWithCallback = _interopDefault(require('staged-git-files'));
|
35 |
|
36 | var fails = function (exec) {
|
37 | try {
|
38 | return !!exec();
|
39 | } catch (error) {
|
40 | return true;
|
41 | }
|
42 | };
|
43 |
|
44 |
|
45 | var descriptors = !fails(function () {
|
46 | return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
|
47 | });
|
48 |
|
49 | var hasOwnProperty = {}.hasOwnProperty;
|
50 |
|
51 | var has = function (it, key) {
|
52 | return hasOwnProperty.call(it, key);
|
53 | };
|
54 |
|
55 | var isObject = function (it) {
|
56 | return typeof it === 'object' ? it !== null : typeof it === 'function';
|
57 | };
|
58 |
|
59 |
|
60 | var global = typeof window == 'object' && window && window.Math == Math ? window
|
61 | : typeof self == 'object' && self && self.Math == Math ? self
|
62 |
|
63 | : Function('return this')();
|
64 |
|
65 | var document$1 = global.document;
|
66 |
|
67 | var exist = isObject(document$1) && isObject(document$1.createElement);
|
68 |
|
69 | var documentCreateElement = function (it) {
|
70 | return exist ? document$1.createElement(it) : {};
|
71 | };
|
72 |
|
73 |
|
74 | var ie8DomDefine = !descriptors && !fails(function () {
|
75 | return Object.defineProperty(documentCreateElement('div'), 'a', {
|
76 | get: function () { return 7; }
|
77 | }).a != 7;
|
78 | });
|
79 |
|
80 | var anObject = function (it) {
|
81 | if (!isObject(it)) {
|
82 | throw TypeError(String(it) + ' is not an object');
|
83 | } return it;
|
84 | };
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | var toPrimitive = function (it, S) {
|
91 | if (!isObject(it)) return it;
|
92 | var fn, val;
|
93 | if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
|
94 | if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;
|
95 | if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;
|
96 | throw TypeError("Can't convert object to primitive value");
|
97 | };
|
98 |
|
99 | var nativeDefineProperty = Object.defineProperty;
|
100 |
|
101 | var f = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
|
102 | anObject(O);
|
103 | P = toPrimitive(P, true);
|
104 | anObject(Attributes);
|
105 | if (ie8DomDefine) try {
|
106 | return nativeDefineProperty(O, P, Attributes);
|
107 | } catch (error) { }
|
108 | if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
|
109 | if ('value' in Attributes) O[P] = Attributes.value;
|
110 | return O;
|
111 | };
|
112 |
|
113 | var objectDefineProperty = {
|
114 | f: f
|
115 | };
|
116 |
|
117 | var toString = {}.toString;
|
118 |
|
119 | var classofRaw = function (it) {
|
120 | return toString.call(it).slice(8, -1);
|
121 | };
|
122 |
|
123 |
|
124 |
|
125 |
|
126 | var split = ''.split;
|
127 |
|
128 | var indexedObject = fails(function () {
|
129 |
|
130 |
|
131 | return !Object('z').propertyIsEnumerable(0);
|
132 | }) ? function (it) {
|
133 | return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
|
134 | } : Object;
|
135 |
|
136 |
|
137 |
|
138 | var requireObjectCoercible = function (it) {
|
139 | if (it == undefined) throw TypeError("Can't call method on " + it);
|
140 | return it;
|
141 | };
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 | var toIndexedObject = function (it) {
|
148 | return indexedObject(requireObjectCoercible(it));
|
149 | };
|
150 |
|
151 | var ceil = Math.ceil;
|
152 | var floor = Math.floor;
|
153 |
|
154 |
|
155 |
|
156 | var toInteger = function (argument) {
|
157 | return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
|
158 | };
|
159 |
|
160 | var min = Math.min;
|
161 |
|
162 |
|
163 |
|
164 | var toLength = function (argument) {
|
165 | return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0;
|
166 | };
|
167 |
|
168 | var max = Math.max;
|
169 | var min$1 = Math.min;
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | var toAbsoluteIndex = function (index, length) {
|
175 | var integer = toInteger(index);
|
176 | return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
|
177 | };
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 |
|
184 | var arrayIncludes = function (IS_INCLUDES) {
|
185 | return function ($this, el, fromIndex) {
|
186 | var O = toIndexedObject($this);
|
187 | var length = toLength(O.length);
|
188 | var index = toAbsoluteIndex(fromIndex, length);
|
189 | var value;
|
190 |
|
191 |
|
192 | if (IS_INCLUDES && el != el) while (length > index) {
|
193 | value = O[index++];
|
194 |
|
195 | if (value != value) return true;
|
196 |
|
197 | } else for (;length > index; index++) if (IS_INCLUDES || index in O) {
|
198 | if (O[index] === el) return IS_INCLUDES || index || 0;
|
199 | } return !IS_INCLUDES && -1;
|
200 | };
|
201 | };
|
202 |
|
203 | var hiddenKeys = {};
|
204 |
|
205 | var arrayIndexOf = arrayIncludes(false);
|
206 |
|
207 |
|
208 | var objectKeysInternal = function (object, names) {
|
209 | var O = toIndexedObject(object);
|
210 | var i = 0;
|
211 | var result = [];
|
212 | var key;
|
213 | for (key in O) !has(hiddenKeys, key) && has(O, key) && result.push(key);
|
214 |
|
215 | while (names.length > i) if (has(O, key = names[i++])) {
|
216 | ~arrayIndexOf(result, key) || result.push(key);
|
217 | }
|
218 | return result;
|
219 | };
|
220 |
|
221 |
|
222 | var enumBugKeys = [
|
223 | 'constructor',
|
224 | 'hasOwnProperty',
|
225 | 'isPrototypeOf',
|
226 | 'propertyIsEnumerable',
|
227 | 'toLocaleString',
|
228 | 'toString',
|
229 | 'valueOf'
|
230 | ];
|
231 |
|
232 |
|
233 |
|
234 | var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype');
|
235 |
|
236 | var f$1 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
|
237 | return objectKeysInternal(O, hiddenKeys$1);
|
238 | };
|
239 |
|
240 | var objectGetOwnPropertyNames = {
|
241 | f: f$1
|
242 | };
|
243 |
|
244 | var f$2 = Object.getOwnPropertySymbols;
|
245 |
|
246 | var objectGetOwnPropertySymbols = {
|
247 | f: f$2
|
248 | };
|
249 |
|
250 | var Reflect = global.Reflect;
|
251 |
|
252 |
|
253 | var ownKeys = Reflect && Reflect.ownKeys || function ownKeys(it) {
|
254 | var keys = objectGetOwnPropertyNames.f(anObject(it));
|
255 | var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
|
256 | return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
|
257 | };
|
258 |
|
259 | var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
|
260 | var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
261 |
|
262 |
|
263 | var NASHORN_BUG = nativeGetOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({ 1: 2 }, 1);
|
264 |
|
265 | var f$3 = NASHORN_BUG ? function propertyIsEnumerable(V) {
|
266 | var descriptor = nativeGetOwnPropertyDescriptor(this, V);
|
267 | return !!descriptor && descriptor.enumerable;
|
268 | } : nativePropertyIsEnumerable;
|
269 |
|
270 | var objectPropertyIsEnumerable = {
|
271 | f: f$3
|
272 | };
|
273 |
|
274 | var createPropertyDescriptor = function (bitmap, value) {
|
275 | return {
|
276 | enumerable: !(bitmap & 1),
|
277 | configurable: !(bitmap & 2),
|
278 | writable: !(bitmap & 4),
|
279 | value: value
|
280 | };
|
281 | };
|
282 |
|
283 | var nativeGetOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
|
284 |
|
285 | var f$4 = descriptors ? nativeGetOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O, P) {
|
286 | O = toIndexedObject(O);
|
287 | P = toPrimitive(P, true);
|
288 | if (ie8DomDefine) try {
|
289 | return nativeGetOwnPropertyDescriptor$1(O, P);
|
290 | } catch (error) { }
|
291 | if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
|
292 | };
|
293 |
|
294 | var objectGetOwnPropertyDescriptor = {
|
295 | f: f$4
|
296 | };
|
297 |
|
298 | var copyConstructorProperties = function (target, source) {
|
299 | var keys = ownKeys(source);
|
300 | var defineProperty = objectDefineProperty.f;
|
301 | var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
|
302 | for (var i = 0; i < keys.length; i++) {
|
303 | var key = keys[i];
|
304 | if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
|
305 | }
|
306 | };
|
307 |
|
308 | var hide = descriptors ? function (object, key, value) {
|
309 | return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
|
310 | } : function (object, key, value) {
|
311 | object[key] = value;
|
312 | return object;
|
313 | };
|
314 |
|
315 | function createCommonjsModule(fn, module) {
|
316 | return module = { exports: {} }, fn(module, module.exports), module.exports;
|
317 | }
|
318 |
|
319 | var setGlobal = function (key, value) {
|
320 | try {
|
321 | hide(global, key, value);
|
322 | } catch (error) {
|
323 | global[key] = value;
|
324 | } return value;
|
325 | };
|
326 |
|
327 | var isPure = false;
|
328 |
|
329 | var shared = createCommonjsModule(function (module) {
|
330 | var SHARED = '__core-js_shared__';
|
331 | var store = global[SHARED] || setGlobal(SHARED, {});
|
332 |
|
333 | (module.exports = function (key, value) {
|
334 | return store[key] || (store[key] = value !== undefined ? value : {});
|
335 | })('versions', []).push({
|
336 | version: '3.0.1',
|
337 | mode: 'global',
|
338 | copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
|
339 | });
|
340 | });
|
341 |
|
342 | var functionToString = shared('native-function-to-string', Function.toString);
|
343 |
|
344 | var WeakMap = global.WeakMap;
|
345 |
|
346 | var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(functionToString.call(WeakMap));
|
347 |
|
348 | var id = 0;
|
349 | var postfix = Math.random();
|
350 |
|
351 | var uid = function (key) {
|
352 | return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + postfix).toString(36));
|
353 | };
|
354 |
|
355 | var shared$1 = shared('keys');
|
356 |
|
357 |
|
358 | var sharedKey = function (key) {
|
359 | return shared$1[key] || (shared$1[key] = uid(key));
|
360 | };
|
361 |
|
362 | var WeakMap$1 = global.WeakMap;
|
363 | var set, get, has$1;
|
364 |
|
365 | var enforce = function (it) {
|
366 | return has$1(it) ? get(it) : set(it, {});
|
367 | };
|
368 |
|
369 | var getterFor = function (TYPE) {
|
370 | return function (it) {
|
371 | var state;
|
372 | if (!isObject(it) || (state = get(it)).type !== TYPE) {
|
373 | throw TypeError('Incompatible receiver, ' + TYPE + ' required');
|
374 | } return state;
|
375 | };
|
376 | };
|
377 |
|
378 | if (nativeWeakMap) {
|
379 | var store = new WeakMap$1();
|
380 | var wmget = store.get;
|
381 | var wmhas = store.has;
|
382 | var wmset = store.set;
|
383 | set = function (it, metadata) {
|
384 | wmset.call(store, it, metadata);
|
385 | return metadata;
|
386 | };
|
387 | get = function (it) {
|
388 | return wmget.call(store, it) || {};
|
389 | };
|
390 | has$1 = function (it) {
|
391 | return wmhas.call(store, it);
|
392 | };
|
393 | } else {
|
394 | var STATE = sharedKey('state');
|
395 | hiddenKeys[STATE] = true;
|
396 | set = function (it, metadata) {
|
397 | hide(it, STATE, metadata);
|
398 | return metadata;
|
399 | };
|
400 | get = function (it) {
|
401 | return has(it, STATE) ? it[STATE] : {};
|
402 | };
|
403 | has$1 = function (it) {
|
404 | return has(it, STATE);
|
405 | };
|
406 | }
|
407 |
|
408 | var internalState = {
|
409 | set: set,
|
410 | get: get,
|
411 | has: has$1,
|
412 | enforce: enforce,
|
413 | getterFor: getterFor
|
414 | };
|
415 |
|
416 | var redefine = createCommonjsModule(function (module) {
|
417 | var getInternalState = internalState.get;
|
418 | var enforceInternalState = internalState.enforce;
|
419 | var TEMPLATE = String(functionToString).split('toString');
|
420 |
|
421 | shared('inspectSource', function (it) {
|
422 | return functionToString.call(it);
|
423 | });
|
424 |
|
425 | (module.exports = function (O, key, value, options) {
|
426 | var unsafe = options ? !!options.unsafe : false;
|
427 | var simple = options ? !!options.enumerable : false;
|
428 | var noTargetGet = options ? !!options.noTargetGet : false;
|
429 | if (typeof value == 'function') {
|
430 | if (typeof key == 'string' && !has(value, 'name')) hide(value, 'name', key);
|
431 | enforceInternalState(value).source = TEMPLATE.join(typeof key == 'string' ? key : '');
|
432 | }
|
433 | if (O === global) {
|
434 | if (simple) O[key] = value;
|
435 | else setGlobal(key, value);
|
436 | return;
|
437 | } else if (!unsafe) {
|
438 | delete O[key];
|
439 | } else if (!noTargetGet && O[key]) {
|
440 | simple = true;
|
441 | }
|
442 | if (simple) O[key] = value;
|
443 | else hide(O, key, value);
|
444 |
|
445 | })(Function.prototype, 'toString', function toString() {
|
446 | return typeof this == 'function' && getInternalState(this).source || functionToString.call(this);
|
447 | });
|
448 | });
|
449 |
|
450 | var replacement = /#|\.prototype\./;
|
451 |
|
452 | var isForced = function (feature, detection) {
|
453 | var value = data[normalize(feature)];
|
454 | return value == POLYFILL ? true
|
455 | : value == NATIVE ? false
|
456 | : typeof detection == 'function' ? fails(detection)
|
457 | : !!detection;
|
458 | };
|
459 |
|
460 | var normalize = isForced.normalize = function (string) {
|
461 | return String(string).replace(replacement, '.').toLowerCase();
|
462 | };
|
463 |
|
464 | var data = isForced.data = {};
|
465 | var NATIVE = isForced.NATIVE = 'N';
|
466 | var POLYFILL = isForced.POLYFILL = 'P';
|
467 |
|
468 | var isForced_1 = isForced;
|
469 |
|
470 | var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
|
471 |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 |
|
479 |
|
480 |
|
481 |
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
|
490 |
|
491 | var _export = function (options, source) {
|
492 | var TARGET = options.target;
|
493 | var GLOBAL = options.global;
|
494 | var STATIC = options.stat;
|
495 | var FORCED, target, key, targetProperty, sourceProperty, descriptor;
|
496 | if (GLOBAL) {
|
497 | target = global;
|
498 | } else if (STATIC) {
|
499 | target = global[TARGET] || setGlobal(TARGET, {});
|
500 | } else {
|
501 | target = (global[TARGET] || {}).prototype;
|
502 | }
|
503 | if (target) for (key in source) {
|
504 | sourceProperty = source[key];
|
505 | if (options.noTargetGet) {
|
506 | descriptor = getOwnPropertyDescriptor(target, key);
|
507 | targetProperty = descriptor && descriptor.value;
|
508 | } else targetProperty = target[key];
|
509 | FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
|
510 |
|
511 | if (!FORCED && targetProperty !== undefined) {
|
512 | if (typeof sourceProperty === typeof targetProperty) continue;
|
513 | copyConstructorProperties(sourceProperty, targetProperty);
|
514 | }
|
515 |
|
516 | if (options.sham || (targetProperty && targetProperty.sham)) {
|
517 | hide(sourceProperty, 'sham', true);
|
518 | }
|
519 |
|
520 | redefine(target, key, sourceProperty, options);
|
521 | }
|
522 | };
|
523 |
|
524 | var defineProperty = objectDefineProperty.f;
|
525 |
|
526 | var NativeSymbol = global.Symbol;
|
527 |
|
528 | if (descriptors && typeof NativeSymbol == 'function' && (!('description' in NativeSymbol.prototype) ||
|
529 |
|
530 | NativeSymbol().description !== undefined
|
531 | )) {
|
532 | var EmptyStringDescriptionStore = {};
|
533 |
|
534 | var SymbolWrapper = function Symbol() {
|
535 | var description = arguments.length < 1 || arguments[0] === undefined ? undefined : String(arguments[0]);
|
536 | var result = this instanceof SymbolWrapper
|
537 | ? new NativeSymbol(description)
|
538 |
|
539 | : description === undefined ? NativeSymbol() : NativeSymbol(description);
|
540 | if (description === '') EmptyStringDescriptionStore[result] = true;
|
541 | return result;
|
542 | };
|
543 | copyConstructorProperties(SymbolWrapper, NativeSymbol);
|
544 | var symbolPrototype = SymbolWrapper.prototype = NativeSymbol.prototype;
|
545 | symbolPrototype.constructor = SymbolWrapper;
|
546 |
|
547 | var symbolToString = symbolPrototype.toString;
|
548 | var native = String(NativeSymbol('test')) == 'Symbol(test)';
|
549 | var regexp = /^Symbol\((.*)\)[^)]+$/;
|
550 | defineProperty(symbolPrototype, 'description', {
|
551 | configurable: true,
|
552 | get: function description() {
|
553 | var symbol = isObject(this) ? this.valueOf() : this;
|
554 | var string = symbolToString.call(symbol);
|
555 | if (has(EmptyStringDescriptionStore, symbol)) return '';
|
556 | var desc = native ? string.slice(7, -1) : string.replace(regexp, '$1');
|
557 | return desc === '' ? undefined : desc;
|
558 | }
|
559 | });
|
560 |
|
561 | _export({ global: true, forced: true }, { Symbol: SymbolWrapper });
|
562 | }
|
563 |
|
564 |
|
565 | var nativeSymbol = !fails(function () {
|
566 |
|
567 | return !String(Symbol());
|
568 | });
|
569 |
|
570 | var store$1 = shared('wks');
|
571 |
|
572 | var Symbol$1 = global.Symbol;
|
573 |
|
574 |
|
575 | var wellKnownSymbol = function (name) {
|
576 | return store$1[name] || (store$1[name] = nativeSymbol && Symbol$1[name]
|
577 | || (nativeSymbol ? Symbol$1 : uid)('Symbol.' + name));
|
578 | };
|
579 |
|
580 |
|
581 |
|
582 |
|
583 |
|
584 | var objectKeys = Object.keys || function keys(O) {
|
585 | return objectKeysInternal(O, enumBugKeys);
|
586 | };
|
587 |
|
588 | var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
|
589 | anObject(O);
|
590 | var keys = objectKeys(Properties);
|
591 | var length = keys.length;
|
592 | var i = 0;
|
593 | var key;
|
594 | while (length > i) objectDefineProperty.f(O, key = keys[i++], Properties[key]);
|
595 | return O;
|
596 | };
|
597 |
|
598 | var document$2 = global.document;
|
599 |
|
600 | var html = document$2 && document$2.documentElement;
|
601 |
|
602 |
|
603 |
|
604 |
|
605 |
|
606 |
|
607 |
|
608 | var IE_PROTO = sharedKey('IE_PROTO');
|
609 | var PROTOTYPE = 'prototype';
|
610 | var Empty = function () { };
|
611 |
|
612 |
|
613 | var createDict = function () {
|
614 |
|
615 | var iframe = documentCreateElement('iframe');
|
616 | var length = enumBugKeys.length;
|
617 | var lt = '<';
|
618 | var script = 'script';
|
619 | var gt = '>';
|
620 | var js = 'java' + script + ':';
|
621 | var iframeDocument;
|
622 | iframe.style.display = 'none';
|
623 | html.appendChild(iframe);
|
624 | iframe.src = String(js);
|
625 | iframeDocument = iframe.contentWindow.document;
|
626 | iframeDocument.open();
|
627 | iframeDocument.write(lt + script + gt + 'document.F=Object' + lt + '/' + script + gt);
|
628 | iframeDocument.close();
|
629 | createDict = iframeDocument.F;
|
630 | while (length--) delete createDict[PROTOTYPE][enumBugKeys[length]];
|
631 | return createDict();
|
632 | };
|
633 |
|
634 | var objectCreate = Object.create || function create(O, Properties) {
|
635 | var result;
|
636 | if (O !== null) {
|
637 | Empty[PROTOTYPE] = anObject(O);
|
638 | result = new Empty();
|
639 | Empty[PROTOTYPE] = null;
|
640 |
|
641 | result[IE_PROTO] = O;
|
642 | } else result = createDict();
|
643 | return Properties === undefined ? result : objectDefineProperties(result, Properties);
|
644 | };
|
645 |
|
646 | hiddenKeys[IE_PROTO] = true;
|
647 |
|
648 | var UNSCOPABLES = wellKnownSymbol('unscopables');
|
649 |
|
650 |
|
651 | var ArrayPrototype = Array.prototype;
|
652 |
|
653 |
|
654 |
|
655 | if (ArrayPrototype[UNSCOPABLES] == undefined) {
|
656 | hide(ArrayPrototype, UNSCOPABLES, objectCreate(null));
|
657 | }
|
658 |
|
659 |
|
660 | var addToUnscopables = function (key) {
|
661 | ArrayPrototype[UNSCOPABLES][key] = true;
|
662 | };
|
663 |
|
664 | var iterators = {};
|
665 |
|
666 |
|
667 |
|
668 | var toObject = function (argument) {
|
669 | return Object(requireObjectCoercible(argument));
|
670 | };
|
671 |
|
672 | var correctPrototypeGetter = !fails(function () {
|
673 | function F() { }
|
674 | F.prototype.constructor = null;
|
675 | return Object.getPrototypeOf(new F()) !== F.prototype;
|
676 | });
|
677 |
|
678 |
|
679 |
|
680 |
|
681 | var IE_PROTO$1 = sharedKey('IE_PROTO');
|
682 |
|
683 | var ObjectPrototype = Object.prototype;
|
684 |
|
685 | var objectGetPrototypeOf = correctPrototypeGetter ? Object.getPrototypeOf : function (O) {
|
686 | O = toObject(O);
|
687 | if (has(O, IE_PROTO$1)) return O[IE_PROTO$1];
|
688 | if (typeof O.constructor == 'function' && O instanceof O.constructor) {
|
689 | return O.constructor.prototype;
|
690 | } return O instanceof Object ? ObjectPrototype : null;
|
691 | };
|
692 |
|
693 | var ITERATOR = wellKnownSymbol('iterator');
|
694 | var BUGGY_SAFARI_ITERATORS = false;
|
695 |
|
696 | var returnThis = function () { return this; };
|
697 |
|
698 |
|
699 |
|
700 | var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;
|
701 |
|
702 | if ([].keys) {
|
703 | arrayIterator = [].keys();
|
704 |
|
705 | if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
|
706 | else {
|
707 | PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator));
|
708 | if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
|
709 | }
|
710 | }
|
711 |
|
712 | if (IteratorPrototype == undefined) IteratorPrototype = {};
|
713 |
|
714 |
|
715 | if (!has(IteratorPrototype, ITERATOR)) hide(IteratorPrototype, ITERATOR, returnThis);
|
716 |
|
717 | var iteratorsCore = {
|
718 | IteratorPrototype: IteratorPrototype,
|
719 | BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
|
720 | };
|
721 |
|
722 | var defineProperty$1 = objectDefineProperty.f;
|
723 |
|
724 | var TO_STRING_TAG = wellKnownSymbol('toStringTag');
|
725 |
|
726 | var setToStringTag = function (it, TAG, STATIC) {
|
727 | if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {
|
728 | defineProperty$1(it, TO_STRING_TAG, { configurable: true, value: TAG });
|
729 | }
|
730 | };
|
731 |
|
732 | var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
|
733 |
|
734 |
|
735 |
|
736 |
|
737 |
|
738 | var returnThis$1 = function () { return this; };
|
739 |
|
740 | var createIteratorConstructor = function (IteratorConstructor, NAME, next) {
|
741 | var TO_STRING_TAG = NAME + ' Iterator';
|
742 | IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, { next: createPropertyDescriptor(1, next) });
|
743 | setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true);
|
744 | iterators[TO_STRING_TAG] = returnThis$1;
|
745 | return IteratorConstructor;
|
746 | };
|
747 |
|
748 | var validateSetPrototypeOfArguments = function (O, proto) {
|
749 | anObject(O);
|
750 | if (!isObject(proto) && proto !== null) {
|
751 | throw TypeError("Can't set " + String(proto) + ' as a prototype');
|
752 | }
|
753 | };
|
754 |
|
755 |
|
756 |
|
757 |
|
758 |
|
759 | var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
|
760 | var correctSetter = false;
|
761 | var test = {};
|
762 | var setter;
|
763 | try {
|
764 | setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
|
765 | setter.call(test, []);
|
766 | correctSetter = test instanceof Array;
|
767 | } catch (error) { }
|
768 | return function setPrototypeOf(O, proto) {
|
769 | validateSetPrototypeOfArguments(O, proto);
|
770 | if (correctSetter) setter.call(O, proto);
|
771 | else O.__proto__ = proto;
|
772 | return O;
|
773 | };
|
774 | }() : undefined);
|
775 |
|
776 | var ITERATOR$1 = wellKnownSymbol('iterator');
|
777 |
|
778 |
|
779 | var IteratorPrototype$2 = iteratorsCore.IteratorPrototype;
|
780 | var BUGGY_SAFARI_ITERATORS$1 = iteratorsCore.BUGGY_SAFARI_ITERATORS;
|
781 | var KEYS = 'keys';
|
782 | var VALUES = 'values';
|
783 | var ENTRIES = 'entries';
|
784 |
|
785 | var returnThis$2 = function () { return this; };
|
786 |
|
787 | var defineIterator = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
|
788 | createIteratorConstructor(IteratorConstructor, NAME, next);
|
789 |
|
790 | var getIterationMethod = function (KIND) {
|
791 | if (KIND === DEFAULT && defaultIterator) return defaultIterator;
|
792 | if (!BUGGY_SAFARI_ITERATORS$1 && KIND in IterablePrototype) return IterablePrototype[KIND];
|
793 | switch (KIND) {
|
794 | case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
|
795 | case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
|
796 | case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
|
797 | } return function () { return new IteratorConstructor(this); };
|
798 | };
|
799 |
|
800 | var TO_STRING_TAG = NAME + ' Iterator';
|
801 | var INCORRECT_VALUES_NAME = false;
|
802 | var IterablePrototype = Iterable.prototype;
|
803 | var nativeIterator = IterablePrototype[ITERATOR$1]
|
804 | || IterablePrototype['@@iterator']
|
805 | || DEFAULT && IterablePrototype[DEFAULT];
|
806 | var defaultIterator = !BUGGY_SAFARI_ITERATORS$1 && nativeIterator || getIterationMethod(DEFAULT);
|
807 | var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
|
808 | var CurrentIteratorPrototype, methods, KEY;
|
809 |
|
810 |
|
811 | if (anyNativeIterator) {
|
812 | CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable()));
|
813 | if (IteratorPrototype$2 !== Object.prototype && CurrentIteratorPrototype.next) {
|
814 | if (objectGetPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype$2) {
|
815 | if (objectSetPrototypeOf) {
|
816 | objectSetPrototypeOf(CurrentIteratorPrototype, IteratorPrototype$2);
|
817 | } else if (typeof CurrentIteratorPrototype[ITERATOR$1] != 'function') {
|
818 | hide(CurrentIteratorPrototype, ITERATOR$1, returnThis$2);
|
819 | }
|
820 | }
|
821 |
|
822 | setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);
|
823 | }
|
824 | }
|
825 |
|
826 |
|
827 | if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
|
828 | INCORRECT_VALUES_NAME = true;
|
829 | defaultIterator = function values() { return nativeIterator.call(this); };
|
830 | }
|
831 |
|
832 |
|
833 | if (IterablePrototype[ITERATOR$1] !== defaultIterator) {
|
834 | hide(IterablePrototype, ITERATOR$1, defaultIterator);
|
835 | }
|
836 | iterators[NAME] = defaultIterator;
|
837 |
|
838 |
|
839 | if (DEFAULT) {
|
840 | methods = {
|
841 | values: getIterationMethod(VALUES),
|
842 | keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
|
843 | entries: getIterationMethod(ENTRIES)
|
844 | };
|
845 | if (FORCED) for (KEY in methods) {
|
846 | if (BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
|
847 | redefine(IterablePrototype, KEY, methods[KEY]);
|
848 | }
|
849 | } else _export({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME }, methods);
|
850 | }
|
851 |
|
852 | return methods;
|
853 | };
|
854 |
|
855 | var ARRAY_ITERATOR = 'Array Iterator';
|
856 | var setInternalState = internalState.set;
|
857 | var getInternalState = internalState.getterFor(ARRAY_ITERATOR);
|
858 |
|
859 |
|
860 |
|
861 |
|
862 |
|
863 |
|
864 |
|
865 |
|
866 |
|
867 |
|
868 |
|
869 | var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind) {
|
870 | setInternalState(this, {
|
871 | type: ARRAY_ITERATOR,
|
872 | target: toIndexedObject(iterated),
|
873 | index: 0,
|
874 | kind: kind
|
875 | });
|
876 |
|
877 |
|
878 | }, function () {
|
879 | var state = getInternalState(this);
|
880 | var target = state.target;
|
881 | var kind = state.kind;
|
882 | var index = state.index++;
|
883 | if (!target || index >= target.length) {
|
884 | state.target = undefined;
|
885 | return { value: undefined, done: true };
|
886 | }
|
887 | if (kind == 'keys') return { value: index, done: false };
|
888 | if (kind == 'values') return { value: target[index], done: false };
|
889 | return { value: [index, target[index]], done: false };
|
890 | }, 'values');
|
891 |
|
892 |
|
893 |
|
894 |
|
895 | iterators.Arguments = iterators.Array;
|
896 |
|
897 |
|
898 | addToUnscopables('keys');
|
899 | addToUnscopables('values');
|
900 | addToUnscopables('entries');
|
901 |
|
902 | var aFunction = function (it) {
|
903 | if (typeof it != 'function') {
|
904 | throw TypeError(String(it) + ' is not a function');
|
905 | } return it;
|
906 | };
|
907 |
|
908 | var anInstance = function (it, Constructor, name) {
|
909 | if (!(it instanceof Constructor)) {
|
910 | throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
|
911 | } return it;
|
912 | };
|
913 |
|
914 |
|
915 |
|
916 | var ITERATOR$2 = wellKnownSymbol('iterator');
|
917 | var ArrayPrototype$1 = Array.prototype;
|
918 |
|
919 | var isArrayIteratorMethod = function (it) {
|
920 | return it !== undefined && (iterators.Array === it || ArrayPrototype$1[ITERATOR$2] === it);
|
921 | };
|
922 |
|
923 |
|
924 | var bindContext = function (fn, that, length) {
|
925 | aFunction(fn);
|
926 | if (that === undefined) return fn;
|
927 | switch (length) {
|
928 | case 0: return function () {
|
929 | return fn.call(that);
|
930 | };
|
931 | case 1: return function (a) {
|
932 | return fn.call(that, a);
|
933 | };
|
934 | case 2: return function (a, b) {
|
935 | return fn.call(that, a, b);
|
936 | };
|
937 | case 3: return function (a, b, c) {
|
938 | return fn.call(that, a, b, c);
|
939 | };
|
940 | }
|
941 | return function (/* ...args */) {
|
942 | return fn.apply(that, arguments);
|
943 | };
|
944 | };
|
945 |
|
946 | var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
|
947 |
|
948 | var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) == 'Arguments';
|
949 |
|
950 |
|
951 | var tryGet = function (it, key) {
|
952 | try {
|
953 | return it[key];
|
954 | } catch (error) { }
|
955 | };
|
956 |
|
957 |
|
958 | var classof = function (it) {
|
959 | var O, tag, result;
|
960 | return it === undefined ? 'Undefined' : it === null ? 'Null'
|
961 |
|
962 | : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$1)) == 'string' ? tag
|
963 |
|
964 | : CORRECT_ARGUMENTS ? classofRaw(O)
|
965 |
|
966 | : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
|
967 | };
|
968 |
|
969 | var ITERATOR$3 = wellKnownSymbol('iterator');
|
970 |
|
971 |
|
972 | var getIteratorMethod = function (it) {
|
973 | if (it != undefined) return it[ITERATOR$3]
|
974 | || it['@@iterator']
|
975 | || iterators[classof(it)];
|
976 | };
|
977 |
|
978 |
|
979 | var callWithSafeIterationClosing = function (iterator, fn, value, ENTRIES) {
|
980 | try {
|
981 | return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);
|
982 |
|
983 | } catch (error) {
|
984 | var returnMethod = iterator['return'];
|
985 | if (returnMethod !== undefined) anObject(returnMethod.call(iterator));
|
986 | throw error;
|
987 | }
|
988 | };
|
989 |
|
990 | var iterate = createCommonjsModule(function (module) {
|
991 | var BREAK = {};
|
992 |
|
993 | var exports = module.exports = function (iterable, fn, that, ENTRIES, ITERATOR) {
|
994 | var boundFunction = bindContext(fn, that, ENTRIES ? 2 : 1);
|
995 | var iterator, iterFn, index, length, result, step;
|
996 |
|
997 | if (ITERATOR) {
|
998 | iterator = iterable;
|
999 | } else {
|
1000 | iterFn = getIteratorMethod(iterable);
|
1001 | if (typeof iterFn != 'function') throw TypeError('Target is not iterable');
|
1002 |
|
1003 | if (isArrayIteratorMethod(iterFn)) {
|
1004 | for (index = 0, length = toLength(iterable.length); length > index; index++) {
|
1005 | result = ENTRIES ? boundFunction(anObject(step = iterable[index])[0], step[1]) : boundFunction(iterable[index]);
|
1006 | if (result === BREAK) return BREAK;
|
1007 | } return;
|
1008 | }
|
1009 | iterator = iterFn.call(iterable);
|
1010 | }
|
1011 |
|
1012 | while (!(step = iterator.next()).done) {
|
1013 | if (callWithSafeIterationClosing(iterator, boundFunction, step.value, ENTRIES) === BREAK) return BREAK;
|
1014 | }
|
1015 | };
|
1016 |
|
1017 | exports.BREAK = BREAK;
|
1018 | });
|
1019 |
|
1020 | var ITERATOR$4 = wellKnownSymbol('iterator');
|
1021 | var SAFE_CLOSING = false;
|
1022 |
|
1023 | try {
|
1024 | var called = 0;
|
1025 | var iteratorWithReturn = {
|
1026 | next: function () {
|
1027 | return { done: !!called++ };
|
1028 | },
|
1029 | 'return': function () {
|
1030 | SAFE_CLOSING = true;
|
1031 | }
|
1032 | };
|
1033 | iteratorWithReturn[ITERATOR$4] = function () {
|
1034 | return this;
|
1035 | };
|
1036 | } catch (error) { }
|
1037 |
|
1038 | var checkCorrectnessOfIteration = function (exec, SKIP_CLOSING) {
|
1039 | if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
|
1040 | var ITERATION_SUPPORT = false;
|
1041 | try {
|
1042 | var object = {};
|
1043 | object[ITERATOR$4] = function () {
|
1044 | return {
|
1045 | next: function () {
|
1046 | return { done: ITERATION_SUPPORT = true };
|
1047 | }
|
1048 | };
|
1049 | };
|
1050 | exec(object);
|
1051 | } catch (error) { }
|
1052 | return ITERATION_SUPPORT;
|
1053 | };
|
1054 |
|
1055 | var SPECIES = wellKnownSymbol('species');
|
1056 |
|
1057 |
|
1058 |
|
1059 | var speciesConstructor = function (O, defaultConstructor) {
|
1060 | var C = anObject(O).constructor;
|
1061 | var S;
|
1062 | return C === undefined || (S = anObject(C)[SPECIES]) == undefined ? defaultConstructor : aFunction(S);
|
1063 | };
|
1064 |
|
1065 | var set$1 = global.setImmediate;
|
1066 | var clear = global.clearImmediate;
|
1067 | var process$1 = global.process;
|
1068 | var MessageChannel = global.MessageChannel;
|
1069 | var Dispatch = global.Dispatch;
|
1070 | var counter = 0;
|
1071 | var queue = {};
|
1072 | var ONREADYSTATECHANGE = 'onreadystatechange';
|
1073 | var defer, channel, port;
|
1074 |
|
1075 | var run = function () {
|
1076 | var id = +this;
|
1077 |
|
1078 | if (queue.hasOwnProperty(id)) {
|
1079 | var fn = queue[id];
|
1080 | delete queue[id];
|
1081 | fn();
|
1082 | }
|
1083 | };
|
1084 |
|
1085 | var listener = function (event) {
|
1086 | run.call(event.data);
|
1087 | };
|
1088 |
|
1089 |
|
1090 | if (!set$1 || !clear) {
|
1091 | set$1 = function setImmediate(fn) {
|
1092 | var args = [];
|
1093 | var i = 1;
|
1094 | while (arguments.length > i) args.push(arguments[i++]);
|
1095 | queue[++counter] = function () {
|
1096 |
|
1097 | (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
|
1098 | };
|
1099 | defer(counter);
|
1100 | return counter;
|
1101 | };
|
1102 | clear = function clearImmediate(id) {
|
1103 | delete queue[id];
|
1104 | };
|
1105 |
|
1106 | if (classofRaw(process$1) == 'process') {
|
1107 | defer = function (id) {
|
1108 | process$1.nextTick(bindContext(run, id, 1));
|
1109 | };
|
1110 |
|
1111 | } else if (Dispatch && Dispatch.now) {
|
1112 | defer = function (id) {
|
1113 | Dispatch.now(bindContext(run, id, 1));
|
1114 | };
|
1115 |
|
1116 | } else if (MessageChannel) {
|
1117 | channel = new MessageChannel();
|
1118 | port = channel.port2;
|
1119 | channel.port1.onmessage = listener;
|
1120 | defer = bindContext(port.postMessage, port, 1);
|
1121 |
|
1122 |
|
1123 | } else if (global.addEventListener && typeof postMessage == 'function' && !global.importScripts) {
|
1124 | defer = function (id) {
|
1125 | global.postMessage(id + '', '*');
|
1126 | };
|
1127 | global.addEventListener('message', listener, false);
|
1128 |
|
1129 | } else if (ONREADYSTATECHANGE in documentCreateElement('script')) {
|
1130 | defer = function (id) {
|
1131 | html.appendChild(documentCreateElement('script'))[ONREADYSTATECHANGE] = function () {
|
1132 | html.removeChild(this);
|
1133 | run.call(id);
|
1134 | };
|
1135 | };
|
1136 |
|
1137 | } else {
|
1138 | defer = function (id) {
|
1139 | setTimeout(bindContext(run, id, 1), 0);
|
1140 | };
|
1141 | }
|
1142 | }
|
1143 |
|
1144 | var task = {
|
1145 | set: set$1,
|
1146 | clear: clear
|
1147 | };
|
1148 |
|
1149 | var navigator = global.navigator;
|
1150 |
|
1151 | var userAgent = navigator && navigator.userAgent || '';
|
1152 |
|
1153 | var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
|
1154 |
|
1155 | var macrotask = task.set;
|
1156 |
|
1157 | var MutationObserver = global.MutationObserver || global.WebKitMutationObserver;
|
1158 | var process$2 = global.process;
|
1159 | var Promise$1 = global.Promise;
|
1160 | var IS_NODE = classofRaw(process$2) == 'process';
|
1161 | // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask`
|
1162 | var queueMicrotaskDescriptor = getOwnPropertyDescriptor$1(global, 'queueMicrotask');
|
1163 | var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value;
|
1164 |
|
1165 | var flush, head, last, notify, toggle, node, promise;
|
1166 |
|
1167 | // modern engines have queueMicrotask method
|
1168 | if (!queueMicrotask) {
|
1169 | flush = function () {
|
1170 | var parent, fn;
|
1171 | if (IS_NODE && (parent = process$2.domain)) parent.exit();
|
1172 | while (head) {
|
1173 | fn = head.fn;
|
1174 | head = head.next;
|
1175 | try {
|
1176 | fn();
|
1177 | } catch (error) {
|
1178 | if (head) notify();
|
1179 | else last = undefined;
|
1180 | throw error;
|
1181 | }
|
1182 | } last = undefined;
|
1183 | if (parent) parent.enter();
|
1184 | };
|
1185 |
|
1186 |
|
1187 | if (IS_NODE) {
|
1188 | notify = function () {
|
1189 | process$2.nextTick(flush);
|
1190 | };
|
1191 |
|
1192 | } else if (MutationObserver && !/(iPhone|iPod|iPad).*AppleWebKit/i.test(userAgent)) {
|
1193 | toggle = true;
|
1194 | node = document.createTextNode('');
|
1195 | new MutationObserver(flush).observe(node, { characterData: true });
|
1196 | notify = function () {
|
1197 | node.data = toggle = !toggle;
|
1198 | };
|
1199 |
|
1200 | } else if (Promise$1 && Promise$1.resolve) {
|
1201 |
|
1202 | promise = Promise$1.resolve(undefined);
|
1203 | notify = function () {
|
1204 | promise.then(flush);
|
1205 | };
|
1206 |
|
1207 |
|
1208 |
|
1209 |
|
1210 |
|
1211 |
|
1212 | } else {
|
1213 | notify = function () {
|
1214 |
|
1215 | macrotask.call(global, flush);
|
1216 | };
|
1217 | }
|
1218 | }
|
1219 |
|
1220 | var microtask = queueMicrotask || function (fn) {
|
1221 | var task = { fn: fn, next: undefined };
|
1222 | if (last) last.next = task;
|
1223 | if (!head) {
|
1224 | head = task;
|
1225 | notify();
|
1226 | } last = task;
|
1227 | };
|
1228 |
|
1229 |
|
1230 |
|
1231 |
|
1232 | var PromiseCapability = function (C) {
|
1233 | var resolve, reject;
|
1234 | this.promise = new C(function ($$resolve, $$reject) {
|
1235 | if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
|
1236 | resolve = $$resolve;
|
1237 | reject = $$reject;
|
1238 | });
|
1239 | this.resolve = aFunction(resolve);
|
1240 | this.reject = aFunction(reject);
|
1241 | };
|
1242 |
|
1243 | var f$5 = function (C) {
|
1244 | return new PromiseCapability(C);
|
1245 | };
|
1246 |
|
1247 | var newPromiseCapability = {
|
1248 | f: f$5
|
1249 | };
|
1250 |
|
1251 | var promiseResolve = function (C, x) {
|
1252 | anObject(C);
|
1253 | if (isObject(x) && x.constructor === C) return x;
|
1254 | var promiseCapability = newPromiseCapability.f(C);
|
1255 | var resolve = promiseCapability.resolve;
|
1256 | resolve(x);
|
1257 | return promiseCapability.promise;
|
1258 | };
|
1259 |
|
1260 | var hostReportErrors = function (a, b) {
|
1261 | var console = global.console;
|
1262 | if (console && console.error) {
|
1263 | arguments.length === 1 ? console.error(a) : console.error(a, b);
|
1264 | }
|
1265 | };
|
1266 |
|
1267 | var perform = function (exec) {
|
1268 | try {
|
1269 | return { error: false, value: exec() };
|
1270 | } catch (error) {
|
1271 | return { error: true, value: error };
|
1272 | }
|
1273 | };
|
1274 |
|
1275 | var redefineAll = function (target, src, options) {
|
1276 | for (var key in src) redefine(target, key, src[key], options);
|
1277 | return target;
|
1278 | };
|
1279 |
|
1280 | var path = global;
|
1281 |
|
1282 | var aFunction$1 = function (variable) {
|
1283 | return typeof variable == 'function' ? variable : undefined;
|
1284 | };
|
1285 |
|
1286 | var getBuiltIn = function (namespace, method) {
|
1287 | return arguments.length < 2 ? aFunction$1(path[namespace]) || aFunction$1(global[namespace])
|
1288 | : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];
|
1289 | };
|
1290 |
|
1291 | var SPECIES$1 = wellKnownSymbol('species');
|
1292 |
|
1293 | var setSpecies = function (CONSTRUCTOR_NAME) {
|
1294 | var C = getBuiltIn(CONSTRUCTOR_NAME);
|
1295 | var defineProperty = objectDefineProperty.f;
|
1296 | if (descriptors && C && !C[SPECIES$1]) defineProperty(C, SPECIES$1, {
|
1297 | configurable: true,
|
1298 | get: function () { return this; }
|
1299 | });
|
1300 | };
|
1301 |
|
1302 | var PROMISE = 'Promise';
|
1303 |
|
1304 |
|
1305 |
|
1306 |
|
1307 |
|
1308 |
|
1309 |
|
1310 |
|
1311 |
|
1312 |
|
1313 | var task$1 = task.set;
|
1314 |
|
1315 |
|
1316 |
|
1317 |
|
1318 |
|
1319 |
|
1320 | var SPECIES$2 = wellKnownSymbol('species');
|
1321 |
|
1322 |
|
1323 | var getInternalState$1 = internalState.get;
|
1324 | var setInternalState$1 = internalState.set;
|
1325 | var getInternalPromiseState = internalState.getterFor(PROMISE);
|
1326 | var PromiseConstructor = global[PROMISE];
|
1327 | var TypeError$1 = global.TypeError;
|
1328 | var document$3 = global.document;
|
1329 | var process$3 = global.process;
|
1330 | var $fetch = global.fetch;
|
1331 | var versions = process$3 && process$3.versions;
|
1332 | var v8 = versions && versions.v8 || '';
|
1333 | var newPromiseCapability$1 = newPromiseCapability.f;
|
1334 | var newGenericPromiseCapability = newPromiseCapability$1;
|
1335 | var IS_NODE$1 = classofRaw(process$3) == 'process';
|
1336 | var DISPATCH_EVENT = !!(document$3 && document$3.createEvent && global.dispatchEvent);
|
1337 | var UNHANDLED_REJECTION = 'unhandledrejection';
|
1338 | var REJECTION_HANDLED = 'rejectionhandled';
|
1339 | var PENDING = 0;
|
1340 | var FULFILLED = 1;
|
1341 | var REJECTED = 2;
|
1342 | var HANDLED = 1;
|
1343 | var UNHANDLED = 2;
|
1344 | var Internal, OwnPromiseCapability, PromiseWrapper;
|
1345 |
|
1346 | var FORCED = isForced_1(PROMISE, function () {
|
1347 |
|
1348 | var promise = PromiseConstructor.resolve(1);
|
1349 | var empty = function () { };
|
1350 | var FakePromise = (promise.constructor = {})[SPECIES$2] = function (exec) {
|
1351 | exec(empty, empty);
|
1352 | };
|
1353 |
|
1354 | return !((IS_NODE$1 || typeof PromiseRejectionEvent == 'function')
|
1355 | && (!isPure || promise['finally'])
|
1356 | && promise.then(empty) instanceof FakePromise
|
1357 |
|
1358 |
|
1359 |
|
1360 | && v8.indexOf('6.6') !== 0
|
1361 | && userAgent.indexOf('Chrome/66') === -1);
|
1362 | });
|
1363 |
|
1364 | var INCORRECT_ITERATION = FORCED || !checkCorrectnessOfIteration(function (iterable) {
|
1365 | PromiseConstructor.all(iterable)['catch'](function () { });
|
1366 | });
|
1367 |
|
1368 |
|
1369 | var isThenable = function (it) {
|
1370 | var then;
|
1371 | return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
|
1372 | };
|
1373 |
|
1374 | var notify$1 = function (promise, state, isReject) {
|
1375 | if (state.notified) return;
|
1376 | state.notified = true;
|
1377 | var chain = state.reactions;
|
1378 | microtask(function () {
|
1379 | var value = state.value;
|
1380 | var ok = state.state == FULFILLED;
|
1381 | var i = 0;
|
1382 | var run = function (reaction) {
|
1383 | var handler = ok ? reaction.ok : reaction.fail;
|
1384 | var resolve = reaction.resolve;
|
1385 | var reject = reaction.reject;
|
1386 | var domain = reaction.domain;
|
1387 | var result, then, exited;
|
1388 | try {
|
1389 | if (handler) {
|
1390 | if (!ok) {
|
1391 | if (state.rejection === UNHANDLED) onHandleUnhandled(promise, state);
|
1392 | state.rejection = HANDLED;
|
1393 | }
|
1394 | if (handler === true) result = value;
|
1395 | else {
|
1396 | if (domain) domain.enter();
|
1397 | result = handler(value);
|
1398 | if (domain) {
|
1399 | domain.exit();
|
1400 | exited = true;
|
1401 | }
|
1402 | }
|
1403 | if (result === reaction.promise) {
|
1404 | reject(TypeError$1('Promise-chain cycle'));
|
1405 | } else if (then = isThenable(result)) {
|
1406 | then.call(result, resolve, reject);
|
1407 | } else resolve(result);
|
1408 | } else reject(value);
|
1409 | } catch (error) {
|
1410 | if (domain && !exited) domain.exit();
|
1411 | reject(error);
|
1412 | }
|
1413 | };
|
1414 | while (chain.length > i) run(chain[i++]);
|
1415 | state.reactions = [];
|
1416 | state.notified = false;
|
1417 | if (isReject && !state.rejection) onUnhandled(promise, state);
|
1418 | });
|
1419 | };
|
1420 |
|
1421 | var dispatchEvent = function (name, promise, reason) {
|
1422 | var event, handler;
|
1423 | if (DISPATCH_EVENT) {
|
1424 | event = document$3.createEvent('Event');
|
1425 | event.promise = promise;
|
1426 | event.reason = reason;
|
1427 | event.initEvent(name, false, true);
|
1428 | global.dispatchEvent(event);
|
1429 | } else event = { promise: promise, reason: reason };
|
1430 | if (handler = global['on' + name]) handler(event);
|
1431 | else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
|
1432 | };
|
1433 |
|
1434 | var onUnhandled = function (promise, state) {
|
1435 | task$1.call(global, function () {
|
1436 | var value = state.value;
|
1437 | var IS_UNHANDLED = isUnhandled(state);
|
1438 | var result;
|
1439 | if (IS_UNHANDLED) {
|
1440 | result = perform(function () {
|
1441 | if (IS_NODE$1) {
|
1442 | process$3.emit('unhandledRejection', value, promise);
|
1443 | } else dispatchEvent(UNHANDLED_REJECTION, promise, value);
|
1444 | });
|
1445 |
|
1446 | state.rejection = IS_NODE$1 || isUnhandled(state) ? UNHANDLED : HANDLED;
|
1447 | if (result.error) throw result.value;
|
1448 | }
|
1449 | });
|
1450 | };
|
1451 |
|
1452 | var isUnhandled = function (state) {
|
1453 | return state.rejection !== HANDLED && !state.parent;
|
1454 | };
|
1455 |
|
1456 | var onHandleUnhandled = function (promise, state) {
|
1457 | task$1.call(global, function () {
|
1458 | if (IS_NODE$1) {
|
1459 | process$3.emit('rejectionHandled', promise);
|
1460 | } else dispatchEvent(REJECTION_HANDLED, promise, state.value);
|
1461 | });
|
1462 | };
|
1463 |
|
1464 | var bind = function (fn, promise, state, unwrap) {
|
1465 | return function (value) {
|
1466 | fn(promise, state, value, unwrap);
|
1467 | };
|
1468 | };
|
1469 |
|
1470 | var internalReject = function (promise, state, value, unwrap) {
|
1471 | if (state.done) return;
|
1472 | state.done = true;
|
1473 | if (unwrap) state = unwrap;
|
1474 | state.value = value;
|
1475 | state.state = REJECTED;
|
1476 | notify$1(promise, state, true);
|
1477 | };
|
1478 |
|
1479 | var internalResolve = function (promise, state, value, unwrap) {
|
1480 | if (state.done) return;
|
1481 | state.done = true;
|
1482 | if (unwrap) state = unwrap;
|
1483 | try {
|
1484 | if (promise === value) throw TypeError$1("Promise can't be resolved itself");
|
1485 | var then = isThenable(value);
|
1486 | if (then) {
|
1487 | microtask(function () {
|
1488 | var wrapper = { done: false };
|
1489 | try {
|
1490 | then.call(value,
|
1491 | bind(internalResolve, promise, wrapper, state),
|
1492 | bind(internalReject, promise, wrapper, state)
|
1493 | );
|
1494 | } catch (error) {
|
1495 | internalReject(promise, wrapper, error, state);
|
1496 | }
|
1497 | });
|
1498 | } else {
|
1499 | state.value = value;
|
1500 | state.state = FULFILLED;
|
1501 | notify$1(promise, state, false);
|
1502 | }
|
1503 | } catch (error) {
|
1504 | internalReject(promise, { done: false }, error, state);
|
1505 | }
|
1506 | };
|
1507 |
|
1508 |
|
1509 | if (FORCED) {
|
1510 |
|
1511 | PromiseConstructor = function Promise(executor) {
|
1512 | anInstance(this, PromiseConstructor, PROMISE);
|
1513 | aFunction(executor);
|
1514 | Internal.call(this);
|
1515 | var state = getInternalState$1(this);
|
1516 | try {
|
1517 | executor(bind(internalResolve, this, state), bind(internalReject, this, state));
|
1518 | } catch (error) {
|
1519 | internalReject(this, state, error);
|
1520 | }
|
1521 | };
|
1522 |
|
1523 | Internal = function Promise(executor) {
|
1524 | setInternalState$1(this, {
|
1525 | type: PROMISE,
|
1526 | done: false,
|
1527 | notified: false,
|
1528 | parent: false,
|
1529 | reactions: [],
|
1530 | rejection: false,
|
1531 | state: PENDING,
|
1532 | value: undefined
|
1533 | });
|
1534 | };
|
1535 | Internal.prototype = redefineAll(PromiseConstructor.prototype, {
|
1536 |
|
1537 |
|
1538 | then: function then(onFulfilled, onRejected) {
|
1539 | var state = getInternalPromiseState(this);
|
1540 | var reaction = newPromiseCapability$1(speciesConstructor(this, PromiseConstructor));
|
1541 | reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
|
1542 | reaction.fail = typeof onRejected == 'function' && onRejected;
|
1543 | reaction.domain = IS_NODE$1 ? process$3.domain : undefined;
|
1544 | state.parent = true;
|
1545 | state.reactions.push(reaction);
|
1546 | if (state.state != PENDING) notify$1(this, state, false);
|
1547 | return reaction.promise;
|
1548 | },
|
1549 |
|
1550 |
|
1551 | 'catch': function (onRejected) {
|
1552 | return this.then(undefined, onRejected);
|
1553 | }
|
1554 | });
|
1555 | OwnPromiseCapability = function () {
|
1556 | var promise = new Internal();
|
1557 | var state = getInternalState$1(promise);
|
1558 | this.promise = promise;
|
1559 | this.resolve = bind(internalResolve, promise, state);
|
1560 | this.reject = bind(internalReject, promise, state);
|
1561 | };
|
1562 | newPromiseCapability.f = newPromiseCapability$1 = function (C) {
|
1563 | return C === PromiseConstructor || C === PromiseWrapper
|
1564 | ? new OwnPromiseCapability(C)
|
1565 | : newGenericPromiseCapability(C);
|
1566 | };
|
1567 |
|
1568 |
|
1569 | if (typeof $fetch == 'function') _export({ global: true, enumerable: true, forced: true }, {
|
1570 |
|
1571 | fetch: function fetch(input) {
|
1572 | return promiseResolve(PromiseConstructor, $fetch.apply(global, arguments));
|
1573 | }
|
1574 | });
|
1575 | }
|
1576 |
|
1577 | _export({ global: true, wrap: true, forced: FORCED }, { Promise: PromiseConstructor });
|
1578 |
|
1579 | setToStringTag(PromiseConstructor, PROMISE, false, true);
|
1580 | setSpecies(PROMISE);
|
1581 |
|
1582 | PromiseWrapper = path[PROMISE];
|
1583 |
|
1584 |
|
1585 | _export({ target: PROMISE, stat: true, forced: FORCED }, {
|
1586 |
|
1587 |
|
1588 | reject: function reject(r) {
|
1589 | var capability = newPromiseCapability$1(this);
|
1590 | capability.reject.call(undefined, r);
|
1591 | return capability.promise;
|
1592 | }
|
1593 | });
|
1594 |
|
1595 | _export({ target: PROMISE, stat: true, forced: FORCED }, {
|
1596 |
|
1597 |
|
1598 | resolve: function resolve(x) {
|
1599 | return promiseResolve(this, x);
|
1600 | }
|
1601 | });
|
1602 |
|
1603 | _export({ target: PROMISE, stat: true, forced: INCORRECT_ITERATION }, {
|
1604 |
|
1605 |
|
1606 | all: function all(iterable) {
|
1607 | var C = this;
|
1608 | var capability = newPromiseCapability$1(C);
|
1609 | var resolve = capability.resolve;
|
1610 | var reject = capability.reject;
|
1611 | var result = perform(function () {
|
1612 | var values = [];
|
1613 | var counter = 0;
|
1614 | var remaining = 1;
|
1615 | iterate(iterable, function (promise) {
|
1616 | var index = counter++;
|
1617 | var alreadyCalled = false;
|
1618 | values.push(undefined);
|
1619 | remaining++;
|
1620 | C.resolve(promise).then(function (value) {
|
1621 | if (alreadyCalled) return;
|
1622 | alreadyCalled = true;
|
1623 | values[index] = value;
|
1624 | --remaining || resolve(values);
|
1625 | }, reject);
|
1626 | });
|
1627 | --remaining || resolve(values);
|
1628 | });
|
1629 | if (result.error) reject(result.value);
|
1630 | return capability.promise;
|
1631 | },
|
1632 |
|
1633 |
|
1634 | race: function race(iterable) {
|
1635 | var C = this;
|
1636 | var capability = newPromiseCapability$1(C);
|
1637 | var reject = capability.reject;
|
1638 | var result = perform(function () {
|
1639 | iterate(iterable, function (promise) {
|
1640 | C.resolve(promise).then(capability.resolve, reject);
|
1641 | });
|
1642 | });
|
1643 | if (result.error) reject(result.value);
|
1644 | return capability.promise;
|
1645 | }
|
1646 | });
|
1647 |
|
1648 | function _defineProperty(obj, key, value) {
|
1649 | if (key in obj) {
|
1650 | Object.defineProperty(obj, key, {
|
1651 | value: value,
|
1652 | enumerable: true,
|
1653 | configurable: true,
|
1654 | writable: true
|
1655 | });
|
1656 | } else {
|
1657 | obj[key] = value;
|
1658 | }
|
1659 |
|
1660 | return obj;
|
1661 | }
|
1662 |
|
1663 | function _objectSpread(target) {
|
1664 | for (var i = 1; i < arguments.length; i++) {
|
1665 | var source = arguments[i] != null ? arguments[i] : {};
|
1666 | var ownKeys = Object.keys(source);
|
1667 |
|
1668 | if (typeof Object.getOwnPropertySymbols === 'function') {
|
1669 | ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
|
1670 | return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
1671 | }));
|
1672 | }
|
1673 |
|
1674 | ownKeys.forEach(function (key) {
|
1675 | _defineProperty(target, key, source[key]);
|
1676 | });
|
1677 | }
|
1678 |
|
1679 | return target;
|
1680 | }
|
1681 |
|
1682 | function _objectWithoutPropertiesLoose(source, excluded) {
|
1683 | if (source == null) return {};
|
1684 | var target = {};
|
1685 | var sourceKeys = Object.keys(source);
|
1686 | var key, i;
|
1687 |
|
1688 | for (i = 0; i < sourceKeys.length; i++) {
|
1689 | key = sourceKeys[i];
|
1690 | if (excluded.indexOf(key) >= 0) continue;
|
1691 | target[key] = source[key];
|
1692 | }
|
1693 |
|
1694 | return target;
|
1695 | }
|
1696 |
|
1697 | function _objectWithoutProperties(source, excluded) {
|
1698 | if (source == null) return {};
|
1699 |
|
1700 | var target = _objectWithoutPropertiesLoose(source, excluded);
|
1701 |
|
1702 | var key, i;
|
1703 |
|
1704 | if (Object.getOwnPropertySymbols) {
|
1705 | var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
|
1706 |
|
1707 | for (i = 0; i < sourceSymbolKeys.length; i++) {
|
1708 | key = sourceSymbolKeys[i];
|
1709 | if (excluded.indexOf(key) >= 0) continue;
|
1710 | if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
|
1711 | target[key] = source[key];
|
1712 | }
|
1713 | }
|
1714 |
|
1715 | return target;
|
1716 | }
|
1717 |
|
1718 |
|
1719 |
|
1720 |
|
1721 | class Command {
|
1722 | |
1723 |
|
1724 |
|
1725 | constructor() {
|
1726 | _defineProperty(this, "command", void 0);
|
1727 |
|
1728 | _defineProperty(this, "description", void 0);
|
1729 |
|
1730 | _defineProperty(this, "options", []);
|
1731 | }
|
1732 | |
1733 |
|
1734 |
|
1735 |
|
1736 |
|
1737 | }
|
1738 |
|
1739 |
|
1740 |
|
1741 | var whitespaces = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';
|
1742 |
|
1743 | var whitespace = '[' + whitespaces + ']';
|
1744 | var ltrim = RegExp('^' + whitespace + whitespace + '*');
|
1745 | var rtrim = RegExp(whitespace + whitespace + '*$');
|
1746 |
|
1747 |
|
1748 |
|
1749 |
|
1750 | var stringTrim = function (string, TYPE) {
|
1751 | string = String(requireObjectCoercible(string));
|
1752 | if (TYPE & 1) string = string.replace(ltrim, '');
|
1753 | if (TYPE & 2) string = string.replace(rtrim, '');
|
1754 | return string;
|
1755 | };
|
1756 |
|
1757 | var non = '\u200B\u0085\u180E';
|
1758 |
|
1759 |
|
1760 |
|
1761 | var forcedStringTrimMethod = function (METHOD_NAME) {
|
1762 | return fails(function () {
|
1763 | return !!whitespaces[METHOD_NAME]() || non[METHOD_NAME]() != non || whitespaces[METHOD_NAME].name !== METHOD_NAME;
|
1764 | });
|
1765 | };
|
1766 |
|
1767 | var FORCED$1 = forcedStringTrimMethod('trim');
|
1768 |
|
1769 |
|
1770 |
|
1771 | _export({ target: 'String', proto: true, forced: FORCED$1 }, {
|
1772 | trim: function trim() {
|
1773 | return stringTrim(this, 3);
|
1774 | }
|
1775 | });
|
1776 |
|
1777 | const semverRegex = require('semver-regex');
|
1778 |
|
1779 | const getLatestVersion = require('latest-version');
|
1780 |
|
1781 | function parseVersion(v) {
|
1782 | if (v === null) throw new Error('Version is null.');
|
1783 |
|
1784 | if (typeof v === 'string') {
|
1785 | const parsedV = semver__default.parse(semverRegex().exec(v)[0]);
|
1786 |
|
1787 | if (parsedV === null) {
|
1788 | throw new Error(`Version ${v.trim()} cannot be parsed.`);
|
1789 | }
|
1790 |
|
1791 | return parsedV;
|
1792 | }
|
1793 |
|
1794 | return v;
|
1795 | }
|
1796 | async function latestVersion(npmPackageName) {
|
1797 | return parseVersion((await getLatestVersion(npmPackageName)));
|
1798 | }
|
1799 |
|
1800 | function useExeca(cmd) {
|
1801 | const [execaResult, setExecaResult] = React__default.useState();
|
1802 | React__default.useEffect(() => {
|
1803 | const p = execa.command(cmd, {
|
1804 | reject: false
|
1805 | });
|
1806 | p.then(r => {
|
1807 | if (r.killed) return;
|
1808 | setExecaResult(r);
|
1809 | });
|
1810 | return () => p.kill();
|
1811 | }, [cmd]);
|
1812 | return execaResult;
|
1813 | }
|
1814 | function useLatestNpmVersion(pkg) {
|
1815 | const [latest, setLatest] = React__default.useState(null);
|
1816 | const [error, setError] = React__default.useState();
|
1817 | React__default.useEffect(() => {
|
1818 | let mounted = true;
|
1819 | latestVersion(pkg).then(v => {
|
1820 | if (mounted) setLatest(v);
|
1821 | }).catch(e => {
|
1822 | if (mounted) setError(e);
|
1823 | });
|
1824 | return () => {
|
1825 | mounted = false;
|
1826 | };
|
1827 | }, [pkg]);
|
1828 | return {
|
1829 | latest,
|
1830 | error
|
1831 | };
|
1832 | }
|
1833 | function latestVersionResult(version) {
|
1834 | return {
|
1835 | type: CheckStatusType.Ok,
|
1836 | message: React__default.createElement(React__default.Fragment, null, "Version ", React__default.createElement(Version, {
|
1837 | version: version
|
1838 | }), " is the latest.")
|
1839 | };
|
1840 | }
|
1841 | function outdatedVersionResult(current, latest, type = CheckStatusType.Warning) {
|
1842 | return {
|
1843 | type,
|
1844 | message: React__default.createElement(React__default.Fragment, null, "You have version ", React__default.createElement(Version, {
|
1845 | version: current
|
1846 | }), " while the latest is", ' ', React__default.createElement(Version, {
|
1847 | version: latest
|
1848 | }), ".")
|
1849 | };
|
1850 | }
|
1851 | function Version({
|
1852 | version
|
1853 | }) {
|
1854 | return React__default.createElement(ink.Color, {
|
1855 | cyan: true
|
1856 | }, typeof version === 'string' ? version : version.format());
|
1857 | }
|
1858 |
|
1859 | function usePHPCheck() {
|
1860 | const phpV = useExeca('php -v');
|
1861 | const version = phpV ? parseVersion(phpV.stdout) : undefined;
|
1862 |
|
1863 | if (!phpV) {
|
1864 | return {
|
1865 | type: CheckStatusType.Loading,
|
1866 | message: 'Checking your PHP version...'
|
1867 | };
|
1868 | }
|
1869 |
|
1870 | if (!version) {
|
1871 | return {
|
1872 | type: CheckStatusType.Error,
|
1873 | message: "Looks like you don't have PHP correctly installed."
|
1874 | };
|
1875 | }
|
1876 |
|
1877 | if (version.major >= 7 && version.minor >= 1) {
|
1878 | return {
|
1879 | type: CheckStatusType.Ok,
|
1880 | message: React__default.createElement(React__default.Fragment, null, "You have PHP ", React__default.createElement(Version, {
|
1881 | version: version
|
1882 | }), " installed.")
|
1883 | };
|
1884 | }
|
1885 |
|
1886 | return {
|
1887 | type: CheckStatusType.Ok,
|
1888 | message: React__default.createElement(React__default.Fragment, null, "You have PHP ", React__default.createElement(Version, {
|
1889 | version: version
|
1890 | }), " installed, but you need at least ", React__default.createElement(Version, {
|
1891 | version: "7.1"
|
1892 | }), ".")
|
1893 | };
|
1894 | }
|
1895 |
|
1896 | function useExit(shouldExit, error) {
|
1897 | const {
|
1898 | exit
|
1899 | } = React__default.useContext(ink.AppContext);
|
1900 | React__default.useEffect(() => {
|
1901 | if (shouldExit) exit(error);
|
1902 | }, [error, exit, shouldExit]);
|
1903 | }
|
1904 |
|
1905 | function useAxios(url, config) {
|
1906 | const [res, setRes] = React__default.useState({
|
1907 | loading: true
|
1908 | });
|
1909 | React__default.useEffect(() => {
|
1910 | const source = axios.CancelToken.source();
|
1911 | axios(_objectSpread({
|
1912 | url,
|
1913 | cancelToken: source.token
|
1914 | }, config)).then(response => {
|
1915 | setRes({
|
1916 | response,
|
1917 | loading: false
|
1918 | });
|
1919 | }).catch(error => {
|
1920 | if (!axios.isCancel(error)) {
|
1921 | setRes({
|
1922 | error,
|
1923 | loading: false
|
1924 | });
|
1925 | }
|
1926 | });
|
1927 | return () => {
|
1928 | source.cancel();
|
1929 | };
|
1930 | }, [config, url]);
|
1931 | return res;
|
1932 | }
|
1933 |
|
1934 | const axiosConfig = {
|
1935 | timeout: 3000
|
1936 | };
|
1937 | function useNodeJsCheck() {
|
1938 | const nodeVersions = useAxios('https://nodejs.org/dist/index.json', axiosConfig);
|
1939 | const nodeVersion = parseVersion(process.version);
|
1940 | const versionSupported = nodeVersion.major === 8 || nodeVersion.major === 10;
|
1941 |
|
1942 | if (!versionSupported) {
|
1943 | return {
|
1944 | type: CheckStatusType.Error,
|
1945 | message: 'You should use Node.js 8 or 10.'
|
1946 | };
|
1947 | }
|
1948 |
|
1949 | if (nodeVersions.error) {
|
1950 | return {
|
1951 | type: CheckStatusType.LoadingError,
|
1952 | message: `Error fetching latest version: ${nodeVersions.error.message}`
|
1953 | };
|
1954 | }
|
1955 |
|
1956 | if (nodeVersions.loading) {
|
1957 | return {
|
1958 | type: CheckStatusType.Loading,
|
1959 | message: 'Fetching latest version...'
|
1960 | };
|
1961 | }
|
1962 |
|
1963 | const latestInMajor = nodeVersions.response.data.map(v => parseVersion(v.version)).find(s => !!s && s.major === nodeVersion.major);
|
1964 |
|
1965 | if (!latestInMajor) {
|
1966 | return {
|
1967 | type: CheckStatusType.LoadingError,
|
1968 | message: "Can't find latest Node.js version."
|
1969 | };
|
1970 | }
|
1971 |
|
1972 | if (latestInMajor.compare(nodeVersion) === 0) {
|
1973 | return latestVersionResult(nodeVersion);
|
1974 | }
|
1975 |
|
1976 | return outdatedVersionResult(nodeVersion, latestInMajor);
|
1977 | }
|
1978 |
|
1979 | function useNPMCheck() {
|
1980 | const npmV = useExeca('npm -v');
|
1981 | const version = npmV ? parseVersion(npmV.stdout) : undefined;
|
1982 | const {
|
1983 | latest,
|
1984 | error
|
1985 | } = useLatestNpmVersion('npm');
|
1986 |
|
1987 | if (!npmV) {
|
1988 | return {
|
1989 | type: CheckStatusType.Loading,
|
1990 | message: 'Getting your NPM version...'
|
1991 | };
|
1992 | }
|
1993 |
|
1994 | if (!version) {
|
1995 | return {
|
1996 | type: CheckStatusType.Error,
|
1997 | message: 'Something is wrong with your NPM installation.'
|
1998 | };
|
1999 | }
|
2000 |
|
2001 | if (error) {
|
2002 | return {
|
2003 | type: CheckStatusType.LoadingError,
|
2004 | message: `Error fetching latest version: ${error.message}`
|
2005 | };
|
2006 | }
|
2007 |
|
2008 | if (!latest) {
|
2009 | return {
|
2010 | type: CheckStatusType.Loading,
|
2011 | message: 'Getting latest version from NPM...'
|
2012 | };
|
2013 | }
|
2014 |
|
2015 | if (latest.compare(version.version) === 0) {
|
2016 | return latestVersionResult(version);
|
2017 | }
|
2018 |
|
2019 | return outdatedVersionResult(version, latest);
|
2020 | }
|
2021 |
|
2022 | var version = "0.0.124";
|
2023 |
|
2024 |
|
2025 | function UpdateBurstCli() {
|
2026 | const updateCommand = useExeca('npm i -g @burst/cli');
|
2027 | React__default.useEffect(() => {
|
2028 | if (updateCommand) {
|
2029 | console.log('Burst CLI updated, please re-run your command.');
|
2030 | console.log();
|
2031 | process.exit(1);
|
2032 | }
|
2033 | }, [updateCommand]);
|
2034 |
|
2035 | if (!updateCommand) {
|
2036 | return React__default.createElement(ink.Box, {
|
2037 | marginTop: 1,
|
2038 | marginBottom: 1
|
2039 | }, "Updating the Burst CLI to the latest version...");
|
2040 | }
|
2041 |
|
2042 | return null;
|
2043 | }
|
2044 | function useBurstCliCheck() {
|
2045 | const {
|
2046 | latest,
|
2047 | error
|
2048 | } = useLatestNpmVersion('@burst/cli');
|
2049 |
|
2050 | if (error) {
|
2051 | return {
|
2052 | type: CheckStatusType.LoadingError,
|
2053 | message: `Error fetching latest version: ${error.message}`
|
2054 | };
|
2055 | }
|
2056 |
|
2057 | if (latest) {
|
2058 | if (latest.compare(version) !== 0) {
|
2059 | return outdatedVersionResult(version, latest, CheckStatusType.Error);
|
2060 | }
|
2061 |
|
2062 | return latestVersionResult(latest);
|
2063 | }
|
2064 |
|
2065 | return {
|
2066 | type: CheckStatusType.Loading,
|
2067 | message: 'Getting latest version from NPM...'
|
2068 | };
|
2069 | }
|
2070 |
|
2071 | const minVersion = '3.0.0-rc.12';
|
2072 | const maxVersion = '3.0.0-rc.15';
|
2073 | function useLandoCheck() {
|
2074 | const lando = useExeca('lando version');
|
2075 | const version = lando && lando.exitCode === 0 ? parseVersion(lando.stdout) : undefined;
|
2076 |
|
2077 | if (!lando) {
|
2078 | return {
|
2079 | type: CheckStatusType.Loading,
|
2080 | message: 'Checking your Lando version...'
|
2081 | };
|
2082 | }
|
2083 |
|
2084 | if (!version) {
|
2085 | return {
|
2086 | type: CheckStatusType.Ok,
|
2087 | message: "You don't have Lando installed, which is fine."
|
2088 | };
|
2089 | }
|
2090 |
|
2091 | const downloadLink = React__default.createElement(React__default.Fragment, null, "Download the latest supported version here:", ' ', `https://github.com/lando/lando/releases/tag/v${maxVersion}`);
|
2092 |
|
2093 | if (version.compare(minVersion) === -1) {
|
2094 | return {
|
2095 | type: CheckStatusType.Error,
|
2096 | message: React__default.createElement(React__default.Fragment, null, "You have Lando ", React__default.createElement(Version, {
|
2097 | version: version
|
2098 | }), " installed, but you need at least ", React__default.createElement(Version, {
|
2099 | version: minVersion
|
2100 | }), ". Please update to", ' ', React__default.createElement(Version, {
|
2101 | version: maxVersion
|
2102 | }), " if possible. ", downloadLink)
|
2103 | };
|
2104 | }
|
2105 |
|
2106 | if (version.compare(maxVersion) === 1) {
|
2107 | return {
|
2108 | type: CheckStatusType.Error,
|
2109 | message: React__default.createElement(React__default.Fragment, null, "You have Lando ", React__default.createElement(Version, {
|
2110 | version: version
|
2111 | }), " installed, but the latest supported version is ", React__default.createElement(Version, {
|
2112 | version: maxVersion
|
2113 | }), ". Please downgrade to to that version. ", downloadLink)
|
2114 | };
|
2115 | }
|
2116 |
|
2117 | if (version.compare(maxVersion) === -1) {
|
2118 | return {
|
2119 | type: CheckStatusType.Warning,
|
2120 | message: React__default.createElement(React__default.Fragment, null, "You have Lando ", React__default.createElement(Version, {
|
2121 | version: version
|
2122 | }), " installed, but the latest supported version is ", React__default.createElement(Version, {
|
2123 | version: maxVersion
|
2124 | }), ". ", downloadLink)
|
2125 | };
|
2126 | }
|
2127 |
|
2128 | return {
|
2129 | type: CheckStatusType.Ok,
|
2130 | message: React__default.createElement(React__default.Fragment, null, "You have Lando ", React__default.createElement(Version, {
|
2131 | version: version
|
2132 | }), " installed.")
|
2133 | };
|
2134 | }
|
2135 |
|
2136 | const isCI = require('is-ci');
|
2137 |
|
2138 | class CheckCommand extends Command {
|
2139 | constructor(...args) {
|
2140 | super(...args);
|
2141 |
|
2142 | _defineProperty(this, "command", 'check');
|
2143 |
|
2144 | _defineProperty(this, "description", 'Check your local environment.');
|
2145 | }
|
2146 |
|
2147 | async action() {
|
2148 | const a = ink.render(React__default.createElement(Check, null));
|
2149 | await a.waitUntilExit();
|
2150 | }
|
2151 |
|
2152 | }
|
2153 | function checkFirst(funcToWrap) {
|
2154 | return async (...args) => {
|
2155 |
|
2156 | if (!isCI) {
|
2157 | const a = ink.render(React__default.createElement(Check, {
|
2158 | onlyDisplayErrors: true
|
2159 | }));
|
2160 | await a.waitUntilExit();
|
2161 |
|
2162 | a.cleanup();
|
2163 | }
|
2164 |
|
2165 | return funcToWrap(...args);
|
2166 | };
|
2167 | }
|
2168 | let CheckStatusType;
|
2169 |
|
2170 | (function (CheckStatusType) {
|
2171 | CheckStatusType[CheckStatusType["Loading"] = 0] = "Loading";
|
2172 | CheckStatusType[CheckStatusType["Warning"] = 1] = "Warning";
|
2173 | CheckStatusType[CheckStatusType["Error"] = 2] = "Error";
|
2174 | CheckStatusType[CheckStatusType["LoadingError"] = 3] = "LoadingError";
|
2175 | CheckStatusType[CheckStatusType["Ok"] = 4] = "Ok";
|
2176 | })(CheckStatusType || (CheckStatusType = {}));
|
2177 |
|
2178 | function Check({
|
2179 | onlyDisplayErrors = false
|
2180 | }) {
|
2181 | const checks = [['Burst CLI', useBurstCliCheck()], ['Node.js', useNodeJsCheck()], ['PHP', usePHPCheck()], ['NPM', useNPMCheck()], ['Lando', useLandoCheck()]];
|
2182 | const burstCliNeedsUpdate = checks[0][1].type === CheckStatusType.Error;
|
2183 | const checksLoaded = checks.every(([, c]) => c.type !== CheckStatusType.Loading);
|
2184 | useExit(checksLoaded && !burstCliNeedsUpdate);
|
2185 | return React__default.createElement(ink.Box, {
|
2186 | marginBottom: 1,
|
2187 | flexDirection: "column"
|
2188 | }, (onlyDisplayErrors ? checks.filter(([, c]) => c.type !== CheckStatusType.Loading && c.type !== CheckStatusType.Ok) : checks).map(([n, c]) => React__default.createElement(ink.Box, {
|
2189 | key: n
|
2190 | }, React__default.createElement(ink.Box, {
|
2191 | width: 4
|
2192 | }, c.type === CheckStatusType.Loading ? '⌚' : c.type === CheckStatusType.Warning ? '🚧' : c.type === CheckStatusType.Error ? '❌' : c.type === CheckStatusType.LoadingError ? '❌' : '👍'), React__default.createElement(ink.Box, {
|
2193 | width: 12
|
2194 | }, n), React__default.createElement(ink.Box, {
|
2195 | textWrap: "wrap",
|
2196 | flexGrow: 1
|
2197 | }, c.message))), !checksLoaded && React__default.createElement(ink.Box, {
|
2198 | marginTop: 1,
|
2199 | marginBottom: 1
|
2200 | }, "Checking your local development environment..."), burstCliNeedsUpdate && React__default.createElement(UpdateBurstCli, null));
|
2201 | }
|
2202 |
|
2203 | const isCI$1 = require('is-ci');
|
2204 |
|
2205 | class PrepareCICommand extends Command {
|
2206 | constructor(...args) {
|
2207 | super(...args);
|
2208 |
|
2209 | _defineProperty(this, "command", 'prepare-ci');
|
2210 |
|
2211 | _defineProperty(this, "description", 'This adds various environment varibles.');
|
2212 |
|
2213 | _defineProperty(this, "action", async () => {
|
2214 | if (!isCI$1) {
|
2215 | console.log('You can only run this command in the CI.');
|
2216 | process.exit(1);
|
2217 | }
|
2218 |
|
2219 | console.log((await prepareCI()));
|
2220 | });
|
2221 | }
|
2222 |
|
2223 | }
|
2224 | async function prepareCI() {
|
2225 | if (!isCI$1) return [];
|
2226 | const toEval = [];
|
2227 |
|
2228 | if (!process.env.SSH_AUTH_SOCK || !process.env.SSH_AGENT_PID) {
|
2229 | const {
|
2230 | stdout: agent
|
2231 | } = await execa('ssh-agent');
|
2232 | toEval.push(agent);
|
2233 | const [, authSock] = /SSH_AUTH_SOCK=(.*); export/.exec(agent) || ['', ''];
|
2234 | const [, agentPid] = /SSH_AGENT_PID=(.*); export/.exec(agent) || ['', ''];
|
2235 | process.env.SSH_AUTH_SOCK = authSock;
|
2236 | process.env.SSH_AGENT_PID = agentPid;
|
2237 | }
|
2238 |
|
2239 |
|
2240 | if (process.env.PLATFORMSH_SSH_KEY) {
|
2241 | await execa.command(`echo "$PLATFORMSH_SSH_KEY" | tr -d '\\r' | ssh-add - > /dev/null`, {
|
2242 | shell: true
|
2243 | });
|
2244 | }
|
2245 |
|
2246 | return toEval.join('\n');
|
2247 | }
|
2248 |
|
2249 | const isCI$2 = require('is-ci');
|
2250 |
|
2251 | const repoRootGitCmd = execa.sync('git', ['rev-parse', '--show-toplevel'], {
|
2252 | reject: false
|
2253 | });
|
2254 |
|
2255 | if (repoRootGitCmd.failed) {
|
2256 | throw new Error('Please use the Burst CLI in a git repository.');
|
2257 | }
|
2258 |
|
2259 | const repoRoot = repoRootGitCmd.stdout;
|
2260 |
|
2261 |
|
2262 | function getRepoRoot() {
|
2263 | return repoRoot;
|
2264 | }
|
2265 | async function push(url, branch, {
|
2266 | dir,
|
2267 | showProgress
|
2268 | } = {}) {
|
2269 |
|
2270 |
|
2271 |
|
2272 | await execa('git', ['remote', 'remove', '_burst_tmp_']).catch(() => undefined);
|
2273 |
|
2274 | await execa('git', ['remote', 'add', '_burst_tmp_', url]);
|
2275 |
|
2276 | try {
|
2277 | let src = 'HEAD';
|
2278 |
|
2279 | if (dir) {
|
2280 | console.log(`Creating git subtree of the ${chalk.cyan(dir)} directory.`);
|
2281 | ({
|
2282 | stdout: src
|
2283 | } = await execa('git', ['subtree', 'split', '--prefix', dir], {
|
2284 | stderr: showProgress && !isCI$2 ? 'inherit' : undefined,
|
2285 |
|
2286 |
|
2287 | cwd: repoRoot
|
2288 | }));
|
2289 | console.log('Done with creating subtree.');
|
2290 | }
|
2291 |
|
2292 |
|
2293 | await prepareCI();
|
2294 |
|
2295 |
|
2296 |
|
2297 | await execa('git', ['push', '_burst_tmp_', `${src}:refs/heads/${branch}`, '--force'], showProgress ? {
|
2298 | stdio: 'inherit'
|
2299 | } : undefined);
|
2300 | } finally {
|
2301 |
|
2302 | await execa('git', ['remote', 'remove', '_burst_tmp_']).catch(() => {
|
2303 | });
|
2304 | }
|
2305 | }
|
2306 | async function getCurrentBranch() {
|
2307 |
|
2308 | if (process.env.CI_COMMIT_REF_NAME) return process.env.CI_COMMIT_REF_NAME;
|
2309 |
|
2310 | return (await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'])).stdout;
|
2311 | }
|
2312 | async function getListOfRepoFiles(search = [], fromRoot = false) {
|
2313 | const cwd = fromRoot || !search.length ? repoRoot : undefined;
|
2314 |
|
2315 |
|
2316 |
|
2317 |
|
2318 |
|
2319 |
|
2320 |
|
2321 |
|
2322 |
|
2323 |
|
2324 |
|
2325 |
|
2326 |
|
2327 |
|
2328 |
|
2329 |
|
2330 | const [cached, deleted, untracked] = await Promise.all([gitLsFiles(search, cwd), gitLsFiles(['--deleted', ...search], cwd), gitLsFiles([...search, '--others', '--exclude-standard'], cwd)]);
|
2331 | return [...untracked, ...cached.filter(file => !deleted.includes(file))];
|
2332 | }
|
2333 |
|
2334 | async function gitLsFiles(opts, cwd) {
|
2335 | const {
|
2336 | stdout: command
|
2337 | } = await execa('git', ['ls-files', ...opts, '--full-name'], {
|
2338 | cwd
|
2339 | });
|
2340 | return command.split('\n').filter(f => f.length);
|
2341 | }
|
2342 |
|
2343 | function useTsWorker() {
|
2344 | return useWorker('./workers/ts', ['doTsCheck']);
|
2345 | }
|
2346 | function usePrettierWorker() {
|
2347 | return useWorker('./workers/prettier', ['getFileInfo', 'format']);
|
2348 | }
|
2349 | function useEslintWorker() {
|
2350 | return useWorker('./workers/eslint', ['lintFile', 'writeToDisk']);
|
2351 | }
|
2352 |
|
2353 | function useWorker(path, exposedMethods) {
|
2354 | const exposedMethodsJson = JSON.stringify(exposedMethods);
|
2355 | const worker = React.useMemo(() => new Worker(require.resolve(path), {
|
2356 | exposedMethods: JSON.parse(exposedMethodsJson)
|
2357 | }), [exposedMethodsJson, path]);
|
2358 | React.useEffect(() => () => worker.end(), [worker]);
|
2359 | return worker;
|
2360 | }
|
2361 |
|
2362 | function useTsChecker(allFiles) {
|
2363 | const files = React.useMemo(() => allFiles.filter(f => f.path.endsWith('.ts') || f.path.endsWith('.tsx')), [allFiles]);
|
2364 | const [filesWithTs, filesWithoutTs] = React.useMemo(() => {
|
2365 | const resolved = lodash.groupBy(files, file => resolve.silent(file.absolutePath, 'typescript'));
|
2366 |
|
2367 | const {
|
2368 | undefined: withoutTs = []
|
2369 | } = resolved,
|
2370 | withTs = _objectWithoutProperties(resolved, ["undefined"]);
|
2371 |
|
2372 | return [withTs, withoutTs];
|
2373 | }, [files]);
|
2374 | const worker = useTsWorker();
|
2375 | const [workerResults, setWorkerResults] = React.useState([]);
|
2376 | React.useEffect(() => {
|
2377 | Object.entries(filesWithTs).forEach(async ([tsPath, tsFiles]) => {
|
2378 | const workerResult = await worker.doTsCheck(tsPath, tsFiles.map(f => f.absolutePath));
|
2379 | setWorkerResults(r => [...r, workerResult]);
|
2380 | });
|
2381 | }, [filesWithTs, worker]);
|
2382 | const filesWithoutProject = lodash.flatten(workerResults.map(r => r.filesWithoutProject));
|
2383 | const filesNotIncludedInProject = lodash.flatten(workerResults.map(r => r.filesNotIncludedInProject));
|
2384 | const errors = [...filesWithoutTs.map(f => ({
|
2385 | filename: f.absolutePath,
|
2386 | message: 'No TypeScript module can be found for this file. \nAre you sure TypeScript is installed?'
|
2387 | })), ...filesWithoutProject.map(f => ({
|
2388 | filename: f,
|
2389 | message: 'Found no tsconfig.json file. \nAre you sure there is a tsconfig.json file in the root of the app?'
|
2390 | })), ...filesNotIncludedInProject.map(f => ({
|
2391 | filename: f,
|
2392 | message: 'There is a tsconfig.json file, but it looks like this file is excluded. \nPlease check the include / exclude part of the tsconfig.json file.'
|
2393 | })), ...lodash.flatten(workerResults.map(r => r.errors))].map(f => _objectSpread({}, f, {
|
2394 | linter: 'TypeScript',
|
2395 | autoFixable: false
|
2396 | }));
|
2397 | return {
|
2398 | files,
|
2399 | done: workerResults.length === Object.keys(filesWithTs).length,
|
2400 | errors
|
2401 | };
|
2402 | }
|
2403 |
|
2404 | function useEslint(allFiles, fix) {
|
2405 | const files = React.useMemo(() => allFiles.filter(f => f.path.endsWith('.js') || f.path.endsWith('.jsx') || f.path.endsWith('.ts') || f.path.endsWith('.tsx')), [allFiles]);
|
2406 | const eslint = useEslintWorker();
|
2407 | const [reports, setReports] = React.useState([]);
|
2408 | const [execErrors, setExecErrors] = React.useState({});
|
2409 | React.useEffect(() => {
|
2410 | files.forEach(async file => {
|
2411 | try {
|
2412 | const report = await eslint.lintFile(file.absolutePath, fix);
|
2413 |
|
2414 | if (fix) {
|
2415 | await eslint.writeToDisk(report);
|
2416 | }
|
2417 |
|
2418 | setReports(r => [...r, ...report.results]);
|
2419 | } catch (e) {
|
2420 | setExecErrors(exe => _objectSpread({}, exe, {
|
2421 | [file.absolutePath]: e.message || e.toString()
|
2422 | }));
|
2423 | }
|
2424 | });
|
2425 | }, [eslint, files, fix]);
|
2426 | const filesAutoFixed = fix ? reports.reduce((c, r) => c + (r.output ? 1 : 0), 0) : 0;
|
2427 | const errors = [];
|
2428 | const prettierErrors = [];
|
2429 | reports.forEach(r => {
|
2430 | r.messages.forEach(m => {
|
2431 |
|
2432 | if (m.ruleId === 'prettier/prettier') {
|
2433 | if (prettierErrors.includes(r.filePath)) return;
|
2434 | errors.push({
|
2435 | linter: 'ESLint',
|
2436 | filename: r.filePath,
|
2437 | autoFixable: true,
|
2438 | message: 'Not according to Prettier styling.',
|
2439 | rule: 'prettier/prettier'
|
2440 | });
|
2441 | prettierErrors.push(r.filePath);
|
2442 | return;
|
2443 | }
|
2444 |
|
2445 | errors.push({
|
2446 | linter: 'ESLint',
|
2447 | filename: r.filePath,
|
2448 | autoFixable: !!m.fix,
|
2449 | message: m.message,
|
2450 | rule: m.ruleId || undefined,
|
2451 | sourceLocation: _objectSpread({
|
2452 | start: {
|
2453 | line: m.line,
|
2454 | column: m.column
|
2455 | }
|
2456 | }, m.endLine ? {
|
2457 | end: {
|
2458 | line: m.endLine,
|
2459 | column: m.endColumn
|
2460 | }
|
2461 | } : {})
|
2462 | });
|
2463 | });
|
2464 | });
|
2465 | Object.entries(execErrors).forEach(([filename, error]) => {
|
2466 | errors.push({
|
2467 | linter: 'ESLint',
|
2468 | filename,
|
2469 | autoFixable: false,
|
2470 | message: error
|
2471 | });
|
2472 | });
|
2473 | return {
|
2474 | files,
|
2475 | reports,
|
2476 | filesAutoFixed,
|
2477 | errors,
|
2478 | done: reports.length + Object.keys(execErrors).length === files.length
|
2479 | };
|
2480 | }
|
2481 |
|
2482 | var sloppyArrayMethod = function (METHOD_NAME, argument) {
|
2483 | var method = [][METHOD_NAME];
|
2484 | return !method || !fails(function () {
|
2485 |
|
2486 | method.call(null, argument || function () { throw 1; }, 1);
|
2487 | });
|
2488 | };
|
2489 |
|
2490 | var nativeSort = [].sort;
|
2491 | var test = [1, 2, 3];
|
2492 |
|
2493 |
|
2494 | var FAILS_ON_UNDEFINED = fails(function () {
|
2495 | test.sort(undefined);
|
2496 | });
|
2497 |
|
2498 | var FAILS_ON_NULL = fails(function () {
|
2499 | test.sort(null);
|
2500 | });
|
2501 |
|
2502 | var SLOPPY_METHOD = sloppyArrayMethod('sort');
|
2503 |
|
2504 | var FORCED$2 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || SLOPPY_METHOD;
|
2505 |
|
2506 |
|
2507 |
|
2508 | _export({ target: 'Array', proto: true, forced: FORCED$2 }, {
|
2509 | sort: function sort(comparefn) {
|
2510 | return comparefn === undefined
|
2511 | ? nativeSort.call(toObject(this))
|
2512 | : nativeSort.call(toObject(this), aFunction(comparefn));
|
2513 | }
|
2514 | });
|
2515 |
|
2516 | function isObject$1(something) {
|
2517 | return typeof something === 'object' && something !== null;
|
2518 | }
|
2519 |
|
2520 | const appTypes = ['drupal', 'wordpress', 'magento', 'other'];
|
2521 | function getProjectConfiguration(burstYaml, gitlabYaml, getPathFromDir) {
|
2522 | const burstConfig = jsYaml.safeLoad(burstYaml);
|
2523 | const gitlabConfig = jsYaml.safeLoad(gitlabYaml);
|
2524 |
|
2525 | if (!isObject$1(burstConfig)) {
|
2526 | throw new Error('The burst.yaml is invalid. Please export an object.');
|
2527 | }
|
2528 |
|
2529 | if (!isObject$1(gitlabConfig)) {
|
2530 | throw new Error('The .gitlab-ci.yml file is invalid. The contents should be an object.');
|
2531 | }
|
2532 |
|
2533 | const apps = isObject$1(burstConfig.apps) ? Object.entries(burstConfig.apps).map(([name, app]) => {
|
2534 | if (!isObject$1(app)) {
|
2535 | throw new Error(`App "${name}" should be an object.`);
|
2536 | }
|
2537 |
|
2538 | let type = 'other';
|
2539 |
|
2540 | if (typeof app.type !== 'undefined') {
|
2541 | if (!isAppType(app.type)) {
|
2542 | throw new Error(`The type of "${name}" should be any of: ${appTypes.join(', ')}.`);
|
2543 | }
|
2544 |
|
2545 | ({
|
2546 | type
|
2547 | } = app);
|
2548 | } else if (isAppType(name)) {
|
2549 | type = name;
|
2550 | }
|
2551 |
|
2552 | let dir = name;
|
2553 |
|
2554 | if (typeof app.dir === 'string') {
|
2555 | ({
|
2556 | dir
|
2557 | } = app);
|
2558 |
|
2559 | if (app.dir === '__legacy__project_root__') {
|
2560 | dir = undefined;
|
2561 | }
|
2562 | }
|
2563 |
|
2564 | const path = getPathFromDir(dir);
|
2565 | return {
|
2566 | name,
|
2567 | type,
|
2568 | dir,
|
2569 | path,
|
2570 | options: app,
|
2571 | disableLinting: !!app.disableLinting
|
2572 | };
|
2573 | }) : [];
|
2574 |
|
2575 | if (typeof burstConfig.apps !== 'undefined' && !apps.length) {
|
2576 | throw new Error("The 'apps' property in the burst.yaml should be an object with one or more keys.");
|
2577 | }
|
2578 |
|
2579 | const usesProjectTemplate = Array.isArray(gitlabConfig.include) && gitlabConfig.include.some(i => isObject$1(i) && i.project === 'burstdigital/utils/burst-devtools' && i.file === '/ci-templates/project.yml');
|
2580 | const vars = isObject$1(gitlabConfig.variables) ? gitlabConfig.variables : {};
|
2581 | return {
|
2582 | apps,
|
2583 | deployEnabled: variableFlag(vars, 'BURST_DEPLOY', true),
|
2584 | lintEnabled: variableFlag(vars, 'BURST_LINT', usesProjectTemplate),
|
2585 | lintStylesEnabled: variableFlag(vars, 'BURST_LINT_STYLES', usesProjectTemplate),
|
2586 | lintPhpEnabled: variableFlag(vars, 'BURST_LINT_PHP', usesProjectTemplate)
|
2587 | };
|
2588 | }
|
2589 |
|
2590 | function variableFlag(variables, variableName, fallback) {
|
2591 | const variable = variables[variableName];
|
2592 |
|
2593 | if (typeof process.env[variableName] !== 'undefined' && process.env[variableName] !== variable) {
|
2594 | throw new Error(`It looks like there exists an environment variable with the name of ${variableName}. You should not set this environment variable yourself. It should only be present in the 'variables' section in the .gitlab-ci.yml file. This way, the configuration is consistent for everyone. The .gitlab-ci.yml file is also read when using the Burst CLI locally.`);
|
2595 | }
|
2596 |
|
2597 | if (typeof variable === 'undefined') return fallback;
|
2598 | if (variable === 'disable') return false;
|
2599 | if (variable === 'enable') return true;
|
2600 | throw new Error(`The variable ${variableName} defined in .gitlab-ci.yml should be 'enable' or 'disable'. ` + `If you remove the variable, it will default to '${fallback ? 'enable' : 'disable'}'.`);
|
2601 | }
|
2602 |
|
2603 | function isAppType(something) {
|
2604 | return typeof something === 'string' && appTypes.includes(something);
|
2605 | }
|
2606 |
|
2607 |
|
2608 |
|
2609 | var stringAt = function (that, pos, CONVERT_TO_STRING) {
|
2610 | var S = String(requireObjectCoercible(that));
|
2611 | var position = toInteger(pos);
|
2612 | var size = S.length;
|
2613 | var first, second;
|
2614 | if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
|
2615 | first = S.charCodeAt(position);
|
2616 | return first < 0xD800 || first > 0xDBFF || position + 1 === size
|
2617 | || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF
|
2618 | ? CONVERT_TO_STRING ? S.charAt(position) : first
|
2619 | : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
|
2620 | };
|
2621 |
|
2622 |
|
2623 |
|
2624 | var advanceStringIndex = function (S, index, unicode) {
|
2625 | return index + (unicode ? stringAt(S, index, true).length : 1);
|
2626 | };
|
2627 |
|
2628 |
|
2629 |
|
2630 | var regexpFlags = function () {
|
2631 | var that = anObject(this);
|
2632 | var result = '';
|
2633 | if (that.global) result += 'g';
|
2634 | if (that.ignoreCase) result += 'i';
|
2635 | if (that.multiline) result += 'm';
|
2636 | if (that.unicode) result += 'u';
|
2637 | if (that.sticky) result += 'y';
|
2638 | return result;
|
2639 | };
|
2640 |
|
2641 | var nativeExec = RegExp.prototype.exec;
|
2642 |
|
2643 |
|
2644 |
|
2645 | var nativeReplace = String.prototype.replace;
|
2646 |
|
2647 | var patchedExec = nativeExec;
|
2648 |
|
2649 | var UPDATES_LAST_INDEX_WRONG = (function () {
|
2650 | var re1 = /a/;
|
2651 | var re2 = /b*/g;
|
2652 | nativeExec.call(re1, 'a');
|
2653 | nativeExec.call(re2, 'a');
|
2654 | return re1.lastIndex !== 0 || re2.lastIndex !== 0;
|
2655 | })();
|
2656 |
|
2657 |
|
2658 | var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
|
2659 |
|
2660 | var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED;
|
2661 |
|
2662 | if (PATCH) {
|
2663 | patchedExec = function exec(str) {
|
2664 | var re = this;
|
2665 | var lastIndex, reCopy, match, i;
|
2666 |
|
2667 | if (NPCG_INCLUDED) {
|
2668 | reCopy = new RegExp('^' + re.source + '$(?!\\s)', regexpFlags.call(re));
|
2669 | }
|
2670 | if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
|
2671 |
|
2672 | match = nativeExec.call(re, str);
|
2673 |
|
2674 | if (UPDATES_LAST_INDEX_WRONG && match) {
|
2675 | re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
|
2676 | }
|
2677 | if (NPCG_INCLUDED && match && match.length > 1) {
|
2678 |
|
2679 |
|
2680 | nativeReplace.call(match[0], reCopy, function () {
|
2681 | for (i = 1; i < arguments.length - 2; i++) {
|
2682 | if (arguments[i] === undefined) match[i] = undefined;
|
2683 | }
|
2684 | });
|
2685 | }
|
2686 |
|
2687 | return match;
|
2688 | };
|
2689 | }
|
2690 |
|
2691 | var regexpExec = patchedExec;
|
2692 |
|
2693 |
|
2694 |
|
2695 | var regexpExecAbstract = function (R, S) {
|
2696 | var exec = R.exec;
|
2697 | if (typeof exec === 'function') {
|
2698 | var result = exec.call(R, S);
|
2699 | if (typeof result !== 'object') {
|
2700 | throw TypeError('RegExp exec method returned something other than an Object or null');
|
2701 | }
|
2702 | return result;
|
2703 | }
|
2704 |
|
2705 | if (classofRaw(R) !== 'RegExp') {
|
2706 | throw TypeError('RegExp#exec called on incompatible receiver');
|
2707 | }
|
2708 |
|
2709 | return regexpExec.call(R, S);
|
2710 | };
|
2711 |
|
2712 | var SPECIES$3 = wellKnownSymbol('species');
|
2713 |
|
2714 | var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
|
2715 |
|
2716 |
|
2717 |
|
2718 | var re = /./;
|
2719 | re.exec = function () {
|
2720 | var result = [];
|
2721 | result.groups = { a: '7' };
|
2722 | return result;
|
2723 | };
|
2724 | return ''.replace(re, '$<a>') !== '7';
|
2725 | });
|
2726 |
|
2727 |
|
2728 |
|
2729 | var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
|
2730 | var re = /(?:)/;
|
2731 | var originalExec = re.exec;
|
2732 | re.exec = function () { return originalExec.apply(this, arguments); };
|
2733 | var result = 'ab'.split(re);
|
2734 | return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
|
2735 | });
|
2736 |
|
2737 | var fixRegexpWellKnownSymbolLogic = function (KEY, length, exec, sham) {
|
2738 | var SYMBOL = wellKnownSymbol(KEY);
|
2739 |
|
2740 | var DELEGATES_TO_SYMBOL = !fails(function () {
|
2741 |
|
2742 | var O = {};
|
2743 | O[SYMBOL] = function () { return 7; };
|
2744 | return ''[KEY](O) != 7;
|
2745 | });
|
2746 |
|
2747 | var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
|
2748 |
|
2749 | var execCalled = false;
|
2750 | var re = /a/;
|
2751 | re.exec = function () { execCalled = true; return null; };
|
2752 |
|
2753 | if (KEY === 'split') {
|
2754 |
|
2755 |
|
2756 | re.constructor = {};
|
2757 | re.constructor[SPECIES$3] = function () { return re; };
|
2758 | }
|
2759 |
|
2760 | re[SYMBOL]('');
|
2761 | return !execCalled;
|
2762 | });
|
2763 |
|
2764 | if (
|
2765 | !DELEGATES_TO_SYMBOL ||
|
2766 | !DELEGATES_TO_EXEC ||
|
2767 | (KEY === 'replace' && !REPLACE_SUPPORTS_NAMED_GROUPS) ||
|
2768 | (KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC)
|
2769 | ) {
|
2770 | var nativeRegExpMethod = /./[SYMBOL];
|
2771 | var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
|
2772 | if (regexp.exec === regexpExec) {
|
2773 | if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
|
2774 |
|
2775 |
|
2776 |
|
2777 | return { done: true, value: nativeRegExpMethod.call(regexp, str, arg2) };
|
2778 | }
|
2779 | return { done: true, value: nativeMethod.call(str, regexp, arg2) };
|
2780 | }
|
2781 | return { done: false };
|
2782 | });
|
2783 | var stringMethod = methods[0];
|
2784 | var regexMethod = methods[1];
|
2785 |
|
2786 | redefine(String.prototype, KEY, stringMethod);
|
2787 | redefine(RegExp.prototype, SYMBOL, length == 2
|
2788 |
|
2789 |
|
2790 | ? function (string, arg) { return regexMethod.call(string, this, arg); }
|
2791 |
|
2792 |
|
2793 | : function (string) { return regexMethod.call(string, this); }
|
2794 | );
|
2795 | if (sham) hide(RegExp.prototype[SYMBOL], 'sham', true);
|
2796 | }
|
2797 | };
|
2798 |
|
2799 | var max$1 = Math.max;
|
2800 | var min$2 = Math.min;
|
2801 | var floor$1 = Math.floor;
|
2802 | var SUBSTITUTION_SYMBOLS = /\$([$&`']|\d\d?|<[^>]*>)/g;
|
2803 | var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&`']|\d\d?)/g;
|
2804 |
|
2805 | var maybeToString = function (it) {
|
2806 | return it === undefined ? it : String(it);
|
2807 | };
|
2808 |
|
2809 |
|
2810 | fixRegexpWellKnownSymbolLogic(
|
2811 | 'replace',
|
2812 | 2,
|
2813 | function (REPLACE, nativeReplace, maybeCallNative) {
|
2814 | return [
|
2815 |
|
2816 |
|
2817 | function replace(searchValue, replaceValue) {
|
2818 | var O = requireObjectCoercible(this);
|
2819 | var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
|
2820 | return replacer !== undefined
|
2821 | ? replacer.call(searchValue, O, replaceValue)
|
2822 | : nativeReplace.call(String(O), searchValue, replaceValue);
|
2823 | },
|
2824 |
|
2825 |
|
2826 | function (regexp, replaceValue) {
|
2827 | var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
|
2828 | if (res.done) return res.value;
|
2829 |
|
2830 | var rx = anObject(regexp);
|
2831 | var S = String(this);
|
2832 |
|
2833 | var functionalReplace = typeof replaceValue === 'function';
|
2834 | if (!functionalReplace) replaceValue = String(replaceValue);
|
2835 |
|
2836 | var global = rx.global;
|
2837 | if (global) {
|
2838 | var fullUnicode = rx.unicode;
|
2839 | rx.lastIndex = 0;
|
2840 | }
|
2841 | var results = [];
|
2842 | while (true) {
|
2843 | var result = regexpExecAbstract(rx, S);
|
2844 | if (result === null) break;
|
2845 |
|
2846 | results.push(result);
|
2847 | if (!global) break;
|
2848 |
|
2849 | var matchStr = String(result[0]);
|
2850 | if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
|
2851 | }
|
2852 |
|
2853 | var accumulatedResult = '';
|
2854 | var nextSourcePosition = 0;
|
2855 | for (var i = 0; i < results.length; i++) {
|
2856 | result = results[i];
|
2857 |
|
2858 | var matched = String(result[0]);
|
2859 | var position = max$1(min$2(toInteger(result.index), S.length), 0);
|
2860 | var captures = [];
|
2861 |
|
2862 |
|
2863 |
|
2864 |
|
2865 |
|
2866 | for (var j = 1; j < result.length; j++) captures.push(maybeToString(result[j]));
|
2867 | var namedCaptures = result.groups;
|
2868 | if (functionalReplace) {
|
2869 | var replacerArgs = [matched].concat(captures, position, S);
|
2870 | if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
|
2871 | var replacement = String(replaceValue.apply(undefined, replacerArgs));
|
2872 | } else {
|
2873 | replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
|
2874 | }
|
2875 | if (position >= nextSourcePosition) {
|
2876 | accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
|
2877 | nextSourcePosition = position + matched.length;
|
2878 | }
|
2879 | }
|
2880 | return accumulatedResult + S.slice(nextSourcePosition);
|
2881 | }
|
2882 | ];
|
2883 |
|
2884 |
|
2885 | function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
|
2886 | var tailPos = position + matched.length;
|
2887 | var m = captures.length;
|
2888 | var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
|
2889 | if (namedCaptures !== undefined) {
|
2890 | namedCaptures = toObject(namedCaptures);
|
2891 | symbols = SUBSTITUTION_SYMBOLS;
|
2892 | }
|
2893 | return nativeReplace.call(replacement, symbols, function (match, ch) {
|
2894 | var capture;
|
2895 | switch (ch.charAt(0)) {
|
2896 | case '$': return '$';
|
2897 | case '&': return matched;
|
2898 | case '`': return str.slice(0, position);
|
2899 | case "'": return str.slice(tailPos);
|
2900 | case '<':
|
2901 | capture = namedCaptures[ch.slice(1, -1)];
|
2902 | break;
|
2903 | default:
|
2904 | var n = +ch;
|
2905 | if (n === 0) return match;
|
2906 | if (n > m) {
|
2907 | var f = floor$1(n / 10);
|
2908 | if (f === 0) return match;
|
2909 | if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
|
2910 | return match;
|
2911 | }
|
2912 | capture = captures[n - 1];
|
2913 | }
|
2914 | return capture === undefined ? '' : capture;
|
2915 | });
|
2916 | }
|
2917 | }
|
2918 | );
|
2919 |
|
2920 | class HostingProvider {
|
2921 | constructor(config) {
|
2922 | this.config = config;
|
2923 | }
|
2924 |
|
2925 | |
2926 |
|
2927 |
|
2928 |
|
2929 |
|
2930 |
|
2931 | static getAvailableDeployTargetLevels() {
|
2932 | return 1;
|
2933 | }
|
2934 |
|
2935 | }
|
2936 | class HostingProviderEnvironment {
|
2937 | |
2938 |
|
2939 |
|
2940 |
|
2941 |
|
2942 |
|
2943 |
|
2944 | getDeployTarget() {
|
2945 | return DeployTarget.Other;
|
2946 | }
|
2947 |
|
2948 | isSuggested() {
|
2949 | return false;
|
2950 | }
|
2951 |
|
2952 | isActive() {
|
2953 | return false;
|
2954 | }
|
2955 |
|
2956 | }
|
2957 |
|
2958 | const PlatformClient = require('platformsh-client').default;
|
2959 |
|
2960 | class Platform extends HostingProvider {
|
2961 | constructor(...args) {
|
2962 | super(...args);
|
2963 |
|
2964 | _defineProperty(this, "name", 'platform');
|
2965 |
|
2966 | _defineProperty(this, "isEnterpriseProject", false);
|
2967 |
|
2968 | _defineProperty(this, "platformProject", null);
|
2969 | }
|
2970 |
|
2971 | isSameAs(config) {
|
2972 | return config.id === this.config.id;
|
2973 | }
|
2974 |
|
2975 | getDisplayName() {
|
2976 | if (this.platformProject) return this.platformProject.title;
|
2977 | return this.config.id;
|
2978 | }
|
2979 |
|
2980 | getLink() {
|
2981 | return `https://console.platform.sh/burst/${encodeURIComponent(this.config.id)}`;
|
2982 | }
|
2983 |
|
2984 | static getAvailableDeployTargetLevels() {
|
2985 | return 3;
|
2986 | }
|
2987 |
|
2988 | static async getClient() {
|
2989 | if (this.client) return this.client;
|
2990 |
|
2991 | if (process.env.PLATFORMSH_CLI_TOKEN) {
|
2992 | this.client = new PlatformClient({
|
2993 | api_token: process.env.PLATFORMSH_CLI_TOKEN
|
2994 | });
|
2995 | } else {
|
2996 | this.client = new PlatformClient({
|
2997 | access_token: await getPlatformToken()
|
2998 | });
|
2999 | }
|
3000 |
|
3001 | return this.client;
|
3002 | }
|
3003 |
|
3004 | async getPlatformProject() {
|
3005 | if (this.platformProject) return this.platformProject;
|
3006 | const platformClient = await Platform.getClient();
|
3007 | this.platformProject = await platformClient.getProject(this.config.id);
|
3008 | return this.platformProject;
|
3009 | }
|
3010 |
|
3011 | async getPossibleEnvs(config) {
|
3012 | const spinner = ora().start(`Getting platform environments for project ${this.config.id}.`);
|
3013 | const platformProject = await this.getPlatformProject();
|
3014 | const platformEnvs = await platformProject.getEnvironments();
|
3015 | this.isEnterpriseProject = platformEnvs.some(e => e.id === 'production' && e.deployment_target === 'enterprise');
|
3016 | spinner.stop();
|
3017 | const instances = [];
|
3018 | instances.push(...platformEnvs.map(
|
3019 | e => new PlatformEnvironment(this, e, config, instances)));
|
3020 |
|
3021 | if (!instances.find(i => i.isSuggested())) {
|
3022 | instances.push(
|
3023 | new PlatformEnvironment(this, {
|
3024 | new: true
|
3025 | }, config, instances));
|
3026 | }
|
3027 |
|
3028 | return instances;
|
3029 | }
|
3030 |
|
3031 | async getGitUrl() {
|
3032 | return (await this.getPlatformProject()).getGitUrl();
|
3033 | }
|
3034 |
|
3035 | }
|
3036 |
|
3037 | _defineProperty(Platform, "client", void 0);
|
3038 |
|
3039 | class PlatformEnvironment extends HostingProviderEnvironment {
|
3040 | constructor(project, model, config, environments) {
|
3041 | super();
|
3042 | this.project = project;
|
3043 | this.config = config;
|
3044 | this.environments = environments;
|
3045 |
|
3046 | _defineProperty(this, "model", void 0);
|
3047 |
|
3048 | if (model.new) {
|
3049 | const target = Object.entries(this.branchNamesWithTargets()).find(([, t]) => t === config.suggestedTarget);
|
3050 | const id = target ? target[0] : config.suggestedName;
|
3051 |
|
3052 | if (!id) {
|
3053 | throw new Error(`Not a valid config was passed. Either pass a 'suggestedTarget' or ` + `'suggestedName'.\n Passed now: \n${JSON.stringify(config)}`);
|
3054 | }
|
3055 |
|
3056 | this.model = _objectSpread({}, model, {
|
3057 | id
|
3058 | });
|
3059 | } else {
|
3060 | this.model = model;
|
3061 | }
|
3062 | }
|
3063 |
|
3064 | getDisplayName() {
|
3065 | const {
|
3066 | id
|
3067 | } = this.model;
|
3068 |
|
3069 | if (this.project.isEnterpriseProject) {
|
3070 | if (id === 'production') return 'Production (enterprise)';
|
3071 | if (id === 'staging') return 'Staging (enterprise)';
|
3072 | if (id === 'master') return 'Mirror';
|
3073 | }
|
3074 |
|
3075 | if (id === 'master') return 'Production';
|
3076 | if (id === 'staging') return 'Staging (will be deleted in the future)';
|
3077 | if (id === 'mirror') return 'Mirror';
|
3078 | if (this.hasOptedOutResync()) return `${id} [keep data]`;
|
3079 | if (this.hasOptedOutDeactvation()) return `${id} [keep]`;
|
3080 | return id;
|
3081 | }
|
3082 |
|
3083 | branchNamesWithTargets() {
|
3084 | if (this.project.isEnterpriseProject) {
|
3085 | return {
|
3086 | production: DeployTarget.Production,
|
3087 | staging: DeployTarget.Staging,
|
3088 | master: DeployTarget.Staging
|
3089 | };
|
3090 | }
|
3091 |
|
3092 | return {
|
3093 | master: DeployTarget.Production,
|
3094 | staging: DeployTarget.Staging,
|
3095 | mirror: DeployTarget.Staging
|
3096 | };
|
3097 | }
|
3098 |
|
3099 | getDeployTarget() {
|
3100 | const {
|
3101 | id
|
3102 | } = this.model;
|
3103 |
|
3104 | if (this.branchNamesWithTargets()[id]) {
|
3105 | return this.branchNamesWithTargets()[id];
|
3106 | }
|
3107 |
|
3108 | return DeployTarget.Dynamic;
|
3109 | }
|
3110 |
|
3111 | isSuggested() {
|
3112 | return this.config.suggestedTarget === this.getDeployTarget() || this.config.suggestedName === this.model.id ||
|
3113 |
|
3114 | !!this.config.suggestedName && slugify(this.config.suggestedName).replace(/-+/g, '') === slugify(this.model.id).replace(/-+/g, '');
|
3115 | }
|
3116 |
|
3117 | isActive() {
|
3118 | if (this.model.new) return false;
|
3119 |
|
3120 |
|
3121 |
|
3122 |
|
3123 |
|
3124 | if (this.model.is_dirty) {
|
3125 | return !this.model.hasLink('#activate');
|
3126 | }
|
3127 |
|
3128 | return this.model.isActive();
|
3129 | }
|
3130 |
|
3131 | hasOptedOutDeactvation() {
|
3132 | return this.hasOptedOutResync() || !this.model.new && this.model.title.endsWith('[keep]');
|
3133 | }
|
3134 |
|
3135 | hasOptedOutResync() {
|
3136 | return !this.model.new && this.model.title.endsWith('[keep data]');
|
3137 | }
|
3138 |
|
3139 | canBeResyncedOrDeactivated() {
|
3140 | return !this.model.new && !['master', 'production', 'mirror'].includes(this.model.id) && !(this.project.isEnterpriseProject && this.model.id === 'staging') && this.isActive();
|
3141 | }
|
3142 |
|
3143 | async deploy({
|
3144 | deployOnlySubdirectory
|
3145 | }) {
|
3146 | if (!this.project.platformProject) {
|
3147 | throw Error('Not possible.');
|
3148 | }
|
3149 |
|
3150 | const envsMax = this.project.platformProject.data.subscription.environments + 1;
|
3151 | const envsToBeUsed = this.environments.filter(e => e === this || e.isActive()).length;
|
3152 | const mirrorPossible = envsToBeUsed <= envsMax || this.environments.some(e => e.model.id === 'mirror');
|
3153 | let newParent = this.project.isEnterpriseProject || this.getDeployTarget() !== DeployTarget.Dynamic ? 'master' : !this.model.new && this.model.parent === 'staging' && this.environments.some(e => e.model.id === 'staging' && e.isActive()) && this.isActive() ? 'staging' : 'mirror';
|
3154 |
|
3155 | if (newParent === 'staging' && mirrorPossible && !process.env.CI) {
|
3156 | const {
|
3157 | transfer
|
3158 | } = await inquirer.prompt([{
|
3159 | type: 'confirm',
|
3160 | name: 'transfer',
|
3161 | message: `Do you want to change the parent from 'staging' to 'mirror'? The staging environment is deprecated.`
|
3162 | }]);
|
3163 |
|
3164 | if (transfer) {
|
3165 | newParent = 'mirror';
|
3166 | }
|
3167 | }
|
3168 |
|
3169 | let resync = false;
|
3170 |
|
3171 | if (this.canBeResyncedOrDeactivated() && !this.hasOptedOutResync() && !process.env.CI) {
|
3172 | ({
|
3173 | resync
|
3174 | } = await inquirer.prompt([{
|
3175 | type: 'confirm',
|
3176 | name: 'resync',
|
3177 | message: `💣 Do you want to use fresh data (and remove the database on this environment)?`
|
3178 | }]));
|
3179 | }
|
3180 |
|
3181 | if (this.canBeResyncedOrDeactivated() && !this.hasOptedOutResync() && !resync) {
|
3182 | console.log('\n\n💣');
|
3183 | console.log('💣 WARNING');
|
3184 | console.log('💣');
|
3185 | console.log('💣 In the future, a deploy will automatically use fresh data.');
|
3186 | console.log('💣 This means that the database will be removed.');
|
3187 | console.log('💣');
|
3188 | console.log(`💣 If you want to opt out, add ${chalk.cyan('[keep data]')} to the name of the environment.`);
|
3189 | console.log('💣\n\n');
|
3190 | }
|
3191 |
|
3192 | console.log(`\n\n${chalk.bgYellow.black(' DEPLOY START ')} Deploying to Platform.sh project ${this.project.getDisplayName()} branch ${this.model.id}\n\n`);
|
3193 |
|
3194 | try {
|
3195 |
|
3196 | if (resync && !this.model.new) {
|
3197 | try {
|
3198 | await this.model.backup();
|
3199 | } catch (e) {
|
3200 | ({
|
3201 | resync
|
3202 | } = await inquirer.prompt([{
|
3203 | type: 'confirm',
|
3204 | name: 'resync',
|
3205 | message: `💣 Creating a backup isn't possible at the moment. Continue?`
|
3206 | }]));
|
3207 | }
|
3208 | }
|
3209 |
|
3210 | if (resync && !this.model.new) {
|
3211 | await this.model.runLongOperation('deactivate', 'POST', undefined);
|
3212 | await this.model.refresh();
|
3213 | }
|
3214 |
|
3215 |
|
3216 | let isPushed = false;
|
3217 |
|
3218 | if (this.model.new) {
|
3219 | await this.push(deployOnlySubdirectory);
|
3220 | isPushed = true;
|
3221 | this.model = await this.project.platformProject.getEnvironment(encodeURIComponent(this.model.id));
|
3222 | }
|
3223 |
|
3224 |
|
3225 |
|
3226 | let needsSave = false;
|
3227 | const {
|
3228 | title
|
3229 | } = this.model;
|
3230 | const newTitle = this.getDisplayName();
|
3231 |
|
3232 | if (title !== newTitle) {
|
3233 | console.log(`The environment title is currently ${chalk.red(title)}. That will be changed to ${chalk.cyan(newTitle)}.`);
|
3234 | this.model.title = newTitle;
|
3235 | needsSave = true;
|
3236 | }
|
3237 |
|
3238 | if (this.getDeployTarget() === DeployTarget.Dynamic) {
|
3239 | if (this.model.parent !== newParent) {
|
3240 | console.log(`The parent of the environment was ${chalk.red(this.model.parent)}. That will be changed to ${chalk.cyan(newParent)}.`);
|
3241 | this.model.parent = newParent;
|
3242 | needsSave = true;
|
3243 | }
|
3244 |
|
3245 |
|
3246 |
|
3247 |
|
3248 | const p = this.environments.find(e => e.model.id === newParent);
|
3249 |
|
3250 | if (!p) {
|
3251 | const m = this.environments.find(e => e.model.id === 'master');
|
3252 | if (!m || m.model.new) throw new Error("The master envronment doesn't exist.");
|
3253 | await this.catchTooManyEnvironments(() => {
|
3254 | if (m.model.new) throw new Error('Not possible.');
|
3255 | return m.model.branch('Mirror', newParent);
|
3256 | });
|
3257 | } else if (!p.isActive()) {
|
3258 | await this.catchTooManyEnvironments(() => {
|
3259 | if (p.model.new) throw new Error('Not possible.');
|
3260 | return p.model.activate();
|
3261 | });
|
3262 | }
|
3263 | }
|
3264 |
|
3265 | if (needsSave) {
|
3266 | await this.model.update(this.model.data);
|
3267 | console.log('Updated environment information.');
|
3268 | }
|
3269 |
|
3270 |
|
3271 |
|
3272 | if (!isPushed) {
|
3273 | await this.push(deployOnlySubdirectory);
|
3274 | }
|
3275 |
|
3276 |
|
3277 |
|
3278 | if (!this.isActive()) {
|
3279 | await this.catchTooManyEnvironments(() => {
|
3280 | if (this.model.new) throw new Error('Not possible');
|
3281 | return this.model.activate();
|
3282 | });
|
3283 | console.log('\n\nThe environment is being activated.');
|
3284 | console.log('Follow the progress here: ');
|
3285 | console.log(`${this.project.getLink()}/${encodeURIComponent(this.model.id)}`);
|
3286 | }
|
3287 |
|
3288 | console.log(`\n\n${chalk.bgGreen.black(' DEPLOY DONE ')} Deploy successfully completed.\n\n`);
|
3289 | } catch (e) {
|
3290 | console.error(chalk.bgRed(' DEPLOY FAILED '));
|
3291 | throw e;
|
3292 | }
|
3293 | }
|
3294 |
|
3295 | async push(dir) {
|
3296 | return push((await this.project.getGitUrl()), this.model.id, {
|
3297 | dir,
|
3298 | showProgress: true
|
3299 | });
|
3300 | }
|
3301 |
|
3302 | getUrls() {
|
3303 | if (this.model.new) return [];
|
3304 | const urls = this.model.getRouteUrls();
|
3305 | return urls.filter(u => !u.startsWith('http://'));
|
3306 | }
|
3307 |
|
3308 | async catchTooManyEnvironments(action) {
|
3309 | try {
|
3310 | return await action();
|
3311 | } catch (error) {
|
3312 | if (error.message !== 'This action would raise the count of environments over its limit.') {
|
3313 | throw error;
|
3314 | }
|
3315 |
|
3316 | console.log(chalk.red('\n\nThere are not enough environments available.\n\n'));
|
3317 | const envsThatCanBeDeleted = this.environments.filter(env => env.canBeResyncedOrDeactivated() && !env.hasOptedOutDeactvation());
|
3318 |
|
3319 | if (!envsThatCanBeDeleted.length) {
|
3320 | throw new Error('There are no environments that can be deactivated. Please upgrade the number of available environments.');
|
3321 | }
|
3322 |
|
3323 | if (process.env.CI) {
|
3324 | throw new Error('Use the Burst CLI locally to choose an environment to remove.');
|
3325 | }
|
3326 |
|
3327 | const {
|
3328 | envToDeactivate
|
3329 | } = await inquirer.prompt([{
|
3330 | type: 'list',
|
3331 | name: 'envToDeactivate',
|
3332 | message: '💣 What environment do you want to deactivate? (we will create a backup before deactivation, just to be sure)',
|
3333 | choices: envsThatCanBeDeleted.map(env => ({
|
3334 | name: env.getDisplayName(),
|
3335 | value: env
|
3336 | }))
|
3337 | }]);
|
3338 | if (envToDeactivate.model.new) throw new Error('Not possible');
|
3339 | await envToDeactivate.model.backup();
|
3340 | await envToDeactivate.model.deactivate();
|
3341 | return action();
|
3342 | }
|
3343 | }
|
3344 |
|
3345 | }
|
3346 |
|
3347 | async function getPlatformToken() {
|
3348 | const {
|
3349 | stdout: res
|
3350 | } = await execa('platform', ['auth:token'], {
|
3351 | preferLocal: false
|
3352 | });
|
3353 |
|
3354 | if (res.length === 0) {
|
3355 | throw new Error("The Platform access_token token can't be fetched from the Platform CLI.");
|
3356 | }
|
3357 |
|
3358 | return res;
|
3359 | }
|
3360 |
|
3361 | class Heroku extends HostingProvider {
|
3362 | constructor(config) {
|
3363 | super(config);
|
3364 |
|
3365 | if (typeof config.id !== 'string') {
|
3366 | throw new Error('Hosting config not okay.');
|
3367 | }
|
3368 | }
|
3369 |
|
3370 | getDisplayName() {
|
3371 | return this.config.id;
|
3372 | }
|
3373 |
|
3374 | getLink() {
|
3375 | return '';
|
3376 | }
|
3377 |
|
3378 | isSameAs(config) {
|
3379 | return config.id === this.config.id;
|
3380 | }
|
3381 |
|
3382 | async getPossibleEnvs() {
|
3383 |
|
3384 | return [new HerokuApp(this)];
|
3385 | }
|
3386 |
|
3387 | }
|
3388 | class HerokuApp extends HostingProviderEnvironment {
|
3389 | constructor(hostingProvider) {
|
3390 | super();
|
3391 | this.hostingProvider = hostingProvider;
|
3392 | }
|
3393 |
|
3394 | getDisplayName() {
|
3395 | return this.hostingProvider.getDisplayName();
|
3396 | }
|
3397 |
|
3398 | async deploy() {
|
3399 | throw new Error('Not possible to deploy a Heroku application yet.');
|
3400 | }
|
3401 |
|
3402 | getUrls() {
|
3403 | return [];
|
3404 | }
|
3405 |
|
3406 | }
|
3407 |
|
3408 | const hostingProviders = {
|
3409 | platform: Platform,
|
3410 | heroku: Heroku
|
3411 | };
|
3412 |
|
3413 | let DeployTarget;
|
3414 |
|
3415 | (function (DeployTarget) {
|
3416 | DeployTarget["Production"] = "production";
|
3417 | DeployTarget["Staging"] = "staging";
|
3418 | DeployTarget["Dynamic"] = "dynamic";
|
3419 | DeployTarget["Other"] = "other";
|
3420 | })(DeployTarget || (DeployTarget = {}));
|
3421 |
|
3422 | function isFile(path) {
|
3423 | try {
|
3424 | return fs.statSync(path).isFile();
|
3425 | } catch (_unused) {
|
3426 | return false;
|
3427 | }
|
3428 | }
|
3429 |
|
3430 | const burstYamlPath = `${repoRoot}/burst.yaml`;
|
3431 | const gitlabYamlPath = `${repoRoot}/.gitlab-ci.yml`;
|
3432 | const projectConfig = getProjectConfiguration(isFile(burstYamlPath) ? fs.readFileSync(burstYamlPath, 'utf8') : '{}', isFile(gitlabYamlPath) ? fs.readFileSync(gitlabYamlPath, 'utf8') : '{}', dir => {
|
3433 | const path = dir ? `${repoRoot}/${dir}` : repoRoot;
|
3434 |
|
3435 | try {
|
3436 | const isDir = fs.statSync(path).isDirectory();
|
3437 |
|
3438 | if (!isDir) {
|
3439 | throw new Error(`The location ${path} was found, but it's not a directory.`);
|
3440 | }
|
3441 |
|
3442 | return path;
|
3443 | } catch (e) {
|
3444 | console.log();
|
3445 | console.log();
|
3446 | console.log(chalk.red("Your burst.yaml file references a path that doesn't exist:"));
|
3447 | console.log(chalk.yellow(path));
|
3448 | console.log();
|
3449 | console.log();
|
3450 | console.log(chalk.red('Please fix the burst.yaml file in the root.'));
|
3451 | console.log();
|
3452 | console.log();
|
3453 | throw e;
|
3454 | }
|
3455 | });
|
3456 |
|
3457 | class ProjectInfo {
|
3458 | |
3459 |
|
3460 |
|
3461 |
|
3462 |
|
3463 |
|
3464 |
|
3465 | async getHostingProvidersWithApps() {
|
3466 | const hostingProvidersWithApps = [];
|
3467 | projectConfig.apps.forEach(app => {
|
3468 |
|
3469 | if (typeof app.options.hosting === 'undefined') return;
|
3470 |
|
3471 | const hostingConfigs = Array.isArray(app.options.hosting) ? app.options.hosting : [app.options.hosting];
|
3472 | hostingConfigs.forEach(hc => {
|
3473 |
|
3474 | if (typeof hc !== 'object' || typeof hc.type !== 'string') {
|
3475 | throw new Error('Please check your burst.yaml file.');
|
3476 | }
|
3477 |
|
3478 | const {
|
3479 | type
|
3480 | } = hc,
|
3481 | hostingConfig = _objectWithoutProperties(hc, ["type"]);
|
3482 |
|
3483 |
|
3484 | const ThisHostingProvider = hostingProviders[type];
|
3485 |
|
3486 | if (!ThisHostingProvider) {
|
3487 | throw new Error(`There is no hosting provider with the name '${type}' supported.`);
|
3488 | }
|
3489 |
|
3490 |
|
3491 |
|
3492 | const existingHosting = hostingProvidersWithApps.find(h => h.hostingProvider instanceof ThisHostingProvider && h.hostingProvider.isSameAs(hostingConfig));
|
3493 |
|
3494 | if (existingHosting) {
|
3495 | existingHosting.apps.push(app);
|
3496 | } else {
|
3497 | hostingProvidersWithApps.push({
|
3498 | hostingProvider: new ThisHostingProvider(hostingConfig),
|
3499 | apps: [app]
|
3500 | });
|
3501 | }
|
3502 | });
|
3503 | });
|
3504 | return hostingProvidersWithApps;
|
3505 | }
|
3506 | |
3507 |
|
3508 |
|
3509 |
|
3510 |
|
3511 |
|
3512 |
|
3513 |
|
3514 | async getHostingProvidersByAppCominations() {
|
3515 | const hostings = await this.getHostingProvidersWithApps();
|
3516 | const hostingsGrouped = lodash.groupBy(hostings, hosting => hosting.apps.map(a => a.name).sort().join('__'));
|
3517 | return Object.values(hostingsGrouped).map(hostingsGroup => ({
|
3518 | apps: hostingsGroup[0].apps,
|
3519 | hostingProviders: hostingsGroup.map(hosting => hosting.hostingProvider)
|
3520 | }));
|
3521 | }
|
3522 |
|
3523 | }
|
3524 |
|
3525 | let projectInfo;
|
3526 | function getProjectInfo() {
|
3527 | if (projectInfo) return projectInfo;
|
3528 | projectInfo = new ProjectInfo();
|
3529 | return projectInfo;
|
3530 | }
|
3531 |
|
3532 | const composerHelperDir = path$1__default.join(__dirname, '../composer-helper');
|
3533 | function usePHPCS(allFiles, fix) {
|
3534 | const files = React.useMemo(() => allFiles.filter(f => f.path.endsWith('.php') || f.path.endsWith('.module') || f.path.endsWith('.theme') || f.path.endsWith('.inc') || f.path.endsWith('.install')), [allFiles]);
|
3535 | const composerInstalled = useComposerHelper(files.length > 0 && projectConfig.lintPhpEnabled);
|
3536 | const fileChunksPerStandard = React.useMemo(() => {
|
3537 | const filesPerStandard = lodash.groupBy(files, file => {
|
3538 | if (file.app) {
|
3539 | if (file.app.type === 'drupal') {
|
3540 | return `${composerHelperDir}/drupal_ruleset.xml`;
|
3541 | }
|
3542 |
|
3543 | if (file.app.type === 'magento') {
|
3544 | return `${composerHelperDir}/magento_ruleset.xml`;
|
3545 | }
|
3546 |
|
3547 | if (file.app.type === 'wordpress') {
|
3548 | return `${composerHelperDir}/wordpress_ruleset.xml`;
|
3549 | }
|
3550 | }
|
3551 |
|
3552 | return `${composerHelperDir}/other_ruleset.xml`;
|
3553 | });
|
3554 | return lodash.flatten(Object.entries(filesPerStandard).map(([standard, fs]) => lodash.chunk(fs, 20).map(fc => ({
|
3555 | chunkFiles: fc,
|
3556 | standard
|
3557 | }))));
|
3558 | }, [files]);
|
3559 | const [results, setResults] = React.useState({});
|
3560 | const [filesFixed, setFilesFixed] = React.useState(0);
|
3561 | const [filesWithoutFixes, setFilesWithoutFixes] = React.useState(0);
|
3562 | React.useEffect(() => {
|
3563 | if (!composerInstalled) return;
|
3564 | const queue = new PQueue({
|
3565 | concurrency: 20
|
3566 | });
|
3567 | queue.addAll(fileChunksPerStandard.map(({
|
3568 | chunkFiles,
|
3569 | standard
|
3570 | }) => async () => {
|
3571 |
|
3572 | const args = [...chunkFiles.map(f => f.absolutePath), '-q', `--standard=${standard}`];
|
3573 |
|
3574 | const result = parsePhpcsResult((await execa(`${composerHelperDir}/vendor/bin/phpcs`, [...args, '--report=json'], {
|
3575 | reject: false,
|
3576 | preferLocal: false
|
3577 | })).stdout);
|
3578 |
|
3579 |
|
3580 | chunkFiles.forEach(f => {
|
3581 | if (!result.files[f.absolutePath]) result.files[f.absolutePath] = {
|
3582 | errors: 0,
|
3583 | warnings: 0,
|
3584 | messages: []
|
3585 | };
|
3586 | });
|
3587 | setResults(r => _objectSpread({}, r, result.files));
|
3588 |
|
3589 | if (fix) {
|
3590 | if (result.totals.fixable > 0) {
|
3591 | await execa(`${composerHelperDir}/vendor/bin/phpcbf`, args, {
|
3592 | reject: false,
|
3593 | preferLocal: false
|
3594 | });
|
3595 | setFilesFixed(f => f + chunkFiles.length);
|
3596 | } else {
|
3597 | setFilesWithoutFixes(f => f + chunkFiles.length);
|
3598 | }
|
3599 | }
|
3600 | }));
|
3601 | return () => queue.clear();
|
3602 | }, [composerInstalled, fileChunksPerStandard, fix]);
|
3603 |
|
3604 | const errors = lodash.flatten(Object.entries(results).map(([filename, r]) => r.messages.filter(message => fix ? message.type === 'ERROR' && !message.fixable : message.type === 'ERROR' || message.fixable).map(message => ({
|
3605 | linter: 'PHPCS',
|
3606 | filename,
|
3607 | autoFixable: message.fixable,
|
3608 | message: message.message,
|
3609 | rule: message.source,
|
3610 | sourceLocation: {
|
3611 | start: {
|
3612 | line: message.line,
|
3613 | column: message.column
|
3614 | }
|
3615 | }
|
3616 | }))));
|
3617 |
|
3618 | if (composerInstalled === false) {
|
3619 | errors.push({
|
3620 | linter: 'PHPCS',
|
3621 | filename: 'Composer dependencies',
|
3622 | autoFixable: false,
|
3623 | message: "The composer dependencies couldn't be installed. PHP files can't be linted."
|
3624 | });
|
3625 | }
|
3626 |
|
3627 | const filesLinted = Object.keys(results).length;
|
3628 | const done = !projectConfig.lintPhpEnabled || composerInstalled === false || filesLinted === files.length && (!fix || files.length - filesFixed - filesWithoutFixes === 0);
|
3629 | return {
|
3630 | errors,
|
3631 | files,
|
3632 | filesLinted,
|
3633 | filesFixed,
|
3634 | filesWithFixes: fix ? files.length - filesWithoutFixes : 0,
|
3635 | done
|
3636 | };
|
3637 | }
|
3638 |
|
3639 | function parsePhpcsResult(result) {
|
3640 | return JSON.parse(result);
|
3641 | }
|
3642 |
|
3643 | function useComposerHelper(install) {
|
3644 | const [installCompleted, setInstallCompleted] = React.useState();
|
3645 | React.useEffect(() => {
|
3646 | if (!install) return;
|
3647 | const composerInstall = execa('composer', ['install', '--no-interaction'], {
|
3648 | cwd: composerHelperDir,
|
3649 | reject: false,
|
3650 | preferLocal: false
|
3651 | });
|
3652 | composerInstall.then(a => {
|
3653 | if (a.killed) return;
|
3654 | if (a.failed) setInstallCompleted(false);
|
3655 | setInstallCompleted(true);
|
3656 | });
|
3657 | return () => composerInstall.kill();
|
3658 | }, [install]);
|
3659 | return installCompleted;
|
3660 | }
|
3661 |
|
3662 | const readFileAsync = util.promisify(fs.readFile);
|
3663 | const writeFileAsync = util.promisify(fs.writeFile);
|
3664 | function usePrettier(allFiles, fix) {
|
3665 | const prettier = usePrettierWorker();
|
3666 | const [filesInfo, setFilesInfo] = React.useState({});
|
3667 | React.useEffect(() => {
|
3668 | const queue = new PQueue({
|
3669 | concurrency: 10
|
3670 | });
|
3671 | queue.addAll(allFiles.map(file => async () => {
|
3672 |
|
3673 | if (/\/config\/[\w/]+\/[\w.-]+\.yml$/.test(file.absolutePath)) {
|
3674 | setFilesInfo(i => _objectSpread({}, i, {
|
3675 | [file.absolutePath]: {
|
3676 | ignored: true,
|
3677 | inferredParser: null
|
3678 | }
|
3679 | }));
|
3680 | return;
|
3681 | }
|
3682 |
|
3683 | const fileInfo = await prettier.getFileInfo(file.absolutePath);
|
3684 | setFilesInfo(i => _objectSpread({}, i, {
|
3685 | [file.absolutePath]: fileInfo
|
3686 | }));
|
3687 | }));
|
3688 | return () => queue.clear();
|
3689 | }, [allFiles, prettier]);
|
3690 | const filesChecked = Object.keys(filesInfo).length;
|
3691 | const files = React.useMemo(() => Object.entries(filesInfo).filter(([, result]) => result.inferredParser).map(([filename, result]) => ({
|
3692 | filename,
|
3693 | inferredParser: result.inferredParser
|
3694 | })), [filesInfo]);
|
3695 | const [results, setResults] = React.useState({});
|
3696 | const [errorResults, setErrorResults] = React.useState({});
|
3697 | React.useEffect(() => {
|
3698 | if (filesChecked < allFiles.length) return;
|
3699 | const queue = new PQueue({
|
3700 | concurrency: 10
|
3701 | });
|
3702 | queue.addAll(files.map(({
|
3703 | filename,
|
3704 | inferredParser
|
3705 | }) => async () => {
|
3706 |
|
3707 | const filePrettierConfig = _objectSpread({}, prettierConfig$1, {
|
3708 | parser: inferredParser
|
3709 | });
|
3710 |
|
3711 |
|
3712 | if (filename.endsWith('composer.lock') || filename.endsWith('composer.json')) {
|
3713 | filePrettierConfig.parser = 'json-stringify';
|
3714 | filePrettierConfig.tabWidth = 4;
|
3715 | }
|
3716 |
|
3717 | try {
|
3718 |
|
3719 | const fileContents = await readFileAsync(filename, {
|
3720 | encoding: 'utf8'
|
3721 | });
|
3722 |
|
3723 | const newFileContents = await prettier.format(fileContents, filePrettierConfig);
|
3724 |
|
3725 | const correct = fileContents === newFileContents;
|
3726 |
|
3727 | if (fix && !correct) {
|
3728 | await writeFileAsync(filename, newFileContents, {
|
3729 | encoding: 'utf8'
|
3730 | });
|
3731 | }
|
3732 |
|
3733 | setResults(r => _objectSpread({}, r, {
|
3734 | [filename]: correct
|
3735 | }));
|
3736 | } catch (e) {
|
3737 | setErrorResults(r => _objectSpread({}, r, {
|
3738 | [filename]: e.message || e.toString()
|
3739 | }));
|
3740 | }
|
3741 | }));
|
3742 | return () => queue.clear();
|
3743 | }, [allFiles.length, files, filesChecked, fix, prettier]);
|
3744 | const filesToLint = Object.keys(files).length;
|
3745 | const linted = Object.keys(results).length + Object.keys(errorResults).length;
|
3746 | const filesNotCorrect = Object.entries(results).filter(([, correct]) => !correct).map(([file]) => file);
|
3747 | const errors = [...(fix ? [] : filesNotCorrect.map(f => ({
|
3748 | linter: 'Prettier',
|
3749 | filename: f,
|
3750 | autoFixable: true,
|
3751 | message: 'Not according to Prettier styling.'
|
3752 | }))), ...Object.entries(errorResults).map(([filename, error]) => ({
|
3753 | linter: 'Prettier',
|
3754 | filename,
|
3755 | autoFixable: false,
|
3756 | message: `Error while linting with Prettier: ${error}`
|
3757 | }))];
|
3758 | return {
|
3759 | filesChecked,
|
3760 | filesToLint,
|
3761 | linted,
|
3762 | done: allFiles.length === filesChecked && linted === filesToLint,
|
3763 | errors,
|
3764 | fixed: fix ? filesNotCorrect : [],
|
3765 | filesNotCorrect
|
3766 | };
|
3767 | }
|
3768 |
|
3769 | function useStylelint(allFiles, fix) {
|
3770 | const [lintResults, setLintResults] = React.useState();
|
3771 | const [fixResults, setFixResults] = React.useState();
|
3772 | const filesLintable = React.useMemo(() => projectConfig.lintStylesEnabled ? allFiles.filter(({
|
3773 | filename: f
|
3774 | }) => !f.endsWith('.d.ts') && (f.endsWith('.js') || f.endsWith('.jsx') || f.endsWith('.ts') || f.endsWith('.tsx'))) : [], [allFiles]);
|
3775 | const filesFixable = React.useMemo(() => projectConfig.lintStylesEnabled ? allFiles.filter(({
|
3776 | filename: f
|
3777 | }) => f.endsWith('.css') || f.endsWith('.sass') || f.endsWith('.scss') || f.endsWith('.less')) : [], [allFiles]);
|
3778 | const filesForLintRun = React.useMemo(() => fix ? filesLintable : [...filesLintable, ...filesFixable], [filesFixable, filesLintable, fix]);
|
3779 | const filesForFixRun = React.useMemo(() => fix ? filesFixable : [], [filesFixable, fix]);
|
3780 | React.useEffect(() => {
|
3781 | if (!filesForLintRun.length) return;
|
3782 | stylelint.lint({
|
3783 | configFile: require.resolve('@burst/stylelint-config'),
|
3784 | files: filesForLintRun.map(f => f.absolutePath)
|
3785 | }).then(r => setLintResults(r));
|
3786 | }, [filesForLintRun]);
|
3787 | React.useEffect(() => {
|
3788 | if (!filesForFixRun.length) return;
|
3789 | stylelint.lint({
|
3790 | configFile: require.resolve('@burst/stylelint-config/pure'),
|
3791 | files: filesForFixRun.map(f => f.absolutePath),
|
3792 | fix: true
|
3793 | }).then(() =>
|
3794 |
|
3795 |
|
3796 | stylelint.lint({
|
3797 | configFile: require.resolve('@burst/stylelint-config/pure'),
|
3798 | files: filesForFixRun.map(f => f.absolutePath)
|
3799 | })).then(r => setFixResults(r));
|
3800 | }, [filesForFixRun]);
|
3801 | const errors = [];
|
3802 | [...(lintResults ? lintResults.results : []), ...(fixResults ? fixResults.results : [])].forEach(r => {
|
3803 | errors.push(...[...r.parseErrors, ...r.warnings].map(e => ({
|
3804 | linter: 'Stylelint',
|
3805 | filename: r.source,
|
3806 | autoFixable: false,
|
3807 | message: e.text.replace(` (${e.line}:${e.column})`, '').replace(` (${e.rule})`, ''),
|
3808 | rule: e.rule,
|
3809 | sourceLocation: {
|
3810 | start: {
|
3811 | line: e.line,
|
3812 | column: e.column
|
3813 | }
|
3814 | }
|
3815 | })));
|
3816 | });
|
3817 | return {
|
3818 | filesFixable,
|
3819 | filesToLint: filesForFixRun.length + filesForLintRun.length,
|
3820 | done: (!filesForLintRun.length || !!lintResults) && (!filesForFixRun.length || !!fixResults),
|
3821 | errors
|
3822 | };
|
3823 | }
|
3824 |
|
3825 | const lintingFailed = new Error('ERRORS');
|
3826 | class LintCommand extends Command {
|
3827 | constructor(...args) {
|
3828 | super(...args);
|
3829 |
|
3830 | _defineProperty(this, "command", 'lint [files...]');
|
3831 |
|
3832 | _defineProperty(this, "description", 'Lint files in the current git repository.');
|
3833 |
|
3834 | _defineProperty(this, "options", [{
|
3835 | flags: '-f, --fix',
|
3836 | description: 'Fix linting errors automatically if possible.'
|
3837 | }, {
|
3838 | flags: '-v, --verbose',
|
3839 | description: 'Show the source of every linting error.'
|
3840 | }, {
|
3841 | flags: '--summary',
|
3842 | description: 'Show a list of errors and how many times they occur.'
|
3843 | }, {
|
3844 | flags: '--staged',
|
3845 | description: 'Only lint staged files.'
|
3846 | }]);
|
3847 | }
|
3848 |
|
3849 | async action(filesToSearch, {
|
3850 | fix,
|
3851 | verbose,
|
3852 | summary,
|
3853 | staged
|
3854 | }) {
|
3855 | if (!projectConfig.lintEnabled) {
|
3856 | console.log(chalk.underline('\n\n\nThe Burst linter is not enabled for this project.\n'));
|
3857 | console.log('Is this a new project, or are you trying to add the linter');
|
3858 | console.log('to a project that is not yet lint-compatible? Then you can');
|
3859 | console.log("use the Gitlab CI Template to enable the linter. If that's");
|
3860 | console.log('not possible, you can add to the .gitlab-ci.yml:\n');
|
3861 | console.log(chalk.grey('variables:'));
|
3862 | console.log(chalk.grey(' BURST_LINT: enable\n'));
|
3863 | console.log('But using the Gitlab CI Template is preferred.\n\n');
|
3864 | console.log(chalk.bold.yellow(`If this is a project where linting was enabled before, you\nprobabily only have to ${chalk.underline('merge from master')}!`));
|
3865 | console.log('\n\nIf you have any questions, please ask Bart.\n\n');
|
3866 | process.exit(1);
|
3867 | }
|
3868 |
|
3869 | if (staged) {
|
3870 |
|
3871 | const lintStaged = require('lint-staged/src');
|
3872 |
|
3873 | if (!filesToSearch.length) {
|
3874 | process.chdir(repoRoot);
|
3875 | }
|
3876 |
|
3877 | lintStaged(console, `${__dirname}../../config/lint-staged.js`);
|
3878 | return;
|
3879 | }
|
3880 |
|
3881 | const a = ink.render(React__default.createElement(Lint, {
|
3882 | paths: filesToSearch,
|
3883 | fix: !!fix,
|
3884 | verbose: !!verbose,
|
3885 | summary: !!summary,
|
3886 | staged: !!staged
|
3887 | }));
|
3888 |
|
3889 | try {
|
3890 | await a.waitUntilExit();
|
3891 | } catch (e) {
|
3892 | if (e.message !== 'ERRORS') throw e;
|
3893 | process.exitCode = 1;
|
3894 | }
|
3895 |
|
3896 |
|
3897 | a.cleanup();
|
3898 | }
|
3899 |
|
3900 | }
|
3901 |
|
3902 | function Lint(props) {
|
3903 | const filePaths = useFilePaths(props.paths);
|
3904 |
|
3905 | useExit(!!filePaths && filePaths.length === 0, lintingFailed);
|
3906 |
|
3907 | if (!filePaths || !projectConfig.apps || !repoRoot) {
|
3908 | return React__default.createElement(ink.Box, null, "Listing all files in this repository...");
|
3909 | }
|
3910 |
|
3911 | if (filePaths.length === 0) {
|
3912 | return React__default.createElement(ink.Box, null, "We found no files.");
|
3913 | }
|
3914 |
|
3915 | const files = filePaths.map(path => ({
|
3916 | path,
|
3917 | absolutePath: `${repoRoot}/${path}`,
|
3918 | filename: path$1.basename(path),
|
3919 | app: projectConfig.apps.find(a => !!a.dir && path.startsWith(`${a.dir}/`)) || projectConfig.apps.find(a => !a.dir)
|
3920 | })).filter(f => !f.app || !f.app.disableLinting);
|
3921 | return React__default.createElement(Lint2, {
|
3922 | files: files,
|
3923 | verbose: props.verbose,
|
3924 | fix: props.fix,
|
3925 | repoRoot: repoRoot,
|
3926 | summary: props.summary
|
3927 | });
|
3928 | }
|
3929 |
|
3930 | function Lint2(props) {
|
3931 | const startTime = React.useMemo(() => new Date(), []);
|
3932 | const eslint = useEslint(props.files, props.fix);
|
3933 | const phpcs = usePHPCS(props.files, props.fix);
|
3934 | const stylelint = useStylelint(props.files, props.fix);
|
3935 | const prettierFiles = React.useMemo(() => props.files.filter(f => !eslint.files.includes(f) && !phpcs.files.includes(f) && !stylelint.filesFixable.includes(f)), [eslint.files, phpcs.files, props.files, stylelint.filesFixable]);
|
3936 | const prettier = usePrettier(prettierFiles, props.fix);
|
3937 | const tsChecker = useTsChecker(props.files);
|
3938 |
|
3939 | const allErrors = [...prettier.errors, ...eslint.errors, ...tsChecker.errors, ...phpcs.errors, ...stylelint.errors];
|
3940 | const done = eslint.done && tsChecker.done && phpcs.done && prettier.done && stylelint.done;
|
3941 | const numErrors = allErrors.length;
|
3942 | const numAutofixed = prettier.fixed.length + eslint.filesAutoFixed + phpcs.filesFixed;
|
3943 | const errorsAutofixable = allErrors.filter(e => e.autoFixable).length;
|
3944 | useExit(done, allErrors.length ? lintingFailed : undefined);
|
3945 | useTick();
|
3946 | return React__default.createElement(React__default.Fragment, null, React__default.createElement(ink.Box, {
|
3947 | marginTop: 1,
|
3948 | flexDirection: "column"
|
3949 | }, props.summary ? React__default.createElement(ErrorSummaryList, {
|
3950 | allErrors: allErrors
|
3951 | }) : React__default.createElement(FileErrorList, {
|
3952 | allErrors: allErrors,
|
3953 | repoRoot: props.repoRoot,
|
3954 | verbose: props.verbose
|
3955 | })), React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3956 | width: 15
|
3957 | }, "Git"), React__default.createElement(ink.Box, null, "Found ", React__default.createElement(ink.Color, {
|
3958 | cyan: true
|
3959 | }, props.files.length), " files.")), !!eslint.files.length && React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3960 | width: 15
|
3961 | }, "ESLint"), React__default.createElement(ink.Box, null, "Linted", ' ', React__default.createElement(NumberOfTotal, {
|
3962 | number: eslint.reports.length,
|
3963 | total: eslint.files.length
|
3964 | }), ' ', "files, found ", React__default.createElement(ErrorCount, {
|
3965 | errors: eslint.errors.length
|
3966 | }), ".")), !!prettierFiles.length && React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3967 | width: 15
|
3968 | }, "Prettier"), React__default.createElement(ink.Box, null, "Linted", ' ', React__default.createElement(NumberOfTotal, {
|
3969 | number: prettier.linted,
|
3970 | total: prettier.filesToLint
|
3971 | }), ' ', "files, found ", React__default.createElement(ErrorCount, {
|
3972 | errors: prettier.filesNotCorrect.length
|
3973 | }), ".")), !!tsChecker.files.length && React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3974 | width: 15
|
3975 | }, "Typescript"), tsChecker.done ? React__default.createElement(ink.Box, null, "Typechecked projects, found", ' ', React__default.createElement(ErrorCount, {
|
3976 | errors: tsChecker.errors.length
|
3977 | }), ".") : React__default.createElement(ink.Box, null, "Typechecking projects...", !!tsChecker.errors.length && React__default.createElement(React__default.Fragment, null, ' ', "found ", React__default.createElement(ErrorCount, {
|
3978 | errors: tsChecker.errors.length
|
3979 | }), " so far."))), !!phpcs.files.length && projectConfig.lintPhpEnabled && React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3980 | width: 15
|
3981 | }, "PHPCS"), React__default.createElement(ink.Box, null, "Linted", ' ', React__default.createElement(NumberOfTotal, {
|
3982 | number: phpcs.filesLinted,
|
3983 | total: phpcs.files.length
|
3984 | }), ' ', "files", props.fix && React__default.createElement(React__default.Fragment, null, ", fixed", ' ', React__default.createElement(NumberOfTotal, {
|
3985 | number: phpcs.filesFixed,
|
3986 | total: phpcs.filesWithFixes
|
3987 | }), ' ', "files"), ". Found ", React__default.createElement(ErrorCount, {
|
3988 | errors: phpcs.errors.length
|
3989 | }), ".")), projectConfig.lintPhpEnabled || React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3990 | width: 15
|
3991 | }, "PHPCS"), React__default.createElement(ink.Box, null, React__default.createElement(ink.Text, {
|
3992 | italic: true
|
3993 | }, "Disabled."))), !!stylelint.filesToLint && React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
3994 | width: 15
|
3995 | }, "Stylelint"), React__default.createElement(ink.Box, null, stylelint.done ? 'Linted' : 'Linting', ' ', React__default.createElement(ink.Color, {
|
3996 | cyan: true
|
3997 | }, stylelint.filesToLint), " files", stylelint.done ? '.' : '...', " Found", ' ', React__default.createElement(ErrorCount, {
|
3998 | errors: stylelint.errors.length
|
3999 | }), ".")), projectConfig.lintStylesEnabled || React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
4000 | width: 15
|
4001 | }, "Stylelint"), React__default.createElement(ink.Box, null, React__default.createElement(ink.Text, {
|
4002 | italic: true
|
4003 | }, "Disabled."))), React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
4004 | width: 15
|
4005 | }, "Time"), React__default.createElement(ink.Box, null, Math.round((new Date().getTime() - startTime.getTime()) / 1000), "s")), React__default.createElement(ink.Box, {
|
4006 | marginY: 1,
|
4007 | flexDirection: "column"
|
4008 | }, numErrors === 0 && numAutofixed === 0 && done ? React__default.createElement(ink.Text, {
|
4009 | underline: true
|
4010 | }, "No errors found. Perfect!") : numErrors === 0 && numAutofixed === 0 ? React__default.createElement(ink.Text, {
|
4011 | underline: true
|
4012 | }, "No errors found so far...") : numErrors === 0 && numAutofixed > 0 ? React__default.createElement(ink.Text, {
|
4013 | underline: true
|
4014 | }, "Autofixed ", numAutofixed, " file", numAutofixed === 1 ? '' : 's', done ? '' : ' so far', ", found no unfixable errors", done ? '.' : ' yet...') : numErrors > 0 && numAutofixed > 0 ? React__default.createElement(ink.Text, {
|
4015 | underline: true
|
4016 | }, "Autofixed ", numAutofixed, " file", numAutofixed === 1 ? '' : 's', done ? '' : ' so far', ", but also found ", allErrors.length, " error", allErrors.length === 1 ? ' ' : 's ', "that you need to fix manually.") : numErrors > 0 && numAutofixed === 0 ? React__default.createElement(ink.Text, {
|
4017 | underline: true
|
4018 | }, "Found ", allErrors.length, " error", allErrors.length === 1 ? '' : 's', done ? '.' : ' so far...') : null, !props.fix && errorsAutofixable > 0 && React__default.createElement(ink.Box, {
|
4019 | marginTop: 1
|
4020 | }, React__default.createElement(ink.Color, {
|
4021 | grey: true
|
4022 | }, "If you run ", React__default.createElement(ink.Color, {
|
4023 | red: true
|
4024 | }, "burst lint --fix"), " ", errorsAutofixable, ' ', "error", errorsAutofixable !== 1 && 's', " will be automatically fixed."))));
|
4025 | }
|
4026 |
|
4027 | function useTick() {
|
4028 | const [, setS] = React.useState(0);
|
4029 | React.useEffect(() => {
|
4030 | const t = setTimeout(() => setS(se => se + 1), 1000);
|
4031 | return () => clearTimeout(t);
|
4032 | });
|
4033 | }
|
4034 |
|
4035 | function FileErrorList(props) {
|
4036 | const errorsPerFile = lodash.groupBy(props.allErrors, 'filename');
|
4037 | return React__default.createElement(React__default.Fragment, null, Object.entries(errorsPerFile).map(([file, errors], i1) => React__default.createElement(ink.Box, {
|
4038 | marginBottom: 1,
|
4039 | flexDirection: "column",
|
4040 | key: file
|
4041 | }, React__default.createElement(ink.Text, {
|
4042 | italic: true
|
4043 | }, file.startsWith(props.repoRoot) ? file.substr(props.repoRoot.length + 1) : file), errors.map((e, i2) => React__default.createElement(LintErrorMessage
|
4044 | , {
|
4045 | key: `${i1}_${i2}`,
|
4046 | error: e,
|
4047 | verbose: props.verbose
|
4048 | })))));
|
4049 | }
|
4050 |
|
4051 | function ErrorSummaryList(props) {
|
4052 | const errorsPerError = lodash.countBy(props.allErrors, e => e.rule ? `${e.linter} - ${e.rule}` : `${e.linter} - ${e.message}`);
|
4053 | return React__default.createElement(ink.Box, {
|
4054 | marginBottom: 2,
|
4055 | flexDirection: "column"
|
4056 | }, React__default.createElement(ink.Text, {
|
4057 | italic: true
|
4058 | }, "There are ", Object.keys(errorsPerError).length, " different types of errors."), lodash.sortBy(Object.entries(errorsPerError), ['1', '0']).map(([error, errors]) => React__default.createElement(ink.Box, {
|
4059 | key: error
|
4060 | }, React__default.createElement(ink.Box, {
|
4061 | width: 6,
|
4062 | alignItems: "flex-end"
|
4063 | }, errors), React__default.createElement(ink.Box, {
|
4064 | textWrap: "wrap"
|
4065 | }, error))));
|
4066 | }
|
4067 |
|
4068 | function useFilePaths(paths) {
|
4069 | const [filePaths, setFilePaths] = React.useState(null);
|
4070 | React.useEffect(() => {
|
4071 | getListOfRepoFiles(paths).then(f => setFilePaths(f));
|
4072 | }, [paths]);
|
4073 | return filePaths;
|
4074 | }
|
4075 |
|
4076 | function LintErrorMessage({
|
4077 | error,
|
4078 | verbose
|
4079 | }) {
|
4080 | return React__default.createElement(React__default.Fragment, null, React__default.createElement(ink.Box, null, React__default.createElement(ink.Box, {
|
4081 | width: 3
|
4082 | }, error.autoFixable ? '✨' : ''), React__default.createElement(ink.Box, {
|
4083 | width: 10
|
4084 | }, error.linter), React__default.createElement(ink.Box, {
|
4085 | width: 10
|
4086 | }, error.sourceLocation ? React__default.createElement(ink.Color, {
|
4087 | grey: true,
|
4088 | blue: true
|
4089 | }, error.sourceLocation.start.line, ":", error.sourceLocation.start.column) : null), React__default.createElement(ink.Box, {
|
4090 | textWrap: "wrap"
|
4091 | }, error.message, " ", !!error.rule && React__default.createElement(ink.Color, {
|
4092 | grey: true
|
4093 | }, error.rule))), verbose && error.rawlines && error.sourceLocation && codeFrame.codeFrameColumns(error.rawlines, error.sourceLocation));
|
4094 | }
|
4095 |
|
4096 | function ErrorCount(props) {
|
4097 | return React__default.createElement(React__default.Fragment, null, React__default.createElement(ink.Color, {
|
4098 | red: !!props.errors,
|
4099 | cyan: !props.errors
|
4100 | }, props.errors), ' ', "error", props.errors !== 1 ? 's' : '');
|
4101 | }
|
4102 |
|
4103 | function NumberOfTotal(props) {
|
4104 | return React__default.createElement(React__default.Fragment, null, React__default.createElement(ink.Color, {
|
4105 | cyan: true
|
4106 | }, props.number), props.number !== props.total && React__default.createElement(React__default.Fragment, null, ' ', "/ ", React__default.createElement(ink.Color, {
|
4107 | cyan: true
|
4108 | }, props.total)));
|
4109 | }
|
4110 |
|
4111 | const {
|
4112 | SLACK_TOKEN,
|
4113 | GITLAB_USER_NAME
|
4114 | } = process.env;
|
4115 | const token = SLACK_TOKEN;
|
4116 | const web = new client.WebClient(token);
|
4117 | async function sendStartDeploymentMessage(project, environment) {
|
4118 | if (!token) return;
|
4119 | const attachment = {
|
4120 | color: '#ffff00',
|
4121 | fallback: `Deploy ${project.getDisplayName()}`,
|
4122 | title: `Deploy ${project.getDisplayName()}`,
|
4123 | title_link: project.getLink(),
|
4124 | text: GITLAB_USER_NAME ? `The Gitlab user ${GITLAB_USER_NAME} triggered a deploy.\n` : 'A deploy was triggered.\n',
|
4125 | fields: [{
|
4126 | title: 'Deploy start',
|
4127 | value: new Date().toTimeString(),
|
4128 | short: true
|
4129 | }, {
|
4130 | title: 'Deploy done',
|
4131 | value: 'Not yet...',
|
4132 | short: true
|
4133 | }, {
|
4134 | title: 'URLs',
|
4135 | value: environment.getUrls().join('\n'),
|
4136 | short: false
|
4137 | }]
|
4138 | };
|
4139 | const message = await web.chat.postMessage({
|
4140 | channel: '#deploys',
|
4141 | text: '',
|
4142 | attachments: [attachment]
|
4143 | });
|
4144 | return async (successful, text) => {
|
4145 | attachment.color = successful ? '#00ff00' : '#ff0000';
|
4146 | attachment.fields[1].value = new Date().toTimeString();
|
4147 | if (text) attachment.text += `${text}\n`;
|
4148 | await web.chat.update({
|
4149 | channel: message.channel,
|
4150 | text: '',
|
4151 | attachments: [attachment],
|
4152 | ts: message.ts
|
4153 | });
|
4154 | };
|
4155 | }
|
4156 |
|
4157 | const isCI$3 = require('is-ci');
|
4158 |
|
4159 | class DeployCommand extends Command {
|
4160 | constructor(...args) {
|
4161 | super(...args);
|
4162 |
|
4163 | _defineProperty(this, "command", 'deploy');
|
4164 |
|
4165 | _defineProperty(this, "description", 'Deploy one or more applications.');
|
4166 |
|
4167 | _defineProperty(this, "options", [{
|
4168 | flags: '--all',
|
4169 | description: "Deprecated. Doesn't do anything."
|
4170 | }, {
|
4171 | flags: '--production',
|
4172 | description: 'Deploy to the production environment.'
|
4173 | }, {
|
4174 | flags: '--same-branch',
|
4175 | description: "Deprecated. Doesn't do anything."
|
4176 | }]);
|
4177 | }
|
4178 |
|
4179 | async action(command) {
|
4180 | |
4181 |
|
4182 |
|
4183 | const allHostingProvidersPerAppCombination = await getProjectInfo().getHostingProvidersByAppCominations();
|
4184 |
|
4185 | if (allHostingProvidersPerAppCombination.length === 0) {
|
4186 | console.error('There are no apps configured for deployment.');
|
4187 | return process.exit(1);
|
4188 | }
|
4189 |
|
4190 | let hostingProvidersPerAppCombination = allHostingProvidersPerAppCombination;
|
4191 | |
4192 |
|
4193 |
|
4194 |
|
4195 |
|
4196 | if (!isCI$3 && allHostingProvidersPerAppCombination.length >= 2) {
|
4197 | const answers = await inquirer.prompt([{
|
4198 | type: 'list',
|
4199 | name: 'h',
|
4200 | message: 'What apps do you want to deploy?',
|
4201 | choices: [...allHostingProvidersPerAppCombination.map(h => ({
|
4202 | name: `Deploy ${h.apps.map(a => a.name).join(' + ')}`,
|
4203 | value: [h]
|
4204 | })), new inquirer.Separator(), {
|
4205 | name: 'All of the above',
|
4206 | value: hostingProvidersPerAppCombination
|
4207 | }]
|
4208 | }]);
|
4209 | hostingProvidersPerAppCombination = answers.h;
|
4210 | }
|
4211 | |
4212 |
|
4213 |
|
4214 |
|
4215 |
|
4216 |
|
4217 | const environmentsToDeploy = [];
|
4218 | const branch = await getCurrentBranch();
|
4219 |
|
4220 |
|
4221 | const suggestedTarget = command.production ? DeployTarget.Production : branch === 'master' ? DeployTarget.Staging : undefined;
|
4222 |
|
4223 |
|
4224 | const suggestedName = suggestedTarget ? undefined : branch;
|
4225 |
|
4226 | for (const appCombi of hostingProvidersPerAppCombination) {
|
4227 | const environments = lodash.flatten((await Promise.all(appCombi.hostingProviders.map(async provider => (await provider.getPossibleEnvs({
|
4228 | suggestedTarget,
|
4229 | suggestedName
|
4230 | })).map(environment => ({
|
4231 | provider,
|
4232 | environment,
|
4233 | apps: appCombi.apps
|
4234 | }))))));
|
4235 |
|
4236 |
|
4237 | if (isCI$3) {
|
4238 | environmentsToDeploy.push(...environments.filter(e => e.environment.isSuggested()));
|
4239 | } else {
|
4240 | const {
|
4241 | e
|
4242 | } = await inquirer.prompt([{
|
4243 | type: 'list',
|
4244 | name: 'e',
|
4245 | message: `Where do you want to deploy ${appCombi.apps.map(awdt => awdt.name).join(' + ')} to?`,
|
4246 | choices: [
|
4247 | ...lodash.sortBy(environments, ewa => ewa.environment.isSuggested() ? 0 : ewa.environment.isActive() ? 1 : 2).map(ewa => ({
|
4248 |
|
4249 | name: (ewa.environment.isSuggested() ? '🚀 ' : ' ') + getEnvironmentDisplayName(ewa),
|
4250 | value: ewa
|
4251 | }))],
|
4252 | pageSize: 30
|
4253 | }]);
|
4254 | environmentsToDeploy.push(e);
|
4255 | }
|
4256 | }
|
4257 |
|
4258 |
|
4259 | if (environmentsToDeploy.length === 0) {
|
4260 | console.error('There are no environments to deploy to.');
|
4261 | return process.exit(1);
|
4262 | }
|
4263 | |
4264 |
|
4265 |
|
4266 |
|
4267 |
|
4268 |
|
4269 | console.log("You're about to perform the following actions:");
|
4270 | environmentsToDeploy.forEach(e => console.log(` - ${getEnvironmentDisplayName(e)}`));
|
4271 |
|
4272 | if (!isCI$3) {
|
4273 | const {
|
4274 | sure
|
4275 | } = await inquirer.prompt([{
|
4276 | type: 'confirm',
|
4277 | name: 'sure',
|
4278 | message: `Are you sure?`
|
4279 | }]);
|
4280 | if (!sure) return process.exit(1);
|
4281 | }
|
4282 | |
4283 |
|
4284 |
|
4285 |
|
4286 |
|
4287 | for (const env of environmentsToDeploy) {
|
4288 |
|
4289 |
|
4290 | const hostingProvidersOfSameType = allHostingProvidersPerAppCombination.filter(hppac => hppac.hostingProviders.find(hp => hp.constructor === env.provider.constructor));
|
4291 |
|
4292 | if (hostingProvidersOfSameType.length > 1 && env.apps.length !== 1) {
|
4293 | console.error('Impossible to have multiple apps deployed when more then 1 hosting provider config of that type available.');
|
4294 | process.exit(1);
|
4295 | }
|
4296 |
|
4297 | const deployOnlySubdirectory = hostingProvidersOfSameType.length > 1 ? env.apps[0].dir : undefined;
|
4298 |
|
4299 | const done = env.environment.getDeployTarget() === DeployTarget.Production ? await sendStartDeploymentMessage(env.provider, env.environment).catch(e => console.error('Slack fail!', e)) : null;
|
4300 |
|
4301 | try {
|
4302 | await env.environment.deploy({
|
4303 | deployOnlySubdirectory
|
4304 | });
|
4305 | } catch (e) {
|
4306 |
|
4307 | if (done) {
|
4308 | await done(false, e.message).catch(console.error);
|
4309 | }
|
4310 |
|
4311 | throw e;
|
4312 | }
|
4313 |
|
4314 |
|
4315 | if (done) {
|
4316 | await done(true).catch(e => console.error('Slack fail!', e));
|
4317 | }
|
4318 | }
|
4319 | }
|
4320 |
|
4321 | }
|
4322 |
|
4323 | function getEnvironmentDisplayName(e) {
|
4324 | const displayName = e.apps.map(a => `Deploy ${chalk.magenta(a.name)} to ${chalk.cyan(e.environment.getDisplayName())}`).join(' and ') + chalk.grey(` - ${e.provider.getDisplayName()}`);
|
4325 | if (e.environment.isActive()) return displayName;
|
4326 | return chalk.dim(displayName) + chalk.grey(' (inactive)');
|
4327 | }
|
4328 |
|
4329 |
|
4330 |
|
4331 | var isArray = Array.isArray || function isArray(arg) {
|
4332 | return classofRaw(arg) == 'Array';
|
4333 | };
|
4334 |
|
4335 |
|
4336 |
|
4337 | var flattenIntoArray = function (target, original, source, sourceLen, start, depth, mapper, thisArg) {
|
4338 | var targetIndex = start;
|
4339 | var sourceIndex = 0;
|
4340 | var mapFn = mapper ? bindContext(mapper, thisArg, 3) : false;
|
4341 | var element;
|
4342 |
|
4343 | while (sourceIndex < sourceLen) {
|
4344 | if (sourceIndex in source) {
|
4345 | element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
|
4346 |
|
4347 | if (depth > 0 && isArray(element)) {
|
4348 | targetIndex = flattenIntoArray(target, original, element, toLength(element.length), targetIndex, depth - 1) - 1;
|
4349 | } else {
|
4350 | if (targetIndex >= 0x1FFFFFFFFFFFFF) throw TypeError('Exceed the acceptable array length');
|
4351 | target[targetIndex] = element;
|
4352 | }
|
4353 |
|
4354 | targetIndex++;
|
4355 | }
|
4356 | sourceIndex++;
|
4357 | }
|
4358 | return targetIndex;
|
4359 | };
|
4360 |
|
4361 | var flattenIntoArray_1 = flattenIntoArray;
|
4362 |
|
4363 | var SPECIES$4 = wellKnownSymbol('species');
|
4364 |
|
4365 |
|
4366 |
|
4367 | var arraySpeciesCreate = function (originalArray, length) {
|
4368 | var C;
|
4369 | if (isArray(originalArray)) {
|
4370 | C = originalArray.constructor;
|
4371 |
|
4372 | if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;
|
4373 | else if (isObject(C)) {
|
4374 | C = C[SPECIES$4];
|
4375 | if (C === null) C = undefined;
|
4376 | }
|
4377 | } return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
|
4378 | };
|
4379 |
|
4380 |
|
4381 |
|
4382 | _export({ target: 'Array', proto: true }, {
|
4383 | flat: function flat(/* depthArg = 1 */) {
|
4384 | var depthArg = arguments[0];
|
4385 | var O = toObject(this);
|
4386 | var sourceLen = toLength(O.length);
|
4387 | var A = arraySpeciesCreate(O, 0);
|
4388 | A.length = flattenIntoArray_1(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toInteger(depthArg));
|
4389 | return A;
|
4390 | }
|
4391 | });
|
4392 |
|
4393 |
|
4394 |
|
4395 | addToUnscopables('flat');
|
4396 |
|
4397 | const prettierConfig = require('@burst/prettier-config');
|
4398 |
|
4399 | const write = util.promisify(fs__default.writeFile);
|
4400 | const read = util.promisify(fs__default.readFile);
|
4401 | const unlink = util.promisify(fs__default.unlink);
|
4402 | const mkdir = util.promisify(fs__default.mkdir);
|
4403 | const access = util.promisify(fs__default.access);
|
4404 | const parseXml = util.promisify(new xml2js.Parser().parseString);
|
4405 | const buildXml = new xml2js.Builder();
|
4406 | const {
|
4407 | apps
|
4408 | } = projectConfig;
|
4409 | class ScaffoldCommand extends Command {
|
4410 | constructor(...args) {
|
4411 | super(...args);
|
4412 |
|
4413 | _defineProperty(this, "command", 'scaffold');
|
4414 |
|
4415 | _defineProperty(this, "description", 'Scaffolds various configuration files into the root of the git repository.');
|
4416 |
|
4417 | _defineProperty(this, "action", async () => {
|
4418 |
|
4419 |
|
4420 |
|
4421 | const filesToDelete = ['.eslintrc.yaml', '.prettierrc.yaml', 'tslint.yaml'];
|
4422 | await Promise.all(filesToDelete.map(async filename => {
|
4423 | if (await this.exists(`${repoRoot}/${filename}`)) {
|
4424 | await unlink(`${repoRoot}/${filename}`);
|
4425 | console.log(`💣 Deleted ${filename} because it isn't used anymore.`);
|
4426 | }
|
4427 | }));
|
4428 | const composerHelperDir = path$1__default.join(__dirname, '../composer-helper');
|
4429 | const rootApp = apps.find(a => a.dir === undefined);
|
4430 | const rootRuleset = rootApp ? rootApp.type : 'other';
|
4431 | const paths = {};
|
4432 | appTypes.filter(t => t !== rootRuleset).forEach(t => {
|
4433 | paths[t] = apps.filter(a => a.type === t).map(a => [a.path, `phpcs_temp.tmp/${a.dir}`]).flat();
|
4434 | });
|
4435 | const allNotOtherPaths = Object.values(paths).flat();
|
4436 | const phpcsRuleset = ['<?xml version="1.0"?>', '<ruleset name="Auto-generated ruleset for this project by the Burst CLI" namespace="Burst">', ` <rule ref="${composerHelperDir}/${rootRuleset}_ruleset.xml">`, ...allNotOtherPaths.map(p => ` <exclude-pattern>${p}</exclude-pattern>`), ` </rule>`, ...Object.entries(paths).map(([type, ps]) => ps.length ? ` <rule ref="${composerHelperDir}/${type}_ruleset.xml">\n${ps.map(p => ` <include-pattern>${p}</include-pattern>\n`).join('')} </rule>` : ` <!-- No ${type} apps -->`), '</ruleset>'];
|
4437 | await write(`${repoRoot}/phpcs.xml`, phpcsRuleset.join('\n'));
|
4438 | console.log('🔥 Written to phpcs.xml');
|
4439 | const eslintModuleFolder = `${require.resolve('eslint').split('/node_modules/eslint/')[0]}/node_modules`;
|
4440 | const eslintFolder = `${eslintModuleFolder}/eslint`;
|
4441 |
|
4442 | if (!(await this.exists(`${repoRoot}/.idea`))) {
|
4443 | console.log("⛔ The .idea folder doesn't exist, so IntelliJ won't be configured.");
|
4444 | } else {
|
4445 |
|
4446 | if (!(await this.exists(`${repoRoot}/.idea/jsLinters`))) {
|
4447 | await mkdir(`${repoRoot}/.idea/jsLinters`);
|
4448 | console.log('🔥 Created .idea/jsLinters');
|
4449 | }
|
4450 |
|
4451 | await write(`${repoRoot}/.idea/jsLinters/eslint.xml`, `<?xml version="1.0" encoding="UTF-8"?>
|
4452 | <project version="4">
|
4453 | <component name="EslintConfiguration">
|
4454 | <custom-configuration-file used="true" path="${require.resolve('@burst/eslint-config')}" />
|
4455 | </component>
|
4456 | </project>
|
4457 | `);
|
4458 | console.log('🔥 Written to .idea/jsLinters/eslint.xml');
|
4459 | const phpXmlPath = `${repoRoot}/.idea/php.xml`;
|
4460 |
|
4461 | if (!(await this.exists(phpXmlPath))) {
|
4462 | await write(`${repoRoot}/.idea/php.xml`, `<?xml version="1.0" encoding="UTF-8"?>
|
4463 | <project version="4">
|
4464 | <component name="PhpCodeSniffer">
|
4465 | <phpcs_settings>
|
4466 | <PhpCSConfiguration standards="Drupal;DrupalPractice;MySource;PEAR;PHPCS;PSR1;PSR2;Squiz;Zend" tool_path="${composerHelperDir}/vendor/bin/phpcs" timeout="30000" />
|
4467 | </phpcs_settings>
|
4468 | </component>
|
4469 | </project>
|
4470 | `);
|
4471 | console.log('🔥 Created .idea/php.xml');
|
4472 | } else {
|
4473 | try {
|
4474 | const phpXml = await parseXml((await read(phpXmlPath)));
|
4475 | phpXml.project.component = phpXml.project.component ? phpXml.project.component.filter(c => c.$.name !== 'PhpCodeSniffer') : [];
|
4476 | phpXml.project.component.push({
|
4477 | $: {
|
4478 | name: 'PhpCodeSniffer'
|
4479 | },
|
4480 | phpcs_settings: [{
|
4481 | PhpCSConfiguration: [{
|
4482 | $: {
|
4483 | standards: 'Drupal;DrupalPractice;MySource;PEAR;PHPCS;PSR1;PSR2;Squiz;Zend',
|
4484 | tool_path: `${composerHelperDir}/vendor/bin/phpcs`,
|
4485 | beautifier_path: `${composerHelperDir}/vendor/bin/phpcbf`,
|
4486 | timeout: 30000
|
4487 | }
|
4488 | }]
|
4489 | }]
|
4490 | });
|
4491 | await write(phpXmlPath, buildXml.buildObject(phpXml));
|
4492 | console.log('🔥 Adjusted .idea/php.xml');
|
4493 | } catch (e) {
|
4494 | console.error(e);
|
4495 | console.error();
|
4496 | console.log('⛔ Writing to .idea/php.xml not possible. Please configure the following phpcs package:');
|
4497 | console.error(` ${composerHelperDir}/vendor/bin/phpcs`);
|
4498 | }
|
4499 | }
|
4500 |
|
4501 | try {
|
4502 | const workspacePath = `${repoRoot}/.idea/workspace.xml`;
|
4503 | const workspaceXml = await parseXml((await read(workspacePath)));
|
4504 | const properties = workspaceXml.project.component.find(c => c.$.name === 'PropertiesComponent').property;
|
4505 | Object.entries({
|
4506 | 'node.js.detected.package.eslint': 'true',
|
4507 | 'node.js.path.for.package.eslint': 'project',
|
4508 | 'node.js.selected.package.eslint': eslintFolder,
|
4509 | 'node.js.detected.package.standard': 'true',
|
4510 | 'node.js.path.for.package.standard': 'project',
|
4511 | 'node.js.selected.package.standard': eslintFolder
|
4512 | }).forEach(([name, value]) => {
|
4513 | const property = properties.find(p => p.$.name === name);
|
4514 | if (property) property.$.value = value;else properties.push({
|
4515 | $: {
|
4516 | name,
|
4517 | value
|
4518 | }
|
4519 | });
|
4520 | });
|
4521 | await write(workspacePath, buildXml.buildObject(workspaceXml));
|
4522 | console.log('🔥 Written to .idea/workspace.xml');
|
4523 | } catch (e) {
|
4524 | console.error(e);
|
4525 | console.error();
|
4526 | console.log('⛔ Writing to .idea/workspace.xml not possible. Please configure the following eslint package:');
|
4527 | console.log(` ${eslintFolder}`);
|
4528 | }
|
4529 |
|
4530 | try {
|
4531 | const inspectionPath = `${repoRoot}/.idea/inspectionProfiles/Project_Default.xml`;
|
4532 |
|
4533 | if (!(await this.exists(`${repoRoot}/.idea/inspectionProfiles`))) {
|
4534 | await mkdir(`${repoRoot}/.idea/inspectionProfiles`);
|
4535 | console.log('🔥 Created .idea/inspectionProfiles');
|
4536 | }
|
4537 |
|
4538 | if (!(await this.exists(inspectionPath))) {
|
4539 | await write(inspectionPath, `<component name="InspectionProjectProfileManager">
|
4540 | <profile version="1.0">
|
4541 | <option name="myName" value="Project Default" />
|
4542 | <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
4543 | </profile>
|
4544 | </component>`);
|
4545 | console.log('🔥 Created .idea/inspectionProfiles/Project_Default.xml');
|
4546 | } else {
|
4547 | const inspectionXml = await parseXml((await read(inspectionPath)));
|
4548 | const profile = inspectionXml.component.profile[0];
|
4549 |
|
4550 | if (!profile.inspection_tool) {
|
4551 | profile.inspection_tool = [];
|
4552 | }
|
4553 |
|
4554 | profile.inspection_tool = profile.inspection_tool.filter(i => i.$.class !== 'Eslint' && i.$.class !== 'PhpCSValidationInspection');
|
4555 | profile.inspection_tool.push({
|
4556 | $: {
|
4557 | class: 'Eslint',
|
4558 | enabled: true,
|
4559 | level: 'WARNING',
|
4560 | enabled_by_default: 'true'
|
4561 | }
|
4562 | });
|
4563 | profile.inspection_tool.push({
|
4564 | $: {
|
4565 | class: 'PhpCSValidationInspection',
|
4566 | enabled: true,
|
4567 | level: 'WARNING',
|
4568 | enabled_by_default: 'true'
|
4569 | },
|
4570 | option: [{
|
4571 | $: {
|
4572 | name: 'CODING_STANDARD',
|
4573 | value: 'Custom'
|
4574 | }
|
4575 | }, {
|
4576 | $: {
|
4577 | name: 'CUSTOM_RULESET_PATH',
|
4578 | value: `${repoRoot}/phpcs.xml`
|
4579 | }
|
4580 | }, {
|
4581 | $: {
|
4582 | name: 'EXTENSIONS',
|
4583 | value: 'php'
|
4584 | }
|
4585 | }]
|
4586 | });
|
4587 | await write(inspectionPath, buildXml.buildObject(inspectionXml));
|
4588 | console.log('🔥 Adjusted .idea/inspectionProfiles/Project_Default.xml');
|
4589 | }
|
4590 | } catch (e) {
|
4591 | console.error(e);
|
4592 | console.error();
|
4593 | console.log('⛔ Writing to .idea/inspectionProfiles/Project_Default.xml not possible. You need to enable eslint in the project settings yourself.');
|
4594 | }
|
4595 | }
|
4596 |
|
4597 |
|
4598 |
|
4599 | const vscode = this.json(_objectSpread({
|
4600 |
|
4601 |
|
4602 | 'editor.rulers': [80],
|
4603 |
|
4604 | 'eslint.autoFixOnSave': true,
|
4605 | 'eslint.validate': ['javascript', 'javascriptreact', {
|
4606 | language: 'typescript',
|
4607 | autoFix: true
|
4608 | }, {
|
4609 | language: 'typescriptreact',
|
4610 | autoFix: true
|
4611 | }],
|
4612 | 'eslint.nodePath': `${eslintModuleFolder}/`,
|
4613 | 'eslint.options': {
|
4614 | configFile: require.resolve('@burst/eslint-config'),
|
4615 | useEslintRc: false,
|
4616 | reportUnusedDisaleDirectives: true
|
4617 | }
|
4618 | }, Object.entries(prettierConfig).reduce((c, [k, v]) => _objectSpread({}, c, {
|
4619 | [`prettier.${k}`]: v
|
4620 | }), {}), {
|
4621 |
|
4622 | 'editor.formatOnSave': true,
|
4623 |
|
4624 |
|
4625 | '[javascript]': {
|
4626 | 'editor.formatOnSave': false
|
4627 | },
|
4628 | '[javascriptreact]': {
|
4629 | 'editor.formatOnSave': false
|
4630 | },
|
4631 | '[typescript]': {
|
4632 | 'editor.formatOnSave': false
|
4633 | },
|
4634 | '[typescriptreact]': {
|
4635 | 'editor.formatOnSave': false
|
4636 | },
|
4637 | 'phpSniffer.executablesFolder': `${composerHelperDir}/vendor/bin/`,
|
4638 | 'phpSniffer.standard': `${repoRoot}/phpcs.xml`,
|
4639 | 'phpSniffer.run': 'onType',
|
4640 | 'phpcs.executablePath': `${composerHelperDir}/vendor/bin/phpcs`,
|
4641 | 'phpcs.standard': `${repoRoot}/phpcs.xml`,
|
4642 | 'css.validate': false,
|
4643 | 'stylelint.config': {
|
4644 | extends: require.resolve('@burst/stylelint-config')
|
4645 | }
|
4646 | })).trim().split('\n').slice(1, -1);
|
4647 |
|
4648 | if (!(await this.exists(`${repoRoot}/.vscode`))) {
|
4649 | await mkdir(`${repoRoot}/.vscode`);
|
4650 | console.log('🔥 Created .vscode');
|
4651 | }
|
4652 |
|
4653 | if (!(await this.exists(`${repoRoot}/.vscode/settings.json`))) {
|
4654 | await write(`${repoRoot}/.vscode/settings.json`, `{\n}`);
|
4655 | console.log('🔥 Created .vscode/settings.json');
|
4656 | }
|
4657 |
|
4658 | const vscodeFile = (await read(`${repoRoot}/.vscode/settings.json`, {
|
4659 | encoding: 'utf8'
|
4660 | })).trim().split('\n');
|
4661 | const startScaffoldL = ' // @start-burst-cli-scaffold';
|
4662 | const endScaffoldL = ' // @end-burst-cli-scaffold';
|
4663 | const startScaffoldI = vscodeFile.findIndex(l => l.trim() === startScaffoldL.trim());
|
4664 | const endScaffoldI = vscodeFile.findIndex(l => l.trim() === endScaffoldL.trim());
|
4665 | const newVscodeFile = startScaffoldI !== -1 && endScaffoldI !== -1 ? [
|
4666 | ...vscodeFile.slice(0, startScaffoldI + 1), ...vscode, ...vscodeFile.slice(endScaffoldI), ''] : [
|
4667 | '{', startScaffoldL, ...vscode, endScaffoldL,
|
4668 | ...vscodeFile.slice(1, -1), '}', ''];
|
4669 | await write(`${repoRoot}/.vscode/settings.json`, newVscodeFile.join('\n'));
|
4670 | console.log('🔥 Written to .vscode/settings.json');
|
4671 |
|
4672 | const gitignoreLines = ['# @start-burst-cli-gitignore', '', `# DON'T ADD ANY RULES BEFORE THIS BLOCK.`, `# These rules are automatically generated by the 'burst scaffold' command.`, '# Add your own rules after this block, or they will be overwritten.', '', '.vscode', '.idea', 'phpcs.xml', '', '# YOU CAN ADD RULES AFTER THE NEXT LINE.', '# @end-burst-cli-gitignore'];
|
4673 | const giS = gitignoreLines[0];
|
4674 | const giE = gitignoreLines[gitignoreLines.length - 1];
|
4675 | const gitignore = await read(`${repoRoot}/.gitignore`, {
|
4676 | encoding: 'utf8'
|
4677 | });
|
4678 |
|
4679 | if (gitignore.startsWith(giS)) {
|
4680 | await write(`${repoRoot}/.gitignore`, `${gitignoreLines.join('\n')}${gitignore.split(giE, 2)[1]}`);
|
4681 | console.log('🔥 Adjusted .gitignore rules');
|
4682 | } else {
|
4683 | await write(`${repoRoot}/.gitignore`, `${gitignoreLines.join('\n')}\n\n${gitignore}`);
|
4684 | console.log('🔥 Added new .gitignore rules');
|
4685 | }
|
4686 | });
|
4687 | }
|
4688 |
|
4689 | json(data) {
|
4690 | return JSON.stringify(data, null, 2);
|
4691 | }
|
4692 |
|
4693 | async exists(somePath) {
|
4694 | return access(somePath).then(() => true).catch(() => false);
|
4695 | }
|
4696 |
|
4697 | }
|
4698 |
|
4699 | class InstallCommand extends Command {
|
4700 | constructor(...args) {
|
4701 | super(...args);
|
4702 |
|
4703 | _defineProperty(this, "command", 'install');
|
4704 |
|
4705 | _defineProperty(this, "description", 'Installs all dependencies of a repository.');
|
4706 |
|
4707 | _defineProperty(this, "action", async () => {
|
4708 |
|
4709 |
|
4710 | const index = parseInt(process.env.CI_NODE_INDEX || '0', 10) - 1;
|
4711 | const total = parseInt(process.env.CI_NODE_TOTAL || '1', 10);
|
4712 |
|
4713 | const lockfiles = await getListOfRepoFiles(['package-lock.json', '*/package-lock.json', 'yarn.lock', '*/yarn.lock', 'composer.lock', '*/composer.lock'], true);
|
4714 |
|
4715 |
|
4716 |
|
4717 |
|
4718 |
|
4719 |
|
4720 |
|
4721 | const lockfilesToInstall = lockfiles.filter(({}, i) => (i - index) % total === 0);
|
4722 |
|
4723 | if (lockfilesToInstall.length === 0) {
|
4724 | console.log("This job doesn't do anything.");
|
4725 | console.log("That's completely fine, and you don't have to change anything about that.");
|
4726 |
|
4727 | if (lockfiles.length > 0) {
|
4728 | console.log(`Please look at the first ${lockfiles.length !== 1 ? `${lockfiles.length} jobs` : 'job'}.`);
|
4729 | }
|
4730 |
|
4731 | return;
|
4732 | }
|
4733 |
|
4734 | console.log('===================================');
|
4735 | console.log('INSTALLING THE FOLLOWING LOCKFILES:\n');
|
4736 | lockfilesToInstall.forEach(l => console.log(l));
|
4737 | console.log('===================================\n\n');
|
4738 | const root = await getRepoRoot();
|
4739 |
|
4740 | for (const lockfile of lockfilesToInstall) {
|
4741 | const absolutePath = `${root}/${lockfile}`;
|
4742 | console.log('===================================');
|
4743 | console.log('Starting installation of:');
|
4744 | console.log(absolutePath);
|
4745 | console.log('===================================\n');
|
4746 |
|
4747 | if (absolutePath.endsWith('/package-lock.json')) {
|
4748 | await exec('npm install', absolutePath);
|
4749 | } else if (absolutePath.endsWith('/yarn.lock')) {
|
4750 |
|
4751 |
|
4752 | if (lockfiles.includes(lockfile.replace('yarn.lock', 'package-lock.json'))) {
|
4753 | console.log('There is both a yarn.lock and package-lock.json in the same folder.');
|
4754 | console.log('Please delete one of them.');
|
4755 | process.exit(1);
|
4756 | }
|
4757 |
|
4758 | await exec('yarn', absolutePath);
|
4759 | } else if (absolutePath.endsWith('/composer.lock')) {
|
4760 | await exec('composer validate', absolutePath);
|
4761 | await exec('composer install --no-interaction', absolutePath);
|
4762 | } else {
|
4763 | console.log('Unexpected file.');
|
4764 | process.exit(1);
|
4765 | }
|
4766 | }
|
4767 |
|
4768 | const {
|
4769 | stdout: status
|
4770 | } = await execa('git', ['status', '--porcelain']);
|
4771 |
|
4772 | if (status) {
|
4773 | console.log("\n\nAfter installations, some files were changed. That shouldn't happen.");
|
4774 | console.log("It's about these files:");
|
4775 | console.log(status);
|
4776 | process.exit(1);
|
4777 | }
|
4778 | });
|
4779 | }
|
4780 |
|
4781 | }
|
4782 |
|
4783 | function exec(cmd, path) {
|
4784 | console.log(`\n\n$ ${cmd}\n\n`);
|
4785 | const [bin, ...args] = cmd.split(' ');
|
4786 | return execa(bin, args, {
|
4787 | cwd: path$1.dirname(path),
|
4788 | stdio: 'inherit',
|
4789 | preferLocal: false,
|
4790 | env: {
|
4791 | NODE_ENV: 'development'
|
4792 | }
|
4793 | });
|
4794 | }
|
4795 |
|
4796 | const rimraf = util.promisify(rimrafWithCallback);
|
4797 | const stagedFiles = util.promisify(stagedFilesWithCallback);
|
4798 | const read$1 = util.promisify(fs.readFile);
|
4799 | const write$1 = util.promisify(fs.writeFile);
|
4800 | const append = util.promisify(fs.appendFile);
|
4801 |
|
4802 | process.env.COMPOSER_MEMORY_LIMIT = '-1';
|
4803 | class UpdateDrupalCommand extends Command {
|
4804 | constructor(...args) {
|
4805 | super(...args);
|
4806 |
|
4807 | _defineProperty(this, "command", 'update-drupal');
|
4808 |
|
4809 | _defineProperty(this, "description", 'Updates a Drupal project to the latest versions of all modules');
|
4810 |
|
4811 | _defineProperty(this, "unstageFiles", []);
|
4812 |
|
4813 | _defineProperty(this, "options", [{
|
4814 | flags: '--no-db',
|
4815 | description: 'Do not download a fresh database and import it.'
|
4816 | }]);
|
4817 |
|
4818 | _defineProperty(this, "action", async ({
|
4819 | db
|
4820 | }) => {
|
4821 | const apps = projectConfig.apps.filter(a => a.type === 'drupal');
|
4822 |
|
4823 | if (!apps.length) {
|
4824 | console.log('There were no Drupal apps found in the burst.yaml file.');
|
4825 | }
|
4826 |
|
4827 | for (const app of apps) {
|
4828 |
|
4829 |
|
4830 |
|
4831 | process.chdir(app.path);
|
4832 |
|
4833 | const platform = app.options && isObject$1(app.options.hosting) && app.options.hosting.type === 'platform' && typeof app.options.hosting.id === 'string' && app.options.hosting.id;
|
4834 |
|
4835 | if (!platform) {
|
4836 | console.log(`The Drupal app ${app.name} doesn't have a Platform hosting configured in the burst.yaml file.`);
|
4837 | continue;
|
4838 | }
|
4839 |
|
4840 |
|
4841 | const platformApp = jsYaml.safeLoad((await read$1(`${app.path}/.platform.app.yaml`, 'utf8'))).name;
|
4842 |
|
4843 | if (typeof platformApp !== 'string') {
|
4844 | throw new Error("Platform app yaml doesn't contain a valid name.");
|
4845 | }
|
4846 |
|
4847 | console.log(`
|
4848 |
|
4849 | UPDATING DRUPAL
|
4850 |
|
4851 | Path: ${app.path}
|
4852 | Platform project: ${platform}
|
4853 | Platform app name: ${platformApp}
|
4854 |
|
4855 | `);
|
4856 |
|
4857 |
|
4858 | await execa.command('git reset');
|
4859 | await this.cleanComposer();
|
4860 |
|
4861 | await this.applyComposerConfig();
|
4862 | await this.commit('build(drupal): change composer config', 'composer.json composer.lock');
|
4863 |
|
4864 | await this.cleanComposer();
|
4865 | await this.logPromise('composer install', this.composer('install'));
|
4866 | await this.lint();
|
4867 |
|
4868 |
|
4869 | await this.commit('build(drupal): add missing files');
|
4870 | const devtool = process.env.MYSQL_DATABASE ? null : (await execa.command('ddev describe').catch(() => false)) ? 'ddev' : 'lando';
|
4871 |
|
4872 | if (devtool) {
|
4873 | await this.logPromise(`${devtool} start`, execa.command(`${devtool} start`));
|
4874 | } else {
|
4875 |
|
4876 |
|
4877 | const {
|
4878 | all: statusString
|
4879 | } = await this.drush(devtool, 'status --format=json');
|
4880 | const status = JSON.parse(statusString);
|
4881 | const settingsPath = `${status.root}/${status.site}/settings.php`;
|
4882 | await append(settingsPath, `
|
4883 | $databases['default']['default'] = [
|
4884 | 'database' => getenv('MYSQL_DATABASE'),
|
4885 | 'username' => 'root',
|
4886 | 'password' => getenv('MYSQL_ROOT_PASSWORD'),
|
4887 | 'host' => 'mariadb',
|
4888 | 'port' => getenv('MARIADB_PORT_3306_TCP_PORT'),
|
4889 | 'driver' => 'mysql',
|
4890 | 'prefix' => '',
|
4891 | 'collation' => 'utf8mb4_general_ci',
|
4892 | ];
|
4893 | `);
|
4894 | this.unstageFiles.push(settingsPath);
|
4895 | }
|
4896 |
|
4897 |
|
4898 | await this.logPromise('Logging result of "drush status"', this.drush(devtool, 'status', true));
|
4899 |
|
4900 | if (db) {
|
4901 |
|
4902 | await this.logPromise('database download', execa.command(`platform db:dump --project ${platform} --environment master --directory . --file drupal--dump.sql --app ${platformApp} --yes`));
|
4903 |
|
4904 |
|
4905 | await this.importDatabase(devtool);
|
4906 | await rimraf(`${process.cwd()}/drupal--dump.sql`);
|
4907 | }
|
4908 |
|
4909 |
|
4910 |
|
4911 | await this.clearCache(devtool);
|
4912 |
|
4913 | try {
|
4914 | await this.exportConfig(devtool);
|
4915 |
|
4916 | await this.lint();
|
4917 | await this.commit('fix(drupal): update config with latest production data');
|
4918 | } catch (e) {
|
4919 | console.log(e.all || e);
|
4920 | console.log(`${chalk.bgRed('ERROR')} Re-exporting config failed. Let's just ignore this for now.`);
|
4921 |
|
4922 | await execa.command('git checkout -- config');
|
4923 | }
|
4924 |
|
4925 | await this.addBurstDrupalDistribution();
|
4926 |
|
4927 | await this.logPromise('updating drupal modules with composer', this.composer('update burst/drupal-distribution drupal/* --with-all-dependencies'));
|
4928 | await this.clearCache(devtool);
|
4929 | await this.accountForSlowDocker(devtool, () => this.logPromise('update database', this.drush(devtool, 'updb')));
|
4930 |
|
4931 | try {
|
4932 | await this.exportConfig(devtool);
|
4933 | } catch (_unused) {
|
4934 | await this.clearCache(devtool);
|
4935 | await this.exportConfig(devtool);
|
4936 | }
|
4937 |
|
4938 | await this.lint();
|
4939 | await this.commit('fix(drupal): update all drupal-related packages');
|
4940 |
|
4941 | if (devtool) {
|
4942 | await this.logPromise(`${devtool} stop`, execa.command(`${devtool} stop`));
|
4943 | }
|
4944 | }
|
4945 |
|
4946 | console.log('Done with all sites.');
|
4947 | });
|
4948 |
|
4949 | _defineProperty(this, "log", {
|
4950 | start(label) {
|
4951 | console.time(label);
|
4952 | console.log(chalk.bgYellow('START'), label);
|
4953 | return () => {
|
4954 | process.stdout.write(`${chalk.bgGreen('DONE')} `);
|
4955 | console.timeEnd(label);
|
4956 | };
|
4957 | }
|
4958 |
|
4959 | });
|
4960 | }
|
4961 |
|
4962 | async applyComposerConfig() {
|
4963 | const l = this.log.start('Applying composer best practices');
|
4964 | await this.composer('config minimum-stability dev');
|
4965 | await this.composer('config prefer-stable true');
|
4966 | await this.composer('config discard-changes true');
|
4967 | await this.composer('config sort-packages true');
|
4968 | await this.composer('config extra.enable-patching true');
|
4969 | await this.composer('config extra.composer-exit-on-patch-failure true');
|
4970 | await this.composer('config extra.drupal-scaffold.locations web-root.web');
|
4971 | const composerFile = `${process.cwd()}/composer.json`;
|
4972 | await write$1(composerFile, (await read$1(composerFile, 'utf8')).replace(`"enable-patching": "true"`, `"enable-patching": true`).replace(`"composer-exit-on-patch-failure": "true"`, `"composer-exit-on-patch-failure": true`).replace(`"locations": "web-root.web"`, `"locations": {"web-root": "web"}`));
|
4973 | await this.composer('update --lock');
|
4974 | await this.lint();
|
4975 | l();
|
4976 | }
|
4977 |
|
4978 | async importDatabase(devtool) {
|
4979 | if (devtool) {
|
4980 | await this.logPromise('database import', execa.command(devtool === 'lando' ? 'lando db-import drupal--dump.sql' : 'ddev import-db --src=drupal--dump.sql'));
|
4981 | } else {
|
4982 | const connectionCommand = await this.drush(devtool, 'sql-connect');
|
4983 | this.log.start('database import');
|
4984 | await this.logPromise('database import', execa.command(`${connectionCommand.all} < drupal--dump.sql`, {
|
4985 | shell: true
|
4986 | }));
|
4987 | }
|
4988 | }
|
4989 |
|
4990 | async addBurstDrupalDistribution() {
|
4991 | let composerJson = await this.readJsonFile(`${process.cwd()}/composer.json`);
|
4992 | const composerLock = await this.readJsonFile(`${process.cwd()}/composer.lock`);
|
4993 | const burstDistribution = composerLock.packages.find(p => p.name === 'burst/drupal-distribution');
|
4994 | const hnDistribution = composerLock.packages.find(p => p.name === 'headless-ninja/drupal-distribution');
|
4995 |
|
4996 | if (burstDistribution && !hnDistribution) {
|
4997 | console.log('There was not a legacy version of the Burst distribution found that needs migration.');
|
4998 | return;
|
4999 | }
|
5000 |
|
5001 | if (burstDistribution) {
|
5002 | console.log('Found a legacy version of the Burst distribution that will be removed.');
|
5003 | const requiredPackagesByDists = [...Object.entries(burstDistribution.require), ...Object.entries(hnDistribution.require)];
|
5004 |
|
5005 |
|
5006 |
|
5007 | await this.logPromise('Adding packages of legacy Burst distribution to the root composer.json', this.composer(`require ${requiredPackagesByDists.filter(([p]) => p !== 'headless-ninja/drupal-distribution' && !Object.keys(composerJson.require).includes(p)).map(([p, v]) => `"${p}:${v}"`).join(' ')} --no-update`, {
|
5008 | shell: true
|
5009 | }));
|
5010 |
|
5011 | await this.logPromise('Removing legacy Burst distribution', this.composer('remove burst/drupal-distribution'));
|
5012 | await this.applyComposerConfig();
|
5013 | await this.commit('refactor(drupal): remove legacy Burst distribution');
|
5014 | }
|
5015 |
|
5016 | console.log('Installing latest version of the Burst distribution.');
|
5017 | await this.upgradeDistributionSettingsCall();
|
5018 |
|
5019 | if (composerLock.packages.some(p => p.name === 'drupal-composer/drupal-scaffold')) {
|
5020 | const configChangesDone = this.log.start('Remove old drupal-scaffold scripts');
|
5021 | composerJson = await this.readJsonFile(`${process.cwd()}/composer.json`);
|
5022 |
|
5023 | if (typeof composerJson.scripts === 'object') {
|
5024 | Object.entries(composerJson.scripts).forEach(([key, value]) => {
|
5025 | const newValue = (Array.isArray(value) ? value : [value]).filter(s => !s.startsWith('DrupalProject\\') && !s.startsWith('DrupalComposer\\') && s !== '@drupal-scaffold');
|
5026 |
|
5027 | if (newValue.length === 1) composerJson.scripts[key] = newValue[0];else if (newValue.length) composerJson.scripts[key] = newValue;else delete composerJson.scripts[key];
|
5028 | });
|
5029 | }
|
5030 |
|
5031 | if (composerJson.autoload && Array.isArray(composerJson.autoload.classmap)) {
|
5032 | composerJson.autoload.classmap = composerJson.autoload.classmap.filter(c => c !== 'scripts/composer/ScriptHandler.php');
|
5033 | if (composerJson.autoload.classmap.length === 0) delete composerJson.autoload.classmap;
|
5034 | if (Object.keys(composerJson.autoload).length === 0) delete composerJson.autoload;
|
5035 | }
|
5036 |
|
5037 | if (!composerJson.extra) composerJson.extra = {};
|
5038 | composerJson.extra['drupal-scaffold'] = {
|
5039 | locations: {
|
5040 | 'web-root': 'web'
|
5041 | }
|
5042 | };
|
5043 | await write$1(`${process.cwd()}/composer.json`, JSON.stringify(composerJson, null, 4));
|
5044 | configChangesDone();
|
5045 | }
|
5046 |
|
5047 | const packagesInLatest = [
|
5048 | 'composer/installers', 'cweagans/composer-patches', 'drupal/admin_toolbar', 'drupal/config_ignore', 'drupal/core', 'drupal/core-composer-scaffold', 'drupal/devel', 'drupal/paragraphs', 'drupal/pathauto', 'drupal/simple_sitemap', 'drush/drush',
|
5049 | 'drupal-composer/drupal-scaffold', 'drupal/console'];
|
5050 | await this.logPromise('Remove packages that are part of the latest Burst distribution', this.composer(`remove ${packagesInLatest.join(' ')}`));
|
5051 | await this.logPromise('Add latest Burst distribution', this.composer('require burst/drupal-distribution --update-with-all-dependencies'));
|
5052 | await this.lint();
|
5053 | await this.commit('feat(drupal): add Burst distribution');
|
5054 | }
|
5055 |
|
5056 | async upgradeDistributionSettingsCall() {
|
5057 |
|
5058 | const files = await execa.command('git grep -l burst_distribution_settings', {
|
5059 | reject: false
|
5060 | });
|
5061 | await Promise.all(files.stdout.split('\n').filter(Boolean).map(relativeFile => `${process.cwd()}/${relativeFile}`).map(async absoluteFile => this.logPromise(`Rewriting burst_distribution_settings() call in file ${absoluteFile}`, write$1(absoluteFile, (await read$1(absoluteFile, 'utf8')).replace(/burst_distribution_settings\([^)]*\)/g, `require_once __DIR__ . '/${path$1.relative(path$1.dirname(absoluteFile), `${process.cwd()}/web/profiles/contrib/burst-drupal-distribution/includes/settings.php`)}'`))).catch(() => {
|
5062 | })));
|
5063 | }
|
5064 |
|
5065 | async drush(devtool, drushCommand, echo = false) {
|
5066 | const drush = devtool === 'ddev' ? 'ddev . drush' : devtool === 'lando' ? 'lando drush' : `drush --root=${process.cwd()}`;
|
5067 | const cmd = `${drush} -y ${drushCommand}`;
|
5068 |
|
5069 | if (echo) {
|
5070 | await execa.command(cmd, {
|
5071 | stdio: 'inherit'
|
5072 | });
|
5073 | return null;
|
5074 | }
|
5075 |
|
5076 | return execa.command(cmd);
|
5077 | }
|
5078 |
|
5079 | cleanComposer() {
|
5080 | return Promise.all([rimraf(`${process.cwd()}/vendor`), rimraf(`${process.cwd()}/web/core`), rimraf(`${process.cwd()}/web/modules/contrib`), rimraf(`${process.cwd()}/web/themes/contrib`), rimraf(`${process.cwd()}/web/profiles/contrib`), rimraf(`${process.cwd()}/drush/contrib`)]);
|
5081 | }
|
5082 |
|
5083 | async composer(command, options = {}, retryCount = 0) {
|
5084 | try {
|
5085 | const res = await execa.command(`composer ${command} --ansi${command.startsWith('install') || command.startsWith('require') || command.startsWith('update') ? ' --no-progress --no-suggest' : ''}`, options);
|
5086 |
|
5087 | if (retryCount > 0) {
|
5088 | console.log('This time, the command succeeded.');
|
5089 | }
|
5090 |
|
5091 | return res;
|
5092 | } catch (err) {
|
5093 | const log = err && err.all;
|
5094 | if (!log) throw err;
|
5095 | const cannotApplyMatch = log.match(/Cannot apply patch [^(]* \(([^)]*)\)/);
|
5096 |
|
5097 | if (cannotApplyMatch) {
|
5098 | const composerFile = `${process.cwd()}/composer.json`;
|
5099 | const contents = await read$1(composerFile, 'utf8');
|
5100 | const newContents = contents.replace(new RegExp(`,?\\s*"[^"]*":\\s"${cannotApplyMatch[1]}"`), '');
|
5101 |
|
5102 | if (contents !== newContents) {
|
5103 | await write$1(composerFile, newContents);
|
5104 | console.log(`Removed patch ${cannotApplyMatch[1]}`);
|
5105 |
|
5106 | await this.cleanComposer();
|
5107 |
|
5108 | return this.composer(command, options);
|
5109 | }
|
5110 |
|
5111 | console.log(`Could not find patch ${cannotApplyMatch[1]}, so can't fix.`);
|
5112 | }
|
5113 |
|
5114 |
|
5115 | console.log(log);
|
5116 | console.log(`\n\n\nThe composer command failed: ${command}`);
|
5117 |
|
5118 | if (retryCount < 3) {
|
5119 | console.log('Deleting all composer folders...');
|
5120 | await this.cleanComposer();
|
5121 | console.log(`Re-running command (retry ${retryCount + 1})...`);
|
5122 | return this.composer(command, options, retryCount + 1);
|
5123 | }
|
5124 |
|
5125 | throw err;
|
5126 | }
|
5127 | }
|
5128 |
|
5129 | async accountForSlowDocker(devtool, promise) {
|
5130 | try {
|
5131 | return await promise();
|
5132 | } catch (e) {
|
5133 | if (!devtool) throw e;
|
5134 | console.log('Retry in 40 seconds (could be slow Docker sync)');
|
5135 | await new Promise(r => setTimeout(r, 40 * 1000));
|
5136 | return promise();
|
5137 | }
|
5138 | }
|
5139 |
|
5140 | async clearCache(devtool) {
|
5141 | await this.accountForSlowDocker(devtool, () => this.logPromise('cache clear', this.drush(devtool, 'cache-rebuild')));
|
5142 | }
|
5143 |
|
5144 | async commit(msg, filesToAdd = '.') {
|
5145 | await execa.command(`git add ${filesToAdd}`);
|
5146 |
|
5147 | if (this.unstageFiles.length) {
|
5148 | await execa.command(`git reset -- ${this.unstageFiles.join(' ')}`);
|
5149 | }
|
5150 |
|
5151 | if (!(await stagedFiles()).length) {
|
5152 | console.log(`${chalk.bgBlue('EMPTY COMMIT SKIPPED')} ${msg}\n\n`);
|
5153 | return;
|
5154 | }
|
5155 |
|
5156 | const {
|
5157 | all
|
5158 | } = await execa('git', ['commit', `-m ${msg}`, '--author="Bart Langelaan <bart@burst-digital.com>"', '--no-verify']);
|
5159 | console.log(`\n\n${chalk.bgBlue('COMMIT')} ${all}\n\n`);
|
5160 | }
|
5161 |
|
5162 | async exportConfig(devtool) {
|
5163 | await rimraf(`${process.cwd()}/config/**/*.yml`);
|
5164 | await this.logPromise('config export', this.drush(devtool, 'config-export'));
|
5165 | }
|
5166 |
|
5167 | async readJsonFile(file) {
|
5168 | return JSON.parse((await read$1(file, 'utf8')));
|
5169 | }
|
5170 |
|
5171 | lint() {
|
5172 | return this.logPromise('Linting & fixing project', execa.command(`${process.argv0} ${process.argv[1]} lint --fix`, {
|
5173 | reject: false
|
5174 | }));
|
5175 | }
|
5176 |
|
5177 | async logPromise(label, promise) {
|
5178 | const promiseDone = this.log.start(label);
|
5179 |
|
5180 | try {
|
5181 | const p = await promise;
|
5182 | promiseDone();
|
5183 | return p;
|
5184 | } catch (e) {
|
5185 | process.stdout.write(`${chalk.bgRed('ERROR')} `);
|
5186 | console.timeEnd(label);
|
5187 | throw e;
|
5188 | }
|
5189 | }
|
5190 |
|
5191 | }
|
5192 |
|
5193 |
|
5194 |
|
5195 |
|
5196 |
|
5197 | const commands = [CheckCommand, LintCommand, DeployCommand, ScaffoldCommand, PrepareCICommand, InstallCommand, UpdateDrupalCommand];
|
5198 |
|
5199 |
|
5200 |
|
5201 |
|
5202 | function registerCommands(commander) {
|
5203 | commands.forEach(CommandClass => {
|
5204 |
|
5205 | const command = new CommandClass();
|
5206 |
|
5207 | const commanderCommand = commander.command(command.command).description(command.description);
|
5208 |
|
5209 | if (command.command === 'check') {
|
5210 | commanderCommand.action(command.action);
|
5211 | } else {
|
5212 | commanderCommand.action(checkFirst(command.action));
|
5213 | }
|
5214 |
|
5215 |
|
5216 | command.options.forEach(opt => commanderCommand.option(opt.flags, opt.description));
|
5217 | });
|
5218 | }
|
5219 |
|
5220 |
|
5221 |
|
5222 |
|
5223 | const pkg = require('../package.json');
|
5224 |
|
5225 | commander.version(pkg.version);
|
5226 |
|
5227 |
|
5228 | registerCommands(commander);
|
5229 |
|
5230 | commander.on('command:*', checkFirst(() => {
|
5231 | console.log(chalk`Command {magenta ${commander.args.join(' ')}} not found.`);
|
5232 | process.exit(1);
|
5233 | }));
|
5234 |
|
5235 |
|
5236 | commander.parse(process.argv);
|
5237 |
|
5238 | if (!process.argv.slice(2).length) {
|
5239 | commander.help();
|
5240 | }
|