api-to-cli 0.1.1 → 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 (64) hide show
  1. package/README.md +153 -9
  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 +9 -5
  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
  63. package/PROJECT_BRIEF.md +0 -65
  64. package/SPEC.md +0 -99
@@ -0,0 +1,244 @@
1
+ const fs = require('fs');
2
+
3
+ function toKebab(name) {
4
+ return String(name)
5
+ .trim()
6
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
7
+ .toLowerCase()
8
+ .replace(/[^a-z0-9]+/g, '-')
9
+ .replace(/^-+|-+$/g, '');
10
+ }
11
+
12
+ function toCamelCase(name) {
13
+ return String(name).replace(/[-_]+([a-zA-Z0-9])/g, (_m, g1) => g1.toUpperCase());
14
+ }
15
+
16
+ function readOption(options, name) {
17
+ if (Object.prototype.hasOwnProperty.call(options, name)) {
18
+ return options[name];
19
+ }
20
+
21
+ const camel = toCamelCase(name);
22
+ if (Object.prototype.hasOwnProperty.call(options, camel)) {
23
+ return options[camel];
24
+ }
25
+
26
+ return undefined;
27
+ }
28
+
29
+ function coerceValue(value, type) {
30
+ if (value === undefined || value === null || value === '') {
31
+ return value;
32
+ }
33
+
34
+ if (type === 'number') {
35
+ const parsed = Number(value);
36
+ if (Number.isNaN(parsed)) {
37
+ throw new Error(`Expected number but received: ${value}`);
38
+ }
39
+ return parsed;
40
+ }
41
+
42
+ if (type === 'boolean') {
43
+ if (typeof value === 'boolean') {
44
+ return value;
45
+ }
46
+
47
+ const normalized = String(value).toLowerCase();
48
+ if (normalized === 'true' || normalized === '1') {
49
+ return true;
50
+ }
51
+
52
+ if (normalized === 'false' || normalized === '0') {
53
+ return false;
54
+ }
55
+
56
+ throw new Error(`Expected boolean but received: ${value}`);
57
+ }
58
+
59
+ return String(value);
60
+ }
61
+
62
+ function parseJsonText(raw, label) {
63
+ try {
64
+ return JSON.parse(raw);
65
+ } catch (_error) {
66
+ throw new Error(`Invalid JSON for ${label}`);
67
+ }
68
+ }
69
+
70
+ function parseJsonBody(rawBody) {
71
+ if (rawBody === undefined || rawBody === null || rawBody === '') {
72
+ return null;
73
+ }
74
+
75
+ return parseJsonText(rawBody, '--body');
76
+ }
77
+
78
+ function parseBodyFromStdin(enabled) {
79
+ if (!enabled) {
80
+ return null;
81
+ }
82
+
83
+ const raw = fs.readFileSync(0, 'utf8').trim();
84
+ if (!raw) {
85
+ throw new Error('Expected JSON on stdin because --body-stdin was provided');
86
+ }
87
+
88
+ return parseJsonText(raw, '--body-stdin');
89
+ }
90
+
91
+ function buildRequestBody(command, options) {
92
+ const requestBody = command.requestBody || null;
93
+ if (!requestBody) {
94
+ return null;
95
+ }
96
+
97
+ const direct = parseJsonBody(readOption(options, 'body'));
98
+ const stdin = parseBodyFromStdin(Boolean(readOption(options, 'body-stdin')));
99
+
100
+ if (direct !== null && stdin !== null) {
101
+ throw new Error('Use either --body or --body-stdin, not both');
102
+ }
103
+
104
+ const properties = requestBody.properties || {};
105
+ const hasBodyProps = Object.keys(properties).length > 0;
106
+
107
+ let payload = direct !== null ? direct : stdin !== null ? stdin : hasBodyProps ? {} : null;
108
+ if (payload !== null && (typeof payload !== 'object' || Array.isArray(payload))) {
109
+ throw new Error('Request body must be a JSON object');
110
+ }
111
+
112
+ if (payload === null && requestBody.required) {
113
+ throw new Error('Missing required request body. Provide --body, --body-stdin, or body field flags.');
114
+ }
115
+
116
+ let hadBodyFlag = false;
117
+ Object.entries(properties).forEach(([propName, schema]) => {
118
+ const optionName = `body-${toKebab(propName)}`;
119
+ const raw = readOption(options, optionName);
120
+ if (raw === undefined || raw === null || raw === '') {
121
+ return;
122
+ }
123
+
124
+ if (payload === null) {
125
+ payload = {};
126
+ }
127
+
128
+ payload[propName] = coerceValue(raw, schema.type);
129
+ hadBodyFlag = true;
130
+ });
131
+
132
+ if (hasBodyProps) {
133
+ if (payload === null) {
134
+ payload = {};
135
+ }
136
+
137
+ Object.entries(properties).forEach(([propName, schema]) => {
138
+ if (!schema.required) {
139
+ return;
140
+ }
141
+
142
+ if (!Object.prototype.hasOwnProperty.call(payload, propName) || payload[propName] === undefined || payload[propName] === null || payload[propName] === '') {
143
+ const optionName = `--body-${toKebab(propName)}`;
144
+ throw new Error(`Missing required request body field: ${optionName}`);
145
+ }
146
+ });
147
+ }
148
+
149
+ if (payload !== null) {
150
+ const isEmptyObject = typeof payload === 'object' && !Array.isArray(payload) && Object.keys(payload).length === 0;
151
+ if (isEmptyObject && !requestBody.required && !hadBodyFlag && direct === null && stdin === null) {
152
+ return null;
153
+ }
154
+ }
155
+
156
+ return payload;
157
+ }
158
+
159
+ async function request(command, options) {
160
+ const auth = {
161
+ "credentials": []
162
+ };
163
+ const params = new URLSearchParams();
164
+ const commandParams = command.params || {};
165
+ let resolvedPath = command.path;
166
+ const headers = {
167
+ accept: 'application/json'
168
+ };
169
+
170
+ (auth.credentials || []).forEach((credential) => {
171
+ const envValue = process.env[credential.envVar];
172
+
173
+ if (!envValue) {
174
+ throw new Error(`Missing required auth environment variable: ${credential.envVar}`);
175
+ }
176
+
177
+ const authValue = credential.prefix ? `${credential.prefix}${envValue}` : envValue;
178
+
179
+ if (credential.in === 'header') {
180
+ headers[credential.name] = authValue;
181
+ return;
182
+ }
183
+
184
+ params.append(credential.name, authValue);
185
+ });
186
+
187
+ Object.entries(commandParams).forEach(([name, schema]) => {
188
+ const raw = readOption(options, name);
189
+
190
+ if ((raw === undefined || raw === null || raw === '') && schema.required) {
191
+ throw new Error(`Missing required parameter: --${name}`);
192
+ }
193
+
194
+ if (raw === undefined || raw === null || raw === '') {
195
+ return;
196
+ }
197
+
198
+ const value = coerceValue(raw, schema.type);
199
+ const token = `{${name}}`;
200
+
201
+ if (resolvedPath.includes(token)) {
202
+ resolvedPath = resolvedPath.replaceAll(token, encodeURIComponent(String(value)));
203
+ return;
204
+ }
205
+
206
+ params.append(name, String(value));
207
+ });
208
+
209
+ const query = params.toString();
210
+ const url = 'https://api.example-crm.com/v1' + resolvedPath + (query ? '?' + query : '');
211
+ const requestBody = buildRequestBody(command, options);
212
+
213
+ if (requestBody !== null) {
214
+ headers['content-type'] = 'application/json';
215
+ }
216
+
217
+ const response = await fetch(url, {
218
+ method: command.method,
219
+ headers,
220
+ body: requestBody !== null ? JSON.stringify(requestBody) : undefined
221
+ });
222
+
223
+ const text = await response.text();
224
+ let responseBody = text;
225
+
226
+ try {
227
+ responseBody = text ? JSON.parse(text) : null;
228
+ } catch (_err) {
229
+ responseBody = text;
230
+ }
231
+
232
+ if (!response.ok) {
233
+ const error = new Error(`HTTP ${response.status}`);
234
+ error.statusCode = response.status;
235
+ error.responseBody = responseBody;
236
+ throw error;
237
+ }
238
+
239
+ return responseBody;
240
+ }
241
+
242
+ module.exports = {
243
+ request
244
+ };
@@ -0,0 +1,21 @@
1
+ function json(data, pretty) {
2
+ const text = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
3
+ process.stdout.write(text + '\n');
4
+ }
5
+
6
+ function error(payload, pretty) {
7
+ const envelope = {
8
+ error: true,
9
+ code: payload.code || 'REQUEST_FAILED',
10
+ message: payload.message || 'Request failed',
11
+ details: payload.details || {}
12
+ };
13
+
14
+ const text = pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope);
15
+ process.stderr.write(text + '\n');
16
+ }
17
+
18
+ module.exports = {
19
+ json,
20
+ error
21
+ };
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "sample-crm-api-cli",
3
+ "version": "1.0.0",
4
+ "description": "sample-crm-api CLI generated by AgentBridge",
5
+ "license": "MIT",
6
+ "type": "commonjs",
7
+ "bin": {
8
+ "sample-crm-api": "./bin/sample-crm-api.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node ./bin/sample-crm-api.js"
12
+ },
13
+ "dependencies": {
14
+ "commander": "^12.1.0"
15
+ }
16
+ }
@@ -0,0 +1,50 @@
1
+ # sample-crm-api CLI Skill
2
+
3
+ ## Purpose
4
+ Use the generated sample-crm-api CLI from AgentBridge. Always prefer JSON output for machine parsing.
5
+
6
+ ## Location
7
+ - CLI project: ./cli
8
+ - Binary name: sample-crm-api
9
+
10
+ ## Setup
11
+ 1. cd ./cli
12
+ 2. npm install
13
+ 3. npm link
14
+
15
+ ## Auth
16
+ - No auth env vars required
17
+
18
+ ## Commands
19
+ - list-contacts: List contacts
20
+ - --limit <value> (optional)
21
+ - example: sample-crm-api list-contacts --limit <value>
22
+ - create-contact: Create contact
23
+ - --yes (required for non-GET operations)
24
+ - --body <json> (raw JSON body fallback)
25
+ - --body-stdin (read JSON body from stdin)
26
+ - --body-name <value> (required)
27
+ - --body-email <value> (optional)
28
+ - --body-subscribed <value> (optional)
29
+ - example: sample-crm-api create-contact --yes --body-name <value> --body-email <value> --body-subscribed <value> --body '{"key":"value"}'
30
+ - get-contacts-by-contactid: Get contact by ID
31
+ - --contact-id <value> (required)
32
+ - example: sample-crm-api get-contacts-by-contactid --contact-id <value>
33
+ - patch-contacts-by-contactid: Update contact fields
34
+ - --contact-id <value> (required)
35
+ - --yes (required for non-GET operations)
36
+ - --body <json> (raw JSON body fallback)
37
+ - --body-stdin (read JSON body from stdin)
38
+ - --body-name <value> (optional)
39
+ - --body-email <value> (optional)
40
+ - example: sample-crm-api patch-contacts-by-contactid --contact-id <value> --yes --body-name <value> --body-email <value> --body '{"key":"value"}'
41
+ - delete-contacts-by-contactid: Delete contact
42
+ - --contact-id <value> (required)
43
+ - --yes (required for non-GET operations)
44
+ - example: sample-crm-api delete-contacts-by-contactid --contact-id <value> --yes
45
+
46
+ ## Rules
47
+ - Do not echo or log auth secrets.
48
+ - Do not pass credentials as command flags.
49
+ - Parse command stdout as JSON.
50
+ - Treat non-zero exits as failure and read stderr JSON envelope.
@@ -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
+ };