@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.
@@ -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 dry = await dryRunReport(report, {
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: defineCommand({
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 rollupsCommand = defineCommand({
36
+ const rebuildSubCommand = defineCommand({
37
37
  meta: {
38
- name: "rollups",
39
- description: "Manage post-sync rollups"
38
+ name: "rebuild",
39
+ description: "Rebuild post-sync rollups (daily totals, weekly totals, top-N tables) for a site"
40
40
  },
41
- subCommands: { rebuild: defineCommand({
42
- meta: {
43
- name: "rebuild",
44
- description: "Rebuild post-sync rollups (daily totals, weekly totals, top-N tables) for a site"
45
- },
46
- args: {
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
- async run({ args }) {
60
- const { json } = applyOutputMode(args);
61
- const defs = args["with-canonical"] ? [...DEFAULT_ROLLUPS, ...CANONICAL_ROLLUPS] : DEFAULT_ROLLUPS;
62
- const store = (await createCommandContext({ needsStore: true })).store;
63
- const explicitSiteId = args.site ? store.siteIdFor(String(args.site)) : void 0;
64
- const allSiteIds = /* @__PURE__ */ new Set();
65
- if (explicitSiteId) allSiteIds.add(explicitSiteId);
66
- else {
67
- const entries = await store.engine.listLive({ userId: store.userId });
68
- for (const e of entries) if (e.siteId) allSiteIds.add(e.siteId);
69
- }
70
- if (allSiteIds.size === 0) {
71
- if (json) console.log(JSON.stringify({
72
- sites: [],
73
- totalBytes: 0
74
- }, null, 2));
75
- else logger.warn("No sites with local data. Run `gscdump sync` first.");
76
- return;
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
- const summary = [];
79
- let totalBytes = 0;
80
- for (const siteId of allSiteIds) {
81
- if (args["with-canonical"]) {
82
- const dimRows = await buildSiteQueryDim(store, siteId);
83
- if (!json) logger.info(`Built query dimension for [${siteId}] (${dimRows} distinct queries, normalizer v${NORMALIZER_VERSION})`);
84
- }
85
- logger.info(`Rebuilding rollups for [${siteId}] (${defs.length} rollups)`);
86
- const results = await rebuildRollups({
87
- engine: {
88
- runSQL: (opts) => store.engine.runSQL(opts),
89
- listPartitions: async ({ ctx, table, searchType }) => {
90
- return (await store.engine.listLive({
91
- userId: ctx.userId,
92
- ...ctx.siteId !== void 0 ? { siteId: ctx.siteId } : {},
93
- table,
94
- ...searchType !== void 0 ? { searchType } : {}
95
- })).map((e) => ({
96
- partition: e.partition,
97
- bytes: e.bytes
98
- }));
99
- }
100
- },
101
- dataSource: store.dataSource,
102
- ctx: {
103
- userId: store.userId,
104
- siteId
105
- },
106
- defs
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
- const site = {
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
- logger.success(`Rebuilt rollups across ${allSiteIds.size} site(s) — total ${(totalBytes / 1024).toFixed(1)} KB`);
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 };