@gscdump/cli 2.1.0 → 2.2.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 +1 -1
- package/dist/analysis-local.mjs +2 -1
- package/dist/auth.mjs +1 -1
- package/dist/cli.mjs +2 -1
- package/dist/commands/analyze.mjs +19 -18
- package/dist/commands/config.mjs +172 -166
- package/dist/commands/doctor.mjs +1 -1
- package/dist/commands/dump.mjs +2 -1
- package/dist/commands/entities.mjs +241 -237
- package/dist/commands/indexing.mjs +159 -154
- package/dist/commands/inspect.mjs +0 -7
- package/dist/commands/profile.mjs +146 -140
- package/dist/commands/report.mjs +35 -32
- package/dist/commands/rollups.mjs +91 -90
- package/dist/commands/sitemaps.mjs +392 -382
- package/dist/commands/sites.mjs +23 -17
- package/dist/commands/stats.mjs +2 -2
- package/dist/mcp/handlers/diagnostics.mjs +1 -1
- package/dist/mcp/handlers/reports.mjs +12 -10
- package/dist/mcp/server/index.mjs +14 -7
- package/dist/package.mjs +1 -1
- package/package.json +6 -6
package/dist/commands/report.mjs
CHANGED
|
@@ -165,12 +165,13 @@ function makeReportCommand(report) {
|
|
|
165
165
|
};
|
|
166
166
|
const params = buildReportParams(report, args);
|
|
167
167
|
if (args.explain || args["dry-run"]) {
|
|
168
|
-
const
|
|
168
|
+
const ctx = {
|
|
169
169
|
site: args.site ? String(args.site) : "(unresolved)",
|
|
170
170
|
window,
|
|
171
171
|
params,
|
|
172
172
|
registryVersion: defaultReportRegistry.version
|
|
173
|
-
}
|
|
173
|
+
};
|
|
174
|
+
const dry = await dryRunReport(report, ctx);
|
|
174
175
|
console.log(JSON.stringify({
|
|
175
176
|
id: report.id,
|
|
176
177
|
window,
|
|
@@ -184,15 +185,16 @@ function makeReportCommand(report) {
|
|
|
184
185
|
live: !!args.live,
|
|
185
186
|
json: !!args.json
|
|
186
187
|
});
|
|
188
|
+
const ctx = {
|
|
189
|
+
site: siteUrl,
|
|
190
|
+
window,
|
|
191
|
+
params,
|
|
192
|
+
registryVersion: defaultReportRegistry.version
|
|
193
|
+
};
|
|
187
194
|
const result = await runReport(report, {
|
|
188
195
|
source,
|
|
189
196
|
analyzers: defaultAnalyzerRegistry,
|
|
190
|
-
ctx
|
|
191
|
-
site: siteUrl,
|
|
192
|
-
window,
|
|
193
|
-
params,
|
|
194
|
-
registryVersion: defaultReportRegistry.version
|
|
195
|
-
}
|
|
197
|
+
ctx
|
|
196
198
|
});
|
|
197
199
|
if (args.json) {
|
|
198
200
|
console.log(JSON.stringify(result, null, 2));
|
|
@@ -207,36 +209,37 @@ function presetToFlag(preset) {
|
|
|
207
209
|
if (preset === "mtd" || preset === "ytd" || preset === "custom") return preset;
|
|
208
210
|
return preset.replace(/^last-/, "");
|
|
209
211
|
}
|
|
212
|
+
const listCommand = defineCommand({
|
|
213
|
+
meta: {
|
|
214
|
+
name: "list",
|
|
215
|
+
description: "List available report ids"
|
|
216
|
+
},
|
|
217
|
+
args: { json: {
|
|
218
|
+
type: "boolean",
|
|
219
|
+
default: false,
|
|
220
|
+
description: "Output as JSON"
|
|
221
|
+
} },
|
|
222
|
+
async run({ args }) {
|
|
223
|
+
const reports = defaultReportRegistry.listReports().map((r) => ({
|
|
224
|
+
id: r.id,
|
|
225
|
+
description: r.description,
|
|
226
|
+
defaultPeriod: r.defaultPeriod,
|
|
227
|
+
defaultComparison: r.defaultComparison
|
|
228
|
+
}));
|
|
229
|
+
if (args.json) {
|
|
230
|
+
console.log(JSON.stringify(reports, null, 2));
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
for (const r of reports) console.log(`${r.id.padEnd(16)} ${r.description}`);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
210
236
|
const reportCommand = defineCommand({
|
|
211
237
|
meta: {
|
|
212
238
|
name: "report",
|
|
213
239
|
description: "Run an intent-keyed report (composes analyzers into bounded sections)"
|
|
214
240
|
},
|
|
215
241
|
subCommands: {
|
|
216
|
-
list:
|
|
217
|
-
meta: {
|
|
218
|
-
name: "list",
|
|
219
|
-
description: "List available report ids"
|
|
220
|
-
},
|
|
221
|
-
args: { json: {
|
|
222
|
-
type: "boolean",
|
|
223
|
-
default: false,
|
|
224
|
-
description: "Output as JSON"
|
|
225
|
-
} },
|
|
226
|
-
async run({ args }) {
|
|
227
|
-
const reports = defaultReportRegistry.listReports().map((r) => ({
|
|
228
|
-
id: r.id,
|
|
229
|
-
description: r.description,
|
|
230
|
-
defaultPeriod: r.defaultPeriod,
|
|
231
|
-
defaultComparison: r.defaultComparison
|
|
232
|
-
}));
|
|
233
|
-
if (args.json) {
|
|
234
|
-
console.log(JSON.stringify(reports, null, 2));
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
for (const r of reports) console.log(`${r.id.padEnd(16)} ${r.description}`);
|
|
238
|
-
}
|
|
239
|
-
}),
|
|
242
|
+
list: listCommand,
|
|
240
243
|
...Object.fromEntries(REPORT_IDS.map((id) => [id, makeReportCommand(defaultReportRegistry.getReport(id))]))
|
|
241
244
|
}
|
|
242
245
|
});
|
|
@@ -33,102 +33,103 @@ async function buildSiteQueryDim(store, siteId) {
|
|
|
33
33
|
await createQueryDimStore({ dataSource: store.dataSource }).write(ctx, records, Date.now());
|
|
34
34
|
return records.length;
|
|
35
35
|
}
|
|
36
|
-
const
|
|
36
|
+
const rebuildSubCommand = defineCommand({
|
|
37
37
|
meta: {
|
|
38
|
-
name: "
|
|
39
|
-
description: "
|
|
38
|
+
name: "rebuild",
|
|
39
|
+
description: "Rebuild post-sync rollups (daily totals, weekly totals, top-N tables) for a site"
|
|
40
40
|
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
...OUTPUT_ARGS,
|
|
48
|
-
"site": {
|
|
49
|
-
type: "string",
|
|
50
|
-
alias: "s",
|
|
51
|
-
description: "Restrict to a single site (default: all sites with local data)"
|
|
52
|
-
},
|
|
53
|
-
"with-canonical": {
|
|
54
|
-
type: "boolean",
|
|
55
|
-
description: "Also build the opt-in canonical-primary rollups (query_canonical_variants, query_canonical_daily)",
|
|
56
|
-
default: false
|
|
57
|
-
}
|
|
41
|
+
args: {
|
|
42
|
+
...OUTPUT_ARGS,
|
|
43
|
+
"site": {
|
|
44
|
+
type: "string",
|
|
45
|
+
alias: "s",
|
|
46
|
+
description: "Restrict to a single site (default: all sites with local data)"
|
|
58
47
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
48
|
+
"with-canonical": {
|
|
49
|
+
type: "boolean",
|
|
50
|
+
description: "Also build the opt-in canonical-primary rollups (query_canonical_variants, query_canonical_daily)",
|
|
51
|
+
default: false
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
async run({ args }) {
|
|
55
|
+
const { json } = applyOutputMode(args);
|
|
56
|
+
const defs = args["with-canonical"] ? [...DEFAULT_ROLLUPS, ...CANONICAL_ROLLUPS] : DEFAULT_ROLLUPS;
|
|
57
|
+
const store = (await createCommandContext({ needsStore: true })).store;
|
|
58
|
+
const explicitSiteId = args.site ? store.siteIdFor(String(args.site)) : void 0;
|
|
59
|
+
const allSiteIds = /* @__PURE__ */ new Set();
|
|
60
|
+
if (explicitSiteId) allSiteIds.add(explicitSiteId);
|
|
61
|
+
else {
|
|
62
|
+
const entries = await store.engine.listLive({ userId: store.userId });
|
|
63
|
+
for (const e of entries) if (e.siteId) allSiteIds.add(e.siteId);
|
|
64
|
+
}
|
|
65
|
+
if (allSiteIds.size === 0) {
|
|
66
|
+
if (json) console.log(JSON.stringify({
|
|
67
|
+
sites: [],
|
|
68
|
+
totalBytes: 0
|
|
69
|
+
}, null, 2));
|
|
70
|
+
else logger.warn("No sites with local data. Run `gscdump sync` first.");
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const summary = [];
|
|
74
|
+
let totalBytes = 0;
|
|
75
|
+
for (const siteId of allSiteIds) {
|
|
76
|
+
if (args["with-canonical"]) {
|
|
77
|
+
const dimRows = await buildSiteQueryDim(store, siteId);
|
|
78
|
+
if (!json) logger.info(`Built query dimension for [${siteId}] (${dimRows} distinct queries, normalizer v${NORMALIZER_VERSION})`);
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
80
|
+
logger.info(`Rebuilding rollups for [${siteId}] (${defs.length} rollups)`);
|
|
81
|
+
const results = await rebuildRollups({
|
|
82
|
+
engine: {
|
|
83
|
+
runSQL: (opts) => store.engine.runSQL(opts),
|
|
84
|
+
listPartitions: async ({ ctx, table, searchType }) => {
|
|
85
|
+
return (await store.engine.listLive({
|
|
86
|
+
userId: ctx.userId,
|
|
87
|
+
...ctx.siteId !== void 0 ? { siteId: ctx.siteId } : {},
|
|
88
|
+
table,
|
|
89
|
+
...searchType !== void 0 ? { searchType } : {}
|
|
90
|
+
})).map((e) => ({
|
|
91
|
+
partition: e.partition,
|
|
92
|
+
bytes: e.bytes
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
dataSource: store.dataSource,
|
|
97
|
+
ctx: {
|
|
98
|
+
userId: store.userId,
|
|
99
|
+
siteId
|
|
100
|
+
},
|
|
101
|
+
defs
|
|
102
|
+
});
|
|
103
|
+
const site = {
|
|
104
|
+
siteId,
|
|
105
|
+
rollups: []
|
|
106
|
+
};
|
|
107
|
+
for (const r of results) {
|
|
108
|
+
totalBytes += r.bytes;
|
|
109
|
+
site.rollups.push({
|
|
110
|
+
id: r.id,
|
|
111
|
+
bytes: r.bytes,
|
|
112
|
+
objectKey: r.objectKey
|
|
107
113
|
});
|
|
108
|
-
|
|
109
|
-
siteId,
|
|
110
|
-
rollups: []
|
|
111
|
-
};
|
|
112
|
-
for (const r of results) {
|
|
113
|
-
totalBytes += r.bytes;
|
|
114
|
-
site.rollups.push({
|
|
115
|
-
id: r.id,
|
|
116
|
-
bytes: r.bytes,
|
|
117
|
-
objectKey: r.objectKey
|
|
118
|
-
});
|
|
119
|
-
if (!json) console.log(` ${r.id.padEnd(20)} ${(r.bytes / 1024).toFixed(1).padStart(8)} KB ${r.objectKey}`);
|
|
120
|
-
}
|
|
121
|
-
summary.push(site);
|
|
122
|
-
}
|
|
123
|
-
if (json) {
|
|
124
|
-
console.log(JSON.stringify({
|
|
125
|
-
sites: summary,
|
|
126
|
-
totalBytes
|
|
127
|
-
}, null, 2));
|
|
128
|
-
return;
|
|
114
|
+
if (!json) console.log(` ${r.id.padEnd(20)} ${(r.bytes / 1024).toFixed(1).padStart(8)} KB ${r.objectKey}`);
|
|
129
115
|
}
|
|
130
|
-
|
|
116
|
+
summary.push(site);
|
|
117
|
+
}
|
|
118
|
+
if (json) {
|
|
119
|
+
console.log(JSON.stringify({
|
|
120
|
+
sites: summary,
|
|
121
|
+
totalBytes
|
|
122
|
+
}, null, 2));
|
|
123
|
+
return;
|
|
131
124
|
}
|
|
132
|
-
|
|
125
|
+
logger.success(`Rebuilt rollups across ${allSiteIds.size} site(s) — total ${(totalBytes / 1024).toFixed(1)} KB`);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
const rollupsCommand = defineCommand({
|
|
129
|
+
meta: {
|
|
130
|
+
name: "rollups",
|
|
131
|
+
description: "Manage post-sync rollups"
|
|
132
|
+
},
|
|
133
|
+
subCommands: { rebuild: rebuildSubCommand }
|
|
133
134
|
});
|
|
134
135
|
export { rollupsCommand };
|