@eventcatalog/cli 0.3.4 → 0.4.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 +134 -31
- package/dist/cli/index.js +79 -17
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/index.mjs +79 -17
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli-docs.js +2 -2
- package/dist/cli-docs.js.map +1 -1
- package/dist/cli-docs.mjs +2 -2
- package/dist/cli-docs.mjs.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
## @eventcatalog/cli
|
|
2
2
|
|
|
3
|
-
Command-line interface for [EventCatalog](https://eventcatalog.dev).
|
|
3
|
+
Command-line interface for [EventCatalog](https://eventcatalog.dev). Import and export catalogs using the [EventCatalog DSL](https://www.eventcatalog.dev/docs/development/dsl/introduction), run SDK functions directly from your terminal, and automate your EventCatalog workflows.
|
|
4
4
|
|
|
5
5
|
### Installation
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ npm i @eventcatalog/cli
|
|
|
11
11
|
### Running with npx (no installation required)
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npx @eventcatalog/cli --dir <catalog-path> <
|
|
14
|
+
npx @eventcatalog/cli --dir <catalog-path> <command> [args...]
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
### Running after installation
|
|
@@ -19,77 +19,180 @@ npx @eventcatalog/cli --dir <catalog-path> <function-name> [args...]
|
|
|
19
19
|
If you've installed the package, the `eventcatalog` command is available:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
eventcatalog --dir <catalog-path> <
|
|
22
|
+
eventcatalog --dir <catalog-path> <command> [args...]
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
###
|
|
25
|
+
### Global Options
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
| Option | Description | Default |
|
|
28
|
+
| ------------------ | ------------------------------ | ----------------------- |
|
|
29
|
+
| `-d, --dir <path>` | Path to your catalog directory | `.` (current directory) |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
### Commands
|
|
34
|
+
|
|
35
|
+
#### `import` — Import DSL files into your catalog
|
|
36
|
+
|
|
37
|
+
Parse `.ec` (EventCatalog DSL) files and write them as catalog resources (markdown + frontmatter).
|
|
28
38
|
|
|
29
39
|
```bash
|
|
30
|
-
|
|
40
|
+
eventcatalog import [files...] [options]
|
|
31
41
|
```
|
|
32
42
|
|
|
33
|
-
**
|
|
43
|
+
**Options:**
|
|
44
|
+
|
|
45
|
+
| Option | Description |
|
|
46
|
+
| ----------- | ------------------------------------------------------------ |
|
|
47
|
+
| `--stdin` | Read DSL from stdin instead of files |
|
|
48
|
+
| `--dry-run` | Preview changes without writing to disk |
|
|
49
|
+
| `--flat` | Write all resources at the top level (no nested directories) |
|
|
50
|
+
| `--no-init` | Skip the interactive catalog scaffolding prompt |
|
|
51
|
+
|
|
52
|
+
**Examples:**
|
|
34
53
|
|
|
35
54
|
```bash
|
|
36
|
-
|
|
37
|
-
|
|
55
|
+
# Import a single DSL file
|
|
56
|
+
eventcatalog import architecture.ec
|
|
57
|
+
|
|
58
|
+
# Import multiple files
|
|
59
|
+
eventcatalog import services.ec events.ec domains.ec
|
|
60
|
+
|
|
61
|
+
# Pipe DSL from another tool
|
|
62
|
+
cat architecture.ec | eventcatalog import --stdin
|
|
63
|
+
|
|
64
|
+
# Preview what would change
|
|
65
|
+
eventcatalog import architecture.ec --dry-run
|
|
66
|
+
|
|
67
|
+
# Import without nesting services inside domains
|
|
68
|
+
eventcatalog import architecture.ec --flat
|
|
38
69
|
```
|
|
39
70
|
|
|
40
|
-
**
|
|
71
|
+
**Behaviors:**
|
|
72
|
+
|
|
73
|
+
- If no `eventcatalog.config.js` exists, you'll be prompted to scaffold a new catalog (skip with `--no-init`).
|
|
74
|
+
- Importing a newer version of an existing resource automatically versions the old one.
|
|
75
|
+
- Re-importing the same version overwrites the existing resource.
|
|
76
|
+
- Referenced resources that aren't defined in the DSL (e.g., `sends event OrderCreated` without an inline body) are created as stubs at version `0.0.1`.
|
|
77
|
+
- Existing resource locations are preserved — updates go to where the resource already lives.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
#### `export` — Export catalog resources to DSL
|
|
82
|
+
|
|
83
|
+
Convert catalog resources back into EventCatalog DSL (`.ec`) format.
|
|
41
84
|
|
|
42
85
|
```bash
|
|
43
|
-
|
|
44
|
-
npx @eventcatalog/cli --dir ./my-catalog getEvents '{"latestOnly":true}'
|
|
86
|
+
eventcatalog export [options]
|
|
45
87
|
```
|
|
46
88
|
|
|
47
|
-
**
|
|
89
|
+
**Options:**
|
|
90
|
+
|
|
91
|
+
| Option | Description |
|
|
92
|
+
| --------------------- | -------------------------------------------------------------------------------------------- |
|
|
93
|
+
| `--all` | Export the entire catalog |
|
|
94
|
+
| `--resource <type>` | Resource type to export (`event`, `command`, `query`, `service`, `domain`, `channel`) |
|
|
95
|
+
| `--id <id>` | Export a specific resource by ID (requires `--resource`) |
|
|
96
|
+
| `--version <version>` | Export a specific version (requires `--resource` and `--id`) |
|
|
97
|
+
| `--hydrate` | Include referenced resources (e.g., messages referenced by a service) |
|
|
98
|
+
| `--stdout` | Print to stdout instead of writing a file |
|
|
99
|
+
| `--playground` | Open the exported DSL in the [EventCatalog Playground](https://playground.eventcatalog.dev/) |
|
|
100
|
+
| `--output <path>` | Custom output file path |
|
|
101
|
+
|
|
102
|
+
**Examples:**
|
|
48
103
|
|
|
49
104
|
```bash
|
|
50
|
-
|
|
105
|
+
# Export a single event
|
|
106
|
+
eventcatalog export --resource event --id OrderCreated --stdout
|
|
107
|
+
|
|
108
|
+
# Export all services with their referenced messages
|
|
109
|
+
eventcatalog export --resource service --hydrate --stdout
|
|
110
|
+
|
|
111
|
+
# Export the entire catalog to a file
|
|
112
|
+
eventcatalog export --all --output catalog.ec
|
|
113
|
+
|
|
114
|
+
# Export and open in the playground
|
|
115
|
+
eventcatalog export --all --playground
|
|
51
116
|
```
|
|
52
117
|
|
|
53
|
-
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
#### `list` — List available SDK functions
|
|
121
|
+
|
|
122
|
+
Display all SDK functions organized by category (Events, Commands, Queries, Services, Domains, etc.).
|
|
54
123
|
|
|
55
124
|
```bash
|
|
56
|
-
|
|
125
|
+
eventcatalog list
|
|
57
126
|
```
|
|
58
127
|
|
|
59
|
-
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
#### `<function>` — Run any SDK function
|
|
131
|
+
|
|
132
|
+
Any unrecognized command is treated as an SDK function call. Output is JSON.
|
|
60
133
|
|
|
61
134
|
```bash
|
|
62
|
-
|
|
135
|
+
eventcatalog <function-name> [args...]
|
|
63
136
|
```
|
|
64
137
|
|
|
65
|
-
|
|
138
|
+
**Examples:**
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# Get an event (latest version)
|
|
142
|
+
eventcatalog --dir ./my-catalog getEvent "OrderCreated"
|
|
143
|
+
|
|
144
|
+
# Get a specific version
|
|
145
|
+
eventcatalog --dir ./my-catalog getEvent "OrderCreated" "1.0.0"
|
|
146
|
+
|
|
147
|
+
# Get all events with options
|
|
148
|
+
eventcatalog --dir ./my-catalog getEvents '{"latestOnly":true}'
|
|
66
149
|
|
|
67
|
-
|
|
150
|
+
# Write an event
|
|
151
|
+
eventcatalog --dir ./my-catalog writeEvent '{"id":"OrderCreated","name":"Order Created","version":"1.0.0","markdown":"# Order Created"}'
|
|
152
|
+
|
|
153
|
+
# Get a service
|
|
154
|
+
eventcatalog --dir ./my-catalog getService "InventoryService"
|
|
155
|
+
|
|
156
|
+
# Add an event to a service
|
|
157
|
+
eventcatalog --dir ./my-catalog addEventToService "InventoryService" "sends" '{"id":"OrderCreated","version":"1.0.0"}'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Run `eventcatalog list` to see all available functions.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
### Piping and Composing
|
|
165
|
+
|
|
166
|
+
Output from SDK functions is JSON, making it easy to pipe to tools like `jq`:
|
|
68
167
|
|
|
69
168
|
```bash
|
|
70
|
-
#
|
|
71
|
-
|
|
169
|
+
# Filter events by version
|
|
170
|
+
eventcatalog --dir ./my-catalog getEvents | jq '.[] | select(.version == "1.0.0")'
|
|
72
171
|
|
|
73
172
|
# Count total events
|
|
74
|
-
|
|
173
|
+
eventcatalog --dir ./my-catalog getEvents | jq 'length'
|
|
75
174
|
|
|
76
175
|
# Extract event IDs
|
|
77
|
-
|
|
176
|
+
eventcatalog --dir ./my-catalog getEvents | jq '.[].id'
|
|
78
177
|
```
|
|
79
178
|
|
|
80
179
|
### Arguments Format
|
|
81
180
|
|
|
82
181
|
Arguments are automatically parsed:
|
|
83
182
|
|
|
84
|
-
- **JSON objects:** `'{"key":"value"}'`
|
|
85
|
-
- **JSON arrays:** `'["item1","item2"]'`
|
|
86
|
-
- **Booleans:** `true` or `false`
|
|
87
|
-
- **Numbers:** `42` or `3.14`
|
|
88
|
-
- **Strings:** anything else
|
|
183
|
+
- **JSON objects:** `'{"key":"value"}'` — parsed as object
|
|
184
|
+
- **JSON arrays:** `'["item1","item2"]'` — parsed as array
|
|
185
|
+
- **Booleans:** `true` or `false` — parsed as boolean
|
|
186
|
+
- **Numbers:** `42` or `3.14` — parsed as number
|
|
187
|
+
- **Strings:** anything else — kept as string
|
|
188
|
+
|
|
189
|
+
### Documentation
|
|
89
190
|
|
|
90
|
-
|
|
191
|
+
- [EventCatalog DSL](https://www.eventcatalog.dev/docs/development/dsl/introduction)
|
|
192
|
+
- [SDK reference](https://www.eventcatalog.dev/docs/sdk)
|
|
193
|
+
- [CLI documentation](https://www.eventcatalog.dev/docs/development/cli)
|
|
91
194
|
|
|
92
|
-
|
|
195
|
+
## Enterprise support
|
|
93
196
|
|
|
94
197
|
Interested in collaborating with us? Our offerings include dedicated support, priority assistance, feature development, custom integrations, and more.
|
|
95
198
|
|
package/dist/cli/index.js
CHANGED
|
@@ -250,19 +250,45 @@ ${items.join("\n\n")}`);
|
|
|
250
250
|
}
|
|
251
251
|
return sections.join("\n\n");
|
|
252
252
|
}
|
|
253
|
-
function
|
|
254
|
-
const
|
|
255
|
-
const
|
|
256
|
-
for (
|
|
257
|
-
const trimmed =
|
|
253
|
+
function extractResourceDefinitions(dsl, filterTypes) {
|
|
254
|
+
const results = [];
|
|
255
|
+
const lines = dsl.split("\n");
|
|
256
|
+
for (let i = 0; i < lines.length; i++) {
|
|
257
|
+
const trimmed = lines[i].trimStart();
|
|
258
258
|
const parts = trimmed.split(/\s/);
|
|
259
259
|
const keyword = parts[0];
|
|
260
260
|
const id = parts[1];
|
|
261
|
-
if (!
|
|
261
|
+
if (!filterTypes.includes(keyword)) continue;
|
|
262
262
|
if (!id || !trimmed.endsWith("{")) continue;
|
|
263
|
-
|
|
263
|
+
let version2;
|
|
264
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
265
|
+
const inner = lines[j].trim();
|
|
266
|
+
if (inner === "}") break;
|
|
267
|
+
const vMatch = inner.match(/^version\s+(.+)$/);
|
|
268
|
+
if (vMatch) {
|
|
269
|
+
version2 = vMatch[1];
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
results.push({ keyword, id, version: version2 });
|
|
274
|
+
}
|
|
275
|
+
return results;
|
|
276
|
+
}
|
|
277
|
+
function buildVisualizerBlock(dsl, name, filterTypes) {
|
|
278
|
+
const types = Array.isArray(filterTypes) ? filterTypes : [filterTypes];
|
|
279
|
+
const definitions = extractResourceDefinitions(dsl, types);
|
|
280
|
+
if (definitions.length === 0) return "";
|
|
281
|
+
const counts = /* @__PURE__ */ new Map();
|
|
282
|
+
for (const def of definitions) {
|
|
283
|
+
const key = `${def.keyword}:${def.id}`;
|
|
284
|
+
counts.set(key, (counts.get(key) || 0) + 1);
|
|
264
285
|
}
|
|
265
|
-
|
|
286
|
+
const entries = definitions.map((def) => {
|
|
287
|
+
const key = `${def.keyword}:${def.id}`;
|
|
288
|
+
const needsVersion = (counts.get(key) || 0) > 1 && def.version;
|
|
289
|
+
const ref = needsVersion ? `${def.id}@${def.version}` : def.id;
|
|
290
|
+
return ` ${def.keyword} ${ref}`;
|
|
291
|
+
});
|
|
266
292
|
return `
|
|
267
293
|
visualizer main {
|
|
268
294
|
name "${name}"
|
|
@@ -299,9 +325,9 @@ ${vizBlock}` : grouped;
|
|
|
299
325
|
const encoded = Buffer.from(dsl).toString("base64");
|
|
300
326
|
const playgroundUrl = `https://playground.eventcatalog.dev/?code=${encoded}`;
|
|
301
327
|
await (0, import_open.default)(playgroundUrl);
|
|
302
|
-
lines.push("", ` Opening in EventCatalog
|
|
328
|
+
lines.push("", ` Opening in EventCatalog Canvas...`);
|
|
303
329
|
} else {
|
|
304
|
-
lines.push("", ` Tip: Use --playground to open in EventCatalog
|
|
330
|
+
lines.push("", ` Tip: Use --playground to open in EventCatalog Canvas`);
|
|
305
331
|
}
|
|
306
332
|
lines.push("");
|
|
307
333
|
return lines.join("\n");
|
|
@@ -333,9 +359,9 @@ ${vizBlock}` : grouped;
|
|
|
333
359
|
const encoded = Buffer.from(dsl).toString("base64");
|
|
334
360
|
const playgroundUrl = `https://playground.eventcatalog.dev/?code=${encoded}`;
|
|
335
361
|
await (0, import_open.default)(playgroundUrl);
|
|
336
|
-
lines.push("", ` Opening in EventCatalog
|
|
362
|
+
lines.push("", ` Opening in EventCatalog Canvas...`);
|
|
337
363
|
} else {
|
|
338
|
-
lines.push("", ` Tip: Use --playground to open in EventCatalog
|
|
364
|
+
lines.push("", ` Tip: Use --playground to open in EventCatalog Canvas`);
|
|
339
365
|
}
|
|
340
366
|
lines.push("");
|
|
341
367
|
return lines.join("\n");
|
|
@@ -356,7 +382,8 @@ async function exportResource(options) {
|
|
|
356
382
|
}
|
|
357
383
|
const rawDsl = await sdk.toDSL(data, { type, hydrate });
|
|
358
384
|
const grouped = hydrate ? groupDSLBlocks(rawDsl) : rawDsl;
|
|
359
|
-
const
|
|
385
|
+
const vizTypes = hydrate ? [...RESOURCE_TYPES] : [type];
|
|
386
|
+
const vizBlock = buildVisualizerBlock(grouped, `View of ${id}`, vizTypes);
|
|
360
387
|
const dsl = vizBlock ? `${grouped}
|
|
361
388
|
${vizBlock}` : grouped;
|
|
362
389
|
if (stdout) {
|
|
@@ -370,9 +397,9 @@ ${vizBlock}` : grouped;
|
|
|
370
397
|
const encoded = Buffer.from(dsl).toString("base64");
|
|
371
398
|
const playgroundUrl = `https://playground.eventcatalog.dev/?code=${encoded}`;
|
|
372
399
|
await (0, import_open.default)(playgroundUrl);
|
|
373
|
-
lines.push("", ` Opening in EventCatalog
|
|
400
|
+
lines.push("", ` Opening in EventCatalog Canvas...`);
|
|
374
401
|
} else {
|
|
375
|
-
lines.push("", ` Tip: Use --playground to open in EventCatalog
|
|
402
|
+
lines.push("", ` Tip: Use --playground to open in EventCatalog Canvas`);
|
|
376
403
|
}
|
|
377
404
|
lines.push("");
|
|
378
405
|
return lines.join("\n");
|
|
@@ -385,6 +412,17 @@ var import_node_crypto = require("crypto");
|
|
|
385
412
|
var import_node_readline = require("readline");
|
|
386
413
|
var import_gray_matter = __toESM(require("gray-matter"));
|
|
387
414
|
var import_sdk4 = __toESM(require("@eventcatalog/sdk"));
|
|
415
|
+
|
|
416
|
+
// src/cli/dsl-managed-keys.ts
|
|
417
|
+
var MESSAGE_MANAGED_KEYS = /* @__PURE__ */ new Set(["id", "name", "version", "owners", "deprecated", "draft", "summary"]);
|
|
418
|
+
var DSL_MANAGED_KEYS_BY_TYPE = {
|
|
419
|
+
domain: /* @__PURE__ */ new Set(["id", "name", "version", "owners", "deprecated", "draft", "summary", "services", "domains"]),
|
|
420
|
+
event: MESSAGE_MANAGED_KEYS,
|
|
421
|
+
command: MESSAGE_MANAGED_KEYS,
|
|
422
|
+
query: MESSAGE_MANAGED_KEYS
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
// src/cli/import.ts
|
|
388
426
|
function normalizeImportedFrontmatter(type, frontmatter) {
|
|
389
427
|
const normalized = { ...frontmatter };
|
|
390
428
|
if (type === "container") {
|
|
@@ -396,9 +434,33 @@ function normalizeImportedFrontmatter(type, frontmatter) {
|
|
|
396
434
|
normalized.access_mode = normalized.accessMode;
|
|
397
435
|
delete normalized.accessMode;
|
|
398
436
|
}
|
|
437
|
+
if (!normalized.container_type) {
|
|
438
|
+
normalized.container_type = "database";
|
|
439
|
+
}
|
|
399
440
|
}
|
|
400
441
|
return normalized;
|
|
401
442
|
}
|
|
443
|
+
function toFrontmatter(resource) {
|
|
444
|
+
if (!resource || typeof resource !== "object") return {};
|
|
445
|
+
const { markdown: _markdown, ...frontmatter } = resource;
|
|
446
|
+
return frontmatter;
|
|
447
|
+
}
|
|
448
|
+
function mergeImportedFrontmatter(type, incomingFrontmatter, existing, latest) {
|
|
449
|
+
const normalizedIncoming = normalizeImportedFrontmatter(type, incomingFrontmatter);
|
|
450
|
+
const managedKeys = DSL_MANAGED_KEYS_BY_TYPE[type];
|
|
451
|
+
if (!managedKeys) {
|
|
452
|
+
return normalizedIncoming;
|
|
453
|
+
}
|
|
454
|
+
const baseFrontmatter = toFrontmatter(existing ?? latest);
|
|
455
|
+
const preservedFrontmatter = { ...baseFrontmatter };
|
|
456
|
+
for (const key of managedKeys) {
|
|
457
|
+
delete preservedFrontmatter[key];
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
...preservedFrontmatter,
|
|
461
|
+
...normalizedIncoming
|
|
462
|
+
};
|
|
463
|
+
}
|
|
402
464
|
var RESOURCE_TYPE_FROM_FOLDER = {
|
|
403
465
|
events: "event",
|
|
404
466
|
commands: "command",
|
|
@@ -945,7 +1007,7 @@ async function importDSL(options) {
|
|
|
945
1007
|
}
|
|
946
1008
|
}
|
|
947
1009
|
const resourceData = {
|
|
948
|
-
...
|
|
1010
|
+
...mergeImportedFrontmatter(resource.type, resource.frontmatter, existing, latest),
|
|
949
1011
|
markdown
|
|
950
1012
|
};
|
|
951
1013
|
const writeOptions = {
|
|
@@ -1117,7 +1179,7 @@ import_commander.program.command("list").description("List all available SDK fun
|
|
|
1117
1179
|
process.exit(1);
|
|
1118
1180
|
}
|
|
1119
1181
|
});
|
|
1120
|
-
import_commander.program.command("export").description("Export a catalog resource to EventCatalog DSL (.ec) format").option("-a, --all", "Export the entire catalog (all resource types)", false).option("-r, --resource <type>", "Resource type (event, command, query, service, domain)").option("--id <id>", "Resource ID (omit to export all resources of the given type)").option("-v, --version <version>", "Resource version (defaults to latest)").option("--hydrate", "Include referenced resources (messages, channels, owners)", false).option("--stdout", "Print to stdout instead of writing a file", false).option("--playground", "Open the exported DSL in EventCatalog
|
|
1182
|
+
import_commander.program.command("export").description("Export a catalog resource to EventCatalog DSL (.ec) format").option("-a, --all", "Export the entire catalog (all resource types)", false).option("-r, --resource <type>", "Resource type (event, command, query, service, domain)").option("--id <id>", "Resource ID (omit to export all resources of the given type)").option("-v, --version <version>", "Resource version (defaults to latest)").option("--hydrate", "Include referenced resources (messages, channels, owners)", false).option("--stdout", "Print to stdout instead of writing a file", false).option("--playground", "Open the exported DSL in EventCatalog Canvas", false).option("-o, --output <path>", "Output file path (defaults to <id>.ec or catalog.ec)").action(async (opts) => {
|
|
1121
1183
|
try {
|
|
1122
1184
|
const globalOpts = import_commander.program.opts();
|
|
1123
1185
|
const dir = globalOpts.dir || ".";
|