@gojinko/cli 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/SKILL.md +108 -0
- package/dist/bin/jinko.d.ts +3 -0
- package/dist/bin/jinko.d.ts.map +1 -0
- package/dist/bin/jinko.js +8 -0
- package/dist/bin/jinko.js.map +1 -0
- package/dist/commands/auth/index.d.ts +3 -0
- package/dist/commands/auth/index.d.ts.map +1 -0
- package/dist/commands/auth/index.js +74 -0
- package/dist/commands/auth/index.js.map +1 -0
- package/dist/commands/config/index.d.ts +3 -0
- package/dist/commands/config/index.d.ts.map +1 -0
- package/dist/commands/config/index.js +32 -0
- package/dist/commands/config/index.js.map +1 -0
- package/dist/commands/flights/calendar.d.ts +3 -0
- package/dist/commands/flights/calendar.d.ts.map +1 -0
- package/dist/commands/flights/calendar.js +45 -0
- package/dist/commands/flights/calendar.js.map +1 -0
- package/dist/commands/flights/destinations.d.ts +3 -0
- package/dist/commands/flights/destinations.d.ts.map +1 -0
- package/dist/commands/flights/destinations.js +39 -0
- package/dist/commands/flights/destinations.js.map +1 -0
- package/dist/commands/flights/index.d.ts +3 -0
- package/dist/commands/flights/index.d.ts.map +1 -0
- package/dist/commands/flights/index.js +12 -0
- package/dist/commands/flights/index.js.map +1 -0
- package/dist/commands/flights/search.d.ts +3 -0
- package/dist/commands/flights/search.d.ts.map +1 -0
- package/dist/commands/flights/search.js +61 -0
- package/dist/commands/flights/search.js.map +1 -0
- package/dist/commands/schema.d.ts +3 -0
- package/dist/commands/schema.d.ts.map +1 -0
- package/dist/commands/schema.js +113 -0
- package/dist/commands/schema.js.map +1 -0
- package/dist/commands/shared.d.ts +16 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +45 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/travelers/index.d.ts +3 -0
- package/dist/commands/travelers/index.d.ts.map +1 -0
- package/dist/commands/travelers/index.js +118 -0
- package/dist/commands/travelers/index.js.map +1 -0
- package/dist/commands/trip/add-flight.d.ts +3 -0
- package/dist/commands/trip/add-flight.d.ts.map +1 -0
- package/dist/commands/trip/add-flight.js +22 -0
- package/dist/commands/trip/add-flight.js.map +1 -0
- package/dist/commands/trip/checkout.d.ts +3 -0
- package/dist/commands/trip/checkout.d.ts.map +1 -0
- package/dist/commands/trip/checkout.js +59 -0
- package/dist/commands/trip/checkout.js.map +1 -0
- package/dist/commands/trip/create.d.ts +3 -0
- package/dist/commands/trip/create.d.ts.map +1 -0
- package/dist/commands/trip/create.js +14 -0
- package/dist/commands/trip/create.js.map +1 -0
- package/dist/commands/trip/index.d.ts +3 -0
- package/dist/commands/trip/index.d.ts.map +1 -0
- package/dist/commands/trip/index.js +16 -0
- package/dist/commands/trip/index.js.map +1 -0
- package/dist/commands/trip/remove.d.ts +3 -0
- package/dist/commands/trip/remove.d.ts.map +1 -0
- package/dist/commands/trip/remove.js +19 -0
- package/dist/commands/trip/remove.js.map +1 -0
- package/dist/commands/trip/show.d.ts +3 -0
- package/dist/commands/trip/show.d.ts.map +1 -0
- package/dist/commands/trip/show.js +17 -0
- package/dist/commands/trip/show.js.map +1 -0
- package/dist/commands/trip/travelers.d.ts +3 -0
- package/dist/commands/trip/travelers.d.ts.map +1 -0
- package/dist/commands/trip/travelers.js +37 -0
- package/dist/commands/trip/travelers.js.map +1 -0
- package/dist/config/config.d.ts +12 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +12 -0
- package/dist/config/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/output/formatter.d.ts +19 -0
- package/dist/output/formatter.d.ts.map +1 -0
- package/dist/output/formatter.js +77 -0
- package/dist/output/formatter.js.map +1 -0
- package/package.json +40 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Jinko CLI — Agent Skill Guide
|
|
2
|
+
|
|
3
|
+
You are using `jinko`, a CLI for searching flights, managing trips, and booking travel via the Jinko developer platform.
|
|
4
|
+
|
|
5
|
+
## Authentication
|
|
6
|
+
|
|
7
|
+
Before any command, ensure an API key is configured:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
jinko auth login --key jnk_YOUR_KEY
|
|
11
|
+
# or
|
|
12
|
+
export JINKO_API_KEY=jnk_YOUR_KEY
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Check status: `jinko auth status`
|
|
16
|
+
|
|
17
|
+
## Core Workflow: Search → Price → Book
|
|
18
|
+
|
|
19
|
+
### Step 1: Discover flights (pick one approach)
|
|
20
|
+
|
|
21
|
+
**Search by route:**
|
|
22
|
+
```bash
|
|
23
|
+
jinko flights search --from PAR --to NYC --date 2026-04-01
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Explore destinations:**
|
|
27
|
+
```bash
|
|
28
|
+
jinko flights destinations --from PAR --from CDG
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Browse prices by date:**
|
|
32
|
+
```bash
|
|
33
|
+
jinko flights calendar --from PAR --to NYC --month 2026-04
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
All discovery commands return `offer_token` per flight.
|
|
37
|
+
|
|
38
|
+
### Step 2: Price a specific flight (live pricing)
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
jinko flights search --offer-token <offer_token>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Returns fare options with `trip_item_token` per fare. This hits live pricing (more expensive, more accurate).
|
|
45
|
+
|
|
46
|
+
### Step 3: Book
|
|
47
|
+
|
|
48
|
+
**One-shot booking (recommended):**
|
|
49
|
+
```bash
|
|
50
|
+
jinko trip checkout \
|
|
51
|
+
--trip-item-token <trip_item_token> \
|
|
52
|
+
--travelers '[{"first_name":"John","last_name":"Doe","date_of_birth":"1990-01-15","gender":"MALE","passenger_type":"ADULT"}]' \
|
|
53
|
+
--contact '{"email":"john@example.com","phone":"+33612345678"}'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Returns `checkout_url` — the user opens this in a browser to complete payment.
|
|
57
|
+
|
|
58
|
+
**Step-by-step booking (advanced):**
|
|
59
|
+
```bash
|
|
60
|
+
jinko trip create
|
|
61
|
+
jinko trip add-flight --trip-item-token <token> --trip-id <trip_id>
|
|
62
|
+
jinko trip travelers --trip-id <trip_id> --travelers '[...]' --contact '{...}'
|
|
63
|
+
jinko trip checkout --trip-id <trip_id>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Token Flow
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
flights search (filters) → offer_token (per flight)
|
|
70
|
+
flights search (offer_token) → trip_item_token (per fare)
|
|
71
|
+
trip checkout (trip_item_token + travelers + contact) → checkout_url
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Tool Selection Guide
|
|
75
|
+
|
|
76
|
+
| User Intent | Command |
|
|
77
|
+
|-------------|---------|
|
|
78
|
+
| "Find flights from Paris to New York" | `flights search --from PAR --to NYC --date ...` |
|
|
79
|
+
| "Where can I fly from Paris?" | `flights destinations --from PAR` |
|
|
80
|
+
| "What's the cheapest day to fly?" | `flights calendar --from PAR --to NYC --month ...` |
|
|
81
|
+
| "Get exact price for this flight" | `flights search --offer-token <token>` |
|
|
82
|
+
| "Book this flight" | `trip checkout --trip-item-token <token> --travelers ... --contact ...` |
|
|
83
|
+
| "Show my travelers" | `travelers list` |
|
|
84
|
+
| "Add a traveler" | `travelers add --first-name ... --last-name ... --dob ... --gender ...` |
|
|
85
|
+
|
|
86
|
+
## Output Format
|
|
87
|
+
|
|
88
|
+
All commands output JSON by default (machine-readable). Add `--format table` for human display.
|
|
89
|
+
|
|
90
|
+
## Schema Introspection
|
|
91
|
+
|
|
92
|
+
To see the exact request/response shape for any command:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
jinko schema # List all documented commands
|
|
96
|
+
jinko schema flights.search # Show flights search schema
|
|
97
|
+
jinko schema trip.checkout # Show checkout schema
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Important Notes
|
|
101
|
+
|
|
102
|
+
- **Airport codes**: Use IATA codes (PAR, NYC, JFK, CDG). Multi-city codes expand automatically.
|
|
103
|
+
- **Dates**: Always YYYY-MM-DD format.
|
|
104
|
+
- **Gender**: `MALE` or `FEMALE` (uppercase).
|
|
105
|
+
- **Passenger types**: `ADULT`, `CHILD`, `INFANT`.
|
|
106
|
+
- **Cabin classes**: `economy`, `premium_economy`, `business`, `first`.
|
|
107
|
+
- **Trip type**: Inferred from `--return` flag presence. Include `--return` for round-trip.
|
|
108
|
+
- **Checkout URL**: Opens the Jinko checkout page. User completes payment there.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jinko.d.ts","sourceRoot":"","sources":["../../src/bin/jinko.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createProgram } from '../index.js';
|
|
3
|
+
const program = createProgram();
|
|
4
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
5
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
6
|
+
process.exit(1);
|
|
7
|
+
});
|
|
8
|
+
//# sourceMappingURL=jinko.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jinko.js","sourceRoot":"","sources":["../../src/bin/jinko.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtD,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgF3D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { resolveAuth, writeConfigFile, CONFIG_FILE } from '@gojinko/api-client';
|
|
2
|
+
import { output, outputError } from '../shared.js';
|
|
3
|
+
import { getGlobalOptions } from '../../config/config.js';
|
|
4
|
+
export function registerAuthCommands(program) {
|
|
5
|
+
const auth = program
|
|
6
|
+
.command('auth')
|
|
7
|
+
.description('Manage authentication.');
|
|
8
|
+
auth
|
|
9
|
+
.command('login')
|
|
10
|
+
.description('Configure authentication. Accepts an API key (jnk_...) or OAuth token.')
|
|
11
|
+
.option('--key <token>', 'API key (jnk_...) or OAuth JWT token')
|
|
12
|
+
.action(async (opts, cmd) => {
|
|
13
|
+
const globals = getGlobalOptions(cmd);
|
|
14
|
+
let token = opts['key'];
|
|
15
|
+
if (!token) {
|
|
16
|
+
// Interactive: read from stdin.
|
|
17
|
+
const readline = await import('node:readline');
|
|
18
|
+
const rl = readline.createInterface({
|
|
19
|
+
input: process.stdin,
|
|
20
|
+
output: process.stdout,
|
|
21
|
+
});
|
|
22
|
+
token = await new Promise((resolve) => {
|
|
23
|
+
rl.question('Enter your Jinko API key (jnk_...) or OAuth token: ', (answer) => {
|
|
24
|
+
rl.close();
|
|
25
|
+
resolve(answer.trim());
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (!token) {
|
|
30
|
+
outputError({ code: 'INVALID_TOKEN', message: 'No token provided.' }, globals);
|
|
31
|
+
process.exit(3);
|
|
32
|
+
}
|
|
33
|
+
const isApiKey = token.startsWith('jnk_');
|
|
34
|
+
const configUpdate = isApiKey
|
|
35
|
+
? { api_key: token }
|
|
36
|
+
: { oauth_token: token };
|
|
37
|
+
await writeConfigFile(configUpdate);
|
|
38
|
+
output({
|
|
39
|
+
status: 'ok',
|
|
40
|
+
method: isApiKey ? 'api_key' : 'oauth',
|
|
41
|
+
message: `${isApiKey ? 'API key' : 'OAuth token'} saved to ${CONFIG_FILE}`,
|
|
42
|
+
}, { format: globals.format });
|
|
43
|
+
});
|
|
44
|
+
auth
|
|
45
|
+
.command('status')
|
|
46
|
+
.description('Show current authentication status.')
|
|
47
|
+
.action(async (_opts, cmd) => {
|
|
48
|
+
const globals = getGlobalOptions(cmd);
|
|
49
|
+
const auth = await resolveAuth(globals.apiKey);
|
|
50
|
+
if (!auth) {
|
|
51
|
+
output({
|
|
52
|
+
authenticated: false,
|
|
53
|
+
message: 'No credentials configured. Run `jinko auth login` or set JINKO_API_KEY / JINKO_TOKEN.',
|
|
54
|
+
}, { format: globals.format });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Mask the token for display.
|
|
58
|
+
const masked = auth.token.length > 12
|
|
59
|
+
? auth.token.slice(0, 8) + '...' + auth.token.slice(-4)
|
|
60
|
+
: '***';
|
|
61
|
+
const source = globals.apiKey
|
|
62
|
+
? 'flag'
|
|
63
|
+
: (process.env['JINKO_API_KEY'] || process.env['JINKO_TOKEN'])
|
|
64
|
+
? 'env'
|
|
65
|
+
: 'config';
|
|
66
|
+
output({
|
|
67
|
+
authenticated: true,
|
|
68
|
+
method: auth.method,
|
|
69
|
+
token: masked,
|
|
70
|
+
source,
|
|
71
|
+
}, { format: globals.format });
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,OAAO;SACjB,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,wBAAwB,CAAC,CAAC;IAEzC,IAAI;SACD,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,wEAAwE,CAAC;SACrF,MAAM,CAAC,eAAe,EAAE,sCAAsC,CAAC;SAC/D,MAAM,CAAC,KAAK,EAAE,IAA6B,EAAE,GAAY,EAAE,EAAE;QAC5D,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAuB,CAAC;QAE9C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,gCAAgC;YAChC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;YAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;gBAClC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,CAAC,CAAC;YAEH,KAAK,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;gBAC5C,EAAE,CAAC,QAAQ,CAAC,qDAAqD,EAAE,CAAC,MAAM,EAAE,EAAE;oBAC5E,EAAE,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,WAAW,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,OAAO,CAAC,CAAC;YAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,QAAQ;YAC3B,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;YACpB,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;QAE3B,MAAM,eAAe,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC;YACL,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;YACtC,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,aAAa,WAAW,EAAE;SAC3E,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,qCAAqC,CAAC;SAClD,MAAM,CAAC,KAAK,EAAE,KAA8B,EAAE,GAAY,EAAE,EAAE;QAC7D,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,CAAC;gBACL,aAAa,EAAE,KAAK;gBACpB,OAAO,EAAE,uFAAuF;aACjG,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QAED,8BAA8B;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE;YACnC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvD,CAAC,CAAC,KAAK,CAAC;QAEV,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;YAC3B,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBAC5D,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,QAAQ,CAAC;QAEf,MAAM,CAAC;YACL,aAAa,EAAE,IAAI;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,MAAM;YACb,MAAM;SACP,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+B7D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { writeConfigFile, readConfigFile } from '@gojinko/api-client';
|
|
2
|
+
import { output } from '../shared.js';
|
|
3
|
+
import { getGlobalOptions } from '../../config/config.js';
|
|
4
|
+
const ALLOWED_KEYS = ['base_url', 'api_key'];
|
|
5
|
+
export function registerConfigCommands(program) {
|
|
6
|
+
const config = program
|
|
7
|
+
.command('config')
|
|
8
|
+
.description('Manage CLI configuration.');
|
|
9
|
+
config
|
|
10
|
+
.command('set <key> <value>')
|
|
11
|
+
.description(`Set a config value. Keys: ${ALLOWED_KEYS.join(', ')}`)
|
|
12
|
+
.action(async (key, value, _opts, cmd) => {
|
|
13
|
+
const globals = getGlobalOptions(cmd);
|
|
14
|
+
// Normalize key: base-url → base_url
|
|
15
|
+
const normalizedKey = key.replace(/-/g, '_');
|
|
16
|
+
if (!ALLOWED_KEYS.includes(normalizedKey)) {
|
|
17
|
+
console.error(`Error: unknown config key "${key}". Allowed: ${ALLOWED_KEYS.join(', ')}`);
|
|
18
|
+
process.exit(3);
|
|
19
|
+
}
|
|
20
|
+
await writeConfigFile({ [normalizedKey]: value });
|
|
21
|
+
output({ status: 'ok', key: normalizedKey, value }, { format: globals.format });
|
|
22
|
+
});
|
|
23
|
+
config
|
|
24
|
+
.command('show')
|
|
25
|
+
.description('Show current configuration.')
|
|
26
|
+
.action(async (_opts, cmd) => {
|
|
27
|
+
const globals = getGlobalOptions(cmd);
|
|
28
|
+
const configData = await readConfigFile();
|
|
29
|
+
output(configData ?? {}, { format: globals.format });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,YAAY,GAAG,CAAC,UAAU,EAAE,SAAS,CAAU,CAAC;AAEtD,MAAM,UAAU,sBAAsB,CAAC,OAAgB;IACrD,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,2BAA2B,CAAC,CAAC;IAE5C,MAAM;SACH,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,6BAA6B,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;SACnE,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,KAAa,EAAE,KAA8B,EAAE,GAAY,EAAE,EAAE;QACzF,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QAEtC,qCAAqC;QACrC,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAE7C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,aAA4C,CAAC,EAAE,CAAC;YACzE,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,eAAe,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,eAAe,CAAC,EAAE,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAClD,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,CAAC,CAAC,CAAC;IAEL,MAAM;SACH,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,KAA8B,EAAE,GAAY,EAAE,EAAE;QAC7D,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,MAAM,cAAc,EAAE,CAAC;QAC1C,MAAM,CAAC,UAAU,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","sourceRoot":"","sources":["../../../src/commands/flights/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAgD7D"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { withClient, output } from '../shared.js';
|
|
2
|
+
export function registerCalendarCommand(parent) {
|
|
3
|
+
parent
|
|
4
|
+
.command('calendar')
|
|
5
|
+
.description('Show cheapest prices across a date range for a route. (Coming soon: dedicated endpoint)')
|
|
6
|
+
.requiredOption('--from <origin>', 'origin airport code')
|
|
7
|
+
.requiredOption('--to <destination>', 'destination airport code')
|
|
8
|
+
.option('--month <month>', 'month to display (YYYY-MM), defaults to current month')
|
|
9
|
+
.option('--cabin <class>', 'cabin class', 'economy')
|
|
10
|
+
.option('--direct-only', 'only direct flights')
|
|
11
|
+
.action(withClient(async (client, globals, opts) => {
|
|
12
|
+
// v1: Use search with date range. Dedicated BFF endpoint deferred.
|
|
13
|
+
const month = opts.month ?? new Date().toISOString().slice(0, 7);
|
|
14
|
+
const [year, mon] = month.split('-').map(Number);
|
|
15
|
+
if (!year || !mon) {
|
|
16
|
+
console.error('Error: --month must be in YYYY-MM format.');
|
|
17
|
+
process.exit(3);
|
|
18
|
+
}
|
|
19
|
+
const startDate = `${month}-01`;
|
|
20
|
+
const lastDay = new Date(year, mon, 0).getDate();
|
|
21
|
+
const endDate = `${month}-${String(lastDay).padStart(2, '0')}`;
|
|
22
|
+
const body = {
|
|
23
|
+
origin: opts.from,
|
|
24
|
+
destination: opts.to,
|
|
25
|
+
departure_date: startDate,
|
|
26
|
+
trip_type: 'oneway',
|
|
27
|
+
cabin_class: opts.cabin,
|
|
28
|
+
direct_only: opts.directOnly ?? false,
|
|
29
|
+
sort_by: 'lowest',
|
|
30
|
+
passengers: { adults: 1 },
|
|
31
|
+
};
|
|
32
|
+
// Note: This is a simplified v1. A proper calendar endpoint would
|
|
33
|
+
// return price-per-date. For now, we search the full range.
|
|
34
|
+
const response = await client.raw.POST('/api/v1/devplatform/flights/shop', {
|
|
35
|
+
body,
|
|
36
|
+
});
|
|
37
|
+
const data = response.data;
|
|
38
|
+
if (globals.format === 'table') {
|
|
39
|
+
console.log(`\nFlight calendar: ${opts.from} → ${opts.to} (${month})`);
|
|
40
|
+
console.log(`Date range: ${startDate} to ${endDate}\n`);
|
|
41
|
+
}
|
|
42
|
+
output(data, { format: globals.format });
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../../src/commands/flights/calendar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,UAAU,uBAAuB,CAAC,MAAe;IACrD,MAAM;SACH,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,yFAAyF,CAAC;SACtG,cAAc,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;SACxD,cAAc,CAAC,oBAAoB,EAAE,0BAA0B,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,uDAAuD,CAAC;SAClF,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,CAAC;SACnD,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC;SAC9C,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACjD,mEAAmE;QACnE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,SAAS,GAAG,GAAG,KAAK,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QACjD,MAAM,OAAO,GAAG,GAAG,KAAK,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QAE/D,MAAM,IAAI,GAA4B;YACpC,MAAM,EAAE,IAAI,CAAC,IAAI;YACjB,WAAW,EAAE,IAAI,CAAC,EAAE;YACpB,cAAc,EAAE,SAAS;YACzB,SAAS,EAAE,QAAQ;YACnB,WAAW,EAAE,IAAI,CAAC,KAAK;YACvB,WAAW,EAAE,IAAI,CAAC,UAAU,IAAI,KAAK;YACrC,OAAO,EAAE,QAAQ;YACjB,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;SAC1B,CAAC;QAEF,kEAAkE;QAClE,4DAA4D;QAC5D,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,kCAA2C,EAAE;YAClF,IAAI;SACI,CAAC,CAAC;QAEZ,MAAM,IAAI,GAAI,QAA+B,CAAC,IAAI,CAAC;QAEnD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,KAAK,KAAK,GAAG,CAAC,CAAC;YACvE,OAAO,CAAC,GAAG,CAAC,eAAe,SAAS,OAAO,OAAO,IAAI,CAAC,CAAC;QAC1D,CAAC;QAED,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destinations.d.ts","sourceRoot":"","sources":["../../../src/commands/flights/destinations.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAwCjE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { withClient, output } from '../shared.js';
|
|
2
|
+
export function registerDestinationsCommand(parent) {
|
|
3
|
+
parent
|
|
4
|
+
.command('destinations')
|
|
5
|
+
.description('Discover destinations from one or more origins.')
|
|
6
|
+
.requiredOption('--from <origins...>', 'origin airport code(s) (e.g. PAR or PAR CDG)')
|
|
7
|
+
.option('--date <date>', 'departure date (YYYY-MM-DD)')
|
|
8
|
+
.option('--return <date>', 'return date (YYYY-MM-DD)')
|
|
9
|
+
.option('--direct-only', 'only direct flights')
|
|
10
|
+
.option('--cabin <class>', 'cabin class', 'economy')
|
|
11
|
+
.option('--max-price <amount>', 'maximum price filter')
|
|
12
|
+
.option('--sort <sort>', 'sort: price, destination', 'price')
|
|
13
|
+
.option('--limit <n>', 'max destinations', '20')
|
|
14
|
+
.action(withClient(async (client, globals, opts) => {
|
|
15
|
+
const origins = Array.isArray(opts.from) ? opts.from : [opts.from];
|
|
16
|
+
const body = {
|
|
17
|
+
passengers: { adults: 1 },
|
|
18
|
+
filters: {
|
|
19
|
+
locations: {
|
|
20
|
+
origins: origins.map((o) => ({ code: o })),
|
|
21
|
+
},
|
|
22
|
+
trip_type: opts.return ? 'roundtrip' : 'oneway',
|
|
23
|
+
},
|
|
24
|
+
flights_per_destination: 1,
|
|
25
|
+
limit: Number(opts.limit) || 20,
|
|
26
|
+
};
|
|
27
|
+
if (opts.date) {
|
|
28
|
+
body['filters']['dates'] = {
|
|
29
|
+
departure: opts.date,
|
|
30
|
+
...(opts.return ? { return: opts.return } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const response = await client.raw.POST('/api/v1/flights/destination-search', {
|
|
34
|
+
body,
|
|
35
|
+
});
|
|
36
|
+
output(response.data, { format: globals.format });
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=destinations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"destinations.js","sourceRoot":"","sources":["../../../src/commands/flights/destinations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAElD,MAAM,UAAU,2BAA2B,CAAC,MAAe;IACzD,MAAM;SACH,OAAO,CAAC,cAAc,CAAC;SACvB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,cAAc,CAAC,qBAAqB,EAAE,8CAA8C,CAAC;SACrF,MAAM,CAAC,eAAe,EAAE,6BAA6B,CAAC;SACtD,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACrD,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC;SAC9C,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,CAAC;SACnD,MAAM,CAAC,sBAAsB,EAAE,sBAAsB,CAAC;SACtD,MAAM,CAAC,eAAe,EAAE,0BAA0B,EAAE,OAAO,CAAC;SAC5D,MAAM,CAAC,aAAa,EAAE,kBAAkB,EAAE,IAAI,CAAC;SAC/C,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACjD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnE,MAAM,IAAI,GAA4B;YACpC,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;YACzB,OAAO,EAAE;gBACP,SAAS,EAAE;oBACT,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;iBACnD;gBACD,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ;aAChD;YACD,uBAAuB,EAAE,CAAC;YAC1B,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;SAChC,CAAC;QAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,CAA6B,CAAC,OAAO,CAAC,GAAG;gBACtD,SAAS,EAAE,IAAI,CAAC,IAAI;gBACpB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChD,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,oCAA6C,EAAE;YACpF,IAAI;SACI,CAAC,CAAC;QAEZ,MAAM,CAAE,QAA+B,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC,CAAC;AACR,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/flights/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAQ9D"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { registerSearchCommand } from './search.js';
|
|
2
|
+
import { registerDestinationsCommand } from './destinations.js';
|
|
3
|
+
import { registerCalendarCommand } from './calendar.js';
|
|
4
|
+
export function registerFlightsCommands(program) {
|
|
5
|
+
const flights = program
|
|
6
|
+
.command('flights')
|
|
7
|
+
.description('Search flights, explore destinations, and check prices.');
|
|
8
|
+
registerSearchCommand(flights);
|
|
9
|
+
registerDestinationsCommand(flights);
|
|
10
|
+
registerCalendarCommand(flights);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/flights/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,MAAM,OAAO,GAAG,OAAO;SACpB,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,yDAAyD,CAAC,CAAC;IAE1E,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACrC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/commands/flights/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA6D3D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { withClient, output } from '../shared.js';
|
|
2
|
+
export function registerSearchCommand(parent) {
|
|
3
|
+
parent
|
|
4
|
+
.command('search')
|
|
5
|
+
.description('Search flights or price-check a specific offer.')
|
|
6
|
+
.option('--from <origin>', 'origin airport code (e.g. PAR)')
|
|
7
|
+
.option('--to <destination>', 'destination airport code (e.g. NYC)')
|
|
8
|
+
.option('--date <date>', 'departure date (YYYY-MM-DD)')
|
|
9
|
+
.option('--return <date>', 'return date for round-trip (YYYY-MM-DD)')
|
|
10
|
+
.option('--passengers <n>', 'number of passengers', '1')
|
|
11
|
+
.option('--cabin <class>', 'cabin class: economy, premium_economy, business, first', 'economy')
|
|
12
|
+
.option('--direct-only', 'only show direct flights')
|
|
13
|
+
.option('--max-price <amount>', 'maximum price filter')
|
|
14
|
+
.option('--sort <sort>', 'sort: lowest, recommendation', 'lowest')
|
|
15
|
+
.option('--offer-token <token>', 'price-check a specific offer (live pricing)')
|
|
16
|
+
.option('--limit <n>', 'max results', '10')
|
|
17
|
+
.action(withClient(async (client, globals, opts) => {
|
|
18
|
+
const isOfferCheck = Boolean(opts.offerToken);
|
|
19
|
+
if (isOfferCheck) {
|
|
20
|
+
// Mode B: Price check via devplatform/flights/shop
|
|
21
|
+
const response = await client.raw.POST('/api/v1/devplatform/flights/shop', {
|
|
22
|
+
body: {
|
|
23
|
+
offer_token: opts.offerToken,
|
|
24
|
+
passengers: {
|
|
25
|
+
adults: Number(opts.passengers) || 1,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
output(response.data, { format: globals.format });
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Mode A: Search via devplatform/flights/shop
|
|
33
|
+
if (!opts.from || !opts.to || !opts.date) {
|
|
34
|
+
console.error('Error: --from, --to, and --date are required for search mode.');
|
|
35
|
+
console.error(' Or provide --offer-token for price-check mode.');
|
|
36
|
+
process.exit(3);
|
|
37
|
+
}
|
|
38
|
+
const body = {
|
|
39
|
+
origin: opts.from,
|
|
40
|
+
destination: opts.to,
|
|
41
|
+
departure_date: opts.date,
|
|
42
|
+
trip_type: opts.return ? 'roundtrip' : 'oneway',
|
|
43
|
+
cabin_class: opts.cabin,
|
|
44
|
+
direct_only: opts.directOnly ?? false,
|
|
45
|
+
sort_by: opts.sort,
|
|
46
|
+
passengers: {
|
|
47
|
+
adults: Number(opts.passengers) || 1,
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
if (opts.return)
|
|
51
|
+
body['return_date'] = opts.return;
|
|
52
|
+
if (opts.maxPrice)
|
|
53
|
+
body['max_price'] = Number(opts.maxPrice);
|
|
54
|
+
const response = await client.raw.POST('/api/v1/devplatform/flights/shop', {
|
|
55
|
+
body,
|
|
56
|
+
});
|
|
57
|
+
output(response.data, { format: globals.format });
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/commands/flights/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2FpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0B5D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { output } from './shared.js';
|
|
2
|
+
import { getGlobalOptions } from '../config/config.js';
|
|
3
|
+
/**
|
|
4
|
+
* Schema definitions for CLI commands. These describe the expected
|
|
5
|
+
* request/response shapes for agent consumption.
|
|
6
|
+
*/
|
|
7
|
+
const SCHEMAS = {
|
|
8
|
+
'flights.search': {
|
|
9
|
+
description: 'Search flights (Mode A) or price-check an offer (Mode B).',
|
|
10
|
+
request: {
|
|
11
|
+
mode_a_search: {
|
|
12
|
+
origin: 'string (IATA code, e.g. PAR)',
|
|
13
|
+
destination: 'string (IATA code, e.g. NYC)',
|
|
14
|
+
departure_date: 'string (YYYY-MM-DD)',
|
|
15
|
+
return_date: 'string? (YYYY-MM-DD, for roundtrip)',
|
|
16
|
+
trip_type: 'oneway | roundtrip',
|
|
17
|
+
cabin_class: 'economy | premium_economy | business | first',
|
|
18
|
+
direct_only: 'boolean?',
|
|
19
|
+
max_price: 'number?',
|
|
20
|
+
passengers: '{ adults: number, children?: number, infants?: number }',
|
|
21
|
+
},
|
|
22
|
+
mode_b_price_check: {
|
|
23
|
+
offer_token: 'string (from search results)',
|
|
24
|
+
passengers: '{ adults: number, children?: number, infants?: number }',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
response: {
|
|
28
|
+
mode: 'search | price_check',
|
|
29
|
+
flights: '[{ offer_token, airline, departure, arrival, duration, stops, price, currency, ... }]',
|
|
30
|
+
fares: '(mode B only) [{ trip_item_token, cabin_class, baggage, refundable, price }]',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
'flights.destinations': {
|
|
34
|
+
description: 'Discover destinations from origin airports.',
|
|
35
|
+
request: {
|
|
36
|
+
origins: 'string[] (IATA codes)',
|
|
37
|
+
departure_date: 'string? (YYYY-MM-DD)',
|
|
38
|
+
return_date: 'string? (YYYY-MM-DD)',
|
|
39
|
+
direct_only: 'boolean?',
|
|
40
|
+
cabin_class: 'string?',
|
|
41
|
+
max_price: 'number?',
|
|
42
|
+
},
|
|
43
|
+
response: {
|
|
44
|
+
destinations: '[{ city, country, airport_code, cheapest_price, currency, offer_token }]',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
'flights.calendar': {
|
|
48
|
+
description: 'Show cheapest prices across a date range.',
|
|
49
|
+
request: {
|
|
50
|
+
origin: 'string (IATA code)',
|
|
51
|
+
destination: 'string (IATA code)',
|
|
52
|
+
month: 'string (YYYY-MM)',
|
|
53
|
+
cabin_class: 'string?',
|
|
54
|
+
direct_only: 'boolean?',
|
|
55
|
+
},
|
|
56
|
+
response: {
|
|
57
|
+
dates: '[{ date, price, currency, offer_token }]',
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
'trip.checkout': {
|
|
61
|
+
description: 'One-shot booking: send trip_item_token + travelers + contact, get checkout URL.',
|
|
62
|
+
request: {
|
|
63
|
+
trip_item_token: 'string (from flights search price-check)',
|
|
64
|
+
travelers: '[{ first_name, last_name, date_of_birth, gender, passenger_type, nationality?, passport_number?, passport_expiry?, passport_country? }]',
|
|
65
|
+
contact: '{ email: string, phone: string }',
|
|
66
|
+
},
|
|
67
|
+
response: {
|
|
68
|
+
checkout_url: 'string (https://app.gojinko.com/checkout?sid=XXX)',
|
|
69
|
+
session_id: 'string',
|
|
70
|
+
trip_id: 'string',
|
|
71
|
+
status: 'ready | error',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
'trip.travelers': {
|
|
75
|
+
description: 'Set travelers on a trip (inline, via devplatform/trips).',
|
|
76
|
+
request: {
|
|
77
|
+
trip_id: 'string',
|
|
78
|
+
travelers: '[{ first_name, last_name, date_of_birth, gender, passenger_type, nationality?, passport_number?, passport_expiry?, passport_country? }]',
|
|
79
|
+
contact: '{ email: string, phone: string }',
|
|
80
|
+
},
|
|
81
|
+
response: {
|
|
82
|
+
trip_id: 'string',
|
|
83
|
+
status: 'string',
|
|
84
|
+
travelers: '[...]',
|
|
85
|
+
actions_performed: 'string[]',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
export function registerSchemaCommand(program) {
|
|
90
|
+
program
|
|
91
|
+
.command('schema [command]')
|
|
92
|
+
.description('Show request/response schema for a command. List all if no command given.')
|
|
93
|
+
.action((commandName, _opts, cmd) => {
|
|
94
|
+
const globals = getGlobalOptions(cmd);
|
|
95
|
+
if (!commandName) {
|
|
96
|
+
// List all available schemas.
|
|
97
|
+
const list = Object.entries(SCHEMAS).map(([name, schema]) => ({
|
|
98
|
+
command: name,
|
|
99
|
+
description: schema.description,
|
|
100
|
+
}));
|
|
101
|
+
output(list, { format: globals.format });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const schema = SCHEMAS[commandName];
|
|
105
|
+
if (!schema) {
|
|
106
|
+
const available = Object.keys(SCHEMAS).join(', ');
|
|
107
|
+
console.error(`Unknown command: ${commandName}. Available: ${available}`);
|
|
108
|
+
process.exit(3);
|
|
109
|
+
}
|
|
110
|
+
output({ command: commandName, ...schema }, { format: globals.format });
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/commands/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
import { type JinkoClient } from '@gojinko/api-client';
|
|
3
|
+
import { type GlobalOptions } from '../config/config.js';
|
|
4
|
+
import { output, outputError } from '../output/formatter.js';
|
|
5
|
+
export { output, outputError };
|
|
6
|
+
export type { GlobalOptions };
|
|
7
|
+
/**
|
|
8
|
+
* Wraps a command handler with standard error handling and client creation.
|
|
9
|
+
* Commander calls action with varying arg counts:
|
|
10
|
+
* command('foo') → action(opts, cmd)
|
|
11
|
+
* command('foo <arg>') → action(arg, opts, cmd)
|
|
12
|
+
* command('foo <a> <b>') → action(a, b, opts, cmd)
|
|
13
|
+
* We always extract the last arg as Command and second-to-last as opts.
|
|
14
|
+
*/
|
|
15
|
+
export declare function withClient(handler: (client: JinkoClient, globals: GlobalOptions, cmdOpts?: any, cmd?: Command) => Promise<void>): (this: Command, ...args: any[]) => Promise<void>;
|
|
16
|
+
//# sourceMappingURL=shared.d.ts.map
|