@gscdump/cli 3.8.0 → 4.0.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/README.md +113 -30
- package/bin/gscdump.mjs +21 -1
- package/dist/analysis-local.mjs +172 -53
- package/dist/auth-state.mjs +21 -6
- package/dist/auth.mjs +27 -18
- package/dist/bing-data.mjs +6 -2
- package/dist/bing-hosted.mjs +1 -1
- package/dist/cli-args.mjs +8 -0
- package/dist/cli.d.mts +5 -1
- package/dist/cli.mjs +41 -10
- package/dist/cloud-google.mjs +8 -1
- package/dist/command-meta.mjs +4 -4
- package/dist/command-registry.mjs +86 -10
- package/dist/commands/analyze.mjs +84 -43
- package/dist/commands/auth.mjs +46 -37
- package/dist/commands/bing.mjs +3 -3
- package/dist/commands/compact.mjs +12 -8
- package/dist/commands/config.mjs +14 -14
- package/dist/commands/doctor.mjs +26 -26
- package/dist/commands/dump.mjs +203 -105
- package/dist/commands/entities.mjs +10 -113
- package/dist/commands/gc.mjs +4 -3
- package/dist/commands/indexing-urls.mjs +185 -0
- package/dist/commands/indexing.mjs +12 -8
- package/dist/commands/init.mjs +77 -18
- package/dist/commands/inspect.mjs +97 -110
- package/dist/commands/mcp.mjs +37 -57
- package/dist/commands/papercut.mjs +1 -1
- package/dist/commands/profile.mjs +9 -17
- package/dist/commands/query.mjs +219 -210
- package/dist/commands/report.mjs +68 -85
- package/dist/commands/rollups.mjs +9 -6
- package/dist/commands/sitemaps.mjs +51 -104
- package/dist/commands/sites.mjs +40 -24
- package/dist/commands/stats.mjs +14 -17
- package/dist/commands/store-purge.mjs +9 -5
- package/dist/commands/store.mjs +0 -12
- package/dist/commands/sync.mjs +774 -296
- package/dist/config.mjs +7 -4
- package/dist/context.mjs +51 -21
- package/dist/coverage.mjs +251 -0
- package/dist/dump-bing.mjs +71 -0
- package/dist/dump-writers.mjs +246 -0
- package/dist/error-handler.mjs +108 -38
- package/dist/filters.mjs +125 -0
- package/dist/hosted-site.mjs +91 -0
- package/dist/inspect-urls.mjs +76 -0
- package/dist/inspection-record.mjs +93 -0
- package/dist/local-entities.mjs +658 -0
- package/dist/mcp/errors.mjs +71 -18
- package/dist/mcp/handlers/diagnostics.mjs +15 -12
- package/dist/mcp/handlers/reports.mjs +33 -42
- package/dist/mcp/server/index.mjs +80 -38
- package/dist/mcp/types.mjs +7 -7
- package/dist/package.mjs +1 -1
- package/dist/quota-ledger.mjs +370 -0
- package/dist/render/analysis.mjs +8 -1
- package/dist/render/report.mjs +8 -1
- package/dist/request-pacer.mjs +29 -0
- package/dist/route.mjs +295 -0
- package/dist/sitemap.mjs +4 -0
- package/dist/sql-views.mjs +117 -0
- package/dist/store-sites.mjs +134 -0
- package/dist/sync-plan.mjs +129 -0
- package/dist/sync-run.mjs +96 -0
- package/dist/table-sources.mjs +57 -0
- package/dist/token-info.mjs +54 -0
- package/dist/utils.mjs +28 -19
- package/dist/window.mjs +159 -0
- package/package.json +17 -14
- package/skills/gscdump/SKILL.md +167 -37
- package/dist/commands/export.mjs +0 -76
- package/dist/native-duckdb.mjs +0 -46
package/dist/commands/sites.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { sitesCommandMeta } from "../command-meta.mjs";
|
|
2
|
+
import { formatHostedSync, getCloudSites } from "../auth-state.mjs";
|
|
2
3
|
import { OUTPUT_ARGS, applyOutputMode, logger } from "../utils.mjs";
|
|
3
|
-
import { createCommandContext } from "../context.mjs";
|
|
4
|
-
import { gscErrorHandler } from "../error-handler.mjs";
|
|
4
|
+
import { createCommandContext, formatSiteResolution } from "../context.mjs";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
import { defineCommand } from "citty";
|
|
7
7
|
import { confirm, isCancel } from "@clack/prompts";
|
|
8
|
+
import { resolveSiteInput } from "gscdump";
|
|
8
9
|
import { addSite, deleteSite, fetchSitesWithSitemaps, getVerificationToken, getVerifiedSite, listVerifiedSites, siteUrlToVerificationSite, unverifySite, verificationMethodsFor, verifySite } from "gscdump/sites";
|
|
9
10
|
const ALL_METHODS = [
|
|
10
11
|
"META",
|
|
@@ -101,7 +102,7 @@ const addCommand = defineCommand({
|
|
|
101
102
|
async run({ args }) {
|
|
102
103
|
applyOutputMode(args);
|
|
103
104
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
104
|
-
await addSite(ctx.client, args.url)
|
|
105
|
+
await addSite(ctx.client, args.url);
|
|
105
106
|
if (!args.verify) {
|
|
106
107
|
if (args.json) {
|
|
107
108
|
console.log(JSON.stringify({
|
|
@@ -118,7 +119,7 @@ const addCommand = defineCommand({
|
|
|
118
119
|
return;
|
|
119
120
|
}
|
|
120
121
|
const method = validateMethod(args.url, args.method ?? pickDefaultMethod(args.url));
|
|
121
|
-
const tokenResult = await getVerificationToken(ctx.client, args.url, method)
|
|
122
|
+
const tokenResult = await getVerificationToken(ctx.client, args.url, method);
|
|
122
123
|
if (args.json) {
|
|
123
124
|
console.log(JSON.stringify({
|
|
124
125
|
siteUrl: args.url,
|
|
@@ -141,7 +142,7 @@ const addCommand = defineCommand({
|
|
|
141
142
|
logger.info("Skipped verification. Run `gscdump sites verify` once the token is live.");
|
|
142
143
|
return;
|
|
143
144
|
}
|
|
144
|
-
const resource = await verifySite(ctx.client, args.url, method)
|
|
145
|
+
const resource = await verifySite(ctx.client, args.url, method);
|
|
145
146
|
logger.success(`Verified: ${args.url}`);
|
|
146
147
|
if (resource.owners?.length) {
|
|
147
148
|
console.log();
|
|
@@ -182,7 +183,7 @@ const deleteCommand = defineCommand({
|
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
185
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
185
|
-
await deleteSite(ctx.client, args.url)
|
|
186
|
+
await deleteSite(ctx.client, args.url);
|
|
186
187
|
if (args.json) {
|
|
187
188
|
console.log(JSON.stringify({
|
|
188
189
|
siteUrl: args.url,
|
|
@@ -202,7 +203,7 @@ const verifyTokenCommand = defineCommand({
|
|
|
202
203
|
url: {
|
|
203
204
|
type: "positional",
|
|
204
205
|
required: true,
|
|
205
|
-
description: "
|
|
206
|
+
description: "Site, for example example.com"
|
|
206
207
|
},
|
|
207
208
|
method: {
|
|
208
209
|
type: "string",
|
|
@@ -215,7 +216,7 @@ const verifyTokenCommand = defineCommand({
|
|
|
215
216
|
applyOutputMode(args);
|
|
216
217
|
const method = validateMethod(args.url, args.method ?? pickDefaultMethod(args.url));
|
|
217
218
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
218
|
-
const result = await getVerificationToken(ctx.client, args.url, method)
|
|
219
|
+
const result = await getVerificationToken(ctx.client, args.url, method);
|
|
219
220
|
if (args.json) {
|
|
220
221
|
console.log(JSON.stringify({
|
|
221
222
|
siteUrl: args.url,
|
|
@@ -237,7 +238,7 @@ const verifyCommand = defineCommand({
|
|
|
237
238
|
url: {
|
|
238
239
|
type: "positional",
|
|
239
240
|
required: true,
|
|
240
|
-
description: "
|
|
241
|
+
description: "Site, for example example.com"
|
|
241
242
|
},
|
|
242
243
|
method: {
|
|
243
244
|
type: "string",
|
|
@@ -250,7 +251,7 @@ const verifyCommand = defineCommand({
|
|
|
250
251
|
applyOutputMode(args);
|
|
251
252
|
const method = validateMethod(args.url, args.method ?? pickDefaultMethod(args.url));
|
|
252
253
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
253
|
-
const resource = await verifySite(ctx.client, args.url, method)
|
|
254
|
+
const resource = await verifySite(ctx.client, args.url, method);
|
|
254
255
|
if (args.json) {
|
|
255
256
|
console.log(JSON.stringify({
|
|
256
257
|
siteUrl: args.url,
|
|
@@ -283,7 +284,7 @@ const verifyGetCommand = defineCommand({
|
|
|
283
284
|
async run({ args }) {
|
|
284
285
|
applyOutputMode(args);
|
|
285
286
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
286
|
-
const resource = await getVerifiedSite(ctx.client, args.id)
|
|
287
|
+
const resource = await getVerifiedSite(ctx.client, args.id);
|
|
287
288
|
if (args.json) {
|
|
288
289
|
console.log(JSON.stringify(resource, null, 2));
|
|
289
290
|
return;
|
|
@@ -332,7 +333,7 @@ const unverifyCommand = defineCommand({
|
|
|
332
333
|
}
|
|
333
334
|
}
|
|
334
335
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
335
|
-
await unverifySite(ctx.client, args.id)
|
|
336
|
+
await unverifySite(ctx.client, args.id);
|
|
336
337
|
if (args.json) {
|
|
337
338
|
console.log(JSON.stringify({
|
|
338
339
|
id: args.id,
|
|
@@ -352,7 +353,7 @@ const verifyListCommand = defineCommand({
|
|
|
352
353
|
async run({ args }) {
|
|
353
354
|
applyOutputMode(args);
|
|
354
355
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
355
|
-
const resources = await listVerifiedSites(ctx.client)
|
|
356
|
+
const resources = await listVerifiedSites(ctx.client);
|
|
356
357
|
if (args.json) {
|
|
357
358
|
console.log(JSON.stringify(resources, null, 2));
|
|
358
359
|
return;
|
|
@@ -382,21 +383,20 @@ const getCommand = defineCommand({
|
|
|
382
383
|
url: {
|
|
383
384
|
type: "positional",
|
|
384
385
|
required: true,
|
|
385
|
-
description: "
|
|
386
|
+
description: "Site, for example example.com"
|
|
386
387
|
},
|
|
387
388
|
...OUTPUT_ARGS
|
|
388
389
|
},
|
|
389
390
|
async run({ args }) {
|
|
390
391
|
applyOutputMode(args);
|
|
391
|
-
const
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
logger.error(`Not found: ${args.url}`);
|
|
392
|
+
const all = await (await createCommandContext({ needsAuth: true })).loadSites();
|
|
393
|
+
const resolution = resolveSiteInput(String(args.url), all);
|
|
394
|
+
if (resolution.kind !== "resolved") {
|
|
395
|
+
if (args.json) console.log(JSON.stringify(null));
|
|
396
|
+
logger.error(formatSiteResolution(resolution, "account"));
|
|
398
397
|
process.exit(1);
|
|
399
398
|
}
|
|
399
|
+
const site = all.find((s) => s.siteUrl === resolution.siteUrl);
|
|
400
400
|
if (args.json) {
|
|
401
401
|
console.log(JSON.stringify(site, null, 2));
|
|
402
402
|
return;
|
|
@@ -426,7 +426,7 @@ async function runListSites(args) {
|
|
|
426
426
|
const ctx = await createCommandContext({ needsAuth: true });
|
|
427
427
|
const ownerOnly = Boolean(args["owner-only"]);
|
|
428
428
|
if (args["with-sitemaps"]) {
|
|
429
|
-
const all = await fetchSitesWithSitemaps(ctx.client)
|
|
429
|
+
const all = await fetchSitesWithSitemaps(ctx.client);
|
|
430
430
|
const sites = ownerOnly ? all.filter((s) => s.permissionLevel === "siteOwner") : all;
|
|
431
431
|
if (args.json) {
|
|
432
432
|
const enriched = sites.map((s) => ({
|
|
@@ -458,8 +458,22 @@ async function runListSites(args) {
|
|
|
458
458
|
}
|
|
459
459
|
const all = await ctx.loadSites();
|
|
460
460
|
const sites = ownerOnly ? all.filter((s) => s.permissionLevel === "siteOwner") : all;
|
|
461
|
+
const hosted = ctx.authentication._tag === "Cloud" ? await getCloudSites(ctx.authentication).then((list) => new Map(list.map((site) => [site.siteUrl, site])), (error) => {
|
|
462
|
+
logger.warn(`Hosted sync status is not available: ${error.message}`);
|
|
463
|
+
}) : void 0;
|
|
461
464
|
if (args.json) {
|
|
462
|
-
console.log(JSON.stringify(sites
|
|
465
|
+
console.log(JSON.stringify(hosted ? sites.map((site) => {
|
|
466
|
+
const entry = hosted.get(site.siteUrl);
|
|
467
|
+
return {
|
|
468
|
+
...site,
|
|
469
|
+
hostedSync: entry?.registered ? {
|
|
470
|
+
syncStatus: entry.syncStatus ?? null,
|
|
471
|
+
syncProgress: entry.syncProgress ?? null,
|
|
472
|
+
oldestDateSynced: entry.oldestDateSynced ?? null,
|
|
473
|
+
newestDateSynced: entry.newestDateSynced ?? null
|
|
474
|
+
} : null
|
|
475
|
+
};
|
|
476
|
+
}) : sites, null, 2));
|
|
463
477
|
return;
|
|
464
478
|
}
|
|
465
479
|
if (sites.length === 0) {
|
|
@@ -470,7 +484,9 @@ async function runListSites(args) {
|
|
|
470
484
|
console.log();
|
|
471
485
|
for (const site of sites) {
|
|
472
486
|
const perm = site.permissionLevel === "siteOwner" ? "\x1B[32m" : "\x1B[90m";
|
|
473
|
-
|
|
487
|
+
const entry = hosted?.get(site.siteUrl);
|
|
488
|
+
const sync = entry ? formatHostedSync(entry) : void 0;
|
|
489
|
+
console.log(` ${site.siteUrl} ${perm}(${site.permissionLevel})\x1B[0m${sync ? ` hosted sync ${sync}` : ""}`);
|
|
474
490
|
}
|
|
475
491
|
}
|
|
476
492
|
const listCommand = defineCommand({
|
package/dist/commands/stats.mjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { terminalOutputOptions } from "../render/terminal.mjs";
|
|
2
|
-
import { OUTPUT_ARGS, applyOutputMode, displayPath, formatAge
|
|
2
|
+
import { OUTPUT_ARGS, applyOutputMode, displayPath, formatAge } from "../utils.mjs";
|
|
3
3
|
import { allTables, tableDimensions } from "../local-store.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { readSiteMap, siteUrlForId } from "../store-sites.mjs";
|
|
5
|
+
import { createCommandContext, siteArg } from "../context.mjs";
|
|
5
6
|
import { renderTable, textLines } from "../render/layout.mjs";
|
|
6
7
|
import { formatMetric } from "../render/metrics.mjs";
|
|
7
8
|
import { barColumn } from "../render/charts.mjs";
|
|
8
9
|
import { columnsFor } from "../render/analysis.mjs";
|
|
9
|
-
import process from "node:process";
|
|
10
10
|
import { defineCommand } from "citty";
|
|
11
|
-
import { decodeSiteId, parseGscSiteUrl } from "gscdump";
|
|
12
11
|
import { filesystemStats } from "@gscdump/engine/filesystem";
|
|
13
12
|
const statsCommand = defineCommand({
|
|
14
13
|
meta: {
|
|
@@ -19,19 +18,17 @@ const statsCommand = defineCommand({
|
|
|
19
18
|
...OUTPUT_ARGS,
|
|
20
19
|
site: {
|
|
21
20
|
type: "string",
|
|
22
|
-
description: "Limit to one
|
|
21
|
+
description: "Limit to one Site, for example example.com"
|
|
23
22
|
}
|
|
24
23
|
},
|
|
25
24
|
async run({ args }) {
|
|
26
25
|
const { json } = applyOutputMode(args);
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const siteId =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
26
|
+
const ctx = await createCommandContext({ needsStore: true });
|
|
27
|
+
const store = ctx.store;
|
|
28
|
+
const siteUrl = args.site ? await ctx.resolveSite(String(args.site), { scope: "store" }) : void 0;
|
|
29
|
+
const siteId = siteUrl ? store.siteIdFor(siteUrl) : void 0;
|
|
30
|
+
const [allEntries, siteMap] = await Promise.all([store.engine.listAll({ userId: store.userId }), readSiteMap(store.dataDir, store.userId)]);
|
|
31
|
+
const knownSites = [...new Set(allEntries.filter((entry) => entry.retiredAt === void 0 && entry.siteId !== void 0).map((entry) => siteUrlForId(siteMap, entry.siteId)))];
|
|
35
32
|
const selectedEntries = siteId === void 0 ? allEntries : allEntries.filter((entry) => entry.siteId === siteId);
|
|
36
33
|
const perTable = allTables().map((table) => {
|
|
37
34
|
const all = selectedEntries.filter((entry) => entry.table === table);
|
|
@@ -48,9 +45,9 @@ const statsCommand = defineCommand({
|
|
|
48
45
|
if (json) {
|
|
49
46
|
const payload = {
|
|
50
47
|
dataDir: store.dataDir,
|
|
51
|
-
|
|
48
|
+
siteUrl: siteUrl ?? null,
|
|
52
49
|
knownSites,
|
|
53
|
-
nextCommand: `gscdump sync${
|
|
50
|
+
nextCommand: `gscdump sync${siteUrl ? ` --site ${siteArg(siteUrl)}` : ""} --status --json`,
|
|
54
51
|
disk,
|
|
55
52
|
tables: perTable.map(({ table, live, retired }) => ({
|
|
56
53
|
table,
|
|
@@ -61,7 +58,7 @@ const statsCommand = defineCommand({
|
|
|
61
58
|
retiredFiles: retired.length,
|
|
62
59
|
retiredBytes: sumBytes(retired),
|
|
63
60
|
watermarks: watermarks.filter((w) => w.table === table).map((w) => ({
|
|
64
|
-
|
|
61
|
+
siteUrl: w.siteId ? siteUrlForId(siteMap, w.siteId) : null,
|
|
65
62
|
searchType: w.searchType ?? "web",
|
|
66
63
|
newestDateSynced: w.newestDateSynced,
|
|
67
64
|
oldestDateSynced: w.oldestDateSynced,
|
|
@@ -107,7 +104,7 @@ const statsCommand = defineCommand({
|
|
|
107
104
|
];
|
|
108
105
|
if (rows.length > 1) lines.push(...textLines(`Total ${formatMetric("bytes", rows.reduce((sum, row) => sum + row.liveBytes, 0))} live`, options, "muted"));
|
|
109
106
|
if (watermarks.length) lines.push("", ...renderTable(sortWatermarks(watermarks).map((w) => ({
|
|
110
|
-
scope: w.siteId ? `${w.table}@${
|
|
107
|
+
scope: w.siteId ? `${w.table}@${siteArg(siteUrlForId(siteMap, w.siteId))}` : w.table,
|
|
111
108
|
dates: `${w.oldestDateSynced} to ${w.newestDateSynced}`,
|
|
112
109
|
synced: formatAge(w.lastSyncAt)
|
|
113
110
|
})), [
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { OUTPUT_ARGS, applyOutputMode, logger } from "../utils.mjs";
|
|
2
|
+
import { removeStoreSite } from "../store-sites.mjs";
|
|
2
3
|
import { createCommandContext } from "../context.mjs";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import { defineCommand } from "citty";
|
|
@@ -12,7 +13,7 @@ const rmSiteCommand = defineCommand({
|
|
|
12
13
|
site: {
|
|
13
14
|
type: "positional",
|
|
14
15
|
required: true,
|
|
15
|
-
description: "Site
|
|
16
|
+
description: "Site, for example example.com"
|
|
16
17
|
},
|
|
17
18
|
yes: {
|
|
18
19
|
type: "boolean",
|
|
@@ -24,11 +25,13 @@ const rmSiteCommand = defineCommand({
|
|
|
24
25
|
},
|
|
25
26
|
async run({ args }) {
|
|
26
27
|
const { json } = applyOutputMode(args);
|
|
27
|
-
const
|
|
28
|
-
const
|
|
28
|
+
const ctx = await createCommandContext({ needsStore: true });
|
|
29
|
+
const store = ctx.store;
|
|
30
|
+
const siteUrl = await ctx.resolveSite(String(args.site), { scope: "store" });
|
|
31
|
+
const siteId = store.siteIdFor(siteUrl);
|
|
29
32
|
if (!args.yes && !json) {
|
|
30
33
|
const ok = await confirm({
|
|
31
|
-
message: `Delete ALL local data for ${
|
|
34
|
+
message: `Delete ALL local data for ${siteUrl}? This is irreversible.`,
|
|
32
35
|
initialValue: false
|
|
33
36
|
});
|
|
34
37
|
if (isCancel(ok) || !ok) {
|
|
@@ -40,11 +43,12 @@ const rmSiteCommand = defineCommand({
|
|
|
40
43
|
userId: store.userId,
|
|
41
44
|
siteId
|
|
42
45
|
});
|
|
46
|
+
await removeStoreSite(store.dataDir, siteId, store.userId);
|
|
43
47
|
if (json) {
|
|
44
48
|
console.log(JSON.stringify(result, null, 2));
|
|
45
49
|
return;
|
|
46
50
|
}
|
|
47
|
-
logger.success(`Removed local data for ${
|
|
51
|
+
logger.success(`Removed local data for ${siteUrl}`);
|
|
48
52
|
console.log(` Objects deleted: ${result.objectsDeleted}`);
|
|
49
53
|
console.log(` Manifest entries: ${result.entriesRemoved}`);
|
|
50
54
|
console.log(` Watermarks: ${result.watermarksRemoved}`);
|
package/dist/commands/store.mjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { storeCommandMeta } from "../command-meta.mjs";
|
|
2
|
-
import { noSubcommandSelected } from "../utils.mjs";
|
|
3
2
|
import { compactCommand } from "./compact.mjs";
|
|
4
|
-
import { exportCommand } from "./export.mjs";
|
|
5
3
|
import { gcCommand } from "./gc.mjs";
|
|
6
4
|
import { rollupsCommand } from "./rollups.mjs";
|
|
7
5
|
import { statsCommand } from "./stats.mjs";
|
|
@@ -14,21 +12,11 @@ const storeCommand = defineCommand({
|
|
|
14
12
|
"stats": statsCommand,
|
|
15
13
|
"compact": compactCommand,
|
|
16
14
|
"gc": gcCommand,
|
|
17
|
-
"export": exportCommand,
|
|
18
15
|
"rollups": rollupsCommand,
|
|
19
16
|
"rm-site": rmSiteCommand,
|
|
20
17
|
"reset": resetCommand
|
|
21
18
|
},
|
|
22
19
|
async run({ args }) {
|
|
23
|
-
if (!noSubcommandSelected("store", [
|
|
24
|
-
"stats",
|
|
25
|
-
"compact",
|
|
26
|
-
"gc",
|
|
27
|
-
"export",
|
|
28
|
-
"rollups",
|
|
29
|
-
"rm-site",
|
|
30
|
-
"reset"
|
|
31
|
-
])) return;
|
|
32
20
|
await statsCommand.run?.({
|
|
33
21
|
args,
|
|
34
22
|
cmd: statsCommand,
|