@actsecurity/log 0.1.60

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 ADDED
@@ -0,0 +1,214 @@
1
+ # Log
2
+
3
+ [![NPM Version](https://img.shields.io/npm/v/@cloud-copilot/log.svg?logo=nodedotjs)](https://www.npmjs.com/package/@cloud-copilot/log) [![MIT](https://img.shields.io/github/license/cloud-copilot/log)](LICENSE.txt) [![GuardDog](https://github.com/cloud-copilot/log/actions/workflows/guarddog.yml/badge.svg)](https://github.com/cloud-copilot/log/actions/workflows/guarddog.yml) [![Known Vulnerabilities](https://snyk.io/test/github/cloud-copilot/log/badge.svg?targetFile=package.json&style=flat-square)](https://snyk.io/test/github/cloud-copilot/log?targetFile=package.json)
4
+
5
+ A lightweight logger to output JSON structured logs for Typescript.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @cloud-copilot/log
11
+ ```
12
+
13
+ ## Basic Usage
14
+
15
+ ```typescript
16
+ import { StandardLogger } from '@cloud-copilot/log'
17
+
18
+ // Create a logger with default log level (warn)
19
+ const logger = new StandardLogger()
20
+
21
+ // Or specify an initial log level
22
+ const logger = new StandardLogger('info')
23
+
24
+ // Log messages at different levels
25
+ logger.error('Something went wrong')
26
+ logger.warn('This is a warning')
27
+ logger.info('Information message')
28
+ logger.debug('Debug information')
29
+ logger.trace('Trace information')
30
+ ```
31
+
32
+ ## Log Levels
33
+
34
+ The logger supports five log levels in order of priority:
35
+
36
+ - `error` (0) - Highest priority
37
+ - `warn` (1)
38
+ - `info` (2)
39
+ - `debug` (3)
40
+ - `trace` (4) - Lowest priority
41
+
42
+ Only messages at or above the current log level will be output. For example, if the log level is set to `info`, then `error`, `warn`, and `info` messages will be logged, but `debug` and `trace` will be filtered out.
43
+
44
+ ```typescript
45
+ const logger = new StandardLogger('info')
46
+
47
+ logger.error('This will be logged') // ✓
48
+ logger.warn('This will be logged') // ✓
49
+ logger.info('This will be logged') // ✓
50
+ logger.debug('This will be filtered') // ✗
51
+ logger.trace('This will be filtered') // ✗
52
+ ```
53
+
54
+ ## Changing Log Level
55
+
56
+ ```typescript
57
+ const logger = new StandardLogger('error')
58
+
59
+ // Change the log level at runtime
60
+ logger.setLogLevel('debug')
61
+
62
+ // Invalid log levels throw an error
63
+ logger.setLogLevel('invalid') // throws Error: Invalid log level: invalid
64
+ ```
65
+
66
+ ## Structured Logging
67
+
68
+ The logger automatically creates structured JSON output with timestamps:
69
+
70
+ ```typescript
71
+ const logger = new StandardLogger('info')
72
+
73
+ logger.info('User logged in')
74
+ // Output: {"timestamp":"2023-10-01T12:00:00.000Z","level":"info","message":"User logged in"}
75
+ ```
76
+
77
+ ## Object Merging
78
+
79
+ Objects passed as arguments are merged into the log entry:
80
+
81
+ ```typescript
82
+ logger.info('User action', {
83
+ userId: 123,
84
+ action: 'login',
85
+ ip: '192.168.1.1'
86
+ })
87
+ // Output: {"timestamp":"2023-10-01T12:00:00.000Z","level":"info","message":"User action","userId":123,"action":"login","ip":"192.168.1.1"}
88
+ ```
89
+
90
+ ## Error Handling
91
+
92
+ Error objects are specially handled and added to an `errors` array:
93
+
94
+ ```typescript
95
+ const error = new Error('Database connection failed')
96
+
97
+ logger.error('Operation failed', error, { userId: 123 })
98
+ // Output: {
99
+ // "timestamp": "2023-10-01T12:00:00.000Z",
100
+ // "level": "error",
101
+ // "message": "Operation failed",
102
+ // "userId": 123,
103
+ // "errors": [{
104
+ // "name": "Error",
105
+ // "message": "Database connection failed",
106
+ // "stack": "Error: Database connection failed\n at ..."
107
+ // }]
108
+ // }
109
+ ```
110
+
111
+ ## Mixed Arguments
112
+
113
+ The logger handles mixed argument types intelligently:
114
+
115
+ ```typescript
116
+ logger.warn(
117
+ 'Processing user', // string message
118
+ { userId: 123 }, // object (merged)
119
+ 'with status', // string message
120
+ { status: 'active' }, // object (merged)
121
+ new Error('Minor issue') // error (in errors array)
122
+ )
123
+ // Output: {
124
+ // "timestamp": "2023-10-01T12:00:00.000Z",
125
+ // "level": "warn",
126
+ // "message": "Processing user with status",
127
+ // "userId": 123,
128
+ // "status": "active",
129
+ // "errors": [{"name": "Error", "message": "Minor issue", "stack": "..."}]
130
+ // }
131
+ ```
132
+
133
+ ## Advanced Examples
134
+
135
+ ### Application Logging
136
+
137
+ ```typescript
138
+ import { StandardLogger } from '@cloud-copilot/log'
139
+
140
+ class UserService {
141
+ private logger = new StandardLogger('info')
142
+
143
+ async createUser(userData: any) {
144
+ this.logger.info('Creating user', {
145
+ operation: 'createUser',
146
+ email: userData.email
147
+ })
148
+
149
+ try {
150
+ // ... user creation logic
151
+ this.logger.info('User created successfully', {
152
+ userId: newUser.id,
153
+ email: newUser.email
154
+ })
155
+ } catch (error) {
156
+ this.logger.error('Failed to create user', error, {
157
+ email: userData.email
158
+ })
159
+ throw error
160
+ }
161
+ }
162
+ }
163
+ ```
164
+
165
+ ### Environment-based Log Levels
166
+
167
+ ```typescript
168
+ const logLevel = process.env.LOG_LEVEL || 'warn'
169
+ const logger = new StandardLogger(logLevel as LogLevel)
170
+
171
+ // In production: LOG_LEVEL=error (only errors)
172
+ // In development: LOG_LEVEL=debug (detailed logging)
173
+ ```
174
+
175
+ ### Validating Log Levels
176
+
177
+ Use the `isLogLevel` utility function to validate log level strings:
178
+
179
+ ```typescript
180
+ import { isLogLevel } from '@cloud-copilot/log'
181
+
182
+ // Validate user input
183
+ const userInput = 'debug'
184
+ if (isLogLevel(userInput)) {
185
+ const logger = new StandardLogger(userInput)
186
+ } else {
187
+ console.error('Invalid log level provided')
188
+ }
189
+
190
+ // Safe environment variable parsing
191
+ const envLogLevel = process.env.LOG_LEVEL
192
+ const logLevel = isLogLevel(envLogLevel) ? envLogLevel : 'warn'
193
+ const logger = new StandardLogger(logLevel)
194
+
195
+ // Type guard in functions
196
+ function createLoggerFromConfig(config: { logLevel?: string }) {
197
+ if (config.logLevel && isLogLevel(config.logLevel)) {
198
+ return new StandardLogger(config.logLevel)
199
+ }
200
+ return new StandardLogger() // defaults to 'warn'
201
+ }
202
+ ```
203
+
204
+ ## TypeScript Support
205
+
206
+ Full TypeScript support with proper type definitions:
207
+
208
+ ```typescript
209
+ import { StandardLogger, LogLevel, LogLevels, isLogLevel } from '@cloud-copilot/log'
210
+
211
+ const logger: StandardLogger = new StandardLogger()
212
+ const level: LogLevel = 'info'
213
+ const isValid: boolean = isLogLevel('debug') // true
214
+ ```
@@ -0,0 +1,2 @@
1
+ export { isLogLevel, log, StandardLogger, type StandardLoggerOptions, type Logger, type LogLevel, LogLevels, normalizeArgs, type NormalizedLogArgs, setLogger, getLogger } from './log.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,GAAG,EACH,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,SAAS,EACT,aAAa,EACb,KAAK,iBAAiB,EACtB,SAAS,EACT,SAAS,EACV,MAAM,UAAU,CAAA"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLogger = exports.setLogger = exports.normalizeArgs = exports.LogLevels = exports.StandardLogger = exports.log = exports.isLogLevel = void 0;
4
+ var log_js_1 = require("./log.js");
5
+ Object.defineProperty(exports, "isLogLevel", { enumerable: true, get: function () { return log_js_1.isLogLevel; } });
6
+ Object.defineProperty(exports, "log", { enumerable: true, get: function () { return log_js_1.log; } });
7
+ Object.defineProperty(exports, "StandardLogger", { enumerable: true, get: function () { return log_js_1.StandardLogger; } });
8
+ Object.defineProperty(exports, "LogLevels", { enumerable: true, get: function () { return log_js_1.LogLevels; } });
9
+ Object.defineProperty(exports, "normalizeArgs", { enumerable: true, get: function () { return log_js_1.normalizeArgs; } });
10
+ Object.defineProperty(exports, "setLogger", { enumerable: true, get: function () { return log_js_1.setLogger; } });
11
+ Object.defineProperty(exports, "getLogger", { enumerable: true, get: function () { return log_js_1.getLogger; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAYiB;AAXf,oGAAA,UAAU,OAAA;AACV,6FAAA,GAAG,OAAA;AACH,wGAAA,cAAc,OAAA;AAId,mGAAA,SAAS,OAAA;AACT,uGAAA,aAAa,OAAA;AAEb,mGAAA,SAAS,OAAA;AACT,mGAAA,SAAS,OAAA"}
@@ -0,0 +1,119 @@
1
+ export declare const LogLevels: readonly ["error", "warn", "info", "debug", "trace"];
2
+ export type LogLevel = (typeof LogLevels)[number];
3
+ /**
4
+ * Determine if a string is a valid log level.
5
+ *
6
+ * @param level the log level string to check
7
+ * @returns true if the string is a valid log level, false otherwise
8
+ */
9
+ export declare function isLogLevel(level: string | LogLevel): level is LogLevel;
10
+ /**
11
+ * A structured logger that outputs JSON log entries to the console.
12
+ * Accepts variadic arguments of mixed types: strings are joined as the message,
13
+ * objects are merged as context, and Errors are serialized into the entry.
14
+ */
15
+ export interface Logger {
16
+ /** Log at error level. */
17
+ error: (...args: unknown[]) => void;
18
+ /** Log at warn level. */
19
+ warn: (...args: unknown[]) => void;
20
+ /** Log at info level. */
21
+ info: (...args: unknown[]) => void;
22
+ /** Log at debug level. */
23
+ debug: (...args: unknown[]) => void;
24
+ /** Log at trace level. */
25
+ trace: (...args: unknown[]) => void;
26
+ }
27
+ /**
28
+ * Options for constructing a StandardLogger.
29
+ */
30
+ export interface StandardLoggerOptions {
31
+ /** The initial log level. Defaults to 'warn'. */
32
+ logLevel?: LogLevel;
33
+ /**
34
+ * When true, outputs raw objects instead of JSON.stringify for environments
35
+ * like CloudWatch Logs where each log line is expected to be a JSON object.
36
+ * Defaults to false.
37
+ */
38
+ rawJsonLogs?: boolean;
39
+ }
40
+ /**
41
+ * A logger that outputs structured JSON to the console.
42
+ * Supports configurable log levels, raw JSON output for CloudWatch,
43
+ * and variadic arguments with mixed types.
44
+ */
45
+ export declare class StandardLogger implements Logger {
46
+ private logLevel;
47
+ private rawJsonLogs;
48
+ /**
49
+ * Create a new StandardLogger.
50
+ *
51
+ * @param initialLogLevel - The initial log level (backward-compatible positional form)
52
+ */
53
+ constructor(initialLogLevel?: LogLevel);
54
+ /**
55
+ * Create a new StandardLogger with options.
56
+ *
57
+ * @param options - Configuration options for the logger
58
+ */
59
+ constructor(options: StandardLoggerOptions);
60
+ /**
61
+ * Update the log level.
62
+ *
63
+ * @param level - The new log level to set
64
+ * @throws Error if the provided level is not a valid log level
65
+ */
66
+ setLogLevel(level: LogLevel): void;
67
+ error(...args: unknown[]): void;
68
+ warn(...args: unknown[]): void;
69
+ info(...args: unknown[]): void;
70
+ debug(...args: unknown[]): void;
71
+ trace(...args: unknown[]): void;
72
+ }
73
+ /**
74
+ * The result of normalizing variadic log arguments into structured parts.
75
+ */
76
+ export interface NormalizedLogArgs {
77
+ /** All string arguments joined with spaces. */
78
+ message: string;
79
+ /** All non-Error object arguments merged together. */
80
+ context: Record<string, unknown>;
81
+ /** All Error arguments, normalized to a consistent shape. */
82
+ errors: {
83
+ name: string;
84
+ message: string;
85
+ stack?: string;
86
+ code?: unknown;
87
+ }[];
88
+ }
89
+ /**
90
+ * Normalize variadic log arguments into structured parts.
91
+ * Separates string args (joined as message), Error args (serialized), and object args (merged as context).
92
+ * This is useful for adapters that need to convert cloud-copilot's variadic log calls
93
+ * into structured `(message, context)` calls for other logging frameworks.
94
+ *
95
+ * @param args - The variadic arguments passed to a log method
96
+ * @returns The normalized parts: message, context, and errors
97
+ */
98
+ export declare function normalizeArgs(args: unknown[]): NormalizedLogArgs;
99
+ /**
100
+ * Replace the current module-level logger with a custom implementation.
101
+ * Call this at application startup to inject your own logger (e.g. an adapter
102
+ * that bridges to another logging framework).
103
+ *
104
+ * @param logger - The logger implementation to use
105
+ */
106
+ export declare function setLogger(logger: Logger): void;
107
+ /**
108
+ * Get the current module-level logger.
109
+ *
110
+ * @returns The current logger instance (default: StandardLogger)
111
+ */
112
+ export declare function getLogger(): Logger;
113
+ /**
114
+ * A proxy object that delegates all log calls to the current module-level logger.
115
+ * Use this for convenient access: `log.info('message', { context })`.
116
+ * The underlying logger can be swapped at runtime via `setLogger()`.
117
+ */
118
+ export declare const log: Logger;
119
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,sDAAuD,CAAA;AAE7E,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAUjD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,IAAI,QAAQ,CAEtE;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,0BAA0B;IAC1B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACnC,yBAAyB;IACzB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,yBAAyB;IACzB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,0BAA0B;IAC1B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACnC,0BAA0B;IAC1B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,MAAM;IAC3C,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;OAIG;gBACS,eAAe,CAAC,EAAE,QAAQ;IACtC;;;;OAIG;gBACS,OAAO,EAAE,qBAAqB;IAe1C;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ;IAO3B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGxB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGvB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGvB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGxB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;CAGzB;AAeD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,6DAA6D;IAC7D,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAehE;AA4FD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,EAAE,MAMjB,CAAA"}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.log = exports.StandardLogger = exports.LogLevels = void 0;
4
+ exports.isLogLevel = isLogLevel;
5
+ exports.normalizeArgs = normalizeArgs;
6
+ exports.setLogger = setLogger;
7
+ exports.getLogger = getLogger;
8
+ exports.LogLevels = ['error', 'warn', 'info', 'debug', 'trace'];
9
+ const LEVELS = {
10
+ error: 0,
11
+ warn: 1,
12
+ info: 2,
13
+ debug: 3,
14
+ trace: 4
15
+ };
16
+ /**
17
+ * Determine if a string is a valid log level.
18
+ *
19
+ * @param level the log level string to check
20
+ * @returns true if the string is a valid log level, false otherwise
21
+ */
22
+ function isLogLevel(level) {
23
+ return level !== undefined && LEVELS.hasOwnProperty(level);
24
+ }
25
+ /**
26
+ * A logger that outputs structured JSON to the console.
27
+ * Supports configurable log levels, raw JSON output for CloudWatch,
28
+ * and variadic arguments with mixed types.
29
+ */
30
+ class StandardLogger {
31
+ logLevel;
32
+ rawJsonLogs;
33
+ constructor(arg) {
34
+ const envRawJsonLogs = typeof process !== 'undefined' &&
35
+ process.env?.IAM_COLLECT_RAW_JSON_LOGS?.toLowerCase() === 'true';
36
+ if (typeof arg === 'object' && arg !== null) {
37
+ this.logLevel = arg.logLevel && isLogLevel(arg.logLevel) ? arg.logLevel : 'warn';
38
+ this.rawJsonLogs = arg.rawJsonLogs ?? envRawJsonLogs;
39
+ }
40
+ else {
41
+ this.logLevel = arg && isLogLevel(arg) ? arg : 'warn';
42
+ this.rawJsonLogs = envRawJsonLogs;
43
+ }
44
+ }
45
+ /**
46
+ * Update the log level.
47
+ *
48
+ * @param level - The new log level to set
49
+ * @throws Error if the provided level is not a valid log level
50
+ */
51
+ setLogLevel(level) {
52
+ if (!isLogLevel(level)) {
53
+ throw new Error(`Invalid log level: ${level}`);
54
+ }
55
+ this.logLevel = level;
56
+ }
57
+ error(...args) {
58
+ logAt(this.logLevel, 'error', args, this.rawJsonLogs);
59
+ }
60
+ warn(...args) {
61
+ logAt(this.logLevel, 'warn', args, this.rawJsonLogs);
62
+ }
63
+ info(...args) {
64
+ logAt(this.logLevel, 'info', args, this.rawJsonLogs);
65
+ }
66
+ debug(...args) {
67
+ logAt(this.logLevel, 'debug', args, this.rawJsonLogs);
68
+ }
69
+ trace(...args) {
70
+ logAt(this.logLevel, 'trace', args, this.rawJsonLogs);
71
+ }
72
+ }
73
+ exports.StandardLogger = StandardLogger;
74
+ /**
75
+ * Check if an object is an Error or Error-like (has name and message properties).
76
+ *
77
+ * @param obj - The object to check
78
+ * @returns true if the object is an Error or Error-like
79
+ */
80
+ function isError(obj) {
81
+ return (obj instanceof Error ||
82
+ (typeof obj === 'object' && obj !== null && 'message' in obj && 'name' in obj));
83
+ }
84
+ /**
85
+ * Normalize variadic log arguments into structured parts.
86
+ * Separates string args (joined as message), Error args (serialized), and object args (merged as context).
87
+ * This is useful for adapters that need to convert cloud-copilot's variadic log calls
88
+ * into structured `(message, context)` calls for other logging frameworks.
89
+ *
90
+ * @param args - The variadic arguments passed to a log method
91
+ * @returns The normalized parts: message, context, and errors
92
+ */
93
+ function normalizeArgs(args) {
94
+ const messageArgs = args.filter((a) => typeof a !== 'object' || a === null);
95
+ const objectArgs = args.filter((a) => typeof a === 'object' && a !== null && !isError(a));
96
+ const errorArgs = args.filter(isError);
97
+ const context = {};
98
+ for (const obj of objectArgs) {
99
+ Object.assign(context, obj);
100
+ }
101
+ return {
102
+ message: serializeArgs(messageArgs),
103
+ context,
104
+ errors: errorArgs.map(mapError)
105
+ };
106
+ }
107
+ // helper to serialize non-object args into a single string
108
+ function serializeArgs(args) {
109
+ return args
110
+ .map((a) => typeof a === 'string'
111
+ ? a
112
+ : a instanceof Error
113
+ ? a.stack || a.message
114
+ : a === undefined
115
+ ? 'undefined'
116
+ : JSON.stringify(a))
117
+ .join(' ');
118
+ }
119
+ /**
120
+ * Map an Error object to a consistent shape.
121
+ *
122
+ * @param e The error object to map
123
+ * @returns A normalized error object
124
+ */
125
+ function mapError(e) {
126
+ // Normalize anything Error-like to a consistent shape
127
+ const { name, message, stack, code } = e;
128
+ return {
129
+ name: typeof name === 'string' ? name : 'Error',
130
+ message: typeof message === 'string' ? message : String(message ?? ''),
131
+ stack: typeof stack === 'string' ? stack : undefined,
132
+ ...(code !== undefined ? { code } : {})
133
+ };
134
+ }
135
+ // core log function: level check → prefix → JSON output
136
+ function logAt(currentLevel, level, args, rawJsonLogs) {
137
+ if (LEVELS[level] > LEVELS[currentLevel])
138
+ return;
139
+ // Base log entry
140
+ const entry = {
141
+ timestamp: new Date().toISOString(),
142
+ level
143
+ };
144
+ // Separate object args and message args
145
+ const objectArgs = args.filter((a) => typeof a === 'object' && a !== null && !isError(a));
146
+ const messageArgs = args.filter((a) => typeof a !== 'object' || a === null);
147
+ const errorArgs = args.filter(isError);
148
+ // Merge all object arguments into the entry
149
+ for (const obj of objectArgs) {
150
+ Object.assign(entry, obj);
151
+ }
152
+ const msg = serializeArgs(messageArgs);
153
+ if (msg) {
154
+ entry.message = msg;
155
+ }
156
+ if (errorArgs.length > 0) {
157
+ entry.error = mapError(errorArgs[0]);
158
+ entry.error_count = errorArgs.length;
159
+ if (errorArgs.length > 1) {
160
+ entry.errors = errorArgs.map(mapError);
161
+ }
162
+ }
163
+ /**
164
+ * Raw JSON logging is great for things like CloudWatch Logs where each log line
165
+ * is expected to be a single JSON object for easier parsing and querying.
166
+ *
167
+ * The default is JSON.stringify for each log line as a single line for processing
168
+ * with bash and other command-line tools.
169
+ */
170
+ const line = rawJsonLogs ? entry : JSON.stringify(entry);
171
+ switch (level) {
172
+ case 'error':
173
+ return console.error(line);
174
+ case 'warn':
175
+ return console.warn(line);
176
+ case 'info':
177
+ return console.info(line);
178
+ default:
179
+ return console.log(line);
180
+ }
181
+ }
182
+ // ── Module-level logger singleton ──────────────────────────────────────────────
183
+ let currentLogger = new StandardLogger();
184
+ /**
185
+ * Replace the current module-level logger with a custom implementation.
186
+ * Call this at application startup to inject your own logger (e.g. an adapter
187
+ * that bridges to another logging framework).
188
+ *
189
+ * @param logger - The logger implementation to use
190
+ */
191
+ function setLogger(logger) {
192
+ currentLogger = logger;
193
+ }
194
+ /**
195
+ * Get the current module-level logger.
196
+ *
197
+ * @returns The current logger instance (default: StandardLogger)
198
+ */
199
+ function getLogger() {
200
+ return currentLogger;
201
+ }
202
+ /**
203
+ * A proxy object that delegates all log calls to the current module-level logger.
204
+ * Use this for convenient access: `log.info('message', { context })`.
205
+ * The underlying logger can be swapped at runtime via `setLogger()`.
206
+ */
207
+ exports.log = {
208
+ error: (...args) => currentLogger.error(...args),
209
+ warn: (...args) => currentLogger.warn(...args),
210
+ info: (...args) => currentLogger.info(...args),
211
+ debug: (...args) => currentLogger.debug(...args),
212
+ trace: (...args) => currentLogger.trace(...args)
213
+ };
214
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":";;;AAkBA,gCAEC;AAqID,sCAeC;AAmGD,8BAEC;AAOD,8BAEC;AAtRY,QAAA,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAU,CAAA;AAI7E,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,CAAC;CACT,CAAA;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,KAAwB;IACjD,OAAO,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAA;AAC5D,CAAC;AAkCD;;;;GAIG;AACH,MAAa,cAAc;IACjB,QAAQ,CAAU;IAClB,WAAW,CAAS;IAc5B,YAAY,GAAsC;QAChD,MAAM,cAAc,GAClB,OAAO,OAAO,KAAK,WAAW;YAC9B,OAAO,CAAC,GAAG,EAAE,yBAAyB,EAAE,WAAW,EAAE,KAAK,MAAM,CAAA;QAElE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAA;YAChF,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,IAAI,cAAc,CAAA;QACtD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,QAAQ,GAAG,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAA;YACrD,IAAI,CAAC,WAAW,GAAG,cAAc,CAAA;QACnC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,KAAe;QACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,sBAAsB,KAAK,EAAE,CAAC,CAAA;QAChD,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,GAAG,IAAe;QACtB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC;IACD,IAAI,CAAC,GAAG,IAAe;QACrB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACtD,CAAC;IACD,IAAI,CAAC,GAAG,IAAe;QACrB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACtD,CAAC;IACD,KAAK,CAAC,GAAG,IAAe;QACtB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC;IACD,KAAK,CAAC,GAAG,IAAe;QACtB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IACvD,CAAC;CACF;AA1DD,wCA0DC;AAED;;;;;GAKG;AACH,SAAS,OAAO,CAAC,GAAY;IAC3B,OAAO,CACL,GAAG,YAAY,KAAK;QACpB,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC,CAC/E,CAAA;AACH,CAAC;AAcD;;;;;;;;GAQG;AACH,SAAgB,aAAa,CAAC,IAAe;IAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAA;IAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IACzF,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEtC,MAAM,OAAO,GAA4B,EAAE,CAAA;IAC3C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IAC7B,CAAC;IAED,OAAO;QACL,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC;QACnC,OAAO;QACP,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;KAChC,CAAA;AACH,CAAC;AAED,2DAA2D;AAC3D,SAAS,aAAa,CAAC,IAAe;IACpC,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,OAAO,CAAC,KAAK,QAAQ;QACnB,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,CAAC,YAAY,KAAK;YAClB,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO;YACtB,CAAC,CAAC,CAAC,KAAK,SAAS;gBACf,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAC1B;SACA,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,CAAQ;IACxB,sDAAsD;IACtD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAQ,CAAA;IAC/C,OAAO;QACL,IAAI,EAAE,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;QAC/C,OAAO,EAAE,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;QACtE,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QACpD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxC,CAAA;AACH,CAAC;AAED,wDAAwD;AACxD,SAAS,KAAK,CAAC,YAAsB,EAAE,KAAe,EAAE,IAAe,EAAE,WAAoB;IAC3F,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC;QAAE,OAAM;IAEhD,iBAAiB;IACjB,MAAM,KAAK,GAAwB;QACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK;KACN,CAAA;IAED,wCAAwC;IACxC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IACzF,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAA;IAC3E,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEtC,4CAA4C;IAC5C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAC3B,CAAC;IAED,MAAM,GAAG,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;IACtC,IAAI,GAAG,EAAE,CAAC;QACR,KAAK,CAAC,OAAO,GAAG,GAAG,CAAA;IACrB,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;QACpC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,MAAM,CAAA;QACpC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACxC,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAExD,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC5B,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B;YACE,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;AACH,CAAC;AAED,kFAAkF;AAElF,IAAI,aAAa,GAAW,IAAI,cAAc,EAAE,CAAA;AAEhD;;;;;;GAMG;AACH,SAAgB,SAAS,CAAC,MAAc;IACtC,aAAa,GAAG,MAAM,CAAA;AACxB,CAAC;AAED;;;;GAIG;AACH,SAAgB,SAAS;IACvB,OAAO,aAAa,CAAA;AACtB,CAAC;AAED;;;;GAIG;AACU,QAAA,GAAG,GAAW;IACzB,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAC3D,IAAI,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,IAAI,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IAC3D,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;CAC5D,CAAA"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,2 @@
1
+ export { isLogLevel, log, StandardLogger, type StandardLoggerOptions, type Logger, type LogLevel, LogLevels, normalizeArgs, type NormalizedLogArgs, setLogger, getLogger } from './log.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,GAAG,EACH,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,MAAM,EACX,KAAK,QAAQ,EACb,SAAS,EACT,aAAa,EACb,KAAK,iBAAiB,EACtB,SAAS,EACT,SAAS,EACV,MAAM,UAAU,CAAA"}
@@ -0,0 +1,2 @@
1
+ export { isLogLevel, log, StandardLogger, LogLevels, normalizeArgs, setLogger, getLogger } from './log.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,GAAG,EACH,cAAc,EAId,SAAS,EACT,aAAa,EAEb,SAAS,EACT,SAAS,EACV,MAAM,UAAU,CAAA"}
@@ -0,0 +1,119 @@
1
+ export declare const LogLevels: readonly ["error", "warn", "info", "debug", "trace"];
2
+ export type LogLevel = (typeof LogLevels)[number];
3
+ /**
4
+ * Determine if a string is a valid log level.
5
+ *
6
+ * @param level the log level string to check
7
+ * @returns true if the string is a valid log level, false otherwise
8
+ */
9
+ export declare function isLogLevel(level: string | LogLevel): level is LogLevel;
10
+ /**
11
+ * A structured logger that outputs JSON log entries to the console.
12
+ * Accepts variadic arguments of mixed types: strings are joined as the message,
13
+ * objects are merged as context, and Errors are serialized into the entry.
14
+ */
15
+ export interface Logger {
16
+ /** Log at error level. */
17
+ error: (...args: unknown[]) => void;
18
+ /** Log at warn level. */
19
+ warn: (...args: unknown[]) => void;
20
+ /** Log at info level. */
21
+ info: (...args: unknown[]) => void;
22
+ /** Log at debug level. */
23
+ debug: (...args: unknown[]) => void;
24
+ /** Log at trace level. */
25
+ trace: (...args: unknown[]) => void;
26
+ }
27
+ /**
28
+ * Options for constructing a StandardLogger.
29
+ */
30
+ export interface StandardLoggerOptions {
31
+ /** The initial log level. Defaults to 'warn'. */
32
+ logLevel?: LogLevel;
33
+ /**
34
+ * When true, outputs raw objects instead of JSON.stringify for environments
35
+ * like CloudWatch Logs where each log line is expected to be a JSON object.
36
+ * Defaults to false.
37
+ */
38
+ rawJsonLogs?: boolean;
39
+ }
40
+ /**
41
+ * A logger that outputs structured JSON to the console.
42
+ * Supports configurable log levels, raw JSON output for CloudWatch,
43
+ * and variadic arguments with mixed types.
44
+ */
45
+ export declare class StandardLogger implements Logger {
46
+ private logLevel;
47
+ private rawJsonLogs;
48
+ /**
49
+ * Create a new StandardLogger.
50
+ *
51
+ * @param initialLogLevel - The initial log level (backward-compatible positional form)
52
+ */
53
+ constructor(initialLogLevel?: LogLevel);
54
+ /**
55
+ * Create a new StandardLogger with options.
56
+ *
57
+ * @param options - Configuration options for the logger
58
+ */
59
+ constructor(options: StandardLoggerOptions);
60
+ /**
61
+ * Update the log level.
62
+ *
63
+ * @param level - The new log level to set
64
+ * @throws Error if the provided level is not a valid log level
65
+ */
66
+ setLogLevel(level: LogLevel): void;
67
+ error(...args: unknown[]): void;
68
+ warn(...args: unknown[]): void;
69
+ info(...args: unknown[]): void;
70
+ debug(...args: unknown[]): void;
71
+ trace(...args: unknown[]): void;
72
+ }
73
+ /**
74
+ * The result of normalizing variadic log arguments into structured parts.
75
+ */
76
+ export interface NormalizedLogArgs {
77
+ /** All string arguments joined with spaces. */
78
+ message: string;
79
+ /** All non-Error object arguments merged together. */
80
+ context: Record<string, unknown>;
81
+ /** All Error arguments, normalized to a consistent shape. */
82
+ errors: {
83
+ name: string;
84
+ message: string;
85
+ stack?: string;
86
+ code?: unknown;
87
+ }[];
88
+ }
89
+ /**
90
+ * Normalize variadic log arguments into structured parts.
91
+ * Separates string args (joined as message), Error args (serialized), and object args (merged as context).
92
+ * This is useful for adapters that need to convert cloud-copilot's variadic log calls
93
+ * into structured `(message, context)` calls for other logging frameworks.
94
+ *
95
+ * @param args - The variadic arguments passed to a log method
96
+ * @returns The normalized parts: message, context, and errors
97
+ */
98
+ export declare function normalizeArgs(args: unknown[]): NormalizedLogArgs;
99
+ /**
100
+ * Replace the current module-level logger with a custom implementation.
101
+ * Call this at application startup to inject your own logger (e.g. an adapter
102
+ * that bridges to another logging framework).
103
+ *
104
+ * @param logger - The logger implementation to use
105
+ */
106
+ export declare function setLogger(logger: Logger): void;
107
+ /**
108
+ * Get the current module-level logger.
109
+ *
110
+ * @returns The current logger instance (default: StandardLogger)
111
+ */
112
+ export declare function getLogger(): Logger;
113
+ /**
114
+ * A proxy object that delegates all log calls to the current module-level logger.
115
+ * Use this for convenient access: `log.info('message', { context })`.
116
+ * The underlying logger can be swapped at runtime via `setLogger()`.
117
+ */
118
+ export declare const log: Logger;
119
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,sDAAuD,CAAA;AAE7E,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;AAUjD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,IAAI,QAAQ,CAEtE;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,0BAA0B;IAC1B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACnC,yBAAyB;IACzB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,yBAAyB;IACzB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAClC,0BAA0B;IAC1B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IACnC,0BAA0B;IAC1B,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;GAIG;AACH,qBAAa,cAAe,YAAW,MAAM;IAC3C,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,WAAW,CAAS;IAE5B;;;;OAIG;gBACS,eAAe,CAAC,EAAE,QAAQ;IACtC;;;;OAIG;gBACS,OAAO,EAAE,qBAAqB;IAe1C;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ;IAO3B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGxB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGvB,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGvB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;IAGxB,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE;CAGzB;AAeD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,6DAA6D;IAC7D,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,iBAAiB,CAehE;AA4FD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAE9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;;;GAIG;AACH,eAAO,MAAM,GAAG,EAAE,MAMjB,CAAA"}
@@ -0,0 +1,204 @@
1
+ export const LogLevels = ['error', 'warn', 'info', 'debug', 'trace'];
2
+ const LEVELS = {
3
+ error: 0,
4
+ warn: 1,
5
+ info: 2,
6
+ debug: 3,
7
+ trace: 4
8
+ };
9
+ /**
10
+ * Determine if a string is a valid log level.
11
+ *
12
+ * @param level the log level string to check
13
+ * @returns true if the string is a valid log level, false otherwise
14
+ */
15
+ export function isLogLevel(level) {
16
+ return level !== undefined && LEVELS.hasOwnProperty(level);
17
+ }
18
+ /**
19
+ * A logger that outputs structured JSON to the console.
20
+ * Supports configurable log levels, raw JSON output for CloudWatch,
21
+ * and variadic arguments with mixed types.
22
+ */
23
+ export class StandardLogger {
24
+ constructor(arg) {
25
+ const envRawJsonLogs = typeof process !== 'undefined' &&
26
+ process.env?.IAM_COLLECT_RAW_JSON_LOGS?.toLowerCase() === 'true';
27
+ if (typeof arg === 'object' && arg !== null) {
28
+ this.logLevel = arg.logLevel && isLogLevel(arg.logLevel) ? arg.logLevel : 'warn';
29
+ this.rawJsonLogs = arg.rawJsonLogs ?? envRawJsonLogs;
30
+ }
31
+ else {
32
+ this.logLevel = arg && isLogLevel(arg) ? arg : 'warn';
33
+ this.rawJsonLogs = envRawJsonLogs;
34
+ }
35
+ }
36
+ /**
37
+ * Update the log level.
38
+ *
39
+ * @param level - The new log level to set
40
+ * @throws Error if the provided level is not a valid log level
41
+ */
42
+ setLogLevel(level) {
43
+ if (!isLogLevel(level)) {
44
+ throw new Error(`Invalid log level: ${level}`);
45
+ }
46
+ this.logLevel = level;
47
+ }
48
+ error(...args) {
49
+ logAt(this.logLevel, 'error', args, this.rawJsonLogs);
50
+ }
51
+ warn(...args) {
52
+ logAt(this.logLevel, 'warn', args, this.rawJsonLogs);
53
+ }
54
+ info(...args) {
55
+ logAt(this.logLevel, 'info', args, this.rawJsonLogs);
56
+ }
57
+ debug(...args) {
58
+ logAt(this.logLevel, 'debug', args, this.rawJsonLogs);
59
+ }
60
+ trace(...args) {
61
+ logAt(this.logLevel, 'trace', args, this.rawJsonLogs);
62
+ }
63
+ }
64
+ /**
65
+ * Check if an object is an Error or Error-like (has name and message properties).
66
+ *
67
+ * @param obj - The object to check
68
+ * @returns true if the object is an Error or Error-like
69
+ */
70
+ function isError(obj) {
71
+ return (obj instanceof Error ||
72
+ (typeof obj === 'object' && obj !== null && 'message' in obj && 'name' in obj));
73
+ }
74
+ /**
75
+ * Normalize variadic log arguments into structured parts.
76
+ * Separates string args (joined as message), Error args (serialized), and object args (merged as context).
77
+ * This is useful for adapters that need to convert cloud-copilot's variadic log calls
78
+ * into structured `(message, context)` calls for other logging frameworks.
79
+ *
80
+ * @param args - The variadic arguments passed to a log method
81
+ * @returns The normalized parts: message, context, and errors
82
+ */
83
+ export function normalizeArgs(args) {
84
+ const messageArgs = args.filter((a) => typeof a !== 'object' || a === null);
85
+ const objectArgs = args.filter((a) => typeof a === 'object' && a !== null && !isError(a));
86
+ const errorArgs = args.filter(isError);
87
+ const context = {};
88
+ for (const obj of objectArgs) {
89
+ Object.assign(context, obj);
90
+ }
91
+ return {
92
+ message: serializeArgs(messageArgs),
93
+ context,
94
+ errors: errorArgs.map(mapError)
95
+ };
96
+ }
97
+ // helper to serialize non-object args into a single string
98
+ function serializeArgs(args) {
99
+ return args
100
+ .map((a) => typeof a === 'string'
101
+ ? a
102
+ : a instanceof Error
103
+ ? a.stack || a.message
104
+ : a === undefined
105
+ ? 'undefined'
106
+ : JSON.stringify(a))
107
+ .join(' ');
108
+ }
109
+ /**
110
+ * Map an Error object to a consistent shape.
111
+ *
112
+ * @param e The error object to map
113
+ * @returns A normalized error object
114
+ */
115
+ function mapError(e) {
116
+ // Normalize anything Error-like to a consistent shape
117
+ const { name, message, stack, code } = e;
118
+ return {
119
+ name: typeof name === 'string' ? name : 'Error',
120
+ message: typeof message === 'string' ? message : String(message ?? ''),
121
+ stack: typeof stack === 'string' ? stack : undefined,
122
+ ...(code !== undefined ? { code } : {})
123
+ };
124
+ }
125
+ // core log function: level check → prefix → JSON output
126
+ function logAt(currentLevel, level, args, rawJsonLogs) {
127
+ if (LEVELS[level] > LEVELS[currentLevel])
128
+ return;
129
+ // Base log entry
130
+ const entry = {
131
+ timestamp: new Date().toISOString(),
132
+ level
133
+ };
134
+ // Separate object args and message args
135
+ const objectArgs = args.filter((a) => typeof a === 'object' && a !== null && !isError(a));
136
+ const messageArgs = args.filter((a) => typeof a !== 'object' || a === null);
137
+ const errorArgs = args.filter(isError);
138
+ // Merge all object arguments into the entry
139
+ for (const obj of objectArgs) {
140
+ Object.assign(entry, obj);
141
+ }
142
+ const msg = serializeArgs(messageArgs);
143
+ if (msg) {
144
+ entry.message = msg;
145
+ }
146
+ if (errorArgs.length > 0) {
147
+ entry.error = mapError(errorArgs[0]);
148
+ entry.error_count = errorArgs.length;
149
+ if (errorArgs.length > 1) {
150
+ entry.errors = errorArgs.map(mapError);
151
+ }
152
+ }
153
+ /**
154
+ * Raw JSON logging is great for things like CloudWatch Logs where each log line
155
+ * is expected to be a single JSON object for easier parsing and querying.
156
+ *
157
+ * The default is JSON.stringify for each log line as a single line for processing
158
+ * with bash and other command-line tools.
159
+ */
160
+ const line = rawJsonLogs ? entry : JSON.stringify(entry);
161
+ switch (level) {
162
+ case 'error':
163
+ return console.error(line);
164
+ case 'warn':
165
+ return console.warn(line);
166
+ case 'info':
167
+ return console.info(line);
168
+ default:
169
+ return console.log(line);
170
+ }
171
+ }
172
+ // ── Module-level logger singleton ──────────────────────────────────────────────
173
+ let currentLogger = new StandardLogger();
174
+ /**
175
+ * Replace the current module-level logger with a custom implementation.
176
+ * Call this at application startup to inject your own logger (e.g. an adapter
177
+ * that bridges to another logging framework).
178
+ *
179
+ * @param logger - The logger implementation to use
180
+ */
181
+ export function setLogger(logger) {
182
+ currentLogger = logger;
183
+ }
184
+ /**
185
+ * Get the current module-level logger.
186
+ *
187
+ * @returns The current logger instance (default: StandardLogger)
188
+ */
189
+ export function getLogger() {
190
+ return currentLogger;
191
+ }
192
+ /**
193
+ * A proxy object that delegates all log calls to the current module-level logger.
194
+ * Use this for convenient access: `log.info('message', { context })`.
195
+ * The underlying logger can be swapped at runtime via `setLogger()`.
196
+ */
197
+ export const log = {
198
+ error: (...args) => currentLogger.error(...args),
199
+ warn: (...args) => currentLogger.warn(...args),
200
+ info: (...args) => currentLogger.info(...args),
201
+ debug: (...args) => currentLogger.debug(...args),
202
+ trace: (...args) => currentLogger.trace(...args)
203
+ };
204
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json ADDED
@@ -0,0 +1,115 @@
1
+ {
2
+ "name": "@actsecurity/log",
3
+ "version": "0.1.60",
4
+ "description": "A lightweight JSON logger",
5
+ "keywords": [
6
+ "typescript",
7
+ "logging"
8
+ ],
9
+ "homepage": "https://github.com/act-security-labs/log#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/act-security-labs/log/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/act-security-labs/log.git"
16
+ },
17
+ "exports": {
18
+ ".": {
19
+ "import": "./dist/esm/index.js",
20
+ "require": "./dist/cjs/index.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist/**/*"
25
+ ],
26
+ "types": "dist/cjs/index.d.ts",
27
+ "license": "MIT",
28
+ "author": "Act Security",
29
+ "main": "dist/esm/index.js",
30
+ "scripts": {
31
+ "build": "npx tsc -p tsconfig.cjs.json && npx tsc -p tsconfig.esm.json && ./postbuild.sh",
32
+ "clean": "rm -rf dist",
33
+ "test": "npx vitest --run --coverage",
34
+ "release": "npm install && npm run clean && npm run build && npm test && npm run format-check && npm publish",
35
+ "format": "npx prettier --write src/",
36
+ "format-check": "npx prettier --check src/"
37
+ },
38
+ "devDependencies": {
39
+ "@actsecurity/prettier-config": "^0.1.0",
40
+ "@semantic-release/changelog": "^6.0.3",
41
+ "@semantic-release/commit-analyzer": "^13.0.1",
42
+ "@semantic-release/exec": "^7.1.0",
43
+ "@semantic-release/git": "^10.0.1",
44
+ "@semantic-release/github": "^12.0.6",
45
+ "@semantic-release/npm": "^13.1.4",
46
+ "@semantic-release/release-notes-generator": "^14.0.3",
47
+ "@types/node": "^22.5.0",
48
+ "@vitest/coverage-v8": "^4.0.18",
49
+ "semantic-release": "^25.0.3",
50
+ "typescript": "^5.7.2",
51
+ "vitest": "^4.0.18"
52
+ },
53
+ "prettier": "@actsecurity/prettier-config",
54
+ "release": {
55
+ "branches": [
56
+ "main"
57
+ ],
58
+ "plugins": [
59
+ [
60
+ "@semantic-release/commit-analyzer",
61
+ {
62
+ "releaseRules": [
63
+ {
64
+ "type": "feat",
65
+ "release": "patch"
66
+ },
67
+ {
68
+ "type": "fix",
69
+ "release": "patch"
70
+ },
71
+ {
72
+ "breaking": true,
73
+ "release": "patch"
74
+ },
75
+ {
76
+ "type": "*",
77
+ "release": "patch"
78
+ }
79
+ ]
80
+ }
81
+ ],
82
+ "@semantic-release/release-notes-generator",
83
+ "@semantic-release/changelog",
84
+ [
85
+ "@semantic-release/npm",
86
+ {
87
+ "npmPublish": true
88
+ }
89
+ ],
90
+ [
91
+ "@semantic-release/exec",
92
+ {
93
+ "successCmd": "echo published=true >> $GITHUB_OUTPUT && echo version=${nextRelease.version} >> $GITHUB_OUTPUT && echo package_name=$(node -p \"require('./package.json').name\") >> $GITHUB_OUTPUT"
94
+ }
95
+ ],
96
+ [
97
+ "@semantic-release/git",
98
+ {
99
+ "assets": [
100
+ "package.json",
101
+ "package-lock.json",
102
+ "CHANGELOG.md"
103
+ ],
104
+ "message": "chore(release): ${nextRelease.version} [skip ci]"
105
+ }
106
+ ],
107
+ [
108
+ "@semantic-release/github",
109
+ {
110
+ "assets": []
111
+ }
112
+ ]
113
+ ]
114
+ }
115
+ }