Skip to content

Update to latest API#2

Merged
yosriady merged 7 commits into
mainfrom
chore/update
May 3, 2026
Merged

Update to latest API#2
yosriady merged 7 commits into
mainfrom
chore/update

Conversation

@yosriady
Copy link
Copy Markdown
Contributor

@yosriady yosriady commented May 3, 2026

No description provided.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the CLI to accommodate a flatter API response structure by removing response envelopes in tests and the API key validation logic. It also renames pagination parameters from limit/offset to page/size and introduces a new api command for raw API access via OpenAPI specifications. Additionally, error handling has been enhanced to provide more detailed feedback. Feedback was provided to optimize the request forwarding utility by streaming the request body instead of buffering it in memory to avoid potential performance and memory issues.

Comment thread src/lib/forward.ts Outdated
Comment on lines +23 to +25
if (req.method !== 'GET' && req.method !== 'HEAD') {
init.body = await req.text()
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Buffering the entire request body into memory as a string using req.text() is inefficient for large payloads and can lead to memory exhaustion or issues with binary data. Since this is a proxy-like forwarding function, it is better to pass the request body stream directly to fetch. Note that in Node.js environments, when passing a stream as a body to fetch, you must also set the duplex property to 'half'.

Suggested change
if (req.method !== 'GET' && req.method !== 'HEAD') {
init.body = await req.text()
}
if (req.body) {
init.body = req.body
// @ts-ignore - duplex is required for streaming bodies in Node.js fetch
init.duplex = 'half'
}

yosriady and others added 6 commits May 3, 2026 16:32
Re-vendor openapi.json from formono and update list-endpoint tests to
consume the new PaginatedResponse<T> envelope ({ data, total, page,
size, has_more }). Charts list now reads res.data (was res.charts);
contracts list now reads res.data + res.deploy (was res.contracts +
top-level deployAt/deployDiff). New getContract op surfaces
automatically via `formo api getContract`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the auto-generated passthrough subcommands and the vendored
openapi.json (~215KB). The hand-written commands (alerts, boards,
charts, contracts, segments, profiles, query, import) cover the
human-facing surface; raw access wasn't paying its weight in bundle
size and discoverability cost.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 11 failing integration tests were all hitting api.formo.so and
returning 401 — the configured TEST_TOKEN is unauthorized. Probe the
API once via /api/validate-api-key at suite startup; if the probe
returns 401/403 (or the host is unreachable), every test that needs
the live API skips with a clear stderr message instead of producing a
wall of identical 401 stack traces.

Action item for CI: rotate TEST_TOKEN to a key with the required
scopes (alerts:read, boards:read, charts:read, contracts:read,
segments:read, profiles:read, query:read).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Wire the three new /v0/profiles/{address}/(properties|labels)
endpoints into the profiles subcommand surface:

- profiles set-properties <address> --properties '<json>' → PUT
  identity properties (display_name, twitter, ens, etc.). Only the
  22 allowed keys are accepted server-side.
- profiles add-label <address> --tagId <id> [--value <v>] [--chainId <c>]
  or --labels '<json>' → POST a single label or batch upsert.
- profiles remove-label <address> --tagId <id> [--chainId <c>] →
  DELETE the label from the profile.

Local validation: properties must be a non-empty JSON object; labels
must be either a single tagId or a non-empty JSON array; remove-label
requires tagId. Wired up tests for each validation path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Move the ad-hoc verb-noun commands onto the established CRUD verb
conventions used elsewhere in the CLI:

- profiles set-properties → profiles update
- profiles add-label      → profiles labels create
- profiles remove-label   → profiles labels delete

`labels` is now a proper sub-resource group under profiles (mirrors
the URL /v0/profiles/{address}/labels) so future label operations
slot in cleanly. Single-verb naming matches alerts/boards/charts/
contracts/segments. Tests renamed to track the new helper exports.

README rewritten to cover the full surface — auth (login/logout/
status), profiles (get, search, update, labels create/delete),
alerts, boards, charts, contracts, segments, query, import — plus
FilterCondition reference, response shapes, and output flags.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two big coverage gaps closed without a network-mock library:

1. parseApiError() — exported from src/lib/client.ts, the function the
   axios response interceptor delegates to. Six tests cover the
   canonical { error: { code, message, doc_url, param, details } }
   envelope, fallback to axios message when no envelope, transport
   errors with no response, and the multi-line message construction
   (Param/Docs lines elided when absent).

2. Body builders — extracted from each *Run() helper into pure
   build*Body() functions so we can test the camelCase→snake_case key
   translation (triggerType→trigger_type, chainId→chain_id, etc.),
   JSON parsing of nested fields (triggerFilters, recipient, abi,
   events, filterSets, properties, labels), single-vs-batch label
   dispatch, and what isn't included in update bodies (e.g. path
   params don't leak in). 17 new tests across alerts, contracts,
   segments, import, profiles update, and labels create/delete.

Net: 47 → 68 tests passing, no new dependencies, no behavior change in
the run helpers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yosriady yosriady merged commit 03821e0 into main May 3, 2026
5 checks passed
@yosriady yosriady deleted the chore/update branch May 3, 2026 11:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant