@qodalis/cli-server-logs 1.0.8 → 2.0.0-beta.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 DELETED
@@ -1,33 +0,0 @@
1
- # Cli extension
2
-
3
- The `@qodalis/cli-server-logs` package is a CLI extension designed to provide seamless server log management and analysis capabilities for the Qodalis CLI.
4
-
5
- # Features
6
-
7
- View Logs: Fetch and display server logs directly in the CLI.
8
- Filter Logs: Apply filters based on date, severity, or keywords.
9
- Download Logs: Download logs to a local file for further analysis.
10
- Integration: Integrates seamlessly with Qodalis CLI for server monitoring.
11
-
12
- # Installation
13
-
14
- ```bash
15
- packages add @qodalis/cli-server-logs
16
- ```
17
-
18
- This command downloads and registers the extension for use within the CLI environment.
19
-
20
- # Usage
21
-
22
- ```bash
23
- server-logs live
24
- server-logs live --level=error
25
- server-logs live --file # on Ctrl + C the logs are downloaded in a file
26
- server-logs live --pattern=text-to-search # supports regex
27
-
28
- server-logs --help # for more options
29
- ```
30
-
31
- # Dependencies
32
-
33
- This extension is dependent on a server which use signalR as a transport layer.
@@ -1,19 +0,0 @@
1
- import { NgModule } from '@angular/core';
2
- import { resolveCommandProcessorProvider } from '@qodalis/angular-cli';
3
- import { CliLogsCommandProcessor } from './processors/cli-logs-command-processor';
4
- import * as i0 from "@angular/core";
5
- export class CliServerLogsModule {
6
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
7
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule }); }
8
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule, providers: [resolveCommandProcessorProvider(CliLogsCommandProcessor)] }); }
9
- }
10
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule, decorators: [{
11
- type: NgModule,
12
- args: [{
13
- declarations: [],
14
- imports: [],
15
- exports: [],
16
- providers: [resolveCommandProcessorProvider(CliLogsCommandProcessor)],
17
- }]
18
- }] });
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLXNlcnZlci1sb2dzLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NlcnZlci1sb2dzL3NyYy9saWIvY2xpLXNlcnZlci1sb2dzLm1vZHVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOztBQVFsRixNQUFNLE9BQU8sbUJBQW1COytHQUFuQixtQkFBbUI7Z0hBQW5CLG1CQUFtQjtnSEFBbkIsbUJBQW1CLGFBRmpCLENBQUMsK0JBQStCLENBQUMsdUJBQXVCLENBQUMsQ0FBQzs7NEZBRTVELG1CQUFtQjtrQkFOL0IsUUFBUTttQkFBQztvQkFDTixZQUFZLEVBQUUsRUFBRTtvQkFDaEIsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsT0FBTyxFQUFFLEVBQUU7b0JBQ1gsU0FBUyxFQUFFLENBQUMsK0JBQStCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztpQkFDeEUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgcmVzb2x2ZUNvbW1hbmRQcm9jZXNzb3JQcm92aWRlciB9IGZyb20gJ0Bxb2RhbGlzL2FuZ3VsYXItY2xpJztcbmltcG9ydCB7IENsaUxvZ3NDb21tYW5kUHJvY2Vzc29yIH0gZnJvbSAnLi9wcm9jZXNzb3JzL2NsaS1sb2dzLWNvbW1hbmQtcHJvY2Vzc29yJztcblxuQE5nTW9kdWxlKHtcbiAgICBkZWNsYXJhdGlvbnM6IFtdLFxuICAgIGltcG9ydHM6IFtdLFxuICAgIGV4cG9ydHM6IFtdLFxuICAgIHByb3ZpZGVyczogW3Jlc29sdmVDb21tYW5kUHJvY2Vzc29yUHJvdmlkZXIoQ2xpTG9nc0NvbW1hbmRQcm9jZXNzb3IpXSxcbn0pXG5leHBvcnQgY2xhc3MgQ2xpU2VydmVyTG9nc01vZHVsZSB7fVxuIl19
@@ -1,173 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import * as signalR from '@microsoft/signalr';
3
- import { CliForegroundColor, DefaultLibraryAuthor, highlightTextWithBg, toQueryString, } from '@qodalis/cli-core';
4
- import { LIBRARY_VERSION } from '../version';
5
- import * as i0 from "@angular/core";
6
- const levels = ['verbose', 'debug', 'information', 'warning', 'error', 'fatal'];
7
- export class CliLogsCommandProcessor {
8
- constructor() {
9
- this.command = 'server-logs';
10
- this.description = 'Show live logs';
11
- this.processors = [];
12
- this.metadata = {
13
- requireServer: true,
14
- icon: '📜',
15
- requiredCoreVersion: '0.0.16',
16
- requiredCliVersion: '1.0.37',
17
- };
18
- this.parameters = [
19
- {
20
- name: 'pattern',
21
- type: 'string',
22
- description: 'The regex pattern to search for in the logs',
23
- required: false,
24
- validator: (value) => {
25
- const isValid = this.isValidRegex(value);
26
- return {
27
- valid: isValid,
28
- message: isValid
29
- ? undefined
30
- : 'Invalid regex pattern provided',
31
- };
32
- },
33
- },
34
- {
35
- name: 'level',
36
- type: 'string',
37
- description: 'The log level to filter by, e.g. ' + levels.join(', '),
38
- required: false,
39
- validator: (value) => {
40
- const isValid = levels.includes(value);
41
- return {
42
- valid: isValid,
43
- message: isValid
44
- ? undefined
45
- : 'Invalid log level provided, must be one of: ' +
46
- levels.join(', '),
47
- };
48
- },
49
- },
50
- {
51
- name: 'server',
52
- type: 'string',
53
- description: 'The server to connect to, e.g. "http://localhost:5000"',
54
- required: false,
55
- },
56
- {
57
- name: 'hub',
58
- type: 'string',
59
- description: 'The hub to connect to, e.g. "loghub" (default) or "loghub2"',
60
- required: false,
61
- },
62
- {
63
- name: 'file',
64
- type: 'boolean',
65
- description: 'Export logs to a file',
66
- required: false,
67
- },
68
- ];
69
- this.author = DefaultLibraryAuthor;
70
- this.version = LIBRARY_VERSION;
71
- this.processors?.push({
72
- command: 'live',
73
- description: this.description,
74
- parameters: this.parameters,
75
- processCommand: this.processCommand.bind(this),
76
- writeDescription: this.writeDescription.bind(this),
77
- });
78
- }
79
- async processCommand(command, context) {
80
- let qs = '?';
81
- const args = this.excludeKeys(command.args, ['server', 'hub', 'file']);
82
- if (Object.keys(args).length > 0) {
83
- qs += toQueryString(args);
84
- }
85
- const hub = command.args['hub'] || 'loghub';
86
- let server = command.args['server'] || '';
87
- server = server.replace(/\/+$/, '');
88
- const url = `${server}/${hub}${qs}`;
89
- console.log('Connecting to:', url);
90
- this.hubConnection = new signalR.HubConnectionBuilder()
91
- .withUrl(url)
92
- .build();
93
- const buffer = [];
94
- await this.hubConnection
95
- .start()
96
- .then(() => {
97
- console.log('SignalR connection started');
98
- context.writer.writeWarning('Connected to live logs');
99
- if (qs.length) {
100
- Object.keys(args).forEach((key) => {
101
- context.writer.writeWarning(`Filtering logs by: ${key}=${command.args[key]}`);
102
- });
103
- }
104
- let firstLog = true;
105
- let index = 0;
106
- this.hubConnection.on('log', (log) => {
107
- if (firstLog) {
108
- context.writer.writeln();
109
- }
110
- buffer.push(log);
111
- context.writer.writeln(`\x1b[33m${++index}\x1b[0m. ` +
112
- (command.args['pattern']
113
- ? highlightTextWithBg(log, new RegExp(command.args['pattern'], 'g'))
114
- : log));
115
- firstLog = false;
116
- });
117
- const subscription = context.onAbort.subscribe(() => {
118
- this.hubConnection.stop();
119
- context.writer.writeWarning('Disconnected from live logs');
120
- if (command.args['file']) {
121
- const filename = `logs-${new Date().toISOString()}.txt`;
122
- context.writer.writeToFile(filename, buffer.join('\n'));
123
- }
124
- subscription.unsubscribe();
125
- });
126
- })
127
- .catch((err) => {
128
- console.error('Error starting SignalR connection:', err);
129
- context.writer.writeError('Failed to connect to live logs');
130
- context.writer.writeError(err?.toString());
131
- });
132
- }
133
- writeDescription(context) {
134
- const { writer } = context;
135
- writer.writeln('Stream live server logs via SignalR');
136
- writer.writeln();
137
- writer.writeln('📋 Usage:');
138
- writer.writeln(` ${writer.wrapInColor('server-logs', CliForegroundColor.Cyan)} Start streaming`);
139
- writer.writeln(` ${writer.wrapInColor('server-logs --level=error', CliForegroundColor.Cyan)} Filter by level`);
140
- writer.writeln(` ${writer.wrapInColor('server-logs --pattern="Exception"', CliForegroundColor.Cyan)} Filter by regex`);
141
- writer.writeln(` ${writer.wrapInColor('server-logs --server=http://localhost:5000', CliForegroundColor.Cyan)} Custom server`);
142
- writer.writeln();
143
- writer.writeln(`⚙️ Options:`);
144
- writer.writeln(` ${writer.wrapInColor('--level', CliForegroundColor.Yellow)} Log level: verbose, debug, information, warning, error, fatal`);
145
- writer.writeln(` ${writer.wrapInColor('--pattern', CliForegroundColor.Yellow)} Regex pattern to highlight matches`);
146
- writer.writeln(` ${writer.wrapInColor('--server', CliForegroundColor.Yellow)} Server URL to connect to`);
147
- writer.writeln(` ${writer.wrapInColor('--hub', CliForegroundColor.Yellow)} Hub name (default: loghub)`);
148
- writer.writeln(` ${writer.wrapInColor('--file', CliForegroundColor.Yellow)} Export logs to a file on disconnect`);
149
- writer.writeln();
150
- writer.writeln(`💡 Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to stop streaming`);
151
- }
152
- excludeKeys(record, keysToExclude) {
153
- return Object.fromEntries(Object.entries(record).filter(([key]) => !keysToExclude.includes(key)));
154
- }
155
- isValidRegex(pattern) {
156
- try {
157
- new RegExp(pattern);
158
- return true;
159
- }
160
- catch (e) {
161
- return false;
162
- }
163
- }
164
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliLogsCommandProcessor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
165
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliLogsCommandProcessor, providedIn: 'root' }); }
166
- }
167
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliLogsCommandProcessor, decorators: [{
168
- type: Injectable,
169
- args: [{
170
- providedIn: 'root',
171
- }]
172
- }], ctorParameters: function () { return []; } });
173
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLWxvZ3MtY29tbWFuZC1wcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zZXJ2ZXItbG9ncy9zcmMvbGliL3Byb2Nlc3NvcnMvY2xpLWxvZ3MtY29tbWFuZC1wcm9jZXNzb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEtBQUssT0FBTyxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFDSCxrQkFBa0IsRUFHbEIsb0JBQW9CLEVBQ3BCLG1CQUFtQixFQUtuQixhQUFhLEdBQ2hCLE1BQU0sbUJBQW1CLENBQUM7QUFDM0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLFlBQVksQ0FBQzs7QUFFN0MsTUFBTSxNQUFNLEdBQUcsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBS2hGLE1BQU0sT0FBTyx1QkFBdUI7SUE0RWhDO1FBM0VBLFlBQU8sR0FBRyxhQUFhLENBQUM7UUFFeEIsZ0JBQVcsR0FBd0IsZ0JBQWdCLENBQUM7UUFFcEQsZUFBVSxHQUF3QyxFQUFFLENBQUM7UUFFckQsYUFBUSxHQUFzQztZQUMxQyxhQUFhLEVBQUUsSUFBSTtZQUNuQixJQUFJLEVBQUUsSUFBSTtZQUNWLG1CQUFtQixFQUFFLFFBQVE7WUFDN0Isa0JBQWtCLEVBQUUsUUFBUTtTQUMvQixDQUFDO1FBRUYsZUFBVSxHQUFrRDtZQUN4RDtnQkFDSSxJQUFJLEVBQUUsU0FBUztnQkFDZixJQUFJLEVBQUUsUUFBUTtnQkFDZCxXQUFXLEVBQUUsNkNBQTZDO2dCQUMxRCxRQUFRLEVBQUUsS0FBSztnQkFDZixTQUFTLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRTtvQkFDekIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxL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LENBQUMsQ0FBQztRQUNoSCxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssTUFBTSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsa0JBQWtCLENBQUMsTUFBTSxDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDekgsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLE1BQU0sQ0FBQyxPQUFPLENBQUMsWUFBWSxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUM1RyxDQUFDO0lBRU8sV0FBVyxDQUNmLE1BQVMsRUFDVCxhQUF1QjtRQUV2QixPQUFPLE1BQU0sQ0FBQyxXQUFXLENBQ3JCLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxDQUN6QixDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FDMUMsQ0FDVSxDQUFDO0lBQ3BCLENBQUM7SUFFTyxZQUFZLENBQUMsT0FBZTtRQUNoQyxJQUFJO1lBQ0EsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDcEIsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1IsT0FBTyxLQUFLLENBQUM7U0FDaEI7SUFDTCxDQUFDOytHQTlNUSx1QkFBdUI7bUhBQXZCLHVCQUF1QixjQUZwQixNQUFNOzs0RkFFVCx1QkFBdUI7a0JBSG5DLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgc2lnbmFsUiBmcm9tICdAbWljcm9zb2Z0L3NpZ25hbHInO1xuaW1wb3J0IHtcbiAgICBDbGlGb3JlZ3JvdW5kQ29sb3IsXG4gICAgQ2xpUHJvY2Vzc0NvbW1hbmQsXG4gICAgQ2xpUHJvY2Vzc29yTWV0YWRhdGEsXG4gICAgRGVmYXVsdExpYnJhcnlBdXRob3IsXG4gICAgaGlnaGxpZ2h0VGV4dFdpdGhCZyxcbiAgICBJQ2xpQ29tbWFuZEF1dGhvcixcbiAgICBJQ2xpQ29tbWFuZFBhcmFtZXRlckRlc2NyaXB0b3IsXG4gICAgSUNsaUNvbW1hbmRQcm9jZXNzb3IsXG4gICAgSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG4gICAgdG9RdWVyeVN0cmluZyxcbn0gZnJvbSAnQHFvZGFsaXMvY2xpLWNvcmUnO1xuaW1wb3J0IHsgTElCUkFSWV9WRVJTSU9OIH0gZnJvbSAnLi4vdmVyc2lvbic7XG5cbmNvbnN0IGxldmVscyA9IFsndmVyYm9zZScsICdkZWJ1ZycsICdpbmZvcm1hdGlvbicsICd3YXJuaW5nJywgJ2Vycm9yJywgJ2ZhdGFsJ107XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIENsaUxvZ3NDb21tYW5kUHJvY2Vzc29yIGltcGxlbWVudHMgSUNsaUNvbW1hbmRQcm9jZXNzb3Ige1xuICAgIGNvbW1hbmQgPSAnc2VydmVyLWxvZ3MnO1xuXG4gICAgZGVzY3JpcHRpb24/OiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnU2hvdyBsaXZlIGxvZ3MnO1xuXG4gICAgcHJvY2Vzc29ycz86IElDbGlDb21tYW5kUHJvY2Vzc29yW10gfCB1bmRlZmluZWQgPSBbXTtcblxuICAgIG1ldGFkYXRhPzogQ2xpUHJvY2Vzc29yTWV0YWRhdGEgfCB1bmRlZmluZWQgPSB7XG4gICAgICAgIHJlcXVpcmVTZXJ2ZXI6IHRydWUsXG4gICAgICAgIGljb246ICfwn5OcJyxcbiAgICAgICAgcmVxdWlyZWRDb3JlVmVyc2lvbjogJzAuMC4xNicsXG4gICAgICAgIHJlcXVpcmVkQ2xpVmVyc2lvbjogJzEuMC4zNycsXG4gICAgfTtcblxuICAgIHBhcmFtZXRlcnM/OiBJQ2xpQ29tbWFuZFBhcmFtZXRlckRlc2NyaXB0b3JbXSB8IHVuZGVmaW5lZCA9IFtcbiAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ3BhdHRlcm4nLFxuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZSByZWdleCBwYXR0ZXJuIHRvIHNlYXJjaCBmb3IgaW4gdGhlIGxvZ3MnLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgdmFsaWRhdG9yOiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzVmFsaWQgPSB0aGlzLmlzVmFsaWRSZWdleCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IGlzVmFsaWQsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGlzVmFsaWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICA6ICdJbnZhbGlkIHJlZ2V4IHBhdHRlcm4gcHJvdmlkZWQnLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiAnbGV2ZWwnLFxuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAnVGhlIGxvZyBsZXZlbCB0byBmaWx0ZXIgYnksIGUuZy4gJyArIGxldmVscy5qb2luKCcsICcpLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgICAgdmFsaWRhdG9yOiAodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzVmFsaWQgPSBsZXZlbHMuaW5jbHVkZXModmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQ6IGlzVmFsaWQsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGlzVmFsaWRcbiAgICAgICAgICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICA6ICdJbnZhbGlkIGxvZyBsZXZlbCBwcm92aWRlZCwgbXVzdCBiZSBvbmUgb2Y6ICcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMuam9pbignLCAnKSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ3NlcnZlcicsXG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICdUaGUgc2VydmVyIHRvIGNvbm5lY3QgdG8sIGUuZy4gXCJodHRwOi8vbG9jYWxob3N0OjUwMDBcIicsXG4gICAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6ICdodWInLFxuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICAnVGhlIGh1YiB0byBjb25uZWN0IHRvLCBlLmcuIFwibG9naHViXCIgKGRlZmF1bHQpIG9yIFwibG9naHViMlwiJyxcbiAgICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogJ2ZpbGUnLFxuICAgICAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246ICdFeHBvcnQgbG9ncyB0byBhIGZpbGUnLFxuICAgICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICB9LFxuICAgIF07XG5cbiAgICBhdXRob3I/OiBJQ2xpQ29tbWFuZEF1dGhvciB8IHVuZGVmaW5lZCA9IERlZmF1bHRMaWJyYXJ5QXV0aG9yO1xuXG4gICAgdmVyc2lvbiA9IExJQlJBUllfVkVSU0lPTjtcblxuICAgIHByaXZhdGUgaHViQ29ubmVjdGlvbiE6IHNpZ25hbFIuSHViQ29ubmVjdGlvbjtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnByb2Nlc3NvcnM/LnB1c2goe1xuICAgICAgICAgICAgY29tbWFuZDogJ2xpdmUnLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBwYXJhbWV0ZXJzOiB0aGlzLnBhcmFtZXRlcnMsXG4gICAgICAgICAgICBwcm9jZXNzQ29tbWFuZDogdGhpcy5wcm9jZXNzQ29tbWFuZC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgd3JpdGVEZXNjcmlwdGlvbjogdGhpcy53cml0ZURlc2NyaXB0aW9uLmJpbmQodGhpcyksXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIHByb2Nlc3NDb21tYW5kKFxuICAgICAgICBjb21tYW5kOiBDbGlQcm9jZXNzQ29tbWFuZCxcbiAgICAgICAgY29udGV4dDogSUNsaUV4ZWN1dGlvbkNvbnRleHQsXG4gICAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGxldCBxcyA9ICc/JztcblxuICAgICAgICBjb25zdCBhcmdzID0gdGhpcy5leGNsdWRlS2V5cyhjb21tYW5kLmFyZ3MsIFsnc2VydmVyJywgJ2h1YicsICdmaWxlJ10pO1xuXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhhcmdzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBxcyArPSB0b1F1ZXJ5U3RyaW5nKGFyZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaHViID0gY29tbWFuZC5hcmdzWydodWInXSB8fCAnbG9naHViJztcblxuICAgICAgICBsZXQgc2VydmVyID0gY29tbWFuZC5hcmdzWydzZXJ2ZXInXSB8fCAnJztcbiAgICAgICAgc2VydmVyID0gc2VydmVyLnJlcGxhY2UoL1xcLyskLywgJycpO1xuXG4gICAgICAgIGNvbnN0IHVybCA9IGAke3NlcnZlcn0vJHtodWJ9JHtxc31gO1xuXG4gICAgICAgIGNvbnNvbGUubG9nKCdDb25uZWN0aW5nIHRvOicsIHVybCk7XG5cbiAgICAgICAgdGhpcy5odWJDb25uZWN0aW9uID0gbmV3IHNpZ25hbFIuSHViQ29ubmVjdGlvbkJ1aWxkZXIoKVxuICAgICAgICAgICAgLndpdGhVcmwodXJsKVxuICAgICAgICAgICAgLmJ1aWxkKCk7XG5cbiAgICAgICAgY29uc3QgYnVmZmVyOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuaHViQ29ubmVjdGlvblxuICAgICAgICAgICAgLnN0YXJ0KClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnU2lnbmFsUiBjb25uZWN0aW9uIHN0YXJ0ZWQnKTtcblxuICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlV2FybmluZygnQ29ubmVjdGVkIHRvIGxpdmUgbG9ncycpO1xuICAgICAgICAgICAgICAgIGlmIChxcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoYXJncykuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZVdhcm5pbmcoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYEZpbHRlcmluZyBsb2dzIGJ5OiAke2tleX09JHtjb21tYW5kLmFyZ3Nba2V5XX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbGV0IGZpcnN0TG9nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5odWJDb25uZWN0aW9uLm9uKCdsb2cnLCAobG9nOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpcnN0TG9nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZWxuKCk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBidWZmZXIucHVzaChsb2cpO1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQud3JpdGVyLndyaXRlbG4oXG4gICAgICAgICAgICAgICAgICAgICAgICBgXFx4MWJbMzNtJHsrK2luZGV4fVxceDFiWzBtLiBgICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29tbWFuZC5hcmdzWydwYXR0ZXJuJ11cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBoaWdobGlnaHRUZXh0V2l0aEJnKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2csXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBSZWdFeHAoY29tbWFuZC5hcmdzWydwYXR0ZXJuJ10sICdnJyksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGxvZyksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIGZpcnN0TG9nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBjb250ZXh0Lm9uQWJvcnQuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5odWJDb25uZWN0aW9uLnN0b3AoKTtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVXYXJuaW5nKCdEaXNjb25uZWN0ZWQgZnJvbSBsaXZlIGxvZ3MnKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tbWFuZC5hcmdzWydmaWxlJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZpbGVuYW1lID0gYGxvZ3MtJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9LnR4dGA7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LndyaXRlci53cml0ZVRvRmlsZShmaWxlbmFtZSwgYnVmZmVyLmpvaW4oJ1xcbicpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igc3RhcnRpbmcgU2lnbmFsUiBjb25uZWN0aW9uOicsIGVycik7XG4gICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcignRmFpbGVkIHRvIGNvbm5lY3QgdG8gbGl2ZSBsb2dzJyk7XG4gICAgICAgICAgICAgICAgY29udGV4dC53cml0ZXIud3JpdGVFcnJvcihlcnI/LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgd3JpdGVEZXNjcmlwdGlvbihjb250ZXh0OiBJQ2xpRXhlY3V0aW9uQ29udGV4dCk6IHZvaWQge1xuICAgICAgICBjb25zdCB7IHdyaXRlciB9ID0gY29udGV4dDtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4oJ1N0cmVhbSBsaXZlIHNlcnZlciBsb2dzIHZpYSBTaWduYWxSJyk7XG4gICAgICAgIHdyaXRlci53cml0ZWxuKCk7XG4gICAgICAgIHdyaXRlci53cml0ZWxuKCfwn5OLIFVzYWdlOicpO1xuICAgICAgICB3cml0ZXIud3JpdGVsbihgICAke3dyaXRlci53cmFwSW5Db2xvcignc2VydmVyLWxvZ3MnLCBDbGlGb3JlZ3JvdW5kQ29sb3IuQ3lhbil9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXJ0IHN0cmVhbWluZ2ApO1xuICAgICAgICB3cml0ZXIud3JpdGVsbihgICAke3dyaXRlci53cmFwSW5Db2xvcignc2VydmVyLWxvZ3MgLS1sZXZlbD1lcnJvcicsIENsaUZvcmVncm91bmRDb2xvci5DeWFuKX0gICAgICAgICAgICAgICAgICAgICAgICBGaWx0ZXIgYnkgbGV2ZWxgKTtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4oYCAgJHt3cml0ZXIud3JhcEluQ29sb3IoJ3NlcnZlci1sb2dzIC0tcGF0dGVybj1cIkV4Y2VwdGlvblwiJywgQ2xpRm9yZWdyb3VuZENvbG9yLkN5YW4pfSAgICAgICAgICAgICAgICBGaWx0ZXIgYnkgcmVnZXhgKTtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4oYCAgJHt3cml0ZXIud3JhcEluQ29sb3IoJ3NlcnZlci1sb2dzIC0tc2VydmVyPWh0dHA6Ly9sb2NhbGhvc3Q6NTAwMCcsIENsaUZvcmVncm91bmRDb2xvci5DeWFuKX0gICAgICAgQ3VzdG9tIHNlcnZlcmApO1xuICAgICAgICB3cml0ZXIud3JpdGVsbigpO1xuICAgICAgICB3cml0ZXIud3JpdGVsbihg4pqZ77iPICBPcHRpb25zOmApO1xuICAgICAgICB3cml0ZXIud3JpdGVsbihgICAke3dyaXRlci53cmFwSW5Db2xvcignLS1sZXZlbCcsIENsaUZvcmVncm91bmRDb2xvci5ZZWxsb3cpfSAgICAgIExvZyBsZXZlbDogdmVyYm9zZSwgZGVidWcsIGluZm9ybWF0aW9uLCB3YXJuaW5nLCBlcnJvciwgZmF0YWxgKTtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4oYCAgJHt3cml0ZXIud3JhcEluQ29sb3IoJy0tcGF0dGVybicsIENsaUZvcmVncm91bmRDb2xvci5ZZWxsb3cpfSAgICBSZWdleCBwYXR0ZXJuIHRvIGhpZ2hsaWdodCBtYXRjaGVzYCk7XG4gICAgICAgIHdyaXRlci53cml0ZWxuKGAgICR7d3JpdGVyLndyYXBJbkNvbG9yKCctLXNlcnZlcicsIENsaUZvcmVncm91bmRDb2xvci5ZZWxsb3cpfSAgICAgU2VydmVyIFVSTCB0byBjb25uZWN0IHRvYCk7XG4gICAgICAgIHdyaXRlci53cml0ZWxuKGAgICR7d3JpdGVyLndyYXBJbkNvbG9yKCctLWh1YicsIENsaUZvcmVncm91bmRDb2xvci5ZZWxsb3cpfSAgICAgICAgSHViIG5hbWUgKGRlZmF1bHQ6IGxvZ2h1YilgKTtcbiAgICAgICAgd3JpdGVyLndyaXRlbG4oYCAgJHt3cml0ZXIud3JhcEluQ29sb3IoJy0tZmlsZScsIENsaUZvcmVncm91bmRDb2xvci5ZZWxsb3cpfSAgICAgICBFeHBvcnQgbG9ncyB0byBhIGZpbGUgb24gZGlzY29ubmVjdGApO1xuICAgICAgICB3cml0ZXIud3JpdGVsbigpO1xuICAgICAgICB3cml0ZXIud3JpdGVsbihg8J+SoSBQcmVzcyAke3dyaXRlci53cmFwSW5Db2xvcignQ3RybCtDJywgQ2xpRm9yZWdyb3VuZENvbG9yLlllbGxvdyl9IHRvIHN0b3Agc3RyZWFtaW5nYCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBleGNsdWRlS2V5czxUIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gICAgICAgIHJlY29yZDogVCxcbiAgICAgICAga2V5c1RvRXhjbHVkZTogc3RyaW5nW10sXG4gICAgKTogUGFydGlhbDxUPiB7XG4gICAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyhyZWNvcmQpLmZpbHRlcihcbiAgICAgICAgICAgICAgICAoW2tleV0pID0+ICFrZXlzVG9FeGNsdWRlLmluY2x1ZGVzKGtleSksXG4gICAgICAgICAgICApLFxuICAgICAgICApIGFzIFBhcnRpYWw8VD47XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1ZhbGlkUmVnZXgocGF0dGVybjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBuZXcgUmVnRXhwKHBhdHRlcm4pO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==
@@ -1,3 +0,0 @@
1
- // Automatically generated during build
2
- export const LIBRARY_VERSION = '1.0.8';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3NlcnZlci1sb2dzL3NyYy9saWIvdmVyc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSx1Q0FBdUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIlxuLy8gQXV0b21hdGljYWxseSBnZW5lcmF0ZWQgZHVyaW5nIGJ1aWxkXG5leHBvcnQgY29uc3QgTElCUkFSWV9WRVJTSU9OID0gJzEuMC44JztcbiAgIl19
@@ -1,5 +0,0 @@
1
- /*
2
- * Public API Surface of server-logs
3
- */
4
- export * from './lib/cli-server-logs.module';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL3NlcnZlci1sb2dzL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyw4QkFBOEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2Ygc2VydmVyLWxvZ3NcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9jbGktc2VydmVyLWxvZ3MubW9kdWxlJztcbiJdfQ==
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- export * from './public-api';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicW9kYWxpcy1jbGktc2VydmVyLWxvZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9zZXJ2ZXItbG9ncy9zcmMvcW9kYWxpcy1jbGktc2VydmVyLWxvZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
@@ -1,202 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, NgModule } from '@angular/core';
3
- import { resolveCommandProcessorProvider } from '@qodalis/angular-cli';
4
- import * as signalR from '@microsoft/signalr';
5
- import { DefaultLibraryAuthor, toQueryString, highlightTextWithBg, CliForegroundColor } from '@qodalis/cli-core';
6
-
7
- // Automatically generated during build
8
- const LIBRARY_VERSION = '1.0.8';
9
-
10
- const levels = ['verbose', 'debug', 'information', 'warning', 'error', 'fatal'];
11
- class CliLogsCommandProcessor {
12
- constructor() {
13
- this.command = 'server-logs';
14
- this.description = 'Show live logs';
15
- this.processors = [];
16
- this.metadata = {
17
- requireServer: true,
18
- icon: '📜',
19
- requiredCoreVersion: '0.0.16',
20
- requiredCliVersion: '1.0.37',
21
- };
22
- this.parameters = [
23
- {
24
- name: 'pattern',
25
- type: 'string',
26
- description: 'The regex pattern to search for in the logs',
27
- required: false,
28
- validator: (value) => {
29
- const isValid = this.isValidRegex(value);
30
- return {
31
- valid: isValid,
32
- message: isValid
33
- ? undefined
34
- : 'Invalid regex pattern provided',
35
- };
36
- },
37
- },
38
- {
39
- name: 'level',
40
- type: 'string',
41
- description: 'The log level to filter by, e.g. ' + levels.join(', '),
42
- required: false,
43
- validator: (value) => {
44
- const isValid = levels.includes(value);
45
- return {
46
- valid: isValid,
47
- message: isValid
48
- ? undefined
49
- : 'Invalid log level provided, must be one of: ' +
50
- levels.join(', '),
51
- };
52
- },
53
- },
54
- {
55
- name: 'server',
56
- type: 'string',
57
- description: 'The server to connect to, e.g. "http://localhost:5000"',
58
- required: false,
59
- },
60
- {
61
- name: 'hub',
62
- type: 'string',
63
- description: 'The hub to connect to, e.g. "loghub" (default) or "loghub2"',
64
- required: false,
65
- },
66
- {
67
- name: 'file',
68
- type: 'boolean',
69
- description: 'Export logs to a file',
70
- required: false,
71
- },
72
- ];
73
- this.author = DefaultLibraryAuthor;
74
- this.version = LIBRARY_VERSION;
75
- this.processors?.push({
76
- command: 'live',
77
- description: this.description,
78
- parameters: this.parameters,
79
- processCommand: this.processCommand.bind(this),
80
- writeDescription: this.writeDescription.bind(this),
81
- });
82
- }
83
- async processCommand(command, context) {
84
- let qs = '?';
85
- const args = this.excludeKeys(command.args, ['server', 'hub', 'file']);
86
- if (Object.keys(args).length > 0) {
87
- qs += toQueryString(args);
88
- }
89
- const hub = command.args['hub'] || 'loghub';
90
- let server = command.args['server'] || '';
91
- server = server.replace(/\/+$/, '');
92
- const url = `${server}/${hub}${qs}`;
93
- console.log('Connecting to:', url);
94
- this.hubConnection = new signalR.HubConnectionBuilder()
95
- .withUrl(url)
96
- .build();
97
- const buffer = [];
98
- await this.hubConnection
99
- .start()
100
- .then(() => {
101
- console.log('SignalR connection started');
102
- context.writer.writeWarning('Connected to live logs');
103
- if (qs.length) {
104
- Object.keys(args).forEach((key) => {
105
- context.writer.writeWarning(`Filtering logs by: ${key}=${command.args[key]}`);
106
- });
107
- }
108
- let firstLog = true;
109
- let index = 0;
110
- this.hubConnection.on('log', (log) => {
111
- if (firstLog) {
112
- context.writer.writeln();
113
- }
114
- buffer.push(log);
115
- context.writer.writeln(`\x1b[33m${++index}\x1b[0m. ` +
116
- (command.args['pattern']
117
- ? highlightTextWithBg(log, new RegExp(command.args['pattern'], 'g'))
118
- : log));
119
- firstLog = false;
120
- });
121
- const subscription = context.onAbort.subscribe(() => {
122
- this.hubConnection.stop();
123
- context.writer.writeWarning('Disconnected from live logs');
124
- if (command.args['file']) {
125
- const filename = `logs-${new Date().toISOString()}.txt`;
126
- context.writer.writeToFile(filename, buffer.join('\n'));
127
- }
128
- subscription.unsubscribe();
129
- });
130
- })
131
- .catch((err) => {
132
- console.error('Error starting SignalR connection:', err);
133
- context.writer.writeError('Failed to connect to live logs');
134
- context.writer.writeError(err?.toString());
135
- });
136
- }
137
- writeDescription(context) {
138
- const { writer } = context;
139
- writer.writeln('Stream live server logs via SignalR');
140
- writer.writeln();
141
- writer.writeln('📋 Usage:');
142
- writer.writeln(` ${writer.wrapInColor('server-logs', CliForegroundColor.Cyan)} Start streaming`);
143
- writer.writeln(` ${writer.wrapInColor('server-logs --level=error', CliForegroundColor.Cyan)} Filter by level`);
144
- writer.writeln(` ${writer.wrapInColor('server-logs --pattern="Exception"', CliForegroundColor.Cyan)} Filter by regex`);
145
- writer.writeln(` ${writer.wrapInColor('server-logs --server=http://localhost:5000', CliForegroundColor.Cyan)} Custom server`);
146
- writer.writeln();
147
- writer.writeln(`⚙️ Options:`);
148
- writer.writeln(` ${writer.wrapInColor('--level', CliForegroundColor.Yellow)} Log level: verbose, debug, information, warning, error, fatal`);
149
- writer.writeln(` ${writer.wrapInColor('--pattern', CliForegroundColor.Yellow)} Regex pattern to highlight matches`);
150
- writer.writeln(` ${writer.wrapInColor('--server', CliForegroundColor.Yellow)} Server URL to connect to`);
151
- writer.writeln(` ${writer.wrapInColor('--hub', CliForegroundColor.Yellow)} Hub name (default: loghub)`);
152
- writer.writeln(` ${writer.wrapInColor('--file', CliForegroundColor.Yellow)} Export logs to a file on disconnect`);
153
- writer.writeln();
154
- writer.writeln(`💡 Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to stop streaming`);
155
- }
156
- excludeKeys(record, keysToExclude) {
157
- return Object.fromEntries(Object.entries(record).filter(([key]) => !keysToExclude.includes(key)));
158
- }
159
- isValidRegex(pattern) {
160
- try {
161
- new RegExp(pattern);
162
- return true;
163
- }
164
- catch (e) {
165
- return false;
166
- }
167
- }
168
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliLogsCommandProcessor, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
169
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliLogsCommandProcessor, providedIn: 'root' }); }
170
- }
171
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliLogsCommandProcessor, decorators: [{
172
- type: Injectable,
173
- args: [{
174
- providedIn: 'root',
175
- }]
176
- }], ctorParameters: function () { return []; } });
177
-
178
- class CliServerLogsModule {
179
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
180
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule }); }
181
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule, providers: [resolveCommandProcessorProvider(CliLogsCommandProcessor)] }); }
182
- }
183
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: CliServerLogsModule, decorators: [{
184
- type: NgModule,
185
- args: [{
186
- declarations: [],
187
- imports: [],
188
- exports: [],
189
- providers: [resolveCommandProcessorProvider(CliLogsCommandProcessor)],
190
- }]
191
- }] });
192
-
193
- /*
194
- * Public API Surface of server-logs
195
- */
196
-
197
- /**
198
- * Generated bundle index. Do not edit.
199
- */
200
-
201
- export { CliServerLogsModule };
202
- //# sourceMappingURL=qodalis-cli-server-logs.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qodalis-cli-server-logs.mjs","sources":["../../../projects/server-logs/src/lib/version.ts","../../../projects/server-logs/src/lib/processors/cli-logs-command-processor.ts","../../../projects/server-logs/src/lib/cli-server-logs.module.ts","../../../projects/server-logs/src/public-api.ts","../../../projects/server-logs/src/qodalis-cli-server-logs.ts"],"sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '1.0.8';\n ","import { Injectable } from '@angular/core';\nimport * as signalR from '@microsoft/signalr';\nimport {\n CliForegroundColor,\n CliProcessCommand,\n CliProcessorMetadata,\n DefaultLibraryAuthor,\n highlightTextWithBg,\n ICliCommandAuthor,\n ICliCommandParameterDescriptor,\n ICliCommandProcessor,\n ICliExecutionContext,\n toQueryString,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\n\nconst levels = ['verbose', 'debug', 'information', 'warning', 'error', 'fatal'];\n\n@Injectable({\n providedIn: 'root',\n})\nexport class CliLogsCommandProcessor implements ICliCommandProcessor {\n command = 'server-logs';\n\n description?: string | undefined = 'Show live logs';\n\n processors?: ICliCommandProcessor[] | undefined = [];\n\n metadata?: CliProcessorMetadata | undefined = {\n requireServer: true,\n icon: '📜',\n requiredCoreVersion: '0.0.16',\n requiredCliVersion: '1.0.37',\n };\n\n parameters?: ICliCommandParameterDescriptor[] | undefined = [\n {\n name: 'pattern',\n type: 'string',\n description: 'The regex pattern to search for in the logs',\n required: false,\n validator: (value: string) => {\n const isValid = this.isValidRegex(value);\n return {\n valid: isValid,\n message: isValid\n ? undefined\n : 'Invalid regex pattern provided',\n };\n },\n },\n {\n name: 'level',\n type: 'string',\n description:\n 'The log level to filter by, e.g. ' + levels.join(', '),\n required: false,\n validator: (value: string) => {\n const isValid = levels.includes(value);\n\n return {\n valid: isValid,\n message: isValid\n ? undefined\n : 'Invalid log level provided, must be one of: ' +\n levels.join(', '),\n };\n },\n },\n {\n name: 'server',\n type: 'string',\n description:\n 'The server to connect to, e.g. \"http://localhost:5000\"',\n required: false,\n },\n {\n name: 'hub',\n type: 'string',\n description:\n 'The hub to connect to, e.g. \"loghub\" (default) or \"loghub2\"',\n required: false,\n },\n {\n name: 'file',\n type: 'boolean',\n description: 'Export logs to a file',\n required: false,\n },\n ];\n\n author?: ICliCommandAuthor | undefined = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n private hubConnection!: signalR.HubConnection;\n\n constructor() {\n this.processors?.push({\n command: 'live',\n description: this.description,\n parameters: this.parameters,\n processCommand: this.processCommand.bind(this),\n writeDescription: this.writeDescription.bind(this),\n });\n }\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n let qs = '?';\n\n const args = this.excludeKeys(command.args, ['server', 'hub', 'file']);\n\n if (Object.keys(args).length > 0) {\n qs += toQueryString(args);\n }\n\n const hub = command.args['hub'] || 'loghub';\n\n let server = command.args['server'] || '';\n server = server.replace(/\\/+$/, '');\n\n const url = `${server}/${hub}${qs}`;\n\n console.log('Connecting to:', url);\n\n this.hubConnection = new signalR.HubConnectionBuilder()\n .withUrl(url)\n .build();\n\n const buffer: string[] = [];\n\n await this.hubConnection\n .start()\n .then(() => {\n console.log('SignalR connection started');\n\n context.writer.writeWarning('Connected to live logs');\n if (qs.length) {\n Object.keys(args).forEach((key) => {\n context.writer.writeWarning(\n `Filtering logs by: ${key}=${command.args[key]}`,\n );\n });\n }\n\n let firstLog = true;\n let index = 0;\n\n this.hubConnection.on('log', (log: string) => {\n if (firstLog) {\n context.writer.writeln();\n }\n\n buffer.push(log);\n\n context.writer.writeln(\n `\\x1b[33m${++index}\\x1b[0m. ` +\n (command.args['pattern']\n ? highlightTextWithBg(\n log,\n new RegExp(command.args['pattern'], 'g'),\n )\n : log),\n );\n firstLog = false;\n });\n\n const subscription = context.onAbort.subscribe(() => {\n this.hubConnection.stop();\n context.writer.writeWarning('Disconnected from live logs');\n\n if (command.args['file']) {\n const filename = `logs-${new Date().toISOString()}.txt`;\n context.writer.writeToFile(filename, buffer.join('\\n'));\n }\n\n subscription.unsubscribe();\n });\n })\n .catch((err) => {\n console.error('Error starting SignalR connection:', err);\n context.writer.writeError('Failed to connect to live logs');\n context.writer.writeError(err?.toString());\n });\n }\n\n writeDescription(context: ICliExecutionContext): void {\n const { writer } = context;\n writer.writeln('Stream live server logs via SignalR');\n writer.writeln();\n writer.writeln('📋 Usage:');\n writer.writeln(` ${writer.wrapInColor('server-logs', CliForegroundColor.Cyan)} Start streaming`);\n writer.writeln(` ${writer.wrapInColor('server-logs --level=error', CliForegroundColor.Cyan)} Filter by level`);\n writer.writeln(` ${writer.wrapInColor('server-logs --pattern=\"Exception\"', CliForegroundColor.Cyan)} Filter by regex`);\n writer.writeln(` ${writer.wrapInColor('server-logs --server=http://localhost:5000', CliForegroundColor.Cyan)} Custom server`);\n writer.writeln();\n writer.writeln(`⚙️ Options:`);\n writer.writeln(` ${writer.wrapInColor('--level', CliForegroundColor.Yellow)} Log level: verbose, debug, information, warning, error, fatal`);\n writer.writeln(` ${writer.wrapInColor('--pattern', CliForegroundColor.Yellow)} Regex pattern to highlight matches`);\n writer.writeln(` ${writer.wrapInColor('--server', CliForegroundColor.Yellow)} Server URL to connect to`);\n writer.writeln(` ${writer.wrapInColor('--hub', CliForegroundColor.Yellow)} Hub name (default: loghub)`);\n writer.writeln(` ${writer.wrapInColor('--file', CliForegroundColor.Yellow)} Export logs to a file on disconnect`);\n writer.writeln();\n writer.writeln(`💡 Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to stop streaming`);\n }\n\n private excludeKeys<T extends Record<string, any>>(\n record: T,\n keysToExclude: string[],\n ): Partial<T> {\n return Object.fromEntries(\n Object.entries(record).filter(\n ([key]) => !keysToExclude.includes(key),\n ),\n ) as Partial<T>;\n }\n\n private isValidRegex(pattern: string): boolean {\n try {\n new RegExp(pattern);\n return true;\n } catch (e) {\n return false;\n }\n }\n}\n","import { NgModule } from '@angular/core';\nimport { resolveCommandProcessorProvider } from '@qodalis/angular-cli';\nimport { CliLogsCommandProcessor } from './processors/cli-logs-command-processor';\n\n@NgModule({\n declarations: [],\n imports: [],\n exports: [],\n providers: [resolveCommandProcessorProvider(CliLogsCommandProcessor)],\n})\nexport class CliServerLogsModule {}\n","/*\n * Public API Surface of server-logs\n */\n\nexport * from './lib/cli-server-logs.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- /**
2
- * Generated bundle index. Do not edit.
3
- */
4
- /// <amd-module name="@qodalis/cli-server-logs" />
5
- export * from './public-api';
@@ -1,6 +0,0 @@
1
- import * as i0 from "@angular/core";
2
- export declare class CliServerLogsModule {
3
- static ɵfac: i0.ɵɵFactoryDeclaration<CliServerLogsModule, never>;
4
- static ɵmod: i0.ɵɵNgModuleDeclaration<CliServerLogsModule, never, never, never>;
5
- static ɵinj: i0.ɵɵInjectorDeclaration<CliServerLogsModule>;
6
- }
@@ -1,19 +0,0 @@
1
- import { CliProcessCommand, CliProcessorMetadata, ICliCommandAuthor, ICliCommandParameterDescriptor, ICliCommandProcessor, ICliExecutionContext } from '@qodalis/cli-core';
2
- import * as i0 from "@angular/core";
3
- export declare class CliLogsCommandProcessor implements ICliCommandProcessor {
4
- command: string;
5
- description?: string | undefined;
6
- processors?: ICliCommandProcessor[] | undefined;
7
- metadata?: CliProcessorMetadata | undefined;
8
- parameters?: ICliCommandParameterDescriptor[] | undefined;
9
- author?: ICliCommandAuthor | undefined;
10
- version: string;
11
- private hubConnection;
12
- constructor();
13
- processCommand(command: CliProcessCommand, context: ICliExecutionContext): Promise<void>;
14
- writeDescription(context: ICliExecutionContext): void;
15
- private excludeKeys;
16
- private isValidRegex;
17
- static ɵfac: i0.ɵɵFactoryDeclaration<CliLogsCommandProcessor, never>;
18
- static ɵprov: i0.ɵɵInjectableDeclaration<CliLogsCommandProcessor>;
19
- }
package/lib/version.d.ts DELETED
@@ -1 +0,0 @@
1
- export declare const LIBRARY_VERSION = "1.0.8";