datagrok-tools 4.12.10 → 4.12.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/bin/commands/check.js +83 -62
- package/bin/commands/publish.js +23 -17
- package/bin/grok.js +7 -0
- package/package.json +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Datagrok-tools changelog
|
|
2
|
+
|
|
3
|
+
## 4.12.12 (WIP)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* Check for datagrok-api dependency
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Latest package version in CHANGELOG check fix
|
|
12
|
+
|
|
13
|
+
## 4.12.11 (2023-08-04)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* GROK-13643 Check improvements:
|
|
18
|
+
* There is no beta property in package.json
|
|
19
|
+
* No datagrok-tools in dependencies (or latest version)
|
|
20
|
+
* Latest version from package.json is in CHANGELOG (warning)
|
|
21
|
+
* Ignore CHANGELOG checks for service packages ("servicePackage" property in package.json)
|
|
22
|
+
* Change supported h2 formats (1.7.9 (2023-07-24) and 1.7.9 (WIP))
|
|
23
|
+
* For packages < 1.0.0 exit with exit code 0, and only show warnings. And for packages >= 1.0.0, exit with a non-zero code (only for check command)
|
|
24
|
+
* If an invalid flag/command is specified, output the help and exit with exit code 1
|
|
25
|
+
|
|
26
|
+
## 4.12.10 (2023-08-01)
|
|
27
|
+
|
|
28
|
+
### Features
|
|
29
|
+
|
|
30
|
+
* Video recording enhancements
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* FuncSignatures check fix
|
|
35
|
+
|
|
36
|
+
## 4.12.7 (2023-07-28)
|
|
37
|
+
|
|
38
|
+
### Features
|
|
39
|
+
|
|
40
|
+
* Tools: Changelog h2 new format
|
|
41
|
+
|
|
42
|
+
## 4.12.4 (2023-07-24)
|
|
43
|
+
|
|
44
|
+
### Features
|
|
45
|
+
|
|
46
|
+
* GROK-13573 Tools: simplify output (add --verbose flag)
|
|
47
|
+
* GROK-13573 Tools: checks for changelog
|
package/bin/commands/check.js
CHANGED
|
@@ -19,6 +19,7 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
19
19
|
var _ignoreWalk = _interopRequireDefault(require("ignore-walk"));
|
|
20
20
|
var utils = _interopRequireWildcard(require("../utils/utils"));
|
|
21
21
|
var color = _interopRequireWildcard(require("../utils/color-utils"));
|
|
22
|
+
var testUtils = _interopRequireWildcard(require("../utils/test-utils"));
|
|
22
23
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
23
24
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof3(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
24
25
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
@@ -28,72 +29,83 @@ function check(args) {
|
|
|
28
29
|
var nOptions = Object.keys(args).length - 1;
|
|
29
30
|
if (args['_'].length !== 1 || nOptions > 2 || nOptions > 0 && !args.r && !args.recursive) return false;
|
|
30
31
|
var curDir = process.cwd();
|
|
31
|
-
if (args.recursive) {
|
|
32
|
-
var runChecksRec = function runChecksRec(dir) {
|
|
33
|
-
var files = _fs["default"].readdirSync(dir);
|
|
34
|
-
var _iterator = _createForOfIteratorHelper(files),
|
|
35
|
-
_step;
|
|
36
|
-
try {
|
|
37
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
38
|
-
var file = _step.value;
|
|
39
|
-
var filepath = _path["default"].join(dir, file);
|
|
40
|
-
var stats = _fs["default"].statSync(filepath);
|
|
41
|
-
if (stats.isDirectory()) {
|
|
42
|
-
if (utils.isPackageDir(filepath)) runChecks(filepath);else {
|
|
43
|
-
if (file !== 'node_modules' && !file.startsWith('.')) runChecksRec(_path["default"].join(dir, file));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
} catch (err) {
|
|
48
|
-
_iterator.e(err);
|
|
49
|
-
} finally {
|
|
50
|
-
_iterator.f();
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
runChecksRec(curDir);
|
|
54
|
-
} else {
|
|
32
|
+
if (args.recursive) return runChecksRec(curDir);else {
|
|
55
33
|
if (!utils.isPackageDir(curDir)) {
|
|
56
34
|
color.error('File `package.json` not found. Run the command from the package directory');
|
|
57
35
|
return false;
|
|
58
36
|
}
|
|
59
|
-
runChecks(curDir);
|
|
37
|
+
return runChecks(curDir);
|
|
60
38
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
39
|
+
}
|
|
40
|
+
function runChecks(packagePath) {
|
|
41
|
+
var files = _ignoreWalk["default"].sync({
|
|
42
|
+
path: packagePath,
|
|
43
|
+
ignoreFiles: ['.npmignore', '.gitignore']
|
|
44
|
+
});
|
|
45
|
+
var jsTsFiles = files.filter(function (f) {
|
|
46
|
+
return !f.startsWith('dist/') && (f.endsWith('.js') || f.endsWith('.ts'));
|
|
47
|
+
});
|
|
48
|
+
var packageFiles = ['src/package.ts', 'src/detectors.ts', 'src/package.js', 'src/detectors.js', 'src/package-test.ts', 'src/package-test.js', 'package.js', 'detectors.js'];
|
|
49
|
+
var funcFiles = jsTsFiles.filter(function (f) {
|
|
50
|
+
return packageFiles.includes(f);
|
|
51
|
+
});
|
|
52
|
+
var warnings = [];
|
|
53
|
+
var packageFilePath = _path["default"].join(packagePath, 'package.json');
|
|
54
|
+
var json = JSON.parse(_fs["default"].readFileSync(packageFilePath, {
|
|
55
|
+
encoding: 'utf-8'
|
|
56
|
+
}));
|
|
57
|
+
var webpackConfigPath = _path["default"].join(packagePath, 'webpack.config.js');
|
|
58
|
+
var isWebpack = _fs["default"].existsSync(webpackConfigPath);
|
|
59
|
+
var externals = null;
|
|
60
|
+
if (isWebpack) {
|
|
61
|
+
var content = _fs["default"].readFileSync(webpackConfigPath, {
|
|
62
|
+
encoding: 'utf-8'
|
|
72
63
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
64
|
+
externals = extractExternals(content);
|
|
65
|
+
if (externals) warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkImportStatements(packagePath, jsTsFiles, externals)));
|
|
66
|
+
}
|
|
67
|
+
warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkFuncSignatures(packagePath, funcFiles)));
|
|
68
|
+
warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkPackageFile(packagePath, json, {
|
|
69
|
+
isWebpack: isWebpack,
|
|
70
|
+
externals: externals
|
|
71
|
+
})));
|
|
72
|
+
if (!json.servicePackage) warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkChangelog(packagePath, json)));
|
|
73
|
+
if (warnings.length) {
|
|
74
|
+
console.log("Checking package ".concat(_path["default"].basename(packagePath), "..."));
|
|
75
|
+
warn(warnings);
|
|
76
|
+
if (json.version.startsWith('0') || warnings.every(function (w) {
|
|
77
|
+
return warns.some(function (ww) {
|
|
78
|
+
return w.includes(ww);
|
|
80
79
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkFuncSignatures(packagePath, funcFiles)));
|
|
85
|
-
warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkPackageFile(packagePath, {
|
|
86
|
-
isWebpack: isWebpack,
|
|
87
|
-
externals: externals
|
|
88
|
-
})));
|
|
89
|
-
warnings.push.apply(warnings, (0, _toConsumableArray2["default"])(checkChangelog(packagePath)));
|
|
90
|
-
if (warnings.length) {
|
|
91
|
-
console.log("Checking package ".concat(_path["default"].basename(packagePath), "..."));
|
|
92
|
-
warn(warnings);
|
|
93
|
-
} else console.log("Checking package ".concat(_path["default"].basename(packagePath), "...\t\t\t\u2713 OK"));
|
|
80
|
+
})) return true;
|
|
81
|
+
testUtils.exitWithCode(1);
|
|
94
82
|
}
|
|
83
|
+
console.log("Checking package ".concat(_path["default"].basename(packagePath), "...\t\t\t\u2713 OK"));
|
|
95
84
|
return true;
|
|
96
85
|
}
|
|
86
|
+
var warns = ['Latest package version', 'Datagrok API version should contain'];
|
|
87
|
+
function runChecksRec(dir) {
|
|
88
|
+
var files = _fs["default"].readdirSync(dir);
|
|
89
|
+
var _iterator = _createForOfIteratorHelper(files),
|
|
90
|
+
_step;
|
|
91
|
+
try {
|
|
92
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
93
|
+
var file = _step.value;
|
|
94
|
+
var filepath = _path["default"].join(dir, file);
|
|
95
|
+
var stats = _fs["default"].statSync(filepath);
|
|
96
|
+
if (stats.isDirectory()) {
|
|
97
|
+
if (utils.isPackageDir(filepath)) return runChecks(filepath);else {
|
|
98
|
+
if (file !== 'node_modules' && !file.startsWith('.')) runChecksRec(_path["default"].join(dir, file));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch (err) {
|
|
103
|
+
_iterator.e(err);
|
|
104
|
+
} finally {
|
|
105
|
+
_iterator.f();
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
97
109
|
function extractExternals(config) {
|
|
98
110
|
var externalsRegex = /(?<=externals)\s*:\s*(\{[\S\s]*?\})/;
|
|
99
111
|
var match = config.match(externalsRegex);
|
|
@@ -338,12 +350,9 @@ var sharedLibExternals = {
|
|
|
338
350
|
'codemirror': 'CodeMirror'
|
|
339
351
|
}
|
|
340
352
|
};
|
|
341
|
-
function checkPackageFile(packagePath, options) {
|
|
353
|
+
function checkPackageFile(packagePath, json, options) {
|
|
354
|
+
var _json$dependencies, _json$devDependencies, _json$devDependencies2, _json$dependencies2;
|
|
342
355
|
var warnings = [];
|
|
343
|
-
var packageFilePath = _path["default"].join(packagePath, 'package.json');
|
|
344
|
-
var json = JSON.parse(_fs["default"].readFileSync(packageFilePath, {
|
|
345
|
-
encoding: 'utf-8'
|
|
346
|
-
}));
|
|
347
356
|
var isPublicPackage = _path["default"].basename(_path["default"].dirname(packagePath)) === 'packages' && _path["default"].basename(_path["default"].dirname(_path["default"].dirname(packagePath))) === 'public';
|
|
348
357
|
if (!json.description) warnings.push('File "package.json": "description" field is empty. Provide a package description.');
|
|
349
358
|
if (Array.isArray(json.properties) && json.properties.length > 0) {
|
|
@@ -362,6 +371,13 @@ function checkPackageFile(packagePath, options) {
|
|
|
362
371
|
}
|
|
363
372
|
if (json.repository == null && isPublicPackage) warnings.push('File "package.json": add the "repository" field.');
|
|
364
373
|
if (json.author == null && isPublicPackage) warnings.push('File "package.json": add the "author" field.');
|
|
374
|
+
if (json.version.includes('beta') && isPublicPackage) warnings.push('File "package.json": public package cannot be beta version.');
|
|
375
|
+
var api = (_json$dependencies = json.dependencies) === null || _json$dependencies === void 0 ? void 0 : _json$dependencies['datagrok-api'];
|
|
376
|
+
if (api) {
|
|
377
|
+
if (api === '../../js-api') {} else if (api === 'latest') warnings.push('File "package.json": you should specify Datagrok API version constraint.');else if (!(api.startsWith('^') || api.startsWith('>'))) warnings.push('File "package.json": Datagrok API version should contain "^" or ">" symbol, otherwise it is locked to the single Datagrok version.');
|
|
378
|
+
}
|
|
379
|
+
var dt = (_json$devDependencies = (_json$devDependencies2 = json.devDependencies) === null || _json$devDependencies2 === void 0 ? void 0 : _json$devDependencies2['datagrok-tools']) !== null && _json$devDependencies !== void 0 ? _json$devDependencies : (_json$dependencies2 = json.dependencies) === null || _json$dependencies2 === void 0 ? void 0 : _json$dependencies2['datagrok-tools'];
|
|
380
|
+
if (dt && dt !== 'latest') warnings.push('File "package.json": "datagrok-tools" dependency must be "latest" version.');
|
|
365
381
|
if (Array.isArray(json.sources) && json.sources.length > 0) {
|
|
366
382
|
var _iterator6 = _createForOfIteratorHelper(json.sources),
|
|
367
383
|
_step6;
|
|
@@ -400,7 +416,8 @@ function checkPackageFile(packagePath, options) {
|
|
|
400
416
|
}
|
|
401
417
|
return warnings;
|
|
402
418
|
}
|
|
403
|
-
function checkChangelog(packagePath) {
|
|
419
|
+
function checkChangelog(packagePath, json) {
|
|
420
|
+
var _h2$0$match, _h2$, _h2$$match;
|
|
404
421
|
var warnings = [];
|
|
405
422
|
var clf;
|
|
406
423
|
try {
|
|
@@ -426,6 +443,10 @@ function checkChangelog(packagePath) {
|
|
|
426
443
|
} finally {
|
|
427
444
|
_iterator7.f();
|
|
428
445
|
}
|
|
446
|
+
regex = /^## (\d+\.\d+\.\d+)/;
|
|
447
|
+
var v1 = (_h2$0$match = h2[0].match(regex)) === null || _h2$0$match === void 0 ? void 0 : _h2$0$match[1];
|
|
448
|
+
var v2 = (_h2$ = h2[1]) === null || _h2$ === void 0 ? void 0 : (_h2$$match = _h2$.match(regex)) === null || _h2$$match === void 0 ? void 0 : _h2$$match[1];
|
|
449
|
+
if (v1 !== json.version && v2 !== json.version) warnings.push("Latest package version (".concat(json.version, ") is not in CHANGELOG"));
|
|
429
450
|
return warnings;
|
|
430
451
|
}
|
|
431
452
|
function warn(warnings) {
|
package/bin/commands/publish.js
CHANGED
|
@@ -39,7 +39,7 @@ function processPackage(_x, _x2, _x3, _x4, _x5, _x6) {
|
|
|
39
39
|
}
|
|
40
40
|
function _processPackage() {
|
|
41
41
|
_processPackage = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee3(debug, rebuild, host, devKey, packageName, suffix) {
|
|
42
|
-
var timestamps, url, zip, localTimestamps, files, isWebpack, distFiles, contentValidationLog, checkStart, jsTsFiles, webpackConfigPath, content, externals, importWarnings, funcFiles, funcWarnings, packageWarnings, uploadPromise, log;
|
|
42
|
+
var timestamps, url, zip, localTimestamps, files, isWebpack, distFiles, contentValidationLog, checkStart, jsTsFiles, packageFilePath, json, webpackConfigPath, content, externals, importWarnings, funcFiles, funcWarnings, packageWarnings, changelogWarnings, uploadPromise, log;
|
|
43
43
|
return _regenerator["default"].wrap(function _callee3$(_context3) {
|
|
44
44
|
while (1) {
|
|
45
45
|
switch (_context3.prev = _context3.next) {
|
|
@@ -120,6 +120,10 @@ function _processPackage() {
|
|
|
120
120
|
jsTsFiles = files.filter(function (f) {
|
|
121
121
|
return !f.startsWith('dist/') && (f.endsWith('.js') || f.endsWith('.ts'));
|
|
122
122
|
});
|
|
123
|
+
packageFilePath = _path["default"].join(curDir, 'package.json');
|
|
124
|
+
json = JSON.parse(_fs["default"].readFileSync(packageFilePath, {
|
|
125
|
+
encoding: 'utf-8'
|
|
126
|
+
}));
|
|
123
127
|
if (isWebpack) {
|
|
124
128
|
webpackConfigPath = _path["default"].join(curDir, 'webpack.config.js');
|
|
125
129
|
content = _fs["default"].readFileSync(webpackConfigPath, {
|
|
@@ -136,8 +140,10 @@ function _processPackage() {
|
|
|
136
140
|
});
|
|
137
141
|
funcWarnings = (0, _check.checkFuncSignatures)(curDir, funcFiles);
|
|
138
142
|
contentValidationLog += funcWarnings.join('\n') + (funcWarnings.length ? '\n' : '');
|
|
139
|
-
packageWarnings = (0, _check.checkPackageFile)(curDir);
|
|
143
|
+
packageWarnings = (0, _check.checkPackageFile)(curDir, json);
|
|
140
144
|
contentValidationLog += packageWarnings.join('\n') + (packageWarnings.length ? '\n' : '');
|
|
145
|
+
changelogWarnings = (0, _check.checkChangelog)(curDir, json);
|
|
146
|
+
contentValidationLog += changelogWarnings.join('\n') + (packageWarnings.length ? '\n' : '');
|
|
141
147
|
console.log("Checks finished in ".concat(Date.now() - checkStart, " ms"));
|
|
142
148
|
files.forEach(function (file) {
|
|
143
149
|
var fullPath = file;
|
|
@@ -212,41 +218,41 @@ function _processPackage() {
|
|
|
212
218
|
})["catch"](function (error) {
|
|
213
219
|
console.error(error);
|
|
214
220
|
});
|
|
215
|
-
_context3.next =
|
|
221
|
+
_context3.next = 56;
|
|
216
222
|
return zip.finalize();
|
|
217
|
-
case
|
|
218
|
-
_context3.prev =
|
|
219
|
-
_context3.next =
|
|
223
|
+
case 56:
|
|
224
|
+
_context3.prev = 56;
|
|
225
|
+
_context3.next = 59;
|
|
220
226
|
return uploadPromise;
|
|
221
|
-
case
|
|
227
|
+
case 59:
|
|
222
228
|
log = _context3.sent;
|
|
223
229
|
_fs["default"].unlinkSync('zip');
|
|
224
230
|
if (!(log['#type'] === 'ApiError')) {
|
|
225
|
-
_context3.next =
|
|
231
|
+
_context3.next = 67;
|
|
226
232
|
break;
|
|
227
233
|
}
|
|
228
234
|
color.error(log['message']);
|
|
229
235
|
console.error(log['innerMessage']);
|
|
230
236
|
return _context3.abrupt("return", 1);
|
|
231
|
-
case
|
|
237
|
+
case 67:
|
|
232
238
|
console.log(log);
|
|
233
239
|
color.warn(contentValidationLog);
|
|
234
|
-
case
|
|
235
|
-
_context3.next =
|
|
240
|
+
case 69:
|
|
241
|
+
_context3.next = 75;
|
|
236
242
|
break;
|
|
237
|
-
case
|
|
238
|
-
_context3.prev =
|
|
239
|
-
_context3.t1 = _context3["catch"](
|
|
243
|
+
case 71:
|
|
244
|
+
_context3.prev = 71;
|
|
245
|
+
_context3.t1 = _context3["catch"](56);
|
|
240
246
|
console.error(_context3.t1);
|
|
241
247
|
return _context3.abrupt("return", 1);
|
|
242
|
-
case
|
|
248
|
+
case 75:
|
|
243
249
|
return _context3.abrupt("return", 0);
|
|
244
|
-
case
|
|
250
|
+
case 76:
|
|
245
251
|
case "end":
|
|
246
252
|
return _context3.stop();
|
|
247
253
|
}
|
|
248
254
|
}
|
|
249
|
-
}, _callee3, null, [[3, 14], [
|
|
255
|
+
}, _callee3, null, [[3, 14], [56, 71]]);
|
|
250
256
|
}));
|
|
251
257
|
return _processPackage.apply(this, arguments);
|
|
252
258
|
}
|
package/bin/grok.js
CHANGED
|
@@ -21,11 +21,18 @@ if (command in commands) {
|
|
|
21
21
|
try {
|
|
22
22
|
if (!commands[command](argv)) {
|
|
23
23
|
console.log(help[command]);
|
|
24
|
+
exitWithCode(1);
|
|
24
25
|
}
|
|
25
26
|
} catch (err) {
|
|
26
27
|
console.error(err);
|
|
27
28
|
console.log(help[command]);
|
|
29
|
+
exitWithCode(1);
|
|
28
30
|
}
|
|
29
31
|
} else {
|
|
30
32
|
console.log(help.help);
|
|
31
33
|
}
|
|
34
|
+
|
|
35
|
+
function exitWithCode(code) {
|
|
36
|
+
console.log(`Exiting with code ${code}`);
|
|
37
|
+
process.exit(code);
|
|
38
|
+
}
|
package/package.json
CHANGED