@objectstack/core 1.0.4 → 1.0.5

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 (125) hide show
  1. package/.turbo/turbo-build.log +58 -0
  2. package/CHANGELOG.md +12 -0
  3. package/dist/index.cjs +4294 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +1777 -0
  6. package/dist/index.d.ts +1776 -21
  7. package/dist/index.js +4246 -23
  8. package/dist/index.js.map +1 -0
  9. package/package.json +4 -4
  10. package/tsconfig.json +1 -3
  11. package/dist/api-registry-plugin.d.ts +0 -54
  12. package/dist/api-registry-plugin.d.ts.map +0 -1
  13. package/dist/api-registry-plugin.js +0 -53
  14. package/dist/api-registry-plugin.test.d.ts +0 -2
  15. package/dist/api-registry-plugin.test.d.ts.map +0 -1
  16. package/dist/api-registry-plugin.test.js +0 -334
  17. package/dist/api-registry.d.ts +0 -259
  18. package/dist/api-registry.d.ts.map +0 -1
  19. package/dist/api-registry.js +0 -600
  20. package/dist/api-registry.test.d.ts +0 -2
  21. package/dist/api-registry.test.d.ts.map +0 -1
  22. package/dist/api-registry.test.js +0 -957
  23. package/dist/contracts/data-engine.d.ts +0 -62
  24. package/dist/contracts/data-engine.d.ts.map +0 -1
  25. package/dist/contracts/data-engine.js +0 -1
  26. package/dist/contracts/http-server.d.ts +0 -119
  27. package/dist/contracts/http-server.d.ts.map +0 -1
  28. package/dist/contracts/http-server.js +0 -11
  29. package/dist/contracts/logger.d.ts +0 -63
  30. package/dist/contracts/logger.d.ts.map +0 -1
  31. package/dist/contracts/logger.js +0 -1
  32. package/dist/dependency-resolver.d.ts +0 -62
  33. package/dist/dependency-resolver.d.ts.map +0 -1
  34. package/dist/dependency-resolver.js +0 -317
  35. package/dist/dependency-resolver.test.d.ts +0 -2
  36. package/dist/dependency-resolver.test.d.ts.map +0 -1
  37. package/dist/dependency-resolver.test.js +0 -241
  38. package/dist/health-monitor.d.ts +0 -65
  39. package/dist/health-monitor.d.ts.map +0 -1
  40. package/dist/health-monitor.js +0 -269
  41. package/dist/health-monitor.test.d.ts +0 -2
  42. package/dist/health-monitor.test.d.ts.map +0 -1
  43. package/dist/health-monitor.test.js +0 -68
  44. package/dist/hot-reload.d.ts +0 -79
  45. package/dist/hot-reload.d.ts.map +0 -1
  46. package/dist/hot-reload.js +0 -313
  47. package/dist/index.d.ts.map +0 -1
  48. package/dist/kernel-base.d.ts +0 -84
  49. package/dist/kernel-base.d.ts.map +0 -1
  50. package/dist/kernel-base.js +0 -219
  51. package/dist/kernel.d.ts +0 -113
  52. package/dist/kernel.d.ts.map +0 -1
  53. package/dist/kernel.js +0 -472
  54. package/dist/kernel.test.d.ts +0 -2
  55. package/dist/kernel.test.d.ts.map +0 -1
  56. package/dist/kernel.test.js +0 -414
  57. package/dist/lite-kernel.d.ts +0 -55
  58. package/dist/lite-kernel.d.ts.map +0 -1
  59. package/dist/lite-kernel.js +0 -112
  60. package/dist/lite-kernel.test.d.ts +0 -2
  61. package/dist/lite-kernel.test.d.ts.map +0 -1
  62. package/dist/lite-kernel.test.js +0 -161
  63. package/dist/logger.d.ts +0 -71
  64. package/dist/logger.d.ts.map +0 -1
  65. package/dist/logger.js +0 -312
  66. package/dist/logger.test.d.ts +0 -2
  67. package/dist/logger.test.d.ts.map +0 -1
  68. package/dist/logger.test.js +0 -92
  69. package/dist/plugin-loader.d.ts +0 -164
  70. package/dist/plugin-loader.d.ts.map +0 -1
  71. package/dist/plugin-loader.js +0 -319
  72. package/dist/plugin-loader.test.d.ts +0 -2
  73. package/dist/plugin-loader.test.d.ts.map +0 -1
  74. package/dist/plugin-loader.test.js +0 -348
  75. package/dist/qa/adapter.d.ts +0 -14
  76. package/dist/qa/adapter.d.ts.map +0 -1
  77. package/dist/qa/adapter.js +0 -1
  78. package/dist/qa/http-adapter.d.ts +0 -16
  79. package/dist/qa/http-adapter.d.ts.map +0 -1
  80. package/dist/qa/http-adapter.js +0 -107
  81. package/dist/qa/index.d.ts +0 -4
  82. package/dist/qa/index.d.ts.map +0 -1
  83. package/dist/qa/index.js +0 -3
  84. package/dist/qa/runner.d.ts +0 -27
  85. package/dist/qa/runner.d.ts.map +0 -1
  86. package/dist/qa/runner.js +0 -157
  87. package/dist/security/index.d.ts +0 -17
  88. package/dist/security/index.d.ts.map +0 -1
  89. package/dist/security/index.js +0 -17
  90. package/dist/security/permission-manager.d.ts +0 -96
  91. package/dist/security/permission-manager.d.ts.map +0 -1
  92. package/dist/security/permission-manager.js +0 -235
  93. package/dist/security/permission-manager.test.d.ts +0 -2
  94. package/dist/security/permission-manager.test.d.ts.map +0 -1
  95. package/dist/security/permission-manager.test.js +0 -220
  96. package/dist/security/plugin-config-validator.d.ts +0 -79
  97. package/dist/security/plugin-config-validator.d.ts.map +0 -1
  98. package/dist/security/plugin-config-validator.js +0 -166
  99. package/dist/security/plugin-config-validator.test.d.ts +0 -2
  100. package/dist/security/plugin-config-validator.test.d.ts.map +0 -1
  101. package/dist/security/plugin-config-validator.test.js +0 -223
  102. package/dist/security/plugin-permission-enforcer.d.ts +0 -154
  103. package/dist/security/plugin-permission-enforcer.d.ts.map +0 -1
  104. package/dist/security/plugin-permission-enforcer.js +0 -323
  105. package/dist/security/plugin-permission-enforcer.test.d.ts +0 -2
  106. package/dist/security/plugin-permission-enforcer.test.d.ts.map +0 -1
  107. package/dist/security/plugin-permission-enforcer.test.js +0 -205
  108. package/dist/security/plugin-signature-verifier.d.ts +0 -96
  109. package/dist/security/plugin-signature-verifier.d.ts.map +0 -1
  110. package/dist/security/plugin-signature-verifier.js +0 -250
  111. package/dist/security/sandbox-runtime.d.ts +0 -115
  112. package/dist/security/sandbox-runtime.d.ts.map +0 -1
  113. package/dist/security/sandbox-runtime.js +0 -311
  114. package/dist/security/security-scanner.d.ts +0 -92
  115. package/dist/security/security-scanner.d.ts.map +0 -1
  116. package/dist/security/security-scanner.js +0 -273
  117. package/dist/types.d.ts +0 -89
  118. package/dist/types.d.ts.map +0 -1
  119. package/dist/types.js +0 -1
  120. package/dist/utils/env.d.ts +0 -20
  121. package/dist/utils/env.d.ts.map +0 -1
  122. package/dist/utils/env.js +0 -46
  123. package/dist/utils/env.test.d.ts +0 -2
  124. package/dist/utils/env.test.d.ts.map +0 -1
  125. package/dist/utils/env.test.js +0 -52
@@ -1,161 +0,0 @@
1
- import { describe, it, expect, beforeEach } from 'vitest';
2
- import { LiteKernel } from './lite-kernel';
3
- describe('LiteKernel with Configurable Logger', () => {
4
- let kernel;
5
- beforeEach(() => {
6
- kernel = new LiteKernel();
7
- });
8
- describe('Logger Configuration', () => {
9
- it('should create kernel with default logger', () => {
10
- expect(kernel).toBeDefined();
11
- });
12
- it('should create kernel with custom logger config', async () => {
13
- const customKernel = new LiteKernel({
14
- logger: {
15
- level: 'debug',
16
- format: 'pretty',
17
- sourceLocation: true
18
- }
19
- });
20
- expect(customKernel).toBeDefined();
21
- // Cleanup
22
- await customKernel.bootstrap();
23
- await customKernel.shutdown();
24
- });
25
- it('should create kernel with file logging config', async () => {
26
- const fileKernel = new LiteKernel({
27
- logger: {
28
- level: 'info',
29
- format: 'json',
30
- file: '/tmp/test-kernel.log'
31
- }
32
- });
33
- expect(fileKernel).toBeDefined();
34
- // Cleanup
35
- await fileKernel.bootstrap();
36
- await fileKernel.shutdown();
37
- });
38
- });
39
- describe('Plugin Context Logger', () => {
40
- it('should provide logger to plugins', async () => {
41
- let loggerReceived = false;
42
- const testPlugin = {
43
- name: 'test-plugin',
44
- init: async (ctx) => {
45
- if (ctx.logger) {
46
- loggerReceived = true;
47
- ctx.logger.info('Plugin initialized', { plugin: 'test-plugin' });
48
- }
49
- }
50
- };
51
- kernel.use(testPlugin);
52
- await kernel.bootstrap();
53
- expect(loggerReceived).toBe(true);
54
- await kernel.shutdown();
55
- });
56
- it('should allow plugins to use all log levels', async () => {
57
- const logCalls = [];
58
- const loggingPlugin = {
59
- name: 'logging-plugin',
60
- init: async (ctx) => {
61
- ctx.logger.debug('Debug message');
62
- logCalls.push('debug');
63
- ctx.logger.info('Info message');
64
- logCalls.push('info');
65
- ctx.logger.warn('Warning message');
66
- logCalls.push('warn');
67
- ctx.logger.error('Error message');
68
- logCalls.push('error');
69
- }
70
- };
71
- kernel.use(loggingPlugin);
72
- await kernel.bootstrap();
73
- expect(logCalls).toContain('debug');
74
- expect(logCalls).toContain('info');
75
- expect(logCalls).toContain('warn');
76
- expect(logCalls).toContain('error');
77
- await kernel.shutdown();
78
- });
79
- it('should support metadata in logs', async () => {
80
- const metadataPlugin = {
81
- name: 'metadata-plugin',
82
- init: async (ctx) => {
83
- ctx.logger.info('User action', {
84
- userId: '123',
85
- action: 'create',
86
- resource: 'document'
87
- });
88
- }
89
- };
90
- kernel.use(metadataPlugin);
91
- await kernel.bootstrap();
92
- await kernel.shutdown();
93
- });
94
- });
95
- describe('Kernel Lifecycle Logging', () => {
96
- it('should log bootstrap process', async () => {
97
- const plugin = {
98
- name: 'lifecycle-test',
99
- init: async () => {
100
- // Init logic
101
- },
102
- start: async () => {
103
- // Start logic
104
- }
105
- };
106
- kernel.use(plugin);
107
- await kernel.bootstrap();
108
- expect(kernel.isRunning()).toBe(true);
109
- await kernel.shutdown();
110
- });
111
- it('should log shutdown process', async () => {
112
- const plugin = {
113
- name: 'shutdown-test',
114
- init: async () => { },
115
- destroy: async () => {
116
- // Cleanup
117
- }
118
- };
119
- kernel.use(plugin);
120
- await kernel.bootstrap();
121
- await kernel.shutdown();
122
- expect(kernel.getState()).toBe('stopped');
123
- });
124
- });
125
- describe('Environment Compatibility', () => {
126
- it('should work in Node.js environment', async () => {
127
- const nodeKernel = new LiteKernel({
128
- logger: {
129
- level: 'info',
130
- format: 'json'
131
- }
132
- });
133
- const plugin = {
134
- name: 'node-test',
135
- init: async (ctx) => {
136
- ctx.logger.info('Running in Node.js');
137
- }
138
- };
139
- nodeKernel.use(plugin);
140
- await nodeKernel.bootstrap();
141
- await nodeKernel.shutdown();
142
- });
143
- it('should support browser-friendly logging', async () => {
144
- const browserKernel = new LiteKernel({
145
- logger: {
146
- level: 'info',
147
- format: 'pretty'
148
- }
149
- });
150
- const plugin = {
151
- name: 'browser-test',
152
- init: async (ctx) => {
153
- ctx.logger.info('Browser-friendly format');
154
- }
155
- };
156
- browserKernel.use(plugin);
157
- await browserKernel.bootstrap();
158
- await browserKernel.shutdown();
159
- });
160
- });
161
- });
package/dist/logger.d.ts DELETED
@@ -1,71 +0,0 @@
1
- import type { LoggerConfig } from '@objectstack/spec/system';
2
- import type { Logger } from '@objectstack/spec/contracts';
3
- /**
4
- * Universal Logger Implementation
5
- *
6
- * A configurable logger that works in both browser and Node.js environments.
7
- * - Node.js: Uses Pino for high-performance structured logging
8
- * - Browser: Simple console-based implementation
9
- *
10
- * Features:
11
- * - Structured logging with multiple formats (json, text, pretty)
12
- * - Log level filtering
13
- * - Sensitive data redaction
14
- * - File logging with rotation (Node.js only via Pino)
15
- * - Browser console integration
16
- * - Distributed tracing support (traceId, spanId)
17
- */
18
- export declare class ObjectLogger implements Logger {
19
- private config;
20
- private isNode;
21
- private pinoLogger?;
22
- private pinoInstance?;
23
- private require?;
24
- constructor(config?: Partial<LoggerConfig>);
25
- /**
26
- * Initialize Pino logger for Node.js
27
- */
28
- private initPinoLogger;
29
- /**
30
- * Redact sensitive keys from context object (for browser)
31
- */
32
- private redactSensitive;
33
- /**
34
- * Format log entry for browser
35
- */
36
- private formatBrowserLog;
37
- /**
38
- * Log using browser console
39
- */
40
- private logBrowser;
41
- /**
42
- * Public logging methods
43
- */
44
- debug(message: string, meta?: Record<string, any>): void;
45
- info(message: string, meta?: Record<string, any>): void;
46
- warn(message: string, meta?: Record<string, any>): void;
47
- error(message: string, errorOrMeta?: Error | Record<string, any>, meta?: Record<string, any>): void;
48
- fatal(message: string, errorOrMeta?: Error | Record<string, any>, meta?: Record<string, any>): void;
49
- /**
50
- * Create a child logger with additional context
51
- * Note: Child loggers share the parent's Pino instance
52
- */
53
- child(context: Record<string, any>): ObjectLogger;
54
- /**
55
- * Set trace context for distributed tracing
56
- */
57
- withTrace(traceId: string, spanId?: string): ObjectLogger;
58
- /**
59
- * Cleanup resources
60
- */
61
- destroy(): Promise<void>;
62
- /**
63
- * Compatibility method for console.log usage
64
- */
65
- log(message: string, ...args: any[]): void;
66
- }
67
- /**
68
- * Create a logger instance
69
- */
70
- export declare function createLogger(config?: Partial<LoggerConfig>): ObjectLogger;
71
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,MAAM;IACvC,OAAO,CAAC,MAAM,CAAkJ;IAChK,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,UAAU,CAAC,CAAM;IACzB,OAAO,CAAC,YAAY,CAAC,CAAM;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAM;gBAEV,MAAM,GAAE,OAAO,CAAC,YAAY,CAAM;IAwB9C;;OAEG;IACH,OAAO,CAAC,cAAc;IAuGtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQxD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAQvD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBnG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAmBnG;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY;IAYjD;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;IAIzD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAEzE"}
package/dist/logger.js DELETED
@@ -1,312 +0,0 @@
1
- import { isNode } from './utils/env.js';
2
- /**
3
- * Universal Logger Implementation
4
- *
5
- * A configurable logger that works in both browser and Node.js environments.
6
- * - Node.js: Uses Pino for high-performance structured logging
7
- * - Browser: Simple console-based implementation
8
- *
9
- * Features:
10
- * - Structured logging with multiple formats (json, text, pretty)
11
- * - Log level filtering
12
- * - Sensitive data redaction
13
- * - File logging with rotation (Node.js only via Pino)
14
- * - Browser console integration
15
- * - Distributed tracing support (traceId, spanId)
16
- */
17
- export class ObjectLogger {
18
- constructor(config = {}) {
19
- // Detect runtime environment
20
- this.isNode = isNode;
21
- // Set defaults
22
- this.config = {
23
- name: config.name,
24
- level: config.level ?? 'info',
25
- format: config.format ?? (this.isNode ? 'json' : 'pretty'),
26
- redact: config.redact ?? ['password', 'token', 'secret', 'key'],
27
- sourceLocation: config.sourceLocation ?? false,
28
- file: config.file,
29
- rotation: config.rotation ?? {
30
- maxSize: '10m',
31
- maxFiles: 5
32
- }
33
- };
34
- // Initialize Pino logger for Node.js
35
- if (this.isNode) {
36
- this.initPinoLogger();
37
- }
38
- }
39
- /**
40
- * Initialize Pino logger for Node.js
41
- */
42
- initPinoLogger() {
43
- if (!this.isNode)
44
- return;
45
- try {
46
- // Create require function dynamically for Node.js (avoids bundling issues in browser)
47
- // @ts-ignore - dynamic import of Node.js module
48
- const { createRequire } = eval('require("module")');
49
- this.require = createRequire(import.meta.url);
50
- // Synchronous import for Pino using createRequire (works in ESM)
51
- const pino = this.require('pino');
52
- // Build Pino options
53
- const pinoOptions = {
54
- level: this.config.level,
55
- redact: {
56
- paths: this.config.redact,
57
- censor: '***REDACTED***'
58
- }
59
- };
60
- // Add name if provided
61
- if (this.config.name) {
62
- pinoOptions.name = this.config.name;
63
- }
64
- // Transport configuration for pretty printing or file output
65
- const targets = [];
66
- // Console transport
67
- if (this.config.format === 'pretty') {
68
- // Check if pino-pretty is available
69
- let hasPretty = false;
70
- try {
71
- this.require.resolve('pino-pretty');
72
- hasPretty = true;
73
- }
74
- catch (e) {
75
- // ignore
76
- }
77
- if (hasPretty) {
78
- targets.push({
79
- target: 'pino-pretty',
80
- options: {
81
- colorize: true,
82
- translateTime: 'SYS:standard',
83
- ignore: 'pid,hostname'
84
- },
85
- level: this.config.level
86
- });
87
- }
88
- else {
89
- console.warn('[Logger] pino-pretty not found. Install it for pretty logging: pnpm add -D pino-pretty');
90
- // Fallback to text/simple
91
- targets.push({
92
- target: 'pino/file',
93
- options: { destination: 1 },
94
- level: this.config.level
95
- });
96
- }
97
- }
98
- else if (this.config.format === 'json') {
99
- // JSON to stdout
100
- targets.push({
101
- target: 'pino/file',
102
- options: { destination: 1 }, // stdout
103
- level: this.config.level
104
- });
105
- }
106
- else {
107
- // text format (simple)
108
- targets.push({
109
- target: 'pino/file',
110
- options: { destination: 1 },
111
- level: this.config.level
112
- });
113
- }
114
- // File transport (if configured)
115
- if (this.config.file) {
116
- targets.push({
117
- target: 'pino/file',
118
- options: {
119
- destination: this.config.file,
120
- mkdir: true
121
- },
122
- level: this.config.level
123
- });
124
- }
125
- // Create transport
126
- if (targets.length > 0) {
127
- pinoOptions.transport = targets.length === 1 ? targets[0] : { targets };
128
- }
129
- // Create Pino logger
130
- this.pinoInstance = pino(pinoOptions);
131
- this.pinoLogger = this.pinoInstance;
132
- }
133
- catch (error) {
134
- // Fallback to console if Pino is not available
135
- console.warn('[Logger] Pino not available, falling back to console:', error);
136
- this.pinoLogger = null;
137
- }
138
- }
139
- /**
140
- * Redact sensitive keys from context object (for browser)
141
- */
142
- redactSensitive(obj) {
143
- if (!obj || typeof obj !== 'object')
144
- return obj;
145
- const redacted = Array.isArray(obj) ? [...obj] : { ...obj };
146
- for (const key in redacted) {
147
- const lowerKey = key.toLowerCase();
148
- const shouldRedact = this.config.redact.some((pattern) => lowerKey.includes(pattern.toLowerCase()));
149
- if (shouldRedact) {
150
- redacted[key] = '***REDACTED***';
151
- }
152
- else if (typeof redacted[key] === 'object' && redacted[key] !== null) {
153
- redacted[key] = this.redactSensitive(redacted[key]);
154
- }
155
- }
156
- return redacted;
157
- }
158
- /**
159
- * Format log entry for browser
160
- */
161
- formatBrowserLog(level, message, context) {
162
- if (this.config.format === 'json') {
163
- return JSON.stringify({
164
- timestamp: new Date().toISOString(),
165
- level,
166
- message,
167
- ...context
168
- });
169
- }
170
- if (this.config.format === 'text') {
171
- const parts = [new Date().toISOString(), level.toUpperCase(), message];
172
- if (context && Object.keys(context).length > 0) {
173
- parts.push(JSON.stringify(context));
174
- }
175
- return parts.join(' | ');
176
- }
177
- // Pretty format
178
- const levelColors = {
179
- debug: '\x1b[36m', // Cyan
180
- info: '\x1b[32m', // Green
181
- warn: '\x1b[33m', // Yellow
182
- error: '\x1b[31m', // Red
183
- fatal: '\x1b[35m', // Magenta
184
- silent: ''
185
- };
186
- const reset = '\x1b[0m';
187
- const color = levelColors[level] || '';
188
- let output = `${color}[${level.toUpperCase()}]${reset} ${message}`;
189
- if (context && Object.keys(context).length > 0) {
190
- output += ` ${JSON.stringify(context, null, 2)}`;
191
- }
192
- return output;
193
- }
194
- /**
195
- * Log using browser console
196
- */
197
- logBrowser(level, message, context, error) {
198
- const redactedContext = context ? this.redactSensitive(context) : undefined;
199
- const mergedContext = error ? { ...redactedContext, error: { message: error.message, stack: error.stack } } : redactedContext;
200
- const formatted = this.formatBrowserLog(level, message, mergedContext);
201
- const consoleMethod = level === 'debug' ? 'debug' :
202
- level === 'info' ? 'log' :
203
- level === 'warn' ? 'warn' :
204
- level === 'error' || level === 'fatal' ? 'error' :
205
- 'log';
206
- console[consoleMethod](formatted);
207
- }
208
- /**
209
- * Public logging methods
210
- */
211
- debug(message, meta) {
212
- if (this.isNode && this.pinoLogger) {
213
- this.pinoLogger.debug(meta || {}, message);
214
- }
215
- else {
216
- this.logBrowser('debug', message, meta);
217
- }
218
- }
219
- info(message, meta) {
220
- if (this.isNode && this.pinoLogger) {
221
- this.pinoLogger.info(meta || {}, message);
222
- }
223
- else {
224
- this.logBrowser('info', message, meta);
225
- }
226
- }
227
- warn(message, meta) {
228
- if (this.isNode && this.pinoLogger) {
229
- this.pinoLogger.warn(meta || {}, message);
230
- }
231
- else {
232
- this.logBrowser('warn', message, meta);
233
- }
234
- }
235
- error(message, errorOrMeta, meta) {
236
- let error;
237
- let context = {};
238
- if (errorOrMeta instanceof Error) {
239
- error = errorOrMeta;
240
- context = meta || {};
241
- }
242
- else {
243
- context = errorOrMeta || {};
244
- }
245
- if (this.isNode && this.pinoLogger) {
246
- const errorContext = error ? { err: error, ...context } : context;
247
- this.pinoLogger.error(errorContext, message);
248
- }
249
- else {
250
- this.logBrowser('error', message, context, error);
251
- }
252
- }
253
- fatal(message, errorOrMeta, meta) {
254
- let error;
255
- let context = {};
256
- if (errorOrMeta instanceof Error) {
257
- error = errorOrMeta;
258
- context = meta || {};
259
- }
260
- else {
261
- context = errorOrMeta || {};
262
- }
263
- if (this.isNode && this.pinoLogger) {
264
- const errorContext = error ? { err: error, ...context } : context;
265
- this.pinoLogger.fatal(errorContext, message);
266
- }
267
- else {
268
- this.logBrowser('fatal', message, context, error);
269
- }
270
- }
271
- /**
272
- * Create a child logger with additional context
273
- * Note: Child loggers share the parent's Pino instance
274
- */
275
- child(context) {
276
- const childLogger = new ObjectLogger(this.config);
277
- // For Node.js with Pino, create a Pino child logger
278
- if (this.isNode && this.pinoInstance) {
279
- childLogger.pinoLogger = this.pinoInstance.child(context);
280
- childLogger.pinoInstance = this.pinoInstance;
281
- }
282
- return childLogger;
283
- }
284
- /**
285
- * Set trace context for distributed tracing
286
- */
287
- withTrace(traceId, spanId) {
288
- return this.child({ traceId, spanId });
289
- }
290
- /**
291
- * Cleanup resources
292
- */
293
- async destroy() {
294
- if (this.pinoLogger && this.pinoLogger.flush) {
295
- await new Promise((resolve) => {
296
- this.pinoLogger.flush(() => resolve());
297
- });
298
- }
299
- }
300
- /**
301
- * Compatibility method for console.log usage
302
- */
303
- log(message, ...args) {
304
- this.info(message, args.length > 0 ? { args } : undefined);
305
- }
306
- }
307
- /**
308
- * Create a logger instance
309
- */
310
- export function createLogger(config) {
311
- return new ObjectLogger(config);
312
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=logger.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../src/logger.test.ts"],"names":[],"mappings":""}
@@ -1,92 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { createLogger } from './logger';
3
- describe('ObjectLogger', () => {
4
- let logger;
5
- beforeEach(() => {
6
- logger = createLogger();
7
- });
8
- afterEach(async () => {
9
- await logger.destroy();
10
- });
11
- describe('Basic Logging', () => {
12
- it('should create a logger with default config', () => {
13
- expect(logger).toBeDefined();
14
- expect(logger.info).toBeDefined();
15
- expect(logger.debug).toBeDefined();
16
- expect(logger.warn).toBeDefined();
17
- expect(logger.error).toBeDefined();
18
- });
19
- it('should log info messages', () => {
20
- expect(() => logger.info('Test message')).not.toThrow();
21
- });
22
- it('should log debug messages', () => {
23
- expect(() => logger.debug('Debug message')).not.toThrow();
24
- });
25
- it('should log warn messages', () => {
26
- expect(() => logger.warn('Warning message')).not.toThrow();
27
- });
28
- it('should log error messages', () => {
29
- const error = new Error('Test error');
30
- expect(() => logger.error('Error occurred', error)).not.toThrow();
31
- });
32
- it('should log with metadata', () => {
33
- expect(() => logger.info('Message with metadata', { userId: '123', action: 'login' })).not.toThrow();
34
- });
35
- });
36
- describe('Configuration', () => {
37
- it('should respect log level configuration', async () => {
38
- const warnLogger = createLogger({ level: 'warn' });
39
- // These should not throw but might not output anything
40
- expect(() => warnLogger.debug('Debug message')).not.toThrow();
41
- expect(() => warnLogger.info('Info message')).not.toThrow();
42
- expect(() => warnLogger.warn('Warning message')).not.toThrow();
43
- await warnLogger.destroy();
44
- });
45
- it('should support different formats', async () => {
46
- const jsonLogger = createLogger({ format: 'json' });
47
- const textLogger = createLogger({ format: 'text' });
48
- const prettyLogger = createLogger({ format: 'pretty' });
49
- expect(() => jsonLogger.info('JSON format')).not.toThrow();
50
- expect(() => textLogger.info('Text format')).not.toThrow();
51
- expect(() => prettyLogger.info('Pretty format')).not.toThrow();
52
- await jsonLogger.destroy();
53
- await textLogger.destroy();
54
- await prettyLogger.destroy();
55
- });
56
- it('should redact sensitive keys', async () => {
57
- const logger = createLogger({ redact: ['password', 'apiKey'] });
58
- // This should work without exposing the password
59
- expect(() => logger.info('User login', {
60
- username: 'john',
61
- password: 'secret123',
62
- apiKey: 'key-12345'
63
- })).not.toThrow();
64
- await logger.destroy();
65
- });
66
- });
67
- describe('Child Loggers', () => {
68
- it('should create child logger with context', () => {
69
- const childLogger = logger.child({ service: 'api', requestId: '123' });
70
- expect(childLogger).toBeDefined();
71
- expect(() => childLogger.info('Child log message')).not.toThrow();
72
- });
73
- it('should support trace context', () => {
74
- const tracedLogger = logger.withTrace('trace-123', 'span-456');
75
- expect(tracedLogger).toBeDefined();
76
- expect(() => tracedLogger.info('Traced message')).not.toThrow();
77
- });
78
- });
79
- describe('Environment Detection', () => {
80
- it('should detect Node.js environment', async () => {
81
- // This test runs in Node.js, so logger should detect it
82
- const nodeLogger = createLogger({ format: 'json' });
83
- expect(() => nodeLogger.info('Node environment')).not.toThrow();
84
- await nodeLogger.destroy();
85
- });
86
- });
87
- describe('Compatibility', () => {
88
- it('should support console.log compatibility', () => {
89
- expect(() => logger.log('Compatible log')).not.toThrow();
90
- });
91
- });
92
- });