@eventpipe/cli 0.2.1 → 0.2.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.
- package/README.md +140 -40
- package/dist/cli.js +15 -6
- package/dist/publish.d.ts +9 -1
- package/dist/publish.js +28 -14
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,79 +1,179 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Event Pipe CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official command-line tool for **[Event Pipe](https://eventpipe.app)** — bundle code nodes with [esbuild](https://esbuild.github.io/), **publish new pipeline versions**, create webhook endpoints, and stream events to your machine.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**Website:** [eventpipe.app](https://eventpipe.app) · **npm:** [`@eventpipe/cli`](https://www.npmjs.com/package/@eventpipe/cli)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What you can do
|
|
10
|
+
|
|
11
|
+
| Area | What the CLI does |
|
|
12
|
+
|------|-------------------|
|
|
13
|
+
| **Publish** | Run **`eventpipe push`** after **`eventpipe login`** to upload a new pipeline version (same API as Pipe Studio). |
|
|
14
|
+
| **CI** | Set **`EVENTPIPE_API_KEY`** so **`push`** works without a browser. |
|
|
15
|
+
| **Webhooks** | **`create`** endpoints and **`listen`** to the relay (with optional **`--forward-to`** for local replay). |
|
|
16
|
+
| **Tooling** | **`eventpipe update`**, **`--version`**, and optional npm version hints on stderr. |
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- **Node.js 20 or newer** ([nodejs.org](https://nodejs.org))
|
|
23
|
+
- An Event Pipe account ([sign up](https://eventpipe.app))
|
|
24
|
+
- For **`push`**: a **pipeline** already created in the app, and its **`pipelineId`** (UUID) in **`eventpipe.json`**
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### Global (recommended)
|
|
6
31
|
|
|
7
32
|
```bash
|
|
8
|
-
|
|
9
|
-
# or: npm i -D @eventpipe/cli
|
|
33
|
+
npm install -g @eventpipe/cli
|
|
10
34
|
```
|
|
11
35
|
|
|
12
|
-
|
|
36
|
+
This provides **`eventpipe`** and **`eventpipe-cli`** on your `PATH`.
|
|
37
|
+
|
|
38
|
+
### Per project
|
|
13
39
|
|
|
14
40
|
```bash
|
|
15
|
-
npm
|
|
41
|
+
npm add -D @eventpipe/cli
|
|
16
42
|
```
|
|
17
43
|
|
|
18
|
-
|
|
44
|
+
Run with **`npx eventpipe …`** or npm scripts.
|
|
45
|
+
|
|
46
|
+
### Install scripts (from a clone of this repo)
|
|
47
|
+
|
|
48
|
+
**macOS / Linux:** `bash install/macos.sh`
|
|
49
|
+
**Windows (PowerShell):** `Set-ExecutionPolicy -Scope Process Bypass; .\install\windows.ps1`
|
|
50
|
+
|
|
51
|
+
### Develop from source
|
|
19
52
|
|
|
20
53
|
```bash
|
|
21
|
-
|
|
54
|
+
git clone <repo-url> && cd eventpipe-cli
|
|
55
|
+
pnpm install && pnpm run build
|
|
56
|
+
node dist/cli.js --help
|
|
22
57
|
```
|
|
23
58
|
|
|
24
|
-
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Publishing pipeline versions (`build` + `push`)
|
|
62
|
+
|
|
63
|
+
Publishing creates a **new immutable version** of your pipeline by calling **`POST /api/account/pipelines/{pipelineId}/versions`** with bundled code — the same endpoint the [web app](https://eventpipe.app) uses.
|
|
64
|
+
|
|
65
|
+
### 1. Get `pipelineId`
|
|
66
|
+
|
|
67
|
+
In **Pipe Studio**, open your pipeline and copy its **UUID** from the URL or settings.
|
|
68
|
+
|
|
69
|
+
### 2. Add `eventpipe.json` (minimal single code node)
|
|
25
70
|
|
|
26
|
-
|
|
27
|
-
|
|
71
|
+
The **`code`** node id in **`settings.pipe`** must match the code node you bundle (default file: **`src/handler.ts`**).
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"pipelineId": "YOUR_PIPELINE_UUID",
|
|
76
|
+
"settings": {
|
|
77
|
+
"pipe": {
|
|
78
|
+
"schemaVersion": 3,
|
|
79
|
+
"nodes": [
|
|
80
|
+
{ "id": "code", "type": "code", "config": {} }
|
|
81
|
+
],
|
|
82
|
+
"edges": []
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Handler entry (`src/handler.ts`)
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
type FlowEvent = {
|
|
92
|
+
method: string;
|
|
93
|
+
headers: Record<string, string>;
|
|
94
|
+
body: unknown;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
type FlowContext = { env?: Record<string, string> };
|
|
98
|
+
|
|
99
|
+
export async function handler(event: FlowEvent, _context: FlowContext) {
|
|
100
|
+
return { ok: true, received: event.body };
|
|
101
|
+
}
|
|
28
102
|
```
|
|
29
103
|
|
|
30
|
-
|
|
104
|
+
In production, secrets are read from **`context.env`** (set in the app **Event** tab), not from `process.env` inside the bundle.
|
|
105
|
+
|
|
106
|
+
### 4. Sign in and push
|
|
31
107
|
|
|
32
108
|
```bash
|
|
33
|
-
|
|
34
|
-
|
|
109
|
+
eventpipe login
|
|
110
|
+
eventpipe push
|
|
35
111
|
```
|
|
36
112
|
|
|
37
|
-
|
|
113
|
+
- **`login`** opens the browser and saves session under **`~/.eventpipe/credentials.json`**. Default app is **`https://eventpipe.app`** (override with **`EVENTPIPE_BASE_URL`** for self-hosted).
|
|
114
|
+
- **`push`** runs **`build`** then uploads bundles. If **`EVENTPIPE_API_KEY`** is set, it is used **instead of** session (typical for **CI**).
|
|
38
115
|
|
|
39
|
-
|
|
40
|
-
|------|---------|
|
|
41
|
-
| `eventpipe.json` | `pipelineId`, optional `nodeId` / `entry`, and `settings` (must include `pipe` v3) |
|
|
42
|
-
| `src/handler.ts` | Default entry — `export async function handler(event, context)` |
|
|
116
|
+
### CI example
|
|
43
117
|
|
|
44
|
-
|
|
118
|
+
```bash
|
|
119
|
+
export EVENTPIPE_API_KEY=evp_xxxxxxxx
|
|
120
|
+
# optional for self-hosted: export EVENTPIPE_BASE_URL=https://your-app.example.com
|
|
121
|
+
eventpipe push --dir ./my-flow
|
|
122
|
+
```
|
|
45
123
|
|
|
46
|
-
|
|
124
|
+
### Override pipeline id
|
|
47
125
|
|
|
48
|
-
|
|
126
|
+
```bash
|
|
127
|
+
eventpipe push --pipeline <uuid>
|
|
128
|
+
# alias: --flow <uuid>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
49
132
|
|
|
50
|
-
|
|
51
|
-
- **`create [--name <slug>]`** — `POST /api/account/endpoints` (session auth). `--name` sets the URL slug (`/api/webhook/your-slug`) if it’s free; otherwise a random id is used. With no `--name`, the URL and display label are random.
|
|
52
|
-
- **`listen <webhookId> [options]`** — Connects to the relay; prints one line per webhook. **`--verbose` / `-v`** prints the full event JSON (method, headers, query, body). **`--json`** prints one JSON object per line (stdout) for scripts. **`--forward-to http://127.0.0.1:PORT/path`** replays each request to your local server (forward status on stderr).
|
|
133
|
+
## Other commands (summary)
|
|
53
134
|
|
|
54
|
-
|
|
135
|
+
| Command | Purpose |
|
|
136
|
+
|---------|---------|
|
|
137
|
+
| **`eventpipe login`** | Browser sign-in; stores session. |
|
|
138
|
+
| **`eventpipe create [--name <slug>]`** | New webhook endpoint (requires login). |
|
|
139
|
+
| **`eventpipe listen <id> [--json] [-v] [--forward-to <url>]`** | Stream webhooks from the relay. |
|
|
140
|
+
| **`eventpipe build [--dir <path>]`** | Esbuild → `.eventpipe/`; prints size and hash (max **200KB** per bundle). |
|
|
141
|
+
| **`eventpipe update`** | Runs **`npm install -g @eventpipe/cli@latest`**. |
|
|
142
|
+
| **`eventpipe -v` / `--version`** | Print CLI version. |
|
|
143
|
+
| **`eventpipe help`** | Built-in usage. |
|
|
55
144
|
|
|
56
|
-
|
|
57
|
-
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Project layout
|
|
58
148
|
|
|
59
|
-
|
|
149
|
+
| File / folder | Role |
|
|
150
|
+
|---------------|------|
|
|
151
|
+
| **`eventpipe.json`** | **`pipelineId`**, **`settings.pipe`** (v3), optional **`nodeId`**, **`entry`**, or **`codeNodes`** for multi-file graphs. |
|
|
152
|
+
| **`src/handler.ts`** | Default entry when **`entry`** is omitted. |
|
|
153
|
+
| **`.eventpipe/`** | Generated bundles (from **`build`** / **`push`**). |
|
|
60
154
|
|
|
61
|
-
|
|
62
|
-
|----------|---------|-------------|
|
|
63
|
-
| `EVENTPIPE_BASE_URL` | login, push | Origin of the Next app (default `https://eventpipe.app`; no trailing slash) |
|
|
64
|
-
| `EVENTPIPE_API_KEY` | push | Plaintext key from account API keys (`evp_...`) |
|
|
155
|
+
---
|
|
65
156
|
|
|
66
|
-
|
|
157
|
+
## Update hints
|
|
67
158
|
|
|
68
|
-
|
|
159
|
+
After most commands, the CLI may check npm for a newer **`@eventpipe/cli`** and print a short message on **stderr** suggesting **`eventpipe update`**. Set **`EVENTPIPE_SKIP_UPDATE_CHECK=1`** to disable (e.g. in CI).
|
|
69
160
|
|
|
70
|
-
|
|
161
|
+
---
|
|
71
162
|
|
|
72
163
|
## Example
|
|
73
164
|
|
|
74
|
-
See
|
|
165
|
+
See **`examples/stripe-webhook`** for a fuller project (multi-node **`codeNodes`** example).
|
|
166
|
+
|
|
167
|
+
---
|
|
75
168
|
|
|
76
169
|
## Limits
|
|
77
170
|
|
|
78
|
-
-
|
|
79
|
-
-
|
|
171
|
+
- **Single-code-node** workflows are the simplest; multi-node graphs may need a **`codeNodes`** map or publishing from the [dashboard](https://eventpipe.app).
|
|
172
|
+
- **200KB** UTF-8 per code-node bundle (same as the server).
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Getting help
|
|
177
|
+
|
|
178
|
+
- **Product:** [eventpipe.app](https://eventpipe.app) — platform docs include **CLI** and **API reference**.
|
|
179
|
+
- **This repo:** `eventpipe help`
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ import { publishVersion } from "./publish.js";
|
|
|
8
8
|
import { applyPublishedStudioSources, codeNodeUsesLibrary } from "./studio-sources.js";
|
|
9
9
|
import { cmdLogin } from "./cmd-login.js";
|
|
10
10
|
import { cmdCreate } from "./cmd-create.js";
|
|
11
|
+
import { loadCredentials } from "./credentials.js";
|
|
11
12
|
import { resolveEventpipeBaseUrl } from "./base-url.js";
|
|
12
13
|
import { fetchLatestPublishedVersion, isPublishedVersionNewer, readInstalledCliVersion, } from "./cli-version.js";
|
|
13
14
|
import { cmdUpdate } from "./cmd-update.js";
|
|
@@ -18,7 +19,7 @@ function usage() {
|
|
|
18
19
|
|
|
19
20
|
Environment:
|
|
20
21
|
EVENTPIPE_BASE_URL App origin (default: https://eventpipe.app); override for self-hosted
|
|
21
|
-
EVENTPIPE_API_KEY
|
|
22
|
+
EVENTPIPE_API_KEY Optional; for push in CI/automation (overrides session if set)
|
|
22
23
|
EVENTPIPE_SKIP_UPDATE_CHECK Set to 1 to disable the npm version hint on stderr
|
|
23
24
|
|
|
24
25
|
Commands:
|
|
@@ -28,7 +29,7 @@ Commands:
|
|
|
28
29
|
Stream webhooks; --verbose prints full JSON event; --json one NDJSON line per event;
|
|
29
30
|
--forward-to replays the request to your local server (status on stderr)
|
|
30
31
|
build [--dir <path>] Bundle TS into .eventpipe/
|
|
31
|
-
push [--dir <path>] build +
|
|
32
|
+
push [--dir <path>] build + publish (session after login, or EVENTPIPE_API_KEY)
|
|
32
33
|
update npm install -g @eventpipe/cli@latest
|
|
33
34
|
help
|
|
34
35
|
|
|
@@ -102,11 +103,19 @@ async function cmdBuild(projectDir) {
|
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
105
|
async function cmdPush(projectDir, pipelineOverride) {
|
|
105
|
-
const base = resolveEventpipeBaseUrl();
|
|
106
106
|
const key = process.env.EVENTPIPE_API_KEY?.trim();
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
const cred = await loadCredentials();
|
|
108
|
+
let auth = null;
|
|
109
|
+
if (key) {
|
|
110
|
+
auth = { type: "apiKey", apiKey: key };
|
|
109
111
|
}
|
|
112
|
+
else if (cred) {
|
|
113
|
+
auth = { type: "session", cred };
|
|
114
|
+
}
|
|
115
|
+
if (!auth) {
|
|
116
|
+
throw new Error("Run eventpipe login first, or set EVENTPIPE_API_KEY for push (e.g. in CI)");
|
|
117
|
+
}
|
|
118
|
+
const base = auth.type === "session" ? auth.cred.baseUrl : resolveEventpipeBaseUrl();
|
|
110
119
|
const manifest = await loadManifest(projectDir);
|
|
111
120
|
const pipelineId = pipelineOverride ?? manifest.pipelineId;
|
|
112
121
|
const pipe = manifest.settings.pipe;
|
|
@@ -145,7 +154,7 @@ async function cmdPush(projectDir, pipelineOverride) {
|
|
|
145
154
|
: null;
|
|
146
155
|
const result = await publishVersion({
|
|
147
156
|
baseUrl: base,
|
|
148
|
-
|
|
157
|
+
auth,
|
|
149
158
|
pipelineId,
|
|
150
159
|
manifest: manifestForPublish,
|
|
151
160
|
bundles,
|
package/dist/publish.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { EventpipeManifest } from "./config.js";
|
|
2
|
+
import type { StoredCredentials } from "./credentials.js";
|
|
2
3
|
export type PublishResult = {
|
|
3
4
|
success?: boolean;
|
|
4
5
|
version?: number;
|
|
@@ -6,9 +7,16 @@ export type PublishResult = {
|
|
|
6
7
|
bundleSizeBytes?: number;
|
|
7
8
|
error?: string;
|
|
8
9
|
};
|
|
10
|
+
export type PublishAuth = {
|
|
11
|
+
type: "apiKey";
|
|
12
|
+
apiKey: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: "session";
|
|
15
|
+
cred: StoredCredentials;
|
|
16
|
+
};
|
|
9
17
|
export declare function publishVersion(params: {
|
|
10
18
|
baseUrl: string;
|
|
11
|
-
|
|
19
|
+
auth: PublishAuth;
|
|
12
20
|
pipelineId: string;
|
|
13
21
|
manifest: EventpipeManifest;
|
|
14
22
|
bundles: Array<{
|
package/dist/publish.js
CHANGED
|
@@ -1,20 +1,34 @@
|
|
|
1
|
+
import { fetchWithSession } from "./auth-fetch.js";
|
|
1
2
|
export async function publishVersion(params) {
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"
|
|
3
|
+
const url = `${params.baseUrl}/api/account/pipelines/${params.pipelineId}/versions`;
|
|
4
|
+
const body = JSON.stringify({
|
|
5
|
+
sourceCode: params.sourceCode ?? null,
|
|
6
|
+
buildMeta: {
|
|
7
|
+
bundler: "eventpipe-cli",
|
|
8
|
+
generatedAt: new Date().toISOString(),
|
|
7
9
|
},
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
buildMeta: {
|
|
11
|
-
bundler: "eventpipe-cli",
|
|
12
|
-
generatedAt: new Date().toISOString(),
|
|
13
|
-
},
|
|
14
|
-
settings: params.manifest.settings,
|
|
15
|
-
codeBundles: params.bundles,
|
|
16
|
-
}),
|
|
10
|
+
settings: params.manifest.settings,
|
|
11
|
+
codeBundles: params.bundles,
|
|
17
12
|
});
|
|
13
|
+
let res;
|
|
14
|
+
if (params.auth.type === "apiKey") {
|
|
15
|
+
res = await fetch(url, {
|
|
16
|
+
method: "POST",
|
|
17
|
+
headers: {
|
|
18
|
+
"content-type": "application/json",
|
|
19
|
+
"x-api-key": params.auth.apiKey,
|
|
20
|
+
},
|
|
21
|
+
body,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const out = await fetchWithSession(url, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: { "content-type": "application/json" },
|
|
28
|
+
body,
|
|
29
|
+
}, params.auth.cred);
|
|
30
|
+
res = out.response;
|
|
31
|
+
}
|
|
18
32
|
const data = (await res.json());
|
|
19
33
|
if (!res.ok) {
|
|
20
34
|
return { error: data?.error ?? res.statusText };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventpipe/cli",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Build and publish Event Pipe flow bundles (API key
|
|
3
|
+
"version": "0.2.3",
|
|
4
|
+
"description": "Build and publish Event Pipe flow bundles (session or API key)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"eventpipe": "./dist/cli.js",
|