{"content":"# aux4/curl\n\nHTTP client with OAuth2 authentication, stdin body, and NDJSON streaming support. Similar to curl but designed for piping data and OAuth2 workflows: authenticate with any OAuth2 provider, make authenticated requests, read request bodies from stdin, stream NDJSON input where each JSON line triggers a separate HTTP request, and collect results as NDJSON output.\n\n## Installation\n\n``bash\naux4 aux4 pkger install aux4/curl\n`\n\n## Quick Start\n\n`bash\n# Simple GET request\naux4 curl request https://api.example.com/users\n\n# POST with body from stdin\necho '{\"name\":\"Alice\"}' | aux4 curl request --method POST --header \"Content-Type: application/json\" https://api.example.com/users\n\n# OAuth2 login\naux4 curl oauth login myprovider --clientId abc123 --clientSecret secret --authUrl https://provider.com/oauth --tokenUrl https://provider.com/token --scopes read,write\n\n# Authenticated request (auto-injects Bearer token)\naux4 curl auth-request --provider myprovider https://api.provider.com/v1/me\n\n# Stream NDJSON: each line becomes a request, results streamed as NDJSON\ncat users.ndjson | aux4 curl stream https://api.example.com/process\n`\n\n## Commands\n\n### aux4 curl request\n\nMake an HTTP request. Supports all standard HTTP methods, custom headers, and reading the request body from stdin or the --body flag.\n\n`bash\naux4 curl request [--method <METHOD>] [--header <Header: Value>] [--body <data>] [--showHeaders <true|false>] <url>\n`\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| --method | HTTP method (GET, POST, PUT, DELETE, PATCH, etc.) | GET |\n| --header | Request header in Name: Value format (repeatable) | |\n| --body | Request body as a string | |\n| --showHeaders | Include response headers in output | false |\n| url | Request URL (positional argument) | required |\n\nWhen data is piped to stdin, it is used as the request body. The --body flag takes precedence if both are provided.\n\n#### Examples\n\n`bash\n# GET request\naux4 curl request https://api.example.com/users\n\n# POST with inline body\naux4 curl request --method POST --body '{\"name\":\"Alice\"}' --header \"Content-Type: application/json\" https://api.example.com/users\n\n# POST with body from stdin\necho '{\"name\":\"Alice\"}' | aux4 curl request --method POST --header \"Content-Type: application/json\" https://api.example.com/users\n\n# Show response headers\naux4 curl request --showHeaders true https://api.example.com/health\n\n# Pipe a file as body\ncat payload.json | aux4 curl request --method PUT --header \"Content-Type: application/json\" https://api.example.com/resource/1\n`\n\n### aux4 curl stream\n\nRead NDJSON (newline-delimited JSON) from stdin. For each JSON line, make an HTTP request to the given URL with that line as the body. Output results as NDJSON, one JSON object per line.\n\n`bash\naux4 curl stream [--method <METHOD>] [--header <Header: Value>] [--concurrency <N>] <url>\n`\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| --method | HTTP method | POST |\n| --header | Request header in Name: Value format (repeatable) | |\n| --concurrency | Number of concurrent requests | 1 |\n| url | Request URL (positional argument) | required |\n\nEach output line is a JSON object with:\n- status — HTTP status code (or 0 on connection error)\n- body — Response body (parsed as JSON if valid, otherwise a string)\n- input — The original input JSON that triggered this request\n\n#### Examples\n\n`bash\n# Process each user record\ncat users.ndjson | aux4 curl stream https://api.example.com/process\n\n# With concurrency\ncat records.ndjson | aux4 curl stream --concurrency 5 https://api.example.com/batch\n\n# Custom method and headers\ncat updates.ndjson | aux4 curl stream --method PUT --header \"Authorization: Bearer token123\" https://api.example.com/update\n\n# Chain with jq for filtering\ncat items.ndjson | aux4 curl stream https://api.example.com/enrich | jq 'select(.status == 200) | .body'\n`\n\n## OAuth2 Authentication\n\nThe oauth command group manages OAuth2 tokens using the authorization code flow. Tokens are stored locally in .oauth/<provider>.json by default. Add .oauth/ to your .gitignore.\n\n### aux4 curl oauth login\n\nAuthenticate with an OAuth2 provider. Opens a local callback server and prints a URL to authorize in the browser.\n\n`bash\naux4 curl oauth login <provider> --clientId <id> --clientSecret <secret> --authUrl <url> --tokenUrl <url> --scopes <scopes> [--callbackPort <port>] [--tokenFile <path>]\n`\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| provider | Provider name (positional argument) | required |\n| --clientId | OAuth client ID | required |\n| --clientSecret | OAuth client secret | required |\n| --authUrl | Authorization endpoint URL | required |\n| --tokenUrl | Token exchange endpoint URL | required |\n| --scopes | Comma-separated scopes | required |\n| --callbackPort | Local callback server port | 9876 |\n| --tokenFile | Custom token file path | .oauth/<provider>.json |\n\n#### Example\n\n`bash\naux4 curl oauth login pinterest \\\n --clientId abc123 \\\n --clientSecret mysecret \\\n --authUrl https://www.pinterest.com/oauth/ \\\n --tokenUrl https://api.pinterest.com/v5/oauth/token \\\n --scopes boards:read,pins:read,pins:write\n`\n\n### aux4 curl oauth token\n\nPrint a valid access token to stdout. Automatically refreshes if expired.\n\n`bash\naux4 curl oauth token <provider> [--tokenFile <path>]\n`\n\n#### Example\n\n`bash\n# Get token\naux4 curl oauth token pinterest\n\n# Use in a script\nTOKEN=$(aux4 curl oauth token pinterest)\ncurl -H \"Authorization: Bearer $TOKEN\" https://api.pinterest.com/v5/user_account\n`\n\n### aux4 curl oauth status\n\nShow token status, scopes, expiry, and whether a refresh token is available.\n\n`bash\naux4 curl oauth status <provider> [--tokenFile <path>]\n`\n\n#### Example\n\n`bash\naux4 curl oauth status pinterest\n`\n\n`text\nProvider: pinterest\nStatus: valid\nScopes: boards:read,pins:read,pins:write\nExpires at: 2026-04-28T12:30:00Z\nRefresh token: yes\nToken file: .oauth/pinterest.json\n`\n\n### aux4 curl oauth logout\n\nRemove the stored token file for a provider. Does not revoke the token on the provider side.\n\n`bash\naux4 curl oauth logout <provider> [--tokenFile <path>]\n`\n\n## Authenticated Requests\n\n### aux4 curl auth-request\n\nSame as request but automatically injects the Authorization: Bearer <token> header. Reads the stored token for the provider, refreshes if expired, and adds the header before making the request.\n\n`bash\naux4 curl auth-request --provider <name> [--tokenFile <path>] [--method <METHOD>] [--header <Header: Value>] [--body <data>] [--showHeaders <true|false>] <url>\n`\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| --provider | OAuth provider name | required |\n| --tokenFile | Custom token file path | .oauth/<provider>.json |\n| --method | HTTP method | GET |\n| --header | Request header (repeatable) | |\n| --body | Request body | |\n| --showHeaders | Include response headers | false |\n| url | Request URL (positional argument) | required |\n\n#### Examples\n\n`bash\n# GET with auth\naux4 curl auth-request --provider pinterest https://api.pinterest.com/v5/user_account\n\n# POST with auth\naux4 curl auth-request --provider pinterest --method POST \\\n --body '{\"title\":\"My Pin\",\"board_id\":\"123\"}' \\\n --header \"Content-Type: application/json\" \\\n https://api.pinterest.com/v5/pins\n`\n\n### aux4 curl auth-stream\n\nSame as stream but automatically injects the Authorization: Bearer <token> header for each request. Reads NDJSON from stdin, makes one authenticated HTTP request per line, outputs NDJSON results.\n\n`bash\necho '<ndjson>' | aux4 curl auth-stream --provider <name> [--tokenFile <path>] [--method <METHOD>] [--header <Header: Value>] [--concurrency <n>] <url>\n`\n\n| Flag | Description | Default |\n|------|-------------|---------|\n| --provider | OAuth provider name | required |\n| --tokenFile | Custom token file path | .oauth/<provider>.json |\n| --method | HTTP method | POST |\n| --header | Request header (repeatable) | |\n| --concurrency | Number of concurrent requests | 1 |\n| url | Request URL (positional argument) | required |\n\n#### Example\n\n`bash\necho '{\"title\":\"Pin 1\",\"board_id\":\"123\"}\n{\"title\":\"Pin 2\",\"board_id\":\"123\"}' | aux4 curl auth-stream --provider pinterest \\\n --header \"Content-Type: application/json\" \\\n https://api.pinterest.com/v5/pins\n`\n\n## Token File\n\nBy default, tokens are stored in .oauth/<provider>.json in the current directory. Override with --tokenFile on any command:\n\n`bash\naux4 curl oauth login myprovider --tokenFile /custom/path/token.json ...\naux4 curl auth-request --provider myprovider --tokenFile /custom/path/token.json https://api.example.com/data\n``\n"}