@robosystems/client 0.1.10
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 +455 -0
- package/client/client.gen.ts +200 -0
- package/client/index.ts +25 -0
- package/client/types.gen.ts +233 -0
- package/client/utils.gen.ts +419 -0
- package/client.gen.ts +18 -0
- package/core/auth.gen.ts +42 -0
- package/core/bodySerializer.gen.ts +90 -0
- package/core/params.gen.ts +153 -0
- package/core/pathSerializer.gen.ts +181 -0
- package/core/types.gen.ts +121 -0
- package/index.d.ts +8 -0
- package/index.js +8 -0
- package/index.ts +3 -0
- package/openapi-ts.config.js +9 -0
- package/package.json +74 -0
- package/prepare.js +214 -0
- package/sdk.gen.ts +2449 -0
- package/types.gen.ts +6191 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Harbinger FinLab
|
|
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,455 @@
|
|
|
1
|
+
# RoboSystems TypeScript Client
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@robosystems/client)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
Official TypeScript Client for the RoboSystems Financial Knowledge Graph API. Access comprehensive financial data including accounting records, SEC filings, and advanced graph analytics through a type-safe, modern TypeScript interface.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Type-safe API client** with full TypeScript types
|
|
11
|
+
- **Auto-generated from OpenAPI** for always up-to-date types
|
|
12
|
+
- **Browser & Node.js support** with different auth strategies
|
|
13
|
+
- **React hooks** for seamless UI integration
|
|
14
|
+
- **Queue handling** for long-running operations
|
|
15
|
+
- **Streaming support** for large datasets
|
|
16
|
+
- **Financial AI Agent** integration
|
|
17
|
+
- **Comprehensive error handling** with typed errors
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @robosystems/client
|
|
23
|
+
# or
|
|
24
|
+
yarn add @robosystems/client
|
|
25
|
+
# or
|
|
26
|
+
pnpm add @robosystems/client
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
### Browser Usage (with cookies)
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { client, getUserMe, listCompanies, executeCypherQuery } from '@robosystems/client'
|
|
35
|
+
|
|
36
|
+
// Configure the client
|
|
37
|
+
client.setConfig({
|
|
38
|
+
baseUrl: 'https://api.robosystems.ai',
|
|
39
|
+
credentials: 'include',
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// Use with cookie-based authentication (browser)
|
|
43
|
+
const { data: user, error } = await getCurrentUser()
|
|
44
|
+
if (user) {
|
|
45
|
+
console.log('Logged in as:', user.email)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// List companies in a graph
|
|
49
|
+
const { data: companies } = await listCompanies({
|
|
50
|
+
path: { graph_id: 'your-graph-id' },
|
|
51
|
+
query: { limit: 10 },
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
// Execute a Cypher query
|
|
55
|
+
const { data: result } = await executeCypherQuery({
|
|
56
|
+
path: { graph_id: 'your-graph-id' },
|
|
57
|
+
body: {
|
|
58
|
+
query: 'MATCH (c:Company)-[:HAS_FILING]->(f:Filing) RETURN c.name, f.form_type LIMIT 5',
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Server Usage (with API key)
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { client, getUserGraphs, listCompanies } from '@robosystems/client'
|
|
67
|
+
|
|
68
|
+
// Configure with API key for server-side usage
|
|
69
|
+
client.setConfig({
|
|
70
|
+
baseUrl: 'https://api.robosystems.ai',
|
|
71
|
+
headers: {
|
|
72
|
+
'X-API-Key': process.env.ROBOSYSTEMS_API_KEY!,
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
// Fetch user's graphs
|
|
77
|
+
const { data: graphs, error } = await getUserGraphs()
|
|
78
|
+
|
|
79
|
+
// Work with financial data
|
|
80
|
+
if (graphs?.graphs.length) {
|
|
81
|
+
const graphId = graphs.graphs[0].graph_id
|
|
82
|
+
const { data: companies } = await listCompanies({
|
|
83
|
+
path: { graph_id: graphId },
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Key API Endpoints
|
|
89
|
+
|
|
90
|
+
### Authentication & User Management
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import {
|
|
94
|
+
registerUser,
|
|
95
|
+
loginUser,
|
|
96
|
+
logoutUser,
|
|
97
|
+
getCurrentUser,
|
|
98
|
+
createUserApiKey,
|
|
99
|
+
} from '@robosystems/client'
|
|
100
|
+
|
|
101
|
+
// Register a new user
|
|
102
|
+
const { data, error } = await registerUser({
|
|
103
|
+
body: {
|
|
104
|
+
email: 'user@example.com',
|
|
105
|
+
password: 'secure-password',
|
|
106
|
+
name: 'John Doe',
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Sign in
|
|
111
|
+
const { data: session } = await loginUser({
|
|
112
|
+
body: {
|
|
113
|
+
username: 'user@example.com',
|
|
114
|
+
password: 'secure-password',
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
// Get current user
|
|
119
|
+
const { data: user } = await getCurrentUser()
|
|
120
|
+
|
|
121
|
+
// Create API key for programmatic access
|
|
122
|
+
const { data: apiKey } = await createUserApiKey({
|
|
123
|
+
body: {
|
|
124
|
+
key_name: 'Production Server',
|
|
125
|
+
key_type: 'user',
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
console.log('Save this key securely:', apiKey.key)
|
|
129
|
+
|
|
130
|
+
// Sign out
|
|
131
|
+
await logoutUser()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Company & Financial Data
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import {
|
|
138
|
+
listCompanies,
|
|
139
|
+
getCompany,
|
|
140
|
+
createCompany,
|
|
141
|
+
createConnection,
|
|
142
|
+
syncConnection,
|
|
143
|
+
} from '@robosystems/client'
|
|
144
|
+
|
|
145
|
+
// List companies with pagination
|
|
146
|
+
const { data: companies } = await listCompanies({
|
|
147
|
+
path: { graph_id: 'your-graph-id' },
|
|
148
|
+
query: { limit: 20, offset: 0 },
|
|
149
|
+
})
|
|
150
|
+
console.log(`Found ${companies.total} companies`)
|
|
151
|
+
|
|
152
|
+
// Get specific company details
|
|
153
|
+
const { data: company } = await getCompany({
|
|
154
|
+
path: {
|
|
155
|
+
graph_id: 'your-graph-id',
|
|
156
|
+
company_id: 'AAPL',
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// Create new company
|
|
161
|
+
const { data: newCompany } = await createCompany({
|
|
162
|
+
path: { graph_id: 'your-graph-id' },
|
|
163
|
+
body: {
|
|
164
|
+
identifier: 'MSFT',
|
|
165
|
+
name: 'Microsoft Corporation',
|
|
166
|
+
metadata: { industry: 'Technology' },
|
|
167
|
+
},
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
// Create data connection (QuickBooks, etc.)
|
|
171
|
+
const { data: connection } = await createConnection({
|
|
172
|
+
path: { graph_id: 'your-graph-id' },
|
|
173
|
+
body: {
|
|
174
|
+
name: 'QuickBooks Integration',
|
|
175
|
+
connection_type: 'quickbooks',
|
|
176
|
+
config: { company_id: '123456' },
|
|
177
|
+
},
|
|
178
|
+
})
|
|
179
|
+
|
|
180
|
+
// Sync data from connection
|
|
181
|
+
const { data: syncResult } = await syncConnection({
|
|
182
|
+
path: {
|
|
183
|
+
graph_id: 'your-graph-id',
|
|
184
|
+
connection_id: connection.id,
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Graph Queries & Analytics
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
import {
|
|
193
|
+
executeCypherQuery,
|
|
194
|
+
executeReadOnlyCypherQuery,
|
|
195
|
+
getGraphMetrics,
|
|
196
|
+
} from '@robosystems/client'
|
|
197
|
+
|
|
198
|
+
// Execute parameterized Cypher queries
|
|
199
|
+
const { data: results } = await executeCypherQuery({
|
|
200
|
+
path: { graph_id: 'your-graph-id' },
|
|
201
|
+
body: {
|
|
202
|
+
query: `
|
|
203
|
+
MATCH (c:Company {ticker: $ticker})-[:HAS_METRIC]->(m:Metric)
|
|
204
|
+
WHERE m.fiscal_year >= $start_year
|
|
205
|
+
RETURN m.name, m.value, m.fiscal_year
|
|
206
|
+
ORDER BY m.fiscal_year DESC
|
|
207
|
+
`,
|
|
208
|
+
parameters: { ticker: 'AAPL', start_year: 2020 },
|
|
209
|
+
},
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
// Read-only queries for better performance
|
|
213
|
+
const { data: readOnlyResult } = await executeReadOnlyCypherQuery({
|
|
214
|
+
path: { graph_id: 'your-graph-id' },
|
|
215
|
+
body: { query: 'MATCH (n) RETURN count(n) as total' },
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Get graph analytics
|
|
219
|
+
const { data: metrics } = await getGraphMetrics({
|
|
220
|
+
path: { graph_id: 'your-graph-id' },
|
|
221
|
+
})
|
|
222
|
+
console.log(`Total nodes: ${metrics.total_nodes}`)
|
|
223
|
+
console.log(`Total relationships: ${metrics.total_relationships}`)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Financial AI Agent
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import { queryFinancialAgent } from '@robosystems/client'
|
|
230
|
+
|
|
231
|
+
// Natural language financial queries
|
|
232
|
+
const { data: agentResponse } = await queryFinancialAgent({
|
|
233
|
+
path: { graph_id: 'your-graph-id' },
|
|
234
|
+
body: {
|
|
235
|
+
query: "What was Apple's revenue growth over the last 3 years?",
|
|
236
|
+
include_reasoning: true,
|
|
237
|
+
max_tokens: 1000,
|
|
238
|
+
},
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
console.log('Answer:', agentResponse.answer)
|
|
242
|
+
if (agentResponse.reasoning) {
|
|
243
|
+
console.log('Reasoning:', agentResponse.reasoning)
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Advanced Features
|
|
248
|
+
|
|
249
|
+
### Billing & Credit Management
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { getCreditSummary, checkCreditBalance, getCurrentGraphBill } from '@robosystems/client'
|
|
253
|
+
|
|
254
|
+
// Monitor credits and usage for a specific graph
|
|
255
|
+
const { data: creditSummary } = await getCreditSummary({
|
|
256
|
+
path: { graph_id: 'your-graph-id' },
|
|
257
|
+
})
|
|
258
|
+
console.log(`Available credits: ${creditSummary.available_credits.toLocaleString()}`)
|
|
259
|
+
console.log(
|
|
260
|
+
`Monthly usage: ${creditSummary.used_credits.toLocaleString()}/${creditSummary.total_credits.toLocaleString()}`
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
// Check credit requirements before operations
|
|
264
|
+
const { data: creditCheck } = await checkCreditBalance({
|
|
265
|
+
path: { graph_id: 'your-graph-id' },
|
|
266
|
+
body: {
|
|
267
|
+
operation_type: 'query',
|
|
268
|
+
estimated_credits: 100,
|
|
269
|
+
},
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
if (creditCheck.has_sufficient_credits) {
|
|
273
|
+
// Proceed with operation
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Get billing information
|
|
277
|
+
const { data: currentBill } = await getCurrentGraphBill({
|
|
278
|
+
path: { graph_id: 'your-graph-id' },
|
|
279
|
+
})
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### MCP Tools Integration
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import { listMcpTools, callMcpTool } from '@robosystems/client'
|
|
286
|
+
|
|
287
|
+
// List available MCP tools
|
|
288
|
+
const { data: tools } = await listMcpTools({
|
|
289
|
+
path: { graph_id: 'your-graph-id' },
|
|
290
|
+
})
|
|
291
|
+
tools.tools.forEach((tool) => {
|
|
292
|
+
console.log(`${tool.name}: ${tool.description}`)
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
// Call an MCP tool
|
|
296
|
+
const { data: toolResult } = await callMcpTool({
|
|
297
|
+
path: { graph_id: 'your-graph-id' },
|
|
298
|
+
body: {
|
|
299
|
+
name: 'analyze_financial_statement',
|
|
300
|
+
arguments: {
|
|
301
|
+
company_id: 'AAPL',
|
|
302
|
+
statement_type: 'income',
|
|
303
|
+
fiscal_year: 2023,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
})
|
|
307
|
+
console.log('Analysis result:', toolResult.content)
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Advanced Features
|
|
311
|
+
|
|
312
|
+
### Error Handling
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import { listCompanies } from '@robosystems/client'
|
|
316
|
+
import type { ErrorResponse } from '@robosystems/client'
|
|
317
|
+
|
|
318
|
+
try {
|
|
319
|
+
const { data, error } = await listCompanies({
|
|
320
|
+
path: { graph_id: 'your-graph-id' },
|
|
321
|
+
})
|
|
322
|
+
|
|
323
|
+
if (error) {
|
|
324
|
+
const apiError = error as ErrorResponse
|
|
325
|
+
|
|
326
|
+
switch (apiError.status) {
|
|
327
|
+
case 400:
|
|
328
|
+
console.error('Validation error:', apiError.detail)
|
|
329
|
+
break
|
|
330
|
+
case 401:
|
|
331
|
+
console.error('Authentication failed - check your API key')
|
|
332
|
+
break
|
|
333
|
+
case 403:
|
|
334
|
+
console.error('Permission denied - check graph access')
|
|
335
|
+
break
|
|
336
|
+
case 429:
|
|
337
|
+
console.error('Rate limit exceeded - retry later')
|
|
338
|
+
break
|
|
339
|
+
case 503:
|
|
340
|
+
console.error('Service temporarily unavailable')
|
|
341
|
+
break
|
|
342
|
+
default:
|
|
343
|
+
console.error('API Error:', apiError.detail || apiError.message)
|
|
344
|
+
}
|
|
345
|
+
} else if (data) {
|
|
346
|
+
console.log(`Found ${data.total} companies`)
|
|
347
|
+
}
|
|
348
|
+
} catch (err) {
|
|
349
|
+
// Network errors
|
|
350
|
+
console.error('Network Error:', err)
|
|
351
|
+
}
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
### TypeScript Types
|
|
355
|
+
|
|
356
|
+
All API responses and requests are fully typed:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
import type {
|
|
360
|
+
User,
|
|
361
|
+
Graph,
|
|
362
|
+
Company,
|
|
363
|
+
CompanyCreate,
|
|
364
|
+
CypherQueryRequest,
|
|
365
|
+
CypherQueryResponse,
|
|
366
|
+
AgentQueryRequest,
|
|
367
|
+
AgentQueryResponse,
|
|
368
|
+
ErrorResponse,
|
|
369
|
+
PaginatedResponse,
|
|
370
|
+
} from '@robosystems/client'
|
|
371
|
+
|
|
372
|
+
// Type-safe function example
|
|
373
|
+
function processCompany(company: Company): void {
|
|
374
|
+
console.log(`Company: ${company.name} (${company.identifier})`)
|
|
375
|
+
if (company.metadata) {
|
|
376
|
+
console.log('Industry:', company.metadata.industry)
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Type-safe query builder
|
|
381
|
+
function buildMetricQuery(ticker: string, startYear: number): CypherQueryRequest {
|
|
382
|
+
return {
|
|
383
|
+
query: `
|
|
384
|
+
MATCH (c:Company {ticker: $ticker})-[:HAS_METRIC]->(m:Metric)
|
|
385
|
+
WHERE m.fiscal_year >= $start_year
|
|
386
|
+
RETURN m
|
|
387
|
+
`,
|
|
388
|
+
parameters: { ticker, start_year: startYear },
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Environment Configuration
|
|
394
|
+
|
|
395
|
+
### Next.js App Router
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// app/api/robosystems/route.ts
|
|
399
|
+
import { client } from '@robosystems/client'
|
|
400
|
+
|
|
401
|
+
// Configure for server-side API routes
|
|
402
|
+
client.setConfig({
|
|
403
|
+
baseUrl: process.env.ROBOSYSTEMS_API_URL || 'https://api.robosystems.ai',
|
|
404
|
+
headers: {
|
|
405
|
+
'X-API-Key': process.env.ROBOSYSTEMS_API_KEY!,
|
|
406
|
+
},
|
|
407
|
+
})
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### React SPA
|
|
411
|
+
|
|
412
|
+
```typescript
|
|
413
|
+
// src/lib/robosystems.ts
|
|
414
|
+
import { client } from '@robosystems/client'
|
|
415
|
+
|
|
416
|
+
// Configure for browser with cookies
|
|
417
|
+
client.setConfig({
|
|
418
|
+
baseUrl: import.meta.env.VITE_ROBOSYSTEMS_API_URL || 'https://api.robosystems.ai',
|
|
419
|
+
credentials: 'include',
|
|
420
|
+
})
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Node.js Script
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
// scripts/analyze.ts
|
|
427
|
+
import { client } from '@robosystems/client'
|
|
428
|
+
import dotenv from 'dotenv'
|
|
429
|
+
|
|
430
|
+
dotenv.config()
|
|
431
|
+
|
|
432
|
+
client.setConfig({
|
|
433
|
+
baseUrl: process.env.ROBOSYSTEMS_API_URL || 'https://api.robosystems.ai',
|
|
434
|
+
headers: {
|
|
435
|
+
'X-API-Key': process.env.ROBOSYSTEMS_API_KEY!,
|
|
436
|
+
},
|
|
437
|
+
})
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## API Reference
|
|
441
|
+
|
|
442
|
+
- Full API documentation: [https://api.robosystems.ai/docs](https://api.robosystems.ai/docs)
|
|
443
|
+
- OpenAPI specification: [https://api.robosystems.ai/openapi.json](https://api.robosystems.ai/openapi.json)
|
|
444
|
+
|
|
445
|
+
## Support
|
|
446
|
+
|
|
447
|
+
- Documentation: [https://docs.robosystems.ai](https://docs.robosystems.ai)
|
|
448
|
+
- Issues: [GitHub Issues](https://github.com/HarbingerFinLab/robosystems-typescript-client/issues)
|
|
449
|
+
- Email: support@robosystems.ai
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
454
|
+
|
|
455
|
+
MIT © 2024 Harbinger FinLab
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
|
+
/* eslint-disable no-undef */
|
|
3
|
+
|
|
4
|
+
import type { Client, Config, ResolvedRequestOptions } from './types.gen';
|
|
5
|
+
import {
|
|
6
|
+
buildUrl,
|
|
7
|
+
createConfig,
|
|
8
|
+
createInterceptors,
|
|
9
|
+
getParseAs,
|
|
10
|
+
mergeConfigs,
|
|
11
|
+
mergeHeaders,
|
|
12
|
+
setAuthParams,
|
|
13
|
+
} from './utils.gen';
|
|
14
|
+
|
|
15
|
+
type ReqInit = Omit<RequestInit, 'body' | 'headers'> & {
|
|
16
|
+
body?: any;
|
|
17
|
+
headers: ReturnType<typeof mergeHeaders>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const createClient = (config: Config = {}): Client => {
|
|
21
|
+
let _config = mergeConfigs(createConfig(), config);
|
|
22
|
+
|
|
23
|
+
const getConfig = (): Config => ({ ..._config });
|
|
24
|
+
|
|
25
|
+
const setConfig = (config: Config): Config => {
|
|
26
|
+
_config = mergeConfigs(_config, config);
|
|
27
|
+
return getConfig();
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const interceptors = createInterceptors<
|
|
31
|
+
Request,
|
|
32
|
+
Response,
|
|
33
|
+
unknown,
|
|
34
|
+
ResolvedRequestOptions
|
|
35
|
+
>();
|
|
36
|
+
|
|
37
|
+
const request: Client['request'] = async (options) => {
|
|
38
|
+
const opts = {
|
|
39
|
+
..._config,
|
|
40
|
+
...options,
|
|
41
|
+
fetch: options.fetch ?? _config.fetch ?? globalThis.fetch,
|
|
42
|
+
headers: mergeHeaders(_config.headers, options.headers),
|
|
43
|
+
serializedBody: undefined,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
if (opts.security) {
|
|
47
|
+
await setAuthParams({
|
|
48
|
+
...opts,
|
|
49
|
+
security: opts.security,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (opts.requestValidator) {
|
|
54
|
+
await opts.requestValidator(opts);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (opts.body && opts.bodySerializer) {
|
|
58
|
+
opts.serializedBody = opts.bodySerializer(opts.body);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// remove Content-Type header if body is empty to avoid sending invalid requests
|
|
62
|
+
if (opts.serializedBody === undefined || opts.serializedBody === '') {
|
|
63
|
+
opts.headers.delete('Content-Type');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const url = buildUrl(opts);
|
|
67
|
+
const requestInit: ReqInit = {
|
|
68
|
+
redirect: 'follow',
|
|
69
|
+
...opts,
|
|
70
|
+
body: opts.serializedBody,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
let request = new Request(url, requestInit);
|
|
74
|
+
|
|
75
|
+
for (const fn of interceptors.request._fns) {
|
|
76
|
+
if (fn) {
|
|
77
|
+
request = await fn(request, opts);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// fetch must be assigned here, otherwise it would throw the error:
|
|
82
|
+
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
|
|
83
|
+
const _fetch = opts.fetch!;
|
|
84
|
+
let response = await _fetch(request);
|
|
85
|
+
|
|
86
|
+
for (const fn of interceptors.response._fns) {
|
|
87
|
+
if (fn) {
|
|
88
|
+
response = await fn(response, request, opts);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const result = {
|
|
93
|
+
request,
|
|
94
|
+
response,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
if (response.ok) {
|
|
98
|
+
if (
|
|
99
|
+
response.status === 204 ||
|
|
100
|
+
response.headers.get('Content-Length') === '0'
|
|
101
|
+
) {
|
|
102
|
+
return opts.responseStyle === 'data'
|
|
103
|
+
? {}
|
|
104
|
+
: {
|
|
105
|
+
data: {},
|
|
106
|
+
...result,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const parseAs =
|
|
111
|
+
(opts.parseAs === 'auto'
|
|
112
|
+
? getParseAs(response.headers.get('Content-Type'))
|
|
113
|
+
: opts.parseAs) ?? 'json';
|
|
114
|
+
|
|
115
|
+
let data: any;
|
|
116
|
+
switch (parseAs) {
|
|
117
|
+
case 'arrayBuffer':
|
|
118
|
+
case 'blob':
|
|
119
|
+
case 'formData':
|
|
120
|
+
case 'json':
|
|
121
|
+
case 'text':
|
|
122
|
+
data = await response[parseAs]();
|
|
123
|
+
break;
|
|
124
|
+
case 'stream':
|
|
125
|
+
return opts.responseStyle === 'data'
|
|
126
|
+
? response.body
|
|
127
|
+
: {
|
|
128
|
+
data: response.body,
|
|
129
|
+
...result,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (parseAs === 'json') {
|
|
134
|
+
if (opts.responseValidator) {
|
|
135
|
+
await opts.responseValidator(data);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (opts.responseTransformer) {
|
|
139
|
+
data = await opts.responseTransformer(data);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return opts.responseStyle === 'data'
|
|
144
|
+
? data
|
|
145
|
+
: {
|
|
146
|
+
data,
|
|
147
|
+
...result,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const textError = await response.text();
|
|
152
|
+
let jsonError: unknown;
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
jsonError = JSON.parse(textError);
|
|
156
|
+
} catch {
|
|
157
|
+
// noop
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const error = jsonError ?? textError;
|
|
161
|
+
let finalError = error;
|
|
162
|
+
|
|
163
|
+
for (const fn of interceptors.error._fns) {
|
|
164
|
+
if (fn) {
|
|
165
|
+
finalError = (await fn(error, response, request, opts)) as string;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
finalError = finalError || ({} as string);
|
|
170
|
+
|
|
171
|
+
if (opts.throwOnError) {
|
|
172
|
+
throw finalError;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// TODO: we probably want to return error and improve types
|
|
176
|
+
return opts.responseStyle === 'data'
|
|
177
|
+
? undefined
|
|
178
|
+
: {
|
|
179
|
+
error: finalError,
|
|
180
|
+
...result,
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
buildUrl,
|
|
186
|
+
connect: (options) => request({ ...options, method: 'CONNECT' }),
|
|
187
|
+
delete: (options) => request({ ...options, method: 'DELETE' }),
|
|
188
|
+
get: (options) => request({ ...options, method: 'GET' }),
|
|
189
|
+
getConfig,
|
|
190
|
+
head: (options) => request({ ...options, method: 'HEAD' }),
|
|
191
|
+
interceptors,
|
|
192
|
+
options: (options) => request({ ...options, method: 'OPTIONS' }),
|
|
193
|
+
patch: (options) => request({ ...options, method: 'PATCH' }),
|
|
194
|
+
post: (options) => request({ ...options, method: 'POST' }),
|
|
195
|
+
put: (options) => request({ ...options, method: 'PUT' }),
|
|
196
|
+
request,
|
|
197
|
+
setConfig,
|
|
198
|
+
trace: (options) => request({ ...options, method: 'TRACE' }),
|
|
199
|
+
};
|
|
200
|
+
};
|
package/client/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
|
+
|
|
3
|
+
export type { Auth } from '../core/auth.gen';
|
|
4
|
+
export type { QuerySerializerOptions } from '../core/bodySerializer.gen';
|
|
5
|
+
export {
|
|
6
|
+
formDataBodySerializer,
|
|
7
|
+
jsonBodySerializer,
|
|
8
|
+
urlSearchParamsBodySerializer,
|
|
9
|
+
} from '../core/bodySerializer.gen';
|
|
10
|
+
export { buildClientParams } from '../core/params.gen';
|
|
11
|
+
export { createClient } from './client.gen';
|
|
12
|
+
export type {
|
|
13
|
+
Client,
|
|
14
|
+
ClientOptions,
|
|
15
|
+
Config,
|
|
16
|
+
CreateClientConfig,
|
|
17
|
+
Options,
|
|
18
|
+
OptionsLegacyParser,
|
|
19
|
+
RequestOptions,
|
|
20
|
+
RequestResult,
|
|
21
|
+
ResolvedRequestOptions,
|
|
22
|
+
ResponseStyle,
|
|
23
|
+
TDataShape,
|
|
24
|
+
} from './types.gen';
|
|
25
|
+
export { createConfig, mergeHeaders } from './utils.gen';
|