@framedash/cli 0.1.2 → 0.1.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/README.md +42 -7
- package/dist/commands/alerts.d.ts.map +1 -1
- package/dist/commands/alerts.js +2 -1
- package/dist/commands/alerts.js.map +1 -1
- package/dist/commands/auth.d.ts.map +1 -1
- package/dist/commands/auth.js +25 -2
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +142 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +79 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/map-capture.d.ts +2 -1
- package/dist/commands/map-capture.d.ts.map +1 -1
- package/dist/commands/map-capture.js +38 -9
- package/dist/commands/map-capture.js.map +1 -1
- package/dist/commands/projects.d.ts +2 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +26 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/query.d.ts.map +1 -1
- package/dist/commands/query.js +12 -0
- package/dist/commands/query.js.map +1 -1
- package/dist/commands/run-profile-test.d.ts.map +1 -1
- package/dist/commands/run-profile-test.js +143 -26
- package/dist/commands/run-profile-test.js.map +1 -1
- package/dist/commands/threshold-profiles.d.ts +2 -0
- package/dist/commands/threshold-profiles.d.ts.map +1 -0
- package/dist/commands/threshold-profiles.js +24 -0
- package/dist/commands/threshold-profiles.js.map +1 -0
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +42 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +44 -14
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/create-client.d.ts +25 -7
- package/dist/lib/create-client.d.ts.map +1 -1
- package/dist/lib/create-client.js +160 -33
- package/dist/lib/create-client.js.map +1 -1
- package/dist/lib/formatters.js +109 -1
- package/dist/lib/formatters.js.map +1 -1
- package/dist/lib/oauth/loopback-server.d.ts +27 -0
- package/dist/lib/oauth/loopback-server.d.ts.map +1 -0
- package/dist/lib/oauth/loopback-server.js +164 -0
- package/dist/lib/oauth/loopback-server.js.map +1 -0
- package/dist/lib/oauth/manager.d.ts +36 -0
- package/dist/lib/oauth/manager.d.ts.map +1 -0
- package/dist/lib/oauth/manager.js +130 -0
- package/dist/lib/oauth/manager.js.map +1 -0
- package/dist/lib/oauth/pkce.d.ts +15 -0
- package/dist/lib/oauth/pkce.d.ts.map +1 -0
- package/dist/lib/oauth/pkce.js +24 -0
- package/dist/lib/oauth/pkce.js.map +1 -0
- package/dist/lib/oauth/token-endpoint.d.ts +39 -0
- package/dist/lib/oauth/token-endpoint.d.ts.map +1 -0
- package/dist/lib/oauth/token-endpoint.js +117 -0
- package/dist/lib/oauth/token-endpoint.js.map +1 -0
- package/dist/lib/oauth/token-store.d.ts +34 -0
- package/dist/lib/oauth/token-store.d.ts.map +1 -0
- package/dist/lib/oauth/token-store.js +164 -0
- package/dist/lib/oauth/token-store.js.map +1 -0
- package/dist/lib/run-command.js +2 -2
- package/dist/lib/run-command.js.map +1 -1
- package/dist/lib/run-profile-test-lib.d.ts +39 -0
- package/dist/lib/run-profile-test-lib.d.ts.map +1 -1
- package/dist/lib/run-profile-test-lib.js +47 -0
- package/dist/lib/run-profile-test-lib.js.map +1 -1
- package/dist/lib/uploader.d.ts +14 -1
- package/dist/lib/uploader.d.ts.map +1 -1
- package/dist/lib/uploader.js +26 -12
- package/dist/lib/uploader.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,7 +6,10 @@ Framedash CLI tool for CI/CD pipelines, analytics queries, and coding agent inte
|
|
|
6
6
|
|
|
7
7
|
| Command | Description |
|
|
8
8
|
|---------|-------------|
|
|
9
|
-
| `framedash
|
|
9
|
+
| `framedash login` | Sign in via the browser (interactive OAuth; not for CI) |
|
|
10
|
+
| `framedash logout` | Revoke and remove a stored browser login |
|
|
11
|
+
| `framedash auth` | Verify credentials, show their source, and list projects |
|
|
12
|
+
| `framedash projects` | List accessible projects (discover your project id) |
|
|
10
13
|
| `framedash query` | Run SQL analytics queries against ClickHouse |
|
|
11
14
|
| `framedash dashboard` | Fetch dashboard KPI summary |
|
|
12
15
|
| `framedash retention` | Fetch retention cohort data |
|
|
@@ -16,15 +19,40 @@ Framedash CLI tool for CI/CD pipelines, analytics queries, and coding agent inte
|
|
|
16
19
|
| `framedash run-profile-test` | Run a profiling build, wait for ingest, then gate on a regression |
|
|
17
20
|
| `framedash alerts` | Manage alert rules and channels |
|
|
18
21
|
| `framedash maps` | List and manage map overlays |
|
|
22
|
+
| `framedash threshold-profiles` | List threshold profiles (perf budgets for alerts) |
|
|
19
23
|
| `framedash content` | Manage content registry entries |
|
|
20
24
|
| `framedash status` | Check project ingestion status |
|
|
21
25
|
| `framedash map-capture` | Upload captured map images |
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
`framedash alerts create` requires an existing map and threshold profile: pass
|
|
28
|
+
their UUIDs via `--map-id` and `--threshold-profile-id`. Discover those UUIDs
|
|
29
|
+
without opening the dashboard by running `framedash maps list` and
|
|
30
|
+
`framedash threshold-profiles list`.
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
## Authentication
|
|
33
|
+
|
|
34
|
+
Two credential types are supported:
|
|
35
|
+
|
|
36
|
+
- API keys (recommended for CI and any non-interactive use): pass via
|
|
37
|
+
`--api-key-file` (supports `-` for piped stdin), `--api-key`, or the
|
|
38
|
+
`FRAMEDASH_API_KEY` environment variable. Prefer files or piped stdin over
|
|
39
|
+
`--api-key` for local runs so raw keys do not appear in shell history.
|
|
40
|
+
- Interactive browser login: `framedash login` runs an OAuth 2.1
|
|
41
|
+
authorization-code + PKCE flow against the Framedash authorization server
|
|
42
|
+
(loopback redirect on `127.0.0.1`). Tokens are stored per base-URL origin in
|
|
43
|
+
`$XDG_CONFIG_HOME/framedash/credentials.json` (default
|
|
44
|
+
`~/.config/framedash/credentials.json`; the same `~/.config` path is used on
|
|
45
|
+
Windows) and refreshed automatically, including refresh-token rotation.
|
|
46
|
+
`framedash logout` revokes the session server-side (best effort) and removes
|
|
47
|
+
the stored tokens; `framedash logout --all` clears every stored login.
|
|
48
|
+
|
|
49
|
+
Precedence: `--api-key` > `--api-key-file` > `FRAMEDASH_API_KEY` > stored
|
|
50
|
+
OAuth login for the resolved base URL. `framedash auth` reports which source
|
|
51
|
+
is active.
|
|
52
|
+
|
|
53
|
+
CI/non-interactive environments should keep using `FRAMEDASH_API_KEY` with a
|
|
54
|
+
project API key: `framedash login` requires a browser and stores per-user
|
|
55
|
+
refresh tokens, neither of which fits ephemeral CI runners.
|
|
28
56
|
|
|
29
57
|
Project-scoped commands such as `dashboard` also require a project ID from
|
|
30
58
|
`--project-id` or `FRAMEDASH_PROJECT_ID`. The `auth` command only requires an
|
|
@@ -76,8 +104,15 @@ The launched command inherits `FRAMEDASH_BUILD_ID`, `FRAMEDASH_GIT_BRANCH`,
|
|
|
76
104
|
`FRAMEDASH_GIT_COMMIT`, and `FRAMEDASH_TEST_SCENARIO`; an SDK that calls
|
|
77
105
|
`BeginAutomatedSessionFromEnvironment()` stamps them onto every event with no
|
|
78
106
|
in-game code change. The build id (defaulting to the git commit) becomes the
|
|
79
|
-
`perf-diff` candidate.
|
|
80
|
-
|
|
107
|
+
`perf-diff` candidate. Because the build id reaches the game only through the
|
|
108
|
+
exported `FRAMEDASH_BUILD_ID`, a build that hardcodes its SDK build id will never
|
|
109
|
+
match the awaited build and the ingest wait will time out.
|
|
110
|
+
|
|
111
|
+
The launched process is bounded by `--command-timeout` (default 1800s, `0`
|
|
112
|
+
disables): if the game does not exit on its own, its whole process tree is killed
|
|
113
|
+
and the run fails without gating -- so a non-self-quitting build cannot hang the
|
|
114
|
+
CI job forever. Run `framedash run-profile-test --help` for all options, or use
|
|
115
|
+
`framedash builds` / `framedash perf-diff` to drive the steps manually.
|
|
81
116
|
|
|
82
117
|
## Development
|
|
83
118
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../../src/commands/alerts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"alerts.d.ts","sourceRoot":"","sources":["../../src/commands/alerts.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,MAAM,mCAKjB,CAAC"}
|
package/dist/commands/alerts.js
CHANGED
|
@@ -19,8 +19,9 @@ Create a new alert rule.
|
|
|
19
19
|
|
|
20
20
|
Required:
|
|
21
21
|
--name <name> Alert rule name
|
|
22
|
-
--map-id <uuid> Map ID
|
|
22
|
+
--map-id <uuid> Map ID (list IDs with 'framedash maps list')
|
|
23
23
|
--threshold-profile-id <uuid> Threshold profile ID
|
|
24
|
+
(list IDs with 'framedash threshold-profiles list')
|
|
24
25
|
--metric <metric> Metric name
|
|
25
26
|
--threshold-level <level> Threshold level
|
|
26
27
|
--fail-percentage <n> Failure percentage (0-100)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alerts.js","sourceRoot":"","sources":["../../src/commands/alerts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,IAAI,GAAG;;;;;;;;;;0DAU6C,CAAC;AAE3D,MAAM,WAAW,GAAG
|
|
1
|
+
{"version":3,"file":"alerts.js","sourceRoot":"","sources":["../../src/commands/alerts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,IAAI,GAAG;;;;;;;;;;0DAU6C,CAAC;AAE3D,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;8EAiB0D,CAAC;AAE/E,MAAM,CAAC,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,EAAE;IACrD,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;CACpB,CAAC,CAAC;AAEH,KAAK,UAAU,UAAU,CAAC,IAAc;IACvC,MAAM,UAAU,CACf,EAAE,IAAI,EAAE,IAAI,EAAE,yEAAyE,EAAE,EACzF,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5D,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC,CACD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,UAAU,CACf;QACC,IAAI;QACJ,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACR,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC5B,sBAAsB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC1B,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,kBAAkB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACtC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACjC;KACD,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QACpC,MAAM,QAAQ,GAAG;YAChB,MAAM;YACN,QAAQ;YACR,sBAAsB;YACtB,QAAQ;YACR,iBAAiB;YACjB,iBAAiB;YACjB,iBAAiB;YACjB,WAAW;YACX,kBAAkB;SACT,CAAC;QAEX,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnB,KAAK,CAAC,KAAK,IAAI,cAAc,CAAC,CAAC;gBAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACF,CAAC;QAED,MAAM,IAAI,GAA4B;YACrC,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;YACvB,kBAAkB,EAAE,MAAM,CAAC,sBAAsB,CAAC;YAClD,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,cAAc,EAAE,MAAM,CAAC,iBAAiB,CAAC;YACzC,cAAc,EAAE,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAW,EAAE,iBAAiB,CAAC;YACnF,cAAc,EAAE,gBAAgB,CAAC,MAAM,CAAC,iBAAiB,CAAW,EAAE,iBAAiB,CAAC;YACxF,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAW,EAAE,WAAW,CAAC;YACtE,eAAe,EAAE,gBAAgB,CAAC,MAAM,CAAC,kBAAkB,CAAW,EAAE,kBAAkB,CAAC;SAC3F,CAAC;QAEF,IAAI,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,aAAa,CAAW,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;QACnE,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC9B,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC,CACD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,UAAU,CACf;QACC,IAAI;QACJ,IAAI,EAAE,yGAAyG;QAC/G,OAAO,EAAE;YACR,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YAC/B,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACjC,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACrC,kBAAkB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SACtC;QACD,gBAAgB,EAAE,IAAI;KACtB,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QACjD,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,IAAI,GAA4B,EAAE,CAAC;QACzC,IAAI,MAAM,CAAC,IAAI;YAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzC,IAAI,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,CAAW,CAAC;YACxC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC;gBACnC,KAAK,CAAC,+CAA+C,CAAC,EAAE,CAAC,CAAC;gBAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,CAAC,KAAK,MAAM,CAAC;QAC9B,CAAC;QACD,IAAI,MAAM,CAAC,aAAa,CAAC;YAAE,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,aAAa,CAAW,CAAC,CAAC;QAC9F,IAAI,MAAM,CAAC,iBAAiB,CAAC;YAC5B,IAAI,CAAC,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,iBAAiB,CAAW,EAAE,iBAAiB,CAAC,CAAC;QAC3F,IAAI,MAAM,CAAC,iBAAiB,CAAC;YAC5B,IAAI,CAAC,cAAc,GAAG,gBAAgB,CACrC,MAAM,CAAC,iBAAiB,CAAW,EACnC,iBAAiB,CACjB,CAAC;QACH,IAAI,MAAM,CAAC,kBAAkB,CAAC;YAC7B,IAAI,CAAC,eAAe,GAAG,gBAAgB,CACtC,MAAM,CAAC,kBAAkB,CAAW,EACpC,kBAAkB,CAClB,CAAC;QAEH,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAC9B,MAAM,CAAC,WAAW,CAAC,UAAU,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,EAC3D,IAAI,CACJ,CAAC;QACF,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC9B,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC,CACD,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,UAAU,CACf;QACC,IAAI;QACJ,IAAI,EAAE,4DAA4D;QAClE,gBAAgB,EAAE,IAAI;KACtB,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QACjC,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,KAAK,CAAC,0DAA0D,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACjF,OAAO,CAAC,cAAc,OAAO,UAAU,CAAC,CAAC;IAC1C,CAAC,CACD,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IACnC,MAAM,GAAG,GAAG,GAAG;SACb,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAClB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AA0BA,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxD"}
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,19 +1,42 @@
|
|
|
1
1
|
import { formatOutput } from "../lib/formatters.js";
|
|
2
2
|
import { log, success } from "../lib/logger.js";
|
|
3
3
|
import { runCommand } from "../lib/run-command.js";
|
|
4
|
+
/**
|
|
5
|
+
* Human-readable description of the active credential source. For a stored
|
|
6
|
+
* OAuth login this shows scope and expiry ONLY -- never token material.
|
|
7
|
+
*/
|
|
8
|
+
function describeCredential(credential) {
|
|
9
|
+
if (credential.kind === "api-key") {
|
|
10
|
+
switch (credential.source) {
|
|
11
|
+
case "flag":
|
|
12
|
+
return "API key from --api-key flag";
|
|
13
|
+
case "file":
|
|
14
|
+
return "API key from --api-key-file";
|
|
15
|
+
case "env":
|
|
16
|
+
return "API key from FRAMEDASH_API_KEY env";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const expires = new Date(credential.entry.expires_at).toISOString();
|
|
20
|
+
return `stored OAuth login for ${credential.origin} (framedash login; scopes: ${credential.entry.scope || "unknown"}; access token expires: ${expires})`;
|
|
21
|
+
}
|
|
4
22
|
export async function auth(args) {
|
|
5
23
|
await runCommand({ args, help: HELP, noProject: true }, async ({ client, config }) => {
|
|
6
24
|
const projects = await client.get("/api/v1/projects");
|
|
7
|
-
success("API key is valid");
|
|
25
|
+
success(config.credential.kind === "api-key" ? "API key is valid" : "OAuth login is valid");
|
|
26
|
+
success(`Credential source: ${describeCredential(config.credential)}`);
|
|
8
27
|
log(formatOutput(projects, config.format));
|
|
9
28
|
});
|
|
10
29
|
}
|
|
11
30
|
const HELP = `Usage: framedash auth [options]
|
|
12
31
|
|
|
13
|
-
Verify your
|
|
32
|
+
Verify your credentials and list the projects they can read. Also reports
|
|
33
|
+
which credential source is active: --api-key flag, --api-key-file,
|
|
34
|
+
FRAMEDASH_API_KEY env, or a stored OAuth login from 'framedash login'
|
|
35
|
+
(API keys always take precedence over a stored login).
|
|
14
36
|
|
|
15
37
|
Options:
|
|
16
38
|
--api-key <key> API key (or FRAMEDASH_API_KEY env)
|
|
39
|
+
--api-key-file <path> Read the API key from a file ('-' for stdin)
|
|
17
40
|
--base-url <url> API base URL (default: https://app.framedash.dev)
|
|
18
41
|
--format <fmt> Output format: json, table, csv (default: json)
|
|
19
42
|
-h, --help Show help`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD;;;GAGG;AACH,SAAS,kBAAkB,CAAC,UAAyB;IACpD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACnC,QAAQ,UAAU,CAAC,MAAM,EAAE,CAAC;YAC3B,KAAK,MAAM;gBACV,OAAO,6BAA6B,CAAC;YACtC,KAAK,MAAM;gBACV,OAAO,6BAA6B,CAAC;YACtC,KAAK,KAAK;gBACT,OAAO,oCAAoC,CAAC;QAC9C,CAAC;IACF,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IACpE,OAAO,0BAA0B,UAAU,CAAC,MAAM,8BACjD,UAAU,CAAC,KAAK,CAAC,KAAK,IAAI,SAC3B,2BAA2B,OAAO,GAAG,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc;IACxC,MAAM,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QACpF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAiC,kBAAkB,CAAC,CAAC;QACtF,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;QAC5F,OAAO,CAAC,sBAAsB,kBAAkB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvE,GAAG,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,IAAI,GAAG;;;;;;;;;;;;mCAYsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAwEA,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFzD"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { GLOBAL_OPTIONS, resolveBaseAndFormat } from "../lib/config.js";
|
|
4
|
+
import { error, log, success } from "../lib/logger.js";
|
|
5
|
+
import { startLoopbackServer } from "../lib/oauth/loopback-server.js";
|
|
6
|
+
import { computeS256CodeChallenge, generateCodeVerifier, generateState, } from "../lib/oauth/pkce.js";
|
|
7
|
+
import { CLI_OAUTH_CLIENT_ID, exchangeAuthorizationCode, revokeToken, toStoredEntry, } from "../lib/oauth/token-endpoint.js";
|
|
8
|
+
import { credentialsFilePath, saveStoredEntry } from "../lib/oauth/token-store.js";
|
|
9
|
+
const HELP = `Usage: framedash login [options]
|
|
10
|
+
|
|
11
|
+
Sign in interactively via your browser (OAuth 2.1 authorization code + PKCE).
|
|
12
|
+
Tokens are stored in ${"~"}/.config/framedash/credentials.json (honors
|
|
13
|
+
XDG_CONFIG_HOME; the same path is used on Windows) and refreshed
|
|
14
|
+
automatically. Commands use the stored login only when no API key is given
|
|
15
|
+
(--api-key / --api-key-file / FRAMEDASH_API_KEY take precedence).
|
|
16
|
+
|
|
17
|
+
For CI and other non-interactive use, do NOT use login: set the
|
|
18
|
+
FRAMEDASH_API_KEY environment variable to a project API key instead.
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
--scopes <scopes> Space-delimited scopes to request
|
|
22
|
+
(default: analytics:read)
|
|
23
|
+
--no-browser Do not try to open the browser; print the URL only
|
|
24
|
+
--base-url <url> API base URL (default: https://app.framedash.dev)
|
|
25
|
+
-h, --help Show help`;
|
|
26
|
+
/** Give the user five minutes to finish the browser consent. */
|
|
27
|
+
const CALLBACK_TIMEOUT_MS = 5 * 60 * 1000;
|
|
28
|
+
/** RFC 6749 scope tokens: printable ASCII except space, quote, backslash. */
|
|
29
|
+
const SCOPE_RE = /^[\x21\x23-\x5B\x5D-\x7E]+$/;
|
|
30
|
+
/**
|
|
31
|
+
* Best-effort system browser launch; the URL is always printed as fallback.
|
|
32
|
+
* Windows uses rundll32's FileProtocolHandler instead of `cmd /c start`
|
|
33
|
+
* because start parses `&` (which every authorize URL contains) as a shell
|
|
34
|
+
* operator unless escaped.
|
|
35
|
+
*/
|
|
36
|
+
function openBrowser(url) {
|
|
37
|
+
let command;
|
|
38
|
+
let args;
|
|
39
|
+
if (process.platform === "win32") {
|
|
40
|
+
command = "rundll32";
|
|
41
|
+
args = ["url.dll,FileProtocolHandler", url];
|
|
42
|
+
}
|
|
43
|
+
else if (process.platform === "darwin") {
|
|
44
|
+
command = "open";
|
|
45
|
+
args = [url];
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
command = "xdg-open";
|
|
49
|
+
args = [url];
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const child = spawn(command, args, { stdio: "ignore", detached: true });
|
|
53
|
+
child.on("error", () => {
|
|
54
|
+
// Best effort: the printed URL is the fallback.
|
|
55
|
+
});
|
|
56
|
+
child.unref();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Best effort only.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function login(args) {
|
|
63
|
+
const { values } = parseArgs({
|
|
64
|
+
args,
|
|
65
|
+
options: {
|
|
66
|
+
...GLOBAL_OPTIONS,
|
|
67
|
+
scopes: { type: "string" },
|
|
68
|
+
"no-browser": { type: "boolean" },
|
|
69
|
+
},
|
|
70
|
+
allowPositionals: false,
|
|
71
|
+
});
|
|
72
|
+
if (values.help) {
|
|
73
|
+
log(HELP);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const { baseUrl } = resolveBaseAndFormat(values);
|
|
77
|
+
const origin = new URL(baseUrl).origin;
|
|
78
|
+
// Normalize whitespace: trim, split on runs of any whitespace, and drop
|
|
79
|
+
// empty tokens, so "a b" or tab-separated input works. An empty token
|
|
80
|
+
// list must fail explicitly ([].every() is vacuously true).
|
|
81
|
+
const scopeList = (values.scopes ?? "analytics:read").trim().split(/\s+/).filter(Boolean);
|
|
82
|
+
if (scopeList.length === 0 || !scopeList.every((scope) => SCOPE_RE.test(scope))) {
|
|
83
|
+
error(`Invalid --scopes value. Use space-delimited scopes, e.g. "analytics:read".`);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
const scopes = scopeList.join(" ");
|
|
87
|
+
const codeVerifier = generateCodeVerifier();
|
|
88
|
+
const state = generateState();
|
|
89
|
+
const server = await startLoopbackServer(state);
|
|
90
|
+
try {
|
|
91
|
+
const authorizeUrl = new URL("/oauth/authorize", origin);
|
|
92
|
+
authorizeUrl.searchParams.set("response_type", "code");
|
|
93
|
+
authorizeUrl.searchParams.set("client_id", CLI_OAUTH_CLIENT_ID);
|
|
94
|
+
authorizeUrl.searchParams.set("redirect_uri", server.redirectUri);
|
|
95
|
+
authorizeUrl.searchParams.set("scope", scopes);
|
|
96
|
+
authorizeUrl.searchParams.set("state", state);
|
|
97
|
+
authorizeUrl.searchParams.set("code_challenge", computeS256CodeChallenge(codeVerifier));
|
|
98
|
+
authorizeUrl.searchParams.set("code_challenge_method", "S256");
|
|
99
|
+
log("Open this URL in your browser to sign in:");
|
|
100
|
+
log("");
|
|
101
|
+
log(` ${authorizeUrl.toString()}`);
|
|
102
|
+
log("");
|
|
103
|
+
if (!values["no-browser"]) {
|
|
104
|
+
openBrowser(authorizeUrl.toString());
|
|
105
|
+
}
|
|
106
|
+
success("Waiting for the browser sign-in to complete (5 minute timeout)...");
|
|
107
|
+
const { code } = await server.waitForCallback(CALLBACK_TIMEOUT_MS);
|
|
108
|
+
const tokens = await exchangeAuthorizationCode(baseUrl, {
|
|
109
|
+
code,
|
|
110
|
+
codeVerifier,
|
|
111
|
+
redirectUri: server.redirectUri,
|
|
112
|
+
});
|
|
113
|
+
// Last-writer-wins: of two racing logins for the same origin, the later
|
|
114
|
+
// save is the one that sticks (see token-store.ts concurrency model).
|
|
115
|
+
const entry = toStoredEntry(tokens);
|
|
116
|
+
try {
|
|
117
|
+
await saveStoredEntry(origin, entry);
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
// The exchange already minted a LIVE server-side grant, and we are
|
|
121
|
+
// about to discard the only refresh token that could disconnect it
|
|
122
|
+
// (ENOSPC/permissions on the save). Best-effort revoke so no orphaned
|
|
123
|
+
// grant lingers on the server, then surface the original error.
|
|
124
|
+
try {
|
|
125
|
+
await revokeToken(baseUrl, tokens.refresh_token);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// Best effort: the user can also revoke from Connected apps.
|
|
129
|
+
}
|
|
130
|
+
throw err;
|
|
131
|
+
}
|
|
132
|
+
success(`Logged in to ${origin}`);
|
|
133
|
+
// Scope + expiry only -- NEVER print token values.
|
|
134
|
+
log(`Scopes: ${entry.scope || "(none reported)"}`);
|
|
135
|
+
log(`Access token expires: ${new Date(entry.expires_at).toISOString()}`);
|
|
136
|
+
log(`Credentials stored in: ${credentialsFilePath()}`);
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
await server.close();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAyCA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiD1D"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { GLOBAL_OPTIONS, resolveBaseAndFormat } from "../lib/config.js";
|
|
4
|
+
import { log, success, warn } from "../lib/logger.js";
|
|
5
|
+
import { revokeToken } from "../lib/oauth/token-endpoint.js";
|
|
6
|
+
import { clearTokenStore, credentialsFilePath, deleteStoredEntry, readStoredEntry, readTokenStore, } from "../lib/oauth/token-store.js";
|
|
7
|
+
const HELP = `Usage: framedash logout [options]
|
|
8
|
+
|
|
9
|
+
Sign out of a stored OAuth login (created by 'framedash login'): revokes the
|
|
10
|
+
session server-side (best effort) and removes the locally stored tokens for
|
|
11
|
+
the resolved base URL. API keys (FRAMEDASH_API_KEY etc.) are not affected.
|
|
12
|
+
|
|
13
|
+
Options:
|
|
14
|
+
--all Revoke and remove ALL stored logins for every origin
|
|
15
|
+
--base-url <url> API base URL (default: https://app.framedash.dev)
|
|
16
|
+
-h, --help Show help`;
|
|
17
|
+
/**
|
|
18
|
+
* Best-effort server-side revocation of the refresh token (RFC 7009 kills
|
|
19
|
+
* the whole grant). A transport failure only warns: the local credentials
|
|
20
|
+
* are removed regardless, and an unreachable server must not block logout.
|
|
21
|
+
*/
|
|
22
|
+
async function bestEffortRevoke(origin, refreshToken) {
|
|
23
|
+
try {
|
|
24
|
+
await revokeToken(origin, refreshToken);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
warn(`Could not revoke the server-side session for ${origin} ` +
|
|
28
|
+
`(${err instanceof Error ? err.message : String(err)}); removing local credentials anyway. ` +
|
|
29
|
+
`You can also revoke it from the dashboard's Connected apps page.`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function logout(args) {
|
|
33
|
+
const { values } = parseArgs({
|
|
34
|
+
args,
|
|
35
|
+
options: { ...GLOBAL_OPTIONS, all: { type: "boolean" } },
|
|
36
|
+
allowPositionals: false,
|
|
37
|
+
});
|
|
38
|
+
if (values.help) {
|
|
39
|
+
log(HELP);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (values.all) {
|
|
43
|
+
const store = readTokenStore();
|
|
44
|
+
const origins = Object.keys(store);
|
|
45
|
+
const hadFile = existsSync(credentialsFilePath());
|
|
46
|
+
for (const origin of origins) {
|
|
47
|
+
const entry = store[origin];
|
|
48
|
+
if (entry) {
|
|
49
|
+
await bestEffortRevoke(origin, entry.refresh_token);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Always clear: this removes the file (including the corrupt/unparseable
|
|
53
|
+
// case, which still holds token material) AND reaps any orphaned
|
|
54
|
+
// credentials.json.*.tmp files from crashed writes.
|
|
55
|
+
await clearTokenStore();
|
|
56
|
+
if (origins.length > 0) {
|
|
57
|
+
success(`Logged out of ${origins.length} origin(s); credentials file removed.`);
|
|
58
|
+
}
|
|
59
|
+
else if (hadFile) {
|
|
60
|
+
success("Removed the local credentials file (it contained no parseable logins; " +
|
|
61
|
+
"server-side revocation was skipped).");
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
log("No stored logins.");
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const { baseUrl } = resolveBaseAndFormat(values);
|
|
69
|
+
const origin = new URL(baseUrl).origin;
|
|
70
|
+
const entry = readStoredEntry(origin);
|
|
71
|
+
if (!entry) {
|
|
72
|
+
log(`No stored login for ${origin}.`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
await bestEffortRevoke(origin, entry.refresh_token);
|
|
76
|
+
await deleteStoredEntry(origin);
|
|
77
|
+
success(`Logged out of ${origin}`);
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { type UploadCredential } from "../lib/uploader.js";
|
|
1
2
|
/** CLI entry point for map-capture — parses args then delegates to mapCapture(). */
|
|
2
3
|
export declare function mapCaptureCommand(args: string[]): Promise<void>;
|
|
3
4
|
export type MapCaptureOptions = {
|
|
4
5
|
inputDir: string | undefined;
|
|
5
6
|
upload: boolean | undefined;
|
|
6
7
|
dryRun: boolean | undefined;
|
|
7
|
-
|
|
8
|
+
credential: UploadCredential | undefined;
|
|
8
9
|
projectId: string | undefined;
|
|
9
10
|
baseUrl: string | undefined;
|
|
10
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-capture.d.ts","sourceRoot":"","sources":["../../src/commands/map-capture.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"map-capture.d.ts","sourceRoot":"","sources":["../../src/commands/map-capture.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,gBAAgB,EAAoB,MAAM,oBAAoB,CAAC;AAqC7E,oFAAoF;AACpF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCrE;AA4BD,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,UAAU,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACzC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkJnF"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { readdir, readFile, realpath, stat } from "node:fs/promises";
|
|
2
2
|
import { extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
3
3
|
import { parseArgs } from "node:util";
|
|
4
|
-
import {
|
|
4
|
+
import { resolveCredential } from "../lib/config.js";
|
|
5
|
+
import { getSharedOAuthManager } from "../lib/create-client.js";
|
|
5
6
|
import { error, log, success } from "../lib/logger.js";
|
|
6
7
|
import { mapCaptureMetadataSchema } from "../lib/metadata.js";
|
|
7
8
|
import { uploadMapCapture } from "../lib/uploader.js";
|
|
@@ -21,7 +22,9 @@ Upload options (all required together):
|
|
|
21
22
|
--api-key <key> API key (needs the resources:write scope). Prefer
|
|
22
23
|
FRAMEDASH_API_KEY env or --api-key-file: a key passed
|
|
23
24
|
as --api-key is visible in the process list and shell
|
|
24
|
-
history.
|
|
25
|
+
history. Without any API key, a stored browser login
|
|
26
|
+
('framedash login --scopes "analytics:read
|
|
27
|
+
resources:write"') is used.
|
|
25
28
|
--api-key-file <path> Read the API key from a file ('-' for stdin)
|
|
26
29
|
--project-id <uuid> Target project ID, or set FRAMEDASH_PROJECT_ID env
|
|
27
30
|
|
|
@@ -56,22 +59,47 @@ export async function mapCaptureCommand(args) {
|
|
|
56
59
|
log(MAP_CAPTURE_HELP);
|
|
57
60
|
return;
|
|
58
61
|
}
|
|
59
|
-
// Resolve
|
|
62
|
+
// Resolve credentials only when an upload will actually run, so a validation
|
|
60
63
|
// dry run with --api-key-file - does not block on stdin (or fail on a missing
|
|
61
|
-
// file) for a
|
|
64
|
+
// file) for a credential it never uses.
|
|
62
65
|
const willUpload = Boolean(values.upload) && !values["dry-run"];
|
|
66
|
+
const baseUrl = values["base-url"] ?? "https://app.framedash.dev";
|
|
63
67
|
const result = await mapCapture({
|
|
64
68
|
inputDir: values["input-dir"],
|
|
65
69
|
upload: values.upload,
|
|
66
70
|
dryRun: values["dry-run"],
|
|
67
|
-
|
|
71
|
+
credential: willUpload ? resolveUploadCredential(values, baseUrl) : undefined,
|
|
68
72
|
projectId: values["project-id"] ?? process.env.FRAMEDASH_PROJECT_ID,
|
|
69
|
-
baseUrl
|
|
73
|
+
baseUrl,
|
|
70
74
|
});
|
|
71
75
|
if (!result.ok) {
|
|
72
76
|
process.exit(1);
|
|
73
77
|
}
|
|
74
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Map the CLI-wide credential resolution (api-key flag/file/env > stored
|
|
81
|
+
* OAuth login) onto the uploader's credential shape. OAuth rides on the
|
|
82
|
+
* process-shared token manager so uploads participate in the same
|
|
83
|
+
* refresh-rotation state as every other client.
|
|
84
|
+
*/
|
|
85
|
+
function resolveUploadCredential(values, baseUrl) {
|
|
86
|
+
let resolved;
|
|
87
|
+
try {
|
|
88
|
+
resolved = resolveCredential(values, baseUrl);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
// resolveCredential parses the base URL; map-capture does not pre-validate
|
|
92
|
+
// --base-url, so surface a clean CLI error instead of an uncaught throw.
|
|
93
|
+
error(`Invalid --base-url: ${err instanceof Error ? err.message : String(err)}`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
if (!resolved)
|
|
97
|
+
return undefined;
|
|
98
|
+
if (resolved.kind === "api-key") {
|
|
99
|
+
return { kind: "api-key", apiKey: resolved.apiKey };
|
|
100
|
+
}
|
|
101
|
+
return { kind: "oauth", manager: getSharedOAuthManager(baseUrl, resolved) };
|
|
102
|
+
}
|
|
75
103
|
export async function mapCapture(opts) {
|
|
76
104
|
const fail = { ok: false, successCount: 0, errorCount: 0 };
|
|
77
105
|
if (!opts.inputDir) {
|
|
@@ -81,8 +109,9 @@ export async function mapCapture(opts) {
|
|
|
81
109
|
const upload = Boolean(opts.upload);
|
|
82
110
|
const dryRun = Boolean(opts.dryRun);
|
|
83
111
|
if (upload && !dryRun) {
|
|
84
|
-
if (!opts.
|
|
85
|
-
error("--api-key
|
|
112
|
+
if (!opts.credential) {
|
|
113
|
+
error("--api-key, --api-key-file, FRAMEDASH_API_KEY, or a stored 'framedash login' " +
|
|
114
|
+
"is required with --upload");
|
|
86
115
|
return fail;
|
|
87
116
|
}
|
|
88
117
|
if (!opts.projectId) {
|
|
@@ -177,7 +206,7 @@ export async function mapCapture(opts) {
|
|
|
177
206
|
const uploadResult = await uploadMapCapture({
|
|
178
207
|
metadata,
|
|
179
208
|
imagePath,
|
|
180
|
-
|
|
209
|
+
credential: opts.credential,
|
|
181
210
|
projectId: opts.projectId,
|
|
182
211
|
baseUrl: opts.baseUrl ?? "https://app.framedash.dev",
|
|
183
212
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map-capture.js","sourceRoot":"","sources":["../../src/commands/map-capture.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"map-capture.js","sourceRoot":"","sources":["../../src/commands/map-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,QAAQ,mCAEnB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { formatOutput } from "../lib/formatters.js";
|
|
2
|
+
import { log } from "../lib/logger.js";
|
|
3
|
+
import { runCommand, withSubcommands } from "../lib/run-command.js";
|
|
4
|
+
const HELP = `Usage: framedash projects <subcommand> [options]
|
|
5
|
+
|
|
6
|
+
List the projects your credentials can read, including each project's id
|
|
7
|
+
(required by --project-id / FRAMEDASH_PROJECT_ID for most other commands).
|
|
8
|
+
|
|
9
|
+
Subcommands:
|
|
10
|
+
list List projects
|
|
11
|
+
|
|
12
|
+
Run 'framedash projects <subcommand> --help' for more info.`;
|
|
13
|
+
export const projects = withSubcommands("projects", HELP, {
|
|
14
|
+
list: projectsList,
|
|
15
|
+
});
|
|
16
|
+
async function projectsList(args) {
|
|
17
|
+
await runCommand({
|
|
18
|
+
args,
|
|
19
|
+
help: "Usage: framedash projects list [--format json|table|csv] [global options]",
|
|
20
|
+
noProject: true,
|
|
21
|
+
}, async ({ client, config }) => {
|
|
22
|
+
const data = await client.get("/api/v1/projects");
|
|
23
|
+
log(formatOutput(data, config.format));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=projects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,IAAI,GAAG;;;;;;;;4DAQ+C,CAAC;AAE7D,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CAAC,UAAU,EAAE,IAAI,EAAE;IACzD,IAAI,EAAE,YAAY;CAClB,CAAC,CAAC;AAEH,KAAK,UAAU,YAAY,CAAC,IAAc;IACzC,MAAM,UAAU,CACf;QACC,IAAI;QACJ,IAAI,EAAE,2EAA2E;QACjF,SAAS,EAAE,IAAI;KACf,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;QAC5B,MAAM,IAAI,GACT,MAAM,MAAM,CAAC,GAAG,CAAoD,kBAAkB,CAAC,CAAC;QACzF,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACxC,CAAC,CACD,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAMA,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/commands/query.ts"],"names":[],"mappings":"AAMA,wBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDzD"}
|