@robosystems/client 0.1.19 → 0.1.21
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 +1 -1
- package/README.md +10 -423
- package/bin/create-feature +58 -55
- package/client/utils.gen.js +14 -1
- package/client/utils.gen.ts +23 -2
- package/core/bodySerializer.gen.js +3 -0
- package/core/bodySerializer.gen.ts +2 -0
- package/package.json +3 -3
- package/sdk/client/utils.gen.js +14 -1
- package/sdk/client/utils.gen.ts +23 -2
- package/sdk/core/bodySerializer.gen.js +3 -0
- package/sdk/core/bodySerializer.gen.ts +2 -0
- package/sdk/sdk.gen.d.ts +192 -129
- package/sdk/sdk.gen.js +413 -216
- package/sdk/sdk.gen.ts +412 -215
- package/sdk/types.gen.d.ts +952 -252
- package/sdk/types.gen.ts +1016 -253
- package/sdk-extensions/README.md +2 -3
- package/sdk.gen.d.ts +192 -129
- package/sdk.gen.js +413 -216
- package/sdk.gen.ts +412 -215
- package/types.gen.d.ts +952 -252
- package/types.gen.ts +1016 -253
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -3,451 +3,38 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@robosystems/client)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
Official TypeScript Client for the RoboSystems Financial Knowledge Graph API. Access comprehensive financial data including accounting
|
|
6
|
+
Official TypeScript Client for the RoboSystems Financial Knowledge Graph API. Access comprehensive financial data including accounting transactions, financial reports, and advanced graph analytics through a type-safe, modern TypeScript interface.
|
|
7
7
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
10
|
- **Type-safe API client** with full TypeScript types
|
|
11
|
-
- **Auto-generated from OpenAPI** for always up-to-date types
|
|
12
11
|
- **Browser & Node.js support** with different auth strategies
|
|
13
12
|
- **React hooks** for seamless UI integration
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **Financial AI Agent** integration
|
|
13
|
+
- **Streaming support** for memory-efficient processing of large result sets
|
|
14
|
+
- **Financial AI Agent** integration for natural language queries
|
|
17
15
|
- **Comprehensive error handling** with typed errors
|
|
18
16
|
|
|
19
17
|
## Installation
|
|
20
18
|
|
|
21
19
|
```bash
|
|
22
20
|
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
21
|
```
|
|
439
22
|
|
|
440
23
|
## API Reference
|
|
441
24
|
|
|
442
|
-
-
|
|
25
|
+
- API reference: [https://api.robosystems.ai](https://api.robosystems.ai)
|
|
26
|
+
- API documentation: [https://api.robosystems.ai/docs](https://api.robosystems.ai/docs)
|
|
443
27
|
- OpenAPI specification: [https://api.robosystems.ai/openapi.json](https://api.robosystems.ai/openapi.json)
|
|
444
28
|
|
|
445
29
|
## Support
|
|
446
30
|
|
|
447
|
-
- Issues: [
|
|
31
|
+
- Issues: [Issues](https://github.com/RoboFinSystems/robosystems-typescript-client/issues)
|
|
32
|
+
- Discussions: [Discussions](https://github.com/RoboFinSystems/robosystems-typescript-client/discussions)
|
|
33
|
+
- Projects: [Projects](https://github.com/RoboFinSystems/robosystems-typescript-client/projects)
|
|
34
|
+
- Wiki: [Wiki](https://github.com/RoboFinSystems/robosystems-typescript-client/wiki)
|
|
448
35
|
|
|
449
36
|
## License
|
|
450
37
|
|
|
451
38
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
452
39
|
|
|
453
|
-
MIT © 2025
|
|
40
|
+
MIT © 2025 RFS LLC
|
package/bin/create-feature
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
set -e
|
|
3
3
|
|
|
4
|
-
# Create feature branch script
|
|
5
|
-
# Creates a new feature/bugfix/hotfix branch
|
|
4
|
+
# Create feature branch script - local Git operations
|
|
5
|
+
# Creates a new feature/bugfix/hotfix branch locally and pushes to remote
|
|
6
6
|
# Usage: ./bin/create-feature [feature|bugfix|hotfix|chore|refactor] [branch-name] [base-branch]
|
|
7
7
|
|
|
8
8
|
# Default values
|
|
@@ -13,79 +13,82 @@ BASE_BRANCH=${3:-main}
|
|
|
13
13
|
# Validate branch type
|
|
14
14
|
if [[ "$BRANCH_TYPE" != "feature" && "$BRANCH_TYPE" != "bugfix" && "$BRANCH_TYPE" != "hotfix" && "$BRANCH_TYPE" != "chore" && "$BRANCH_TYPE" != "refactor" ]]; then
|
|
15
15
|
echo "❌ Invalid branch type: $BRANCH_TYPE"
|
|
16
|
-
echo "
|
|
16
|
+
echo "Valid types: feature, bugfix, hotfix, chore, refactor"
|
|
17
17
|
exit 1
|
|
18
18
|
fi
|
|
19
19
|
|
|
20
|
-
# Check if branch name
|
|
20
|
+
# Check if branch name was provided
|
|
21
21
|
if [ -z "$BRANCH_NAME" ]; then
|
|
22
22
|
echo "❌ Branch name is required"
|
|
23
|
-
echo "Usage: $0 [
|
|
23
|
+
echo "Usage: $0 [type] [name] [base_branch]"
|
|
24
|
+
echo "Example: $0 feature add-user-auth main"
|
|
24
25
|
exit 1
|
|
25
26
|
fi
|
|
26
27
|
|
|
27
28
|
# Sanitize branch name
|
|
28
|
-
SANITIZED_NAME=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//'
|
|
29
|
-
|
|
29
|
+
SANITIZED_NAME=$(echo "$BRANCH_NAME" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')
|
|
30
|
+
FULL_BRANCH="${BRANCH_TYPE}/${SANITIZED_NAME}"
|
|
30
31
|
|
|
31
|
-
echo "
|
|
32
|
-
echo "📋
|
|
32
|
+
echo "🚀 Creating feature branch locally..."
|
|
33
|
+
echo "📋 Details:"
|
|
33
34
|
echo " Type: $BRANCH_TYPE"
|
|
34
35
|
echo " Name: $SANITIZED_NAME"
|
|
35
|
-
echo " Full
|
|
36
|
+
echo " Full Branch: $FULL_BRANCH"
|
|
36
37
|
echo " Base Branch: $BASE_BRANCH"
|
|
37
38
|
echo ""
|
|
38
39
|
|
|
39
40
|
# Check for uncommitted changes
|
|
40
41
|
if ! git diff --quiet || ! git diff --cached --quiet; then
|
|
41
|
-
echo "⚠️ You have uncommitted changes.
|
|
42
|
-
|
|
43
|
-
echo "
|
|
44
|
-
|
|
42
|
+
echo "⚠️ You have uncommitted changes. Auto-stashing..."
|
|
43
|
+
git stash push -m "Auto-stash before creating branch $FULL_BRANCH"
|
|
44
|
+
echo "✅ Changes stashed"
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
# Fetch latest changes from remote
|
|
48
|
+
echo "📥 Fetching latest changes from remote..."
|
|
49
|
+
git fetch origin
|
|
50
|
+
|
|
51
|
+
# Check if branch already exists (local or remote)
|
|
52
|
+
if git show-ref --verify --quiet refs/heads/$FULL_BRANCH; then
|
|
53
|
+
echo "❌ Branch $FULL_BRANCH already exists locally"
|
|
45
54
|
exit 1
|
|
46
55
|
fi
|
|
47
56
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
57
|
+
if git show-ref --verify --quiet refs/remotes/origin/$FULL_BRANCH; then
|
|
58
|
+
echo "❌ Branch $FULL_BRANCH already exists on remote"
|
|
59
|
+
echo "💡 To check it out: git checkout -b $FULL_BRANCH origin/$FULL_BRANCH"
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
53
62
|
|
|
54
|
-
|
|
63
|
+
# Check if base branch exists on remote
|
|
64
|
+
if ! git show-ref --verify --quiet refs/remotes/origin/$BASE_BRANCH; then
|
|
65
|
+
echo "❌ Base branch $BASE_BRANCH does not exist on remote"
|
|
66
|
+
echo "💡 Available branches:"
|
|
67
|
+
git branch -r | grep -v HEAD | sed 's/origin\///' | head -10
|
|
68
|
+
exit 1
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Create and checkout the new branch from the base branch
|
|
72
|
+
echo "🔨 Creating branch $FULL_BRANCH from origin/$BASE_BRANCH..."
|
|
73
|
+
git checkout -b $FULL_BRANCH origin/$BASE_BRANCH
|
|
74
|
+
|
|
75
|
+
# Push the new branch to remote with upstream tracking
|
|
76
|
+
echo "📤 Pushing branch to remote..."
|
|
77
|
+
git push -u origin $FULL_BRANCH
|
|
55
78
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
79
|
+
echo ""
|
|
80
|
+
echo "🎉 Successfully created and checked out $FULL_BRANCH"
|
|
81
|
+
echo ""
|
|
82
|
+
echo "📝 Next steps:"
|
|
83
|
+
echo " 1. Make your changes and commit them"
|
|
84
|
+
echo " 2. Push your changes: git push"
|
|
85
|
+
echo " 3. Create a PR: gh pr create --base $BASE_BRANCH --title \"Your PR title\" --body \"Your PR description\""
|
|
86
|
+
echo " or use: npm run pr:create"
|
|
59
87
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if git show-ref --verify --quiet refs/remotes/origin/$FULL_BRANCH_NAME; then
|
|
68
|
-
echo "✅ Branch $FULL_BRANCH_NAME found! Checking it out..."
|
|
69
|
-
git checkout -b $FULL_BRANCH_NAME origin/$FULL_BRANCH_NAME 2>/dev/null || git checkout $FULL_BRANCH_NAME
|
|
70
|
-
|
|
71
|
-
echo "🎉 Successfully created and switched to $FULL_BRANCH_NAME"
|
|
72
|
-
echo ""
|
|
73
|
-
echo "📝 Next steps:"
|
|
74
|
-
echo " 1. Make your changes and commit them"
|
|
75
|
-
echo " 2. Push your changes: git push"
|
|
76
|
-
echo " 3. Create a PR when ready: npm run pr:create"
|
|
77
|
-
|
|
78
|
-
exit 0
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
if [ $ATTEMPT -eq $MAX_ATTEMPTS ]; then
|
|
82
|
-
echo "❌ Timeout: Branch $FULL_BRANCH_NAME was not created after 1 minute"
|
|
83
|
-
echo "Check the GitHub Actions workflow status:"
|
|
84
|
-
echo " gh run list --workflow=create-feature.yml"
|
|
85
|
-
exit 1
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
echo "Branch not yet available, waiting 5 seconds..."
|
|
89
|
-
sleep 5
|
|
90
|
-
ATTEMPT=$((ATTEMPT + 1))
|
|
91
|
-
done
|
|
88
|
+
# Check if we had stashed changes and auto-apply them
|
|
89
|
+
if git stash list | grep -q "Auto-stash before creating branch $FULL_BRANCH"; then
|
|
90
|
+
echo ""
|
|
91
|
+
echo "Auto-applying stashed changes..."
|
|
92
|
+
git stash pop
|
|
93
|
+
echo "✅ Stashed changes applied"
|
|
94
|
+
fi
|
package/client/utils.gen.js
CHANGED
|
@@ -135,8 +135,22 @@ const getParseAs = (contentType) => {
|
|
|
135
135
|
return;
|
|
136
136
|
};
|
|
137
137
|
exports.getParseAs = getParseAs;
|
|
138
|
+
const checkForExistence = (options, name) => {
|
|
139
|
+
if (!name) {
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
if (options.headers.has(name) ||
|
|
143
|
+
options.query?.[name] ||
|
|
144
|
+
options.headers.get('Cookie')?.includes(`${name}=`)) {
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
};
|
|
138
149
|
const setAuthParams = async ({ security, ...options }) => {
|
|
139
150
|
for (const auth of security) {
|
|
151
|
+
if (checkForExistence(options, auth.name)) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
140
154
|
const token = await (0, auth_gen_1.getAuthToken)(auth, options.auth);
|
|
141
155
|
if (!token) {
|
|
142
156
|
continue;
|
|
@@ -157,7 +171,6 @@ const setAuthParams = async ({ security, ...options }) => {
|
|
|
157
171
|
options.headers.set(name, token);
|
|
158
172
|
break;
|
|
159
173
|
}
|
|
160
|
-
return;
|
|
161
174
|
}
|
|
162
175
|
};
|
|
163
176
|
exports.setAuthParams = setAuthParams;
|
package/client/utils.gen.ts
CHANGED
|
@@ -188,6 +188,25 @@ export const getParseAs = (
|
|
|
188
188
|
return;
|
|
189
189
|
};
|
|
190
190
|
|
|
191
|
+
const checkForExistence = (
|
|
192
|
+
options: Pick<RequestOptions, 'auth' | 'query'> & {
|
|
193
|
+
headers: Headers;
|
|
194
|
+
},
|
|
195
|
+
name?: string,
|
|
196
|
+
): boolean => {
|
|
197
|
+
if (!name) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
if (
|
|
201
|
+
options.headers.has(name) ||
|
|
202
|
+
options.query?.[name] ||
|
|
203
|
+
options.headers.get('Cookie')?.includes(`${name}=`)
|
|
204
|
+
) {
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
return false;
|
|
208
|
+
};
|
|
209
|
+
|
|
191
210
|
export const setAuthParams = async ({
|
|
192
211
|
security,
|
|
193
212
|
...options
|
|
@@ -196,6 +215,10 @@ export const setAuthParams = async ({
|
|
|
196
215
|
headers: Headers;
|
|
197
216
|
}) => {
|
|
198
217
|
for (const auth of security) {
|
|
218
|
+
if (checkForExistence(options, auth.name)) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
|
|
199
222
|
const token = await getAuthToken(auth, options.auth);
|
|
200
223
|
|
|
201
224
|
if (!token) {
|
|
@@ -219,8 +242,6 @@ export const setAuthParams = async ({
|
|
|
219
242
|
options.headers.set(name, token);
|
|
220
243
|
break;
|
|
221
244
|
}
|
|
222
|
-
|
|
223
|
-
return;
|
|
224
245
|
}
|
|
225
246
|
};
|
|
226
247
|
|
|
@@ -6,6 +6,9 @@ const serializeFormDataPair = (data, key, value) => {
|
|
|
6
6
|
if (typeof value === 'string' || value instanceof Blob) {
|
|
7
7
|
data.append(key, value);
|
|
8
8
|
}
|
|
9
|
+
else if (value instanceof Date) {
|
|
10
|
+
data.append(key, value.toISOString());
|
|
11
|
+
}
|
|
9
12
|
else {
|
|
10
13
|
data.append(key, JSON.stringify(value));
|
|
11
14
|
}
|