@qodalis/cli 2.3.0 → 2.4.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/package.json +2 -2
- package/public-api.d.mts +1 -1
- package/public-api.d.ts +1 -1
- package/public-api.js +158 -83
- package/public-api.js.map +1 -1
- package/public-api.mjs +158 -83
- package/public-api.mjs.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qodalis/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Framework-agnostic CLI engine for @qodalis terminal applications.",
|
|
5
5
|
"author": "Nicolae Lupei, Qodalis Solutions",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"./assets/*": "./assets/*"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@qodalis/cli-core": "2.
|
|
33
|
+
"@qodalis/cli-core": "2.4.0",
|
|
34
34
|
"@xterm/xterm": "^6.0.0",
|
|
35
35
|
"@xterm/addon-fit": "^0.11.0",
|
|
36
36
|
"@xterm/addon-web-links": "^0.12.0",
|
package/public-api.d.mts
CHANGED
|
@@ -165,7 +165,7 @@ declare const CliKeyValueStore_TOKEN: any;
|
|
|
165
165
|
*/
|
|
166
166
|
declare const SyntaxHighlighterRegistry_TOKEN: any;
|
|
167
167
|
|
|
168
|
-
declare const LIBRARY_VERSION = "2.
|
|
168
|
+
declare const LIBRARY_VERSION = "2.4.0";
|
|
169
169
|
declare const API_VERSION = 2;
|
|
170
170
|
|
|
171
171
|
declare class CliAliasCommandProcessor implements ICliCommandProcessor {
|
package/public-api.d.ts
CHANGED
|
@@ -165,7 +165,7 @@ declare const CliKeyValueStore_TOKEN: any;
|
|
|
165
165
|
*/
|
|
166
166
|
declare const SyntaxHighlighterRegistry_TOKEN: any;
|
|
167
167
|
|
|
168
|
-
declare const LIBRARY_VERSION = "2.
|
|
168
|
+
declare const LIBRARY_VERSION = "2.4.0";
|
|
169
169
|
declare const API_VERSION = 2;
|
|
170
170
|
|
|
171
171
|
declare class CliAliasCommandProcessor implements ICliCommandProcessor {
|
package/public-api.js
CHANGED
|
@@ -519,7 +519,7 @@ var CliKeyValueStore_TOKEN = cliCore.createCliToken("cli-key-value-store");
|
|
|
519
519
|
var SyntaxHighlighterRegistry_TOKEN = cliCore.createCliToken("syntax-highlighter-registry");
|
|
520
520
|
|
|
521
521
|
// src/lib/version.ts
|
|
522
|
-
var LIBRARY_VERSION = "2.
|
|
522
|
+
var LIBRARY_VERSION = "2.4.0";
|
|
523
523
|
var API_VERSION = 2;
|
|
524
524
|
var ANONYMOUS = "\0anonymous";
|
|
525
525
|
function aliasOwner(context2) {
|
|
@@ -11188,7 +11188,78 @@ var CliServicesCommandProcessor = class {
|
|
|
11188
11188
|
);
|
|
11189
11189
|
}
|
|
11190
11190
|
};
|
|
11191
|
+
var CLI_EVENT_HISTORY_SIZE = 200;
|
|
11192
|
+
function matchesEventPattern(type, pattern) {
|
|
11193
|
+
if (pattern === "*") return true;
|
|
11194
|
+
if (pattern.endsWith(":*")) {
|
|
11195
|
+
return type.startsWith(pattern.slice(0, -1));
|
|
11196
|
+
}
|
|
11197
|
+
return type === pattern;
|
|
11198
|
+
}
|
|
11199
|
+
var CliEventBus = class {
|
|
11200
|
+
constructor(onHandlerError = (error) => console.error("[CLI] Event handler failed:", error), historySize = CLI_EVENT_HISTORY_SIZE) {
|
|
11201
|
+
this.onHandlerError = onHandlerError;
|
|
11202
|
+
this.historySize = historySize;
|
|
11203
|
+
this.subject = new rxjs.Subject();
|
|
11204
|
+
this.recent = [];
|
|
11205
|
+
this.disposed = false;
|
|
11206
|
+
}
|
|
11207
|
+
emit(type, data, options) {
|
|
11208
|
+
if (this.disposed) return;
|
|
11209
|
+
const event = {
|
|
11210
|
+
type,
|
|
11211
|
+
data,
|
|
11212
|
+
source: options?.source,
|
|
11213
|
+
timestamp: Date.now()
|
|
11214
|
+
};
|
|
11215
|
+
this.recent.push(event);
|
|
11216
|
+
if (this.recent.length > this.historySize) {
|
|
11217
|
+
this.recent.shift();
|
|
11218
|
+
}
|
|
11219
|
+
this.subject.next(event);
|
|
11220
|
+
}
|
|
11221
|
+
on(pattern, handler) {
|
|
11222
|
+
const subscription = this.events$(pattern).subscribe((event) => {
|
|
11223
|
+
try {
|
|
11224
|
+
handler(event);
|
|
11225
|
+
} catch (error) {
|
|
11226
|
+
this.onHandlerError(error, event);
|
|
11227
|
+
}
|
|
11228
|
+
});
|
|
11229
|
+
return () => subscription.unsubscribe();
|
|
11230
|
+
}
|
|
11231
|
+
once(pattern, handler) {
|
|
11232
|
+
let done = false;
|
|
11233
|
+
const unsubscribe = this.on(pattern, (event) => {
|
|
11234
|
+
if (done) return;
|
|
11235
|
+
done = true;
|
|
11236
|
+
unsubscribe();
|
|
11237
|
+
handler(event);
|
|
11238
|
+
});
|
|
11239
|
+
return unsubscribe;
|
|
11240
|
+
}
|
|
11241
|
+
events$(pattern = "*") {
|
|
11242
|
+
return this.subject.asObservable().pipe(operators.filter((event) => matchesEventPattern(event.type, pattern)));
|
|
11243
|
+
}
|
|
11244
|
+
history(pattern = "*", limit) {
|
|
11245
|
+
const matching = this.recent.filter(
|
|
11246
|
+
(event) => matchesEventPattern(event.type, pattern)
|
|
11247
|
+
);
|
|
11248
|
+
return limit !== void 0 ? matching.slice(-limit) : matching;
|
|
11249
|
+
}
|
|
11250
|
+
/** Stop delivering events and complete all observables. */
|
|
11251
|
+
dispose() {
|
|
11252
|
+
if (this.disposed) return;
|
|
11253
|
+
this.disposed = true;
|
|
11254
|
+
this.subject.complete();
|
|
11255
|
+
this.recent.length = 0;
|
|
11256
|
+
}
|
|
11257
|
+
};
|
|
11258
|
+
|
|
11259
|
+
// src/lib/processors/system/cli-events-command-processor.ts
|
|
11191
11260
|
var DATA_PREVIEW_LENGTH = 120;
|
|
11261
|
+
var SERVER_EVENT = "server:event";
|
|
11262
|
+
var SERVER_ENVELOPE_FIELDS = /* @__PURE__ */ new Set(["type", "timestamp"]);
|
|
11192
11263
|
var RESERVED_NAMESPACES = [
|
|
11193
11264
|
"boot",
|
|
11194
11265
|
"command",
|
|
@@ -11200,26 +11271,83 @@ var RESERVED_NAMESPACES = [
|
|
|
11200
11271
|
"session",
|
|
11201
11272
|
"user"
|
|
11202
11273
|
];
|
|
11274
|
+
function serverEventOf(event) {
|
|
11275
|
+
return event.type === SERVER_EVENT ? event.data : void 0;
|
|
11276
|
+
}
|
|
11277
|
+
function matchesFilter(event, filter2) {
|
|
11278
|
+
const remote = serverEventOf(event);
|
|
11279
|
+
if (!remote) {
|
|
11280
|
+
return !filter2.server && matchesEventPattern(event.type, filter2.pattern);
|
|
11281
|
+
}
|
|
11282
|
+
if (filter2.local) return false;
|
|
11283
|
+
if (filter2.server && remote.server.toLowerCase() !== filter2.server.toLowerCase()) return false;
|
|
11284
|
+
return matchesEventPattern(remote.type, filter2.pattern) || matchesEventPattern(SERVER_EVENT, filter2.pattern);
|
|
11285
|
+
}
|
|
11203
11286
|
function canSee(event, context2) {
|
|
11204
11287
|
return !event.type.startsWith("user:") || cliCore.cliAuthorize(context2, cliCore.CliUsersPermissions.AuditRead);
|
|
11205
11288
|
}
|
|
11289
|
+
function formatServerEventFields(data) {
|
|
11290
|
+
if (!data || typeof data !== "object") return "";
|
|
11291
|
+
const parts = [];
|
|
11292
|
+
for (const [key, value] of Object.entries(data)) {
|
|
11293
|
+
if (SERVER_ENVELOPE_FIELDS.has(key) || value === void 0 || value === null) continue;
|
|
11294
|
+
const text = typeof value === "string" ? value : JSON.stringify(value);
|
|
11295
|
+
parts.push(`${key}=${/\s/.test(text) ? JSON.stringify(text) : text}`);
|
|
11296
|
+
}
|
|
11297
|
+
return shorten(parts.join(" "));
|
|
11298
|
+
}
|
|
11299
|
+
function shorten(text) {
|
|
11300
|
+
return text.length > DATA_PREVIEW_LENGTH ? `${text.slice(0, DATA_PREVIEW_LENGTH - 1)}\u2026` : text;
|
|
11301
|
+
}
|
|
11206
11302
|
function formatEvent(event, context2) {
|
|
11207
11303
|
const { writer } = context2;
|
|
11208
|
-
const
|
|
11209
|
-
|
|
11304
|
+
const remote = serverEventOf(event);
|
|
11305
|
+
let time = event.timestamp;
|
|
11306
|
+
let type = event.type;
|
|
11307
|
+
let source = event.source;
|
|
11210
11308
|
let data = "";
|
|
11211
|
-
if (
|
|
11309
|
+
if (remote) {
|
|
11310
|
+
const sent = remote.data?.timestamp;
|
|
11311
|
+
if (typeof sent === "string" && !isNaN(Date.parse(sent))) time = sent;
|
|
11312
|
+
type = remote.type;
|
|
11313
|
+
source = remote.server;
|
|
11314
|
+
data = formatServerEventFields(remote.data);
|
|
11315
|
+
} else if (event.data !== void 0) {
|
|
11212
11316
|
try {
|
|
11213
11317
|
data = JSON.stringify(event.data) ?? "";
|
|
11214
11318
|
} catch {
|
|
11215
11319
|
data = String(event.data);
|
|
11216
11320
|
}
|
|
11217
|
-
|
|
11218
|
-
data = `${data.slice(0, DATA_PREVIEW_LENGTH - 1)}\u2026`;
|
|
11219
|
-
}
|
|
11321
|
+
data = shorten(data);
|
|
11220
11322
|
}
|
|
11221
|
-
|
|
11323
|
+
const when = new Date(time).toISOString().slice(11, 23);
|
|
11324
|
+
const from = source ? ` ${writer.wrapInColor(`[${source}]`, remote ? cliCore.CliForegroundColor.Magenta : cliCore.CliForegroundColor.Blue)}` : "";
|
|
11325
|
+
return `${writer.wrapInColor(when, cliCore.CliForegroundColor.Yellow)} ${writer.wrapInColor(type, cliCore.CliForegroundColor.Cyan)}${from}${data ? ` ${data}` : ""}`;
|
|
11326
|
+
}
|
|
11327
|
+
function filterOf(command2) {
|
|
11328
|
+
const server = command2.args["server"] ?? command2.args["s"];
|
|
11329
|
+
return {
|
|
11330
|
+
pattern: cliCore.joinShellWords(command2.value ?? "") || "*",
|
|
11331
|
+
server: server === void 0 || server === true ? void 0 : String(server),
|
|
11332
|
+
local: !!(command2.args["local"] || command2.args["l"])
|
|
11333
|
+
};
|
|
11222
11334
|
}
|
|
11335
|
+
var FILTER_PARAMETERS = [
|
|
11336
|
+
{
|
|
11337
|
+
name: "server",
|
|
11338
|
+
aliases: ["s"],
|
|
11339
|
+
type: "string",
|
|
11340
|
+
description: "Only the events of this server",
|
|
11341
|
+
required: false
|
|
11342
|
+
},
|
|
11343
|
+
{
|
|
11344
|
+
name: "local",
|
|
11345
|
+
aliases: ["l"],
|
|
11346
|
+
type: "boolean",
|
|
11347
|
+
description: "Only the terminal's own events",
|
|
11348
|
+
required: false
|
|
11349
|
+
}
|
|
11350
|
+
];
|
|
11223
11351
|
function busOf(context2) {
|
|
11224
11352
|
if (!context2.events) {
|
|
11225
11353
|
context2.writer.writeError(
|
|
@@ -11231,7 +11359,7 @@ function busOf(context2) {
|
|
|
11231
11359
|
var CliEventsCommandProcessor = class {
|
|
11232
11360
|
constructor() {
|
|
11233
11361
|
this.command = "events";
|
|
11234
|
-
this.description = "Watch, list and emit events
|
|
11362
|
+
this.description = "Watch, list and emit events of the terminal and the connected servers";
|
|
11235
11363
|
this.author = cliCore.DefaultLibraryAuthor;
|
|
11236
11364
|
this.version = "1.0.0";
|
|
11237
11365
|
this.metadata = {
|
|
@@ -11244,16 +11372,17 @@ var CliEventsCommandProcessor = class {
|
|
|
11244
11372
|
command: "watch",
|
|
11245
11373
|
description: "Print events as they happen (Ctrl+C to stop)",
|
|
11246
11374
|
acceptsRawInput: true,
|
|
11375
|
+
parameters: FILTER_PARAMETERS,
|
|
11247
11376
|
processCommand: async (command2, context2) => {
|
|
11248
11377
|
const bus = busOf(context2);
|
|
11249
11378
|
if (!bus) return;
|
|
11250
|
-
const
|
|
11379
|
+
const filter2 = filterOf(command2);
|
|
11251
11380
|
context2.writer.writeInfo(
|
|
11252
|
-
`Watching ${context2.writer.wrapInColor(pattern, cliCore.CliForegroundColor.Cyan)} \u2014 press Ctrl+C to stop`
|
|
11381
|
+
`Watching ${context2.writer.wrapInColor(filter2.pattern, cliCore.CliForegroundColor.Cyan)} \u2014 press Ctrl+C to stop`
|
|
11253
11382
|
);
|
|
11254
11383
|
await new Promise((resolve) => {
|
|
11255
|
-
const off = bus.on(
|
|
11256
|
-
if (canSee(event, context2)) {
|
|
11384
|
+
const off = bus.on("*", (event) => {
|
|
11385
|
+
if (matchesFilter(event, filter2) && canSee(event, context2)) {
|
|
11257
11386
|
context2.writer.writeln(formatEvent(event, context2));
|
|
11258
11387
|
}
|
|
11259
11388
|
});
|
|
@@ -11279,6 +11408,12 @@ var CliEventsCommandProcessor = class {
|
|
|
11279
11408
|
context2.writer.writeln(
|
|
11280
11409
|
` events watch boot:completed ${t.t("cli.events.watch.help.one_type", "One type")}`
|
|
11281
11410
|
);
|
|
11411
|
+
context2.writer.writeln(
|
|
11412
|
+
` events watch job:* -s node ${t.t("cli.events.watch.help.server_jobs", "Job events of the server node")}`
|
|
11413
|
+
);
|
|
11414
|
+
context2.writer.writeln(
|
|
11415
|
+
` events watch --local ${t.t("cli.events.watch.help.local_only", "Only the terminal's own events")}`
|
|
11416
|
+
);
|
|
11282
11417
|
}
|
|
11283
11418
|
},
|
|
11284
11419
|
{
|
|
@@ -11287,6 +11422,7 @@ var CliEventsCommandProcessor = class {
|
|
|
11287
11422
|
description: "Show recent events (kept in memory, not persisted)",
|
|
11288
11423
|
acceptsRawInput: true,
|
|
11289
11424
|
parameters: [
|
|
11425
|
+
...FILTER_PARAMETERS,
|
|
11290
11426
|
{
|
|
11291
11427
|
name: "limit",
|
|
11292
11428
|
aliases: ["n"],
|
|
@@ -11298,13 +11434,13 @@ var CliEventsCommandProcessor = class {
|
|
|
11298
11434
|
processCommand: async (command2, context2) => {
|
|
11299
11435
|
const bus = busOf(context2);
|
|
11300
11436
|
if (!bus) return;
|
|
11301
|
-
const
|
|
11437
|
+
const filter2 = filterOf(command2);
|
|
11302
11438
|
const limit = Number(
|
|
11303
11439
|
command2.args["limit"] ?? command2.args["n"] ?? 20
|
|
11304
11440
|
);
|
|
11305
|
-
const events = bus.history(
|
|
11441
|
+
const events = bus.history("*").filter((event) => matchesFilter(event, filter2) && canSee(event, context2)).slice(-(limit > 0 ? limit : 20));
|
|
11306
11442
|
if (events.length === 0) {
|
|
11307
|
-
context2.writer.writeInfo(`No events matching ${pattern}`);
|
|
11443
|
+
context2.writer.writeInfo(`No events matching ${filter2.pattern}`);
|
|
11308
11444
|
return;
|
|
11309
11445
|
}
|
|
11310
11446
|
for (const event of events) {
|
|
@@ -11323,6 +11459,9 @@ var CliEventsCommandProcessor = class {
|
|
|
11323
11459
|
context2.writer.writeln(
|
|
11324
11460
|
` events log server:* -n 50 ${t.t("cli.events.log.help.last_50_server", "Last 50 server events")}`
|
|
11325
11461
|
);
|
|
11462
|
+
context2.writer.writeln(
|
|
11463
|
+
` events log job:failed ${t.t("cli.events.log.help.failed_jobs", "Recent failed job runs, on every server")}`
|
|
11464
|
+
);
|
|
11326
11465
|
}
|
|
11327
11466
|
},
|
|
11328
11467
|
{
|
|
@@ -11394,6 +11533,9 @@ var CliEventsCommandProcessor = class {
|
|
|
11394
11533
|
writer.writeln(
|
|
11395
11534
|
t.t("cli.events.help.patterns", "Patterns: an exact type (package:installed), a namespace (package:*) or * for all.")
|
|
11396
11535
|
);
|
|
11536
|
+
writer.writeln(
|
|
11537
|
+
t.t("cli.events.help.servers", "Events of the connected servers (job runs, user, token and file changes, ...) are shown with the server name; each server sends only the events you may see. Filter with --server <name>, or --local for the terminal's own events.")
|
|
11538
|
+
);
|
|
11397
11539
|
writer.writeln(
|
|
11398
11540
|
t.t("cli.events.help.in_memory", "Events are kept in memory for this terminal only; nothing is persisted.")
|
|
11399
11541
|
);
|
|
@@ -21999,73 +22141,6 @@ function createServerModule() {
|
|
|
21999
22141
|
services: []
|
|
22000
22142
|
};
|
|
22001
22143
|
}
|
|
22002
|
-
var CLI_EVENT_HISTORY_SIZE = 200;
|
|
22003
|
-
function matchesEventPattern(type, pattern) {
|
|
22004
|
-
if (pattern === "*") return true;
|
|
22005
|
-
if (pattern.endsWith(":*")) {
|
|
22006
|
-
return type.startsWith(pattern.slice(0, -1));
|
|
22007
|
-
}
|
|
22008
|
-
return type === pattern;
|
|
22009
|
-
}
|
|
22010
|
-
var CliEventBus = class {
|
|
22011
|
-
constructor(onHandlerError = (error) => console.error("[CLI] Event handler failed:", error), historySize = CLI_EVENT_HISTORY_SIZE) {
|
|
22012
|
-
this.onHandlerError = onHandlerError;
|
|
22013
|
-
this.historySize = historySize;
|
|
22014
|
-
this.subject = new rxjs.Subject();
|
|
22015
|
-
this.recent = [];
|
|
22016
|
-
this.disposed = false;
|
|
22017
|
-
}
|
|
22018
|
-
emit(type, data, options) {
|
|
22019
|
-
if (this.disposed) return;
|
|
22020
|
-
const event = {
|
|
22021
|
-
type,
|
|
22022
|
-
data,
|
|
22023
|
-
source: options?.source,
|
|
22024
|
-
timestamp: Date.now()
|
|
22025
|
-
};
|
|
22026
|
-
this.recent.push(event);
|
|
22027
|
-
if (this.recent.length > this.historySize) {
|
|
22028
|
-
this.recent.shift();
|
|
22029
|
-
}
|
|
22030
|
-
this.subject.next(event);
|
|
22031
|
-
}
|
|
22032
|
-
on(pattern, handler) {
|
|
22033
|
-
const subscription = this.events$(pattern).subscribe((event) => {
|
|
22034
|
-
try {
|
|
22035
|
-
handler(event);
|
|
22036
|
-
} catch (error) {
|
|
22037
|
-
this.onHandlerError(error, event);
|
|
22038
|
-
}
|
|
22039
|
-
});
|
|
22040
|
-
return () => subscription.unsubscribe();
|
|
22041
|
-
}
|
|
22042
|
-
once(pattern, handler) {
|
|
22043
|
-
let done = false;
|
|
22044
|
-
const unsubscribe = this.on(pattern, (event) => {
|
|
22045
|
-
if (done) return;
|
|
22046
|
-
done = true;
|
|
22047
|
-
unsubscribe();
|
|
22048
|
-
handler(event);
|
|
22049
|
-
});
|
|
22050
|
-
return unsubscribe;
|
|
22051
|
-
}
|
|
22052
|
-
events$(pattern = "*") {
|
|
22053
|
-
return this.subject.asObservable().pipe(operators.filter((event) => matchesEventPattern(event.type, pattern)));
|
|
22054
|
-
}
|
|
22055
|
-
history(pattern = "*", limit) {
|
|
22056
|
-
const matching = this.recent.filter(
|
|
22057
|
-
(event) => matchesEventPattern(event.type, pattern)
|
|
22058
|
-
);
|
|
22059
|
-
return limit !== void 0 ? matching.slice(-limit) : matching;
|
|
22060
|
-
}
|
|
22061
|
-
/** Stop delivering events and complete all observables. */
|
|
22062
|
-
dispose() {
|
|
22063
|
-
if (this.disposed) return;
|
|
22064
|
-
this.disposed = true;
|
|
22065
|
-
this.subject.complete();
|
|
22066
|
-
this.recent.length = 0;
|
|
22067
|
-
}
|
|
22068
|
-
};
|
|
22069
22144
|
|
|
22070
22145
|
// src/lib/editor/syntax/registry.ts
|
|
22071
22146
|
var SyntaxHighlighterRegistry = class {
|