@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.
Files changed (79) hide show
  1. package/README.md +344 -0
  2. package/dist/commands/api-commands.d.ts +9 -0
  3. package/dist/commands/api-commands.d.ts.map +1 -0
  4. package/dist/commands/api-commands.js +303 -0
  5. package/dist/commands/api-commands.js.map +1 -0
  6. package/dist/commands/auth.d.ts +3 -0
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/auth.js +97 -0
  9. package/dist/commands/auth.js.map +1 -0
  10. package/dist/commands/cart.d.ts +10 -0
  11. package/dist/commands/cart.d.ts.map +1 -0
  12. package/dist/commands/cart.js +125 -0
  13. package/dist/commands/cart.js.map +1 -0
  14. package/dist/commands/config.d.ts +3 -0
  15. package/dist/commands/config.d.ts.map +1 -0
  16. package/dist/commands/config.js +90 -0
  17. package/dist/commands/config.js.map +1 -0
  18. package/dist/commands/env.d.ts +3 -0
  19. package/dist/commands/env.d.ts.map +1 -0
  20. package/dist/commands/env.js +29 -0
  21. package/dist/commands/env.js.map +1 -0
  22. package/dist/generated/openapi-spec.json +5903 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +3 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/api.d.ts +7 -0
  28. package/dist/lib/api.d.ts.map +1 -0
  29. package/dist/lib/api.js +162 -0
  30. package/dist/lib/api.js.map +1 -0
  31. package/dist/lib/command-hooks.d.ts +49 -0
  32. package/dist/lib/command-hooks.d.ts.map +1 -0
  33. package/dist/lib/command-hooks.js +150 -0
  34. package/dist/lib/command-hooks.js.map +1 -0
  35. package/dist/lib/command-registry.d.ts +30 -0
  36. package/dist/lib/command-registry.d.ts.map +1 -0
  37. package/dist/lib/command-registry.js +322 -0
  38. package/dist/lib/command-registry.js.map +1 -0
  39. package/dist/lib/config.d.ts +19 -0
  40. package/dist/lib/config.d.ts.map +1 -0
  41. package/dist/lib/config.js +95 -0
  42. package/dist/lib/config.js.map +1 -0
  43. package/dist/lib/credentials.d.ts +16 -0
  44. package/dist/lib/credentials.d.ts.map +1 -0
  45. package/dist/lib/credentials.js +126 -0
  46. package/dist/lib/credentials.js.map +1 -0
  47. package/dist/lib/formatter.d.ts +34 -0
  48. package/dist/lib/formatter.d.ts.map +1 -0
  49. package/dist/lib/formatter.js +691 -0
  50. package/dist/lib/formatter.js.map +1 -0
  51. package/dist/lib/oauth.d.ts +8 -0
  52. package/dist/lib/oauth.d.ts.map +1 -0
  53. package/dist/lib/oauth.js +212 -0
  54. package/dist/lib/oauth.js.map +1 -0
  55. package/dist/lib/param-builder.d.ts +28 -0
  56. package/dist/lib/param-builder.d.ts.map +1 -0
  57. package/dist/lib/param-builder.js +178 -0
  58. package/dist/lib/param-builder.js.map +1 -0
  59. package/dist/lib/prompt.d.ts +17 -0
  60. package/dist/lib/prompt.d.ts.map +1 -0
  61. package/dist/lib/prompt.js +53 -0
  62. package/dist/lib/prompt.js.map +1 -0
  63. package/dist/lib/spec-parser.d.ts +76 -0
  64. package/dist/lib/spec-parser.d.ts.map +1 -0
  65. package/dist/lib/spec-parser.js +201 -0
  66. package/dist/lib/spec-parser.js.map +1 -0
  67. package/dist/lib/spinner.d.ts +16 -0
  68. package/dist/lib/spinner.d.ts.map +1 -0
  69. package/dist/lib/spinner.js +23 -0
  70. package/dist/lib/spinner.js.map +1 -0
  71. package/dist/lib/types.d.ts +63 -0
  72. package/dist/lib/types.d.ts.map +1 -0
  73. package/dist/lib/types.js +11 -0
  74. package/dist/lib/types.js.map +1 -0
  75. package/dist/program.d.ts +3 -0
  76. package/dist/program.d.ts.map +1 -0
  77. package/dist/program.js +47 -0
  78. package/dist/program.js.map +1 -0
  79. 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":"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"}