@supalytics/cli 0.4.3 → 0.4.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supalytics/cli",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "CLI for Supalytics web analytics",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,10 +37,10 @@ Examples:
37
37
  supalytics funnels
38
38
 
39
39
  # View a funnel with conversion analysis
40
- supalytics funnels view <id>
40
+ supalytics funnels <id>
41
41
 
42
42
  # View with custom date range
43
- supalytics funnels view <id> -p 90d
43
+ supalytics funnels <id> -p 90d
44
44
 
45
45
  # Create a funnel
46
46
  supalytics funnels create "Signup Flow" --step "page:/pricing" --step "event:signup_clicked" --step "purchase"
@@ -215,9 +215,13 @@ function renderAnalysis(rows: FunnelAnalysisRow[], funnel: { name: string; descr
215
215
  export const funnelsCommand = new Command("funnels")
216
216
  .description("Manage and analyze conversion funnels")
217
217
  .addHelpText("after", funnelsExamples)
218
+ .argument("[id]", "Funnel ID to view details and conversion analysis")
218
219
  .option("-s, --site <site>", "Site to query")
220
+ .option("-p, --period <period>", "Time period: 7d, 14d, 30d, 90d, 12mo, all", "30d")
221
+ .option("--start <date>", "Start date (YYYY-MM-DD)")
222
+ .option("--end <date>", "End date (YYYY-MM-DD)")
219
223
  .option("--json", "Output as JSON")
220
- .action(async (options) => {
224
+ .action(async (id, options) => {
221
225
  const site = options.site || (await getDefaultSite())
222
226
 
223
227
  if (!site) {
@@ -229,6 +233,47 @@ export const funnelsCommand = new Command("funnels")
229
233
  process.exit(1)
230
234
  }
231
235
 
236
+ // If an ID is provided, show funnel details + analysis
237
+ if (id) {
238
+ try {
239
+ const dateRange =
240
+ options.start && options.end
241
+ ? ([options.start, options.end] as [string, string])
242
+ : parsePeriod(options.period as string)
243
+
244
+ // Fetch funnel definition and run analysis in parallel
245
+ const [funnelResponse, analysisResponse] = await Promise.all([
246
+ getFunnel(site, id),
247
+ analyzeFunnel(site, id, dateRange),
248
+ ])
249
+
250
+ if (options.json) {
251
+ console.log(
252
+ JSON.stringify(
253
+ {
254
+ funnel: funnelResponse.data,
255
+ analysis: analysisResponse.data,
256
+ meta: analysisResponse.meta,
257
+ },
258
+ null,
259
+ 2
260
+ )
261
+ )
262
+ return
263
+ }
264
+
265
+ const [startDate, endDate] = analysisResponse.meta.date_range
266
+ console.log(chalk.dim(` ${startDate} → ${endDate} (${analysisResponse.meta.query_ms}ms)`))
267
+
268
+ renderAnalysis(analysisResponse.data, funnelResponse.data)
269
+ } catch (error) {
270
+ console.error(chalk.red(`Error: ${(error as Error).message}`))
271
+ process.exit(1)
272
+ }
273
+ return
274
+ }
275
+
276
+ // No ID — list all funnels
232
277
  try {
233
278
  const response = await listFunnels(site)
234
279
 
@@ -271,65 +316,6 @@ export const funnelsCommand = new Command("funnels")
271
316
  }
272
317
  })
273
318
 
274
- // Subcommand: view
275
- funnelsCommand
276
- .command("view <id>")
277
- .description("View funnel details and conversion analysis")
278
- .option("-s, --site <site>", "Site to query")
279
- .option("-p, --period <period>", "Time period: 7d, 14d, 30d, 90d, 12mo, all", "30d")
280
- .option("--start <date>", "Start date (YYYY-MM-DD)")
281
- .option("--end <date>", "End date (YYYY-MM-DD)")
282
- .option("--json", "Output as JSON")
283
- .action(async (id, _options, cmd) => {
284
- const options = mergedOpts(cmd)
285
- const site = await resolveSiteOption(cmd)
286
-
287
- if (!site) {
288
- console.error(
289
- chalk.red(
290
- "Error: No site specified. Use --site or set a default with `supalytics login --site`"
291
- )
292
- )
293
- process.exit(1)
294
- }
295
-
296
- try {
297
- const dateRange =
298
- options.start && options.end
299
- ? ([options.start, options.end] as [string, string])
300
- : parsePeriod(options.period as string)
301
-
302
- // Fetch funnel definition and run analysis in parallel
303
- const [funnelResponse, analysisResponse] = await Promise.all([
304
- getFunnel(site, id),
305
- analyzeFunnel(site, id, dateRange),
306
- ])
307
-
308
- if (options.json) {
309
- console.log(
310
- JSON.stringify(
311
- {
312
- funnel: funnelResponse.data,
313
- analysis: analysisResponse.data,
314
- meta: analysisResponse.meta,
315
- },
316
- null,
317
- 2
318
- )
319
- )
320
- return
321
- }
322
-
323
- const [startDate, endDate] = analysisResponse.meta.date_range
324
- console.log(chalk.dim(` ${startDate} → ${endDate} (${analysisResponse.meta.query_ms}ms)`))
325
-
326
- renderAnalysis(analysisResponse.data, funnelResponse.data)
327
- } catch (error) {
328
- console.error(chalk.red(`Error: ${(error as Error).message}`))
329
- process.exit(1)
330
- }
331
- })
332
-
333
319
  // Subcommand: create
334
320
  funnelsCommand
335
321
  .command("create <name>")