@myapihq/cli 1.0.84 → 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 +52 -27
- 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 +75 -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 +99 -46
- 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 +93 -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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: my-workflow-api
|
|
3
|
+
description: >
|
|
4
|
+
Run actions when a webhook fires. Trigger emails, Slack notifications, or HTTP calls in response to inbound webhook deliveries — without writing a backend.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# MyWorkflowAPI
|
|
8
|
+
|
|
9
|
+
Workflows bind a list of steps to a webhook endpoint. Every time the webhook receives a POST, the workflow runs its steps in order. Each run is recorded with its status, attempt count, and any error.
|
|
10
|
+
|
|
11
|
+
## How It Fits Together
|
|
12
|
+
|
|
13
|
+
- Requires `api_key` and `org_id` from **myapihq**.
|
|
14
|
+
- Requires a webhook endpoint id from **mywebhookapi** as the trigger.
|
|
15
|
+
- Steps can reference other services — e.g. send an email via **myemailapi**.
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Create the webhook that will trigger the workflow
|
|
21
|
+
WID=$(myapi webhook create --name "leads" --json | jq -r .id)
|
|
22
|
+
|
|
23
|
+
# 2. Create a workflow bound to that webhook
|
|
24
|
+
myapi workflow create \
|
|
25
|
+
--name "Slack on new lead" \
|
|
26
|
+
--endpoint-id $WID \
|
|
27
|
+
--steps '[{"type":"slack","webhook_url":"https://hooks.slack.com/..."}]'
|
|
28
|
+
|
|
29
|
+
# 3. POST to the webhook → workflow fires
|
|
30
|
+
curl -X POST <webhook-inbound-url> -d '{"name":"Alice"}'
|
|
31
|
+
|
|
32
|
+
# 4. Inspect runs
|
|
33
|
+
myapi workflow runs <workflow_id>
|
|
34
|
+
myapi workflow get-run <run_id>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## All Commands
|
|
38
|
+
|
|
39
|
+
| Command | What it does |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `myapi workflow create` | Create a new workflow (`--name --endpoint-id --steps`) |
|
|
42
|
+
| `myapi workflow list` | List workflows in your org |
|
|
43
|
+
| `myapi workflow get <id>` | Inspect a workflow's steps + trigger config |
|
|
44
|
+
| `myapi workflow update <id>` | Change name, endpoint, or steps |
|
|
45
|
+
| `myapi workflow enable <id>` | Enable firing |
|
|
46
|
+
| `myapi workflow disable <id>` | Stop firing without deleting |
|
|
47
|
+
| `myapi workflow delete <id>` | Permanently remove workflow + run history |
|
|
48
|
+
| `myapi workflow runs <id>` | List recent runs (status, attempt, errors) |
|
|
49
|
+
| `myapi workflow get-run <run_id>` | Get full run details + step output |
|
|
50
|
+
|
|
51
|
+
## Steps
|
|
52
|
+
|
|
53
|
+
`--steps` is a JSON array of step objects. Each step has a `type` and type-specific fields.
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
[
|
|
57
|
+
{
|
|
58
|
+
"type": "send_email",
|
|
59
|
+
"from": "hello@yourdomain.com",
|
|
60
|
+
"to": "{{ payload.email }}",
|
|
61
|
+
"subject": "Welcome, {{ payload.name }}",
|
|
62
|
+
"template_id": "<template_id>"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": "http",
|
|
66
|
+
"method": "POST",
|
|
67
|
+
"url": "https://crm.example.com/contacts",
|
|
68
|
+
"body": "{{ payload | json }}"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The webhook payload is available as `{{ payload }}` and individual fields as `{{ payload.fieldname }}`.
|
|
74
|
+
|
|
75
|
+
## Lifecycle
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Create disabled, test, then enable
|
|
79
|
+
myapi workflow create --name "X" --endpoint-id $WID --steps '...' --no-enable
|
|
80
|
+
|
|
81
|
+
# Trigger via webhook POST, inspect
|
|
82
|
+
myapi workflow runs <id>
|
|
83
|
+
|
|
84
|
+
# When ready
|
|
85
|
+
myapi workflow enable <id>
|
|
86
|
+
|
|
87
|
+
# To temporarily stop
|
|
88
|
+
myapi workflow disable <id>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Notes
|
|
92
|
+
|
|
93
|
+
- Workflows fire on every webhook delivery. Failed runs don't block subsequent runs.
|
|
94
|
+
- Each run records its attempt number, started_at/finished_at, and any error.
|
|
95
|
+
- A workflow can be disabled to stop firing without losing the configuration.
|
|
96
|
+
- Deleting a workflow purges its run history; the webhook endpoint remains.
|
|
97
|
+
|
|
98
|
+
Run `myapi workflow --help` for full flag reference.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -1,36 +1,3 @@
|
|
|
1
|
-
export function parseArgs(argv) {
|
|
2
|
-
const args = [];
|
|
3
|
-
const flags = {};
|
|
4
|
-
for (let i = 0; i < argv.length; i++) {
|
|
5
|
-
const arg = argv[i];
|
|
6
|
-
if (arg === '-h') {
|
|
7
|
-
flags['help'] = true;
|
|
8
|
-
}
|
|
9
|
-
else if (arg === '-v') {
|
|
10
|
-
flags['version'] = true;
|
|
11
|
-
}
|
|
12
|
-
else if (arg.startsWith('--')) {
|
|
13
|
-
if (arg.includes('=')) {
|
|
14
|
-
const [key, value] = arg.slice(2).split('=', 2);
|
|
15
|
-
flags[key] = value;
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
const next = argv[i + 1];
|
|
19
|
-
if (next && !next.startsWith('--')) {
|
|
20
|
-
flags[arg.slice(2)] = next;
|
|
21
|
-
i++;
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
flags[arg.slice(2)] = true;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
args.push(arg);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return { args, flags };
|
|
33
|
-
}
|
|
34
1
|
export function sleep(ms) {
|
|
35
2
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
36
3
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { parseArgs } from './utils.js';
|
|
3
|
+
describe('parseArgs', () => {
|
|
4
|
+
it('treats unknown flags as boolean', () => {
|
|
5
|
+
const { args, flags } = parseArgs(['funnel', 'get', '--json', 'abc-123']);
|
|
6
|
+
expect(flags.json).toBe(true);
|
|
7
|
+
expect(args).toEqual(['funnel', 'get', 'abc-123']);
|
|
8
|
+
});
|
|
9
|
+
it('treats --yes, --help, --verbose as boolean', () => {
|
|
10
|
+
const { flags } = parseArgs(['--yes', '--help', '--verbose']);
|
|
11
|
+
expect(flags.yes).toBe(true);
|
|
12
|
+
expect(flags.help).toBe(true);
|
|
13
|
+
expect(flags.verbose).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
it('consumes next token for value flags', () => {
|
|
16
|
+
const { args, flags } = parseArgs(['org', 'create', '--name', 'Acme Inc', '--yes']);
|
|
17
|
+
expect(flags.name).toBe('Acme Inc');
|
|
18
|
+
expect(flags.yes).toBe(true);
|
|
19
|
+
expect(args).toEqual(['org', 'create']);
|
|
20
|
+
});
|
|
21
|
+
it('supports --key=value syntax for any flag', () => {
|
|
22
|
+
const { flags } = parseArgs(['--org=abc-123', '--json']);
|
|
23
|
+
expect(flags.org).toBe('abc-123');
|
|
24
|
+
expect(flags.json).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('value flag with no next token becomes boolean true', () => {
|
|
27
|
+
const { flags } = parseArgs(['--name']);
|
|
28
|
+
expect(flags.name).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
it('value flag followed by another flag does not consume it', () => {
|
|
31
|
+
const { flags } = parseArgs(['--org', '--json']);
|
|
32
|
+
expect(flags.org).toBe(true);
|
|
33
|
+
expect(flags.json).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
it('-h maps to help', () => {
|
|
36
|
+
const { flags } = parseArgs(['-h']);
|
|
37
|
+
expect(flags.help).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
it('-v maps to version', () => {
|
|
40
|
+
const { flags } = parseArgs(['-v']);
|
|
41
|
+
expect(flags.version).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
it('collects positional args correctly', () => {
|
|
44
|
+
const { args, flags } = parseArgs(['domain', 'register', 'example.com', '--org', 'uuid-here']);
|
|
45
|
+
expect(args).toEqual(['domain', 'register', 'example.com']);
|
|
46
|
+
expect(flags.org).toBe('uuid-here');
|
|
47
|
+
});
|
|
48
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myapihq/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.1.0-wip.0",
|
|
4
4
|
"description": "MyAPI command-line interface",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -13,10 +13,14 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"prebuild": "node scripts/copy-skills.js",
|
|
15
15
|
"build": "tsc && rm -rf dist/skills && cp -r src/skills dist/skills",
|
|
16
|
-
"dev": "tsc --watch"
|
|
16
|
+
"dev": "tsc --watch",
|
|
17
|
+
"test": "vitest run src",
|
|
18
|
+
"test:smoke": "npm run build && vitest run src test/smoke",
|
|
19
|
+
"test:online": "npm run build && MYAPI_RUN_RESET=1 vitest run test/online",
|
|
20
|
+
"test:all": "npm run build && MYAPI_RUN_RESET=1 vitest run src test/smoke test/online"
|
|
17
21
|
},
|
|
18
22
|
"dependencies": {
|
|
19
|
-
"@myapihq/sdk": "
|
|
23
|
+
"@myapihq/sdk": "1.1.0-wip.0",
|
|
20
24
|
"omelette": "^0.4.17",
|
|
21
25
|
"update-notifier": "^7.3.1"
|
|
22
26
|
},
|
|
@@ -24,6 +28,7 @@
|
|
|
24
28
|
"@types/node": "^25.6.0",
|
|
25
29
|
"@types/omelette": "^0.4.5",
|
|
26
30
|
"@types/update-notifier": "^6.0.8",
|
|
27
|
-
"typescript": "^5.4.0"
|
|
31
|
+
"typescript": "^5.4.0",
|
|
32
|
+
"vitest": "^4.1.5"
|
|
28
33
|
}
|
|
29
34
|
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function create(): Promise<void>;
|
|
2
|
-
export declare function token(flags: Record<string, string | boolean>): Promise<void>;
|
|
3
|
-
export declare function listKeys(flags: Record<string, string | boolean>): Promise<void>;
|
|
4
|
-
export declare function revokeKey(id: string, flags: Record<string, string | boolean>): Promise<void>;
|
package/dist/commands/account.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.create = create;
|
|
37
|
-
exports.token = token;
|
|
38
|
-
exports.listKeys = listKeys;
|
|
39
|
-
exports.revokeKey = revokeKey;
|
|
40
|
-
const sdk_1 = require("@myapihq/sdk");
|
|
41
|
-
const config_js_1 = require("../config.js");
|
|
42
|
-
const output_js_1 = require("../output.js");
|
|
43
|
-
const readline = __importStar(require("readline"));
|
|
44
|
-
async function create() {
|
|
45
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
46
|
-
const key = await new Promise(resolve => rl.question('Paste your API key (get it from https://myapihq.com): ', resolve));
|
|
47
|
-
rl.close();
|
|
48
|
-
if (!key.trim()) {
|
|
49
|
-
(0, output_js_1.error)('API key cannot be empty.');
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
(0, config_js_1.saveConfig)({ api_key: key.trim(), account_id: '', pin: '' });
|
|
53
|
-
(0, output_js_1.success)(`API key saved to ~/.myapi/config.json`);
|
|
54
|
-
}
|
|
55
|
-
async function token(flags) {
|
|
56
|
-
let pin = flags.pin;
|
|
57
|
-
if (!pin) {
|
|
58
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
59
|
-
pin = await new Promise(resolve => rl.question('Enter PIN: ', resolve));
|
|
60
|
-
rl.close();
|
|
61
|
-
}
|
|
62
|
-
const result = await sdk_1.hq.recoverAgentToken(pin);
|
|
63
|
-
const keyInfo = await sdk_1.hq.createApiKey(result.token, 'recovered');
|
|
64
|
-
const config = (0, config_js_1.requireConfig)();
|
|
65
|
-
config.api_key = keyInfo.api_key;
|
|
66
|
-
(0, config_js_1.saveConfig)(config);
|
|
67
|
-
(0, output_js_1.success)(`Token recovered! New API Key: ${keyInfo.api_key}`);
|
|
68
|
-
}
|
|
69
|
-
async function listKeys(flags) {
|
|
70
|
-
const config = (0, config_js_1.requireConfig)();
|
|
71
|
-
const keys = await sdk_1.hq.listApiKeys(config.api_key);
|
|
72
|
-
(0, output_js_1.printTable)(keys);
|
|
73
|
-
}
|
|
74
|
-
async function revokeKey(id, flags) {
|
|
75
|
-
if (!id)
|
|
76
|
-
(0, output_js_1.error)("Missing key id");
|
|
77
|
-
const config = (0, config_js_1.requireConfig)();
|
|
78
|
-
await sdk_1.hq.revokeApiKey(config.api_key, id);
|
|
79
|
-
(0, output_js_1.success)(`Key ${id} revoked`);
|
|
80
|
-
}
|