@formo/cli 1.0.0 → 1.0.2
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 +89 -15
- package/dist/commands/alerts.d.ts +16 -3
- package/dist/commands/alerts.js +94 -24
- package/dist/commands/boards.d.ts +11 -2
- package/dist/commands/boards.js +49 -17
- package/dist/commands/charts.d.ts +30 -3
- package/dist/commands/charts.js +297 -33
- package/dist/commands/contracts.d.ts +17 -13
- package/dist/commands/contracts.js +165 -53
- package/dist/commands/events.d.ts +9 -0
- package/dist/commands/events.js +64 -0
- package/dist/commands/import.d.ts +8 -4
- package/dist/commands/import.js +33 -11
- package/dist/commands/profiles.d.ts +28 -2
- package/dist/commands/profiles.js +182 -16
- package/dist/commands/query.js +5 -1
- package/dist/commands/segments.d.ts +6 -2
- package/dist/commands/segments.js +19 -5
- package/dist/index.js +10 -3
- package/dist/lib/client.d.ts +10 -1
- package/dist/lib/client.js +27 -4
- package/dist/lib/config.js +10 -0
- package/dist/lib/json.d.ts +5 -0
- package/dist/lib/json.js +54 -0
- package/dist/lib/sql.d.ts +31 -0
- package/dist/lib/sql.js +151 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,6 +26,13 @@ export FORMO_API_KEY=formo_abc123
|
|
|
26
26
|
|
|
27
27
|
Get your API key from `Settings → API Keys` in the [Formo dashboard](https://app.formo.so).
|
|
28
28
|
|
|
29
|
+
For local development or proxying, override API hosts with:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
export FORMO_API_BASE_URL=http://localhost:3001
|
|
33
|
+
export FORMO_EVENTS_BASE_URL=http://localhost:3002
|
|
34
|
+
```
|
|
35
|
+
|
|
29
36
|
---
|
|
30
37
|
|
|
31
38
|
## Auth commands
|
|
@@ -114,6 +121,15 @@ formo profiles update vitalik.eth --properties '{"email":"alice@example.com"}'
|
|
|
114
121
|
|
|
115
122
|
> Requires `profiles:write` scope.
|
|
116
123
|
|
|
124
|
+
### `profiles properties batch`
|
|
125
|
+
|
|
126
|
+
Batch update first-party properties for up to 100 wallets.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
formo profiles properties batch \
|
|
130
|
+
--rows '[{"address":"0xd8dA...","display_name":"alice.eth","email":"alice@example.com"}]'
|
|
131
|
+
```
|
|
132
|
+
|
|
117
133
|
### `profiles labels create <address>`
|
|
118
134
|
|
|
119
135
|
Upsert one or more labels on a wallet profile. Provide either a single label via `--tag-id` or a batch via `--labels`.
|
|
@@ -123,12 +139,16 @@ Upsert one or more labels on a wallet profile. Provide either a single label via
|
|
|
123
139
|
| `--tag-id` | Label identifier (e.g. `vip`, `airdrop_eligible`) |
|
|
124
140
|
| `--value` | Optional label value (e.g. tier name, country code) |
|
|
125
141
|
| `--chain-id` | Optional chain identifier the label applies to |
|
|
142
|
+
| `--timestamp` | Optional historical ISO-8601 timestamp |
|
|
143
|
+
| `--is-deleted` | Backfill a historical label removal tombstone |
|
|
126
144
|
| `--labels` | JSON array of `UserLabelInput` objects for batch upsert |
|
|
127
145
|
|
|
128
146
|
```bash
|
|
129
147
|
formo profiles labels create 0xd8dA... --tag-id vip
|
|
130
148
|
formo profiles labels create 0xd8dA... --tag-id tier --value gold --chain-id 1
|
|
131
149
|
formo profiles labels create 0xd8dA... --labels '[{"tag_id":"vip"},{"tag_id":"airdrop_eligible","chain_id":"1"}]'
|
|
150
|
+
formo profiles labels create 0xd8dA... --tag-id tier --timestamp 2024-03-15T00:00:00.000Z --is-deleted
|
|
151
|
+
formo profiles labels batch --labels '[{"address":"0xd8dA...","tag_id":"vip","value":"tier-1"}]'
|
|
132
152
|
```
|
|
133
153
|
|
|
134
154
|
### `profiles labels delete <address>`
|
|
@@ -164,7 +184,7 @@ Get a single alert by ID.
|
|
|
164
184
|
| Option | Description |
|
|
165
185
|
|---|---|
|
|
166
186
|
| `--name` | Alert name |
|
|
167
|
-
| `--trigger-type` | Trigger type
|
|
187
|
+
| `--trigger-type` | Trigger type: `event` or `user` |
|
|
168
188
|
| `--trigger-filters` | JSON array of trigger filter objects |
|
|
169
189
|
| `--recipient` | JSON array of recipient objects |
|
|
170
190
|
| `--secret` | Webhook secret |
|
|
@@ -181,11 +201,18 @@ Same options as `create`. Replaces the alert configuration.
|
|
|
181
201
|
### `alerts delete <alertId>`
|
|
182
202
|
Delete an alert.
|
|
183
203
|
|
|
184
|
-
### `alerts toggle <alertId> --status <active|
|
|
185
|
-
Toggle an alert between `active` and `
|
|
204
|
+
### `alerts toggle <alertId> --status <active|inactive>`
|
|
205
|
+
Toggle an alert between `active` and `inactive`.
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
formo alerts toggle alert_abc123 --status inactive
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### `alerts test <alertId>`
|
|
212
|
+
Send a test alert delivery with optional sample payloads.
|
|
186
213
|
|
|
187
214
|
```bash
|
|
188
|
-
formo alerts
|
|
215
|
+
formo alerts test alert_abc123 --sample-event '{"event":"transaction","revenue":250}'
|
|
189
216
|
```
|
|
190
217
|
|
|
191
218
|
---
|
|
@@ -204,19 +231,21 @@ Get a single board by ID.
|
|
|
204
231
|
|
|
205
232
|
| Option | Description |
|
|
206
233
|
|---|---|
|
|
207
|
-
| `--
|
|
234
|
+
| `--title` | Board title |
|
|
208
235
|
| `--description` | Optional board description |
|
|
236
|
+
| `--is-public` | Make the board publicly viewable |
|
|
209
237
|
|
|
210
238
|
```bash
|
|
211
|
-
formo boards create --
|
|
239
|
+
formo boards create --title "Revenue Metrics" --description "Weekly revenue tracking"
|
|
212
240
|
```
|
|
213
241
|
|
|
214
242
|
### `boards update <boardId>`
|
|
215
243
|
|
|
216
244
|
| Option | Description |
|
|
217
245
|
|---|---|
|
|
218
|
-
| `--
|
|
246
|
+
| `--title` | New board title |
|
|
219
247
|
| `--description` | New board description |
|
|
248
|
+
| `--is-public` | Update public visibility |
|
|
220
249
|
|
|
221
250
|
### `boards delete <boardId>`
|
|
222
251
|
Delete a board.
|
|
@@ -233,12 +262,30 @@ List all charts in a board.
|
|
|
233
262
|
### `charts get <chartId> --board-id <boardId>`
|
|
234
263
|
Get a single chart by ID.
|
|
235
264
|
|
|
236
|
-
### `charts
|
|
237
|
-
|
|
265
|
+
### `charts meta --board-id <boardId>`
|
|
266
|
+
List lightweight chart metadata without executing chart queries.
|
|
267
|
+
|
|
268
|
+
### `charts create --board-id <boardId> [options]`
|
|
269
|
+
Create a chart from typed flags or a raw JSON body.
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
formo charts create --board-id brd_123 --title "Daily Active Users" \
|
|
273
|
+
--chart-type line \
|
|
274
|
+
--query "SELECT toDate(timestamp) AS date, countDistinct(address) AS users FROM events GROUP BY date ORDER BY date" \
|
|
275
|
+
--x-axis date --y-axis users
|
|
276
|
+
|
|
277
|
+
formo charts create --board-id brd_123 --body '{"title":"Recent Events","chart_type":"table","query":"SELECT * FROM events LIMIT 10"}'
|
|
278
|
+
```
|
|
238
279
|
|
|
239
280
|
### `charts update <chartId> --board-id <boardId> --body '<json>'`
|
|
240
281
|
Update a chart.
|
|
241
282
|
|
|
283
|
+
### `charts query <chartId> --board-id <boardId> --date-from <YYYY-MM-DD> --date-to <YYYY-MM-DD>`
|
|
284
|
+
Execute a saved chart that uses `{{date_from}}` / `{{date_to}}` variables.
|
|
285
|
+
|
|
286
|
+
### `charts move|duplicate|reorder`
|
|
287
|
+
Move a chart to another board, duplicate a chart, or reorder charts in a board.
|
|
288
|
+
|
|
242
289
|
### `charts delete <chartId> --board-id <boardId>`
|
|
243
290
|
Delete a chart.
|
|
244
291
|
|
|
@@ -251,6 +298,12 @@ Smart contract commands. Requires `contracts:read` / `contracts:write`.
|
|
|
251
298
|
### `contracts list`
|
|
252
299
|
List all tracked contracts. Returns `{ data: Contract[], deploy: { last_deployed_at, diff }, total, page, size, has_more }`.
|
|
253
300
|
|
|
301
|
+
### `contracts get <chain> <address>`
|
|
302
|
+
Get a single tracked contract.
|
|
303
|
+
|
|
304
|
+
### `contracts recommendations`
|
|
305
|
+
List contracts the project already interacts with but has not added yet.
|
|
306
|
+
|
|
254
307
|
### `contracts create`
|
|
255
308
|
|
|
256
309
|
| Option | Description |
|
|
@@ -258,13 +311,15 @@ List all tracked contracts. Returns `{ data: Contract[], deploy: { last_deployed
|
|
|
258
311
|
| `--address` | Contract address (`0x…`) |
|
|
259
312
|
| `--chain` | Chain ID (e.g. `1`, `137`) |
|
|
260
313
|
| `--name` | Human-readable contract name |
|
|
261
|
-
| `--abi` | Contract ABI as a JSON string |
|
|
262
|
-
| `--events` |
|
|
314
|
+
| `--abi` | Contract ABI as a JSON string; sent stringified to the API |
|
|
315
|
+
| `--events` | JSON array of ABI event objects to monitor |
|
|
316
|
+
| `--start-block` | Optional start block |
|
|
317
|
+
| `--include-in-pipeline` | Include this contract in the Goldsky events pipeline (`true` by default in the API) |
|
|
263
318
|
|
|
264
319
|
```bash
|
|
265
320
|
formo contracts create --address 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984 --chain 1 \
|
|
266
321
|
--name "UNI Token" --abi '[{"type":"event","name":"Transfer","inputs":[]}]' \
|
|
267
|
-
--events '{"Transfer":
|
|
322
|
+
--events '[{"type":"event","name":"Transfer","inputs":[]}]'
|
|
268
323
|
```
|
|
269
324
|
|
|
270
325
|
### `contracts update <chain> <address>`
|
|
@@ -273,7 +328,12 @@ formo contracts create --address 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984 --ch
|
|
|
273
328
|
|---|---|
|
|
274
329
|
| `--name` | Updated contract name |
|
|
275
330
|
| `--abi` | Updated ABI |
|
|
276
|
-
| `--events` | Updated
|
|
331
|
+
| `--events` | Updated JSON array of ABI event objects |
|
|
332
|
+
| `--start-block` | Optional start block |
|
|
333
|
+
| `--include-in-pipeline` | Include or exclude this contract from the Goldsky events pipeline |
|
|
334
|
+
|
|
335
|
+
### `contracts pipeline <chain> <address> --include-in-pipeline <true|false>`
|
|
336
|
+
Toggle pipeline inclusion without re-sending the full ABI/events payload.
|
|
277
337
|
|
|
278
338
|
### `contracts delete <chain> <address>`
|
|
279
339
|
Remove a tracked contract.
|
|
@@ -348,10 +408,24 @@ Bulk-import wallet addresses into the project via the events API.
|
|
|
348
408
|
| Option | Description |
|
|
349
409
|
|---|---|
|
|
350
410
|
| `--addresses` | JSON array of wallet address strings |
|
|
351
|
-
| `--
|
|
411
|
+
| `--rows` | JSON array of `{address,properties?}` objects |
|
|
412
|
+
|
|
413
|
+
```bash
|
|
414
|
+
formo import wallets --addresses '["0xabc...","0xdef..."]'
|
|
415
|
+
formo import wallets --rows '[{"address":"0xabc...","properties":{"display_name":"Alice"}}]'
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## `formo events`
|
|
421
|
+
|
|
422
|
+
### `events ingest`
|
|
423
|
+
|
|
424
|
+
Send raw analytics events to `events.formo.so`. This command uses a project SDK write key, not the workspace API key.
|
|
352
425
|
|
|
353
426
|
```bash
|
|
354
|
-
|
|
427
|
+
export FORMO_WRITE_KEY=formo_write_key_xxx
|
|
428
|
+
formo events ingest --event '{"type":"track","channel":"cli","version":"1","anonymous_id":"anon_123","event":"CLI Test","context":{},"properties":{},"original_timestamp":"2026-04-27T23:05:38.000Z","sent_at":"2026-04-27T23:05:42.000Z","message_id":"cli-test-1"}'
|
|
355
429
|
```
|
|
356
430
|
|
|
357
431
|
---
|
|
@@ -1,23 +1,36 @@
|
|
|
1
1
|
import { Cli } from 'incur';
|
|
2
2
|
export declare const alerts: Cli.Cli<{}, undefined, undefined>;
|
|
3
|
-
export
|
|
3
|
+
export interface PaginationOptions {
|
|
4
|
+
page?: number;
|
|
5
|
+
size?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function listAlertsRun(options?: PaginationOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
4
8
|
export declare function getAlertRun(alertId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
5
9
|
export interface CreateAlertOptions {
|
|
6
10
|
name: string;
|
|
7
|
-
triggerType: string;
|
|
11
|
+
triggerType: 'event' | 'user' | string;
|
|
8
12
|
triggerFilters?: string;
|
|
9
13
|
recipient?: string;
|
|
10
14
|
secret?: string;
|
|
15
|
+
slackPropertyKeys?: string;
|
|
11
16
|
}
|
|
12
17
|
export declare function buildAlertBody(options: CreateAlertOptions | UpdateAlertOptions): Record<string, unknown>;
|
|
13
18
|
export declare function createAlertRun(options: CreateAlertOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
14
19
|
export interface UpdateAlertOptions {
|
|
15
20
|
name: string;
|
|
16
|
-
triggerType: string;
|
|
21
|
+
triggerType: 'event' | 'user' | string;
|
|
17
22
|
triggerFilters?: string;
|
|
18
23
|
recipient?: string;
|
|
19
24
|
secret?: string;
|
|
25
|
+
slackPropertyKeys?: string;
|
|
20
26
|
}
|
|
21
27
|
export declare function updateAlertRun(alertId: string, options: UpdateAlertOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
22
28
|
export declare function deleteAlertRun(alertId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
23
29
|
export declare function toggleAlertRun(alertId: string, status: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
30
|
+
export interface TestAlertOptions {
|
|
31
|
+
sampleEvent?: string;
|
|
32
|
+
sampleUser?: string;
|
|
33
|
+
recipientOverrides?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function buildTestAlertBody(options: TestAlertOptions): Record<string, unknown> | undefined;
|
|
36
|
+
export declare function testAlertRun(alertId: string, options?: TestAlertOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
package/dist/commands/alerts.js
CHANGED
|
@@ -8,23 +8,37 @@ exports.createAlertRun = createAlertRun;
|
|
|
8
8
|
exports.updateAlertRun = updateAlertRun;
|
|
9
9
|
exports.deleteAlertRun = deleteAlertRun;
|
|
10
10
|
exports.toggleAlertRun = toggleAlertRun;
|
|
11
|
+
exports.buildTestAlertBody = buildTestAlertBody;
|
|
12
|
+
exports.testAlertRun = testAlertRun;
|
|
11
13
|
const incur_1 = require("incur");
|
|
12
14
|
const client_1 = require("../lib/client");
|
|
15
|
+
const json_1 = require("../lib/json");
|
|
13
16
|
exports.alerts = incur_1.Cli.create('alerts', {
|
|
14
17
|
description: 'Project alert commands — create, list, update, and delete alerts',
|
|
15
18
|
});
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
function buildPaginationParams(options = {}) {
|
|
20
|
+
const params = {};
|
|
21
|
+
if (options.page !== undefined)
|
|
22
|
+
params.page = options.page;
|
|
23
|
+
if (options.size !== undefined)
|
|
24
|
+
params.size = options.size;
|
|
25
|
+
return params;
|
|
26
|
+
}
|
|
27
|
+
function listAlertsRun(options = {}) {
|
|
18
28
|
(0, client_1.requireApiKey)();
|
|
19
29
|
const client = (0, client_1.createClient)();
|
|
20
|
-
return client.get('/v0/alerts/');
|
|
30
|
+
return client.get('/v0/alerts/', { params: buildPaginationParams(options) });
|
|
21
31
|
}
|
|
22
32
|
exports.alerts.command('list', {
|
|
23
33
|
description: 'List all alerts for the project',
|
|
34
|
+
options: incur_1.z.object({
|
|
35
|
+
page: incur_1.z.coerce.number().optional().describe('Page number (1-indexed, default 1)'),
|
|
36
|
+
size: incur_1.z.coerce.number().optional().describe('Page size (default 100, max 200)'),
|
|
37
|
+
}),
|
|
24
38
|
examples: [{ description: 'List all project alerts' }],
|
|
25
39
|
hint: 'Requires alerts:read scope on your API key.',
|
|
26
|
-
run() {
|
|
27
|
-
return listAlertsRun();
|
|
40
|
+
run({ options }) {
|
|
41
|
+
return listAlertsRun(options);
|
|
28
42
|
},
|
|
29
43
|
});
|
|
30
44
|
// ── Get a single alert ──
|
|
@@ -50,26 +64,20 @@ function buildAlertBody(options) {
|
|
|
50
64
|
const body = {
|
|
51
65
|
name: options.name,
|
|
52
66
|
trigger_type: options.triggerType,
|
|
67
|
+
trigger_filters: [],
|
|
53
68
|
};
|
|
54
69
|
if (options.triggerFilters) {
|
|
55
|
-
|
|
56
|
-
body.trigger_filters = JSON.parse(options.triggerFilters);
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
throw new Error('--trigger-filters must be a valid JSON array');
|
|
60
|
-
}
|
|
70
|
+
body.trigger_filters = (0, json_1.parseJsonArray)(options.triggerFilters, '--trigger-filters');
|
|
61
71
|
}
|
|
62
72
|
if (options.recipient) {
|
|
63
|
-
|
|
64
|
-
body.recipient = JSON.parse(options.recipient);
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
throw new Error('--recipient must be a valid JSON array');
|
|
68
|
-
}
|
|
73
|
+
body.recipient = (0, json_1.parseJsonArray)(options.recipient, '--recipient');
|
|
69
74
|
}
|
|
70
75
|
if (options.secret !== undefined) {
|
|
71
76
|
body.secret = options.secret;
|
|
72
77
|
}
|
|
78
|
+
if (options.slackPropertyKeys !== undefined) {
|
|
79
|
+
body.slack_property_keys = (0, json_1.parseJsonArray)(options.slackPropertyKeys, '--slack-property-keys');
|
|
80
|
+
}
|
|
73
81
|
return body;
|
|
74
82
|
}
|
|
75
83
|
function createAlertRun(options) {
|
|
@@ -81,7 +89,7 @@ exports.alerts.command('create', {
|
|
|
81
89
|
description: 'Create a new project alert',
|
|
82
90
|
options: incur_1.z.object({
|
|
83
91
|
name: incur_1.z.string().describe('Alert name'),
|
|
84
|
-
triggerType: incur_1.z.
|
|
92
|
+
triggerType: incur_1.z.enum(['event', 'user']).describe('Trigger type'),
|
|
85
93
|
triggerFilters: incur_1.z
|
|
86
94
|
.string()
|
|
87
95
|
.optional()
|
|
@@ -91,6 +99,10 @@ exports.alerts.command('create', {
|
|
|
91
99
|
.optional()
|
|
92
100
|
.describe('JSON array of recipient objects'),
|
|
93
101
|
secret: incur_1.z.string().optional().describe('Webhook secret for the alert'),
|
|
102
|
+
slackPropertyKeys: incur_1.z
|
|
103
|
+
.string()
|
|
104
|
+
.optional()
|
|
105
|
+
.describe('JSON array of event/user property keys to include in Slack alerts'),
|
|
94
106
|
}),
|
|
95
107
|
examples: [
|
|
96
108
|
{
|
|
@@ -115,7 +127,7 @@ exports.alerts.command('update', {
|
|
|
115
127
|
}),
|
|
116
128
|
options: incur_1.z.object({
|
|
117
129
|
name: incur_1.z.string().describe('Alert name'),
|
|
118
|
-
triggerType: incur_1.z.
|
|
130
|
+
triggerType: incur_1.z.enum(['event', 'user']).describe('Trigger type'),
|
|
119
131
|
triggerFilters: incur_1.z
|
|
120
132
|
.string()
|
|
121
133
|
.optional()
|
|
@@ -125,6 +137,10 @@ exports.alerts.command('update', {
|
|
|
125
137
|
.optional()
|
|
126
138
|
.describe('JSON array of recipient objects'),
|
|
127
139
|
secret: incur_1.z.string().optional().describe('Webhook secret for the alert'),
|
|
140
|
+
slackPropertyKeys: incur_1.z
|
|
141
|
+
.string()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe('JSON array of event/user property keys to include in Slack alerts'),
|
|
128
144
|
}),
|
|
129
145
|
examples: [
|
|
130
146
|
{
|
|
@@ -161,21 +177,24 @@ exports.alerts.command('delete', {
|
|
|
161
177
|
function toggleAlertRun(alertId, status) {
|
|
162
178
|
(0, client_1.requireApiKey)();
|
|
163
179
|
const client = (0, client_1.createClient)();
|
|
164
|
-
|
|
180
|
+
const normalizedStatus = status === 'paused' ? 'inactive' : status;
|
|
181
|
+
return client.patch(`/v0/alerts/${encodeURIComponent(alertId)}`, {
|
|
182
|
+
status: normalizedStatus,
|
|
183
|
+
});
|
|
165
184
|
}
|
|
166
185
|
exports.alerts.command('toggle', {
|
|
167
|
-
description: 'Toggle an alert status (active/
|
|
186
|
+
description: 'Toggle an alert status (active/inactive)',
|
|
168
187
|
args: incur_1.z.object({
|
|
169
188
|
alertId: incur_1.z.string().describe('Alert ID to toggle'),
|
|
170
189
|
}),
|
|
171
190
|
options: incur_1.z.object({
|
|
172
|
-
status: incur_1.z.enum(['active', 'paused']).describe('New status'),
|
|
191
|
+
status: incur_1.z.enum(['active', 'inactive', 'paused']).describe('New status. "paused" is accepted as a deprecated alias for "inactive".'),
|
|
173
192
|
}),
|
|
174
193
|
examples: [
|
|
175
194
|
{
|
|
176
195
|
args: { alertId: 'alert_abc123' },
|
|
177
|
-
options: { status: '
|
|
178
|
-
description: '
|
|
196
|
+
options: { status: 'inactive' },
|
|
197
|
+
description: 'Deactivate an alert',
|
|
179
198
|
},
|
|
180
199
|
],
|
|
181
200
|
hint: 'Requires alerts:write scope on your API key.',
|
|
@@ -183,3 +202,54 @@ exports.alerts.command('toggle', {
|
|
|
183
202
|
return toggleAlertRun(args.alertId, options.status);
|
|
184
203
|
},
|
|
185
204
|
});
|
|
205
|
+
function buildTestAlertBody(options) {
|
|
206
|
+
const body = {};
|
|
207
|
+
if (options.sampleEvent !== undefined) {
|
|
208
|
+
body.sampleEvent = (0, json_1.parseJsonObject)(options.sampleEvent, '--sample-event');
|
|
209
|
+
}
|
|
210
|
+
if (options.sampleUser !== undefined) {
|
|
211
|
+
body.sampleUser = (0, json_1.parseJsonObject)(options.sampleUser, '--sample-user');
|
|
212
|
+
}
|
|
213
|
+
if (options.recipientOverrides !== undefined) {
|
|
214
|
+
body.recipientOverrides = (0, json_1.parseJsonArray)(options.recipientOverrides, '--recipient-overrides');
|
|
215
|
+
}
|
|
216
|
+
return Object.keys(body).length > 0 ? body : undefined;
|
|
217
|
+
}
|
|
218
|
+
function testAlertRun(alertId, options = {}) {
|
|
219
|
+
(0, client_1.requireApiKey)();
|
|
220
|
+
const client = (0, client_1.createClient)();
|
|
221
|
+
return client.post(`/v0/alerts/${encodeURIComponent(alertId)}/test`, buildTestAlertBody(options));
|
|
222
|
+
}
|
|
223
|
+
exports.alerts.command('test', {
|
|
224
|
+
description: 'Send a test delivery for an alert',
|
|
225
|
+
args: incur_1.z.object({
|
|
226
|
+
alertId: incur_1.z.string().describe('Alert ID to test'),
|
|
227
|
+
}),
|
|
228
|
+
options: incur_1.z.object({
|
|
229
|
+
sampleEvent: incur_1.z
|
|
230
|
+
.string()
|
|
231
|
+
.optional()
|
|
232
|
+
.describe('Optional JSON object to use as the sample event'),
|
|
233
|
+
sampleUser: incur_1.z
|
|
234
|
+
.string()
|
|
235
|
+
.optional()
|
|
236
|
+
.describe('Optional JSON object to use as the sample user/profile'),
|
|
237
|
+
recipientOverrides: incur_1.z
|
|
238
|
+
.string()
|
|
239
|
+
.optional()
|
|
240
|
+
.describe('Optional JSON array of recipient objects to test instead of saved recipients'),
|
|
241
|
+
}),
|
|
242
|
+
examples: [
|
|
243
|
+
{
|
|
244
|
+
args: { alertId: 'alert_abc123' },
|
|
245
|
+
options: {
|
|
246
|
+
sampleEvent: '{"event":"transaction","revenue":250}',
|
|
247
|
+
},
|
|
248
|
+
description: 'Send a test alert with a sample event',
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
hint: 'Requires alerts:write scope on your API key.',
|
|
252
|
+
run({ args, options }) {
|
|
253
|
+
return testAlertRun(args.alertId, options);
|
|
254
|
+
},
|
|
255
|
+
});
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import { Cli } from 'incur';
|
|
2
2
|
export declare const boards: Cli.Cli<{}, undefined, undefined>;
|
|
3
|
-
export
|
|
3
|
+
export interface PaginationOptions {
|
|
4
|
+
page?: number;
|
|
5
|
+
size?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function listBoardsRun(options?: PaginationOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
4
8
|
export declare function getBoardRun(boardId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
5
9
|
export interface CreateBoardOptions {
|
|
6
|
-
|
|
10
|
+
title?: string;
|
|
11
|
+
name?: string;
|
|
7
12
|
description?: string;
|
|
13
|
+
isPublic?: boolean;
|
|
8
14
|
}
|
|
15
|
+
export declare function buildBoardBody(options: CreateBoardOptions | UpdateBoardOptions): Record<string, unknown>;
|
|
9
16
|
export declare function createBoardRun(options: CreateBoardOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
10
17
|
export interface UpdateBoardOptions {
|
|
18
|
+
title?: string;
|
|
11
19
|
name?: string;
|
|
12
20
|
description?: string;
|
|
21
|
+
isPublic?: boolean;
|
|
13
22
|
}
|
|
14
23
|
export declare function updateBoardRun(boardId: string, options: UpdateBoardOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
15
24
|
export declare function deleteBoardRun(boardId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
package/dist/commands/boards.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.boards = void 0;
|
|
4
4
|
exports.listBoardsRun = listBoardsRun;
|
|
5
5
|
exports.getBoardRun = getBoardRun;
|
|
6
|
+
exports.buildBoardBody = buildBoardBody;
|
|
6
7
|
exports.createBoardRun = createBoardRun;
|
|
7
8
|
exports.updateBoardRun = updateBoardRun;
|
|
8
9
|
exports.deleteBoardRun = deleteBoardRun;
|
|
@@ -11,18 +12,30 @@ const client_1 = require("../lib/client");
|
|
|
11
12
|
exports.boards = incur_1.Cli.create('boards', {
|
|
12
13
|
description: 'Dashboard board commands — create, list, update, and delete boards',
|
|
13
14
|
});
|
|
15
|
+
function buildPaginationParams(options = {}) {
|
|
16
|
+
const params = {};
|
|
17
|
+
if (options.page !== undefined)
|
|
18
|
+
params.page = options.page;
|
|
19
|
+
if (options.size !== undefined)
|
|
20
|
+
params.size = options.size;
|
|
21
|
+
return params;
|
|
22
|
+
}
|
|
14
23
|
// ── List boards ──
|
|
15
|
-
function listBoardsRun() {
|
|
24
|
+
function listBoardsRun(options = {}) {
|
|
16
25
|
(0, client_1.requireApiKey)();
|
|
17
26
|
const client = (0, client_1.createClient)();
|
|
18
|
-
return client.get('/v0/boards/');
|
|
27
|
+
return client.get('/v0/boards/', { params: buildPaginationParams(options) });
|
|
19
28
|
}
|
|
20
29
|
exports.boards.command('list', {
|
|
21
30
|
description: 'List all boards for the project',
|
|
31
|
+
options: incur_1.z.object({
|
|
32
|
+
page: incur_1.z.coerce.number().optional().describe('Page number (1-indexed, default 1)'),
|
|
33
|
+
size: incur_1.z.coerce.number().optional().describe('Page size (default 100, max 200)'),
|
|
34
|
+
}),
|
|
22
35
|
examples: [{ description: 'List all dashboard boards' }],
|
|
23
36
|
hint: 'Requires boards:read scope on your API key.',
|
|
24
|
-
run() {
|
|
25
|
-
return listBoardsRun();
|
|
37
|
+
run({ options }) {
|
|
38
|
+
return listBoardsRun(options);
|
|
26
39
|
},
|
|
27
40
|
});
|
|
28
41
|
// ── Get a single board ──
|
|
@@ -44,28 +57,46 @@ exports.boards.command('get', {
|
|
|
44
57
|
return getBoardRun(args.boardId);
|
|
45
58
|
},
|
|
46
59
|
});
|
|
60
|
+
function buildBoardBody(options) {
|
|
61
|
+
const title = options.title ?? options.name;
|
|
62
|
+
const body = {};
|
|
63
|
+
if (title !== undefined) {
|
|
64
|
+
if (!title)
|
|
65
|
+
throw new Error('--title must not be empty');
|
|
66
|
+
body.title = title;
|
|
67
|
+
}
|
|
68
|
+
if (options.description !== undefined) {
|
|
69
|
+
body.description = options.description;
|
|
70
|
+
}
|
|
71
|
+
if (options.isPublic !== undefined) {
|
|
72
|
+
body.isPublic = options.isPublic;
|
|
73
|
+
}
|
|
74
|
+
return body;
|
|
75
|
+
}
|
|
47
76
|
function createBoardRun(options) {
|
|
48
77
|
(0, client_1.requireApiKey)();
|
|
49
78
|
const client = (0, client_1.createClient)();
|
|
50
|
-
const body =
|
|
51
|
-
if (
|
|
52
|
-
|
|
79
|
+
const body = buildBoardBody(options);
|
|
80
|
+
if (!body.title) {
|
|
81
|
+
throw new Error('Provide --title for the board name');
|
|
53
82
|
}
|
|
54
83
|
return client.post('/v0/boards/', body);
|
|
55
84
|
}
|
|
56
85
|
exports.boards.command('create', {
|
|
57
86
|
description: 'Create a new dashboard board',
|
|
58
87
|
options: incur_1.z.object({
|
|
59
|
-
|
|
88
|
+
title: incur_1.z.string().optional().describe('Board title'),
|
|
89
|
+
name: incur_1.z.string().optional().describe('Deprecated alias for --title').meta({ deprecated: true }),
|
|
60
90
|
description: incur_1.z.string().optional().describe('Board description'),
|
|
91
|
+
isPublic: incur_1.z.boolean().optional().describe('Whether the board is publicly viewable'),
|
|
61
92
|
}),
|
|
62
93
|
examples: [
|
|
63
94
|
{
|
|
64
|
-
options: {
|
|
95
|
+
options: { title: 'KPI Dashboard' },
|
|
65
96
|
description: 'Create a board',
|
|
66
97
|
},
|
|
67
98
|
{
|
|
68
|
-
options: {
|
|
99
|
+
options: { title: 'Revenue Metrics', description: 'Weekly revenue tracking' },
|
|
69
100
|
description: 'Create a board with description',
|
|
70
101
|
},
|
|
71
102
|
],
|
|
@@ -77,11 +108,10 @@ exports.boards.command('create', {
|
|
|
77
108
|
function updateBoardRun(boardId, options) {
|
|
78
109
|
(0, client_1.requireApiKey)();
|
|
79
110
|
const client = (0, client_1.createClient)();
|
|
80
|
-
const body =
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
body.description = options.description;
|
|
111
|
+
const body = buildBoardBody(options);
|
|
112
|
+
if (Object.keys(body).length === 0) {
|
|
113
|
+
throw new Error('Provide at least one of --title, --description, or --is-public');
|
|
114
|
+
}
|
|
85
115
|
return client.patch(`/v0/boards/${encodeURIComponent(boardId)}`, body);
|
|
86
116
|
}
|
|
87
117
|
exports.boards.command('update', {
|
|
@@ -90,13 +120,15 @@ exports.boards.command('update', {
|
|
|
90
120
|
boardId: incur_1.z.string().describe('Board ID to update'),
|
|
91
121
|
}),
|
|
92
122
|
options: incur_1.z.object({
|
|
93
|
-
|
|
123
|
+
title: incur_1.z.string().optional().describe('New board title'),
|
|
124
|
+
name: incur_1.z.string().optional().describe('Deprecated alias for --title').meta({ deprecated: true }),
|
|
94
125
|
description: incur_1.z.string().optional().describe('New board description'),
|
|
126
|
+
isPublic: incur_1.z.boolean().optional().describe('Whether the board is publicly viewable'),
|
|
95
127
|
}),
|
|
96
128
|
examples: [
|
|
97
129
|
{
|
|
98
130
|
args: { boardId: 'board_abc123' },
|
|
99
|
-
options: {
|
|
131
|
+
options: { title: 'Renamed Board' },
|
|
100
132
|
description: 'Rename a board',
|
|
101
133
|
},
|
|
102
134
|
],
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
import { Cli } from 'incur';
|
|
2
2
|
export declare const charts: Cli.Cli<{}, undefined, undefined>;
|
|
3
|
-
export
|
|
3
|
+
export interface PaginationOptions {
|
|
4
|
+
page?: number;
|
|
5
|
+
size?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ChartBodyOptions {
|
|
8
|
+
body?: string;
|
|
9
|
+
query?: string;
|
|
10
|
+
chartType?: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
xAxis?: string;
|
|
14
|
+
yAxis?: string;
|
|
15
|
+
groupBy?: string;
|
|
16
|
+
steps?: string;
|
|
17
|
+
settings?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function buildChartBody(options: ChartBodyOptions): Record<string, unknown>;
|
|
20
|
+
export declare function listChartsRun(boardId: string, options?: PaginationOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
21
|
+
export declare function listChartSummariesRun(boardId: string, options?: PaginationOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
4
22
|
export declare function getChartRun(boardId: string, chartId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
5
|
-
export
|
|
6
|
-
|
|
23
|
+
export interface QueryChartOptions {
|
|
24
|
+
dateFrom: string;
|
|
25
|
+
dateTo: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function queryChartRun(boardId: string, chartId: string, options: QueryChartOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
28
|
+
export declare function createChartRun(boardId: string, input: string | ChartBodyOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
29
|
+
export declare function updateChartRun(boardId: string, chartId: string, input: string | ChartBodyOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
30
|
+
export declare function moveChartRun(boardId: string, chartId: string, targetBoardId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
31
|
+
export declare function normalizeDuplicateChartResponse(result: unknown): unknown;
|
|
32
|
+
export declare function duplicateChartRun(boardId: string, chartId: string): Promise<unknown>;
|
|
33
|
+
export declare function reorderChartsRun(boardId: string, chartIds: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
7
34
|
export declare function deleteChartRun(boardId: string, chartId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
|