api-to-cli 0.1.2 → 0.1.3

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 (62) hide show
  1. package/README.md +126 -4
  2. package/examples/openapi/sample-openapi-agent/README.md +12 -0
  3. package/examples/openapi/sample-openapi-agent/agentbridge.manifest.json +85 -0
  4. package/examples/openapi/sample-openapi-agent/cli/README.md +18 -0
  5. package/examples/openapi/sample-openapi-agent/cli/bin/sample-crm-api.js +64 -0
  6. package/examples/openapi/sample-openapi-agent/cli/commands/create-contact.js +59 -0
  7. package/examples/openapi/sample-openapi-agent/cli/commands/delete-contacts-by-contactid.js +45 -0
  8. package/examples/openapi/sample-openapi-agent/cli/commands/get-contacts-by-contactid.js +45 -0
  9. package/examples/openapi/sample-openapi-agent/cli/commands/list-contacts.js +45 -0
  10. package/examples/openapi/sample-openapi-agent/cli/commands/patch-contacts-by-contactid.js +60 -0
  11. package/examples/openapi/sample-openapi-agent/cli/lib/client.js +244 -0
  12. package/examples/openapi/sample-openapi-agent/cli/lib/output.js +21 -0
  13. package/examples/openapi/sample-openapi-agent/cli/package.json +16 -0
  14. package/examples/openapi/sample-openapi-agent/skill/SKILL.md +50 -0
  15. package/examples/openapi/sample-openapi-cli/README.md +18 -0
  16. package/examples/openapi/sample-openapi-cli/bin/sample-crm-api.js +64 -0
  17. package/examples/openapi/sample-openapi-cli/commands/create-contact.js +59 -0
  18. package/examples/openapi/sample-openapi-cli/commands/delete-contacts-by-contactid.js +45 -0
  19. package/examples/openapi/sample-openapi-cli/commands/get-contacts-by-contactid.js +45 -0
  20. package/examples/openapi/sample-openapi-cli/commands/list-contacts.js +45 -0
  21. package/examples/openapi/sample-openapi-cli/commands/patch-contacts-by-contactid.js +60 -0
  22. package/examples/openapi/sample-openapi-cli/lib/client.js +244 -0
  23. package/examples/openapi/sample-openapi-cli/lib/output.js +21 -0
  24. package/examples/openapi/sample-openapi-cli/node_modules/.package-lock.json +15 -0
  25. package/examples/openapi/sample-openapi-cli/node_modules/commander/LICENSE +22 -0
  26. package/examples/openapi/sample-openapi-cli/node_modules/commander/Readme.md +1157 -0
  27. package/examples/openapi/sample-openapi-cli/node_modules/commander/esm.mjs +16 -0
  28. package/examples/openapi/sample-openapi-cli/node_modules/commander/index.js +24 -0
  29. package/examples/openapi/sample-openapi-cli/node_modules/commander/lib/argument.js +149 -0
  30. package/examples/openapi/sample-openapi-cli/node_modules/commander/lib/command.js +2509 -0
  31. package/examples/openapi/sample-openapi-cli/node_modules/commander/lib/error.js +39 -0
  32. package/examples/openapi/sample-openapi-cli/node_modules/commander/lib/help.js +520 -0
  33. package/examples/openapi/sample-openapi-cli/node_modules/commander/lib/option.js +330 -0
  34. package/examples/openapi/sample-openapi-cli/node_modules/commander/lib/suggestSimilar.js +101 -0
  35. package/examples/openapi/sample-openapi-cli/node_modules/commander/package-support.json +16 -0
  36. package/examples/openapi/sample-openapi-cli/node_modules/commander/package.json +84 -0
  37. package/examples/openapi/sample-openapi-cli/node_modules/commander/typings/esm.d.mts +3 -0
  38. package/examples/openapi/sample-openapi-cli/node_modules/commander/typings/index.d.ts +969 -0
  39. package/examples/openapi/sample-openapi-cli/package.json +16 -0
  40. package/examples/openapi/sample-openapi.yaml +67 -0
  41. package/examples/trello/trelloapi-agent/README.md +1 -0
  42. package/examples/trello/trelloapi-agent/agentbridge.manifest.json +1 -1
  43. package/examples/trello/trelloapi-agent/cli/commands/get-board.js +4 -0
  44. package/examples/trello/trelloapi-agent/cli/commands/list-board-lists.js +4 -0
  45. package/examples/trello/trelloapi-agent/cli/commands/list-list-cards.js +4 -0
  46. package/examples/trello/trelloapi-agent/cli/lib/client.js +174 -9
  47. package/examples/trello/trelloapi-cli/commands/get-board.js +4 -0
  48. package/examples/trello/trelloapi-cli/commands/list-board-lists.js +4 -0
  49. package/examples/trello/trelloapi-cli/commands/list-list-cards.js +4 -0
  50. package/examples/trello/trelloapi-cli/lib/client.js +174 -9
  51. package/package.json +8 -2
  52. package/src/commands/doctor.js +234 -0
  53. package/src/commands/generate.js +4 -8
  54. package/src/commands/init.js +154 -0
  55. package/src/commands/scaffold.js +9 -9
  56. package/src/commands/validate.js +6 -10
  57. package/src/index.js +21 -5
  58. package/src/lib/generate-cli.js +208 -15
  59. package/src/lib/generate-skill.js +24 -2
  60. package/src/lib/load-config.js +39 -3
  61. package/src/lib/openapi-to-config.js +314 -0
  62. package/src/lib/resolve-config-input.js +50 -0
package/README.md CHANGED
@@ -12,14 +12,17 @@ This means anyone can create a CLI layer for an API, even if the API owner never
12
12
 
13
13
  ## Current Scope
14
14
  - Generator commands:
15
+ - `doctor`
16
+ - `init`
15
17
  - `validate`
16
18
  - `generate`
17
19
  - `scaffold`
18
20
  - Generated CLI support:
19
- - GET endpoints (MVP)
21
+ - GET, POST, PUT, PATCH, DELETE
20
22
  - JSON output by default
21
23
  - JSON error envelope
22
24
  - Env-var auth injection (`header` or `query`)
25
+ - Safe guard for state-changing operations (`--yes` required)
23
26
 
24
27
  ## Install and Run
25
28
 
@@ -41,16 +44,29 @@ api-to-cli --help
41
44
  Use either `npx api-to-cli` or `api-to-cli` (if globally installed).
42
45
 
43
46
  ```bash
44
- # 1) Validate config only
47
+ # 1) Validate from custom config
45
48
  npx api-to-cli validate \
46
49
  --config ./examples/trello/api-to-cli.config.js
47
50
 
48
- # 2) Generate only the CLI project
51
+ # 2) Diagnose environment and input before generation
52
+ npx api-to-cli doctor --url https://api.example.com
53
+
54
+ # 3) Bootstrap a config from an API base URL
55
+ npx api-to-cli init \
56
+ --url https://api.example.com \
57
+ --output ./api-to-cli.config.js
58
+
59
+ # 4) Generate from custom config
49
60
  npx api-to-cli generate \
50
61
  --config ./examples/trello/api-to-cli.config.js \
51
62
  --output ./examples/trello/trelloapi-cli
52
63
 
53
- # 3) Generate a full agent bundle (CLI + skill + manifest)
64
+ # 5) Generate from OpenAPI spec (local file or URL)
65
+ npx api-to-cli generate \
66
+ --spec ./examples/openapi/sample-openapi.yaml \
67
+ --output ./examples/openapi/sample-openapi-cli
68
+
69
+ # 6) Generate a full agent bundle (CLI + skill + manifest)
54
70
  npx api-to-cli scaffold \
55
71
  --config ./examples/trello/api-to-cli.config.js \
56
72
  --output ./examples/trello/trelloapi-agent
@@ -103,6 +119,109 @@ flowchart LR
103
119
  2. Agent reads `skill/SKILL.md` for operating rules and command examples.
104
120
  3. Agent executes the generated CLI and parses JSON stdout/stderr.
105
121
 
122
+ ## OpenAPI Notes
123
+ - Supported input: OpenAPI 3.x JSON or YAML (`--spec <path-or-url>`)
124
+ - Command names are derived from `operationId` when available, otherwise method + path
125
+ - Path/query parameters are converted into CLI flags
126
+ - For `POST/PUT/PATCH/DELETE`, generated commands require `--yes`
127
+ - If OpenAPI operation has JSON object requestBody, generated command creates typed body flags like `--body-name`
128
+ - Generated commands also support `--body <json>` and `--body-stdin` as fallback modes
129
+
130
+ ## Init From URL
131
+ - Command: `api-to-cli init --url <api-base-url> --output ./api-to-cli.config.js`
132
+ - Behavior:
133
+ - Tries to discover OpenAPI automatically from common paths (`/openapi.json`, `/swagger.json`, etc.)
134
+ - If found: writes a populated config derived from the spec
135
+ - If not found: writes a starter config template you can edit
136
+ - Optional flags:
137
+ - `--name <cli-name>`
138
+ - `--version <semver>`
139
+
140
+ ### URL Init Architecture
141
+
142
+ ```mermaid
143
+ flowchart TD
144
+ U[--url API base] --> C[Build candidate spec URLs]
145
+ C --> T[Try candidate endpoints]
146
+ T -->|Spec found| P[Parse OpenAPI]
147
+ P --> M[Map to api-to-cli config]
148
+ M --> W1[Write api-to-cli.config.js]
149
+ T -->|No spec found| S[Create starter config template]
150
+ S --> W2[Write api-to-cli.config.js]
151
+ W1 --> N[Run generate/scaffold]
152
+ W2 --> N
153
+ ```
154
+
155
+ ## Doctor Command
156
+ - Command: `api-to-cli doctor [--config <path>] [--spec <path-or-url>] [--url <api-base-url>]`
157
+ - Checks include:
158
+ - Node runtime compatibility
159
+ - fetch availability
160
+ - working directory writability
161
+ - config/spec validation (when provided)
162
+ - OpenAPI discovery hints for URL inputs
163
+ - Output is JSON with pass/fail checks and suggested fixes.
164
+
165
+ ## OpenAPI Quickstart
166
+
167
+ Run with your own spec file:
168
+
169
+ ```bash
170
+ # 1) Validate an OpenAPI spec
171
+ npx api-to-cli validate --spec ./openapi.yaml
172
+
173
+ # 2) Generate a CLI project from the spec
174
+ npx api-to-cli generate --spec ./openapi.yaml --output ./myapi-cli
175
+
176
+ # 3) Generate a full agent bundle (CLI + skill + manifest)
177
+ npx api-to-cli scaffold --spec ./openapi.yaml --output ./myapi-agent
178
+ ```
179
+
180
+ Run the generated CLI:
181
+
182
+ ```bash
183
+ cd ./myapi-cli
184
+ npm install
185
+ node ./bin/<generated-cli-name>.js --help
186
+ ```
187
+
188
+ Mutation command examples (POST/PUT/PATCH/DELETE):
189
+
190
+ ```bash
191
+ # Typed body flags from request schema
192
+ node ./bin/<generated-cli-name>.js create-item --body-name "Alice" --yes --pretty
193
+
194
+ # Raw JSON body fallback
195
+ node ./bin/<generated-cli-name>.js create-item --body '{"name":"Alice"}' --yes --pretty
196
+
197
+ # JSON via stdin fallback
198
+ echo '{"name":"Alice"}' | node ./bin/<generated-cli-name>.js create-item --body-stdin --yes --pretty
199
+ ```
200
+
201
+ ## OpenAPI Architecture
202
+
203
+ ```mermaid
204
+ flowchart TD
205
+ SPEC[OpenAPI JSON/YAML] --> PARSE[OpenAPI Parser]
206
+ PARSE --> MAP[Map operations to command config]
207
+ MAP --> PARAMS[Path/query params to CLI flags]
208
+ MAP --> BODY[JSON body schema to body flags]
209
+ BODY --> FLAGS[--body-field flags]
210
+ BODY --> FALLBACK[--body / --body-stdin fallback]
211
+ MAP --> SAFETY[Non-GET safety: --yes required]
212
+ PARAMS --> GEN[CLI Generator]
213
+ FLAGS --> GEN
214
+ FALLBACK --> GEN
215
+ SAFETY --> GEN
216
+ GEN --> OUT[Generated CLI + Skill + Manifest]
217
+ ```
218
+
219
+ ## Sample OpenAPI Spec
220
+ - Included at `examples/openapi/sample-openapi.yaml`
221
+ - Includes GET and mutation operations with JSON request bodies
222
+ - Generated CLI output: `examples/openapi/sample-openapi-cli`
223
+ - Generated agent bundle output: `examples/openapi/sample-openapi-agent`
224
+
106
225
  ## Suggested Usage Flows
107
226
 
108
227
  ### Flow A: Local Personal Use (No API Owner Needed)
@@ -145,6 +264,9 @@ This runs:
145
264
  - `validate:trello`
146
265
  - `generate:trello`
147
266
  - `scaffold:trello`
267
+ - `validate:openapi`
268
+ - `generate:openapi`
269
+ - `scaffold:openapi`
148
270
 
149
271
  ## Notes
150
272
  - Generated CLIs depend on `commander`.
@@ -0,0 +1,12 @@
1
+ # AgentBridge Scaffold Output
2
+
3
+ ## Contents
4
+ - CLI project: ./cli
5
+ - Input source: spec (./examples/openapi/sample-openapi.yaml)
6
+ - Skill file: ./skill/SKILL.md
7
+ - Manifest: ./agentbridge.manifest.json
8
+
9
+ ## Next Steps
10
+ 1. cd ./cli
11
+ 2. npm install
12
+ 3. npm link
@@ -0,0 +1,85 @@
1
+ {
2
+ "schemaVersion": "1.0",
3
+ "generatedBy": "AgentBridge",
4
+ "generatedAt": "2026-02-20T01:48:45.765Z",
5
+ "project": {
6
+ "name": "sample-crm-api",
7
+ "version": "1.0.0"
8
+ },
9
+ "cli": {
10
+ "projectPath": "./cli",
11
+ "packageName": "sample-crm-api-cli",
12
+ "binary": "sample-crm-api",
13
+ "install": [
14
+ "npm install",
15
+ "npm link"
16
+ ]
17
+ },
18
+ "auth": {
19
+ "envVars": []
20
+ },
21
+ "commands": [
22
+ {
23
+ "name": "list-contacts",
24
+ "description": "List contacts",
25
+ "method": "GET",
26
+ "path": "/contacts",
27
+ "params": [
28
+ {
29
+ "name": "limit",
30
+ "required": false,
31
+ "description": "Max contacts to return"
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ "name": "create-contact",
37
+ "description": "Create contact",
38
+ "method": "POST",
39
+ "path": "/contacts",
40
+ "params": []
41
+ },
42
+ {
43
+ "name": "get-contacts-by-contactid",
44
+ "description": "Get contact by ID",
45
+ "method": "GET",
46
+ "path": "/contacts/{contactId}",
47
+ "params": [
48
+ {
49
+ "name": "contactId",
50
+ "required": true,
51
+ "description": "Contact ID"
52
+ }
53
+ ]
54
+ },
55
+ {
56
+ "name": "patch-contacts-by-contactid",
57
+ "description": "Update contact fields",
58
+ "method": "PATCH",
59
+ "path": "/contacts/{contactId}",
60
+ "params": [
61
+ {
62
+ "name": "contactId",
63
+ "required": true,
64
+ "description": "Contact ID"
65
+ }
66
+ ]
67
+ },
68
+ {
69
+ "name": "delete-contacts-by-contactid",
70
+ "description": "Delete contact",
71
+ "method": "DELETE",
72
+ "path": "/contacts/{contactId}",
73
+ "params": [
74
+ {
75
+ "name": "contactId",
76
+ "required": true,
77
+ "description": "Contact ID"
78
+ }
79
+ ]
80
+ }
81
+ ],
82
+ "agent": {
83
+ "skillPath": "./skill/SKILL.md"
84
+ }
85
+ }
@@ -0,0 +1,18 @@
1
+ # sample-crm-api CLI
2
+
3
+ Generated by AgentBridge (api-to-cli).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install
9
+ npm link
10
+ ```
11
+
12
+ ## Commands
13
+
14
+ - `sample-crm-api list-contacts` - List contacts
15
+ - `sample-crm-api create-contact` - Create contact
16
+ - `sample-crm-api get-contacts-by-contactid` - Get contact by ID
17
+ - `sample-crm-api patch-contacts-by-contactid` - Update contact fields
18
+ - `sample-crm-api delete-contacts-by-contactid` - Delete contact
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { Command } = require('commander');
4
+
5
+ const cmd0 = require('../commands/list-contacts');
6
+ const cmd1 = require('../commands/create-contact');
7
+ const cmd2 = require('../commands/get-contacts-by-contactid');
8
+ const cmd3 = require('../commands/patch-contacts-by-contactid');
9
+ const cmd4 = require('../commands/delete-contacts-by-contactid');
10
+
11
+ const program = new Command();
12
+
13
+ program
14
+ .name('sample-crm-api')
15
+ .description('sample-crm-api CLI generated by AgentBridge')
16
+ .version('1.0.0');
17
+
18
+ program
19
+ .command('list-contacts')
20
+ .description('List contacts')
21
+ .option('--limit <value>', 'Max contacts to return')
22
+ .option('--pretty', 'Pretty-print JSON')
23
+ .action((options) => cmd0.run(options));
24
+
25
+ program
26
+ .command('create-contact')
27
+ .description('Create contact')
28
+ .option('--yes', 'Confirm non-GET operation')
29
+ .option('--body <json>', 'Raw JSON request body')
30
+ .option('--body-stdin', 'Read JSON body from stdin')
31
+ .option('--body-name <value>', 'Contact full name (required)')
32
+ .option('--body-email <value>', 'Contact email (optional)')
33
+ .option('--body-subscribed <value>', 'Newsletter subscription status (optional)')
34
+ .option('--pretty', 'Pretty-print JSON')
35
+ .action((options) => cmd1.run(options));
36
+
37
+ program
38
+ .command('get-contacts-by-contactid')
39
+ .description('Get contact by ID')
40
+ .option('--contact-id <value>', 'Contact ID')
41
+ .option('--pretty', 'Pretty-print JSON')
42
+ .action((options) => cmd2.run(options));
43
+
44
+ program
45
+ .command('patch-contacts-by-contactid')
46
+ .description('Update contact fields')
47
+ .option('--contact-id <value>', 'Contact ID')
48
+ .option('--yes', 'Confirm non-GET operation')
49
+ .option('--body <json>', 'Raw JSON request body')
50
+ .option('--body-stdin', 'Read JSON body from stdin')
51
+ .option('--body-name <value>', 'Updated full name (optional)')
52
+ .option('--body-email <value>', 'Updated email (optional)')
53
+ .option('--pretty', 'Pretty-print JSON')
54
+ .action((options) => cmd3.run(options));
55
+
56
+ program
57
+ .command('delete-contacts-by-contactid')
58
+ .description('Delete contact')
59
+ .option('--contact-id <value>', 'Contact ID')
60
+ .option('--yes', 'Confirm non-GET operation')
61
+ .option('--pretty', 'Pretty-print JSON')
62
+ .action((options) => cmd4.run(options));
63
+
64
+ program.parse(process.argv);
@@ -0,0 +1,59 @@
1
+ const { request } = require('../lib/client');
2
+ const output = require('../lib/output');
3
+
4
+ const command = {
5
+ "name": "create-contact",
6
+ "description": "Create contact",
7
+ "method": "POST",
8
+ "path": "/contacts",
9
+ "params": {},
10
+ "requestBody": {
11
+ "required": true,
12
+ "properties": {
13
+ "name": {
14
+ "type": "string",
15
+ "required": true,
16
+ "description": "Contact full name"
17
+ },
18
+ "email": {
19
+ "type": "string",
20
+ "required": false,
21
+ "description": "Contact email"
22
+ },
23
+ "subscribed": {
24
+ "type": "boolean",
25
+ "required": false,
26
+ "description": "Newsletter subscription status"
27
+ }
28
+ }
29
+ }
30
+ };
31
+
32
+ async function createContact(options) {
33
+ try {
34
+ if (command.method !== 'GET' && !options.yes) {
35
+ throw new Error('This operation changes state. Re-run with --yes to confirm.');
36
+ }
37
+
38
+ const data = await request(command, options);
39
+ output.json(data, Boolean(options.pretty));
40
+ } catch (error) {
41
+ output.error(
42
+ {
43
+ code: error.statusCode ? 'HTTP_ERROR' : 'REQUEST_FAILED',
44
+ message: error.message,
45
+ details: {
46
+ statusCode: error.statusCode || null,
47
+ command: command.name
48
+ }
49
+ },
50
+ Boolean(options.pretty)
51
+ );
52
+ process.exit(1);
53
+ }
54
+ }
55
+
56
+ module.exports = {
57
+ run: createContact,
58
+ command
59
+ };
@@ -0,0 +1,45 @@
1
+ const { request } = require('../lib/client');
2
+ const output = require('../lib/output');
3
+
4
+ const command = {
5
+ "name": "delete-contacts-by-contactid",
6
+ "description": "Delete contact",
7
+ "method": "DELETE",
8
+ "path": "/contacts/{contactId}",
9
+ "params": {
10
+ "contactId": {
11
+ "type": "string",
12
+ "required": true,
13
+ "description": "Contact ID"
14
+ }
15
+ }
16
+ };
17
+
18
+ async function deleteContactsByContactid(options) {
19
+ try {
20
+ if (command.method !== 'GET' && !options.yes) {
21
+ throw new Error('This operation changes state. Re-run with --yes to confirm.');
22
+ }
23
+
24
+ const data = await request(command, options);
25
+ output.json(data, Boolean(options.pretty));
26
+ } catch (error) {
27
+ output.error(
28
+ {
29
+ code: error.statusCode ? 'HTTP_ERROR' : 'REQUEST_FAILED',
30
+ message: error.message,
31
+ details: {
32
+ statusCode: error.statusCode || null,
33
+ command: command.name
34
+ }
35
+ },
36
+ Boolean(options.pretty)
37
+ );
38
+ process.exit(1);
39
+ }
40
+ }
41
+
42
+ module.exports = {
43
+ run: deleteContactsByContactid,
44
+ command
45
+ };
@@ -0,0 +1,45 @@
1
+ const { request } = require('../lib/client');
2
+ const output = require('../lib/output');
3
+
4
+ const command = {
5
+ "name": "get-contacts-by-contactid",
6
+ "description": "Get contact by ID",
7
+ "method": "GET",
8
+ "path": "/contacts/{contactId}",
9
+ "params": {
10
+ "contactId": {
11
+ "type": "string",
12
+ "required": true,
13
+ "description": "Contact ID"
14
+ }
15
+ }
16
+ };
17
+
18
+ async function getContactsByContactid(options) {
19
+ try {
20
+ if (command.method !== 'GET' && !options.yes) {
21
+ throw new Error('This operation changes state. Re-run with --yes to confirm.');
22
+ }
23
+
24
+ const data = await request(command, options);
25
+ output.json(data, Boolean(options.pretty));
26
+ } catch (error) {
27
+ output.error(
28
+ {
29
+ code: error.statusCode ? 'HTTP_ERROR' : 'REQUEST_FAILED',
30
+ message: error.message,
31
+ details: {
32
+ statusCode: error.statusCode || null,
33
+ command: command.name
34
+ }
35
+ },
36
+ Boolean(options.pretty)
37
+ );
38
+ process.exit(1);
39
+ }
40
+ }
41
+
42
+ module.exports = {
43
+ run: getContactsByContactid,
44
+ command
45
+ };
@@ -0,0 +1,45 @@
1
+ const { request } = require('../lib/client');
2
+ const output = require('../lib/output');
3
+
4
+ const command = {
5
+ "name": "list-contacts",
6
+ "description": "List contacts",
7
+ "method": "GET",
8
+ "path": "/contacts",
9
+ "params": {
10
+ "limit": {
11
+ "type": "number",
12
+ "required": false,
13
+ "description": "Max contacts to return"
14
+ }
15
+ }
16
+ };
17
+
18
+ async function listContacts(options) {
19
+ try {
20
+ if (command.method !== 'GET' && !options.yes) {
21
+ throw new Error('This operation changes state. Re-run with --yes to confirm.');
22
+ }
23
+
24
+ const data = await request(command, options);
25
+ output.json(data, Boolean(options.pretty));
26
+ } catch (error) {
27
+ output.error(
28
+ {
29
+ code: error.statusCode ? 'HTTP_ERROR' : 'REQUEST_FAILED',
30
+ message: error.message,
31
+ details: {
32
+ statusCode: error.statusCode || null,
33
+ command: command.name
34
+ }
35
+ },
36
+ Boolean(options.pretty)
37
+ );
38
+ process.exit(1);
39
+ }
40
+ }
41
+
42
+ module.exports = {
43
+ run: listContacts,
44
+ command
45
+ };
@@ -0,0 +1,60 @@
1
+ const { request } = require('../lib/client');
2
+ const output = require('../lib/output');
3
+
4
+ const command = {
5
+ "name": "patch-contacts-by-contactid",
6
+ "description": "Update contact fields",
7
+ "method": "PATCH",
8
+ "path": "/contacts/{contactId}",
9
+ "params": {
10
+ "contactId": {
11
+ "type": "string",
12
+ "required": true,
13
+ "description": "Contact ID"
14
+ }
15
+ },
16
+ "requestBody": {
17
+ "required": true,
18
+ "properties": {
19
+ "name": {
20
+ "type": "string",
21
+ "required": false,
22
+ "description": "Updated full name"
23
+ },
24
+ "email": {
25
+ "type": "string",
26
+ "required": false,
27
+ "description": "Updated email"
28
+ }
29
+ }
30
+ }
31
+ };
32
+
33
+ async function patchContactsByContactid(options) {
34
+ try {
35
+ if (command.method !== 'GET' && !options.yes) {
36
+ throw new Error('This operation changes state. Re-run with --yes to confirm.');
37
+ }
38
+
39
+ const data = await request(command, options);
40
+ output.json(data, Boolean(options.pretty));
41
+ } catch (error) {
42
+ output.error(
43
+ {
44
+ code: error.statusCode ? 'HTTP_ERROR' : 'REQUEST_FAILED',
45
+ message: error.message,
46
+ details: {
47
+ statusCode: error.statusCode || null,
48
+ command: command.name
49
+ }
50
+ },
51
+ Boolean(options.pretty)
52
+ );
53
+ process.exit(1);
54
+ }
55
+ }
56
+
57
+ module.exports = {
58
+ run: patchContactsByContactid,
59
+ command
60
+ };