@chainpatrol/cli 0.11.0 → 0.12.0
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 +43 -0
- package/dist/{breakdown-MM5GSZKV.js → breakdown-KCTKQNDY.js} +1 -1
- package/dist/{check-GDKUHVQI.js → check-P5JJJNEX.js} +1 -1
- package/dist/{chunk-37KYJWB3.js → chunk-DJVB73FL.js} +1 -1
- package/dist/{chunk-YXRFUYA6.js → chunk-NQT77IB7.js} +50 -8
- package/dist/{chunk-SX3L6NKR.js → chunk-OSRFCVBT.js} +129 -2
- package/dist/{chunk-EPKNZRX6.js → chunk-W42ITB5J.js} +1 -1
- package/dist/cli.js +395 -76
- package/dist/{completions-62OW3B3Y.js → completions-6C6KG5DH.js} +1 -1
- package/dist/{configs-update-7X7657PB.js → configs-update-3ZVXGADV.js} +1 -1
- package/dist/{create-FL4QQTPN.js → create-DFH2G7RH.js} +1 -1
- package/dist/{drift-JKBHWWFU.js → drift-T74V2C3J.js} +1 -1
- package/dist/{found-3WI4XQG4.js → found-EVXJZGYX.js} +1 -1
- package/dist/{healthcheck-EVQVPGWW.js → healthcheck-HZYEIIOR.js} +1 -1
- package/dist/{list-BLNIE4GL.js → list-23QQYAV5.js} +1 -1
- package/dist/list-EIVPGMWJ.js +82 -0
- package/dist/list-I7SBGA52.js +50 -0
- package/dist/{list-5DN6X3DP.js → list-IYJBKE2F.js} +1 -1
- package/dist/list-PBAXQSL5.js +85 -0
- package/dist/list-QUFY4IP7.js +146 -0
- package/dist/{list-JPG2ZSR4.js → list-WJQT2XLE.js} +7 -1
- package/dist/{list-ULHPOUJV.js → list-WX5G3IOF.js} +2 -2
- package/dist/list-YCT6DYDI.js +89 -0
- package/dist/{list-XDGU6SJQ.js → list-YRJPN4PI.js} +1 -1
- package/dist/{list-E5XNR2YG.js → list-ZFPML3ZR.js} +47 -3
- package/dist/{list-json-R2MIXADX.js → list-json-T2Z7NV7G.js} +1 -1
- package/dist/{organization-MJRKWC4Z.js → organization-IIIOSTHF.js} +1 -1
- package/dist/{run-EUVRC72M.js → run-BHEXWBAS.js} +2 -2
- package/dist/{run-2YZZGZYN.js → run-CJGN6TX4.js} +1 -1
- package/dist/{run-5E5EC3MP.js → run-MSO6IXEV.js} +1 -1
- package/dist/search-WPSKQGUS.js +71 -0
- package/dist/{setup-skill-HAENFIFQ.js → setup-skill-FA4STSGA.js} +2 -2
- package/dist/{snapshot-3FUJICJJ.js → snapshot-ZWAHEG64.js} +1 -1
- package/dist/{summary-RVYQUKWV.js → summary-Y2LG6UJM.js} +1 -1
- package/dist/{validate-UOVKEAJM.js → validate-SM5DD7I2.js} +1 -1
- package/dist/whoami-DH5HVLFN.js +69 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# @chainpatrol/cli
|
|
2
2
|
|
|
3
|
+
## 0.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 28cdda8: Two-part change to the external API surface and the CLI:
|
|
8
|
+
|
|
9
|
+
**Part 1: eight new read-only commands** so operators and agents can pull
|
|
10
|
+
asset, threat, detection, report-search, and identity data without leaving the
|
|
11
|
+
terminal:
|
|
12
|
+
|
|
13
|
+
- `chainpatrol asset list` — `POST /asset/list`
|
|
14
|
+
- `chainpatrol threats list` — `POST /threats/list`
|
|
15
|
+
- `chainpatrol detections list` — `POST /detection/list`
|
|
16
|
+
- `chainpatrol reports search` — `POST /reports/search`
|
|
17
|
+
- `chainpatrol orgs assets list` — `GET /organization/assets`
|
|
18
|
+
- `chainpatrol orgs asset-groups list` — `GET /organization/asset-groups`
|
|
19
|
+
- `chainpatrol whoami` — `GET /validate` (with an API key) or `POST /user/me`
|
|
20
|
+
(with a session token)
|
|
21
|
+
|
|
22
|
+
All support the standard `--json` / `--output {human,json,markdown,csv}` shapes
|
|
23
|
+
and integrate with the existing API-key and session auth modes.
|
|
24
|
+
|
|
25
|
+
**Part 2: filter parity** between the external API + CLI and the app's
|
|
26
|
+
detections / takedowns / reports views.
|
|
27
|
+
|
|
28
|
+
- **Detections** — new filter properties on `POST /detection/list`: liveness,
|
|
29
|
+
watchlist, reported, deleted (opt-in), countryCode. CLI flags:
|
|
30
|
+
`--liveness`, `--watchlist`, `--reported`, `--country-code`,
|
|
31
|
+
`--include-deleted`, plus brand filtering via `--brand`.
|
|
32
|
+
- **Takedowns** — new fields on `POST /takedowns/list`: brandIds, assigneeIds,
|
|
33
|
+
startedAtStartDate / startedAtEndDate (computed from the earliest
|
|
34
|
+
IN_PROGRESS TakedownEvent), hideAutomatedTakedowns,
|
|
35
|
+
hideAutomatedLivenessChecks; plus new sort keys `assigneeId`, `brandId`.
|
|
36
|
+
CLI flags: `--brand`, `--assignee`, `--started-from`, `--started-to`,
|
|
37
|
+
`--hide-automated-takedowns`, `--hide-automated-liveness-checks`.
|
|
38
|
+
- **Reports** — the external `/public/getOrganizationReports` endpoint
|
|
39
|
+
already accepted every app filter via its shared schema; the CLI now
|
|
40
|
+
surfaces them. New flags on `chainpatrol reports list`: `--reporter-query`,
|
|
41
|
+
`--exclude-automation`, `--only-rejected`, `--review-status`,
|
|
42
|
+
`--asset-type`, `--brand`, `--country-code`, `--reviewed-by-user-id`,
|
|
43
|
+
`--updated-from`, `--updated-to`, and the existing `--from`/`--to` are now
|
|
44
|
+
wired through.
|
|
45
|
+
|
|
3
46
|
## 0.11.0
|
|
4
47
|
|
|
5
48
|
### Minor Changes
|
|
@@ -16,13 +16,16 @@ _chainpatrol() {
|
|
|
16
16
|
commands=(
|
|
17
17
|
'login:Authenticate with ChainPatrol'
|
|
18
18
|
'logout:Clear stored credentials'
|
|
19
|
-
'
|
|
19
|
+
'whoami:Show the current authenticated identity'
|
|
20
|
+
'asset:Check or list assets against ChainPatrol'
|
|
20
21
|
'configs:Manage detection configs'
|
|
21
|
-
'detections:Validate
|
|
22
|
+
'detections:Validate, run, list, update detection configs and results'
|
|
22
23
|
'metrics:Query organization metrics'
|
|
23
|
-
'reports:Create
|
|
24
|
+
'reports:Create, list, search reports from terminal'
|
|
24
25
|
'queues:Snapshot operations queues'
|
|
25
26
|
'takedowns:List individual takedown records'
|
|
27
|
+
'threats:List confirmed threats blocked by ChainPatrol'
|
|
28
|
+
'orgs:List organizations, org assets, and asset groups'
|
|
26
29
|
'presets:Run saved workflows'
|
|
27
30
|
'setup:Install Claude Code skill and shell completions'
|
|
28
31
|
'uninstall:Remove Claude Code skill and shell completions'
|
|
@@ -60,7 +63,10 @@ _chainpatrol() {
|
|
|
60
63
|
case "\${words[2]}" in
|
|
61
64
|
asset)
|
|
62
65
|
local -a asset_subcommands
|
|
63
|
-
asset_subcommands=(
|
|
66
|
+
asset_subcommands=(
|
|
67
|
+
'check:Check asset status against ChainPatrol'
|
|
68
|
+
'list:List assets in the global ChainPatrol blocklist'
|
|
69
|
+
)
|
|
64
70
|
_describe 'subcommand' asset_subcommands
|
|
65
71
|
;;
|
|
66
72
|
configs)
|
|
@@ -75,6 +81,7 @@ _chainpatrol() {
|
|
|
75
81
|
'validate:Validate detection configs'
|
|
76
82
|
'drift:Show detection drift signals'
|
|
77
83
|
'run:Run detection configs'
|
|
84
|
+
'list:List threat detection results'
|
|
78
85
|
'configs:Manage detection configs'
|
|
79
86
|
)
|
|
80
87
|
_describe 'subcommand' detections_subcommands
|
|
@@ -94,6 +101,7 @@ _chainpatrol() {
|
|
|
94
101
|
reports_subcommands=(
|
|
95
102
|
'create:Create a new report'
|
|
96
103
|
'list:List organization reports'
|
|
104
|
+
'search:Search reports by asset contents'
|
|
97
105
|
)
|
|
98
106
|
_describe 'subcommand' reports_subcommands
|
|
99
107
|
;;
|
|
@@ -107,6 +115,20 @@ _chainpatrol() {
|
|
|
107
115
|
takedowns_subcommands=('list:List individual takedown records')
|
|
108
116
|
_describe 'subcommand' takedowns_subcommands
|
|
109
117
|
;;
|
|
118
|
+
threats)
|
|
119
|
+
local -a threats_subcommands
|
|
120
|
+
threats_subcommands=('list:List confirmed threats')
|
|
121
|
+
_describe 'subcommand' threats_subcommands
|
|
122
|
+
;;
|
|
123
|
+
orgs)
|
|
124
|
+
local -a orgs_subcommands
|
|
125
|
+
orgs_subcommands=(
|
|
126
|
+
'list:List organizations'
|
|
127
|
+
'assets:Manage organization assets'
|
|
128
|
+
'asset-groups:Manage organization asset groups'
|
|
129
|
+
)
|
|
130
|
+
_describe 'subcommand' orgs_subcommands
|
|
131
|
+
;;
|
|
110
132
|
presets)
|
|
111
133
|
local -a presets_subcommands
|
|
112
134
|
presets_subcommands=(
|
|
@@ -131,7 +153,7 @@ var BASH_COMPLETION = `_chainpatrol() {
|
|
|
131
153
|
COMPREPLY=()
|
|
132
154
|
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
133
155
|
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
134
|
-
commands="login logout asset configs detections metrics reports queues takedowns presets setup uninstall completions help"
|
|
156
|
+
commands="login logout whoami asset configs detections metrics reports queues takedowns threats orgs presets setup uninstall completions help"
|
|
135
157
|
|
|
136
158
|
case "\${prev}" in
|
|
137
159
|
chainpatrol)
|
|
@@ -139,7 +161,7 @@ var BASH_COMPLETION = `_chainpatrol() {
|
|
|
139
161
|
return 0
|
|
140
162
|
;;
|
|
141
163
|
asset)
|
|
142
|
-
COMPREPLY=( $(compgen -W "check" -- "\${cur}") )
|
|
164
|
+
COMPREPLY=( $(compgen -W "check list" -- "\${cur}") )
|
|
143
165
|
return 0
|
|
144
166
|
;;
|
|
145
167
|
configs)
|
|
@@ -147,7 +169,7 @@ var BASH_COMPLETION = `_chainpatrol() {
|
|
|
147
169
|
return 0
|
|
148
170
|
;;
|
|
149
171
|
detections)
|
|
150
|
-
COMPREPLY=( $(compgen -W "healthcheck validate drift run configs" -- "\${cur}") )
|
|
172
|
+
COMPREPLY=( $(compgen -W "healthcheck validate drift run list configs" -- "\${cur}") )
|
|
151
173
|
return 0
|
|
152
174
|
;;
|
|
153
175
|
metrics)
|
|
@@ -155,7 +177,7 @@ var BASH_COMPLETION = `_chainpatrol() {
|
|
|
155
177
|
return 0
|
|
156
178
|
;;
|
|
157
179
|
reports)
|
|
158
|
-
COMPREPLY=( $(compgen -W "create list" -- "\${cur}") )
|
|
180
|
+
COMPREPLY=( $(compgen -W "create list search" -- "\${cur}") )
|
|
159
181
|
return 0
|
|
160
182
|
;;
|
|
161
183
|
queues)
|
|
@@ -166,6 +188,26 @@ var BASH_COMPLETION = `_chainpatrol() {
|
|
|
166
188
|
COMPREPLY=( $(compgen -W "list" -- "\${cur}") )
|
|
167
189
|
return 0
|
|
168
190
|
;;
|
|
191
|
+
threats)
|
|
192
|
+
COMPREPLY=( $(compgen -W "list" -- "\${cur}") )
|
|
193
|
+
return 0
|
|
194
|
+
;;
|
|
195
|
+
orgs)
|
|
196
|
+
COMPREPLY=( $(compgen -W "list assets asset-groups" -- "\${cur}") )
|
|
197
|
+
return 0
|
|
198
|
+
;;
|
|
199
|
+
assets)
|
|
200
|
+
if [[ "\${COMP_WORDS[COMP_CWORD-2]}" == "orgs" ]]; then
|
|
201
|
+
COMPREPLY=( $(compgen -W "list" -- "\${cur}") )
|
|
202
|
+
return 0
|
|
203
|
+
fi
|
|
204
|
+
;;
|
|
205
|
+
asset-groups)
|
|
206
|
+
if [[ "\${COMP_WORDS[COMP_CWORD-2]}" == "orgs" ]]; then
|
|
207
|
+
COMPREPLY=( $(compgen -W "list" -- "\${cur}") )
|
|
208
|
+
return 0
|
|
209
|
+
fi
|
|
210
|
+
;;
|
|
169
211
|
presets)
|
|
170
212
|
COMPREPLY=( $(compgen -W "list run" -- "\${cur}") )
|
|
171
213
|
return 0
|
|
@@ -20,6 +20,12 @@ function parseIsoDate(value) {
|
|
|
20
20
|
function parseIsoDateString(value) {
|
|
21
21
|
return parseIsoDate(value)?.toISOString();
|
|
22
22
|
}
|
|
23
|
+
var REPORT_REVIEW_DECISIONS = ["APPROVE", "REJECT", "SKIP", "ESCALATE"];
|
|
24
|
+
var REPORT_STATUSES = ["TODO", "IN_PROGRESS", "CLOSED"];
|
|
25
|
+
var DETECTION_CONFIDENCE_LEVELS = ["none", "low", "medium", "high"];
|
|
26
|
+
var DETECTION_REPORTED_FILTERS = ["reported", "not_reported"];
|
|
27
|
+
var LIVENESS_FILTER_VALUES = ["ALIVE", "DEAD", "UNKNOWN"];
|
|
28
|
+
var WATCHLIST_FILTER_VALUES = ["ENABLED", "DISABLED"];
|
|
23
29
|
var TAKEDOWN_STATUSES = [
|
|
24
30
|
"TODO",
|
|
25
31
|
"IN_PROGRESS",
|
|
@@ -35,7 +41,9 @@ var TAKEDOWN_SORT_KEYS = [
|
|
|
35
41
|
"updatedAt",
|
|
36
42
|
"createdAt",
|
|
37
43
|
"takedownStatus",
|
|
38
|
-
"takedownUpdatedAt"
|
|
44
|
+
"takedownUpdatedAt",
|
|
45
|
+
"assigneeId",
|
|
46
|
+
"brandId"
|
|
39
47
|
];
|
|
40
48
|
var REQUEST_TIMEOUT_MS = 3e4;
|
|
41
49
|
function defaultGetCredential() {
|
|
@@ -210,7 +218,19 @@ function createApiClient(options) {
|
|
|
210
218
|
cursor: input.cursor,
|
|
211
219
|
status: input.status,
|
|
212
220
|
searchQuery: input.searchQuery,
|
|
213
|
-
|
|
221
|
+
reporterQuery: input.reporterQuery,
|
|
222
|
+
reportedByCustomer: input.reportedByCustomer,
|
|
223
|
+
excludeAutomation: input.excludeAutomation,
|
|
224
|
+
onlyRejected: input.onlyRejected,
|
|
225
|
+
reviewStatuses: input.reviewStatuses?.length ? input.reviewStatuses : void 0,
|
|
226
|
+
assetTypes: input.assetTypes?.length ? input.assetTypes : void 0,
|
|
227
|
+
brandIds: input.brandIds?.length ? input.brandIds : void 0,
|
|
228
|
+
countryCodes: input.countryCodes?.length ? input.countryCodes : void 0,
|
|
229
|
+
reviewedByUserId: input.reviewedByUserId,
|
|
230
|
+
startDate: parseIsoDateString(input.startDate),
|
|
231
|
+
endDate: parseIsoDateString(input.endDate),
|
|
232
|
+
updatedAtStartDate: parseIsoDateString(input.updatedAtStartDate),
|
|
233
|
+
updatedAtEndDate: parseIsoDateString(input.updatedAtEndDate)
|
|
214
234
|
});
|
|
215
235
|
},
|
|
216
236
|
listTakedowns(input) {
|
|
@@ -222,6 +242,12 @@ function createApiClient(options) {
|
|
|
222
242
|
assetType: input.assetType,
|
|
223
243
|
takedownStatus: input.takedownStatus,
|
|
224
244
|
livenessStatus: input.livenessStatus,
|
|
245
|
+
brandIds: input.brandIds?.length ? input.brandIds : void 0,
|
|
246
|
+
assigneeIds: input.assigneeIds?.length ? input.assigneeIds : void 0,
|
|
247
|
+
startedAtStartDate: parseIsoDateString(input.startedAtStartDate),
|
|
248
|
+
startedAtEndDate: parseIsoDateString(input.startedAtEndDate),
|
|
249
|
+
hideAutomatedTakedowns: input.hideAutomatedTakedowns,
|
|
250
|
+
hideAutomatedLivenessChecks: input.hideAutomatedLivenessChecks,
|
|
225
251
|
sorting: input.sorting,
|
|
226
252
|
per_page: input.perPage,
|
|
227
253
|
next_page: input.nextPage
|
|
@@ -243,11 +269,112 @@ function createApiClient(options) {
|
|
|
243
269
|
},
|
|
244
270
|
getUserOrgs(input) {
|
|
245
271
|
return request("/user/orgs", input);
|
|
272
|
+
},
|
|
273
|
+
listAssets(input) {
|
|
274
|
+
return request("/asset/list", {
|
|
275
|
+
type: input.type,
|
|
276
|
+
status: input.status,
|
|
277
|
+
startDate: parseIsoDateString(input.startDate),
|
|
278
|
+
endDate: parseIsoDateString(input.endDate),
|
|
279
|
+
per_page: input.perPage,
|
|
280
|
+
next_page: input.nextPage
|
|
281
|
+
});
|
|
282
|
+
},
|
|
283
|
+
listThreats(input) {
|
|
284
|
+
return request("/threats/list", {
|
|
285
|
+
query: input.query,
|
|
286
|
+
startDate: parseIsoDateString(input.startDate),
|
|
287
|
+
endDate: parseIsoDateString(input.endDate),
|
|
288
|
+
assetType: input.assetType,
|
|
289
|
+
sorting: input.sorting,
|
|
290
|
+
per_page: input.perPage,
|
|
291
|
+
next_page: input.nextPage
|
|
292
|
+
});
|
|
293
|
+
},
|
|
294
|
+
listDetections(input) {
|
|
295
|
+
const filters = [];
|
|
296
|
+
if (input.sources?.length) {
|
|
297
|
+
filters.push({ property: "source", operator: "in", value: input.sources });
|
|
298
|
+
}
|
|
299
|
+
if (input.confidence?.length) {
|
|
300
|
+
filters.push({ property: "confidence", operator: "in", value: input.confidence });
|
|
301
|
+
}
|
|
302
|
+
if (input.assetStatus?.length) {
|
|
303
|
+
filters.push({
|
|
304
|
+
property: "assetStatus",
|
|
305
|
+
operator: "in",
|
|
306
|
+
value: input.assetStatus
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
if (input.assetType?.length) {
|
|
310
|
+
filters.push({ property: "assetType", operator: "in", value: input.assetType });
|
|
311
|
+
}
|
|
312
|
+
if (input.brandIds?.length) {
|
|
313
|
+
filters.push({ property: "brand", operator: "in", value: input.brandIds });
|
|
314
|
+
}
|
|
315
|
+
if (input.liveness?.length) {
|
|
316
|
+
filters.push({ property: "liveness", operator: "in", value: input.liveness });
|
|
317
|
+
}
|
|
318
|
+
if (input.watchlist?.length) {
|
|
319
|
+
filters.push({ property: "watchlist", operator: "in", value: input.watchlist });
|
|
320
|
+
}
|
|
321
|
+
if (input.reported?.length) {
|
|
322
|
+
filters.push({ property: "reported", operator: "in", value: input.reported });
|
|
323
|
+
}
|
|
324
|
+
if (input.countryCodes?.length) {
|
|
325
|
+
filters.push({
|
|
326
|
+
property: "countryCode",
|
|
327
|
+
operator: "in",
|
|
328
|
+
value: input.countryCodes
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
if (input.onlyDeleted) {
|
|
332
|
+
filters.push({ property: "deleted", operator: "in", value: ["deleted"] });
|
|
333
|
+
}
|
|
334
|
+
return request("/detection/list", {
|
|
335
|
+
slug: input.slug,
|
|
336
|
+
cursor: input.cursor,
|
|
337
|
+
limit: input.limit,
|
|
338
|
+
query: input.query,
|
|
339
|
+
startDate: parseIsoDate(input.startDate),
|
|
340
|
+
endDate: parseIsoDate(input.endDate),
|
|
341
|
+
filters: filters.length > 0 ? filters : void 0
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
searchReports(input) {
|
|
345
|
+
return request("/reports/search", input);
|
|
346
|
+
},
|
|
347
|
+
listOrganizationAssets(input) {
|
|
348
|
+
return requestGet("/organization/assets", {
|
|
349
|
+
type: input.type,
|
|
350
|
+
groupId: input.groupId !== void 0 ? String(input.groupId) : void 0,
|
|
351
|
+
query: input.query,
|
|
352
|
+
per_page: input.perPage !== void 0 ? String(input.perPage) : void 0,
|
|
353
|
+
next_page: input.nextPage
|
|
354
|
+
});
|
|
355
|
+
},
|
|
356
|
+
listOrganizationAssetGroups() {
|
|
357
|
+
return requestGet(
|
|
358
|
+
"/organization/asset-groups",
|
|
359
|
+
{}
|
|
360
|
+
);
|
|
361
|
+
},
|
|
362
|
+
getCurrentUser() {
|
|
363
|
+
return request("/user/me", {});
|
|
364
|
+
},
|
|
365
|
+
validateApiKey() {
|
|
366
|
+
return requestGet("/validate", {});
|
|
246
367
|
}
|
|
247
368
|
};
|
|
248
369
|
}
|
|
249
370
|
|
|
250
371
|
export {
|
|
372
|
+
REPORT_REVIEW_DECISIONS,
|
|
373
|
+
REPORT_STATUSES,
|
|
374
|
+
DETECTION_CONFIDENCE_LEVELS,
|
|
375
|
+
DETECTION_REPORTED_FILTERS,
|
|
376
|
+
LIVENESS_FILTER_VALUES,
|
|
377
|
+
WATCHLIST_FILTER_VALUES,
|
|
251
378
|
TAKEDOWN_STATUSES,
|
|
252
379
|
LIVENESS_STATUSES,
|
|
253
380
|
TAKEDOWN_SORT_KEYS,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
installCompletions,
|
|
3
3
|
uninstallCompletions
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NQT77IB7.js";
|
|
5
5
|
|
|
6
6
|
// src/commands/setup-skill.ts
|
|
7
7
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, existsSync as existsSync2, readFileSync as readFileSync3, rmSync } from "fs";
|