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