@formo/cli 0.1.0 → 1.0.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 +328 -44
- package/dist/commands/alerts.d.ts +1 -0
- package/dist/commands/alerts.js +11 -30
- package/dist/commands/analytics.d.ts +25 -0
- package/dist/commands/analytics.js +153 -0
- package/dist/commands/contracts.d.ts +12 -0
- package/dist/commands/contracts.js +18 -10
- package/dist/commands/import.d.ts +4 -0
- package/dist/commands/import.js +9 -5
- package/dist/commands/profiles.d.ts +29 -2
- package/dist/commands/profiles.js +257 -25
- package/dist/commands/query.d.ts +2 -0
- package/dist/commands/query.js +25 -0
- package/dist/commands/segments.d.ts +4 -0
- package/dist/commands/segments.js +10 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +117 -132
- package/dist/lib/client.d.ts +26 -0
- package/dist/lib/client.js +30 -7
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @formo/cli
|
|
2
2
|
|
|
3
|
-
Command-line interface for the Formo API.
|
|
3
|
+
Command-line interface for the Formo API. Manage wallet profiles, alerts, dashboards, charts, contracts, segments, and run analytics SQL — directly from your terminal or via AI agents.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ npx @formo/cli
|
|
|
12
12
|
|
|
13
13
|
## Authentication
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Save your API key locally:
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
formo login <apiKey>
|
|
@@ -24,101 +24,385 @@ Or set the `FORMO_API_KEY` environment variable — it takes precedence over the
|
|
|
24
24
|
export FORMO_API_KEY=formo_abc123
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Get your API key from `Settings → API Keys` in the [Formo dashboard](https://app.formo.so).
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
---
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
## Auth commands
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
### `formo login [apiKey]`
|
|
34
|
+
|
|
35
|
+
Save your API key to `~/.config/formo/config.json`. Validates the key against the API and stores the workspace context.
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
formo login formo_abc123
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
### `formo logout`
|
|
42
|
+
|
|
43
|
+
Remove the saved API key and clear authentication state.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
formo logout
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `formo status`
|
|
50
|
+
|
|
51
|
+
Show current authentication state, workspace, and project ID.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
formo status
|
|
55
|
+
```
|
|
56
|
+
|
|
41
57
|
---
|
|
42
58
|
|
|
43
|
-
|
|
59
|
+
## `formo profiles`
|
|
44
60
|
|
|
45
|
-
|
|
61
|
+
Wallet profile commands.
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
### `profiles get <address>`
|
|
64
|
+
|
|
65
|
+
Fetch a single wallet profile by address or ENS name.
|
|
50
66
|
|
|
51
67
|
| Option | Description |
|
|
52
68
|
|---|---|
|
|
53
|
-
| `--expand` | Comma-separated fields
|
|
69
|
+
| `--expand` | Comma-separated fields: `apps`, `chains`, `tokens`, `labels` |
|
|
54
70
|
|
|
55
71
|
```bash
|
|
56
72
|
formo profiles get 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
|
|
57
73
|
formo profiles get vitalik.eth --expand labels,chains
|
|
58
74
|
```
|
|
59
75
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
### `formo profiles search`
|
|
76
|
+
### `profiles search`
|
|
63
77
|
|
|
64
|
-
Search wallet profiles with
|
|
78
|
+
Search wallet profiles with filters, sorting, and pagination. Returns a `PaginatedResponse<Profile>`.
|
|
65
79
|
|
|
66
80
|
| Option | Description |
|
|
67
81
|
|---|---|
|
|
68
82
|
| `--address` | Filter by wallet address |
|
|
69
|
-
| `--
|
|
70
|
-
| `--
|
|
71
|
-
| `--
|
|
72
|
-
| `--
|
|
83
|
+
| `--page` | Page number (1-indexed, default `1`) |
|
|
84
|
+
| `--size` | Page size (default `100`, max `1000`) |
|
|
85
|
+
| `--order-by` | `last_onchain`, `first_onchain`, `net_worth_usd`, `updated_at`, `tx_count`, `first_seen`, `last_seen`, `num_sessions`, `revenue`, `volume`, `points` |
|
|
86
|
+
| `--order-dir` | `asc` or `desc` |
|
|
73
87
|
| `--expand` | Comma-separated fields to expand |
|
|
74
88
|
| `--conditions` | JSON array of `FilterCondition` objects (see below) |
|
|
89
|
+
| `--logic` | Combine conditions with `and` (default) or `or` |
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
formo profiles search --size 10
|
|
93
|
+
formo profiles search --order-by net_worth_usd --order-dir desc --size 5
|
|
94
|
+
formo profiles search --page 2 --size 20
|
|
95
|
+
formo profiles search --conditions '[{"field":"users.net_worth_usd","op":"gt","value":10000}]' --size 20
|
|
96
|
+
formo profiles search --conditions '[{"field":"users.net_worth_usd","op":"gt","value":10000},{"field":"users.volume","op":"gt","value":1000}]' --logic or --size 20
|
|
97
|
+
formo profiles search --conditions '[{"field":"chains.1.balance","op":"gt","value":1000}]' --size 20
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### `profiles update <address>`
|
|
101
|
+
|
|
102
|
+
Merge-update identity properties on a wallet profile.
|
|
103
|
+
|
|
104
|
+
| Option | Description |
|
|
105
|
+
|---|---|
|
|
106
|
+
| `--properties` | JSON object of properties to merge |
|
|
107
|
+
|
|
108
|
+
**Allowed property keys:** `user_id`, `display_name`, `email`, `farcaster`, `discord`, `twitter`, `telegram`, `instagram`, `website`, `github`, `linkedin`, `facebook`, `tiktok`, `youtube`, `reddit`, `avatar`, `description`, `location`, `ens`, `lens`, `basenames`, `linea`. Unknown keys are rejected server-side.
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
formo profiles update 0xd8dA... --properties '{"display_name":"Vitalik","twitter":"VitalikButerin"}'
|
|
112
|
+
formo profiles update vitalik.eth --properties '{"email":"alice@example.com"}'
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
> Requires `profiles:write` scope.
|
|
116
|
+
|
|
117
|
+
### `profiles labels create <address>`
|
|
118
|
+
|
|
119
|
+
Upsert one or more labels on a wallet profile. Provide either a single label via `--tag-id` or a batch via `--labels`.
|
|
120
|
+
|
|
121
|
+
| Option | Description |
|
|
122
|
+
|---|---|
|
|
123
|
+
| `--tag-id` | Label identifier (e.g. `vip`, `airdrop_eligible`) |
|
|
124
|
+
| `--value` | Optional label value (e.g. tier name, country code) |
|
|
125
|
+
| `--chain-id` | Optional chain identifier the label applies to |
|
|
126
|
+
| `--labels` | JSON array of `UserLabelInput` objects for batch upsert |
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
formo profiles labels create 0xd8dA... --tag-id vip
|
|
130
|
+
formo profiles labels create 0xd8dA... --tag-id tier --value gold --chain-id 1
|
|
131
|
+
formo profiles labels create 0xd8dA... --labels '[{"tag_id":"vip"},{"tag_id":"airdrop_eligible","chain_id":"1"}]'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `profiles labels delete <address>`
|
|
135
|
+
|
|
136
|
+
Delete a label from a wallet profile.
|
|
137
|
+
|
|
138
|
+
| Option | Description |
|
|
139
|
+
|---|---|
|
|
140
|
+
| `--tag-id` | Label identifier to delete (required) |
|
|
141
|
+
| `--chain-id` | Optional chain identifier to scope the deletion |
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
formo profiles labels delete 0xd8dA... --tag-id vip
|
|
145
|
+
formo profiles labels delete 0xd8dA... --tag-id tier --chain-id 1
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
> Requires `profiles:write` scope.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## `formo alerts`
|
|
153
|
+
|
|
154
|
+
Project alert commands. Requires `alerts:read` (list/get) or `alerts:write` (create/update/delete/toggle).
|
|
155
|
+
|
|
156
|
+
### `alerts list`
|
|
157
|
+
List all alerts for the project.
|
|
158
|
+
|
|
159
|
+
### `alerts get <alertId>`
|
|
160
|
+
Get a single alert by ID.
|
|
161
|
+
|
|
162
|
+
### `alerts create`
|
|
163
|
+
|
|
164
|
+
| Option | Description |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `--name` | Alert name |
|
|
167
|
+
| `--trigger-type` | Trigger type (e.g. `event`, `threshold`) |
|
|
168
|
+
| `--trigger-filters` | JSON array of trigger filter objects |
|
|
169
|
+
| `--recipient` | JSON array of recipient objects |
|
|
170
|
+
| `--secret` | Webhook secret |
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
formo alerts create --name "High value tx" --trigger-type event \
|
|
174
|
+
--trigger-filters '[{"name":"event","operator":"equals","value":"transaction"}]' \
|
|
175
|
+
--recipient '[{"type":"email","value":["alerts@myapp.com"]}]'
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### `alerts update <alertId>`
|
|
179
|
+
Same options as `create`. Replaces the alert configuration.
|
|
180
|
+
|
|
181
|
+
### `alerts delete <alertId>`
|
|
182
|
+
Delete an alert.
|
|
183
|
+
|
|
184
|
+
### `alerts toggle <alertId> --status <active|paused>`
|
|
185
|
+
Toggle an alert between `active` and `paused`.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
formo alerts toggle alert_abc123 --status paused
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## `formo boards`
|
|
194
|
+
|
|
195
|
+
Dashboard board commands. Requires `boards:read` / `boards:write`.
|
|
196
|
+
|
|
197
|
+
### `boards list`
|
|
198
|
+
List all boards for the project.
|
|
199
|
+
|
|
200
|
+
### `boards get <boardId>`
|
|
201
|
+
Get a single board by ID.
|
|
202
|
+
|
|
203
|
+
### `boards create`
|
|
75
204
|
|
|
76
|
-
|
|
205
|
+
| Option | Description |
|
|
206
|
+
|---|---|
|
|
207
|
+
| `--name` | Board name |
|
|
208
|
+
| `--description` | Optional board description |
|
|
77
209
|
|
|
78
210
|
```bash
|
|
79
|
-
|
|
80
|
-
|
|
211
|
+
formo boards create --name "Revenue Metrics" --description "Weekly revenue tracking"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `boards update <boardId>`
|
|
215
|
+
|
|
216
|
+
| Option | Description |
|
|
217
|
+
|---|---|
|
|
218
|
+
| `--name` | New board name |
|
|
219
|
+
| `--description` | New board description |
|
|
220
|
+
|
|
221
|
+
### `boards delete <boardId>`
|
|
222
|
+
Delete a board.
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## `formo charts`
|
|
227
|
+
|
|
228
|
+
Chart commands. Charts live inside a board. Requires `charts:read` / `charts:write`.
|
|
229
|
+
|
|
230
|
+
### `charts list --board-id <boardId>`
|
|
231
|
+
List all charts in a board.
|
|
232
|
+
|
|
233
|
+
### `charts get <chartId> --board-id <boardId>`
|
|
234
|
+
Get a single chart by ID.
|
|
235
|
+
|
|
236
|
+
### `charts create --board-id <boardId> --body '<json>'`
|
|
237
|
+
Create a chart from a JSON config string.
|
|
238
|
+
|
|
239
|
+
### `charts update <chartId> --board-id <boardId> --body '<json>'`
|
|
240
|
+
Update a chart.
|
|
241
|
+
|
|
242
|
+
### `charts delete <chartId> --board-id <boardId>`
|
|
243
|
+
Delete a chart.
|
|
244
|
+
|
|
245
|
+
---
|
|
81
246
|
|
|
82
|
-
|
|
83
|
-
formo profiles search --orderBy net_worth_usd --orderDir desc --limit 5
|
|
247
|
+
## `formo contracts`
|
|
84
248
|
|
|
85
|
-
|
|
86
|
-
|
|
249
|
+
Smart contract commands. Requires `contracts:read` / `contracts:write`.
|
|
250
|
+
|
|
251
|
+
### `contracts list`
|
|
252
|
+
List all tracked contracts. Returns `{ data: Contract[], deploy: { last_deployed_at, diff }, total, page, size, has_more }`.
|
|
253
|
+
|
|
254
|
+
### `contracts create`
|
|
255
|
+
|
|
256
|
+
| Option | Description |
|
|
257
|
+
|---|---|
|
|
258
|
+
| `--address` | Contract address (`0x…`) |
|
|
259
|
+
| `--chain` | Chain ID (e.g. `1`, `137`) |
|
|
260
|
+
| `--name` | Human-readable contract name |
|
|
261
|
+
| `--abi` | Contract ABI as a JSON string |
|
|
262
|
+
| `--events` | Events configuration as a JSON string |
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
formo contracts create --address 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984 --chain 1 \
|
|
266
|
+
--name "UNI Token" --abi '[{"type":"event","name":"Transfer","inputs":[]}]' \
|
|
267
|
+
--events '{"Transfer":true}'
|
|
87
268
|
```
|
|
88
269
|
|
|
270
|
+
### `contracts update <chain> <address>`
|
|
271
|
+
|
|
272
|
+
| Option | Description |
|
|
273
|
+
|---|---|
|
|
274
|
+
| `--name` | Updated contract name |
|
|
275
|
+
| `--abi` | Updated ABI |
|
|
276
|
+
| `--events` | Updated events config |
|
|
277
|
+
|
|
278
|
+
### `contracts delete <chain> <address>`
|
|
279
|
+
Remove a tracked contract.
|
|
280
|
+
|
|
89
281
|
---
|
|
90
282
|
|
|
91
|
-
|
|
283
|
+
## `formo segments`
|
|
284
|
+
|
|
285
|
+
User segment commands. Requires `segments:read` / `segments:write`.
|
|
92
286
|
|
|
93
|
-
|
|
287
|
+
### `segments list`
|
|
288
|
+
List all user segments.
|
|
289
|
+
|
|
290
|
+
### `segments create`
|
|
291
|
+
|
|
292
|
+
| Option | Description |
|
|
293
|
+
|---|---|
|
|
294
|
+
| `--title` | Segment title |
|
|
295
|
+
| `--filter-sets` | JSON array of filter set strings defining the segment |
|
|
296
|
+
|
|
297
|
+
### `segments delete <segmentId>`
|
|
298
|
+
Delete a user segment.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## `formo query`
|
|
303
|
+
|
|
304
|
+
### `query run "<sql>"`
|
|
305
|
+
|
|
306
|
+
Run a SQL query against your Formo analytics data. Returns `{ data, total, limit, offset, has_more }`.
|
|
94
307
|
|
|
95
308
|
```bash
|
|
96
309
|
formo query run "SELECT count(*) FROM events"
|
|
97
310
|
formo query run "SELECT address, net_worth_usd FROM wallet_profiles ORDER BY net_worth_usd DESC LIMIT 10"
|
|
98
311
|
```
|
|
99
312
|
|
|
100
|
-
> Requires `query:read` scope
|
|
313
|
+
> Requires `query:read` scope.
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## `formo analytics`
|
|
318
|
+
|
|
319
|
+
Pre-built analytics pipes — the same data that powers the Formo dashboard — without writing SQL. Each pipe is a subcommand: `formo analytics <pipe>`.
|
|
320
|
+
|
|
321
|
+
**Pipes:** `kpis`, `event_timeseries`, `funnel`, `flow`, `frequency`, `lifecycle`, `retention`, `revenue_overview`, `revenue_by_metric`, `revenue_timeseries`, `volume_by_metric`, `top_chains`, `top_events`, `top_locations`, `top_pages`, `top_sources`, `top_wallets`
|
|
322
|
+
|
|
323
|
+
| Option | Description |
|
|
324
|
+
|---|---|
|
|
325
|
+
| `--date-from` | Inclusive start date `YYYY-MM-DD` (default: 7 days before `--date-to`) |
|
|
326
|
+
| `--date-to` | Inclusive end date `YYYY-MM-DD` (default: today) |
|
|
327
|
+
| `--filters` | JSON array of `[{field,op,value}]`. Use `in`/`notIn` with a pipe-delimited value (e.g. `"chrome\|firefox"`) |
|
|
328
|
+
| `--params` | JSON object of pipe-specific params merged into the query (e.g. `{"limit":10,"group_by":"device"}`) |
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
formo analytics kpis
|
|
332
|
+
formo analytics kpis --date-from 2026-04-01 --date-to 2026-04-30 --params '{"group_by":"device"}'
|
|
333
|
+
formo analytics funnel --date-from 2026-04-01 --date-to 2026-04-30 --params '{"steps":[{"type":"event","event":"page","name":"page::0","filters":[]},{"type":"track","event":"connect","name":"connect::1","filters":[]}],"window_seconds":86400}'
|
|
334
|
+
formo analytics top_wallets --date-from 2026-04-01 --date-to 2026-04-30 --params '{"limit":10}'
|
|
335
|
+
formo analytics retention --filters '[{"field":"location","op":"equals","value":"US"}]'
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
> Requires `query:read` scope. Run `formo analytics <pipe> --help` for the pipe-specific params accepted via `--params`.
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## `formo import`
|
|
343
|
+
|
|
344
|
+
### `import wallets`
|
|
345
|
+
|
|
346
|
+
Bulk-import wallet addresses into the project via the events API.
|
|
347
|
+
|
|
348
|
+
| Option | Description |
|
|
349
|
+
|---|---|
|
|
350
|
+
| `--addresses` | JSON array of wallet address strings |
|
|
351
|
+
| `--write-key` | Project write SDK key |
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
formo import wallets --addresses '["0xabc...","0xdef..."]' --write-key write_key_xyz
|
|
355
|
+
```
|
|
101
356
|
|
|
102
357
|
---
|
|
103
358
|
|
|
104
359
|
## FilterCondition reference
|
|
105
360
|
|
|
106
|
-
|
|
361
|
+
`profiles search --conditions` accepts a JSON array of filter condition objects:
|
|
107
362
|
|
|
108
363
|
```json
|
|
109
364
|
[
|
|
110
|
-
{ "field": "net_worth_usd", "op": "gt", "value": 10000 },
|
|
111
|
-
{ "field": "
|
|
365
|
+
{ "field": "users.net_worth_usd", "op": "gt", "value": 10000 },
|
|
366
|
+
{ "field": "chains.1.balance", "op": "gte", "value": 1000 }
|
|
112
367
|
]
|
|
113
368
|
```
|
|
114
369
|
|
|
370
|
+
> **The `field` must be a typed path.** A bare name like `net_worth_usd` is
|
|
371
|
+
> silently ignored by the API (no error, no filtering — the search returns
|
|
372
|
+
> everything). Always prefix the field with its type.
|
|
373
|
+
|
|
115
374
|
| Field | Type | Description |
|
|
116
375
|
|---|---|---|
|
|
117
|
-
| `field` | `string` |
|
|
118
|
-
| `op` | `string` |
|
|
376
|
+
| `field` | `string` | Typed path (see prefixes below) |
|
|
377
|
+
| `op` | `string` | `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `nin` |
|
|
119
378
|
| `value` | `any` | Value to compare against |
|
|
379
|
+
| `scope` | `string` | _(token filters only)_ `any` or `protocol` |
|
|
380
|
+
| `appId` | `string` | _(token filters with `scope: protocol`)_ e.g. `aave-v3` |
|
|
381
|
+
|
|
382
|
+
| Prefix | Examples |
|
|
383
|
+
|---|---|
|
|
384
|
+
| `users.` | `users.net_worth_usd`, `users.volume`, `users.revenue`, `users.points`, `users.device`, `users.location`, `users.lifecycle`, `users.ens`, `users.farcaster` |
|
|
385
|
+
| `chains.` | `chains.balance` (any chain), `chains.1.balance` (Ethereum) |
|
|
386
|
+
| `apps.` | `apps.uniswap-v3.balance` |
|
|
387
|
+
| `tokens.` | `tokens.0xA0b8…48.balance` |
|
|
388
|
+
| `labels.` | `labels.coinbase.verified_account` |
|
|
389
|
+
|
|
390
|
+
Combine multiple conditions with `--logic and` (default) or `--logic or`.
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Output formats
|
|
395
|
+
|
|
396
|
+
Every command supports the standard incur output flags:
|
|
397
|
+
|
|
398
|
+
| Flag | Description |
|
|
399
|
+
|---|---|
|
|
400
|
+
| `--format <toon\|json\|yaml\|md\|jsonl>` | Output format (default: `toon`) |
|
|
401
|
+
| `--json` | Shorthand for `--format json` |
|
|
402
|
+
| `--verbose` | Include the full envelope (`ok`, `data`, `meta`) |
|
|
403
|
+
| `--filter-output <keys>` | Filter output by key paths (e.g. `data,meta.duration`) |
|
|
120
404
|
|
|
121
|
-
|
|
405
|
+
Every list endpoint returns a `PaginatedResponse<T>` envelope: `{ data: [...], total, page, size, has_more }`. Every error follows: `{ error: { code, message, doc_url, param?, details? } }` — branch on `error.code`, not `message`.
|
|
122
406
|
|
|
123
407
|
---
|
|
124
408
|
|
|
@@ -129,14 +413,14 @@ Multiple conditions are combined with `AND` logic.
|
|
|
129
413
|
pnpm install
|
|
130
414
|
|
|
131
415
|
# Run in development mode
|
|
132
|
-
pnpm
|
|
416
|
+
pnpm dev
|
|
133
417
|
|
|
134
418
|
# Build TypeScript
|
|
135
|
-
pnpm
|
|
419
|
+
pnpm build
|
|
136
420
|
|
|
137
|
-
#
|
|
138
|
-
pnpm
|
|
421
|
+
# Lint
|
|
422
|
+
pnpm lint
|
|
139
423
|
|
|
140
|
-
#
|
|
141
|
-
pnpm
|
|
424
|
+
# Run tests (requires TEST_TOKEN in .env)
|
|
425
|
+
pnpm test
|
|
142
426
|
```
|
|
@@ -9,6 +9,7 @@ export interface CreateAlertOptions {
|
|
|
9
9
|
recipient?: string;
|
|
10
10
|
secret?: string;
|
|
11
11
|
}
|
|
12
|
+
export declare function buildAlertBody(options: CreateAlertOptions | UpdateAlertOptions): Record<string, unknown>;
|
|
12
13
|
export declare function createAlertRun(options: CreateAlertOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
13
14
|
export interface UpdateAlertOptions {
|
|
14
15
|
name: string;
|
package/dist/commands/alerts.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.alerts = void 0;
|
|
4
4
|
exports.listAlertsRun = listAlertsRun;
|
|
5
5
|
exports.getAlertRun = getAlertRun;
|
|
6
|
+
exports.buildAlertBody = buildAlertBody;
|
|
6
7
|
exports.createAlertRun = createAlertRun;
|
|
7
8
|
exports.updateAlertRun = updateAlertRun;
|
|
8
9
|
exports.deleteAlertRun = deleteAlertRun;
|
|
@@ -45,9 +46,7 @@ exports.alerts.command('get', {
|
|
|
45
46
|
return getAlertRun(args.alertId);
|
|
46
47
|
},
|
|
47
48
|
});
|
|
48
|
-
function
|
|
49
|
-
(0, client_1.requireApiKey)();
|
|
50
|
-
const client = (0, client_1.createClient)();
|
|
49
|
+
function buildAlertBody(options) {
|
|
51
50
|
const body = {
|
|
52
51
|
name: options.name,
|
|
53
52
|
trigger_type: options.triggerType,
|
|
@@ -57,7 +56,7 @@ function createAlertRun(options) {
|
|
|
57
56
|
body.trigger_filters = JSON.parse(options.triggerFilters);
|
|
58
57
|
}
|
|
59
58
|
catch {
|
|
60
|
-
throw new Error('--
|
|
59
|
+
throw new Error('--trigger-filters must be a valid JSON array');
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
if (options.recipient) {
|
|
@@ -68,10 +67,15 @@ function createAlertRun(options) {
|
|
|
68
67
|
throw new Error('--recipient must be a valid JSON array');
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
|
-
if (options.secret) {
|
|
70
|
+
if (options.secret !== undefined) {
|
|
72
71
|
body.secret = options.secret;
|
|
73
72
|
}
|
|
74
|
-
return
|
|
73
|
+
return body;
|
|
74
|
+
}
|
|
75
|
+
function createAlertRun(options) {
|
|
76
|
+
(0, client_1.requireApiKey)();
|
|
77
|
+
const client = (0, client_1.createClient)();
|
|
78
|
+
return client.post('/v0/alerts/', buildAlertBody(options));
|
|
75
79
|
}
|
|
76
80
|
exports.alerts.command('create', {
|
|
77
81
|
description: 'Create a new project alert',
|
|
@@ -102,30 +106,7 @@ exports.alerts.command('create', {
|
|
|
102
106
|
function updateAlertRun(alertId, options) {
|
|
103
107
|
(0, client_1.requireApiKey)();
|
|
104
108
|
const client = (0, client_1.createClient)();
|
|
105
|
-
|
|
106
|
-
name: options.name,
|
|
107
|
-
trigger_type: options.triggerType,
|
|
108
|
-
};
|
|
109
|
-
if (options.triggerFilters) {
|
|
110
|
-
try {
|
|
111
|
-
body.trigger_filters = JSON.parse(options.triggerFilters);
|
|
112
|
-
}
|
|
113
|
-
catch {
|
|
114
|
-
throw new Error('--triggerFilters must be a valid JSON array');
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (options.recipient) {
|
|
118
|
-
try {
|
|
119
|
-
body.recipient = JSON.parse(options.recipient);
|
|
120
|
-
}
|
|
121
|
-
catch {
|
|
122
|
-
throw new Error('--recipient must be a valid JSON array');
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (options.secret !== undefined) {
|
|
126
|
-
body.secret = options.secret;
|
|
127
|
-
}
|
|
128
|
-
return client.put(`/v0/alerts/${encodeURIComponent(alertId)}`, body);
|
|
109
|
+
return client.put(`/v0/alerts/${encodeURIComponent(alertId)}`, buildAlertBody(options));
|
|
129
110
|
}
|
|
130
111
|
exports.alerts.command('update', {
|
|
131
112
|
description: 'Update an existing alert',
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Cli } from 'incur';
|
|
2
|
+
export declare const analytics: Cli.Cli<{}, undefined, undefined>;
|
|
3
|
+
export interface AnalyticsOptions {
|
|
4
|
+
dateFrom?: string;
|
|
5
|
+
dateTo?: string;
|
|
6
|
+
filters?: string;
|
|
7
|
+
params?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Build the query-string params for an analytics pipe request.
|
|
11
|
+
*
|
|
12
|
+
* - `dateFrom`/`dateTo` map to the API's snake_case `date_from`/`date_to`.
|
|
13
|
+
* All pipes, including `funnel` and `flow`, use snake_case.
|
|
14
|
+
* - `filters` is a JSON array of `{ field, op, value }` objects, re-serialized
|
|
15
|
+
* as a JSON string (the pipe expects a JSON-encoded array in the query).
|
|
16
|
+
* - `params` is a JSON object of any pipe-specific params (e.g. funnel
|
|
17
|
+
* `steps`, kpis `group_by`, `limit`). Object/array values are JSON-encoded
|
|
18
|
+
* (pipes like funnel expect `steps` as a JSON-encoded string); primitives
|
|
19
|
+
* pass through unchanged. Reserved keys (the date/filters flags) are
|
|
20
|
+
* rejected, and the validated flags below always take precedence.
|
|
21
|
+
*
|
|
22
|
+
* Exported for unit testing.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildAnalyticsParams(options: AnalyticsOptions): Record<string, string | number | boolean>;
|
|
25
|
+
export declare function runAnalytics(pipe: string, options: AnalyticsOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
|