accept-to-ship-action 0.3.15 → 0.3.16
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/.prettierrc.json +22 -0
- package/README.md +2 -2
- package/lib/getCheckRuns.d.ts +2 -2
- package/lib/getMergeMethod.js +4 -4
- package/lib/getOcktokit.js +4 -4
- package/lib/getPullRequest.d.ts +3 -3
- package/lib/getPullRequestComments.d.ts +2 -2
- package/lib/getPullRequestReviewRequests.d.ts +2 -2
- package/lib/getPullRequestReviews.d.ts +2 -2
- package/lib/getWorkflowRunJobs.d.ts +2 -2
- package/lib/index.js +35 -35
- package/lib/mergePullRequest.d.ts +3 -3
- package/package.json +2 -1
package/.prettierrc.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"arrowParens": "always",
|
|
3
|
+
"bracketSpacing": true,
|
|
4
|
+
"bracketSameLine": false,
|
|
5
|
+
"semi": true,
|
|
6
|
+
"singleQuote": true,
|
|
7
|
+
"tabWidth": 2,
|
|
8
|
+
"trailingComma": "all",
|
|
9
|
+
"importOrder": [
|
|
10
|
+
"^@action/core/(.*)$",
|
|
11
|
+
"^@action/github/(.*)$",
|
|
12
|
+
"^@action/exec/(.*)$",
|
|
13
|
+
"^@action/glob/(.*)$",
|
|
14
|
+
"^@action/(.*)$",
|
|
15
|
+
"<THIRD_PARTY_MODULES>",
|
|
16
|
+
"^[./]"
|
|
17
|
+
],
|
|
18
|
+
"importOrderSortIndividualImports": true,
|
|
19
|
+
"importOrderMergeDuplicateImports": true,
|
|
20
|
+
"importOrderBuiltinModulesToTop": true,
|
|
21
|
+
"importOrderTypeImportsToTop": true
|
|
22
|
+
}
|
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ jobs:
|
|
|
63
63
|
checks-watch-interval: 10 # optional
|
|
64
64
|
fail-if-timeout: false # optinal
|
|
65
65
|
request-zero-accept-zero: false # optional
|
|
66
|
-
custom-hashtag:
|
|
66
|
+
custom-hashtag: '#accept2ship' #optional
|
|
67
67
|
|
|
68
68
|
pass-to-ship:
|
|
69
69
|
name: Pass to Ship
|
|
@@ -83,7 +83,7 @@ jobs:
|
|
|
83
83
|
- uses: CatChen/accept-to-ship-action@v0.3
|
|
84
84
|
with:
|
|
85
85
|
request-zero-accept-zero: true
|
|
86
|
-
custom-hashtag:
|
|
86
|
+
custom-hashtag: '#pass2ship'
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
## Options
|
package/lib/getCheckRuns.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Octokit } from
|
|
2
|
-
import type { Api } from
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
3
|
export declare function getCheckRuns(owner: string, repo: string, ref: string, octokit: Octokit & Api): Promise<{
|
|
4
4
|
id: number;
|
|
5
5
|
head_sha: string;
|
package/lib/getMergeMethod.js
CHANGED
|
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getMergeMethod = void 0;
|
|
4
4
|
const core_1 = require("@actions/core");
|
|
5
5
|
function getMergeMethod() {
|
|
6
|
-
const mergeMethod = (0, core_1.getInput)(
|
|
7
|
-
if (mergeMethod !==
|
|
8
|
-
mergeMethod !==
|
|
9
|
-
mergeMethod !==
|
|
6
|
+
const mergeMethod = (0, core_1.getInput)('merge-method');
|
|
7
|
+
if (mergeMethod !== 'merge' &&
|
|
8
|
+
mergeMethod !== 'squash' &&
|
|
9
|
+
mergeMethod !== 'rebase') {
|
|
10
10
|
throw new Error(`Unsupported merge-method: ${mergeMethod}`);
|
|
11
11
|
}
|
|
12
12
|
return mergeMethod;
|
package/lib/getOcktokit.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getOctokit = void 0;
|
|
4
|
-
const utils_1 = require("@actions/github/lib/utils");
|
|
5
4
|
const core_1 = require("@actions/core");
|
|
6
|
-
const
|
|
5
|
+
const utils_1 = require("@actions/github/lib/utils");
|
|
7
6
|
const plugin_retry_1 = require("@octokit/plugin-retry");
|
|
7
|
+
const plugin_throttling_1 = require("@octokit/plugin-throttling");
|
|
8
8
|
function getOctokit() {
|
|
9
|
-
const githubToken = (0, core_1.getInput)(
|
|
9
|
+
const githubToken = (0, core_1.getInput)('github-token');
|
|
10
10
|
const Octokit = utils_1.GitHub.plugin(plugin_throttling_1.throttling, plugin_retry_1.retry);
|
|
11
11
|
const octokit = new Octokit((0, utils_1.getOctokitOptions)(githubToken, {
|
|
12
12
|
throttle: {
|
|
@@ -32,7 +32,7 @@ function getOctokit() {
|
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
34
|
retry: {
|
|
35
|
-
doNotRetry: [
|
|
35
|
+
doNotRetry: ['429'],
|
|
36
36
|
},
|
|
37
37
|
}));
|
|
38
38
|
return octokit;
|
package/lib/getPullRequest.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Octokit } from
|
|
2
|
-
import type { Api } from
|
|
3
|
-
import type { PullRequest } from
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
|
+
import type { PullRequest } from '@octokit/webhooks-definitions/schema';
|
|
4
4
|
export declare function getPullRequest(owner: string, repo: string, pullRequestNumber: number, octokit: Octokit & Api): Promise<PullRequest>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Octokit } from
|
|
2
|
-
import type { Api } from
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
3
|
export declare function getPullRequestComments(owner: string, repo: string, pullRequestNumber: number, octokit: Octokit & Api): Promise<{
|
|
4
4
|
url: string;
|
|
5
5
|
pull_request_review_id: number | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Octokit } from
|
|
2
|
-
import type { Api } from
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
3
|
export declare function getPullRequestReviewRequests(owner: string, repo: string, pullRequestNumber: number, octokit: Octokit & Api): Promise<{
|
|
4
4
|
users: {
|
|
5
5
|
name?: string | null | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Octokit } from
|
|
2
|
-
import type { Api } from
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
3
|
export declare function getPullRequestReviews(owner: string, repo: string, pullRequestNumber: number, octokit: Octokit & Api): Promise<{
|
|
4
4
|
id: number;
|
|
5
5
|
node_id: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Octokit } from
|
|
2
|
-
import type { Api } from
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
3
|
export declare function getWorkflowRunJobs(owner: string, repo: string, octokit: Octokit & Api): Promise<{
|
|
4
4
|
id: number;
|
|
5
5
|
run_id: number;
|
package/lib/index.js
CHANGED
|
@@ -10,29 +10,29 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const node_perf_hooks_1 = require("node:perf_hooks");
|
|
13
|
-
const github_1 = require("@actions/github");
|
|
14
13
|
const core_1 = require("@actions/core");
|
|
15
|
-
const
|
|
14
|
+
const github_1 = require("@actions/github");
|
|
15
|
+
const getCheckRuns_1 = require("./getCheckRuns");
|
|
16
16
|
const getMergeMethod_1 = require("./getMergeMethod");
|
|
17
|
+
const getOcktokit_1 = require("./getOcktokit");
|
|
17
18
|
const getPullRequest_1 = require("./getPullRequest");
|
|
18
19
|
const getPullRequestComments_1 = require("./getPullRequestComments");
|
|
19
20
|
const getPullRequestReviewRequests_1 = require("./getPullRequestReviewRequests");
|
|
20
21
|
const getPullRequestReviews_1 = require("./getPullRequestReviews");
|
|
21
22
|
const getWorkflowRunJobs_1 = require("./getWorkflowRunJobs");
|
|
22
|
-
const getCheckRuns_1 = require("./getCheckRuns");
|
|
23
23
|
const mergePullRequest_1 = require("./mergePullRequest");
|
|
24
24
|
const sleep_1 = require("./sleep");
|
|
25
|
-
const APPROVED =
|
|
26
|
-
const CHANGES_REQUESTED =
|
|
27
|
-
const COMPLETED =
|
|
28
|
-
const SUCCESS =
|
|
29
|
-
const NEUTRAL =
|
|
30
|
-
const SKIPPED =
|
|
25
|
+
const APPROVED = 'APPROVED';
|
|
26
|
+
const CHANGES_REQUESTED = 'CHANGES_REQUESTED';
|
|
27
|
+
const COMPLETED = 'completed';
|
|
28
|
+
const SUCCESS = 'success';
|
|
29
|
+
const NEUTRAL = 'neutral';
|
|
30
|
+
const SKIPPED = 'skipped';
|
|
31
31
|
const LOCALE = Intl.NumberFormat().resolvedOptions().locale;
|
|
32
32
|
const FORMATTER = new Intl.NumberFormat(LOCALE, {
|
|
33
|
-
style:
|
|
34
|
-
unit:
|
|
35
|
-
unitDisplay:
|
|
33
|
+
style: 'unit',
|
|
34
|
+
unit: 'second',
|
|
35
|
+
unitDisplay: 'long',
|
|
36
36
|
});
|
|
37
37
|
function handlePullRequest(pullRequestNumber) {
|
|
38
38
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
@@ -46,16 +46,16 @@ function handlePullRequest(pullRequestNumber) {
|
|
|
46
46
|
(0, core_1.error)(`This Pull Request has been merged already.`);
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
const customHashTag = (0, core_1.getInput)(
|
|
50
|
-
const hashTagLabel = customHashTag.replace(/^#*/,
|
|
49
|
+
const customHashTag = (0, core_1.getInput)('custom-hashtag') || '#accept2ship';
|
|
50
|
+
const hashTagLabel = customHashTag.replace(/^#*/, '');
|
|
51
51
|
const hashTag = `#${hashTagLabel}`;
|
|
52
52
|
const pullRequest = yield (0, getPullRequest_1.getPullRequest)(owner, repo, pullRequestNumber, octokit);
|
|
53
53
|
const accept2shipTitle = (_b = (_a = pullRequest.title) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === null || _b === void 0 ? void 0 : _b.includes(hashTag);
|
|
54
|
-
(0, core_1.info)(`${hashTag} ${accept2shipTitle ?
|
|
54
|
+
(0, core_1.info)(`${hashTag} ${accept2shipTitle ? '' : 'not '}found in title`);
|
|
55
55
|
const accept2shipBody = (_d = (_c = pullRequest.body) === null || _c === void 0 ? void 0 : _c.toLowerCase()) === null || _d === void 0 ? void 0 : _d.includes(hashTag);
|
|
56
|
-
(0, core_1.info)(`${hashTag} ${accept2shipBody ?
|
|
56
|
+
(0, core_1.info)(`${hashTag} ${accept2shipBody ? '' : 'not '}found in body`);
|
|
57
57
|
const accept2shipLabel = pullRequest.labels.some((label) => label.name.toLowerCase() === hashTagLabel);
|
|
58
|
-
(0, core_1.info)(`${hashTag} ${accept2shipLabel ?
|
|
58
|
+
(0, core_1.info)(`${hashTag} ${accept2shipLabel ? '' : 'not '}found in labels`);
|
|
59
59
|
const pullRequestUserId = pullRequest.user.id;
|
|
60
60
|
const comments = yield (0, getPullRequestComments_1.getPullRequestComments)(owner, repo, pullRequestNumber, octokit);
|
|
61
61
|
const accept2shipComment = comments.some((comment) => {
|
|
@@ -63,7 +63,7 @@ function handlePullRequest(pullRequestNumber) {
|
|
|
63
63
|
return ((_a = comment.user) === null || _a === void 0 ? void 0 : _a.id) === pullRequestUserId &&
|
|
64
64
|
comment.body.toLowerCase().includes(hashTag);
|
|
65
65
|
});
|
|
66
|
-
(0, core_1.info)(`${hashTag} ${accept2shipComment ?
|
|
66
|
+
(0, core_1.info)(`${hashTag} ${accept2shipComment ? '' : 'not '}found in comments`);
|
|
67
67
|
const accept2shipTag = accept2shipTitle ||
|
|
68
68
|
accept2shipBody ||
|
|
69
69
|
accept2shipLabel ||
|
|
@@ -86,20 +86,20 @@ function handlePullRequest(pullRequestNumber) {
|
|
|
86
86
|
(0, core_1.info)(`Review not requested.`);
|
|
87
87
|
}
|
|
88
88
|
const reviews = yield (0, getPullRequestReviews_1.getPullRequestReviews)(owner, repo, pullRequestNumber, octokit);
|
|
89
|
-
const acceptZeroApprovals = (0, core_1.getBooleanInput)(
|
|
89
|
+
const acceptZeroApprovals = (0, core_1.getBooleanInput)('request-zero-accept-zero');
|
|
90
90
|
let approved = false;
|
|
91
|
-
const reviewsSortedByDescendingTime = reviews.sort((x, y) => { var _a, _b; return Date.parse((_a = y.submitted_at) !== null && _a !== void 0 ? _a :
|
|
91
|
+
const reviewsSortedByDescendingTime = reviews.sort((x, y) => { var _a, _b; return Date.parse((_a = y.submitted_at) !== null && _a !== void 0 ? _a : '') - Date.parse((_b = x.submitted_at) !== null && _b !== void 0 ? _b : ''); });
|
|
92
92
|
if (reviewRequests.users.length === 0 && reviewRequests.teams.length === 0) {
|
|
93
93
|
if (acceptZeroApprovals) {
|
|
94
94
|
approved = reviews.every((review) => review.state !== CHANGES_REQUESTED);
|
|
95
|
-
(0, core_1.info)(`Review states: ${reviews.length ||
|
|
95
|
+
(0, core_1.info)(`Review states: ${reviews.length || 'none'}`);
|
|
96
96
|
for (const review of reviews) {
|
|
97
|
-
(0, core_1.info)(` ${(_f = (_e = review.user) === null || _e === void 0 ? void 0 : _e.login) !== null && _f !== void 0 ? _f :
|
|
97
|
+
(0, core_1.info)(` ${(_f = (_e = review.user) === null || _e === void 0 ? void 0 : _e.login) !== null && _f !== void 0 ? _f : 'Unknown'}: ${review.state}`);
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
else {
|
|
101
101
|
const lastReview = reviewsSortedByDescendingTime[0];
|
|
102
|
-
(0, core_1.info)(`Last review state: ${(_g = lastReview === null || lastReview === void 0 ? void 0 : lastReview.state) !== null && _g !== void 0 ? _g :
|
|
102
|
+
(0, core_1.info)(`Last review state: ${(_g = lastReview === null || lastReview === void 0 ? void 0 : lastReview.state) !== null && _g !== void 0 ? _g : 'none'}`);
|
|
103
103
|
approved = (lastReview === null || lastReview === void 0 ? void 0 : lastReview.state) === APPROVED;
|
|
104
104
|
}
|
|
105
105
|
}
|
|
@@ -115,9 +115,9 @@ function handlePullRequest(pullRequestNumber) {
|
|
|
115
115
|
}, {});
|
|
116
116
|
(0, core_1.info)(`Last review by user:`);
|
|
117
117
|
for (const user of reviewRequests.users) {
|
|
118
|
-
(0, core_1.info)(` ${user.login}: ${(_j = (_h = lastReviewPerUserId[user.id]) === null || _h === void 0 ? void 0 : _h.state) !== null && _j !== void 0 ? _j :
|
|
118
|
+
(0, core_1.info)(` ${user.login}: ${(_j = (_h = lastReviewPerUserId[user.id]) === null || _h === void 0 ? void 0 : _h.state) !== null && _j !== void 0 ? _j : 'none'} ${user.id in lastReviewPerUserId
|
|
119
119
|
? `(${(_k = lastReviewPerUserId[user.id]) === null || _k === void 0 ? void 0 : _k.html_url})`
|
|
120
|
-
:
|
|
120
|
+
: ''}`);
|
|
121
121
|
}
|
|
122
122
|
approved = reviewUserIds
|
|
123
123
|
.map((userId) => lastReviewPerUserId[userId])
|
|
@@ -141,13 +141,13 @@ function handlePullRequest(pullRequestNumber) {
|
|
|
141
141
|
(0, core_1.info)(` Step status/conclusion: ${step.status === COMPLETED ? step.conclusion : step.status}\n`);
|
|
142
142
|
}
|
|
143
143
|
(0, core_1.endGroup)();
|
|
144
|
-
(0, core_1.info)(
|
|
144
|
+
(0, core_1.info)('\n\n');
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
const jobIds = jobs.map((job) => job.id);
|
|
148
|
-
const timeout = parseInt((0, core_1.getInput)(
|
|
149
|
-
const interval = parseInt((0, core_1.getInput)(
|
|
150
|
-
const failIfTimeout = (0, core_1.getBooleanInput)(
|
|
148
|
+
const timeout = parseInt((0, core_1.getInput)('timeout'), 10);
|
|
149
|
+
const interval = parseInt((0, core_1.getInput)('checks-watch-interval'), 10);
|
|
150
|
+
const failIfTimeout = (0, core_1.getBooleanInput)('fail-if-timeout');
|
|
151
151
|
let worthChecking = true;
|
|
152
152
|
let externalIds = undefined;
|
|
153
153
|
while (worthChecking) {
|
|
@@ -219,20 +219,20 @@ function run() {
|
|
|
219
219
|
return __awaiter(this, void 0, void 0, function* () {
|
|
220
220
|
(0, core_1.info)(`Event name: ${github_1.context.eventName}`);
|
|
221
221
|
switch (github_1.context.eventName) {
|
|
222
|
-
case
|
|
222
|
+
case 'pull_request':
|
|
223
223
|
yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
224
224
|
const pullRequest = github_1.context.payload.pull_request;
|
|
225
225
|
yield handlePullRequest(pullRequest.number);
|
|
226
226
|
}))();
|
|
227
227
|
break;
|
|
228
|
-
case
|
|
228
|
+
case 'pull_request_review':
|
|
229
229
|
yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
230
230
|
const pullRequest = github_1.context.payload
|
|
231
231
|
.pull_request;
|
|
232
232
|
yield handlePullRequest(pullRequest.number);
|
|
233
233
|
}))();
|
|
234
234
|
break;
|
|
235
|
-
case
|
|
235
|
+
case 'check_run':
|
|
236
236
|
yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
237
237
|
const checkRun = github_1.context.payload.check_run;
|
|
238
238
|
if (checkRun.status !== COMPLETED ||
|
|
@@ -245,7 +245,7 @@ function run() {
|
|
|
245
245
|
}
|
|
246
246
|
}))();
|
|
247
247
|
return;
|
|
248
|
-
case
|
|
248
|
+
case 'check_suite':
|
|
249
249
|
yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
250
250
|
const checkSuites = github_1.context.payload.check_suite;
|
|
251
251
|
if (checkSuites.status !== COMPLETED ||
|
|
@@ -258,7 +258,7 @@ function run() {
|
|
|
258
258
|
}
|
|
259
259
|
}))();
|
|
260
260
|
return;
|
|
261
|
-
case
|
|
261
|
+
case 'workflow_run':
|
|
262
262
|
yield (() => __awaiter(this, void 0, void 0, function* () {
|
|
263
263
|
const workflowRun = github_1.context.payload.workflow_run;
|
|
264
264
|
if (workflowRun.status !== COMPLETED ||
|
|
@@ -271,7 +271,7 @@ function run() {
|
|
|
271
271
|
}
|
|
272
272
|
}))();
|
|
273
273
|
break;
|
|
274
|
-
case
|
|
274
|
+
case 'workflow_dispatch':
|
|
275
275
|
default:
|
|
276
276
|
(0, core_1.error)(`Unsupported GitHub Action event: ${github_1.context.eventName}`);
|
|
277
277
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
import
|
|
1
|
+
import type { Octokit } from '@octokit/core';
|
|
2
|
+
import type { Api } from '@octokit/plugin-rest-endpoint-methods/dist-types/types';
|
|
3
|
+
import { getMergeMethod } from './getMergeMethod';
|
|
4
4
|
export declare function checkIfPullRequestMerged(owner: string, repo: string, pullRequestNumber: number, octokit: Octokit & Api): Promise<boolean>;
|
|
5
5
|
export declare function mergePullRequest(owner: string, repo: string, pullRequestNumber: number, mergeMethod: ReturnType<typeof getMergeMethod>, octokit: Octokit & Api): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "accept-to-ship-action",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.16",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.js",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://github.com/CatChen/accept-to-ship-action#readme",
|
|
25
25
|
"devDependencies": {
|
|
26
|
+
"@serverless-guru/prettier-plugin-import-order": "^0.2.0",
|
|
26
27
|
"@types/node": "^18.11.3",
|
|
27
28
|
"@typescript-eslint/eslint-plugin": "^5.40.1",
|
|
28
29
|
"@typescript-eslint/parser": "^5.40.1",
|