@pilot-status/mcp-server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +230 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +100 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +204 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/config.d.ts +54 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +79 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/http-transport.d.ts +42 -0
- package/dist/lib/http-transport.d.ts.map +1 -0
- package/dist/lib/http-transport.js +228 -0
- package/dist/lib/http-transport.js.map +1 -0
- package/dist/lib/register.d.ts +28 -0
- package/dist/lib/register.d.ts.map +1 -0
- package/dist/lib/register.js +69 -0
- package/dist/lib/register.js.map +1 -0
- package/dist/lib/server.d.ts +16 -0
- package/dist/lib/server.d.ts.map +1 -0
- package/dist/lib/server.js +23 -0
- package/dist/lib/server.js.map +1 -0
- package/dist/tools/analytics.d.ts +3 -0
- package/dist/tools/analytics.d.ts.map +1 -0
- package/dist/tools/analytics.js +22 -0
- package/dist/tools/analytics.js.map +1 -0
- package/dist/tools/api-keys.d.ts +3 -0
- package/dist/tools/api-keys.d.ts.map +1 -0
- package/dist/tools/api-keys.js +35 -0
- package/dist/tools/api-keys.js.map +1 -0
- package/dist/tools/branding.d.ts +3 -0
- package/dist/tools/branding.d.ts.map +1 -0
- package/dist/tools/branding.js +35 -0
- package/dist/tools/branding.js.map +1 -0
- package/dist/tools/conversations.d.ts +3 -0
- package/dist/tools/conversations.d.ts.map +1 -0
- package/dist/tools/conversations.js +18 -0
- package/dist/tools/conversations.js.map +1 -0
- package/dist/tools/groups.d.ts +3 -0
- package/dist/tools/groups.d.ts.map +1 -0
- package/dist/tools/groups.js +17 -0
- package/dist/tools/groups.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +26 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/messages.d.ts +3 -0
- package/dist/tools/messages.d.ts.map +1 -0
- package/dist/tools/messages.js +134 -0
- package/dist/tools/messages.js.map +1 -0
- package/dist/tools/numbers.d.ts +3 -0
- package/dist/tools/numbers.d.ts.map +1 -0
- package/dist/tools/numbers.js +52 -0
- package/dist/tools/numbers.js.map +1 -0
- package/dist/tools/shared.d.ts +19 -0
- package/dist/tools/shared.d.ts.map +1 -0
- package/dist/tools/shared.js +27 -0
- package/dist/tools/shared.js.map +1 -0
- package/dist/tools/subscription.d.ts +3 -0
- package/dist/tools/subscription.d.ts.map +1 -0
- package/dist/tools/subscription.js +39 -0
- package/dist/tools/subscription.js.map +1 -0
- package/dist/tools/templates.d.ts +3 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +68 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/types.d.ts +23 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +20 -0
- package/dist/tools/types.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pilot Status
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# @pilot-status/mcp-server
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that
|
|
4
|
+
exposes the **Pilot Status public `/v1` API** as MCP tools, so any MCP-capable
|
|
5
|
+
client (Claude Desktop, Cursor, custom agents, …) can send WhatsApp messages,
|
|
6
|
+
manage numbers/templates, read conversations, and more — using a Pilot Status
|
|
7
|
+
API key.
|
|
8
|
+
|
|
9
|
+
It speaks two transports:
|
|
10
|
+
|
|
11
|
+
- **stdio** — for local clients that spawn the server as a child process. The
|
|
12
|
+
API key is read once from `PILOT_STATUS_API_KEY`.
|
|
13
|
+
- **streamable HTTP** — deployable; clients connect over HTTP and authenticate
|
|
14
|
+
either with an `x-api-key` header **or** with an OAuth 2.1 bearer token (for
|
|
15
|
+
the [claude.ai custom connector](#remote-oauth--claudeai-connector)). Runs
|
|
16
|
+
stateless (a fresh MCP session per request), so it scales horizontally behind
|
|
17
|
+
a load balancer.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Run straight from npm (no clone/build):
|
|
23
|
+
npx @pilot-status/mcp-server stdio # stdio transport (default)
|
|
24
|
+
npx @pilot-status/mcp-server http # streamable HTTP transport
|
|
25
|
+
|
|
26
|
+
# Or install the binary globally:
|
|
27
|
+
npm install -g @pilot-status/mcp-server
|
|
28
|
+
pilot-status-mcp stdio
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The published package exposes the `pilot-status-mcp` bin. Configuration is via
|
|
32
|
+
environment variables (see [`.env.example`](./.env.example) / [Configuration](#configuration)):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
PILOT_STATUS_API_KEY=ps_xxx npx @pilot-status/mcp-server stdio
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Authentication
|
|
39
|
+
|
|
40
|
+
There are two ways to authenticate against the public `/v1` API:
|
|
41
|
+
|
|
42
|
+
1. **API key** (`x-api-key`) — a `ps_*` key, used by stdio and by HTTP clients
|
|
43
|
+
that send the header themselves.
|
|
44
|
+
2. **OAuth 2.1 bearer token** — used by the claude.ai custom connector
|
|
45
|
+
(HTTP transport). The token is forwarded verbatim to `/v1`; this server does
|
|
46
|
+
not verify it. See [Remote (OAuth)](#remote-oauth--claudeai-connector).
|
|
47
|
+
|
|
48
|
+
Scope matters (same rules as the REST API):
|
|
49
|
+
|
|
50
|
+
- **Number-scoped key** → per-number action/data tools: `messages_*`,
|
|
51
|
+
`conversations_list`, `groups_list`, `newsletters_list`, `templates_*`,
|
|
52
|
+
`analytics_dashboard`, `api_keys_*`, `numbers_*`.
|
|
53
|
+
- **Tenant-scoped key** → tenant-wide tools: `branding_*`,
|
|
54
|
+
`subscription_extra_numbers_*`. (Number-scoped keys get HTTP 403 on these,
|
|
55
|
+
surfaced as a tool error.)
|
|
56
|
+
|
|
57
|
+
Under an OAuth/tenant token there is no number scope, so number-scoped tools
|
|
58
|
+
accept an optional `whatsappNumberId` argument. It is sent as the
|
|
59
|
+
`x-whatsapp-number-id` header so the backend can resolve the target number; it
|
|
60
|
+
is ignored when the API key is already scoped to a single number.
|
|
61
|
+
|
|
62
|
+
Token-based pairing/connect routes (interactive browser flows) are intentionally
|
|
63
|
+
**not** exposed as tools.
|
|
64
|
+
|
|
65
|
+
## Tools
|
|
66
|
+
|
|
67
|
+
| Tool | Endpoint |
|
|
68
|
+
| --- | --- |
|
|
69
|
+
| `messages_send` | `POST /v1/messages/send` |
|
|
70
|
+
| `message_get` | `GET /v1/messages/{id}` |
|
|
71
|
+
| `messages_cancel` | `DELETE /v1/messages/cancel` |
|
|
72
|
+
| `messages_group` | `GET /v1/messages/group` |
|
|
73
|
+
| `messages_unread` | `GET /v1/messages/unread` |
|
|
74
|
+
| `conversations_list` | `GET /v1/conversations` |
|
|
75
|
+
| `groups_list` | `GET /v1/groups` |
|
|
76
|
+
| `newsletters_list` | `GET /v1/newsletters` |
|
|
77
|
+
| `numbers_list` | `GET /v1/numbers` |
|
|
78
|
+
| `numbers_create` | `POST /v1/numbers` |
|
|
79
|
+
| `numbers_delete` | `DELETE /v1/numbers/{id}` |
|
|
80
|
+
| `numbers_status` | `GET /v1/numbers/{id}/status` |
|
|
81
|
+
| `templates_list` | `GET /v1/templates` |
|
|
82
|
+
| `templates_create` | `POST /v1/templates` |
|
|
83
|
+
| `templates_get` | `GET /v1/templates/{id}` |
|
|
84
|
+
| `templates_update` | `PUT /v1/templates/{id}` |
|
|
85
|
+
| `branding_get` | `GET /v1/branding` |
|
|
86
|
+
| `branding_upsert` | `PUT /v1/branding` |
|
|
87
|
+
| `analytics_dashboard` | `GET /v1/analytics/dashboard` |
|
|
88
|
+
| `api_keys_list` | `GET /v1/api-keys` |
|
|
89
|
+
| `api_keys_create` | `POST /v1/api-keys` |
|
|
90
|
+
| `subscription_extra_numbers_get` | `GET /v1/subscription/extra-numbers` |
|
|
91
|
+
| `subscription_extra_numbers_add` | `POST /v1/subscription/extra-numbers` |
|
|
92
|
+
|
|
93
|
+
> Privacy: when a number's privacy mode is `RELAY_ONLY`, the read tools
|
|
94
|
+
> (`messages_group`, `messages_unread`, `conversations_list`) return empty
|
|
95
|
+
> results; `STORE_X_DAYS` limits results to the retention window.
|
|
96
|
+
|
|
97
|
+
## Configuration
|
|
98
|
+
|
|
99
|
+
See [`.env.example`](./.env.example). Key variables:
|
|
100
|
+
|
|
101
|
+
| Variable | Default | Notes |
|
|
102
|
+
| --- | --- | --- |
|
|
103
|
+
| `PILOT_STATUS_API_URL` | `https://pilotstatuss.com` | Public API base URL (no trailing slash). |
|
|
104
|
+
| `PILOT_STATUS_API_KEY` | — | `ps_*` key. Required for stdio; optional fallback for HTTP. |
|
|
105
|
+
| `PILOT_STATUS_API_KEY_ID` | — | Optional `x-api-key-id` companion. |
|
|
106
|
+
| `MCP_RESOURCE_URL` | `https://mcp.pilotstatuss.com` | Public URL of THIS server (OAuth `resource`). |
|
|
107
|
+
| `PILOT_STATUS_AUTH_SERVER_URL` | `https://pilotstatuss.com` | OAuth authorization server (the backend). |
|
|
108
|
+
| `MCP_TRANSPORT` | `stdio` | `stdio` or `http`. |
|
|
109
|
+
| `PORT` | `8787` | HTTP transport port. |
|
|
110
|
+
| `HOST` | `0.0.0.0` | HTTP transport bind host. |
|
|
111
|
+
|
|
112
|
+
## Running
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
npm install # from the repo root (workspaces)
|
|
116
|
+
npm --workspace @pilot-status/mcp-server run build
|
|
117
|
+
|
|
118
|
+
# stdio (default)
|
|
119
|
+
PILOT_STATUS_API_KEY=ps_xxx node apps/mcp-server/dist/index.js
|
|
120
|
+
|
|
121
|
+
# streamable HTTP
|
|
122
|
+
MCP_TRANSPORT=http PORT=8787 node apps/mcp-server/dist/index.js
|
|
123
|
+
# or: node apps/mcp-server/dist/index.js http
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Dev mode (no build): `npm --workspace @pilot-status/mcp-server run dev`.
|
|
127
|
+
|
|
128
|
+
### HTTP endpoint
|
|
129
|
+
|
|
130
|
+
- `POST /mcp` — JSON-RPC over Streamable HTTP. Authenticate with `x-api-key:
|
|
131
|
+
ps_xxx` **or** `Authorization: Bearer <oauth-token>`. With no credentials it
|
|
132
|
+
replies `401` + `WWW-Authenticate`, which starts the OAuth flow.
|
|
133
|
+
- `GET /.well-known/oauth-protected-resource` — OAuth 2.1 protected-resource
|
|
134
|
+
metadata (RFC 9728); points discovery at the authorization server.
|
|
135
|
+
- `GET /health` — liveness probe.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
curl -s http://localhost:8787/mcp \
|
|
139
|
+
-H "content-type: application/json" \
|
|
140
|
+
-H "accept: application/json, text/event-stream" \
|
|
141
|
+
-H "x-api-key: ps_xxx" \
|
|
142
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Configuring MCP clients
|
|
146
|
+
|
|
147
|
+
### Claude Desktop / Cursor (stdio)
|
|
148
|
+
|
|
149
|
+
Use the published binary via `npx` (recommended) — add to the client's MCP
|
|
150
|
+
config (e.g. `claude_desktop_config.json`):
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"mcpServers": {
|
|
155
|
+
"pilot-status": {
|
|
156
|
+
"command": "npx",
|
|
157
|
+
"args": ["-y", "@pilot-status/mcp-server", "stdio"],
|
|
158
|
+
"env": {
|
|
159
|
+
"PILOT_STATUS_API_KEY": "ps_your_key_here",
|
|
160
|
+
"PILOT_STATUS_API_URL": "https://pilotstatuss.com"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Or point `command`/`args` at a local build
|
|
168
|
+
(`node /absolute/path/to/apps/mcp-server/dist/index.js`).
|
|
169
|
+
|
|
170
|
+
### Remote / HTTP clients (API key)
|
|
171
|
+
|
|
172
|
+
Point the client at the deployed URL and supply the API key as a header:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"mcpServers": {
|
|
177
|
+
"pilot-status": {
|
|
178
|
+
"type": "http",
|
|
179
|
+
"url": "https://mcp.pilotstatuss.com/mcp",
|
|
180
|
+
"headers": { "x-api-key": "ps_your_key_here" }
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Remote (OAuth) — claude.ai connector
|
|
187
|
+
|
|
188
|
+
For the [claude.ai](https://claude.ai) **Custom Connector**, deploy this server
|
|
189
|
+
(HTTP transport) at a public HTTPS URL and let claude.ai run the OAuth login —
|
|
190
|
+
no API key is shared with the client.
|
|
191
|
+
|
|
192
|
+
1. Deploy with `MCP_TRANSPORT=http` and set:
|
|
193
|
+
- `MCP_RESOURCE_URL` — the public URL of this server, e.g.
|
|
194
|
+
`https://mcp.pilotstatuss.com`.
|
|
195
|
+
- `PILOT_STATUS_AUTH_SERVER_URL` — the Pilot Status backend, e.g.
|
|
196
|
+
`https://pilotstatuss.com` (the default).
|
|
197
|
+
- Leave `PILOT_STATUS_API_KEY` **unset** so unauthenticated requests return a
|
|
198
|
+
`401` challenge (otherwise the env key would short-circuit OAuth).
|
|
199
|
+
2. In claude.ai → **Settings → Connectors → Add custom connector**, set the URL
|
|
200
|
+
to `https://mcp.pilotstatuss.com/mcp`.
|
|
201
|
+
3. claude.ai fetches `GET /.well-known/oauth-protected-resource`, discovers the
|
|
202
|
+
authorization server (`PILOT_STATUS_AUTH_SERVER_URL`), and runs the OAuth
|
|
203
|
+
2.1 login (Pilot Status SSO). The resulting access token is sent on every
|
|
204
|
+
`POST /mcp` as `Authorization: Bearer <token>`.
|
|
205
|
+
|
|
206
|
+
This server is a **dumb forwarder**: it does not verify the token. It forwards
|
|
207
|
+
the bearer token to the public `/v1` API, which validates it. If `/v1` rejects
|
|
208
|
+
the token (`401`), the response is relayed as `401` + `WWW-Authenticate` so the
|
|
209
|
+
client re-authenticates. The authorization server itself (`/api/oauth/*` and
|
|
210
|
+
`/.well-known/oauth-authorization-server`) lives in the Pilot Status backend.
|
|
211
|
+
|
|
212
|
+
## Deployment
|
|
213
|
+
|
|
214
|
+
`MCP_TRANSPORT=http` behind HTTPS at `MCP_RESOURCE_URL`. A container image +
|
|
215
|
+
generator entry + Traefik host (`mcp.pilotstatuss.com`) and the backend
|
|
216
|
+
authorization-server endpoints are tracked as follow-up tasks. The server is
|
|
217
|
+
stateless, so it can run with multiple replicas behind the load balancer.
|
|
218
|
+
|
|
219
|
+
## Tests
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npm --workspace @pilot-status/mcp-server test
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Covers the API client (header injection, bearer/OAuth mode, the
|
|
226
|
+
`x-whatsapp-number-id` selector, query building, HTTP error mapping), the HTTP
|
|
227
|
+
transport (protected-resource metadata, the unauthenticated `401` +
|
|
228
|
+
`WWW-Authenticate` challenge, CORS) and tool registration (every public endpoint
|
|
229
|
+
registered, argument dispatch, number-selector threading, error wrapping).
|
|
230
|
+
`fetch` is mocked for the unit tests — no external network access required.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Pilot Status MCP server entrypoint.
|
|
4
|
+
*
|
|
5
|
+
* Selects a transport from CLI args / env (see {@link resolveConfig}):
|
|
6
|
+
* - stdio (default): single-tenant; API key from PILOT_STATUS_API_KEY.
|
|
7
|
+
* - http: deployable; API key per-request from the `x-api-key` header
|
|
8
|
+
* (falls back to PILOT_STATUS_API_KEY if set).
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* pilot-status-mcp # stdio
|
|
12
|
+
* pilot-status-mcp http # streamable HTTP on PORT (default 8787)
|
|
13
|
+
* MCP_TRANSPORT=http PORT=8787 node dist/index.js
|
|
14
|
+
*/
|
|
15
|
+
import { resolveConfig } from "./lib/config.js";
|
|
16
|
+
async function main() {
|
|
17
|
+
const config = resolveConfig();
|
|
18
|
+
if (config.transport === "http") {
|
|
19
|
+
const { startHttpServer } = await import("./lib/http-transport.js");
|
|
20
|
+
await startHttpServer(config);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
// stdio transport
|
|
24
|
+
if (!config.apiKey && !config.apiKeyId) {
|
|
25
|
+
console.error("[mcp] PILOT_STATUS_API_KEY is required for the stdio transport. " +
|
|
26
|
+
"Set it in the environment (or use the HTTP transport with per-request keys).");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
30
|
+
const { buildServer } = await import("./lib/server.js");
|
|
31
|
+
const server = buildServer({
|
|
32
|
+
baseUrl: config.baseUrl,
|
|
33
|
+
apiKey: config.apiKey,
|
|
34
|
+
apiKeyId: config.apiKeyId,
|
|
35
|
+
});
|
|
36
|
+
const transport = new StdioServerTransport();
|
|
37
|
+
await server.connect(transport);
|
|
38
|
+
// stdout is reserved for the JSON-RPC protocol; log to stderr.
|
|
39
|
+
console.error(`[mcp] Pilot Status MCP server (stdio) connected → ${config.baseUrl}/v1`);
|
|
40
|
+
}
|
|
41
|
+
main().catch((err) => {
|
|
42
|
+
console.error("[mcp] fatal:", err instanceof Error ? err.stack ?? err.message : err);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,KAAK,UAAU,IAAI;IACf,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAE/B,IAAI,MAAM,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;QAC9B,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,CAAC;QACpE,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;QAC9B,OAAO;IACX,CAAC;IAED,kBAAkB;IAClB,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACrC,OAAO,CAAC,KAAK,CACT,kEAAkE;YAC9D,8EAA8E,CACrF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CACzC,2CAA2C,CAC9C,CAAC;IACF,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,WAAW,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC5B,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,+DAA+D;IAC/D,OAAO,CAAC,KAAK,CACT,qDAAqD,MAAM,CAAC,OAAO,KAAK,CAC3E,CAAC;AACN,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP client for the Pilot Status public `/v1` API.
|
|
3
|
+
*
|
|
4
|
+
* - Targets `PILOT_STATUS_API_URL` (default https://pilotstatuss.com); every
|
|
5
|
+
* public endpoint lives under the `/v1` prefix (the backend rewrites `/v1/*`
|
|
6
|
+
* to its internal `/api/v1/*` routes).
|
|
7
|
+
* Authentication is one of two modes:
|
|
8
|
+
* - **API key** — `x-api-key` (+ optional `x-api-key-id`) from a constructor
|
|
9
|
+
* value (stdio mode) or a per-request override (HTTP `x-api-key` header).
|
|
10
|
+
* - **Bearer** — an OAuth 2.1 access token, forwarded verbatim as
|
|
11
|
+
* `Authorization: Bearer <token>` (and `x-api-key` is NOT sent). The public
|
|
12
|
+
* `/v1` API validates the token; this client never inspects it.
|
|
13
|
+
*
|
|
14
|
+
* Optionally a WhatsApp number selector (`x-whatsapp-number-id`) is attached so
|
|
15
|
+
* the backend can resolve number-scope under a tenant-wide OAuth token.
|
|
16
|
+
*
|
|
17
|
+
* - Normalizes upstream errors (400/401/403/404/409/422/429/5xx) into a single
|
|
18
|
+
* {@link ApiError} carrying status + machine `code` + details so MCP tools can
|
|
19
|
+
* surface a clean message to the model.
|
|
20
|
+
*/
|
|
21
|
+
export interface ApiClientOptions {
|
|
22
|
+
/** Base URL without trailing slash (e.g. https://pilotstatuss.com). */
|
|
23
|
+
baseUrl: string;
|
|
24
|
+
/** Default `x-api-key` value (stdio). Optional in HTTP mode. */
|
|
25
|
+
apiKey?: string;
|
|
26
|
+
/** Optional `x-api-key-id` companion header. */
|
|
27
|
+
apiKeyId?: string;
|
|
28
|
+
/**
|
|
29
|
+
* OAuth 2.1 bearer token. When set it takes precedence over `apiKey`:
|
|
30
|
+
* the client sends `Authorization: Bearer <token>` and omits `x-api-key`.
|
|
31
|
+
*/
|
|
32
|
+
bearer?: string;
|
|
33
|
+
/** Default WhatsApp number selector → `x-whatsapp-number-id` header. */
|
|
34
|
+
numberId?: string;
|
|
35
|
+
/** Fetch implementation (defaults to global fetch; overridable in tests). */
|
|
36
|
+
fetchImpl?: typeof fetch;
|
|
37
|
+
/**
|
|
38
|
+
* Invoked when an upstream request made in *bearer* mode returns HTTP 401,
|
|
39
|
+
* so the HTTP transport can relay a `WWW-Authenticate` challenge and trigger
|
|
40
|
+
* the client to re-authenticate.
|
|
41
|
+
*/
|
|
42
|
+
onBearerUnauthorized?: () => void;
|
|
43
|
+
}
|
|
44
|
+
export interface RequestOptions {
|
|
45
|
+
/** Query-string parameters (undefined/null entries are skipped). */
|
|
46
|
+
query?: Record<string, string | number | boolean | undefined | null>;
|
|
47
|
+
/** JSON request body (serialized for non-GET requests). */
|
|
48
|
+
body?: unknown;
|
|
49
|
+
/** Per-request `x-api-key` override (HTTP transport). Wins over the default. */
|
|
50
|
+
apiKey?: string;
|
|
51
|
+
/** Per-request `x-api-key-id` override. */
|
|
52
|
+
apiKeyId?: string;
|
|
53
|
+
/** Per-request bearer token override. Wins over the default. */
|
|
54
|
+
bearer?: string;
|
|
55
|
+
/** Per-request WhatsApp number selector → `x-whatsapp-number-id` header. */
|
|
56
|
+
numberId?: string;
|
|
57
|
+
}
|
|
58
|
+
export declare class ApiError extends Error {
|
|
59
|
+
readonly status: number;
|
|
60
|
+
readonly code?: string;
|
|
61
|
+
readonly details?: unknown;
|
|
62
|
+
/** Raw parsed response body (object or string), when available. */
|
|
63
|
+
readonly body?: unknown;
|
|
64
|
+
constructor(args: {
|
|
65
|
+
message: string;
|
|
66
|
+
status: number;
|
|
67
|
+
code?: string;
|
|
68
|
+
details?: unknown;
|
|
69
|
+
body?: unknown;
|
|
70
|
+
});
|
|
71
|
+
toJSON(): {
|
|
72
|
+
details?: {} | null | undefined;
|
|
73
|
+
code?: string | undefined;
|
|
74
|
+
error: string;
|
|
75
|
+
status: number;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export declare class ApiClient {
|
|
79
|
+
private readonly baseUrl;
|
|
80
|
+
private readonly apiKey?;
|
|
81
|
+
private readonly apiKeyId?;
|
|
82
|
+
private readonly bearer?;
|
|
83
|
+
private readonly numberId?;
|
|
84
|
+
private readonly onBearerUnauthorized?;
|
|
85
|
+
private readonly fetchImpl;
|
|
86
|
+
constructor(options: ApiClientOptions);
|
|
87
|
+
/**
|
|
88
|
+
* Return a shallow clone of this client that attaches the given WhatsApp
|
|
89
|
+
* number selector (`x-whatsapp-number-id`) to every request — so a single
|
|
90
|
+
* tool call can scope tenant-wide credentials (OAuth token or tenant key)
|
|
91
|
+
* to one number without mutating the shared client.
|
|
92
|
+
*/
|
|
93
|
+
withNumber(numberId: string): ApiClient;
|
|
94
|
+
request<T = unknown>(method: string, path: string, options?: RequestOptions): Promise<T>;
|
|
95
|
+
get<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
96
|
+
post<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
97
|
+
put<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
98
|
+
delete<T = unknown>(path: string, options?: RequestOptions): Promise<T>;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,gBAAgB;IAC7B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,cAAc;IAC3B,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;IACrE,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAgBD,qBAAa,QAAS,SAAQ,KAAK;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;gBAEZ,IAAI,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,OAAO,CAAC;KAClB;IASD,MAAM;;;;;;CAQT;AAkBD,qBAAa,SAAS;IAClB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,gBAAgB;IAiBrC;;;;;OAKG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS;IAYjC,OAAO,CAAC,CAAC,GAAG,OAAO,EACrB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,cAAmB,GAC7B,OAAO,CAAC,CAAC,CAAC;IAyFb,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIxE,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIzE,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;IAIxE,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC;CAG9E"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thin HTTP client for the Pilot Status public `/v1` API.
|
|
3
|
+
*
|
|
4
|
+
* - Targets `PILOT_STATUS_API_URL` (default https://pilotstatuss.com); every
|
|
5
|
+
* public endpoint lives under the `/v1` prefix (the backend rewrites `/v1/*`
|
|
6
|
+
* to its internal `/api/v1/*` routes).
|
|
7
|
+
* Authentication is one of two modes:
|
|
8
|
+
* - **API key** — `x-api-key` (+ optional `x-api-key-id`) from a constructor
|
|
9
|
+
* value (stdio mode) or a per-request override (HTTP `x-api-key` header).
|
|
10
|
+
* - **Bearer** — an OAuth 2.1 access token, forwarded verbatim as
|
|
11
|
+
* `Authorization: Bearer <token>` (and `x-api-key` is NOT sent). The public
|
|
12
|
+
* `/v1` API validates the token; this client never inspects it.
|
|
13
|
+
*
|
|
14
|
+
* Optionally a WhatsApp number selector (`x-whatsapp-number-id`) is attached so
|
|
15
|
+
* the backend can resolve number-scope under a tenant-wide OAuth token.
|
|
16
|
+
*
|
|
17
|
+
* - Normalizes upstream errors (400/401/403/404/409/422/429/5xx) into a single
|
|
18
|
+
* {@link ApiError} carrying status + machine `code` + details so MCP tools can
|
|
19
|
+
* surface a clean message to the model.
|
|
20
|
+
*/
|
|
21
|
+
/** A friendly hint per HTTP status, prepended to the upstream error message. */
|
|
22
|
+
const STATUS_HINTS = {
|
|
23
|
+
400: "Bad request",
|
|
24
|
+
401: "Unauthorized (check your API key)",
|
|
25
|
+
403: "Forbidden (wrong API key scope for this endpoint)",
|
|
26
|
+
404: "Not found",
|
|
27
|
+
409: "Conflict",
|
|
28
|
+
422: "Unprocessable (billing or validation)",
|
|
29
|
+
429: "Rate limited",
|
|
30
|
+
500: "Server error",
|
|
31
|
+
502: "Upstream provider error",
|
|
32
|
+
503: "Service unavailable",
|
|
33
|
+
};
|
|
34
|
+
export class ApiError extends Error {
|
|
35
|
+
status;
|
|
36
|
+
code;
|
|
37
|
+
details;
|
|
38
|
+
/** Raw parsed response body (object or string), when available. */
|
|
39
|
+
body;
|
|
40
|
+
constructor(args) {
|
|
41
|
+
super(args.message);
|
|
42
|
+
this.name = "ApiError";
|
|
43
|
+
this.status = args.status;
|
|
44
|
+
this.code = args.code;
|
|
45
|
+
this.details = args.details;
|
|
46
|
+
this.body = args.body;
|
|
47
|
+
}
|
|
48
|
+
toJSON() {
|
|
49
|
+
return {
|
|
50
|
+
error: this.message,
|
|
51
|
+
status: this.status,
|
|
52
|
+
...(this.code ? { code: this.code } : {}),
|
|
53
|
+
...(this.details !== undefined ? { details: this.details } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function buildUrl(baseUrl, path, query) {
|
|
58
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
59
|
+
const url = new URL(`${baseUrl}${normalizedPath}`);
|
|
60
|
+
if (query) {
|
|
61
|
+
for (const [key, value] of Object.entries(query)) {
|
|
62
|
+
if (value === undefined || value === null)
|
|
63
|
+
continue;
|
|
64
|
+
url.searchParams.set(key, String(value));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return url.toString();
|
|
68
|
+
}
|
|
69
|
+
export class ApiClient {
|
|
70
|
+
baseUrl;
|
|
71
|
+
apiKey;
|
|
72
|
+
apiKeyId;
|
|
73
|
+
bearer;
|
|
74
|
+
numberId;
|
|
75
|
+
onBearerUnauthorized;
|
|
76
|
+
fetchImpl;
|
|
77
|
+
constructor(options) {
|
|
78
|
+
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
79
|
+
this.apiKey = options.apiKey;
|
|
80
|
+
this.apiKeyId = options.apiKeyId;
|
|
81
|
+
this.bearer = options.bearer;
|
|
82
|
+
this.numberId = options.numberId;
|
|
83
|
+
this.onBearerUnauthorized = options.onBearerUnauthorized;
|
|
84
|
+
const f = options.fetchImpl ?? globalThis.fetch;
|
|
85
|
+
if (typeof f !== "function") {
|
|
86
|
+
throw new Error("No fetch implementation available. Use Node 18+ or pass fetchImpl.");
|
|
87
|
+
}
|
|
88
|
+
// Bind so `this` inside undici/native fetch stays correct.
|
|
89
|
+
this.fetchImpl = f.bind(globalThis);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Return a shallow clone of this client that attaches the given WhatsApp
|
|
93
|
+
* number selector (`x-whatsapp-number-id`) to every request — so a single
|
|
94
|
+
* tool call can scope tenant-wide credentials (OAuth token or tenant key)
|
|
95
|
+
* to one number without mutating the shared client.
|
|
96
|
+
*/
|
|
97
|
+
withNumber(numberId) {
|
|
98
|
+
return new ApiClient({
|
|
99
|
+
baseUrl: this.baseUrl,
|
|
100
|
+
apiKey: this.apiKey,
|
|
101
|
+
apiKeyId: this.apiKeyId,
|
|
102
|
+
bearer: this.bearer,
|
|
103
|
+
numberId,
|
|
104
|
+
fetchImpl: this.fetchImpl,
|
|
105
|
+
onBearerUnauthorized: this.onBearerUnauthorized,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async request(method, path, options = {}) {
|
|
109
|
+
const bearer = options.bearer ?? this.bearer;
|
|
110
|
+
const apiKey = options.apiKey ?? this.apiKey;
|
|
111
|
+
const apiKeyId = options.apiKeyId ?? this.apiKeyId;
|
|
112
|
+
const numberId = options.numberId ?? this.numberId;
|
|
113
|
+
const usingBearer = Boolean(bearer);
|
|
114
|
+
if (!usingBearer && !apiKey && !apiKeyId) {
|
|
115
|
+
throw new ApiError({
|
|
116
|
+
message: "Missing credentials. Provide an OAuth bearer token, set PILOT_STATUS_API_KEY (stdio), or send an x-api-key header (HTTP).",
|
|
117
|
+
status: 401,
|
|
118
|
+
code: "MISSING_API_KEY",
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const headers = {
|
|
122
|
+
accept: "application/json",
|
|
123
|
+
"user-agent": "pilot-status-mcp-server",
|
|
124
|
+
};
|
|
125
|
+
if (usingBearer) {
|
|
126
|
+
// Bearer mode: forward the OAuth token verbatim; never send x-api-key.
|
|
127
|
+
headers["authorization"] = `Bearer ${bearer}`;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
if (apiKey)
|
|
131
|
+
headers["x-api-key"] = apiKey;
|
|
132
|
+
if (apiKeyId)
|
|
133
|
+
headers["x-api-key-id"] = apiKeyId;
|
|
134
|
+
}
|
|
135
|
+
if (numberId)
|
|
136
|
+
headers["x-whatsapp-number-id"] = numberId;
|
|
137
|
+
const hasBody = options.body !== undefined && method.toUpperCase() !== "GET";
|
|
138
|
+
if (hasBody)
|
|
139
|
+
headers["content-type"] = "application/json";
|
|
140
|
+
const url = buildUrl(this.baseUrl, path, options.query);
|
|
141
|
+
let res;
|
|
142
|
+
try {
|
|
143
|
+
res = await this.fetchImpl(url, {
|
|
144
|
+
method,
|
|
145
|
+
headers,
|
|
146
|
+
body: hasBody ? JSON.stringify(options.body) : undefined,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
throw new ApiError({
|
|
151
|
+
message: `Network error calling ${method} ${path}: ${err instanceof Error ? err.message : String(err)}`,
|
|
152
|
+
status: 0,
|
|
153
|
+
code: "NETWORK_ERROR",
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
const text = await res.text();
|
|
157
|
+
let parsed = undefined;
|
|
158
|
+
if (text.length) {
|
|
159
|
+
try {
|
|
160
|
+
parsed = JSON.parse(text);
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
parsed = text;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (!res.ok) {
|
|
167
|
+
const bodyObj = parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
168
|
+
? parsed
|
|
169
|
+
: undefined;
|
|
170
|
+
const upstreamMessage = (typeof bodyObj?.error === "string" && bodyObj.error) ||
|
|
171
|
+
(typeof bodyObj?.message === "string" && bodyObj.message) ||
|
|
172
|
+
(typeof parsed === "string" && parsed) ||
|
|
173
|
+
res.statusText ||
|
|
174
|
+
"Request failed";
|
|
175
|
+
// In bearer mode, surface an upstream 401 so the HTTP transport can
|
|
176
|
+
// emit a WWW-Authenticate challenge and the client can re-auth.
|
|
177
|
+
if (usingBearer && res.status === 401) {
|
|
178
|
+
this.onBearerUnauthorized?.();
|
|
179
|
+
}
|
|
180
|
+
const hint = STATUS_HINTS[res.status] ?? `HTTP ${res.status}`;
|
|
181
|
+
throw new ApiError({
|
|
182
|
+
message: `${hint}: ${upstreamMessage}`,
|
|
183
|
+
status: res.status,
|
|
184
|
+
code: typeof bodyObj?.code === "string" ? bodyObj.code : undefined,
|
|
185
|
+
details: bodyObj?.details,
|
|
186
|
+
body: parsed,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return parsed;
|
|
190
|
+
}
|
|
191
|
+
get(path, options = {}) {
|
|
192
|
+
return this.request("GET", path, options);
|
|
193
|
+
}
|
|
194
|
+
post(path, options = {}) {
|
|
195
|
+
return this.request("POST", path, options);
|
|
196
|
+
}
|
|
197
|
+
put(path, options = {}) {
|
|
198
|
+
return this.request("PUT", path, options);
|
|
199
|
+
}
|
|
200
|
+
delete(path, options = {}) {
|
|
201
|
+
return this.request("DELETE", path, options);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAyCH,gFAAgF;AAChF,MAAM,YAAY,GAA2B;IACzC,GAAG,EAAE,aAAa;IAClB,GAAG,EAAE,mCAAmC;IACxC,GAAG,EAAE,mDAAmD;IACxD,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,uCAAuC;IAC5C,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,cAAc;IACnB,GAAG,EAAE,yBAAyB;IAC9B,GAAG,EAAE,qBAAqB;CAC7B,CAAC;AAEF,MAAM,OAAO,QAAS,SAAQ,KAAK;IACtB,MAAM,CAAS;IACf,IAAI,CAAU;IACd,OAAO,CAAW;IAC3B,mEAAmE;IAC1D,IAAI,CAAW;IAExB,YAAY,IAMX;QACG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,MAAM;QACF,OAAO;YACH,KAAK,EAAE,IAAI,CAAC,OAAO;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACN,CAAC;CACJ;AAED,SAAS,QAAQ,CACb,OAAe,EACf,IAAY,EACZ,KAA+B;IAE/B,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;IAChE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,OAAO,GAAG,cAAc,EAAE,CAAC,CAAC;IACnD,IAAI,KAAK,EAAE,CAAC;QACR,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI;gBAAE,SAAS;YACpD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7C,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,OAAO,SAAS;IACD,OAAO,CAAS;IAChB,MAAM,CAAU;IAChB,QAAQ,CAAU;IAClB,MAAM,CAAU;IAChB,QAAQ,CAAU;IAClB,oBAAoB,CAAc;IAClC,SAAS,CAAe;IAEzC,YAAY,OAAyB;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QACjC,IAAI,CAAC,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC;QACzD,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;QAChD,IAAI,OAAO,CAAC,KAAK,UAAU,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CACX,oEAAoE,CACvE,CAAC;QACN,CAAC;QACD,2DAA2D;QAC3D,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,QAAgB;QACvB,OAAO,IAAI,SAAS,CAAC;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ;YACR,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;SAClD,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,OAAO,CACT,MAAc,EACd,IAAY,EACZ,UAA0B,EAAE;QAE5B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC;QACnD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvC,MAAM,IAAI,QAAQ,CAAC;gBACf,OAAO,EACH,2HAA2H;gBAC/H,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,iBAAiB;aAC1B,CAAC,CAAC;QACP,CAAC;QAED,MAAM,OAAO,GAA2B;YACpC,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,yBAAyB;SAC1C,CAAC;QACF,IAAI,WAAW,EAAE,CAAC;YACd,uEAAuE;YACvE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;QAClD,CAAC;aAAM,CAAC;YACJ,IAAI,MAAM;gBAAE,OAAO,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC;YAC1C,IAAI,QAAQ;gBAAE,OAAO,CAAC,cAAc,CAAC,GAAG,QAAQ,CAAC;QACrD,CAAC;QACD,IAAI,QAAQ;YAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,QAAQ,CAAC;QAEzD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC;QAC7E,IAAI,OAAO;YAAE,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;QAE1D,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAExD,IAAI,GAAa,CAAC;QAClB,IAAI,CAAC;YACD,GAAG,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;gBAC5B,MAAM;gBACN,OAAO;gBACP,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;aAC3D,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,IAAI,QAAQ,CAAC;gBACf,OAAO,EAAE,yBAAyB,MAAM,IAAI,IAAI,KAC5C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACnD,EAAE;gBACF,MAAM,EAAE,CAAC;gBACT,IAAI,EAAE,eAAe;aACxB,CAAC,CAAC;QACP,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,MAAM,GAAY,SAAS,CAAC;QAChC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC;gBACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;YAAC,MAAM,CAAC;gBACL,MAAM,GAAG,IAAI,CAAC;YAClB,CAAC;QACL,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACV,MAAM,OAAO,GACT,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC1D,CAAC,CAAE,MAAkC;gBACrC,CAAC,CAAC,SAAS,CAAC;YACpB,MAAM,eAAe,GACjB,CAAC,OAAO,OAAO,EAAE,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC;gBACrD,CAAC,OAAO,OAAO,EAAE,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;gBACzD,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC;gBACtC,GAAG,CAAC,UAAU;gBACd,gBAAgB,CAAC;YACrB,oEAAoE;YACpE,gEAAgE;YAChE,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACpC,IAAI,CAAC,oBAAoB,EAAE,EAAE,CAAC;YAClC,CAAC;YACD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;YAC9D,MAAM,IAAI,QAAQ,CAAC;gBACf,OAAO,EAAE,GAAG,IAAI,KAAK,eAAe,EAAE;gBACtC,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,OAAO,OAAO,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;gBAClE,OAAO,EAAE,OAAO,EAAE,OAAO;gBACzB,IAAI,EAAE,MAAM;aACf,CAAC,CAAC;QACP,CAAC;QAED,OAAO,MAAW,CAAC;IACvB,CAAC;IAED,GAAG,CAAc,IAAY,EAAE,UAA0B,EAAE;QACvD,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,CAAc,IAAY,EAAE,UAA0B,EAAE;QACxD,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;IAED,GAAG,CAAc,IAAY,EAAE,UAA0B,EAAE;QACvD,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,CAAc,IAAY,EAAE,UAA0B,EAAE;QAC1D,OAAO,IAAI,CAAC,OAAO,CAAI,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;CACJ"}
|