@myapihq/cli 1.0.82 → 1.1.0-wip.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/dist/commands/auth.d.ts +8 -3
- package/dist/commands/auth.js +11 -29
- package/dist/commands/billing.d.ts +8 -4
- package/dist/commands/billing.js +43 -22
- package/dist/commands/config.d.ts +8 -5
- package/dist/commands/config.js +63 -28
- package/dist/commands/domain.d.ts +12 -9
- package/dist/commands/domain.js +117 -86
- package/dist/commands/email.d.ts +4 -12
- package/dist/commands/email.js +490 -128
- package/dist/commands/funnel.d.ts +10 -7
- package/dist/commands/funnel.js +78 -55
- package/dist/commands/image.js +25 -15
- package/dist/commands/keys.d.ts +8 -3
- package/dist/commands/keys.js +67 -28
- package/dist/commands/org.d.ts +9 -5
- package/dist/commands/org.js +121 -53
- package/dist/commands/pixel.js +23 -11
- package/dist/commands/setup.d.ts +3 -2
- package/dist/commands/setup.js +44 -77
- package/dist/commands/storage.js +25 -15
- package/dist/commands/update.d.ts +2 -1
- package/dist/commands/url.js +19 -7
- package/dist/commands/webhook.d.ts +8 -5
- package/dist/commands/webhook.js +52 -36
- package/dist/commands/workflow.d.ts +13 -7
- package/dist/commands/workflow.js +158 -56
- package/dist/flags.d.ts +8 -0
- package/dist/flags.js +88 -0
- package/dist/flags.test.d.ts +1 -0
- package/dist/flags.test.js +73 -0
- package/dist/helpers.d.ts +6 -0
- package/dist/helpers.js +29 -0
- package/dist/index.js +97 -107
- package/dist/output.d.ts +10 -1
- package/dist/output.js +4 -6
- package/dist/skills/my-email-api/README.md +45 -0
- package/dist/skills/my-email-api/SKILL.md +106 -0
- package/dist/skills/my-email-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-email-api/make/.gitkeep +0 -0
- package/dist/skills/my-email-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-email-api/openapi/.gitkeep +0 -0
- package/dist/skills/my-webhook-api/README.md +40 -0
- package/dist/skills/my-webhook-api/SKILL.md +65 -0
- package/dist/skills/my-webhook-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-webhook-api/make/.gitkeep +0 -0
- package/dist/skills/my-webhook-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-webhook-api/openapi/.gitkeep +0 -0
- package/dist/skills/my-workflow-api/README.md +37 -0
- package/dist/skills/my-workflow-api/SKILL.md +98 -0
- package/dist/skills/my-workflow-api/claude/.claude-plugin/plugin.json +6 -0
- package/dist/skills/my-workflow-api/make/.gitkeep +0 -0
- package/dist/skills/my-workflow-api/n8n/.gitkeep +0 -0
- package/dist/skills/my-workflow-api/openapi/.gitkeep +0 -0
- package/dist/utils.d.ts +0 -4
- package/dist/utils.js +0 -33
- package/dist/utils.test.d.ts +1 -0
- package/dist/utils.test.js +48 -0
- package/package.json +9 -4
- package/dist/commands/account.d.ts +0 -4
- package/dist/commands/account.js +0 -80
package/dist/commands/webhook.js
CHANGED
|
@@ -1,68 +1,84 @@
|
|
|
1
1
|
import { webhook as sdkWebhook } from '@myapihq/sdk';
|
|
2
2
|
import { requireConfig } from '../config.js';
|
|
3
3
|
import { success, error, printTable, info, printJson } from '../output.js';
|
|
4
|
+
import { requireOrg } from '../helpers.js';
|
|
5
|
+
export const SCHEMA = {
|
|
6
|
+
org: 'string',
|
|
7
|
+
name: 'string',
|
|
8
|
+
description: 'string',
|
|
9
|
+
};
|
|
4
10
|
export async function list(flags) {
|
|
5
11
|
const config = requireConfig();
|
|
6
|
-
const orgId = flags
|
|
7
|
-
if (!orgId)
|
|
8
|
-
error("Missing required arguments.\nUsage: myapi webhook list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
|
|
12
|
+
const orgId = requireOrg(flags, config, 'myapi webhook list [--org <id>]');
|
|
9
13
|
const endpoints = await sdkWebhook.listEndpoints(config.api_key, orgId);
|
|
10
|
-
if (flags.json)
|
|
14
|
+
if (flags.json) {
|
|
11
15
|
printJson(endpoints);
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
printTable(endpoints, {
|
|
19
|
+
flags,
|
|
20
|
+
empty: 'No webhook endpoints yet. Create one with: myapi webhook create --name <name>',
|
|
21
|
+
});
|
|
14
22
|
}
|
|
15
23
|
export async function create(flags) {
|
|
16
24
|
const config = requireConfig();
|
|
17
|
-
const orgId = flags
|
|
25
|
+
const orgId = requireOrg(flags, config, 'myapi webhook create --name <name> [--description <desc>] [--org <id>]');
|
|
18
26
|
const name = flags.name;
|
|
27
|
+
if (!name)
|
|
28
|
+
error('Missing required arguments.\nUsage: myapi webhook create --name <name> [--description <desc>] [--org <id>]');
|
|
19
29
|
const description = flags.description;
|
|
20
|
-
if (!orgId || !name) {
|
|
21
|
-
error("Missing required arguments.\nUsage: myapi webhook create --name <name> [--description <desc>] --org <id>\n(Or set defaults via: myapi config set-org <id>)");
|
|
22
|
-
}
|
|
23
30
|
const res = await sdkWebhook.createEndpoint(config.api_key, orgId, name, description);
|
|
24
|
-
success(`Webhook created! ID: ${res.id}\nInbound URL: ${res.
|
|
31
|
+
success(`Webhook created! ID: ${res.id}\nInbound URL: ${res.url}`);
|
|
25
32
|
}
|
|
26
33
|
export async function del(id, flags) {
|
|
27
34
|
const config = requireConfig();
|
|
28
|
-
const orgId = flags
|
|
29
|
-
if (!
|
|
30
|
-
error(
|
|
35
|
+
const orgId = requireOrg(flags, config, 'myapi webhook delete <id> [--org <id>]');
|
|
36
|
+
if (!id)
|
|
37
|
+
error('Missing required arguments.\nUsage: myapi webhook delete <id> [--org <id>]');
|
|
31
38
|
await sdkWebhook.deleteEndpoint(config.api_key, orgId, id);
|
|
32
39
|
success(`Webhook ${id} deleted`);
|
|
33
40
|
}
|
|
34
41
|
export async function delivery(id, flags) {
|
|
35
42
|
const config = requireConfig();
|
|
36
|
-
const orgId = flags
|
|
37
|
-
if (!
|
|
38
|
-
error(
|
|
43
|
+
const orgId = requireOrg(flags, config, 'myapi webhook delivery <id> [--org <id>]');
|
|
44
|
+
if (!id)
|
|
45
|
+
error('Missing required arguments.\nUsage: myapi webhook delivery <id> [--org <id>]');
|
|
39
46
|
const res = await sdkWebhook.getDelivery(config.api_key, orgId, id);
|
|
40
47
|
printJson(res);
|
|
41
48
|
}
|
|
49
|
+
// ── Dispatcher ───────────────────────────────────────────────────────────────
|
|
50
|
+
const SUBCOMMAND_USAGE = {
|
|
51
|
+
'list': 'myapi webhook list [--org <id>] [--json]',
|
|
52
|
+
'create': 'myapi webhook create --name <name> [--description <desc>] [--org <id>]',
|
|
53
|
+
'delete': 'myapi webhook delete <id> [--org <id>]',
|
|
54
|
+
'delivery': 'myapi webhook delivery <delivery_id> [--org <id>]',
|
|
55
|
+
};
|
|
42
56
|
export async function run(subcommand, args, flags) {
|
|
43
57
|
if (!subcommand || (flags.help && !subcommand)) {
|
|
44
|
-
info(
|
|
58
|
+
info(`Usage: myapi webhook <subcommand>
|
|
59
|
+
|
|
60
|
+
Subcommands:
|
|
61
|
+
list List all inbound webhook endpoints
|
|
62
|
+
create Create a new endpoint to receive data (returns an inbound URL)
|
|
63
|
+
delete Delete a webhook endpoint
|
|
64
|
+
delivery Inspect a specific webhook delivery (payload, received_at)
|
|
65
|
+
|
|
66
|
+
All commands accept --org <id> (or set default: myapi config set-org <id>).`);
|
|
45
67
|
return;
|
|
46
68
|
}
|
|
47
69
|
if (flags.help) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
info('Usage: myapi webhook delete <id> --org <id>\n\nPermanently deletes the specified webhook endpoint.');
|
|
54
|
-
else if (subcommand === 'delivery')
|
|
55
|
-
info('Usage: myapi webhook delivery <delivery_id> --org <id>\n\nRetrieves the exact HTTP headers, JSON payload, and processing status of a specific received webhook. Useful for debugging inbound data.');
|
|
70
|
+
const usage = SUBCOMMAND_USAGE[subcommand];
|
|
71
|
+
if (usage)
|
|
72
|
+
info(`Usage: ${usage}`);
|
|
73
|
+
else
|
|
74
|
+
info(`Unknown subcommand: ${subcommand}. Run "myapi webhook --help" for the list.`);
|
|
56
75
|
return;
|
|
57
76
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
await delivery(args[0], flags);
|
|
66
|
-
else
|
|
67
|
-
error(`Unknown subcommand: ${subcommand}. Run "myapi webhook --help" for a list of valid subcommands.`);
|
|
77
|
+
switch (subcommand) {
|
|
78
|
+
case 'list': return list(flags);
|
|
79
|
+
case 'create': return create(flags);
|
|
80
|
+
case 'delete': return del(args[0], flags);
|
|
81
|
+
case 'delivery': return delivery(args[0], flags);
|
|
82
|
+
default: error(`Unknown subcommand: ${subcommand}. Run "myapi webhook --help" for a list of valid subcommands.`);
|
|
83
|
+
}
|
|
68
84
|
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export declare
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
6
|
-
export declare function
|
|
7
|
-
export declare function
|
|
1
|
+
import type { FlagSchema } from '../flags.js';
|
|
2
|
+
import { type Flags } from '../helpers.js';
|
|
3
|
+
export declare const SCHEMA: FlagSchema;
|
|
4
|
+
export declare function list(flags: Flags): Promise<void>;
|
|
5
|
+
export declare function get(id: string, flags: Flags): Promise<void>;
|
|
6
|
+
export declare function create(flags: Flags): Promise<void>;
|
|
7
|
+
export declare function update(id: string, flags: Flags): Promise<void>;
|
|
8
|
+
export declare function enable(id: string, flags: Flags): Promise<void>;
|
|
9
|
+
export declare function disable(id: string, flags: Flags): Promise<void>;
|
|
10
|
+
export declare function del(id: string, flags: Flags): Promise<void>;
|
|
11
|
+
export declare function runs(id: string, flags: Flags): Promise<void>;
|
|
12
|
+
export declare function getRun(runId: string, flags: Flags): Promise<void>;
|
|
13
|
+
export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
|
|
@@ -1,107 +1,209 @@
|
|
|
1
1
|
import { workflow as sdkWorkflow } from '@myapihq/sdk';
|
|
2
2
|
import { requireConfig } from '../config.js';
|
|
3
3
|
import { success, error, printTable, info, printJson } from '../output.js';
|
|
4
|
+
import { requireOrg } from '../helpers.js';
|
|
5
|
+
export const SCHEMA = {
|
|
6
|
+
org: 'string',
|
|
7
|
+
name: 'string',
|
|
8
|
+
'endpoint-id': 'string',
|
|
9
|
+
steps: 'string',
|
|
10
|
+
'no-enable': 'boolean',
|
|
11
|
+
};
|
|
12
|
+
function summarizeWorkflow(w) {
|
|
13
|
+
return {
|
|
14
|
+
id: w.id,
|
|
15
|
+
name: w.name,
|
|
16
|
+
enabled: w.enabled,
|
|
17
|
+
endpoint_id: w.trigger_config?.endpoint_id ?? '',
|
|
18
|
+
steps: Array.isArray(w.steps) ? w.steps.length : 0,
|
|
19
|
+
created_at: w.created_at,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function summarizeRun(r) {
|
|
23
|
+
return {
|
|
24
|
+
id: r.id,
|
|
25
|
+
workflow_id: r.workflow_id,
|
|
26
|
+
status: r.status,
|
|
27
|
+
attempt: r.attempt,
|
|
28
|
+
error: r.error ?? '',
|
|
29
|
+
started_at: r.started_at ?? '',
|
|
30
|
+
finished_at: r.finished_at ?? '',
|
|
31
|
+
created_at: r.created_at,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
4
34
|
export async function list(flags) {
|
|
5
35
|
const config = requireConfig();
|
|
6
|
-
const orgId = flags
|
|
7
|
-
if (!orgId)
|
|
8
|
-
error("Missing required arguments.\nUsage: myapi workflow list --org <id>\n(Or set defaults via: myapi config set-org <id>)");
|
|
36
|
+
const orgId = requireOrg(flags, config, 'myapi workflow list [--org <id>]');
|
|
9
37
|
const workflows = await sdkWorkflow.listWorkflows(config.api_key, orgId);
|
|
10
|
-
if (flags.json)
|
|
38
|
+
if (flags.json) {
|
|
11
39
|
printJson(workflows);
|
|
12
|
-
|
|
13
|
-
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
printTable(workflows.map(summarizeWorkflow), {
|
|
43
|
+
flags,
|
|
44
|
+
empty: 'No workflows yet. Create one with: myapi workflow create --name <n> --endpoint-id <id> --steps <json>',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export async function get(id, flags) {
|
|
48
|
+
const config = requireConfig();
|
|
49
|
+
const orgId = requireOrg(flags, config, 'myapi workflow get <id> [--org <id>]');
|
|
50
|
+
if (!id)
|
|
51
|
+
error('Missing required arguments.\nUsage: myapi workflow get <id> [--org <id>]');
|
|
52
|
+
const wf = await sdkWorkflow.getWorkflow(config.api_key, orgId, id);
|
|
53
|
+
printJson(wf);
|
|
14
54
|
}
|
|
15
55
|
export async function create(flags) {
|
|
16
56
|
const config = requireConfig();
|
|
17
|
-
const orgId = flags
|
|
57
|
+
const orgId = requireOrg(flags, config, 'myapi workflow create --name <name> --endpoint-id <id> --steps <json> [--no-enable] [--org <id>]');
|
|
18
58
|
const name = flags.name;
|
|
19
59
|
const endpointId = flags['endpoint-id'];
|
|
20
|
-
if (!
|
|
21
|
-
error(
|
|
60
|
+
if (!name || !endpointId || !flags.steps) {
|
|
61
|
+
error('Missing required arguments.\nUsage: myapi workflow create --name <name> --endpoint-id <id> --steps <json> [--no-enable] [--org <id>]');
|
|
22
62
|
}
|
|
23
63
|
let steps;
|
|
24
64
|
try {
|
|
25
65
|
steps = JSON.parse(flags.steps);
|
|
26
66
|
}
|
|
27
|
-
catch
|
|
28
|
-
error(
|
|
67
|
+
catch {
|
|
68
|
+
error('Invalid JSON for --steps');
|
|
29
69
|
}
|
|
30
70
|
const wf = await sdkWorkflow.createWorkflow(config.api_key, orgId, {
|
|
31
71
|
name,
|
|
32
72
|
trigger_config: { endpoint_id: endpointId },
|
|
33
|
-
steps
|
|
73
|
+
steps,
|
|
34
74
|
});
|
|
35
|
-
|
|
36
|
-
|
|
75
|
+
const shouldEnable = flags['no-enable'] !== true;
|
|
76
|
+
if (shouldEnable) {
|
|
77
|
+
await sdkWorkflow.enableWorkflow(config.api_key, orgId, wf.id);
|
|
78
|
+
success(`Workflow created and enabled! ID: ${wf.id}`);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
success(`Workflow created (disabled). ID: ${wf.id}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export async function update(id, flags) {
|
|
85
|
+
const config = requireConfig();
|
|
86
|
+
const orgId = requireOrg(flags, config, 'myapi workflow update <id> [--name <name>] [--endpoint-id <id>] [--steps <json>] [--org <id>]');
|
|
87
|
+
if (!id)
|
|
88
|
+
error('Missing required arguments.\nUsage: myapi workflow update <id> [--name <name>] [--endpoint-id <id>] [--steps <json>] [--org <id>]');
|
|
89
|
+
const payload = {};
|
|
90
|
+
if (typeof flags.name === 'string')
|
|
91
|
+
payload.name = flags.name;
|
|
92
|
+
if (typeof flags['endpoint-id'] === 'string')
|
|
93
|
+
payload.trigger_config = { endpoint_id: flags['endpoint-id'] };
|
|
94
|
+
if (typeof flags.steps === 'string') {
|
|
95
|
+
try {
|
|
96
|
+
payload.steps = JSON.parse(flags.steps);
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
error('Invalid JSON for --steps');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (!payload.name && !payload.trigger_config && !payload.steps) {
|
|
103
|
+
error('Nothing to update. Provide at least one of --name, --endpoint-id, --steps.');
|
|
104
|
+
}
|
|
105
|
+
const wf = await sdkWorkflow.updateWorkflow(config.api_key, orgId, id, payload);
|
|
106
|
+
success(`Workflow ${wf.id} updated`);
|
|
37
107
|
}
|
|
38
108
|
export async function enable(id, flags) {
|
|
39
109
|
const config = requireConfig();
|
|
40
|
-
const orgId = flags
|
|
41
|
-
if (!
|
|
42
|
-
error(
|
|
110
|
+
const orgId = requireOrg(flags, config, 'myapi workflow enable <id> [--org <id>]');
|
|
111
|
+
if (!id)
|
|
112
|
+
error('Missing required arguments.\nUsage: myapi workflow enable <id> [--org <id>]');
|
|
43
113
|
await sdkWorkflow.enableWorkflow(config.api_key, orgId, id);
|
|
44
114
|
success(`Workflow ${id} enabled`);
|
|
45
115
|
}
|
|
46
116
|
export async function disable(id, flags) {
|
|
47
117
|
const config = requireConfig();
|
|
48
|
-
const orgId = flags
|
|
49
|
-
if (!
|
|
50
|
-
error(
|
|
118
|
+
const orgId = requireOrg(flags, config, 'myapi workflow disable <id> [--org <id>]');
|
|
119
|
+
if (!id)
|
|
120
|
+
error('Missing required arguments.\nUsage: myapi workflow disable <id> [--org <id>]');
|
|
51
121
|
await sdkWorkflow.disableWorkflow(config.api_key, orgId, id);
|
|
52
122
|
success(`Disabled workflow ${id}`);
|
|
53
123
|
}
|
|
54
124
|
export async function del(id, flags) {
|
|
55
125
|
const config = requireConfig();
|
|
56
|
-
const orgId = flags
|
|
57
|
-
if (!
|
|
58
|
-
error(
|
|
126
|
+
const orgId = requireOrg(flags, config, 'myapi workflow delete <id> [--org <id>]');
|
|
127
|
+
if (!id)
|
|
128
|
+
error('Missing required arguments.\nUsage: myapi workflow delete <id> [--org <id>]');
|
|
59
129
|
await sdkWorkflow.deleteWorkflow(config.api_key, orgId, id);
|
|
60
130
|
success(`Deleted workflow ${id}`);
|
|
61
131
|
}
|
|
62
132
|
export async function runs(id, flags) {
|
|
63
133
|
const config = requireConfig();
|
|
64
|
-
const orgId = flags
|
|
65
|
-
if (!
|
|
66
|
-
error(
|
|
134
|
+
const orgId = requireOrg(flags, config, 'myapi workflow runs <id> [--org <id>]');
|
|
135
|
+
if (!id)
|
|
136
|
+
error('Missing required arguments.\nUsage: myapi workflow runs <workflow_id> [--org <id>]');
|
|
67
137
|
const wRuns = await sdkWorkflow.listWorkflowRuns(config.api_key, orgId, id);
|
|
68
|
-
if (flags.json)
|
|
138
|
+
if (flags.json) {
|
|
69
139
|
printJson(wRuns);
|
|
70
|
-
|
|
71
|
-
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
printTable(wRuns.map(summarizeRun), {
|
|
143
|
+
flags,
|
|
144
|
+
empty: 'No runs yet for this workflow.',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
export async function getRun(runId, flags) {
|
|
148
|
+
const config = requireConfig();
|
|
149
|
+
const orgId = requireOrg(flags, config, 'myapi workflow get-run <run_id> [--org <id>]');
|
|
150
|
+
if (!runId)
|
|
151
|
+
error('Missing required arguments.\nUsage: myapi workflow get-run <run_id> [--org <id>]');
|
|
152
|
+
const run = await sdkWorkflow.getWorkflowRun(config.api_key, orgId, runId);
|
|
153
|
+
printJson(run);
|
|
72
154
|
}
|
|
155
|
+
// ── Dispatcher ───────────────────────────────────────────────────────────────
|
|
156
|
+
const SUBCOMMAND_USAGE = {
|
|
157
|
+
'list': 'myapi workflow list [--org <id>] [--json]',
|
|
158
|
+
'get': 'myapi workflow get <id> [--org <id>]',
|
|
159
|
+
'create': 'myapi workflow create --name <str> --endpoint-id <id> --steps <json> [--no-enable] [--org <id>]',
|
|
160
|
+
'update': 'myapi workflow update <id> [--name <str>] [--endpoint-id <id>] [--steps <json>] [--org <id>]',
|
|
161
|
+
'enable': 'myapi workflow enable <id> [--org <id>]',
|
|
162
|
+
'disable': 'myapi workflow disable <id> [--org <id>]',
|
|
163
|
+
'delete': 'myapi workflow delete <id> [--org <id>]',
|
|
164
|
+
'runs': 'myapi workflow runs <workflow_id> [--org <id>] [--json]',
|
|
165
|
+
'get-run': 'myapi workflow get-run <run_id> [--org <id>]',
|
|
166
|
+
};
|
|
73
167
|
export async function run(subcommand, args, flags) {
|
|
74
168
|
if (!subcommand || (flags.help && !subcommand)) {
|
|
75
|
-
info(
|
|
169
|
+
info(`Usage: myapi workflow <subcommand>
|
|
170
|
+
|
|
171
|
+
Subcommands:
|
|
172
|
+
list List all workflows
|
|
173
|
+
get <id> Show a single workflow
|
|
174
|
+
create Create a workflow (enabled by default; --no-enable to stage)
|
|
175
|
+
update <id> Patch name / endpoint-id / steps
|
|
176
|
+
enable <id> Enable a workflow
|
|
177
|
+
disable <id> Disable a workflow
|
|
178
|
+
delete <id> Delete a workflow
|
|
179
|
+
runs <workflow_id> List recent executions of a workflow
|
|
180
|
+
get-run <run_id> Show a single run with full payload
|
|
181
|
+
|
|
182
|
+
Step types for --steps:
|
|
183
|
+
send_email {"type":"send_email","from":"<mailbox>","to":"{{payload.email}}","subject":"...","template_id":"<id>"|"html":"..."}
|
|
184
|
+
slack_message {"type":"slack_message","webhook_url":"https://hooks.slack.com/...","text":"...{{payload.field}}..."}
|
|
185
|
+
|
|
186
|
+
All commands accept --org <id> (or set default: myapi config set-org <id>).`);
|
|
76
187
|
return;
|
|
77
188
|
}
|
|
78
189
|
if (flags.help) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
info('Usage: myapi workflow enable <id> --org <id>\n\nActivates a disabled workflow so it begins listening to its webhook trigger again.');
|
|
85
|
-
else if (subcommand === 'disable')
|
|
86
|
-
info('Usage: myapi workflow disable <id> --org <id>\n\nPauses a workflow. The attached webhook will still accept data, but the workflow steps will not execute.');
|
|
87
|
-
else if (subcommand === 'delete')
|
|
88
|
-
info('Usage: myapi workflow delete <id> --org <id>\n\nDeletes the workflow permanently.');
|
|
89
|
-
else if (subcommand === 'runs')
|
|
90
|
-
info('Usage: myapi workflow runs <workflow_id> --org <id> [--json]\n\nLists the 100 most recent executions of the specified workflow, including completion status and any error messages.');
|
|
190
|
+
const usage = SUBCOMMAND_USAGE[subcommand];
|
|
191
|
+
if (usage)
|
|
192
|
+
info(`Usage: ${usage}`);
|
|
193
|
+
else
|
|
194
|
+
info(`Unknown subcommand: ${subcommand}. Run "myapi workflow --help" for the list.`);
|
|
91
195
|
return;
|
|
92
196
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
else
|
|
106
|
-
error(`Unknown subcommand: ${subcommand}. Run "myapi workflow --help" for a list of valid subcommands.`);
|
|
197
|
+
switch (subcommand) {
|
|
198
|
+
case 'list': return list(flags);
|
|
199
|
+
case 'get': return get(args[0], flags);
|
|
200
|
+
case 'create': return create(flags);
|
|
201
|
+
case 'update': return update(args[0], flags);
|
|
202
|
+
case 'enable': return enable(args[0], flags);
|
|
203
|
+
case 'disable': return disable(args[0], flags);
|
|
204
|
+
case 'delete': return del(args[0], flags);
|
|
205
|
+
case 'runs': return runs(args[0], flags);
|
|
206
|
+
case 'get-run': return getRun(args[0], flags);
|
|
207
|
+
default: error(`Unknown subcommand: ${subcommand}. Run "myapi workflow --help" for a list of valid subcommands.`);
|
|
208
|
+
}
|
|
107
209
|
}
|
package/dist/flags.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type FlagType = 'string' | 'boolean' | 'number';
|
|
2
|
+
export type FlagSchema = Record<string, FlagType>;
|
|
3
|
+
export declare const GLOBAL_FLAGS: FlagSchema;
|
|
4
|
+
export interface ParsedArgs {
|
|
5
|
+
args: string[];
|
|
6
|
+
flags: Record<string, string | boolean | number>;
|
|
7
|
+
}
|
|
8
|
+
export declare function parseFlags(argv: string[], schema?: FlagSchema): ParsedArgs;
|
package/dist/flags.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Per-command flag schemas. Each command file owns its own schema and passes
|
|
2
|
+
// it to `parseFlags`, which knows whether `--foo` consumes the next token.
|
|
3
|
+
//
|
|
4
|
+
// This replaces the global VALUE_FLAGS allowlist that previously lived in
|
|
5
|
+
// utils.ts — adding a new value flag without registering it would silently
|
|
6
|
+
// turn it into a boolean (e.g. `--html '<p>'` becoming `flags.html === true`).
|
|
7
|
+
// Flags every command understands.
|
|
8
|
+
export const GLOBAL_FLAGS = {
|
|
9
|
+
help: 'boolean',
|
|
10
|
+
json: 'boolean',
|
|
11
|
+
verbose: 'boolean',
|
|
12
|
+
yes: 'boolean',
|
|
13
|
+
y: 'boolean',
|
|
14
|
+
};
|
|
15
|
+
export function parseFlags(argv, schema = {}) {
|
|
16
|
+
const merged = { ...GLOBAL_FLAGS, ...schema };
|
|
17
|
+
const args = [];
|
|
18
|
+
const flags = {};
|
|
19
|
+
for (let i = 0; i < argv.length; i++) {
|
|
20
|
+
const arg = argv[i];
|
|
21
|
+
if (arg === '-h') {
|
|
22
|
+
flags.help = true;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (arg === '-v') {
|
|
26
|
+
flags.version = true;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (arg === '--') {
|
|
30
|
+
// Everything after `--` is positional.
|
|
31
|
+
args.push(...argv.slice(i + 1));
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
if (arg.startsWith('--')) {
|
|
35
|
+
let key;
|
|
36
|
+
let inlineValue;
|
|
37
|
+
if (arg.includes('=')) {
|
|
38
|
+
const eq = arg.indexOf('=');
|
|
39
|
+
key = arg.slice(2, eq);
|
|
40
|
+
inlineValue = arg.slice(eq + 1);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
key = arg.slice(2);
|
|
44
|
+
}
|
|
45
|
+
const type = merged[key];
|
|
46
|
+
// Unknown flags: tolerate as boolean (with --key=value still honored)
|
|
47
|
+
// so additions to the schema don't silently break someone's script.
|
|
48
|
+
if (type === undefined) {
|
|
49
|
+
flags[key] = inlineValue ?? true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (type === 'boolean') {
|
|
53
|
+
if (inlineValue !== undefined) {
|
|
54
|
+
flags[key] = inlineValue !== 'false' && inlineValue !== '0';
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
flags[key] = true;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Value flag (string | number).
|
|
62
|
+
let raw = inlineValue;
|
|
63
|
+
if (raw === undefined) {
|
|
64
|
+
const next = argv[i + 1];
|
|
65
|
+
if (next !== undefined && !next.startsWith('--')) {
|
|
66
|
+
raw = next;
|
|
67
|
+
i++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (raw === undefined) {
|
|
71
|
+
// Value flag with no value — keep as boolean true so callers can
|
|
72
|
+
// detect "they tried to pass it" and surface a helpful usage error.
|
|
73
|
+
flags[key] = true;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (type === 'number') {
|
|
77
|
+
const n = Number(raw);
|
|
78
|
+
flags[key] = isNaN(n) ? raw : n;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
flags[key] = raw;
|
|
82
|
+
}
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
args.push(arg);
|
|
86
|
+
}
|
|
87
|
+
return { args, flags };
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseFlags } from './flags.js';
|
|
3
|
+
const SCHEMA = {
|
|
4
|
+
org: 'string',
|
|
5
|
+
name: 'string',
|
|
6
|
+
years: 'number',
|
|
7
|
+
'no-enable': 'boolean',
|
|
8
|
+
};
|
|
9
|
+
describe('parseFlags', () => {
|
|
10
|
+
it('treats unknown flags as boolean by default (forward-compatible)', () => {
|
|
11
|
+
const { args, flags } = parseFlags(['funnel', 'get', '--json', 'abc-123'], SCHEMA);
|
|
12
|
+
expect(flags.json).toBe(true);
|
|
13
|
+
expect(args).toEqual(['funnel', 'get', 'abc-123']);
|
|
14
|
+
});
|
|
15
|
+
it('treats global booleans (--yes, --help, --verbose) as boolean', () => {
|
|
16
|
+
const { flags } = parseFlags(['--yes', '--help', '--verbose'], SCHEMA);
|
|
17
|
+
expect(flags.yes).toBe(true);
|
|
18
|
+
expect(flags.help).toBe(true);
|
|
19
|
+
expect(flags.verbose).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
it('consumes the next token for declared string flags', () => {
|
|
22
|
+
const { args, flags } = parseFlags(['org', 'create', '--name', 'Acme Inc', '--yes'], SCHEMA);
|
|
23
|
+
expect(flags.name).toBe('Acme Inc');
|
|
24
|
+
expect(flags.yes).toBe(true);
|
|
25
|
+
expect(args).toEqual(['org', 'create']);
|
|
26
|
+
});
|
|
27
|
+
it('supports --key=value for any flag', () => {
|
|
28
|
+
const { flags } = parseFlags(['--org=abc-123', '--json'], SCHEMA);
|
|
29
|
+
expect(flags.org).toBe('abc-123');
|
|
30
|
+
expect(flags.json).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it('declared string flag with no next token becomes boolean true', () => {
|
|
33
|
+
const { flags } = parseFlags(['--name'], SCHEMA);
|
|
34
|
+
expect(flags.name).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
it('declared string flag followed by another flag does not consume it', () => {
|
|
37
|
+
const { flags } = parseFlags(['--org', '--json'], SCHEMA);
|
|
38
|
+
expect(flags.org).toBe(true);
|
|
39
|
+
expect(flags.json).toBe(true);
|
|
40
|
+
});
|
|
41
|
+
it('-h maps to help', () => {
|
|
42
|
+
const { flags } = parseFlags(['-h'], SCHEMA);
|
|
43
|
+
expect(flags.help).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
it('-v maps to version', () => {
|
|
46
|
+
const { flags } = parseFlags(['-v'], SCHEMA);
|
|
47
|
+
expect(flags.version).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it('collects positional args correctly', () => {
|
|
50
|
+
const { args, flags } = parseFlags(['domain', 'register', 'example.com', '--org', 'uuid-here'], SCHEMA);
|
|
51
|
+
expect(args).toEqual(['domain', 'register', 'example.com']);
|
|
52
|
+
expect(flags.org).toBe('uuid-here');
|
|
53
|
+
});
|
|
54
|
+
it('parses declared number flags as numbers', () => {
|
|
55
|
+
const { flags } = parseFlags(['--years', '3'], SCHEMA);
|
|
56
|
+
expect(flags.years).toBe(3);
|
|
57
|
+
expect(typeof flags.years).toBe('number');
|
|
58
|
+
});
|
|
59
|
+
it('declared boolean flag does not consume next token', () => {
|
|
60
|
+
const { args, flags } = parseFlags(['--no-enable', 'abc'], SCHEMA);
|
|
61
|
+
expect(flags['no-enable']).toBe(true);
|
|
62
|
+
expect(args).toEqual(['abc']);
|
|
63
|
+
});
|
|
64
|
+
it('-- terminator: everything after is positional', () => {
|
|
65
|
+
const { args, flags } = parseFlags(['--name', 'X', '--', '--not-a-flag', 'y'], SCHEMA);
|
|
66
|
+
expect(flags.name).toBe('X');
|
|
67
|
+
expect(args).toEqual(['--not-a-flag', 'y']);
|
|
68
|
+
});
|
|
69
|
+
it('unknown --key=value preserved as a string (not silently lost)', () => {
|
|
70
|
+
const { flags } = parseFlags(['--mystery=42'], SCHEMA);
|
|
71
|
+
expect(flags.mystery).toBe('42');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Config } from './config.js';
|
|
2
|
+
export type Flags = Record<string, string | boolean | number>;
|
|
3
|
+
export declare function requireOrg(flags: Flags, config: Config, usage: string): string;
|
|
4
|
+
export declare function requireDomain(arg: string | undefined, flags: Flags, config: Config, usage: string): string;
|
|
5
|
+
export declare function requireArg(value: string | undefined, name: string, usage: string): string;
|
|
6
|
+
export declare function requireFlag(flags: Flags, name: string, usage: string): string;
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { error } from './output.js';
|
|
2
|
+
// Resolve org id from --org or the configured default. On miss, exit with a
|
|
3
|
+
// usage-aware error that points the user at both the flag and the config command.
|
|
4
|
+
export function requireOrg(flags, config, usage) {
|
|
5
|
+
const orgId = flags.org || config.default_org;
|
|
6
|
+
if (!orgId || typeof orgId !== 'string') {
|
|
7
|
+
error(`Missing required arguments.\nUsage: ${usage}\n(Or set default: myapi config set-org <id>)`);
|
|
8
|
+
}
|
|
9
|
+
return orgId;
|
|
10
|
+
}
|
|
11
|
+
export function requireDomain(arg, flags, config, usage) {
|
|
12
|
+
const domain = arg || flags.domain || config.default_domain;
|
|
13
|
+
if (!domain || typeof domain !== 'string') {
|
|
14
|
+
error(`Missing required arguments.\nUsage: ${usage}\n(Or set default: myapi config set-domain <domain>)`);
|
|
15
|
+
}
|
|
16
|
+
return domain;
|
|
17
|
+
}
|
|
18
|
+
export function requireArg(value, name, usage) {
|
|
19
|
+
if (!value)
|
|
20
|
+
error(`Missing required argument: ${name}.\nUsage: ${usage}`);
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
export function requireFlag(flags, name, usage) {
|
|
24
|
+
const v = flags[name];
|
|
25
|
+
if (v === undefined || v === true || v === false || v === '') {
|
|
26
|
+
error(`Missing required flag: --${name}.\nUsage: ${usage}`);
|
|
27
|
+
}
|
|
28
|
+
return String(v);
|
|
29
|
+
}
|