@unstoppabledomains/ud-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/README.md +344 -0
- package/dist/commands/api-commands.d.ts +9 -0
- package/dist/commands/api-commands.d.ts.map +1 -0
- package/dist/commands/api-commands.js +303 -0
- package/dist/commands/api-commands.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +97 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/cart.d.ts +10 -0
- package/dist/commands/cart.d.ts.map +1 -0
- package/dist/commands/cart.js +125 -0
- package/dist/commands/cart.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +90 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/env.d.ts +3 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +29 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/generated/openapi-spec.json +5903 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +7 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +162 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/command-hooks.d.ts +49 -0
- package/dist/lib/command-hooks.d.ts.map +1 -0
- package/dist/lib/command-hooks.js +150 -0
- package/dist/lib/command-hooks.js.map +1 -0
- package/dist/lib/command-registry.d.ts +30 -0
- package/dist/lib/command-registry.d.ts.map +1 -0
- package/dist/lib/command-registry.js +322 -0
- package/dist/lib/command-registry.js.map +1 -0
- package/dist/lib/config.d.ts +19 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +95 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/credentials.d.ts +16 -0
- package/dist/lib/credentials.d.ts.map +1 -0
- package/dist/lib/credentials.js +126 -0
- package/dist/lib/credentials.js.map +1 -0
- package/dist/lib/formatter.d.ts +34 -0
- package/dist/lib/formatter.d.ts.map +1 -0
- package/dist/lib/formatter.js +691 -0
- package/dist/lib/formatter.js.map +1 -0
- package/dist/lib/oauth.d.ts +8 -0
- package/dist/lib/oauth.d.ts.map +1 -0
- package/dist/lib/oauth.js +212 -0
- package/dist/lib/oauth.js.map +1 -0
- package/dist/lib/param-builder.d.ts +28 -0
- package/dist/lib/param-builder.d.ts.map +1 -0
- package/dist/lib/param-builder.js +178 -0
- package/dist/lib/param-builder.js.map +1 -0
- package/dist/lib/prompt.d.ts +17 -0
- package/dist/lib/prompt.d.ts.map +1 -0
- package/dist/lib/prompt.js +53 -0
- package/dist/lib/prompt.js.map +1 -0
- package/dist/lib/spec-parser.d.ts +76 -0
- package/dist/lib/spec-parser.d.ts.map +1 -0
- package/dist/lib/spec-parser.js +201 -0
- package/dist/lib/spec-parser.js.map +1 -0
- package/dist/lib/spinner.d.ts +16 -0
- package/dist/lib/spinner.d.ts.map +1 -0
- package/dist/lib/spinner.js +23 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/types.d.ts +63 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +11 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/program.d.ts +3 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +47 -0
- package/dist/program.js.map +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# ud-cli
|
|
2
|
+
|
|
3
|
+
CLI tool for managing Unstoppable Domains — domain portfolio, DNS records, marketplace listings, and more.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Authenticate (opens browser for OAuth)
|
|
12
|
+
npx tsx src/index.ts auth login
|
|
13
|
+
|
|
14
|
+
# Check auth status
|
|
15
|
+
npx tsx src/index.ts auth whoami
|
|
16
|
+
|
|
17
|
+
# Search for domains
|
|
18
|
+
npx tsx src/index.ts domains search mybusiness
|
|
19
|
+
|
|
20
|
+
# List your portfolio
|
|
21
|
+
npx tsx src/index.ts domains list
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Authentication
|
|
25
|
+
|
|
26
|
+
### OAuth (default, browser-based)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
ud auth login
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Opens a browser for authorization using OAuth 2.0 with PKCE. Tokens are automatically refreshed.
|
|
33
|
+
|
|
34
|
+
### API Key
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ud auth login --key ud_mcp_<64-hex-chars>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
API keys have the format `ud_mcp_` followed by 64 hex characters. Generate one from the Unstoppable Domains dashboard. Passing `--key` automatically selects the api-key method.
|
|
41
|
+
|
|
42
|
+
### Managing credentials
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
ud auth whoami # Check current auth status
|
|
46
|
+
ud auth logout # Clear stored credentials
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Global Options
|
|
50
|
+
|
|
51
|
+
| Option | Description |
|
|
52
|
+
|--------|-------------|
|
|
53
|
+
| `--env <environment>` | Override active environment (`production` or `staging`) |
|
|
54
|
+
| `--format <format>` | Output format: `table` (default), `json`, or `csv` |
|
|
55
|
+
| `--fields [columns]` | Show available fields, or specify columns to display |
|
|
56
|
+
| `--quiet` | Suppress output except errors |
|
|
57
|
+
| `--verbose` | Show detailed output |
|
|
58
|
+
| `--profile <name>` | Configuration profile to use (reserved) |
|
|
59
|
+
|
|
60
|
+
### Output Formats
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Table output (default) — human-readable
|
|
64
|
+
ud domains search mybusiness
|
|
65
|
+
|
|
66
|
+
# JSON output — for scripting and piping
|
|
67
|
+
ud domains search mybusiness --format json
|
|
68
|
+
|
|
69
|
+
# CSV output — for spreadsheets and data processing
|
|
70
|
+
ud domains tlds --format csv > tlds.csv
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Field Selection
|
|
74
|
+
|
|
75
|
+
Use `--fields` to customize which columns are displayed in table output.
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Show available fields for a command
|
|
79
|
+
ud domains list --fields
|
|
80
|
+
|
|
81
|
+
# Select specific columns
|
|
82
|
+
ud domains list --fields name,expiresAt,offersCount
|
|
83
|
+
|
|
84
|
+
# Nested fields use dot notation
|
|
85
|
+
ud domains list --fields name,listing.price,autoRenewal.status
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Invalid field names are rejected with an error and a hint to run `--fields` for the full list.
|
|
89
|
+
|
|
90
|
+
## Command Reference
|
|
91
|
+
|
|
92
|
+
### Domains
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
ud domains search <query> Search for available domains
|
|
96
|
+
ud domains tlds List available TLDs
|
|
97
|
+
ud domains list List portfolio domains
|
|
98
|
+
ud domains get <domains...> Get detailed domain info
|
|
99
|
+
ud domains push <domains...> Push domains to another user
|
|
100
|
+
ud domains operations <domains...> Get pending operations
|
|
101
|
+
ud domains tags add <domains...> Add tags to domains
|
|
102
|
+
ud domains tags remove <domains...> Remove tags from domains
|
|
103
|
+
ud domains flags update <domains...> Update domain flags
|
|
104
|
+
ud domains auto-renewal update <domains...> Toggle auto-renewal
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### DNS
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
ud dns records list <domain> List DNS records
|
|
111
|
+
ud dns records add <domain> Add DNS records
|
|
112
|
+
ud dns records update Update DNS records
|
|
113
|
+
ud dns records remove Remove DNS records
|
|
114
|
+
ud dns records remove-all <domains...> Remove all DNS records
|
|
115
|
+
ud dns nameservers list <domain> List nameservers
|
|
116
|
+
ud dns nameservers set-custom Set custom nameservers
|
|
117
|
+
ud dns nameservers set-default Reset to default nameservers
|
|
118
|
+
ud dns hosting list <domain> List hosting configurations
|
|
119
|
+
ud dns hosting add Add hosting configuration
|
|
120
|
+
ud dns hosting remove Remove hosting configuration
|
|
121
|
+
ud dns hosting lander generate <domains...> Generate AI landing page
|
|
122
|
+
ud dns hosting lander status <domains...> Check lander generation status
|
|
123
|
+
ud dns hosting lander remove <domains...> Remove AI landing page
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Cart
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
ud cart get Get shopping cart with pricing
|
|
130
|
+
ud cart remove Remove items from cart
|
|
131
|
+
ud cart checkout Complete cart checkout (requires --confirm)
|
|
132
|
+
ud cart url Get checkout URL
|
|
133
|
+
ud cart payment-methods Get available payment methods
|
|
134
|
+
ud cart add-payment-method Get URL to add payment method
|
|
135
|
+
ud cart add [domain...] Smart add — auto-detects source and routes
|
|
136
|
+
ud cart add registration <domains...> Add domains for registration
|
|
137
|
+
ud cart add listed <domains...> Add marketplace-listed domains
|
|
138
|
+
ud cart add afternic <domains...> Add Afternic marketplace domains
|
|
139
|
+
ud cart add sedo <domains...> Add Sedo marketplace domains
|
|
140
|
+
ud cart add renewal <domains...> Add domain renewals
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Contacts
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
ud contacts list List ICANN contacts
|
|
147
|
+
ud contacts create Create ICANN contact
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Listings
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
ud listings create <domains...> Create marketplace listings
|
|
154
|
+
ud listings create <domains...> --price 99.99 Set listing price in dollars
|
|
155
|
+
ud listings update Update marketplace listings
|
|
156
|
+
ud listings update --price 50.00 Update listing price in dollars
|
|
157
|
+
ud listings cancel Cancel marketplace listings (requires --confirm)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Offers
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
ud offers list List marketplace offers
|
|
164
|
+
ud offers respond Respond to marketplace offers
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Leads
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
ud leads list List domain conversation leads
|
|
171
|
+
ud leads get <domain> Get or create domain conversation
|
|
172
|
+
ud leads messages List messages in a conversation
|
|
173
|
+
ud leads send Send a message in a conversation
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Config
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
ud config set <command> <key> <value> Save a default option for a command
|
|
180
|
+
ud config get [command] Show saved defaults
|
|
181
|
+
ud config reset <command> [key] Remove saved defaults
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Per-command defaults let you persist `--fields`, `--format`, and `--quiet` preferences so you don't have to retype them. CLI flags always override saved defaults.
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Save default fields for domains list
|
|
188
|
+
ud config set "domains list" fields name,expiresAt,offersCount
|
|
189
|
+
|
|
190
|
+
# Now ud domains list automatically uses those fields
|
|
191
|
+
ud domains list
|
|
192
|
+
|
|
193
|
+
# CLI flags still override the saved default
|
|
194
|
+
ud domains list --fields name,expiresAt
|
|
195
|
+
|
|
196
|
+
# Save a default output format
|
|
197
|
+
ud config set "dns records list" format json
|
|
198
|
+
|
|
199
|
+
# View all saved defaults
|
|
200
|
+
ud config get
|
|
201
|
+
|
|
202
|
+
# Remove a specific default
|
|
203
|
+
ud config reset "domains list" fields
|
|
204
|
+
|
|
205
|
+
# Remove all defaults for a command
|
|
206
|
+
ud config reset "domains list"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
When you pass `--fields` explicitly, the CLI shows a tip with the command to save those fields as default.
|
|
210
|
+
|
|
211
|
+
## Usage Examples
|
|
212
|
+
|
|
213
|
+
### Search and register domains
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Search for domains
|
|
217
|
+
ud domains search mybusiness --tlds com,org,io --limit 10
|
|
218
|
+
|
|
219
|
+
# Smart cart add — auto-detects the source type
|
|
220
|
+
ud cart add mybusiness.com mybusiness.io
|
|
221
|
+
|
|
222
|
+
# Or specify the type explicitly
|
|
223
|
+
ud cart add registration mybusiness.com mybusiness.io
|
|
224
|
+
ud cart add --type renewal mysite.com
|
|
225
|
+
|
|
226
|
+
# Review cart and checkout
|
|
227
|
+
ud cart get
|
|
228
|
+
ud cart checkout --confirm
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Manage DNS records
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# List current records
|
|
235
|
+
ud dns records list example.com --format json
|
|
236
|
+
|
|
237
|
+
# Add an A record (single-item shorthand)
|
|
238
|
+
ud dns records add example.com --type A --values 1.2.3.4
|
|
239
|
+
|
|
240
|
+
# Bulk operations with --data
|
|
241
|
+
ud dns records add example.com --data '{
|
|
242
|
+
"records": [
|
|
243
|
+
{"domain": "example.com", "type": "A", "values": ["1.2.3.4"]},
|
|
244
|
+
{"domain": "example.com", "type": "CNAME", "subName": "www", "values": ["example.com"]}
|
|
245
|
+
]
|
|
246
|
+
}'
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Marketplace listings
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# List a domain for sale at $99.99
|
|
253
|
+
ud listings create mydomain.com --price 99.99
|
|
254
|
+
|
|
255
|
+
# Update listing price
|
|
256
|
+
ud listings update --price 50.00 --data '{"listings":[{"listingId":"l123"}]}'
|
|
257
|
+
|
|
258
|
+
# Cancel a listing
|
|
259
|
+
ud listings cancel --confirm --data '{"listingIds":["l123"]}'
|
|
260
|
+
|
|
261
|
+
# View and respond to offers
|
|
262
|
+
ud offers list
|
|
263
|
+
ud offers respond --data '{"offers":[{"offerId":"o123","action":"accept"}]}'
|
|
264
|
+
|
|
265
|
+
# Manage leads
|
|
266
|
+
ud leads list
|
|
267
|
+
ud leads get mydomain.com
|
|
268
|
+
ud leads messages --conversation-id 42
|
|
269
|
+
ud leads send --conversation-id 42 --content "Thanks for your interest!"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Advanced usage
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
# Use --data for complex request bodies
|
|
276
|
+
ud contacts create --data '{
|
|
277
|
+
"firstName": "Jane",
|
|
278
|
+
"lastName": "Doe",
|
|
279
|
+
"email": "jane@example.com",
|
|
280
|
+
"phone": {"dialingPrefix": "+1", "number": "5551234567"},
|
|
281
|
+
"street": "123 Main St",
|
|
282
|
+
"city": "Austin",
|
|
283
|
+
"stateProvince": "TX",
|
|
284
|
+
"postalCode": "78701",
|
|
285
|
+
"countryCode": "US"
|
|
286
|
+
}'
|
|
287
|
+
|
|
288
|
+
# Read request body from a file
|
|
289
|
+
ud dns records add example.com --file records.json
|
|
290
|
+
|
|
291
|
+
# Pipe JSON output for scripting
|
|
292
|
+
ud domains list --format json | jq '.domains[].name'
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Environments
|
|
296
|
+
|
|
297
|
+
| Environment | Base URL |
|
|
298
|
+
|-------------|----------|
|
|
299
|
+
| `production` (default) | `https://api.unstoppabledomains.com` |
|
|
300
|
+
| `staging` | `https://api.ud-staging.com` |
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
ud env show # Show current environment
|
|
304
|
+
ud env set staging # Switch default environment
|
|
305
|
+
ud --env staging <cmd> # Override environment for a single command
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Credentials are stored per-environment, so you can be authenticated to both simultaneously.
|
|
309
|
+
|
|
310
|
+
## Development
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
npm run build # Compile TypeScript to dist/
|
|
314
|
+
npm run typecheck # Type-check without emitting
|
|
315
|
+
npm run lint # Run ESLint
|
|
316
|
+
npm run format # Format with Prettier
|
|
317
|
+
npm test # Run tests
|
|
318
|
+
npm run dev -- --help # Run CLI in development mode
|
|
319
|
+
npm run fetch-spec # Re-download OpenAPI spec from production API
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Updating the API Spec
|
|
323
|
+
|
|
324
|
+
The CLI commands are auto-generated from the OpenAPI spec at `src/generated/openapi-spec.json`. To update after API changes:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
npm run fetch-spec # Downloads latest spec
|
|
328
|
+
npm test # Verify everything still works
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Building Binaries
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
npm run bundle # Bundle into single file (dist/ud-cli.cjs)
|
|
335
|
+
npm run build:binaries # Create standalone executables in bin/
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Binary targets: macOS (arm64, x64), Linux (x64), Windows (x64).
|
|
339
|
+
|
|
340
|
+
## Credential Storage
|
|
341
|
+
|
|
342
|
+
Credentials are stored securely:
|
|
343
|
+
- **Primary:** System keychain via `keytar` (macOS Keychain, Windows Credential Vault, Linux Secret Service)
|
|
344
|
+
- **Fallback:** Plaintext JSON file at `~/.ud-cli/credentials-{env}.json` with permissions `0600` when native keychain is unavailable
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamically registers CLI commands from the OpenAPI spec + command registry.
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
/**
|
|
6
|
+
* Register all API commands on the given Commander program.
|
|
7
|
+
*/
|
|
8
|
+
export declare function registerApiCommands(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=api-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-commands.d.ts","sourceRoot":"","sources":["../../src/commands/api-commands.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4DpC;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAsB1D"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamically registers CLI commands from the OpenAPI spec + command registry.
|
|
3
|
+
*/
|
|
4
|
+
import { parseSpec } from '../lib/spec-parser.js';
|
|
5
|
+
import { COMMAND_ROUTES } from '../lib/command-registry.js';
|
|
6
|
+
import { buildParams, specParamToOption } from '../lib/param-builder.js';
|
|
7
|
+
import { callAction } from '../lib/api.js';
|
|
8
|
+
import { getCommandDefaults } from '../lib/config.js';
|
|
9
|
+
import { formatOutput, formatError, formatFieldsList, getKnownFields } from '../lib/formatter.js';
|
|
10
|
+
import { createSpinner } from '../lib/spinner.js';
|
|
11
|
+
import { getHooks, formatOperationHint, formatCartHint } from '../lib/command-hooks.js';
|
|
12
|
+
import { promptInput, promptConfirm } from '../lib/prompt.js';
|
|
13
|
+
import { readFile } from 'node:fs/promises';
|
|
14
|
+
import chalk from 'chalk';
|
|
15
|
+
/**
|
|
16
|
+
* Human-readable descriptions for command groups and subgroups.
|
|
17
|
+
* Keys are the full command path (e.g., 'dns.hosting.lander').
|
|
18
|
+
*/
|
|
19
|
+
const GROUP_DESCRIPTIONS = {
|
|
20
|
+
// Top-level groups
|
|
21
|
+
domains: 'Search, register, and manage your domains',
|
|
22
|
+
dns: 'Manage DNS records, nameservers, and hosting',
|
|
23
|
+
cart: 'Manage your shopping cart and checkout',
|
|
24
|
+
contacts: 'Manage WHOIS contacts',
|
|
25
|
+
listings: 'Create and manage marketplace listings',
|
|
26
|
+
offers: 'View and respond to domain offers',
|
|
27
|
+
leads: 'Manage domain leads and messages',
|
|
28
|
+
// Subgroups
|
|
29
|
+
'domains.tags': 'Add or remove domain tags',
|
|
30
|
+
'domains.flags': 'Update domain flags (WHOIS privacy, transfer lock, etc.)',
|
|
31
|
+
'domains.auto-renewal': 'Manage domain auto-renewal settings',
|
|
32
|
+
'dns.records': 'List, add, update, and remove DNS records',
|
|
33
|
+
'dns.nameservers': 'View and configure nameservers',
|
|
34
|
+
'dns.hosting': 'Manage hosting configurations and AI landers',
|
|
35
|
+
'dns.hosting.lander': 'Generate, check, and remove AI landing pages',
|
|
36
|
+
'cart.add': 'Add domains to your cart',
|
|
37
|
+
};
|
|
38
|
+
function getRootOpts(cmd) {
|
|
39
|
+
let current = cmd;
|
|
40
|
+
while (current.parent)
|
|
41
|
+
current = current.parent;
|
|
42
|
+
return current.opts();
|
|
43
|
+
}
|
|
44
|
+
// Spec JSON is inlined by esbuild in bundled mode (via .json loader), loaded from disk in dev mode.
|
|
45
|
+
// Note: `with { type: 'json' }` import attributes require Node.js 21+ or tsx for unbundled dev.
|
|
46
|
+
// Production builds go through esbuild which handles this regardless of Node version.
|
|
47
|
+
import specJson from '../generated/openapi-spec.json' with { type: 'json' };
|
|
48
|
+
function loadSpec() {
|
|
49
|
+
const specs = parseSpec(specJson);
|
|
50
|
+
const map = new Map();
|
|
51
|
+
for (const spec of specs) {
|
|
52
|
+
map.set(spec.toolName, spec);
|
|
53
|
+
}
|
|
54
|
+
return map;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Register all API commands on the given Commander program.
|
|
58
|
+
*/
|
|
59
|
+
export function registerApiCommands(program) {
|
|
60
|
+
const specMap = loadSpec();
|
|
61
|
+
// Group routes by their top-level path segment
|
|
62
|
+
const groups = new Map();
|
|
63
|
+
for (const route of COMMAND_ROUTES) {
|
|
64
|
+
const groupName = route.path[0];
|
|
65
|
+
const list = groups.get(groupName) ?? [];
|
|
66
|
+
if (!groups.has(groupName))
|
|
67
|
+
groups.set(groupName, list);
|
|
68
|
+
list.push(route);
|
|
69
|
+
}
|
|
70
|
+
// Create group commands and register routes
|
|
71
|
+
for (const [groupName, routes] of groups) {
|
|
72
|
+
const groupDesc = GROUP_DESCRIPTIONS[groupName] ?? `Manage ${groupName}`;
|
|
73
|
+
const groupCmd = program.commands.find((c) => c.name() === groupName)
|
|
74
|
+
?? program.command(groupName).description(groupDesc);
|
|
75
|
+
for (const route of routes) {
|
|
76
|
+
registerRoute(groupCmd, route, specMap);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function registerRoute(parent, route, specMap) {
|
|
81
|
+
const spec = specMap.get(route.toolName);
|
|
82
|
+
if (!spec) {
|
|
83
|
+
// Route references a tool not in the OpenAPI spec — registers with no flags/empty body.
|
|
84
|
+
// This can happen if the spec is stale or if a route was added for a not-yet-deployed endpoint.
|
|
85
|
+
console.warn(`[warn] No spec found for tool: ${route.toolName}`);
|
|
86
|
+
}
|
|
87
|
+
const pathParts = route.path.slice(1); // remove the group prefix
|
|
88
|
+
// Navigate/create subgroups
|
|
89
|
+
let current = parent;
|
|
90
|
+
const pathSoFar = [route.path[0]]; // starts with the top-level group
|
|
91
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
92
|
+
const subName = pathParts[i];
|
|
93
|
+
pathSoFar.push(subName);
|
|
94
|
+
const descKey = pathSoFar.join('.');
|
|
95
|
+
const subDesc = GROUP_DESCRIPTIONS[descKey] ?? `Manage ${subName}`;
|
|
96
|
+
const existing = current.commands.find((c) => c.name() === subName);
|
|
97
|
+
current = existing ?? current.command(subName).description(subDesc);
|
|
98
|
+
}
|
|
99
|
+
// Create the leaf command
|
|
100
|
+
const leafName = pathParts[pathParts.length - 1];
|
|
101
|
+
const cmd = current.command(leafName);
|
|
102
|
+
// Set description from spec or route override
|
|
103
|
+
cmd.description(route.description ?? spec?.summary ?? `Run ${route.toolName}`);
|
|
104
|
+
// Add positional args
|
|
105
|
+
for (const arg of route.positionalArgs) {
|
|
106
|
+
if (arg.variadic) {
|
|
107
|
+
cmd.argument(arg.required ? `<${arg.name}...>` : `[${arg.name}...]`, arg.description);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
cmd.argument(arg.required ? `<${arg.name}>` : `[${arg.name}]`, arg.description);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Add option flags from spec params
|
|
114
|
+
if (spec) {
|
|
115
|
+
const skipNames = new Set(route.positionalArgs.map((a) => a.name));
|
|
116
|
+
for (const param of spec.params) {
|
|
117
|
+
const opt = specParamToOption(param, skipNames);
|
|
118
|
+
if (opt) {
|
|
119
|
+
cmd.option(opt.flags, opt.description);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Add item-level flags for single-item shorthand (array-of-objects params)
|
|
123
|
+
for (const param of spec.params) {
|
|
124
|
+
if (param.type === 'array' && param.items?.type === 'object' && param.items.properties) {
|
|
125
|
+
for (const prop of param.items.properties) {
|
|
126
|
+
const itemOpt = specParamToOption(prop, skipNames);
|
|
127
|
+
if (itemOpt) {
|
|
128
|
+
cmd.option(itemOpt.flags, itemOpt.description);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// --data and --file escape hatches
|
|
135
|
+
cmd.option('--data <json>', 'Raw JSON request body (overrides all other params)');
|
|
136
|
+
cmd.option('--file <path>', 'Read JSON request body from file');
|
|
137
|
+
// Hook-driven options
|
|
138
|
+
const hooks = getHooks(route.toolName);
|
|
139
|
+
if (hooks?.priceOption) {
|
|
140
|
+
cmd.option('--price <dollars>', 'Listing price in dollars (e.g., 99.99)');
|
|
141
|
+
}
|
|
142
|
+
if (hooks?.requireConfirm) {
|
|
143
|
+
cmd.option('--confirm', 'Confirm the destructive operation without interactive prompt');
|
|
144
|
+
}
|
|
145
|
+
if (hooks?.promptInput) {
|
|
146
|
+
// Only add the flag if the spec didn't already generate it
|
|
147
|
+
const existingFlags = cmd.options.map((o) => o.long);
|
|
148
|
+
if (!existingFlags.includes(`--${hooks.promptInput.flagName}`)) {
|
|
149
|
+
cmd.option(`--${hooks.promptInput.flagName} <value>`, hooks.promptInput.prompt);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// --domains-file for commands with variadic domains positional arg
|
|
153
|
+
const hasVariadicDomains = route.positionalArgs.some((a) => a.name === 'domains' && a.variadic);
|
|
154
|
+
if (hasVariadicDomains) {
|
|
155
|
+
cmd.option('--domains-file <path>', 'Read domain names from a file (one per line)');
|
|
156
|
+
}
|
|
157
|
+
// Add known default fields to --help text
|
|
158
|
+
const knownFields = getKnownFields(route.toolName, spec?.responseFields);
|
|
159
|
+
if (knownFields && knownFields.defaults.length > 0) {
|
|
160
|
+
cmd.addHelpText('after', `\nDefault Fields:\n ${knownFields.defaults.join(', ')}\n\nUse --fields to see all available fields.`);
|
|
161
|
+
}
|
|
162
|
+
// Action handler
|
|
163
|
+
cmd.action(async (...args) => {
|
|
164
|
+
const opts = cmd.opts();
|
|
165
|
+
const globalOpts = getRootOpts(cmd);
|
|
166
|
+
// --fields with no value (boolean true) → show available fields and exit
|
|
167
|
+
if (globalOpts.fields === true) {
|
|
168
|
+
const commandPath = route.path.join(' ');
|
|
169
|
+
console.log(formatFieldsList(route.toolName, commandPath, spec?.responseFields));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
// Merge: CLI flag > saved config default > hard-coded default
|
|
173
|
+
const commandConfigPath = route.path.join('.');
|
|
174
|
+
const savedDefaults = getCommandDefaults(commandConfigPath);
|
|
175
|
+
const cliFormat = globalOpts.format;
|
|
176
|
+
const format = cliFormat ?? savedDefaults.format ?? 'table';
|
|
177
|
+
const quiet = globalOpts.quiet !== undefined ? !!globalOpts.quiet : savedDefaults.quiet ?? false;
|
|
178
|
+
const cliFields = typeof globalOpts.fields === 'string'
|
|
179
|
+
? globalOpts.fields.split(',').map((f) => f.trim()).filter(Boolean)
|
|
180
|
+
: undefined;
|
|
181
|
+
const fields = cliFields
|
|
182
|
+
?? (savedDefaults.fields
|
|
183
|
+
? savedDefaults.fields.split(',').map((f) => f.trim()).filter(Boolean)
|
|
184
|
+
: undefined);
|
|
185
|
+
// Validate --fields values against known fields
|
|
186
|
+
if (fields && fields.length > 0) {
|
|
187
|
+
const known = getKnownFields(route.toolName, spec?.responseFields);
|
|
188
|
+
if (known) {
|
|
189
|
+
const invalid = fields.filter((f) => !known.all.includes(f));
|
|
190
|
+
if (invalid.length > 0) {
|
|
191
|
+
console.error(formatError(new Error(`Unknown field${invalid.length > 1 ? 's' : ''}: ${invalid.join(', ')}\n\nRun with --fields to see available fields.`)));
|
|
192
|
+
process.exitCode = 1;
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Collect positional values
|
|
198
|
+
const positionalValues = {};
|
|
199
|
+
for (let i = 0; i < route.positionalArgs.length; i++) {
|
|
200
|
+
const argDef = route.positionalArgs[i];
|
|
201
|
+
const val = args[i];
|
|
202
|
+
if (val !== undefined) {
|
|
203
|
+
positionalValues[argDef.name] = val;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// --domains-file: merge file contents with positional domains
|
|
207
|
+
if (hasVariadicDomains && opts.domainsFile) {
|
|
208
|
+
try {
|
|
209
|
+
const fileContent = await readFile(opts.domainsFile, 'utf-8');
|
|
210
|
+
const fileDomains = fileContent.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
211
|
+
const existing = positionalValues.domains;
|
|
212
|
+
const arr = Array.isArray(existing) ? existing : existing ? [existing] : [];
|
|
213
|
+
positionalValues.domains = [...arr, ...fileDomains];
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
console.error(formatError(new Error(`Failed to read --domains-file: ${err instanceof Error ? err.message : String(err)}`)));
|
|
217
|
+
process.exitCode = 1;
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Build request body
|
|
222
|
+
let body = buildParams(route, spec?.params ?? [], positionalValues, opts);
|
|
223
|
+
// Pre-call hooks: transformBody (e.g., price conversion)
|
|
224
|
+
if (hooks?.transformBody) {
|
|
225
|
+
try {
|
|
226
|
+
body = hooks.transformBody(body, opts);
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
console.error(formatError(err));
|
|
230
|
+
process.exitCode = 1;
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Pre-call hooks: requireConfirm
|
|
235
|
+
if (hooks?.requireConfirm && !opts.confirm) {
|
|
236
|
+
const confirmed = await promptConfirm(hooks.requireConfirm.message);
|
|
237
|
+
if (!confirmed) {
|
|
238
|
+
console.log('Aborted.');
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Set the API param if confirmation was given (via flag or prompt)
|
|
243
|
+
if (hooks?.requireConfirm?.paramName) {
|
|
244
|
+
body[hooks.requireConfirm.paramName] = true;
|
|
245
|
+
}
|
|
246
|
+
// Pre-call hooks: promptInput (e.g., OTP code)
|
|
247
|
+
if (hooks?.promptInput) {
|
|
248
|
+
const flagCamel = hooks.promptInput.flagName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
249
|
+
let value = opts[flagCamel];
|
|
250
|
+
if (!value) {
|
|
251
|
+
value = await promptInput(hooks.promptInput.prompt, {
|
|
252
|
+
validate: hooks.promptInput.validate,
|
|
253
|
+
});
|
|
254
|
+
if (!value) {
|
|
255
|
+
console.log(`Aborted — use --${hooks.promptInput.flagName} <value> to provide input non-interactively.`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
body[hooks.promptInput.paramName] = value;
|
|
260
|
+
}
|
|
261
|
+
const spinner = await createSpinner(`Running ${route.toolName}...`, { quiet, format });
|
|
262
|
+
spinner.start();
|
|
263
|
+
try {
|
|
264
|
+
const result = await callAction(route.toolName, body);
|
|
265
|
+
spinner.stop();
|
|
266
|
+
if (!quiet) {
|
|
267
|
+
const output = formatOutput(result, {
|
|
268
|
+
format,
|
|
269
|
+
responsePattern: spec?.responsePattern,
|
|
270
|
+
toolName: route.toolName,
|
|
271
|
+
fields,
|
|
272
|
+
});
|
|
273
|
+
console.log(output);
|
|
274
|
+
// Post-call hook: show operation hint
|
|
275
|
+
if (hooks?.showOperationHint) {
|
|
276
|
+
const hint = formatOperationHint(result);
|
|
277
|
+
if (hint)
|
|
278
|
+
console.log(hint);
|
|
279
|
+
}
|
|
280
|
+
// Post-call hook: show cart-add hint
|
|
281
|
+
if (hooks?.showCartHint) {
|
|
282
|
+
const hint = formatCartHint(result);
|
|
283
|
+
if (hint)
|
|
284
|
+
console.log(hint);
|
|
285
|
+
}
|
|
286
|
+
// Show save hint when user explicitly passed --fields that differ from saved default
|
|
287
|
+
if (cliFields && format === 'table') {
|
|
288
|
+
const cliFieldsStr = cliFields.join(',');
|
|
289
|
+
if (cliFieldsStr !== (savedDefaults.fields ?? '')) {
|
|
290
|
+
const displayPath = route.path.join(' ');
|
|
291
|
+
console.log(chalk.dim(`\nTip: To save these fields as default, run:\n ud config set "${displayPath}" fields ${cliFieldsStr}`));
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
spinner.fail('Failed');
|
|
298
|
+
console.error(formatError(err));
|
|
299
|
+
process.exitCode = 1;
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=api-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-commands.js","sourceRoot":"","sources":["../../src/commands/api-commands.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B;;;GAGG;AACH,MAAM,kBAAkB,GAA2B;IACjD,mBAAmB;IACnB,OAAO,EAAE,2CAA2C;IACpD,GAAG,EAAE,8CAA8C;IACnD,IAAI,EAAE,wCAAwC;IAC9C,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,wCAAwC;IAClD,MAAM,EAAE,mCAAmC;IAC3C,KAAK,EAAE,kCAAkC;IACzC,YAAY;IACZ,cAAc,EAAE,2BAA2B;IAC3C,eAAe,EAAE,0DAA0D;IAC3E,sBAAsB,EAAE,qCAAqC;IAC7D,aAAa,EAAE,2CAA2C;IAC1D,iBAAiB,EAAE,gCAAgC;IACnD,aAAa,EAAE,8CAA8C;IAC7D,oBAAoB,EAAE,8CAA8C;IACpE,UAAU,EAAE,0BAA0B;CACvC,CAAC;AAEF,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAY,GAAG,CAAC;IAC3B,OAAO,OAAO,CAAC,MAAM;QAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAChD,OAAO,OAAO,CAAC,IAAI,EAA2B,CAAC;AACjD,CAAC;AAED,oGAAoG;AACpG,gGAAgG;AAChG,sFAAsF;AACtF,OAAO,QAAQ,MAAM,gCAAgC,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAE5E,SAAS,QAAQ;IACf,MAAM,KAAK,GAAG,SAAS,CAAC,QAAsD,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;IAE3B,+CAA+C;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAED,4CAA4C;IAC5C,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,kBAAkB,CAAC,SAAS,CAAC,IAAI,UAAU,SAAS,EAAE,CAAC;QACzE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,SAAS,CAAC;eAChE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAEvD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,MAAe,EACf,KAAmB,EACnB,OAAiC;IAEjC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,wFAAwF;QACxF,gGAAgG;QAChG,OAAO,CAAC,IAAI,CAAC,kCAAkC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B;IAEjE,4BAA4B;IAC5B,IAAI,OAAO,GAAG,MAAM,CAAC;IACrB,MAAM,SAAS,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kCAAkC;IACrE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC7B,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,UAAU,OAAO,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,CAAC;QACpE,OAAO,GAAG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IACtE,CAAC;IAED,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEtC,8CAA8C;IAC9C,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE,OAAO,IAAI,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE/E,sBAAsB;IACtB,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;QACvC,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,GAAG,CAAC,QAAQ,CACV,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,MAAM,EACtD,GAAG,CAAC,WAAW,CAChB,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,QAAQ,CACV,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,EAChD,GAAG,CAAC,WAAW,CAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAChD,IAAI,GAAG,EAAE,CAAC;gBACR,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;gBACvF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;oBAC1C,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;oBACnD,IAAI,OAAO,EAAE,CAAC;wBACZ,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;oBACjD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,oDAAoD,CAAC,CAAC;IAClF,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,kCAAkC,CAAC,CAAC;IAEhE,sBAAsB;IACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEvC,IAAI,KAAK,EAAE,WAAW,EAAE,CAAC;QACvB,GAAG,CAAC,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,KAAK,EAAE,cAAc,EAAE,CAAC;QAC1B,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,8DAA8D,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,KAAK,EAAE,WAAW,EAAE,CAAC;QACvB,2DAA2D;QAC3D,MAAM,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,WAAW,CAAC,QAAQ,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM,kBAAkB,GAAG,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC;IAChG,IAAI,kBAAkB,EAAE,CAAC;QACvB,GAAG,CAAC,MAAM,CAAC,uBAAuB,EAAE,8CAA8C,CAAC,CAAC;IACtF,CAAC;IAED,0CAA0C;IAC1C,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACzE,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,WAAW,CAAC,OAAO,EAAE,wBAAwB,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;IACnI,CAAC;IAED,iBAAiB;IACjB,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAA2B,CAAC;QACjD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QAEpC,yEAAyE;QACzE,IAAI,UAAU,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;YACjF,OAAO;QACT,CAAC;QAED,8DAA8D;QAC9D,MAAM,iBAAiB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,aAAa,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;QAE5D,MAAM,SAAS,GAAG,UAAU,CAAC,MAAkC,CAAC;QAChE,MAAM,MAAM,GAAiB,SAAS,IAAI,aAAa,CAAC,MAAM,IAAI,OAAO,CAAC;QAC1E,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,IAAI,KAAK,CAAC;QAEjG,MAAM,SAAS,GAAG,OAAO,UAAU,CAAC,MAAM,KAAK,QAAQ;YACrD,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YAC3E,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,MAAM,GAAG,SAAS;eACnB,CAAC,aAAa,CAAC,MAAM;gBACtB,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;gBAC9E,CAAC,CAAC,SAAS,CAAC,CAAC;QAEjB,gDAAgD;QAChD,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;YACnE,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,CACjC,gBAAgB,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,gDAAgD,CACrH,CAAC,CAAC,CAAC;oBACJ,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;oBACrB,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,MAAM,gBAAgB,GAAsC,EAAE,CAAC;QAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;YACvC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAwB,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,8DAA8D;QAC9D,IAAI,kBAAkB,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,WAAqB,EAAE,OAAO,CAAC,CAAC;gBACxE,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACjF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC;gBAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5E,gBAAgB,CAAC,OAAO,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,WAAW,CAAC,CAAC;YACtD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,kCAAkC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC5H,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAED,qBAAqB;QACrB,IAAI,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;QAE1E,yDAAyD;QACzD,IAAI,KAAK,EAAE,aAAa,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACzC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,IAAI,KAAK,EAAE,cAAc,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACpE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACxB,OAAO;YACT,CAAC;QACH,CAAC;QACD,mEAAmE;QACnE,IAAI,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;QAC9C,CAAC;QAED,+CAA+C;QAC/C,IAAI,KAAK,EAAE,WAAW,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACrG,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,CAAuB,CAAC;YAClD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE;oBAClD,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,QAAQ;iBACrC,CAAC,CAAC;gBACH,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,WAAW,CAAC,QAAQ,8CAA8C,CAAC,CAAC;oBACzG,OAAO;gBACT,CAAC;YACH,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;QAC5C,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,WAAW,KAAK,CAAC,QAAQ,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACvF,OAAO,CAAC,KAAK,EAAE,CAAC;QAEhB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE;oBAClC,MAAM;oBACN,eAAe,EAAE,IAAI,EAAE,eAAe;oBACtC,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,MAAM;iBACP,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAEpB,sCAAsC;gBACtC,IAAI,KAAK,EAAE,iBAAiB,EAAE,CAAC;oBAC7B,MAAM,IAAI,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;oBACzC,IAAI,IAAI;wBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBAED,qCAAqC;gBACrC,IAAI,KAAK,EAAE,YAAY,EAAE,CAAC;oBACxB,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;oBACpC,IAAI,IAAI;wBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;gBAED,qFAAqF;gBACrF,IAAI,SAAS,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;oBACpC,MAAM,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACzC,IAAI,YAAY,KAAK,CAAC,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;wBAClD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,kEAAkE,WAAW,YAAY,YAAY,EAAE,CAAC,CAAC,CAAC;oBAClI,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YAChC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
|