@mostly-good-metrics/cli 0.1.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/LICENSE +21 -0
- package/README.md +126 -0
- package/bin/mgm.js +2 -0
- package/dist/auth.d.ts +8 -0
- package/dist/auth.js +146 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +287 -0
- package/dist/client.js +123 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/auth.d.ts +2 -0
- package/dist/commands/auth.js +286 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/dashboard.d.ts +2 -0
- package/dist/commands/dashboard.js +74 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/discovery.d.ts +2 -0
- package/dist/commands/discovery.js +94 -0
- package/dist/commands/discovery.js.map +1 -0
- package/dist/commands/events.d.ts +2 -0
- package/dist/commands/events.js +100 -0
- package/dist/commands/events.js.map +1 -0
- package/dist/commands/experiments.d.ts +2 -0
- package/dist/commands/experiments.js +191 -0
- package/dist/commands/experiments.js.map +1 -0
- package/dist/commands/funnels.d.ts +2 -0
- package/dist/commands/funnels.js +186 -0
- package/dist/commands/funnels.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +127 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/keys.d.ts +2 -0
- package/dist/commands/keys.js +71 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/orgs.d.ts +2 -0
- package/dist/commands/orgs.js +92 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/projects.d.ts +2 -0
- package/dist/commands/projects.js +71 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/queries.d.ts +2 -0
- package/dist/commands/queries.js +177 -0
- package/dist/commands/queries.js.map +1 -0
- package/dist/commands/retention.d.ts +2 -0
- package/dist/commands/retention.js +162 -0
- package/dist/commands/retention.js.map +1 -0
- package/dist/commands/widgets.d.ts +2 -0
- package/dist/commands/widgets.js +92 -0
- package/dist/commands/widgets.js.map +1 -0
- package/dist/context.d.ts +9 -0
- package/dist/context.js +42 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/output.d.ts +5 -0
- package/dist/output.js +42 -0
- package/dist/output.js.map +1 -0
- package/dist/program.d.ts +3 -0
- package/dist/program.js +44 -0
- package/dist/program.js.map +1 -0
- package/dist/runtime.d.ts +13 -0
- package/dist/runtime.js +35 -0
- package/dist/runtime.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,QAAQ,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEzD,SAAS,MAAM,CAAC,QAAgB;IAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,kBAAkB,EAAE,4BAA4B,CAAC;SACxD,MAAM,CAAC,cAAc,EAAE,mBAAmB,CAAC;SAC3C,MAAM,CAAC,cAAc,EAAE,sDAAsD,CAAC;SAC9E,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;SAClC,MAAM,CAAC,KAAK,EAAE,IAAsE,EAAE,EAAE;QACvF,IAAI,CAAC,YAAY,EAAE,CAAC;QAEpB,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;YACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,OAAO,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACN,IAAI,SAAS,EAAE,EAAE,CAAC;oBAChB,MAAM,IAAI,aAAa,CAAC,sFAAsF,CAAC,CAAC;gBAClH,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBAC9B,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;gBAClF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;gBACzD,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBACxC,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC9D,CAAC;QACH,CAAC;QAED,IAAI,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,IAAI,aAAa,CAAC,iDAAiD,CAAC,CAAC;QAC7E,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC;QACrE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,WAAW,QAAQ,OAAO,KAAK,CAAC,CAAC;QAClF,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAErE,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACnD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAEzE,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAEjC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;YAC9C,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,oBAAoB,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YAC/D,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW,EAAE,MAAc;IACvD,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAC1B,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,YAAY;YACf,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;YAClF,OAAO,CAAC,GAAG,CAAC,6BAA6B,MAAM,KAAK,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,cAAc;YACjB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;YAC/D,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;YACpF,OAAO,CAAC,GAAG,CAAC,6BAA6B,MAAM,KAAK,CAAC,CAAC;YACtD,MAAM;QACR,KAAK,OAAO;YACV,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,4GAA4G,CAAC,CAAC;YAC1H,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,0CAA0C,MAAM,IAAI,CAAC,CAAC;YAClE,MAAM;QACR,KAAK,SAAS,CAAC;QACf,KAAK,QAAQ;YACX,OAAO,CAAC,GAAG,CAAC,iEAAiE,CAAC,CAAC;YAC/E,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,2CAA2C,MAAM,IAAI,CAAC,CAAC;YACnE,MAAM;QACR,KAAK,SAAS,CAAC;QACf,KAAK,MAAM;YACT,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACrD,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,0CAA0C,MAAM,KAAK,CAAC,CAAC;YACnE,MAAM;QACR;YACE,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as client from "../client.js";
|
|
2
|
+
import * as auth from "../auth.js";
|
|
3
|
+
import * as output from "../output.js";
|
|
4
|
+
import { requireProjectId } from "../context.js";
|
|
5
|
+
import { requireConfirmation } from "../runtime.js";
|
|
6
|
+
export function registerKeysCommands(program) {
|
|
7
|
+
const keys = program
|
|
8
|
+
.command("keys")
|
|
9
|
+
.description("Manage API keys");
|
|
10
|
+
keys
|
|
11
|
+
.command("list")
|
|
12
|
+
.description("List API keys for current project")
|
|
13
|
+
.option("--project <id>", "Project ID")
|
|
14
|
+
.option("--json", "Output as JSON")
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
auth.requireToken();
|
|
17
|
+
const projectId = requireProjectId(opts.project);
|
|
18
|
+
const data = await client.listApiKeys(projectId);
|
|
19
|
+
if (opts.json) {
|
|
20
|
+
output.json(data.api_keys);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (data.api_keys.length === 0) {
|
|
24
|
+
console.log("No API keys found. Create one with `mgm keys create`.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
output.table(["ID", "Name", "Prefix", "Created"], data.api_keys.map((k) => [
|
|
28
|
+
k.id,
|
|
29
|
+
k.name,
|
|
30
|
+
k.key_prefix ?? "-",
|
|
31
|
+
k.created_at ?? "-",
|
|
32
|
+
]));
|
|
33
|
+
});
|
|
34
|
+
keys
|
|
35
|
+
.command("create")
|
|
36
|
+
.description("Create a new API key")
|
|
37
|
+
.argument("<name>", "Key name")
|
|
38
|
+
.option("--project <id>", "Project ID")
|
|
39
|
+
.option("--json", "Output as JSON")
|
|
40
|
+
.action(async (name, opts) => {
|
|
41
|
+
auth.requireToken();
|
|
42
|
+
const projectId = requireProjectId(opts.project);
|
|
43
|
+
const data = await client.createApiKey(projectId, name);
|
|
44
|
+
if (opts.json) {
|
|
45
|
+
output.json(data.api_key);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
console.log(`API key created: ${data.api_key.name}`);
|
|
49
|
+
console.log(`Key: ${data.api_key.key}`);
|
|
50
|
+
console.log();
|
|
51
|
+
console.log("Save this key — it won't be shown again.");
|
|
52
|
+
});
|
|
53
|
+
keys
|
|
54
|
+
.command("revoke")
|
|
55
|
+
.description("Revoke an API key")
|
|
56
|
+
.argument("<id>", "Key ID")
|
|
57
|
+
.option("--project <id>", "Project ID")
|
|
58
|
+
.option("--json", "Output as JSON")
|
|
59
|
+
.action(async (id, opts) => {
|
|
60
|
+
auth.requireToken();
|
|
61
|
+
const projectId = requireProjectId(opts.project);
|
|
62
|
+
await requireConfirmation(`Revoke API key ${id}`);
|
|
63
|
+
const data = await client.revokeApiKey(projectId, id);
|
|
64
|
+
if (opts.json) {
|
|
65
|
+
output.json(data);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.log("API key revoked.");
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import * as client from "../client.js";
|
|
2
|
+
import * as auth from "../auth.js";
|
|
3
|
+
import * as output from "../output.js";
|
|
4
|
+
export function registerOrgsCommands(program) {
|
|
5
|
+
const orgs = program
|
|
6
|
+
.command("orgs")
|
|
7
|
+
.description("Manage organizations");
|
|
8
|
+
orgs
|
|
9
|
+
.command("list")
|
|
10
|
+
.description("List organizations")
|
|
11
|
+
.option("--json", "Output as JSON")
|
|
12
|
+
.action(async (opts) => {
|
|
13
|
+
auth.requireToken();
|
|
14
|
+
const data = await client.listOrganizations();
|
|
15
|
+
if (opts.json) {
|
|
16
|
+
output.json(data.organizations);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (data.organizations.length === 0) {
|
|
20
|
+
console.log("No organizations found. Create one with `mgm orgs create`.");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
output.table(["Name", "Slug", "Plan", "Role"], data.organizations.map((o) => [o.name, o.slug, o.plan ?? "-", o.role ?? "-"]));
|
|
24
|
+
});
|
|
25
|
+
orgs
|
|
26
|
+
.command("show")
|
|
27
|
+
.description("Show organization details and projects")
|
|
28
|
+
.argument("<slug>", "Organization slug")
|
|
29
|
+
.option("--json", "Output as JSON")
|
|
30
|
+
.action(async (slug, opts) => {
|
|
31
|
+
auth.requireToken();
|
|
32
|
+
const data = await client.getOrganization(slug);
|
|
33
|
+
if (opts.json) {
|
|
34
|
+
output.json(data);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const o = data.organization;
|
|
38
|
+
console.log(`Name: ${o.name}`);
|
|
39
|
+
console.log(`Slug: ${o.slug}`);
|
|
40
|
+
if (o.plan)
|
|
41
|
+
console.log(`Plan: ${o.plan}`);
|
|
42
|
+
if (o.events_per_month_limit !== undefined) {
|
|
43
|
+
console.log(`Events/month limit: ${output.formatNumber(o.events_per_month_limit)}`);
|
|
44
|
+
}
|
|
45
|
+
if (data.projects.length > 0) {
|
|
46
|
+
console.log();
|
|
47
|
+
console.log("Projects:");
|
|
48
|
+
output.table(["ID", "Name", "Timezone"], data.projects.map((p) => [p.id, p.name, p.timezone]));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
orgs
|
|
52
|
+
.command("create")
|
|
53
|
+
.description("Create a new organization")
|
|
54
|
+
.argument("<name>", "Organization name")
|
|
55
|
+
.option("--json", "Output as JSON")
|
|
56
|
+
.action(async (name, opts) => {
|
|
57
|
+
auth.requireToken();
|
|
58
|
+
const data = await client.createOrganization(name);
|
|
59
|
+
if (opts.json) {
|
|
60
|
+
output.json(data.organization);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
console.log(`Organization created: ${data.organization.name}`);
|
|
64
|
+
console.log(`Slug: ${data.organization.slug}`);
|
|
65
|
+
});
|
|
66
|
+
orgs
|
|
67
|
+
.command("invite")
|
|
68
|
+
.description("Invite a member to an organization")
|
|
69
|
+
.argument("<email>", "Email address to invite")
|
|
70
|
+
.option("--org <slug>", "Organization slug (defaults to your first org)")
|
|
71
|
+
.option("--role <role>", "Role (member, admin)", "member")
|
|
72
|
+
.option("--json", "Output as JSON")
|
|
73
|
+
.action(async (email, opts) => {
|
|
74
|
+
auth.requireToken();
|
|
75
|
+
let orgSlug = opts.org;
|
|
76
|
+
if (!orgSlug) {
|
|
77
|
+
const { organizations } = await client.getMe();
|
|
78
|
+
if (organizations.length === 0) {
|
|
79
|
+
console.error("No organizations found. Create one first.");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
orgSlug = organizations[0].slug;
|
|
83
|
+
}
|
|
84
|
+
const data = await client.inviteMember(orgSlug, email, opts.role);
|
|
85
|
+
if (opts.json) {
|
|
86
|
+
output.json(data);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.log(`Invitation sent to ${email} (${orgSlug}, role: ${opts.role}).`);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=orgs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgs.js","sourceRoot":"","sources":["../../src/commands/orgs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as client from "../client.js";
|
|
2
|
+
import * as auth from "../auth.js";
|
|
3
|
+
import * as output from "../output.js";
|
|
4
|
+
export function registerProjectsCommands(program) {
|
|
5
|
+
const projects = program
|
|
6
|
+
.command("projects")
|
|
7
|
+
.description("Manage projects");
|
|
8
|
+
projects
|
|
9
|
+
.command("list")
|
|
10
|
+
.description("List all projects")
|
|
11
|
+
.option("--json", "Output as JSON")
|
|
12
|
+
.action(async (opts) => {
|
|
13
|
+
auth.requireToken();
|
|
14
|
+
const data = await client.listProjects();
|
|
15
|
+
if (opts.json) {
|
|
16
|
+
output.json(data.projects);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (data.projects.length === 0) {
|
|
20
|
+
console.log("No projects found. Create one with `mgm projects create`.");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
output.table(["ID", "Name", "Timezone"], data.projects.map((p) => [p.id, p.name, p.timezone]));
|
|
24
|
+
});
|
|
25
|
+
projects
|
|
26
|
+
.command("create")
|
|
27
|
+
.description("Create a new project")
|
|
28
|
+
.argument("<name>", "Project name")
|
|
29
|
+
.option("--org <slug>", "Organization slug")
|
|
30
|
+
.option("--timezone <tz>", "Timezone (e.g. America/New_York)")
|
|
31
|
+
.option("--json", "Output as JSON")
|
|
32
|
+
.action(async (name, opts) => {
|
|
33
|
+
auth.requireToken();
|
|
34
|
+
let orgSlug = opts.org;
|
|
35
|
+
if (!orgSlug) {
|
|
36
|
+
const { organizations } = await client.getMe();
|
|
37
|
+
if (organizations.length === 0) {
|
|
38
|
+
console.error("No organizations found. Create one first.");
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
orgSlug = organizations[0].slug;
|
|
42
|
+
}
|
|
43
|
+
const data = await client.createProject(orgSlug, name, opts.timezone);
|
|
44
|
+
if (opts.json) {
|
|
45
|
+
output.json(data.project);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
console.log(`Project created: ${data.project.name}`);
|
|
49
|
+
console.log(`ID: ${data.project.id}`);
|
|
50
|
+
});
|
|
51
|
+
projects
|
|
52
|
+
.command("show")
|
|
53
|
+
.description("Show project details")
|
|
54
|
+
.argument("<id>", "Project ID")
|
|
55
|
+
.option("--json", "Output as JSON")
|
|
56
|
+
.action(async (id, opts) => {
|
|
57
|
+
auth.requireToken();
|
|
58
|
+
const data = await client.getProject(id);
|
|
59
|
+
if (opts.json) {
|
|
60
|
+
output.json(data.project);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const p = data.project;
|
|
64
|
+
console.log(`Name: ${p.name}`);
|
|
65
|
+
console.log(`ID: ${p.id}`);
|
|
66
|
+
console.log(`Timezone: ${p.timezone}`);
|
|
67
|
+
if (p.organization_id)
|
|
68
|
+
console.log(`Organization: ${p.organization_id}`);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import * as client from "../client.js";
|
|
2
|
+
import * as auth from "../auth.js";
|
|
3
|
+
import * as output from "../output.js";
|
|
4
|
+
import { requireProjectId } from "../context.js";
|
|
5
|
+
import { requireConfirmation } from "../runtime.js";
|
|
6
|
+
export function registerQueriesCommands(program) {
|
|
7
|
+
const queries = program
|
|
8
|
+
.command("queries")
|
|
9
|
+
.description("Manage and execute saved queries");
|
|
10
|
+
queries
|
|
11
|
+
.command("list")
|
|
12
|
+
.description("List saved queries")
|
|
13
|
+
.option("--project <id>", "Project ID")
|
|
14
|
+
.option("--json", "Output as JSON")
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
auth.requireToken();
|
|
17
|
+
const projectId = requireProjectId(opts.project);
|
|
18
|
+
const data = await client.listInsights(projectId);
|
|
19
|
+
if (opts.json) {
|
|
20
|
+
output.json(data.insights);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (data.insights.length === 0) {
|
|
24
|
+
console.log("No saved queries found.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
output.table(["ID", "Name", "Visualization"], data.insights.map((q) => [q.id, q.name, q.visualization ?? "-"]));
|
|
28
|
+
});
|
|
29
|
+
queries
|
|
30
|
+
.command("create")
|
|
31
|
+
.description("Create a saved query")
|
|
32
|
+
.requiredOption("--name <name>", "Query name")
|
|
33
|
+
.option("--metric <metric>", "Metric (e.g. unique_users, count_events)")
|
|
34
|
+
.option("--group-by <field>", "Group by field (e.g. date, event_name)")
|
|
35
|
+
.option("--range <range>", "Date range (e.g. 30d)")
|
|
36
|
+
.option("--visualization <type>", "Chart type (line, bar, table)")
|
|
37
|
+
.option("--project <id>", "Project ID")
|
|
38
|
+
.option("--json", "Output as JSON")
|
|
39
|
+
.action(async (opts) => {
|
|
40
|
+
auth.requireToken();
|
|
41
|
+
const projectId = requireProjectId(opts.project);
|
|
42
|
+
const queryDef = {};
|
|
43
|
+
if (opts.metric)
|
|
44
|
+
queryDef.metric = opts.metric;
|
|
45
|
+
if (opts.groupBy)
|
|
46
|
+
queryDef.group_by = opts.groupBy;
|
|
47
|
+
if (opts.range)
|
|
48
|
+
queryDef.date_range = opts.range;
|
|
49
|
+
const attrs = {
|
|
50
|
+
name: opts.name,
|
|
51
|
+
query_definition: queryDef,
|
|
52
|
+
};
|
|
53
|
+
if (opts.visualization)
|
|
54
|
+
attrs.visualization = opts.visualization;
|
|
55
|
+
const data = await client.createInsight(projectId, attrs);
|
|
56
|
+
if (opts.json) {
|
|
57
|
+
output.json(data.insight);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
console.log(`Query created: ${data.insight.name}`);
|
|
61
|
+
console.log(`ID: ${data.insight.id}`);
|
|
62
|
+
});
|
|
63
|
+
queries
|
|
64
|
+
.command("show")
|
|
65
|
+
.description("Show a saved query's full definition")
|
|
66
|
+
.argument("<id>", "Query ID")
|
|
67
|
+
.option("--project <id>", "Project ID")
|
|
68
|
+
.option("--json", "Output as JSON")
|
|
69
|
+
.action(async (id, opts) => {
|
|
70
|
+
auth.requireToken();
|
|
71
|
+
const data = await client.getInsight(requireProjectId(opts.project), id);
|
|
72
|
+
if (opts.json) {
|
|
73
|
+
output.json(data.insight);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
console.log(`Query: ${data.insight.name}`);
|
|
77
|
+
console.log(`ID: ${data.insight.id}`);
|
|
78
|
+
});
|
|
79
|
+
queries
|
|
80
|
+
.command("update")
|
|
81
|
+
.description("Update a saved query")
|
|
82
|
+
.argument("<id>", "Query ID")
|
|
83
|
+
.option("--name <name>", "Query name")
|
|
84
|
+
.option("--metric <metric>", "Metric")
|
|
85
|
+
.option("--group-by <field>", "Group by field")
|
|
86
|
+
.option("--range <range>", "Date range")
|
|
87
|
+
.option("--visualization <type>", "Chart type")
|
|
88
|
+
.option("--project <id>", "Project ID")
|
|
89
|
+
.option("--json", "Output as JSON")
|
|
90
|
+
.action(async (id, opts) => {
|
|
91
|
+
auth.requireToken();
|
|
92
|
+
const attrs = {};
|
|
93
|
+
const queryDefinition = {};
|
|
94
|
+
if (opts.name)
|
|
95
|
+
attrs.name = opts.name;
|
|
96
|
+
if (opts.metric)
|
|
97
|
+
queryDefinition.metric = opts.metric;
|
|
98
|
+
if (opts.groupBy)
|
|
99
|
+
queryDefinition.group_by = opts.groupBy;
|
|
100
|
+
if (opts.range)
|
|
101
|
+
queryDefinition.date_range = opts.range;
|
|
102
|
+
if (Object.keys(queryDefinition).length > 0)
|
|
103
|
+
attrs.query_definition = queryDefinition;
|
|
104
|
+
if (opts.visualization)
|
|
105
|
+
attrs.visualization = opts.visualization;
|
|
106
|
+
if (Object.keys(attrs).length === 0)
|
|
107
|
+
throw new Error("Provide at least one field to update.");
|
|
108
|
+
const data = await client.updateInsight(requireProjectId(opts.project), id, attrs);
|
|
109
|
+
if (opts.json) {
|
|
110
|
+
output.json(data.insight);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
console.log(`Query updated: ${data.insight.name}`);
|
|
114
|
+
});
|
|
115
|
+
queries
|
|
116
|
+
.command("execute")
|
|
117
|
+
.description("Execute a saved or ad-hoc query")
|
|
118
|
+
.argument("[id]", "Query ID (omit for ad-hoc)")
|
|
119
|
+
.option("--metric <metric>", "Metric (ad-hoc)")
|
|
120
|
+
.option("--group-by <field>", "Group by field (ad-hoc)")
|
|
121
|
+
.option("--range <range>", "Date range")
|
|
122
|
+
.option("--project <id>", "Project ID")
|
|
123
|
+
.option("--json", "Output as JSON")
|
|
124
|
+
.action(async (id, opts) => {
|
|
125
|
+
auth.requireToken();
|
|
126
|
+
const projectId = requireProjectId(opts.project);
|
|
127
|
+
let result;
|
|
128
|
+
if (id) {
|
|
129
|
+
result = await client.executeInsight(projectId, id);
|
|
130
|
+
}
|
|
131
|
+
else if (opts.metric) {
|
|
132
|
+
const query = { metric: opts.metric };
|
|
133
|
+
if (opts.groupBy)
|
|
134
|
+
query.group_by = opts.groupBy;
|
|
135
|
+
if (opts.range)
|
|
136
|
+
query.date_range = opts.range;
|
|
137
|
+
result = await client.executeAdHocQuery(projectId, query);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
console.error("Provide a query ID or --metric for ad-hoc execution.");
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
if (opts.json) {
|
|
144
|
+
output.json(result);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const results = result.results;
|
|
148
|
+
if (results.labels && results.datasets) {
|
|
149
|
+
for (const ds of results.datasets) {
|
|
150
|
+
console.log(ds.label);
|
|
151
|
+
output.table(["Label", "Value"], results.labels.map((l, i) => [l, output.formatNumber(ds.data[i])]));
|
|
152
|
+
console.log();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
output.json(results);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
queries
|
|
160
|
+
.command("delete")
|
|
161
|
+
.description("Delete a saved query")
|
|
162
|
+
.argument("<id>", "Query ID")
|
|
163
|
+
.option("--project <id>", "Project ID")
|
|
164
|
+
.option("--json", "Output as JSON")
|
|
165
|
+
.action(async (id, opts) => {
|
|
166
|
+
auth.requireToken();
|
|
167
|
+
const projectId = requireProjectId(opts.project);
|
|
168
|
+
await requireConfirmation(`Delete query ${id}`);
|
|
169
|
+
const data = await client.deleteInsight(projectId, id);
|
|
170
|
+
if (opts.json) {
|
|
171
|
+
output.json(data);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
console.log("Query deleted.");
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/commands/queries.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import * as client from "../client.js";
|
|
2
|
+
import * as auth from "../auth.js";
|
|
3
|
+
import * as output from "../output.js";
|
|
4
|
+
import { requireProjectId } from "../context.js";
|
|
5
|
+
import { requireConfirmation } from "../runtime.js";
|
|
6
|
+
export function registerRetentionCommands(program) {
|
|
7
|
+
const retention = program
|
|
8
|
+
.command("retention")
|
|
9
|
+
.description("Manage and execute retention analyses");
|
|
10
|
+
retention
|
|
11
|
+
.command("list")
|
|
12
|
+
.description("List saved retentions")
|
|
13
|
+
.option("--project <id>", "Project ID")
|
|
14
|
+
.option("--json", "Output as JSON")
|
|
15
|
+
.action(async (opts) => {
|
|
16
|
+
auth.requireToken();
|
|
17
|
+
const projectId = requireProjectId(opts.project);
|
|
18
|
+
const data = await client.listRetentions(projectId);
|
|
19
|
+
if (opts.json) {
|
|
20
|
+
output.json(data.retentions);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (data.retentions.length === 0) {
|
|
24
|
+
console.log("No retention analyses found.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
output.table(["ID", "Name", "Cohort Event", "Grain"], data.retentions.map((r) => [r.id, r.name, r.cohort_event, r.cohort_grain]));
|
|
28
|
+
});
|
|
29
|
+
retention
|
|
30
|
+
.command("create")
|
|
31
|
+
.description("Create a retention analysis")
|
|
32
|
+
.requiredOption("--name <name>", "Name")
|
|
33
|
+
.requiredOption("--cohort-event <event>", "Cohort event name")
|
|
34
|
+
.option("--retention-event <event>", "Retention event (null = any)")
|
|
35
|
+
.option("--grain <grain>", "Cohort grain (day, week, month)", "week")
|
|
36
|
+
.option("--days <days>", "Retention days (comma-separated)", "1,7,14,30")
|
|
37
|
+
.option("--range <range>", "Date range (e.g. 90d)")
|
|
38
|
+
.option("--project <id>", "Project ID")
|
|
39
|
+
.option("--json", "Output as JSON")
|
|
40
|
+
.action(async (opts) => {
|
|
41
|
+
auth.requireToken();
|
|
42
|
+
const projectId = requireProjectId(opts.project);
|
|
43
|
+
const attrs = {
|
|
44
|
+
name: opts.name,
|
|
45
|
+
cohort_event: opts.cohortEvent,
|
|
46
|
+
retention_event: opts.retentionEvent ?? null,
|
|
47
|
+
cohort_grain: opts.grain,
|
|
48
|
+
retention_days: opts.days.split(",").map((d) => parseInt(d.trim())),
|
|
49
|
+
};
|
|
50
|
+
if (opts.range)
|
|
51
|
+
attrs.date_range = opts.range;
|
|
52
|
+
const data = await client.createRetention(projectId, attrs);
|
|
53
|
+
if (opts.json) {
|
|
54
|
+
output.json(data.retention);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log(`Retention created: ${data.retention.name}`);
|
|
58
|
+
console.log(`ID: ${data.retention.id}`);
|
|
59
|
+
});
|
|
60
|
+
retention
|
|
61
|
+
.command("show")
|
|
62
|
+
.description("Show a saved retention analysis' full definition")
|
|
63
|
+
.argument("<id>", "Retention ID")
|
|
64
|
+
.option("--project <id>", "Project ID")
|
|
65
|
+
.option("--json", "Output as JSON")
|
|
66
|
+
.action(async (id, opts) => {
|
|
67
|
+
auth.requireToken();
|
|
68
|
+
const data = await client.getRetention(requireProjectId(opts.project), id);
|
|
69
|
+
if (opts.json) {
|
|
70
|
+
output.json(data.retention);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
console.log(`Retention: ${data.retention.name}`);
|
|
74
|
+
console.log(`Cohort event: ${data.retention.cohort_event}`);
|
|
75
|
+
console.log(`Days: ${data.retention.retention_days.join(", ")}`);
|
|
76
|
+
});
|
|
77
|
+
retention
|
|
78
|
+
.command("update")
|
|
79
|
+
.description("Update a saved retention analysis")
|
|
80
|
+
.argument("<id>", "Retention ID")
|
|
81
|
+
.option("--name <name>", "Name")
|
|
82
|
+
.option("--cohort-event <event>", "Cohort event name")
|
|
83
|
+
.option("--retention-event <event>", "Retention event name")
|
|
84
|
+
.option("--grain <grain>", "Cohort grain (day, week, month)")
|
|
85
|
+
.option("--days <days>", "Retention days (comma-separated)")
|
|
86
|
+
.option("--range <range>", "Date range (e.g. 90d)")
|
|
87
|
+
.option("--project <id>", "Project ID")
|
|
88
|
+
.option("--json", "Output as JSON")
|
|
89
|
+
.action(async (id, opts) => {
|
|
90
|
+
auth.requireToken();
|
|
91
|
+
const attrs = {};
|
|
92
|
+
if (opts.name)
|
|
93
|
+
attrs.name = opts.name;
|
|
94
|
+
if (opts.cohortEvent)
|
|
95
|
+
attrs.cohort_event = opts.cohortEvent;
|
|
96
|
+
if (opts.retentionEvent)
|
|
97
|
+
attrs.retention_event = opts.retentionEvent;
|
|
98
|
+
if (opts.grain)
|
|
99
|
+
attrs.cohort_grain = opts.grain;
|
|
100
|
+
if (opts.days) {
|
|
101
|
+
if (!/^\d+(,\d+)*$/.test(opts.days))
|
|
102
|
+
throw new Error("--days must be comma-separated whole numbers.");
|
|
103
|
+
attrs.retention_days = opts.days.split(",").map((day) => parseInt(day, 10));
|
|
104
|
+
}
|
|
105
|
+
if (opts.range)
|
|
106
|
+
attrs.date_range = opts.range;
|
|
107
|
+
if (Object.keys(attrs).length === 0)
|
|
108
|
+
throw new Error("Provide at least one field to update.");
|
|
109
|
+
const data = await client.updateRetention(requireProjectId(opts.project), id, attrs);
|
|
110
|
+
if (opts.json) {
|
|
111
|
+
output.json(data.retention);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
console.log(`Retention analysis updated: ${data.retention.name}`);
|
|
115
|
+
});
|
|
116
|
+
retention
|
|
117
|
+
.command("execute")
|
|
118
|
+
.description("Execute a saved retention analysis")
|
|
119
|
+
.argument("<id>", "Retention ID")
|
|
120
|
+
.option("--project <id>", "Project ID")
|
|
121
|
+
.option("--json", "Output as JSON")
|
|
122
|
+
.action(async (id, opts) => {
|
|
123
|
+
auth.requireToken();
|
|
124
|
+
const projectId = requireProjectId(opts.project);
|
|
125
|
+
const result = await client.executeRetention(projectId, id);
|
|
126
|
+
if (opts.json) {
|
|
127
|
+
output.json(result);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const results = result.results;
|
|
131
|
+
if (results.cohorts && results.periods) {
|
|
132
|
+
const headers = ["Cohort", "Size", ...results.periods];
|
|
133
|
+
const rows = results.cohorts.map((c) => [
|
|
134
|
+
c.cohort_date,
|
|
135
|
+
output.formatNumber(c.cohort_size),
|
|
136
|
+
...c.retention.map((r) => `${r}%`),
|
|
137
|
+
]);
|
|
138
|
+
output.table(headers, rows);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
output.json(results);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
retention
|
|
145
|
+
.command("delete")
|
|
146
|
+
.description("Delete a retention analysis")
|
|
147
|
+
.argument("<id>", "Retention ID")
|
|
148
|
+
.option("--project <id>", "Project ID")
|
|
149
|
+
.option("--json", "Output as JSON")
|
|
150
|
+
.action(async (id, opts) => {
|
|
151
|
+
auth.requireToken();
|
|
152
|
+
const projectId = requireProjectId(opts.project);
|
|
153
|
+
await requireConfirmation(`Delete retention analysis ${id}`);
|
|
154
|
+
const data = await client.deleteRetention(projectId, id);
|
|
155
|
+
if (opts.json) {
|
|
156
|
+
output.json(data);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
console.log("Retention analysis deleted.");
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=retention.js.map
|