From 666413a8352649d58efd12df3c323867d2ce4c6d Mon Sep 17 00:00:00 2001 From: lentil32 Date: Fri, 10 Apr 2026 16:56:26 +0900 Subject: [PATCH 1/2] remove plan --- docs/cli-source-api-spec.md | 562 ------------------------------------ 1 file changed, 562 deletions(-) delete mode 100644 docs/cli-source-api-spec.md diff --git a/docs/cli-source-api-spec.md b/docs/cli-source-api-spec.md deleted file mode 100644 index 094deab4..00000000 --- a/docs/cli-source-api-spec.md +++ /dev/null @@ -1,562 +0,0 @@ -# Spec: rewrite `onequery use` as the source API client - -## Decision summary - -- Public command name stays **`onequery use`** in this cutover. -- Internal architecture, modules, and RPC names use **`source_api`**, not `use`. -- This is a **hard cutover**. Do not keep backward compatibility with the current provider-enum / markdown-skill behavior. -- `onequery use` becomes **source-key based**, not provider based. -- Both **describe** and **execute** go through **Connect RPC**. The CLI must not call `/api/data-sources/{provider}/query` directly. -- The server owns the canonical source API registry, validation, normalization, authorization hook, execution, and pagination state. - -## Current problems to remove - -- `UseSource` and `CliUseSource` duplicate the supported provider list across Rust, proto, and TypeScript. -- `onequery use` mixes two unrelated behaviors: load markdown skill text vs execute raw provider relay JSON. -- `load_use_skill()` uses Connect, but `execute_use_input()` bypasses Connect and posts to `/api/data-sources/{source}/query`. -- `packages/cli-server/src/use/skills.ts` is human documentation, not a canonical API descriptor. -- Provider request schemas live in `packages/server/src/routes/data-sources/*-query.ts`, separate from the CLI skill text. -- Current execution is provider-centric, not source-centric. It cannot cleanly support multiple connected sources of the same provider. -- Current `CommandOutput` is structured for normal CLI commands, not raw API-style status/headers/body output. - -## Final command contract - -### Usage - -```text -onequery use --source -onequery use --source [] [flags] -onequery use --source --op [] [flags] -``` - -### Resolution rules - -- `--source ` is required and always means the connected source key. -- Authenticated session and resolved org are required for both describe and execute. -- If only `--source` is provided, the command describes the source API surface. -- If `--op` is provided, positional `` is treated as the selector. -- If `--op` is not provided: - - if `` starts with `/`, `http://`, or `https://`, treat it as a selector and use the descriptor's `default_path_operation`; - - otherwise treat `` as the operation name. -- If request-construction flags are present but neither an operation nor a selector can be resolved, fail with a local parse error. - -### Flags - -- `--source `: required. -- `--op `: explicit operation name. -- `-X, --method `: only for `http_request` operations. -- `-H, --header `: repeated; allowed header names come from the descriptor. -- `-f, --raw-field `: repeated string field patch. -- `-F, --field `: repeated typed field patch. -- `--input `: request body input. -- `--paginate`: follow opaque server-issued page tokens. -- `--slurp`: combine paginated bodies into one JSON array before formatting. -- `--max-pages `: hard client-side pagination cap. -- `-i, --include`: include upstream status and allowed response headers. -- `--silent`: suppress body output. -- `-q, --jq `: apply JSON selection after response assembly. -- `--dry-run`: print normalized request plan with redactions; do not execute. - -### Request construction rules - -- `-f` always writes a string value. -- `-F` parses JSON first; otherwise parses `true`, `false`, `null`, integers, and floats; otherwise uses a string. -- `@path` and `@-` read UTF-8 text before parsing. -- `key[subkey]=value` builds nested objects. -- `key[]=value` appends array items. -- Duplicate writes to the same non-array path are a local error. -- `--input` behavior: - - for `structured_request`, parse JSON as the initial request object, then merge field patches over it; - - for `http_request`, treat input as the request body; field patches follow the operation's field policy. - -### Output contract - -Text mode: -- JSON body: pretty JSON. -- Text body: verbatim. -- Binary body: write raw bytes only when stdout is not a TTY; otherwise fail with a local render error. -- `--include`: print status line, allowed headers, blank line, then body. - -JSON mode: -- `onequery use` does **not** use the generic `{ ok, data }` envelope. -- It emits a command-specific API object. - -Example JSON-mode shape: - -```json -{ - "source": { "key": "github-prod", "provider": "github" }, - "operation": "fetch", - "selector": "/pulls", - "status": 200, - "headers": { - "content-type": "application/json" - }, - "contentType": "application/json", - "body": [{ "id": 1 }], - "requestId": "rq_123" -} -``` - -## Transport contract - -### Proto changes - -- Delete `proto/onequery/cli/v1/use.proto`. -- Add `proto/onequery/cli/v1/source_api.proto`. -- Update `proto/onequery/cli/v1/cli.proto`: - - remove `import "onequery/cli/v1/use.proto";` - - remove `rpc Use(UseRequest) returns (UseResponse);` - - add `rpc DescribeSourceApi(DescribeSourceApiRequest) returns (DescribeSourceApiResponse);` - - add `rpc NormalizeSourceApi(NormalizeSourceApiRequest) returns (NormalizeSourceApiResponse);` - - add `rpc ExecuteSourceApi(ExecuteSourceApiRequest) returns (ExecuteSourceApiResponse);` - -### Proto shape - -Use `google.protobuf.Struct` / `google.protobuf.Value` for dynamic JSON only where needed. - -```proto -message DescribeSourceApiRequest { - string org_slug = 1; - string source_key = 2; -} - -message DescribeSourceApiResponse { - CliSourceApiSource source = 1; - string descriptor_version = 2; - optional string default_path_operation = 3; - repeated CliSourceApiOperation operations = 4; - repeated CliSourceApiExample examples = 5; - repeated string notes = 6; -} - -message CliSourceApiInvocation { - string org_slug = 1; - string source_key = 2; - optional string descriptor_version = 3; - string operation = 4; - optional string selector = 5; - optional string method_override = 6; - repeated CliSourceApiHeader headers = 7; - optional google.protobuf.Struct field_patch = 8; - oneof body { - google.protobuf.Value json_body = 9; - string text_body = 10; - bytes binary_body = 11; - } - optional string page_token = 12; -} - -message NormalizeSourceApiRequest { - CliSourceApiInvocation invocation = 1; -} - -message NormalizeSourceApiResponse { - CliSourceApiPlan plan = 1; -} - -message ExecuteSourceApiRequest { - CliSourceApiInvocation invocation = 1; -} - -message ExecuteSourceApiResponse { - CliSourceApiSource source = 1; - string operation = 2; - optional string selector = 3; - uint32 status = 4; - repeated CliSourceApiHeader headers = 5; - string content_type = 6; - oneof body { - google.protobuf.Value json = 7; - string text = 8; - bytes binary = 9; - } - optional string request_id = 10; - optional string next_page_token = 11; -} - -message CliSourceApiPlan { - string source_id = 1; - string source_key = 2; - string provider = 3; - string operation = 4; - CliSourceApiOperationKind kind = 5; - optional string method = 6; - optional string selector = 7; - optional string selector_template = 8; - optional string host = 9; - repeated string header_names = 10; - CliSourceApiBodyKind body_kind = 11; - repeated string body_paths = 12; - string request_fingerprint = 13; - optional string descriptor_version = 14; -} -``` - -`CliSourceApiPlan` is the public, redacted projection of normalization. It must stay limited to stable planning data needed for `--dry-run`, pagination binding, and policy inspection. It must not expose transport-only execution internals such as the finalized request URL, normalized header values, request body payloads, adapter metadata, or structured request objects. - -Required descriptor fields: - -- `CliSourceApiSource`: `key`, `provider`, optional `display_name`. -- `CliSourceApiOperation`: - - `name` - - `kind`: `HTTP_REQUEST | STRUCTURED_REQUEST` - - `summary` - - `description` - - `selector_kind`: `NONE | PATH | IDENTIFIER` - - `selector_label` - - `method_policy`: default + allowed methods - - `field_policy`: raw field support, typed field support, syntax, transport rules - - `header_policy`: allowed request header names - - `pagination_policy`: `NONE | OPAQUE_TOKEN` - - repeated examples and notes - -### RPC rules - -- `DescribeSourceApi` must validate org access and source access. -- `NormalizeSourceApi` must validate org access, source access, operation validity, and return the canonical normalized plan without executing. -- `ExecuteSourceApi` must validate org access, source access, operation validity, and permission hooks before execution. -- Pagination tokens are opaque, short-lived, and bound to source key, operation, normalized request fingerprint, and descriptor version. -- The CLI never invents or decodes page tokens. - -## Server architecture - -### Canonical domain - -Add a single canonical source API domain under `packages/server/src/source-api/`: - -```text -packages/server/src/source-api/ - types.ts - registry.ts - describe.ts - normalize.ts - authorize.ts - execute.ts - policy.ts - adapters/ - github.ts - ga.ts - mongodb.ts - amplitude.ts - mixpanel.ts - posthog.ts - sentry.ts - helpers/ - http-rest.ts - structured.ts - pagination.ts -``` - -### Adapter contract - -Each provider adapter implements: - -```ts -type SourceApiAdapter = { - provider: ProviderType; - describe(input: { source: ConnectedSource; actor: ActorContext }): Promise; - normalize(input: { - source: ConnectedSource; - actor: ActorContext; - descriptor: SourceApiDescriptor; - request: CliSourceApiInvocation; - }): Promise; - execute(input: { - source: ConnectedSource; - actor: ActorContext; - plan: NormalizedExecutionPlan; - }): Promise; -}; -``` - -### Required pipeline - -All execution must follow this order: - -```text -describe -> normalize -> authorize -> execute -``` - -Do not authorize or execute directly from raw CLI args or raw RPC payloads. - -### Normalized plan - -`normalize.ts` must produce a canonical plan that is stable enough for later fine-grained permissions. - -```ts -type NormalizedExecutionPlan = { - sourceId: string; - sourceKey: string; - provider: ProviderType; - operation: string; - kind: "http_request" | "structured_request"; - method?: string; - selector?: string; - selectorTemplate?: string; - host?: string; - headerNames: string[]; - bodyKind: "none" | "json" | "text" | "binary"; - bodyPaths?: string[]; - requestFingerprint: string; - descriptorVersion?: string; -}; -``` - -`NormalizeSourceApiResponse.plan` is the typed public projection of this normalized plan, not the full internal execution object. - -### Adapter families - -Start with two helper families: - -- `http-rest.ts`: GitHub, Sentry, Amplitude, Mixpanel fallback REST, PostHog fallback REST. -- `structured.ts`: GA, MongoDB, other operation-driven providers. - -New providers should be added as descriptor + adapter code on top of one of these helpers whenever possible. - -### Route migration - -Current provider route logic must move into adapters: - -- `packages/server/src/routes/data-sources/github-query.ts` -> `packages/server/src/source-api/adapters/github.ts` -- `packages/server/src/routes/data-sources/ga-query.ts` -> `packages/server/src/source-api/adapters/ga.ts` -- `packages/server/src/routes/data-sources/mongodb-query.ts` -> `packages/server/src/source-api/adapters/mongodb.ts` -- same pattern for amplitude, mixpanel, posthog, sentry - -If `/api/data-sources/*/query` routes remain for non-CLI callers, they must become thin wrappers over the same source-api domain. They are not the CLI contract anymore. - -## CLI server architecture - -### Connect service - -Replace the `use` service handler with a source-api transport wrapper: - -```text -packages/cli-server/src/connect/service/source_api.ts -``` - -Responsibilities: -- resolve session and authorized org context; -- load source by `source_key`; -- call `packages/server/src/source-api/*`; -- map domain objects to generated Connect messages; -- never carry provider lists or markdown skills. - -### Required repo changes - -- Delete `packages/cli-server/src/use/skills.ts`. -- Delete `packages/cli-server/src/connect/service/use.ts`. -- Remove `CliUseSource` conversion helpers from `packages/cli-server/src/connect/service/conversions.ts`. -- Update `packages/cli-server/src/connect/service.ts` to register `describeSourceApi`, `normalizeSourceApi`, and `executeSourceApi`. -- Regenerate `packages/cli-server/src/connect/gen/**` from proto. - -## Rust CLI architecture - -### Args - -Replace the current `UseArgs` with a source-key based request builder. - -```rust -pub(crate) struct UseArgs { - pub source: String, - pub op: Option, - pub target: Option, - pub method: Option, - pub headers: Vec, - pub raw_fields: Vec, - pub fields: Vec, - pub input: Option, - pub paginate: bool, - pub slurp: bool, - pub max_pages: Option, - pub include: bool, - pub silent: bool, - pub jq: Option, - pub dry_run: bool, -} -``` - -### Modules - -Add: - -```text -apps/cli/crates/onequery-cli/src/commands/source_api/ - mod.rs - args.rs - intent.rs - field_patch.rs - plan.rs - workflow.rs - render.rs - format.rs - tests.rs - -apps/cli/crates/onequery-cli/src/transport/source_api.rs -``` - -Remove: - -- `apps/cli/crates/onequery-cli/src/transport/use_source.rs` -- `apps/cli/crates/onequery-cli/src/transport/use_cmd.rs` -- current `apps/cli/crates/onequery-cli/src/commands/use_cmd.rs` - -`commands/use_cmd.rs` may remain only as a tiny compatibility-free delegate to `commands::source_api::execute()` if that keeps command registration simpler. - -### CLI rules - -- Clap must parse `--source` as a plain string, not `ValueEnum`. -- All describe/execute behavior must depend on the server descriptor, not Rust enums. -- The CLI must load the descriptor before it decides how to interpret fields, headers, pagination, selector shape, or output formatting. - -### Output - -`CommandOutput` must support an API response mode. - -Required design: - -```rust -enum OutputPayload { - Structured { data: Value }, - Api { - status: Option, - headers: Vec<(String, String)>, - body: ApiBody, - request_id: Option, - }, -} -``` - -`onequery use` must render through `OutputPayload::Api`, not the generic structured JSON envelope. - -## Authorization design - -### Coarse actions - -Add two explicit CLI actions: - -- `source_api.describe` -- `source_api.execute` - -Do not overload `source.list` or `query.execute` for the new command. - -### Fine-grained hook - -Do not ship endpoint/method rules in this cutover, but the hook must exist now. - -Required server function: - -```ts -authorizeSourceApi(plan: NormalizedExecutionPlan, actor: ActorContext): Promise -``` - -The initial implementation may only enforce coarse capability checks, but it must receive the normalized plan so method/selector-specific rules can be added later without changing the execution pipeline. - -## Implementation checklists - -### 1) Proto and generation - -- [x] Add `proto/onequery/cli/v1/source_api.proto`. -- [x] Delete `proto/onequery/cli/v1/use.proto`. -- [x] Update `proto/onequery/cli/v1/cli.proto` imports and RPCs. -- [ ] Add generated TS and Rust code for the new RPCs and messages. -- [ ] Remove generated `use_pb` references from TS and Rust. - -### 2) Server source-api domain - -- [x] Add `packages/server/src/source-api/types.ts` with canonical descriptor, plan, response, and policy types. -- [x] Add `packages/server/src/source-api/registry.ts`. -- [x] Add `describe.ts`, `normalize.ts`, `authorize.ts`, and `execute.ts`. -- [x] Add `helpers/http-rest.ts`. -- [x] Add `helpers/structured.ts`. -- [x] Add opaque pagination token helper in `helpers/pagination.ts`. -- [x] Export the new domain from `@onequery/server` if needed by `@onequery/cli-server`. - -### 3) Provider migration - -- [x] Move GitHub relay behavior from `routes/data-sources/github-query.ts` into `source-api/adapters/github.ts`. -- [x] Move GA relay behavior from `routes/data-sources/ga-query.ts` into `source-api/adapters/ga.ts`. -- [x] Move MongoDB relay behavior from `routes/data-sources/mongodb-query.ts` into `source-api/adapters/mongodb.ts`. -- [x] Move Amplitude, Mixpanel, PostHog, and Sentry relay behavior into corresponding adapters. -- [x] Keep request validation next to the adapter definition; do not leave runtime schema in the old route file. -- [x] Remove markdown skill content as a source of truth. - -### 4) CLI server transport - -- [x] Add `packages/cli-server/src/connect/service/source_api.ts`. -- [x] Replace `handleUse` registration in `packages/cli-server/src/connect/service.ts`. -- [x] Remove `packages/cli-server/src/use/skills.ts`. -- [x] Remove `fromCliUseSource` / `toCliUseSourceEnum` from `packages/cli-server/src/connect/service/conversions.ts`. -- [x] Add conversions for source-api descriptor, normalize plan, and execute response messages. -- [x] Update tests to call `DescribeSourceApi`, `NormalizeSourceApi`, and `ExecuteSourceApi`. - -### 5) Rust CLI parser and transport - -- [x] Replace `UseArgs` in `apps/cli/crates/onequery-cli/src/cli/args.rs`. -- [x] Remove `UseSource` enum usage from `cli/mod.rs`, `labels.rs`, and any snapshots. -- [x] Add `commands/source_api/*` modules. -- [x] Add `transport/source_api.rs`. -- [x] Delete `transport/use_source.rs` and `transport/use_cmd.rs`. -- [x] Replace `commands/use_cmd.rs` implementation. -- [x] Update help text and usage snapshots for `onequery use`. - -### 6) Output and formatting - -- [x] Extend `apps/cli/crates/onequery-cli/src/output.rs` with API output mode. -- [x] Ensure JSON mode for `onequery use` bypasses the generic `{ ok, data }` envelope. -- [x] Support `--include`, `--silent`, `--paginate`, `--slurp`, and `--jq` in the source-api renderer. -- [x] Reject binary-to-TTY output with a clear render error. - -### 7) Authorization hook - -- [x] Add `source_api.describe` and `source_api.execute` to `packages/cli-server/src/authorization.ts` and underlying org permission wiring. -- [x] Add `authorizeSourceApi(plan, actor)` to the server source-api domain. -- [x] Call the authorization hook after normalization and before execution. -- [x] Ensure the plan includes method, selector, headers, and body kind even before fine-grained policy rules ship. - -### 8) Remove current `use` architecture - -- [ ] Delete all `CliUseSource` references from proto, TS, and Rust. -- [x] Delete markdown skill registry behavior. -- [ ] Delete direct CLI HTTP calls to `/api/data-sources/{provider}/query`. -- [ ] Delete provider-specific retry/help text that assumes `--source` is a provider enum. - -## Test checklist - -### Rust CLI - -- [x] Parse `-f`, `-F`, nested object syntax, array syntax, and `@file` input. -- [x] Resolve describe vs execute intent correctly. -- [x] Resolve `TARGET` as operation vs selector correctly. -- [x] Render JSON/text/binary responses correctly. -- [x] Render `--include`, `--paginate`, `--slurp`, and `--jq` correctly. - -### CLI server / proto - -- [x] `DescribeSourceApi` rejects missing org/source access. -- [x] `ExecuteSourceApi` rejects unsupported operations and invalid headers. -- [x] `descriptor_version` mismatch returns a deterministic invalid-request or failed-precondition error. -- [x] pagination tokens round-trip only for the same normalized request. - -### Source-api domain - -- [ ] Every descriptor example parses and normalizes successfully. -- [ ] Every described operation is executable by its adapter. -- [ ] Header allowlists are enforced. -- [ ] Normalized plan is stable for the same logical request. -- [ ] Authorization hook receives the normalized plan before execution. - -### Extensibility - -- [ ] Adding a new operation to an existing provider requires no Rust enum changes. -- [ ] Adding a new provider adapter requires no proto enum changes. -- [ ] Adding a new provider adapter requires no CLI parsing changes unless new generic flags are introduced. - -## Acceptance criteria - -- [ ] `onequery use --source ` describes the live source API surface for that connected source. -- [ ] `onequery use --source /path ...` executes through Connect only. -- [ ] No part of the CLI depends on a hard-coded provider list for `use`. -- [ ] No part of the source API surface is documented only in markdown. -- [ ] The server owns source API descriptors, normalization, authorization hooks, execution, and pagination state. -- [ ] The command is ready for later endpoint/method-specific permissions without changing the high-level pipeline. From 9055804f4f3af332b591eee6d8d00680bdb594db Mon Sep 17 00:00:00 2001 From: lentil32 Date: Fri, 10 Apr 2026 17:42:48 +0900 Subject: [PATCH 2/2] feat(cli): rename source API command to api --- apps/cli/crates/onequery-cli/src/cli/args.rs | 2 +- apps/cli/crates/onequery-cli/src/cli/mod.rs | 2 +- apps/cli/crates/onequery-cli/src/cli/model.rs | 6 +-- apps/cli/crates/onequery-cli/src/cli/raw.rs | 12 ++--- apps/cli/crates/onequery-cli/src/cli_tests.rs | 26 ++++----- .../onequery-cli/src/commands/json_input.rs | 12 ++--- .../crates/onequery-cli/src/commands/mod.rs | 2 +- .../src/commands/source_api/args.rs | 4 +- .../src/commands/source_api/field_patch.rs | 2 +- .../src/commands/source_api/intent.rs | 50 ++++++++--------- .../src/commands/source_api/mod.rs | 22 ++++---- .../src/commands/source_api/plan.rs | 54 +++++++++---------- .../src/commands/source_api/render.rs | 34 ++++++------ ..._output_snapshot_targets_api_surface.snap} | 8 +-- ...config_commands_out_of_public_surface.snap | 2 +- apps/cli/justfile | 8 +-- packages/cli-server/src/cli-defaults.test.ts | 18 +++---- packages/cli-server/src/cli-defaults.ts | 12 ++--- .../src/connect/service/source_api.test.ts | 2 +- .../src/source-api/adapters/amplitude.ts | 2 +- packages/server/src/source-api/adapters/ga.ts | 4 +- .../server/src/source-api/adapters/github.ts | 4 +- .../src/source-api/adapters/mixpanel.ts | 8 +-- .../server/src/source-api/adapters/mongodb.ts | 6 +-- .../server/src/source-api/adapters/posthog.ts | 2 +- .../server/src/source-api/adapters/sentry.ts | 2 +- 26 files changed, 153 insertions(+), 153 deletions(-) rename apps/cli/crates/onequery-cli/src/snapshots/{onequery__cli__tests__use_help_output_snapshot_targets_use_surface.snap => onequery__cli__tests__api_help_output_snapshot_targets_api_surface.snap} (88%) diff --git a/apps/cli/crates/onequery-cli/src/cli/args.rs b/apps/cli/crates/onequery-cli/src/cli/args.rs index 515adeb0..46f2cacf 100644 --- a/apps/cli/crates/onequery-cli/src/cli/args.rs +++ b/apps/cli/crates/onequery-cli/src/cli/args.rs @@ -263,7 +263,7 @@ onequery query validate [OPTIONS] --source --input } #[derive(Debug, Clone, Args, Eq, PartialEq)] -pub(crate) struct UseArgs { +pub(crate) struct ApiArgs { /// Describe or execute this connected source API. #[arg(long, value_name = "SOURCE_KEY")] pub source: String, diff --git a/apps/cli/crates/onequery-cli/src/cli/mod.rs b/apps/cli/crates/onequery-cli/src/cli/mod.rs index 54c7debd..fe1b45d7 100644 --- a/apps/cli/crates/onequery-cli/src/cli/mod.rs +++ b/apps/cli/crates/onequery-cli/src/cli/mod.rs @@ -9,6 +9,7 @@ mod raw; #[path = "../cli_tests.rs"] mod tests; +pub(crate) use args::ApiArgs; pub(crate) use args::AuthImportArgs; pub(crate) use args::AuthSessionSubcommand; pub(crate) use args::AuthSubcommand; @@ -27,7 +28,6 @@ pub(crate) use args::ReadArgs; pub(crate) use args::RestoreArgs; pub(crate) use args::SourceConnectArgs; pub(crate) use args::SourceSubcommand; -pub(crate) use args::UseArgs; pub(crate) use model::Command; pub(crate) use model::ConfigCommand; pub(crate) use model::GatewayCommand; diff --git a/apps/cli/crates/onequery-cli/src/cli/model.rs b/apps/cli/crates/onequery-cli/src/cli/model.rs index 0d676285..98de329e 100644 --- a/apps/cli/crates/onequery-cli/src/cli/model.rs +++ b/apps/cli/crates/onequery-cli/src/cli/model.rs @@ -2,6 +2,7 @@ use crate::config::RawCliConfigOverrides; use crate::output::EffectiveOutputMode; use crate::output::TerminalOutput; +use super::args::ApiArgs; use super::args::AuthSessionSubcommand; use super::args::AuthSubcommand; use super::args::BackupArgs; @@ -10,7 +11,6 @@ use super::args::OrgSubcommand; use super::args::QuerySubcommand; use super::args::RestoreArgs; use super::args::SourceSubcommand; -use super::args::UseArgs; #[derive(Debug)] pub(crate) enum ParseOutcome { @@ -46,7 +46,7 @@ pub(crate) enum Command { Restore(RestoreArgs), Gateway(GatewayCommand), Upgrade, - Use(UseArgs), + Api(ApiArgs), Debug(DebugSubcommand), } @@ -78,7 +78,7 @@ impl Command { Self::Gateway(GatewayCommand::Status) => "gateway status", Self::Gateway(GatewayCommand::Logs) => "gateway logs", Self::Upgrade => "upgrade", - Self::Use(_) => "use", + Self::Api(_) => "api", Self::Debug(DebugSubcommand::Config) => "debug config", Self::Debug(DebugSubcommand::AuthSession) => "debug auth-session", } diff --git a/apps/cli/crates/onequery-cli/src/cli/raw.rs b/apps/cli/crates/onequery-cli/src/cli/raw.rs index 34da8c28..c0075f1e 100644 --- a/apps/cli/crates/onequery-cli/src/cli/raw.rs +++ b/apps/cli/crates/onequery-cli/src/cli/raw.rs @@ -4,6 +4,7 @@ use clap::Subcommand; use crate::output::RequestedOutputMode; +use super::args::ApiArgs; use super::args::AuthSubcommand; use super::args::BackupArgs; use super::args::DebugSubcommand; @@ -11,7 +12,6 @@ use super::args::OrgSubcommand; use super::args::QuerySubcommand; use super::args::RestoreArgs; use super::args::SourceSubcommand; -use super::args::UseArgs; use super::model::Command; use super::model::ConfigCommand; use super::model::GatewayCommand; @@ -124,10 +124,10 @@ pub(super) enum RawCommand { Upgrade, /// Describe or execute a connected source API. #[command(override_usage = "\ -onequery use [OPTIONS] --source - onequery use [OPTIONS] --source [] - onequery use [OPTIONS] --source --op []")] - Use(UseArgs), +onequery api [OPTIONS] --source + onequery api [OPTIONS] --source [] + onequery api [OPTIONS] --source --op []")] + Api(ApiArgs), /// Inspect local CLI state and diagnostics. #[command(hide = true, arg_required_else_help(true))] Debug { @@ -180,7 +180,7 @@ impl From for Command { RawCommand::Restore(args) => Self::Restore(args), RawCommand::Gateway { action } => Self::Gateway(action.into()), RawCommand::Upgrade => Self::Upgrade, - RawCommand::Use(args) => Self::Use(args), + RawCommand::Api(args) => Self::Api(args), RawCommand::Debug { action } => Self::Debug(action), } } diff --git a/apps/cli/crates/onequery-cli/src/cli_tests.rs b/apps/cli/crates/onequery-cli/src/cli_tests.rs index e1297b74..59ccc2df 100644 --- a/apps/cli/crates/onequery-cli/src/cli_tests.rs +++ b/apps/cli/crates/onequery-cli/src/cli_tests.rs @@ -11,6 +11,7 @@ use crate::output::EffectiveOutputMode; use crate::output::RequestedOutputMode; use crate::transport::source_connect_provider::SourceConnectProvider; +use super::ApiArgs; use super::AuthImportArgs; use super::AuthSessionSubcommand; use super::Command; @@ -23,7 +24,6 @@ use super::QueryInputArgs; use super::QueryResultWindowArgs; use super::QuerySubcommand; use super::ReadArgs; -use super::UseArgs; fn argv(args: &[&str]) -> Vec { args.iter().map(OsString::from).collect() @@ -71,8 +71,8 @@ fn query_help_output_snapshot_targets_query_surface() { } #[test] -fn use_help_output_snapshot_targets_use_surface() { - assert_snapshot!(rendered_display(&["onequery", "use", "--help"])); +fn api_help_output_snapshot_targets_api_surface() { + assert_snapshot!(rendered_display(&["onequery", "api", "--help"])); } #[test] @@ -348,15 +348,15 @@ fn normalize_command_line_redacts_raw_config_override_values() { } #[test] -fn parse_invocation_accepts_use_describe_surface() { - let invocation = parse_invocation(&["onequery", "use", "--source", "sentry-prod"]); +fn parse_invocation_accepts_api_describe_surface() { + let invocation = parse_invocation(&["onequery", "api", "--source", "sentry-prod"]); assert_eq!( match invocation.command { - Command::Use(args) => args, - other => panic!("expected use command, got {other:?}"), + Command::Api(args) => args, + other => panic!("expected api command, got {other:?}"), }, - UseArgs { + ApiArgs { source: "sentry-prod".to_owned(), op: None, target: None, @@ -377,10 +377,10 @@ fn parse_invocation_accepts_use_describe_surface() { } #[test] -fn parse_invocation_accepts_use_execute_flags() { +fn parse_invocation_accepts_api_execute_flags() { let invocation = parse_invocation(&[ "onequery", - "use", + "api", "--source", "github-prod", "--op", @@ -411,10 +411,10 @@ fn parse_invocation_accepts_use_execute_flags() { assert_eq!( match invocation.command { - Command::Use(args) => args, - other => panic!("expected use command, got {other:?}"), + Command::Api(args) => args, + other => panic!("expected api command, got {other:?}"), }, - UseArgs { + ApiArgs { source: "github-prod".to_owned(), op: Some("fetch-api".to_owned()), target: Some("/repos/acme/widgets/pulls/1".to_owned()), diff --git a/apps/cli/crates/onequery-cli/src/commands/json_input.rs b/apps/cli/crates/onequery-cli/src/commands/json_input.rs index e51d224e..ddab016b 100644 --- a/apps/cli/crates/onequery-cli/src/commands/json_input.rs +++ b/apps/cli/crates/onequery-cli/src/commands/json_input.rs @@ -75,15 +75,15 @@ mod tests { fn parse_org_scoped_json_input_rejects_non_object_payloads() { let error = parse_org_scoped_json_input( r#"["not","an","object"]"#, - &test_context("onequery use --source github --input "), - "invalid use input", - "use input", - || vec!["onequery use --source github".to_owned()], + &test_context("onequery api --source github --input "), + "invalid api input", + "api input", + || vec!["onequery api --source github".to_owned()], ) .expect_err("expected non-object input to be rejected"); - assert_eq!(error.title, "invalid use input"); - assert_eq!(error.why, "use input must be one JSON object"); + assert_eq!(error.title, "invalid api input"); + assert_eq!(error.why, "api input must be one JSON object"); } #[test] diff --git a/apps/cli/crates/onequery-cli/src/commands/mod.rs b/apps/cli/crates/onequery-cli/src/commands/mod.rs index 5a6a6e2f..eee9bd26 100644 --- a/apps/cli/crates/onequery-cli/src/commands/mod.rs +++ b/apps/cli/crates/onequery-cli/src/commands/mod.rs @@ -238,7 +238,7 @@ where gateway::execute(gateway_command, context, runtime).await } Command::Upgrade => upgrade::execute(context, runtime).await, - Command::Use(use_args) => source_api::execute(&use_args, context, runtime).await, + Command::Api(api_args) => source_api::execute(&api_args, context, runtime).await, Command::Debug(debug_command) => debug::execute(&debug_command, context, runtime).await, } } diff --git a/apps/cli/crates/onequery-cli/src/commands/source_api/args.rs b/apps/cli/crates/onequery-cli/src/commands/source_api/args.rs index e690bc0c..09706d33 100644 --- a/apps/cli/crates/onequery-cli/src/commands/source_api/args.rs +++ b/apps/cli/crates/onequery-cli/src/commands/source_api/args.rs @@ -6,12 +6,12 @@ use onequery_cli_core::error::ErrorStage; use tokio::fs; use tokio::io::AsyncReadExt; -use crate::cli::UseArgs; +use crate::cli::ApiArgs; use crate::path_utils::resolve_user_path_for_cli; use super::CommandContext; -pub(super) fn has_execute_intent_flags(args: &UseArgs) -> bool { +pub(super) fn has_execute_intent_flags(args: &ApiArgs) -> bool { args.op.is_some() || args.target.is_some() || args.method.is_some() diff --git a/apps/cli/crates/onequery-cli/src/commands/source_api/field_patch.rs b/apps/cli/crates/onequery-cli/src/commands/source_api/field_patch.rs index 0e16b963..c2566c11 100644 --- a/apps/cli/crates/onequery-cli/src/commands/source_api/field_patch.rs +++ b/apps/cli/crates/onequery-cli/src/commands/source_api/field_patch.rs @@ -479,7 +479,7 @@ mod tests { fn context() -> CommandContext { CommandContext { - command_line: "onequery use --source github-prod".to_owned(), + command_line: "onequery api --source github-prod".to_owned(), base_url: default_base_url(), request_id: None, resolved_org: Some("acme".to_owned()), diff --git a/apps/cli/crates/onequery-cli/src/commands/source_api/intent.rs b/apps/cli/crates/onequery-cli/src/commands/source_api/intent.rs index 37f4e667..168d2162 100644 --- a/apps/cli/crates/onequery-cli/src/commands/source_api/intent.rs +++ b/apps/cli/crates/onequery-cli/src/commands/source_api/intent.rs @@ -1,6 +1,6 @@ use onequery_cli_core::error::CliError; -use crate::cli::UseArgs; +use crate::cli::ApiArgs; use crate::transport::source_api::SourceApiDescriptor; use super::CommandContext; @@ -17,7 +17,7 @@ pub(super) enum ResolvedIntent { } pub(super) fn resolve_intent( - args: &UseArgs, + args: &ApiArgs, descriptor: &SourceApiDescriptor, context: &CommandContext, ) -> Result { @@ -80,7 +80,7 @@ fn is_selector_target(target: &str) -> bool { mod tests { use onequery_cli_core::error::ErrorStage; - use crate::cli::UseArgs; + use crate::cli::ApiArgs; use crate::commands::ResolvedOrgSource; use crate::config::default_base_url; use crate::transport::source_api::SourceApiDescriptor; @@ -92,7 +92,7 @@ mod tests { #[test] fn resolve_intent_describes_when_only_source_is_provided() { - let intent = resolve_intent(&use_args(), &descriptor(), &context()) + let intent = resolve_intent(&api_args(), &descriptor(), &context()) .expect("expected bare source usage to describe"); assert_eq!(intent, ResolvedIntent::Describe); @@ -101,9 +101,9 @@ mod tests { #[test] fn resolve_intent_executes_when_explicit_operation_is_provided() { let intent = resolve_intent( - &UseArgs { + &ApiArgs { op: Some(" fetch ".to_owned()), - ..use_args() + ..api_args() }, &descriptor(), &context(), @@ -122,17 +122,17 @@ mod tests { #[test] fn resolve_intent_describes_when_only_render_flags_are_provided() { for args in [ - UseArgs { + ApiArgs { include: true, - ..use_args() + ..api_args() }, - UseArgs { + ApiArgs { silent: true, - ..use_args() + ..api_args() }, - UseArgs { + ApiArgs { jq: Some(".items[0]".to_owned()), - ..use_args() + ..api_args() }, ] { let intent = resolve_intent(&args, &descriptor(), &context()) @@ -145,9 +145,9 @@ mod tests { #[test] fn resolve_intent_rejects_execute_flags_without_operation_or_selector() { let error = resolve_intent( - &UseArgs { + &ApiArgs { method: Some("POST".to_owned()), - ..use_args() + ..api_args() }, &descriptor(), &context(), @@ -164,9 +164,9 @@ mod tests { #[test] fn resolve_intent_treats_bare_target_as_operation() { let intent = resolve_intent( - &UseArgs { + &ApiArgs { target: Some("search".to_owned()), - ..use_args() + ..api_args() }, &descriptor(), &context(), @@ -185,9 +185,9 @@ mod tests { #[test] fn resolve_intent_treats_path_target_as_selector() { let intent = resolve_intent( - &UseArgs { + &ApiArgs { target: Some("/pulls".to_owned()), - ..use_args() + ..api_args() }, &descriptor(), &context(), @@ -206,9 +206,9 @@ mod tests { #[test] fn resolve_intent_treats_url_target_as_selector() { let intent = resolve_intent( - &UseArgs { + &ApiArgs { target: Some("https://api.github.com/repos/acme/widgets/pulls".to_owned()), - ..use_args() + ..api_args() }, &descriptor(), &context(), @@ -227,9 +227,9 @@ mod tests { #[test] fn resolve_intent_rejects_selector_target_without_default_path_operation() { let error = resolve_intent( - &UseArgs { + &ApiArgs { target: Some("/pulls".to_owned()), - ..use_args() + ..api_args() }, &descriptor_without_default_path_operation(), &context(), @@ -267,7 +267,7 @@ mod tests { fn context() -> CommandContext { CommandContext { - command_line: "onequery use --source github-prod".to_owned(), + command_line: "onequery api --source github-prod".to_owned(), base_url: default_base_url(), request_id: None, resolved_org: Some("acme".to_owned()), @@ -276,8 +276,8 @@ mod tests { } } - fn use_args() -> UseArgs { - UseArgs { + fn api_args() -> ApiArgs { + ApiArgs { source: "github-prod".to_owned(), op: None, target: None, diff --git a/apps/cli/crates/onequery-cli/src/commands/source_api/mod.rs b/apps/cli/crates/onequery-cli/src/commands/source_api/mod.rs index 9cd096d0..2fde803a 100644 --- a/apps/cli/crates/onequery-cli/src/commands/source_api/mod.rs +++ b/apps/cli/crates/onequery-cli/src/commands/source_api/mod.rs @@ -10,7 +10,7 @@ use std::time::Duration; use onequery_cli_core::error::CliError; use onequery_cli_core::error::ErrorStage; -use crate::cli::UseArgs; +use crate::cli::ApiArgs; use crate::output::CommandOutput; use crate::presentation::api_failure::ApiErrorPresentation; use crate::presentation::api_failure::present_api_failure; @@ -30,7 +30,7 @@ use render::render_dry_run_output; use render::render_execute_output; pub(super) async fn execute( - args: &UseArgs, + args: &ApiArgs, context: &CommandContext, runtime: &mut Runtime, ) -> Result { @@ -51,7 +51,7 @@ pub(super) async fn execute( title: "source API describe failed", transport_why_prefix: "failed to reach source API service", decode_why_prefix: "failed to decode source API descriptor", - fallback_try_next: vec![format!("onequery use --source {}", args.source)], + fallback_try_next: vec![format!("onequery api --source {}", args.source)], unauthorized_try_next: Some(vec!["onequery auth login".to_owned()]), }, ) @@ -103,7 +103,7 @@ async fn execute_source_api_pages( source_key: &str, request: &ExecuteSourceApiRequestPayload, execution: &SourceApiExecutionOptions, - args: &UseArgs, + args: &ApiArgs, context: &CommandContext, ) -> Result { let mut next_request = request.clone(); @@ -137,7 +137,7 @@ async fn execute_source_api_pages( fn present_source_api_normalize_failure( failure: crate::transport::http::ApiFailure, - args: &UseArgs, + args: &ApiArgs, context: &CommandContext, ) -> CliError { present_api_failure( @@ -148,7 +148,7 @@ fn present_source_api_normalize_failure( transport_why_prefix: "failed to reach source API service", decode_why_prefix: "failed to decode source API normalized plan", fallback_try_next: vec![ - format!("onequery use --source {}", args.source), + format!("onequery api --source {}", args.source), format!("retry {}", context.command_line), ], unauthorized_try_next: Some(vec!["onequery auth login".to_owned()]), @@ -158,7 +158,7 @@ fn present_source_api_normalize_failure( fn present_source_api_execute_failure( failure: crate::transport::http::ApiFailure, - args: &UseArgs, + args: &ApiArgs, context: &CommandContext, ) -> CliError { present_api_failure( @@ -169,7 +169,7 @@ fn present_source_api_execute_failure( transport_why_prefix: "failed to reach source API service", decode_why_prefix: "failed to decode source API response", fallback_try_next: vec![ - format!("onequery use --source {}", args.source), + format!("onequery api --source {}", args.source), format!("retry {}", context.command_line), ], unauthorized_try_next: Some(vec!["onequery auth login".to_owned()]), @@ -179,9 +179,9 @@ fn present_source_api_execute_failure( pub(super) fn source_api_examples(source_key: &str) -> Vec { vec![ - format!("onequery use --source {source_key}"), - format!("onequery use --source {source_key} /path"), - format!("onequery use --source {source_key} --op "), + format!("onequery api --source {source_key}"), + format!("onequery api --source {source_key} /path"), + format!("onequery api --source {source_key} --op "), ] } diff --git a/apps/cli/crates/onequery-cli/src/commands/source_api/plan.rs b/apps/cli/crates/onequery-cli/src/commands/source_api/plan.rs index 5f5fd5ae..80cda9cd 100644 --- a/apps/cli/crates/onequery-cli/src/commands/source_api/plan.rs +++ b/apps/cli/crates/onequery-cli/src/commands/source_api/plan.rs @@ -1,6 +1,6 @@ use serde_json::Value; -use crate::cli::UseArgs; +use crate::cli::ApiArgs; use crate::transport::source_api::ExecuteSourceApiRequestPayload; use crate::transport::source_api::SourceApiDescriptor; use crate::transport::source_api::SourceApiHeader; @@ -55,7 +55,7 @@ pub(super) enum PlannedCommand { } pub(super) async fn build_plan( - args: &UseArgs, + args: &ApiArgs, descriptor: &SourceApiDescriptor, context: &CommandContext, ) -> Result { @@ -188,7 +188,7 @@ fn validate_selector( } fn validate_pagination( - args: &UseArgs, + args: &ApiArgs, operation: &SourceApiOperation, context: &CommandContext, source_key: &str, @@ -239,7 +239,7 @@ fn validate_pagination( } fn validate_method( - args: &UseArgs, + args: &ApiArgs, operation: &SourceApiOperation, context: &CommandContext, source_key: &str, @@ -283,7 +283,7 @@ fn validate_method( } fn validate_field_flags( - args: &UseArgs, + args: &ApiArgs, operation: &SourceApiOperation, context: &CommandContext, source_key: &str, @@ -316,7 +316,7 @@ fn validate_field_flags( } fn validate_input( - args: &UseArgs, + args: &ApiArgs, operation: &SourceApiOperation, context: &CommandContext, source_key: &str, @@ -410,7 +410,7 @@ fn parse_headers( } async fn load_request_body( - args: &UseArgs, + args: &ApiArgs, operation: &SourceApiOperation, reader: &mut SourceApiInputReader, context: &CommandContext, @@ -494,7 +494,7 @@ fn normalized_method_override(value: Option<&str>) -> Option { mod tests { use onequery_cli_core::error::ErrorStage; - use crate::cli::UseArgs; + use crate::cli::ApiArgs; use crate::commands::ResolvedOrgSource; use crate::config::default_base_url; use crate::transport::source_api::SourceApiDescriptor; @@ -516,9 +516,9 @@ mod tests { #[test] fn validate_pagination_rejects_slurp_without_paginate() { let error = validate_pagination( - &UseArgs { + &ApiArgs { slurp: true, - ..use_args() + ..api_args() }, &operation(SourceApiPaginationPolicy::OpaqueToken), &context(), @@ -536,9 +536,9 @@ mod tests { #[test] fn validate_pagination_rejects_max_pages_without_paginate() { let error = validate_pagination( - &UseArgs { + &ApiArgs { max_pages: Some(2), - ..use_args() + ..api_args() }, &operation(SourceApiPaginationPolicy::OpaqueToken), &context(), @@ -556,10 +556,10 @@ mod tests { #[test] fn validate_pagination_rejects_zero_max_pages() { let error = validate_pagination( - &UseArgs { + &ApiArgs { paginate: true, max_pages: Some(0), - ..use_args() + ..api_args() }, &operation(SourceApiPaginationPolicy::OpaqueToken), &context(), @@ -574,9 +574,9 @@ mod tests { #[test] fn validate_pagination_rejects_operations_without_pagination_support() { let error = validate_pagination( - &UseArgs { + &ApiArgs { paginate: true, - ..use_args() + ..api_args() }, &operation(SourceApiPaginationPolicy::None), &context(), @@ -591,10 +591,10 @@ mod tests { #[test] fn validate_pagination_accepts_supported_paginate_flags() { validate_pagination( - &UseArgs { + &ApiArgs { paginate: true, max_pages: Some(3), - ..use_args() + ..api_args() }, &operation(SourceApiPaginationPolicy::OpaqueToken), &context(), @@ -644,9 +644,9 @@ mod tests { #[tokio::test] async fn build_plan_rejects_input_when_operation_disallows_it() { let error = build_plan( - &UseArgs { + &ApiArgs { input: Some("request.json".to_owned()), - ..use_args() + ..api_args() }, &descriptor_with_operation(SourceApiOperation { field_policy: SourceApiFieldPolicy { @@ -668,10 +668,10 @@ mod tests { #[tokio::test] async fn build_plan_rejects_nested_field_paths_when_operation_disallows_them() { let error = build_plan( - &UseArgs { + &ApiArgs { fields: vec!["request[database]=analytics".to_owned()], target: None, - ..use_args() + ..api_args() }, &descriptor_with_operation(SourceApiOperation { selector_kind: SourceApiSelectorKind::None, @@ -698,10 +698,10 @@ mod tests { #[tokio::test] async fn build_plan_rejects_array_field_paths_when_operation_disallows_them() { let error = build_plan( - &UseArgs { + &ApiArgs { fields: vec!["database[]=analytics".to_owned()], target: None, - ..use_args() + ..api_args() }, &descriptor_with_operation(SourceApiOperation { selector_kind: SourceApiSelectorKind::None, @@ -727,7 +727,7 @@ mod tests { fn context() -> CommandContext { CommandContext { - command_line: "onequery use --source github-prod".to_owned(), + command_line: "onequery api --source github-prod".to_owned(), base_url: default_base_url(), request_id: None, resolved_org: Some("demo-org".to_owned()), @@ -753,8 +753,8 @@ mod tests { } } - fn use_args() -> UseArgs { - UseArgs { + fn api_args() -> ApiArgs { + ApiArgs { source: "github-prod".to_owned(), op: Some("fetch".to_owned()), target: Some("/pulls".to_owned()), diff --git a/apps/cli/crates/onequery-cli/src/commands/source_api/render.rs b/apps/cli/crates/onequery-cli/src/commands/source_api/render.rs index 0381ef40..8fbe201a 100644 --- a/apps/cli/crates/onequery-cli/src/commands/source_api/render.rs +++ b/apps/cli/crates/onequery-cli/src/commands/source_api/render.rs @@ -31,7 +31,7 @@ use super::plan::SourceApiRenderOptions; pub(super) fn render_descriptor_output( descriptor: SourceApiDescriptor, ) -> Result { - let data = serialize_command_data(&descriptor, "onequery use")?; + let data = serialize_command_data(&descriptor, "onequery api")?; let mut lines = vec![format!( "Source: {} ({})", @@ -69,7 +69,7 @@ pub(super) fn render_descriptor_output( pub(super) fn render_dry_run_output( plan: NormalizedSourceApiPlan, ) -> Result { - let data = serialize_command_data(&plan, "onequery use")?; + let data = serialize_command_data(&plan, "onequery api")?; Ok(CommandOutput::raw_json(pretty_json_lines(&data), data)) } @@ -100,7 +100,7 @@ fn serialize_execute_response( let mut object = serde_json::Map::new(); object.insert( "source".to_owned(), - serialize_command_data(&response.source, "onequery use")?, + serialize_command_data(&response.source, "onequery api")?, ); object.insert( "operation".to_owned(), @@ -174,7 +174,7 @@ fn assemble_execute_response( let mut response = responses.next().ok_or_else(|| { source_api_render_error( "source API execution returned no response", - vec!["retry onequery use".to_owned()], + vec!["retry onequery api".to_owned()], ) })?; @@ -219,7 +219,7 @@ fn assemble_paginated_body( let Some(first_body) = bodies.first() else { return Err(source_api_render_error( "source API execution returned no response body", - vec!["retry onequery use".to_owned()], + vec!["retry onequery api".to_owned()], )); }; @@ -269,7 +269,7 @@ fn assemble_paginated_body( .map_err(|decode_error| { source_api_render_error( format!("failed to assemble paginated binary response: {decode_error}"), - vec!["retry onequery use --output json ...".to_owned()], + vec!["retry onequery api --output json ...".to_owned()], ) })?; bytes.extend(decoded); @@ -311,7 +311,7 @@ fn apply_jq_to_response_body( | SourceApiResponseBody::Text { .. } | SourceApiResponseBody::Binary { .. } => Err(source_api_render_error( "`--jq` requires a JSON source API response body", - vec!["retry onequery use without --jq".to_owned()], + vec!["retry onequery api without --jq".to_owned()], )), } } @@ -323,7 +323,7 @@ fn apply_jq_expression( let input = serde_json::from_value::(input).map_err(|deserialize_error| { source_api_render_error( format!("failed to prepare response body for `--jq`: {deserialize_error}"), - vec!["retry onequery use without --jq".to_owned()], + vec!["retry onequery api without --jq".to_owned()], ) })?; @@ -343,7 +343,7 @@ fn apply_jq_expression( .map_err(|errors| { source_api_render_error( format!("invalid `--jq` expression: {errors:?}"), - vec!["retry onequery use --jq ''".to_owned()], + vec!["retry onequery api --jq ''".to_owned()], ) })?; let funs = jaq_core::funs() @@ -355,7 +355,7 @@ fn apply_jq_expression( .map_err(|errors| { source_api_render_error( format!("invalid `--jq` expression: {errors:?}"), - vec!["retry onequery use --jq ''".to_owned()], + vec!["retry onequery api --jq ''".to_owned()], ) })?; @@ -368,7 +368,7 @@ fn apply_jq_expression( value.map_err(|execute_error| { source_api_render_error( format!("failed to execute `--jq` expression: {execute_error:?}"), - vec!["retry onequery use --jq ''".to_owned()], + vec!["retry onequery api --jq ''".to_owned()], ) }) }) @@ -388,7 +388,7 @@ fn jaq_value_to_json(value: JaqValue) -> Result { |write_error| { source_api_render_error( format!("failed to serialize `--jq` output: {write_error}"), - vec!["retry onequery use --jq ''".to_owned()], + vec!["retry onequery api --jq ''".to_owned()], ) }, )?; @@ -396,7 +396,7 @@ fn jaq_value_to_json(value: JaqValue) -> Result { serde_json::from_slice(&bytes).map_err(|parse_error| { source_api_render_error( format!("`--jq` output was not valid JSON: {parse_error}"), - vec!["retry onequery use --jq ''".to_owned()], + vec!["retry onequery api --jq ''".to_owned()], ) }) } @@ -404,14 +404,14 @@ fn jaq_value_to_json(value: JaqValue) -> Result { fn mixed_paginated_body_error() -> CliError { source_api_render_error( "paginated source API responses changed body kind between pages", - vec!["retry onequery use without --paginate".to_owned()], + vec!["retry onequery api without --paginate".to_owned()], ) } fn source_api_render_error(why: impl Into, try_next: Vec) -> CliError { CliError::new( "failed to render source API response", - "onequery use", + "onequery api", ErrorStage::Render, why, try_next, @@ -581,7 +581,7 @@ fn render_response_stdout_bytes( .map_err(|decode_error| { source_api_render_error( format!("failed to decode binary source API response: {decode_error}"), - vec!["retry onequery use --output json ...".to_owned()], + vec!["retry onequery api --output json ...".to_owned()], ) })?; @@ -606,7 +606,7 @@ fn binary_tty_render_error() -> CliError { source_api_render_error( "binary source API responses require non-TTY stdout; pipe the output or use `--output json`", vec![ - "retry onequery use --output json ...".to_owned(), + "retry onequery api --output json ...".to_owned(), "pipe stdout to a file or another command".to_owned(), ], ) diff --git a/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__use_help_output_snapshot_targets_use_surface.snap b/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__api_help_output_snapshot_targets_api_surface.snap similarity index 88% rename from apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__use_help_output_snapshot_targets_use_surface.snap rename to apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__api_help_output_snapshot_targets_api_surface.snap index 3f13bd1d..acbb25e0 100644 --- a/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__use_help_output_snapshot_targets_use_surface.snap +++ b/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__api_help_output_snapshot_targets_api_surface.snap @@ -1,12 +1,12 @@ --- source: crates/onequery-cli/src/cli/../cli_tests.rs -expression: "rendered_display(&[\"onequery\", \"use\", \"--help\"])" +expression: "rendered_display(&[\"onequery\", \"api\", \"--help\"])" --- Describe or execute a connected source API -Usage: onequery use [OPTIONS] --source - onequery use [OPTIONS] --source [] - onequery use [OPTIONS] --source --op [] +Usage: onequery api [OPTIONS] --source + onequery api [OPTIONS] --source [] + onequery api [OPTIONS] --source --op [] Arguments: [TARGET] Provide the selector or inferred operation target diff --git a/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__help_output_snapshot_keeps_config_commands_out_of_public_surface.snap b/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__help_output_snapshot_keeps_config_commands_out_of_public_surface.snap index 4e3bb09c..870a8f00 100644 --- a/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__help_output_snapshot_keeps_config_commands_out_of_public_surface.snap +++ b/apps/cli/crates/onequery-cli/src/snapshots/onequery__cli__tests__help_output_snapshot_keeps_config_commands_out_of_public_surface.snap @@ -16,7 +16,7 @@ Commands: restore Restore a self-host backup archive into the runtime directories gateway Run the self-host gateway in foreground by default or manage the background lifecycle upgrade Upgrade this published CLI installation in place - use Describe or execute a connected source API + api Describe or execute a connected source API help Print this message or the help of the given subcommand(s) Options: diff --git a/apps/cli/justfile b/apps/cli/justfile index 2563e16c..04702e3c 100644 --- a/apps/cli/justfile +++ b/apps/cli/justfile @@ -9,10 +9,10 @@ alias o := onequery onequery *args: cargo run --bin onequery -- "$@" -# Run `onequery use --source ` -alias u := use -use source: - cargo run --bin onequery -- use --source {{source}} +# Run `onequery api --source ` +alias a := api +api source: + cargo run --bin onequery -- api --source {{source}} # format code fmt: diff --git a/packages/cli-server/src/cli-defaults.test.ts b/packages/cli-server/src/cli-defaults.test.ts index c659fb2e..d4cce83f 100644 --- a/packages/cli-server/src/cli-defaults.test.ts +++ b/packages/cli-server/src/cli-defaults.test.ts @@ -5,9 +5,9 @@ import { CLI_DEFAULT_RELAY_TIMEOUT_MS, buildCliSourceConnectCommand, buildCliSourceShowCommand, - buildCliUseExecuteCommand, - buildCliUseIntegrationReminder, - buildCliUseInspectCommand, + buildCliApiExecuteCommand, + buildCliApiIntegrationReminder, + buildCliApiInspectCommand, deviceAuthorizationPollAfterMs, slowedDeviceAuthorizationPollAfterMs, } from "./cli-defaults"; @@ -20,14 +20,14 @@ describe("cli defaults", () => { expect(buildCliSourceShowCommand("warehouse")).toBe( "onequery source show warehouse" ); - expect(buildCliUseInspectCommand("github")).toBe( - "onequery use --source github" + expect(buildCliApiInspectCommand("github")).toBe( + "onequery api --source github" ); - expect(buildCliUseExecuteCommand("github")).toBe( - "onequery use --source github /path" + expect(buildCliApiExecuteCommand("github")).toBe( + "onequery api --source github /path" ); - expect(buildCliUseIntegrationReminder("GitHub", "github")).toBe( - "You should connect GitHub in OneQuery before using `onequery use --source github`." + expect(buildCliApiIntegrationReminder("GitHub", "github")).toBe( + "You should connect GitHub in OneQuery before using `onequery api --source github`." ); }); diff --git a/packages/cli-server/src/cli-defaults.ts b/packages/cli-server/src/cli-defaults.ts index 58e0bc3b..3f6de426 100644 --- a/packages/cli-server/src/cli-defaults.ts +++ b/packages/cli-server/src/cli-defaults.ts @@ -19,19 +19,19 @@ export function buildCliSourceShowCommand(sourceKey: string) { return `onequery source show ${sourceKey}`; } -export function buildCliUseInspectCommand(sourceKey: string) { - return `onequery use --source ${sourceKey}`; +export function buildCliApiInspectCommand(sourceKey: string) { + return `onequery api --source ${sourceKey}`; } -export function buildCliUseExecuteCommand(sourceKey: string) { - return `onequery use --source ${sourceKey} /path`; +export function buildCliApiExecuteCommand(sourceKey: string) { + return `onequery api --source ${sourceKey} /path`; } -export function buildCliUseIntegrationReminder( +export function buildCliApiIntegrationReminder( providerLabel: string, sourceKey: string ) { - return `You should connect ${providerLabel} in OneQuery before using \`${buildCliUseInspectCommand( + return `You should connect ${providerLabel} in OneQuery before using \`${buildCliApiInspectCommand( sourceKey )}\`.`; } diff --git a/packages/cli-server/src/connect/service/source_api.test.ts b/packages/cli-server/src/connect/service/source_api.test.ts index 1961a0c2..a678880a 100644 --- a/packages/cli-server/src/connect/service/source_api.test.ts +++ b/packages/cli-server/src/connect/service/source_api.test.ts @@ -86,7 +86,7 @@ const descriptor = { descriptorVersion: "github-v1", examples: [ { - command: "onequery use --source github-prod /issues", + command: "onequery api --source github-prod /issues", description: "Fetch issues", label: "issues", }, diff --git a/packages/server/src/source-api/adapters/amplitude.ts b/packages/server/src/source-api/adapters/amplitude.ts index 62c09523..34e7e28f 100644 --- a/packages/server/src/source-api/adapters/amplitude.ts +++ b/packages/server/src/source-api/adapters/amplitude.ts @@ -239,7 +239,7 @@ export function buildAmplitudeUrl(input: { function buildAmplitudeExamples(sourceKey: string): SourceApiExample[] { return [ { - command: `onequery use --source ${sourceKey} /2/events/segmentation -f 'params[e]=[{"event_type":"Signup"}]' -f params[start]=2026-03-01 -f params[end]=2026-03-07`, + command: `onequery api --source ${sourceKey} /2/events/segmentation -f 'params[e]=[{"event_type":"Signup"}]' -f params[start]=2026-03-01 -f params[end]=2026-03-07`, description: "Run an Amplitude segmentation request against the connected source.", label: "Fetch event segmentation", diff --git a/packages/server/src/source-api/adapters/ga.ts b/packages/server/src/source-api/adapters/ga.ts index 59eaeb85..36870472 100644 --- a/packages/server/src/source-api/adapters/ga.ts +++ b/packages/server/src/source-api/adapters/ga.ts @@ -259,7 +259,7 @@ function buildGoogleAnalyticsExamples(sourceKey: string): { } { const reportExamples = [ { - command: `onequery use --source ${sourceKey} --op run_report --input '{"dateRanges":[{"startDate":"7daysAgo","endDate":"today"}],"dimensions":[{"name":"date"}],"metrics":[{"name":"activeUsers"}],"limit":100}'`, + command: `onequery api --source ${sourceKey} --op run_report --input '{"dateRanges":[{"startDate":"7daysAgo","endDate":"today"}],"dimensions":[{"name":"date"}],"metrics":[{"name":"activeUsers"}],"limit":100}'`, description: "Run a standard report with the property saved on the connected source.", label: "Run a report", @@ -267,7 +267,7 @@ function buildGoogleAnalyticsExamples(sourceKey: string): { ] satisfies SourceApiExample[]; const realtimeExamples = [ { - command: `onequery use --source ${sourceKey} --op run_realtime_report -F 'property="properties/123456789"' -F 'dimensions[]={"name":"country"}' -F 'metrics[]={"name":"activeUsers"}'`, + command: `onequery api --source ${sourceKey} --op run_realtime_report -F 'property="properties/123456789"' -F 'dimensions[]={"name":"country"}' -F 'metrics[]={"name":"activeUsers"}'`, description: "Override the property and run a realtime report with typed field patches.", label: "Run a realtime report", diff --git a/packages/server/src/source-api/adapters/github.ts b/packages/server/src/source-api/adapters/github.ts index 31691d0f..17ea8fae 100644 --- a/packages/server/src/source-api/adapters/github.ts +++ b/packages/server/src/source-api/adapters/github.ts @@ -445,13 +445,13 @@ export function toLegacyGitHubRelayBody( function buildGitHubExamples(sourceKey: string): SourceApiExample[] { return [ { - command: `onequery use --source ${sourceKey} /issues -f 'params[state]=open'`, + command: `onequery api --source ${sourceKey} /issues -f 'params[state]=open'`, description: "Fetch repo-scoped issues for the connected repository selection.", label: "List open issues", }, { - command: `onequery use --source ${sourceKey} --op fetch /repos/openai/example/pulls -f 'params[per_page]=20'`, + command: `onequery api --source ${sourceKey} --op fetch /repos/openai/example/pulls -f 'params[per_page]=20'`, description: "Call an explicit repository path when multiple repositories are connected.", label: "List pull requests", diff --git a/packages/server/src/source-api/adapters/mixpanel.ts b/packages/server/src/source-api/adapters/mixpanel.ts index f31aa954..28b8b522 100644 --- a/packages/server/src/source-api/adapters/mixpanel.ts +++ b/packages/server/src/source-api/adapters/mixpanel.ts @@ -604,21 +604,21 @@ function buildMixpanelExamples(sourceKey: string): { } { const engageExamples = [ { - command: `onequery use --source ${sourceKey} --op query_engage --input '{"where":"properties[\\"plan\\"] == \\"pro\\"","pageSize":100}'`, + command: `onequery api --source ${sourceKey} --op query_engage --input '{"where":"properties[\\"plan\\"] == \\"pro\\"","pageSize":100}'`, description: "Query Engage profiles with a narrow page size.", label: "Query engage", }, ] satisfies SourceApiExample[]; const segmentationExamples = [ { - command: `onequery use --source ${sourceKey} --op query_segmentation --input '{"event":"Signup","fromDate":"2026-03-01","toDate":"2026-03-07","unit":"day"}'`, + command: `onequery api --source ${sourceKey} --op query_segmentation --input '{"event":"Signup","fromDate":"2026-03-01","toDate":"2026-03-07","unit":"day"}'`, description: "Query Mixpanel event segmentation for one event.", label: "Query segmentation", }, ] satisfies SourceApiExample[]; const fetchExamples = [ { - command: `onequery use --source ${sourceKey} /query/events/top -f 'params[type]=general' -f 'params[from_date]=2026-03-01' -f 'params[to_date]=2026-03-07'`, + command: `onequery api --source ${sourceKey} /query/events/top -f 'params[type]=general' -f 'params[from_date]=2026-03-01' -f 'params[to_date]=2026-03-07'`, description: "Call a raw Mixpanel Query API endpoint when the higher-level helpers do not fit.", label: "Fetch query API", @@ -626,7 +626,7 @@ function buildMixpanelExamples(sourceKey: string): { ] satisfies SourceApiExample[]; const exportExamples = [ { - command: `onequery use --source ${sourceKey} --op export_events -f 'params[from_date]=2026-03-01' -f 'params[to_date]=2026-03-07'`, + command: `onequery api --source ${sourceKey} --op export_events -f 'params[from_date]=2026-03-01' -f 'params[to_date]=2026-03-07'`, description: "Export Mixpanel events for a bounded date range.", label: "Export events", }, diff --git a/packages/server/src/source-api/adapters/mongodb.ts b/packages/server/src/source-api/adapters/mongodb.ts index 0a6a2ec6..49970140 100644 --- a/packages/server/src/source-api/adapters/mongodb.ts +++ b/packages/server/src/source-api/adapters/mongodb.ts @@ -312,21 +312,21 @@ function buildMongoDbExamples(sourceKey: string): { } { const listDatabasesExamples = [ { - command: `onequery use --source ${sourceKey} --op list_databases`, + command: `onequery api --source ${sourceKey} --op list_databases`, description: "List databases visible to the connected MongoDB source.", label: "List databases", }, ] satisfies SourceApiExample[]; const listCollectionsExamples = [ { - command: `onequery use --source ${sourceKey} --op list_collections analytics`, + command: `onequery api --source ${sourceKey} --op list_collections analytics`, description: "List collections in the `analytics` database.", label: "List collections", }, ] satisfies SourceApiExample[]; const findExamples = [ { - command: `onequery use --source ${sourceKey} --op find_documents events -F 'filter={"status":"active"}' -F limit=25`, + command: `onequery api --source ${sourceKey} --op find_documents events -F 'filter={"status":"active"}' -F limit=25`, description: "Fetch active documents from the `events` collection with a typed filter patch.", label: "Find documents", diff --git a/packages/server/src/source-api/adapters/posthog.ts b/packages/server/src/source-api/adapters/posthog.ts index b7ac08fa..95945a30 100644 --- a/packages/server/src/source-api/adapters/posthog.ts +++ b/packages/server/src/source-api/adapters/posthog.ts @@ -189,7 +189,7 @@ export async function requestPostHogSourceApi(input: { function buildPostHogExamples(sourceKey: string): SourceApiExample[] { return [ { - command: `onequery use --source ${sourceKey} --op run_query --input '{"query":{"kind":"TrendsQuery","series":[{"event":"Signup"}],"dateRange":{"date_from":"-7d"}}}'`, + command: `onequery api --source ${sourceKey} --op run_query --input '{"query":{"kind":"TrendsQuery","series":[{"event":"Signup"}],"dateRange":{"date_from":"-7d"}}}'`, description: "Run a PostHog trends query against the connected project.", label: "Run trends query", }, diff --git a/packages/server/src/source-api/adapters/sentry.ts b/packages/server/src/source-api/adapters/sentry.ts index 4bba7f13..967472aa 100644 --- a/packages/server/src/source-api/adapters/sentry.ts +++ b/packages/server/src/source-api/adapters/sentry.ts @@ -252,7 +252,7 @@ export function buildSentryUrl(input: { function buildSentryExamples(sourceKey: string): SourceApiExample[] { return [ { - command: `onequery use --source ${sourceKey} /organizations/{organizationSlug}/issues/ -f 'params[query]=is:unresolved'`, + command: `onequery api --source ${sourceKey} /organizations/{organizationSlug}/issues/ -f 'params[query]=is:unresolved'`, description: "List unresolved Sentry issues for the connected organization.", label: "List issues",