@jetstart/logs 1.5.2

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.
Files changed (45) hide show
  1. package/.eslintrc.json +6 -0
  2. package/README.md +122 -0
  3. package/dist/cli/formatter.d.ts +8 -0
  4. package/dist/cli/formatter.js +60 -0
  5. package/dist/cli/index.d.ts +9 -0
  6. package/dist/cli/index.js +24 -0
  7. package/dist/cli/viewer.d.ts +13 -0
  8. package/dist/cli/viewer.js +63 -0
  9. package/dist/filters/index.d.ts +10 -0
  10. package/dist/filters/index.js +45 -0
  11. package/dist/filters/level.d.ts +8 -0
  12. package/dist/filters/level.js +28 -0
  13. package/dist/filters/search.d.ts +7 -0
  14. package/dist/filters/search.js +29 -0
  15. package/dist/filters/source.d.ts +7 -0
  16. package/dist/filters/source.js +11 -0
  17. package/dist/index.d.ts +11 -0
  18. package/dist/index.js +26 -0
  19. package/dist/server/index.d.ts +26 -0
  20. package/dist/server/index.js +119 -0
  21. package/dist/server/storage.d.ts +15 -0
  22. package/dist/server/storage.js +70 -0
  23. package/dist/types/index.d.ts +14 -0
  24. package/dist/types/index.js +6 -0
  25. package/dist/utils/colors.d.ts +9 -0
  26. package/dist/utils/colors.js +50 -0
  27. package/dist/utils/index.d.ts +5 -0
  28. package/dist/utils/index.js +21 -0
  29. package/package.json +65 -0
  30. package/src/cli/formatter.ts +63 -0
  31. package/src/cli/index.ts +24 -0
  32. package/src/cli/viewer.ts +64 -0
  33. package/src/filters/index.ts +51 -0
  34. package/src/filters/level.ts +28 -0
  35. package/src/filters/search.ts +32 -0
  36. package/src/filters/source.ts +10 -0
  37. package/src/index.ts +19 -0
  38. package/src/server/index.ts +134 -0
  39. package/src/server/storage.ts +77 -0
  40. package/src/types/index.ts +15 -0
  41. package/src/utils/colors.ts +45 -0
  42. package/src/utils/index.ts +5 -0
  43. package/tests/filters.test.ts +81 -0
  44. package/tests/storage.test.ts +89 -0
  45. package/tsconfig.json +25 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Log Storage
3
+ * In-memory log storage with size limits
4
+ */
5
+
6
+ import { LogEntry, LogLevel, LogSource, LogStats } from '@jetstart/shared';
7
+
8
+ export class LogStorage {
9
+ private logs: LogEntry[] = [];
10
+ private maxEntries: number;
11
+
12
+ constructor(maxEntries: number = 10000) {
13
+ this.maxEntries = maxEntries;
14
+ }
15
+
16
+ add(entry: LogEntry): void {
17
+ this.logs.push(entry);
18
+
19
+ // Trim if exceeds max
20
+ if (this.logs.length > this.maxEntries) {
21
+ this.logs.shift();
22
+ }
23
+ }
24
+
25
+ getAll(): LogEntry[] {
26
+ return [...this.logs];
27
+ }
28
+
29
+ clear(): void {
30
+ this.logs = [];
31
+ }
32
+
33
+ getStats(): LogStats {
34
+ const stats: LogStats = {
35
+ totalLogs: this.logs.length,
36
+ errorCount: 0,
37
+ warningCount: 0,
38
+ lastLogTime: this.logs.length > 0 ? this.logs[this.logs.length - 1].timestamp : 0,
39
+ logsByLevel: {
40
+ [LogLevel.VERBOSE]: 0,
41
+ [LogLevel.DEBUG]: 0,
42
+ [LogLevel.INFO]: 0,
43
+ [LogLevel.WARN]: 0,
44
+ [LogLevel.ERROR]: 0,
45
+ [LogLevel.FATAL]: 0,
46
+ },
47
+ logsBySource: {
48
+ [LogSource.CLI]: 0,
49
+ [LogSource.CORE]: 0,
50
+ [LogSource.CLIENT]: 0,
51
+ [LogSource.BUILD]: 0,
52
+ [LogSource.NETWORK]: 0,
53
+ [LogSource.SYSTEM]: 0,
54
+ },
55
+ };
56
+
57
+ this.logs.forEach(log => {
58
+ // Count by level
59
+ stats.logsByLevel[log.level]++;
60
+
61
+ // Count errors and warnings
62
+ if (log.level === LogLevel.ERROR || log.level === LogLevel.FATAL) {
63
+ stats.errorCount++;
64
+ }
65
+ if (log.level === LogLevel.WARN) {
66
+ stats.warningCount++;
67
+ }
68
+
69
+ // Count by source
70
+ if (log.source in stats.logsBySource) {
71
+ stats.logsBySource[log.source]++;
72
+ }
73
+ });
74
+
75
+ return stats;
76
+ }
77
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Logs-specific types
3
+ */
4
+
5
+ export interface LogViewerOptions {
6
+ follow?: boolean;
7
+ tail?: number;
8
+ filter?: any;
9
+ }
10
+
11
+ export interface LogServerStats {
12
+ totalLogs: number;
13
+ activeClients: number;
14
+ uptime: number;
15
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Color Utilities
3
+ * Colors for different log levels and sources
4
+ */
5
+
6
+ import chalk from 'chalk';
7
+ import { LogLevel, LogSource } from '@jetstart/shared';
8
+
9
+ export function getColorForLevel(level: LogLevel): chalk.Chalk {
10
+ switch (level) {
11
+ case LogLevel.VERBOSE:
12
+ return chalk.gray;
13
+ case LogLevel.DEBUG:
14
+ return chalk.blue;
15
+ case LogLevel.INFO:
16
+ return chalk.green;
17
+ case LogLevel.WARN:
18
+ return chalk.yellow;
19
+ case LogLevel.ERROR:
20
+ return chalk.red;
21
+ case LogLevel.FATAL:
22
+ return chalk.bgRed.white;
23
+ default:
24
+ return chalk.white;
25
+ }
26
+ }
27
+
28
+ export function getColorForSource(source: LogSource): chalk.Chalk {
29
+ switch (source) {
30
+ case LogSource.CLI:
31
+ return chalk.cyan;
32
+ case LogSource.CORE:
33
+ return chalk.magenta;
34
+ case LogSource.CLIENT:
35
+ return chalk.green;
36
+ case LogSource.BUILD:
37
+ return chalk.yellow;
38
+ case LogSource.NETWORK:
39
+ return chalk.blue;
40
+ case LogSource.SYSTEM:
41
+ return chalk.gray;
42
+ default:
43
+ return chalk.white;
44
+ }
45
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Export all utilities
3
+ */
4
+
5
+ export * from './colors';
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Tests for log filters
3
+ */
4
+
5
+ import { filterByLevel, filterBySource, filterBySearch, applyFilters } from '../src/filters';
6
+ import { LogEntry, LogLevel, LogSource } from '@jetstart/shared';
7
+
8
+ describe('Log Filters', () => {
9
+ const sampleLogs: LogEntry[] = [
10
+ {
11
+ id: '1',
12
+ timestamp: Date.now(),
13
+ level: LogLevel.INFO,
14
+ tag: 'Test',
15
+ message: 'Info message',
16
+ source: LogSource.CLI,
17
+ },
18
+ {
19
+ id: '2',
20
+ timestamp: Date.now(),
21
+ level: LogLevel.ERROR,
22
+ tag: 'Test',
23
+ message: 'Error message',
24
+ source: LogSource.BUILD,
25
+ },
26
+ {
27
+ id: '3',
28
+ timestamp: Date.now(),
29
+ level: LogLevel.WARN,
30
+ tag: 'Test',
31
+ message: 'Warning message',
32
+ source: LogSource.CORE,
33
+ },
34
+ ];
35
+
36
+ describe('filterByLevel', () => {
37
+ it('should filter logs by level', () => {
38
+ const filtered = filterByLevel(sampleLogs, [LogLevel.ERROR]);
39
+ expect(filtered.length).toBe(1);
40
+ expect(filtered[0].level).toBe(LogLevel.ERROR);
41
+ });
42
+
43
+ it('should filter by multiple levels', () => {
44
+ const filtered = filterByLevel(sampleLogs, [LogLevel.ERROR, LogLevel.WARN]);
45
+ expect(filtered.length).toBe(2);
46
+ });
47
+ });
48
+
49
+ describe('filterBySource', () => {
50
+ it('should filter logs by source', () => {
51
+ const filtered = filterBySource(sampleLogs, [LogSource.BUILD]);
52
+ expect(filtered.length).toBe(1);
53
+ expect(filtered[0].source).toBe(LogSource.BUILD);
54
+ });
55
+ });
56
+
57
+ describe('filterBySearch', () => {
58
+ it('should search in message', () => {
59
+ const filtered = filterBySearch(sampleLogs, 'error');
60
+ expect(filtered.length).toBe(1);
61
+ expect(filtered[0].message).toContain('Error');
62
+ });
63
+
64
+ it('should be case-insensitive', () => {
65
+ const filtered = filterBySearch(sampleLogs, 'ERROR');
66
+ expect(filtered.length).toBe(1);
67
+ });
68
+ });
69
+
70
+ describe('applyFilters', () => {
71
+ it('should apply multiple filters', () => {
72
+ const filtered = applyFilters(sampleLogs, {
73
+ levels: [LogLevel.ERROR, LogLevel.WARN],
74
+ sources: [LogSource.BUILD],
75
+ });
76
+ expect(filtered.length).toBe(1);
77
+ expect(filtered[0].level).toBe(LogLevel.ERROR);
78
+ expect(filtered[0].source).toBe(LogSource.BUILD);
79
+ });
80
+ });
81
+ });
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Tests for log storage
3
+ */
4
+
5
+ import { LogStorage } from '../src/server/storage';
6
+ import { LogEntry, LogLevel, LogSource } from '@jetstart/shared';
7
+
8
+ describe('LogStorage', () => {
9
+ let storage: LogStorage;
10
+
11
+ beforeEach(() => {
12
+ storage = new LogStorage(100);
13
+ });
14
+
15
+ it('should add and retrieve logs', () => {
16
+ const log: LogEntry = {
17
+ id: '1',
18
+ timestamp: Date.now(),
19
+ level: LogLevel.INFO,
20
+ tag: 'Test',
21
+ message: 'Test message',
22
+ source: LogSource.CLI,
23
+ };
24
+
25
+ storage.add(log);
26
+ const logs = storage.getAll();
27
+
28
+ expect(logs.length).toBe(1);
29
+ expect(logs[0]).toEqual(log);
30
+ });
31
+
32
+ it('should enforce max entries limit', () => {
33
+ const smallStorage = new LogStorage(5);
34
+
35
+ for (let i = 0; i < 10; i++) {
36
+ smallStorage.add({
37
+ id: String(i),
38
+ timestamp: Date.now(),
39
+ level: LogLevel.INFO,
40
+ tag: 'Test',
41
+ message: `Message ${i}`,
42
+ source: LogSource.CLI,
43
+ });
44
+ }
45
+
46
+ const logs = smallStorage.getAll();
47
+ expect(logs.length).toBe(5);
48
+ expect(logs[0].id).toBe('5'); // First 5 removed
49
+ });
50
+
51
+ it('should clear all logs', () => {
52
+ storage.add({
53
+ id: '1',
54
+ timestamp: Date.now(),
55
+ level: LogLevel.INFO,
56
+ tag: 'Test',
57
+ message: 'Test',
58
+ source: LogSource.CLI,
59
+ });
60
+
61
+ storage.clear();
62
+ expect(storage.getAll().length).toBe(0);
63
+ });
64
+
65
+ it('should generate statistics', () => {
66
+ storage.add({
67
+ id: '1',
68
+ timestamp: Date.now(),
69
+ level: LogLevel.ERROR,
70
+ tag: 'Test',
71
+ message: 'Error',
72
+ source: LogSource.BUILD,
73
+ });
74
+
75
+ storage.add({
76
+ id: '2',
77
+ timestamp: Date.now(),
78
+ level: LogLevel.WARN,
79
+ tag: 'Test',
80
+ message: 'Warning',
81
+ source: LogSource.CORE,
82
+ });
83
+
84
+ const stats = storage.getStats();
85
+ expect(stats.totalLogs).toBe(2);
86
+ expect(stats.errorCount).toBe(1);
87
+ expect(stats.warningCount).toBe(1);
88
+ });
89
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "commonjs",
5
+ "lib": ["ES2022"],
6
+ "moduleResolution": "node",
7
+ "esModuleInterop": true,
8
+ "allowSyntheticDefaultImports": true,
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "composite": true,
17
+ "outDir": "./dist",
18
+ "rootDir": "./src"
19
+ },
20
+ "references": [
21
+ { "path": "../shared" }
22
+ ],
23
+ "include": ["src/**/*"],
24
+ "exclude": ["node_modules", "dist", "tests"]
25
+ }