@eve-horizon/cli 0.0.1
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 +275 -0
- package/bin/eve.js +2 -0
- package/dist/commands/api.js +350 -0
- package/dist/commands/auth.js +99 -0
- package/dist/commands/db.js +149 -0
- package/dist/commands/env.js +303 -0
- package/dist/commands/event.js +273 -0
- package/dist/commands/harness.js +96 -0
- package/dist/commands/job.js +2266 -0
- package/dist/commands/org.js +97 -0
- package/dist/commands/pipeline.js +403 -0
- package/dist/commands/profile.js +103 -0
- package/dist/commands/project.js +185 -0
- package/dist/commands/secrets.js +147 -0
- package/dist/commands/system.js +457 -0
- package/dist/commands/workflow.js +337 -0
- package/dist/index.js +97 -0
- package/dist/lib/args.js +57 -0
- package/dist/lib/client.js +116 -0
- package/dist/lib/config.js +76 -0
- package/dist/lib/context.js +45 -0
- package/dist/lib/help.js +938 -0
- package/dist/lib/logs.js +51 -0
- package/dist/lib/output.js +14 -0
- package/package.json +36 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleEvent = handleEvent;
|
|
4
|
+
const args_1 = require("../lib/args");
|
|
5
|
+
const client_1 = require("../lib/client");
|
|
6
|
+
const output_1 = require("../lib/output");
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Main Handler
|
|
9
|
+
// ============================================================================
|
|
10
|
+
async function handleEvent(subcommand, positionals, flags, context) {
|
|
11
|
+
const json = Boolean(flags.json);
|
|
12
|
+
switch (subcommand) {
|
|
13
|
+
case 'list':
|
|
14
|
+
return handleList(positionals, flags, context, json);
|
|
15
|
+
case 'show':
|
|
16
|
+
return handleShow(positionals, flags, context, json);
|
|
17
|
+
case 'emit':
|
|
18
|
+
return handleEmit(flags, context, json);
|
|
19
|
+
default:
|
|
20
|
+
throw new Error('Usage: eve event <list|show|emit>\n' +
|
|
21
|
+
' list [project] - list events for a project\n' +
|
|
22
|
+
' show <event_id> - show details of an event\n' +
|
|
23
|
+
' emit --type=<type> --source=<source> - emit a new event (for testing)');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Subcommand Handlers
|
|
28
|
+
// ============================================================================
|
|
29
|
+
/**
|
|
30
|
+
* eve event list [project] [--type] [--source] [--status] [--limit] [--offset]
|
|
31
|
+
* List events for a project
|
|
32
|
+
*/
|
|
33
|
+
async function handleList(positionals, flags, context, json) {
|
|
34
|
+
const projectId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['project']) ?? context.projectId;
|
|
35
|
+
if (!projectId) {
|
|
36
|
+
throw new Error('Usage: eve event list [project] [--project=<id>] [--type=<type>] [--source=<source>] [--status=<status>]');
|
|
37
|
+
}
|
|
38
|
+
const query = buildQuery({
|
|
39
|
+
type: (0, args_1.getStringFlag)(flags, ['type']),
|
|
40
|
+
source: (0, args_1.getStringFlag)(flags, ['source']),
|
|
41
|
+
status: (0, args_1.getStringFlag)(flags, ['status']),
|
|
42
|
+
limit: (0, args_1.getStringFlag)(flags, ['limit']),
|
|
43
|
+
offset: (0, args_1.getStringFlag)(flags, ['offset']),
|
|
44
|
+
});
|
|
45
|
+
const response = await (0, client_1.requestJson)(context, `/projects/${projectId}/events${query}`);
|
|
46
|
+
if (json) {
|
|
47
|
+
(0, output_1.outputJson)(response, json);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (response.data.length === 0) {
|
|
51
|
+
console.log('No events found.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
formatEventsTable(response.data);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* eve event show <event_id>
|
|
59
|
+
* Show details of an event
|
|
60
|
+
*/
|
|
61
|
+
async function handleShow(positionals, flags, context, json) {
|
|
62
|
+
const eventId = positionals[0] ?? (0, args_1.getStringFlag)(flags, ['id', 'event']);
|
|
63
|
+
const projectId = (0, args_1.getStringFlag)(flags, ['project']) ?? context.projectId;
|
|
64
|
+
if (!eventId) {
|
|
65
|
+
throw new Error('Usage: eve event show <event_id> [--id=<id>]');
|
|
66
|
+
}
|
|
67
|
+
if (!projectId) {
|
|
68
|
+
throw new Error('Project ID is required. Use --project=<id> or set a default project in your profile.');
|
|
69
|
+
}
|
|
70
|
+
const response = await (0, client_1.requestJson)(context, `/projects/${projectId}/events/${eventId}`);
|
|
71
|
+
if (json) {
|
|
72
|
+
(0, output_1.outputJson)(response, json);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
formatEventDetails(response);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* eve event emit --type=<type> --source=<source> [--env] [--payload]
|
|
80
|
+
* Emit a new event (for testing)
|
|
81
|
+
*/
|
|
82
|
+
async function handleEmit(flags, context, json) {
|
|
83
|
+
const projectId = (0, args_1.getStringFlag)(flags, ['project']) ?? context.projectId;
|
|
84
|
+
const type = (0, args_1.getStringFlag)(flags, ['type']);
|
|
85
|
+
const source = (0, args_1.getStringFlag)(flags, ['source']);
|
|
86
|
+
if (!projectId) {
|
|
87
|
+
throw new Error('Usage: eve event emit --project=<id> --type=<type> --source=<source> [options]');
|
|
88
|
+
}
|
|
89
|
+
if (!type) {
|
|
90
|
+
throw new Error('--type is required (e.g., "github.push", "cron.tick", "app.event")');
|
|
91
|
+
}
|
|
92
|
+
if (!source) {
|
|
93
|
+
throw new Error('--source is required (e.g., "github", "cron", "manual", "app", "system")');
|
|
94
|
+
}
|
|
95
|
+
const body = {
|
|
96
|
+
type,
|
|
97
|
+
source,
|
|
98
|
+
};
|
|
99
|
+
// Optional fields
|
|
100
|
+
const envName = (0, args_1.getStringFlag)(flags, ['env', 'env-name']);
|
|
101
|
+
if (envName) {
|
|
102
|
+
body.env_name = envName;
|
|
103
|
+
}
|
|
104
|
+
const refSha = (0, args_1.getStringFlag)(flags, ['ref-sha', 'sha']);
|
|
105
|
+
if (refSha) {
|
|
106
|
+
body.ref_sha = refSha;
|
|
107
|
+
}
|
|
108
|
+
const refBranch = (0, args_1.getStringFlag)(flags, ['ref-branch', 'branch']);
|
|
109
|
+
if (refBranch) {
|
|
110
|
+
body.ref_branch = refBranch;
|
|
111
|
+
}
|
|
112
|
+
const actorType = (0, args_1.getStringFlag)(flags, ['actor-type']);
|
|
113
|
+
if (actorType) {
|
|
114
|
+
body.actor_type = actorType;
|
|
115
|
+
}
|
|
116
|
+
const actorId = (0, args_1.getStringFlag)(flags, ['actor-id', 'actor']);
|
|
117
|
+
if (actorId) {
|
|
118
|
+
body.actor_id = actorId;
|
|
119
|
+
}
|
|
120
|
+
const dedupeKey = (0, args_1.getStringFlag)(flags, ['dedupe-key']);
|
|
121
|
+
if (dedupeKey) {
|
|
122
|
+
body.dedupe_key = dedupeKey;
|
|
123
|
+
}
|
|
124
|
+
// Payload as JSON string
|
|
125
|
+
const payloadStr = (0, args_1.getStringFlag)(flags, ['payload']);
|
|
126
|
+
if (payloadStr) {
|
|
127
|
+
try {
|
|
128
|
+
body.payload_json = JSON.parse(payloadStr);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw new Error(`Invalid JSON in --payload: ${error.message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const response = await (0, client_1.requestJson)(context, `/projects/${projectId}/events`, {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
body,
|
|
137
|
+
});
|
|
138
|
+
if (json) {
|
|
139
|
+
(0, output_1.outputJson)(response, json);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.log(`Event created: ${response.id}`);
|
|
143
|
+
console.log(` Type: ${response.type}`);
|
|
144
|
+
console.log(` Source: ${response.source}`);
|
|
145
|
+
console.log(` Status: ${response.status}`);
|
|
146
|
+
if (response.env_name) {
|
|
147
|
+
console.log(` Env: ${response.env_name}`);
|
|
148
|
+
}
|
|
149
|
+
if (response.ref_sha) {
|
|
150
|
+
console.log(` SHA: ${response.ref_sha}`);
|
|
151
|
+
}
|
|
152
|
+
if (response.ref_branch) {
|
|
153
|
+
console.log(` Branch: ${response.ref_branch}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// ============================================================================
|
|
158
|
+
// Helper Functions
|
|
159
|
+
// ============================================================================
|
|
160
|
+
/**
|
|
161
|
+
* Build query string from parameters
|
|
162
|
+
*/
|
|
163
|
+
function buildQuery(params) {
|
|
164
|
+
const search = new URLSearchParams();
|
|
165
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
166
|
+
if (value === undefined || value === '')
|
|
167
|
+
return;
|
|
168
|
+
search.set(key, String(value));
|
|
169
|
+
});
|
|
170
|
+
const query = search.toString();
|
|
171
|
+
return query ? `?${query}` : '';
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Format events as a human-readable table
|
|
175
|
+
*/
|
|
176
|
+
function formatEventsTable(events) {
|
|
177
|
+
if (events.length === 0) {
|
|
178
|
+
console.log('No events found.');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
// Calculate column widths
|
|
182
|
+
const idWidth = Math.max(8, ...events.map((e) => e.id.length));
|
|
183
|
+
const typeWidth = Math.max(4, ...events.map((e) => e.type.length));
|
|
184
|
+
const sourceWidth = Math.max(6, ...events.map((e) => e.source.length));
|
|
185
|
+
const statusWidth = Math.max(6, ...events.map((e) => e.status.length));
|
|
186
|
+
// Header
|
|
187
|
+
const header = [
|
|
188
|
+
padRight('ID', idWidth),
|
|
189
|
+
padRight('Type', typeWidth),
|
|
190
|
+
padRight('Source', sourceWidth),
|
|
191
|
+
padRight('Status', statusWidth),
|
|
192
|
+
padRight('Env', 12),
|
|
193
|
+
padRight('Branch', 20),
|
|
194
|
+
'Created',
|
|
195
|
+
].join(' ');
|
|
196
|
+
console.log(header);
|
|
197
|
+
console.log('-'.repeat(header.length));
|
|
198
|
+
// Rows
|
|
199
|
+
for (const event of events) {
|
|
200
|
+
const row = [
|
|
201
|
+
padRight(event.id, idWidth),
|
|
202
|
+
padRight(event.type, typeWidth),
|
|
203
|
+
padRight(event.source, sourceWidth),
|
|
204
|
+
padRight(event.status, statusWidth),
|
|
205
|
+
padRight(event.env_name || '-', 12),
|
|
206
|
+
padRight(event.ref_branch || '-', 20),
|
|
207
|
+
formatDate(event.created_at),
|
|
208
|
+
].join(' ');
|
|
209
|
+
console.log(row);
|
|
210
|
+
}
|
|
211
|
+
console.log('');
|
|
212
|
+
console.log(`Total: ${events.length} event(s)`);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Format a single event's details
|
|
216
|
+
*/
|
|
217
|
+
function formatEventDetails(event) {
|
|
218
|
+
console.log(`Event: ${event.id}`);
|
|
219
|
+
console.log('');
|
|
220
|
+
console.log(` Project: ${event.project_id}`);
|
|
221
|
+
console.log(` Type: ${event.type}`);
|
|
222
|
+
console.log(` Source: ${event.source}`);
|
|
223
|
+
console.log(` Status: ${event.status}`);
|
|
224
|
+
if (event.env_name) {
|
|
225
|
+
console.log(` Environment: ${event.env_name}`);
|
|
226
|
+
}
|
|
227
|
+
if (event.ref_sha) {
|
|
228
|
+
console.log(` Ref SHA: ${event.ref_sha}`);
|
|
229
|
+
}
|
|
230
|
+
if (event.ref_branch) {
|
|
231
|
+
console.log(` Ref Branch: ${event.ref_branch}`);
|
|
232
|
+
}
|
|
233
|
+
if (event.actor_type) {
|
|
234
|
+
console.log(` Actor Type: ${event.actor_type}`);
|
|
235
|
+
}
|
|
236
|
+
if (event.actor_id) {
|
|
237
|
+
console.log(` Actor ID: ${event.actor_id}`);
|
|
238
|
+
}
|
|
239
|
+
if (event.dedupe_key) {
|
|
240
|
+
console.log(` Dedupe Key: ${event.dedupe_key}`);
|
|
241
|
+
}
|
|
242
|
+
if (event.payload_json && Object.keys(event.payload_json).length > 0) {
|
|
243
|
+
console.log('');
|
|
244
|
+
console.log(' Payload:');
|
|
245
|
+
console.log(` ${JSON.stringify(event.payload_json, null, 2).split('\n').join('\n ')}`);
|
|
246
|
+
}
|
|
247
|
+
console.log('');
|
|
248
|
+
console.log(` Created: ${formatDate(event.created_at)}`);
|
|
249
|
+
console.log(` Updated: ${formatDate(event.updated_at)}`);
|
|
250
|
+
if (event.processed_at) {
|
|
251
|
+
console.log(` Processed: ${formatDate(event.processed_at)}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Format a date string for display
|
|
256
|
+
*/
|
|
257
|
+
function formatDate(dateStr) {
|
|
258
|
+
try {
|
|
259
|
+
const date = new Date(dateStr);
|
|
260
|
+
return date.toLocaleString();
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return dateStr;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Pad a string to the right with spaces
|
|
268
|
+
*/
|
|
269
|
+
function padRight(str, width) {
|
|
270
|
+
if (str.length >= width)
|
|
271
|
+
return str;
|
|
272
|
+
return str + ' '.repeat(width - str.length);
|
|
273
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleHarness = handleHarness;
|
|
4
|
+
const client_1 = require("../lib/client");
|
|
5
|
+
const output_1 = require("../lib/output");
|
|
6
|
+
async function handleHarness(subcommand, positionals, flags, context) {
|
|
7
|
+
const json = Boolean(flags.json);
|
|
8
|
+
switch (subcommand) {
|
|
9
|
+
case 'list': {
|
|
10
|
+
const response = await (0, client_1.requestJson)(context, '/harnesses');
|
|
11
|
+
if (json) {
|
|
12
|
+
(0, output_1.outputJson)(response, json);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
renderHarnessList(response.data);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
case 'get': {
|
|
19
|
+
const name = positionals[0];
|
|
20
|
+
if (!name)
|
|
21
|
+
throw new Error('Usage: eve harness get <name>');
|
|
22
|
+
const response = await (0, client_1.requestJson)(context, `/harnesses/${name}`);
|
|
23
|
+
if (json) {
|
|
24
|
+
(0, output_1.outputJson)(response, json);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
renderHarnessDetail(response);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
default:
|
|
31
|
+
throw new Error('Usage: eve harness <list|get>');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function renderHarnessList(harnesses) {
|
|
35
|
+
const rows = harnesses.map((harness) => {
|
|
36
|
+
const variants = harness.variants
|
|
37
|
+
.map((variant) => variant.name)
|
|
38
|
+
.join(', ') || 'default';
|
|
39
|
+
const auth = harness.auth.available ? 'ready' : 'missing';
|
|
40
|
+
const name = formatHarnessLabel(harness);
|
|
41
|
+
const description = truncate(harness.description, 64);
|
|
42
|
+
return { name, variants, auth, description };
|
|
43
|
+
});
|
|
44
|
+
const headers = ['Harness', 'Variants', 'Auth', 'Description'];
|
|
45
|
+
const widths = [
|
|
46
|
+
Math.max(headers[0].length, ...rows.map((row) => row.name.length)),
|
|
47
|
+
Math.max(headers[1].length, ...rows.map((row) => row.variants.length)),
|
|
48
|
+
Math.max(headers[2].length, ...rows.map((row) => row.auth.length)),
|
|
49
|
+
Math.max(headers[3].length, ...rows.map((row) => row.description.length)),
|
|
50
|
+
];
|
|
51
|
+
const line = `+${widths.map((w) => '-'.repeat(w + 2)).join('+')}+`;
|
|
52
|
+
const mid = `+${widths.map((w) => '-'.repeat(w + 2)).join('+')}+`;
|
|
53
|
+
const end = `+${widths.map((w) => '-'.repeat(w + 2)).join('+')}+`;
|
|
54
|
+
console.log(line);
|
|
55
|
+
console.log(formatRow(headers, widths));
|
|
56
|
+
console.log(mid);
|
|
57
|
+
for (const row of rows) {
|
|
58
|
+
console.log(formatRow([row.name, row.variants, row.auth, row.description], widths));
|
|
59
|
+
}
|
|
60
|
+
console.log(end);
|
|
61
|
+
}
|
|
62
|
+
function renderHarnessDetail(harness) {
|
|
63
|
+
const variants = harness.variants.length
|
|
64
|
+
? harness.variants
|
|
65
|
+
: [{ name: 'default', description: 'Default harness configuration' }];
|
|
66
|
+
console.log(`Harness: ${harness.name}`);
|
|
67
|
+
if (harness.aliases?.length) {
|
|
68
|
+
console.log(`Aliases: ${harness.aliases.join(', ')}`);
|
|
69
|
+
}
|
|
70
|
+
console.log(`Description: ${harness.description}`);
|
|
71
|
+
console.log('Variants:');
|
|
72
|
+
for (const variant of variants) {
|
|
73
|
+
console.log(` - ${variant.name}: ${variant.description}`);
|
|
74
|
+
}
|
|
75
|
+
console.log('Auth:');
|
|
76
|
+
console.log(` - Status: ${harness.auth.available ? 'ready' : 'missing'}`);
|
|
77
|
+
console.log(` - Details: ${harness.auth.reason}`);
|
|
78
|
+
console.log(' - To enable:');
|
|
79
|
+
for (const instruction of harness.auth.instructions) {
|
|
80
|
+
console.log(` - ${instruction}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function formatHarnessLabel(harness) {
|
|
84
|
+
if (!harness.aliases?.length)
|
|
85
|
+
return harness.name;
|
|
86
|
+
return `${harness.name} (aliases: ${harness.aliases.join(', ')})`;
|
|
87
|
+
}
|
|
88
|
+
function formatRow(columns, widths) {
|
|
89
|
+
const cells = columns.map((value, idx) => ` ${value.padEnd(widths[idx])} `);
|
|
90
|
+
return `|${cells.join('|')}|`;
|
|
91
|
+
}
|
|
92
|
+
function truncate(value, max) {
|
|
93
|
+
if (value.length <= max)
|
|
94
|
+
return value;
|
|
95
|
+
return `${value.slice(0, Math.max(0, max - 3))}...`;
|
|
96
|
+
}
|