hierarchical-area-logger 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ dist
3
+ coverage
4
+ *.log
package/.prettierrc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "semi": true,
3
+ "trailingComma": "es5",
4
+ "singleQuote": true,
5
+ "printWidth": 80,
6
+ "tabWidth": 2,
7
+ "useTabs": false
8
+ }
@@ -0,0 +1,313 @@
1
+ # 🤝 Contributing to Hierarchical Area Logger
2
+
3
+ Thank you for your interest in contributing to this TypeScript logging library! This guide will help you get started and ensure your contributions align with the project standards.
4
+
5
+ ## 📋 Table of Contents
6
+
7
+ - [Development Setup](#development-setup)
8
+ - [Development Workflow](#development-workflow)
9
+ - [Project Structure](#project-structure)
10
+ - [Code Standards](#code-standards)
11
+ - [Testing](#testing)
12
+ - [Pull Request Process](#pull-request-process)
13
+ - [Release Process](#release-process)
14
+
15
+ ## 🛠 Development Setup
16
+
17
+ ### Prerequisites
18
+
19
+ - **Node.js** (v18 or higher)
20
+ - **npm** or **yarn** package manager
21
+ - **TypeScript** knowledge
22
+
23
+ ### Installation
24
+
25
+ 1. **Fork and clone the repository**
26
+
27
+ ```bash
28
+ git clone https://github.com/Em3ODMe/hierarchical-area-logger.git
29
+ cd hierarchical-area-logger
30
+ ```
31
+
32
+ 2. **Install dependencies**
33
+
34
+ ```bash
35
+ npm install
36
+ ```
37
+
38
+ 3. **Verify setup**
39
+ ```bash
40
+ npm run lint:check
41
+ npm test
42
+ npm run build
43
+ ```
44
+
45
+ ## 🔄 Development Workflow
46
+
47
+ ### Available Scripts
48
+
49
+ | Script | Purpose | When to Use |
50
+ | ------------------ | ------------------------ | ------------------ |
51
+ | `npm run dev` | Watch mode development | Active development |
52
+ | `npm run build` | Build the library | Before committing |
53
+ | `npm test` | Run unit tests | After code changes |
54
+ | `npm run test:ui` | Interactive test runner | Debugging tests |
55
+ | `npm run lint` | Check code quality | Before committing |
56
+ | `npm run lint:fix` | Auto-fix lint issues | During development |
57
+ | `npm run coverage` | Generate coverage report | Before PR |
58
+
59
+ ### Daily Development
60
+
61
+ 1. **Start development server**
62
+
63
+ ```bash
64
+ npm run dev
65
+ ```
66
+
67
+ 2. **Make changes to source files** in `src/` directory
68
+
69
+ 3. **Run tests frequently**
70
+
71
+ ```bash
72
+ npm test
73
+ ```
74
+
75
+ 4. **Check linting**
76
+
77
+ ```bash
78
+ npm run lint:check
79
+ ```
80
+
81
+ 5. **Build before commit**
82
+ ```bash
83
+ npm run build
84
+ ```
85
+
86
+ ## 📁 Project Structure
87
+
88
+ ```
89
+ logger/
90
+ ├── src/
91
+ │ ├── index.ts # Main entry point and exports
92
+ │ ├── Logger.ts # Core Logger class implementation
93
+ │ ├── types.ts # TypeScript type definitions
94
+ │ └── utils.ts # Utility functions
95
+ ├── dist/ # Built output (auto-generated)
96
+ ├── test/
97
+ │ └── logger.test.ts # Test suite
98
+ ├── coverage/ # Coverage reports (auto-generated)
99
+ ├── package.json # Project configuration
100
+ ├── tsconfig.json # TypeScript configuration
101
+ ├── vitest.config.ts # Test configuration
102
+ ├── eslint.config.js # Linting configuration
103
+ └── tsup.config.ts # Build configuration
104
+ ```
105
+
106
+ ### Key Files & Responsibilities
107
+
108
+ - **`src/Logger.ts`**: Core Logger class with area-based logging
109
+ - **`src/types.ts`**: TypeScript interfaces and type definitions
110
+ - **`src/utils.ts`**: Helper functions for log creation and error handling
111
+ - **`src/index.ts`**: Public API exports
112
+
113
+ ## 📝 Code Standards
114
+
115
+ ### TypeScript Configuration
116
+
117
+ - **Target**: ES2020
118
+ - **Module**: ESNext
119
+ - **Strict mode**: Enabled
120
+ - **Output**: Both CommonJS and ESM modules
121
+
122
+ ### ESLint Rules
123
+
124
+ Key rules enforced:
125
+
126
+ - No unused variables (with `_` prefix exception)
127
+ - Warn on `any` types
128
+ - Prefer `const` over `let`
129
+ - No `var` declarations
130
+ - No empty functions (warn)
131
+
132
+ ### Code Style Guidelines
133
+
134
+ 1. **Use TypeScript for all new code**
135
+ 2. **Follow existing naming conventions** (camelCase for variables, PascalCase for classes)
136
+ 3. **Export only what's necessary** from index.ts
137
+ 4. **Add JSDoc comments for public APIs**
138
+ 5. **Use meaningful variable and function names**
139
+
140
+ ### Import Organization
141
+
142
+ ```typescript
143
+ // External dependencies
144
+ import { init } from '@paralleldrive/cuid2';
145
+
146
+ // Internal modules
147
+ import { createRootLogEntry, prettyError } from './utils';
148
+ import { LogData, LoggerOptions, LogEntry } from './types';
149
+ ```
150
+
151
+ ## 🧪 Testing
152
+
153
+ ### Test Framework
154
+
155
+ - **Vitest** for unit testing
156
+ - **Coverage** with v8 provider
157
+ - **100% coverage requirement** for new code
158
+
159
+ ### Writing Tests
160
+
161
+ 1. **Test file location**: `test/` directory
162
+ 2. **Naming convention**: `*.test.ts`
163
+ 3. **Structure your tests**:
164
+
165
+ ```typescript
166
+ import { describe, it, expect } from 'vitest';
167
+ import { createLogger } from '../src/index';
168
+
169
+ describe('Logger functionality', () => {
170
+ it('should create logger with event ID', () => {
171
+ const logger = createLogger({
172
+ details: { service: 'test' },
173
+ });
174
+
175
+ expect(logger.eventId).toBeDefined();
176
+ expect(typeof logger.eventId).toBe('string');
177
+ });
178
+ });
179
+ ```
180
+
181
+ ### Test Categories
182
+
183
+ 1. **Unit tests**: Individual function behavior
184
+ 2. **Integration tests**: Component interaction
185
+ 3. **Edge cases**: Error handling, invalid inputs
186
+ 4. **Type safety**: TypeScript compilation checks
187
+
188
+ ## 🔄 Pull Request Process
189
+
190
+ ### Branch Naming
191
+
192
+ Use descriptive branch names:
193
+
194
+ - `feature/area-logging-enhancement`
195
+ - `fix/error-handling-bug`
196
+ - `docs/updated-readme`
197
+
198
+ ### Commit Messages
199
+
200
+ Follow conventional commits:
201
+
202
+ ```
203
+ type(scope): description
204
+
205
+ feat(logger): add batch logging capability
206
+ fix(types): resolve optional parameter issue
207
+ docs(readme): update installation instructions
208
+ ```
209
+
210
+ ### Before Submitting PR
211
+
212
+ 1. **Create feature branch** from main
213
+ 2. **Make your changes** with atomic commits
214
+ 3. **Ensure all tests pass**:
215
+ ```bash
216
+ npm test
217
+ npm run test
218
+ ```
219
+ 4. **Verify linting**:
220
+ ```bash
221
+ npm run lint:check
222
+ ```
223
+ 5. **Build successfully**:
224
+ ```bash
225
+ npm run build
226
+ ```
227
+ 6. **Update documentation** if needed
228
+
229
+ ### PR Description Template
230
+
231
+ ```markdown
232
+ ## Description
233
+
234
+ Brief description of changes made.
235
+
236
+ ## Type of Change
237
+
238
+ - [ ] Bug fix
239
+ - [ ] New feature
240
+ - [ ] Breaking change
241
+ - [ ] Documentation update
242
+
243
+ ## Testing
244
+
245
+ - [ ] All tests pass
246
+ - [ ] 100% coverage maintained
247
+ - [ ] New tests added for new functionality
248
+
249
+ ## Checklist
250
+
251
+ - [ ] Code follows project style guidelines
252
+ - [ ] Self-review completed
253
+ - [ ] Documentation updated if necessary
254
+ ```
255
+
256
+ ## 🚀 Release Process
257
+
258
+ ### Version Management
259
+
260
+ - Follow **Semantic Versioning** (SemVer)
261
+ - Update version in `package.json`
262
+ - Create git tag for releases
263
+
264
+ ### Pre-release Checks
265
+
266
+ 1. **All tests pass**
267
+ 2. **100% coverage maintained**
268
+ 3. **Linting passes**
269
+ 4. **Build succeeds**
270
+ 5. **Documentation updated**
271
+
272
+ ### Build Verification
273
+
274
+ ```bash
275
+ # Clean build
276
+ rm -rf dist/
277
+ npm run build
278
+
279
+ # Verify outputs
280
+ ls -la dist/
281
+ # Should contain: index.js, index.mjs, index.d.ts, source maps
282
+ ```
283
+
284
+ ### Publishing
285
+
286
+ 1. **Update version** in package.json
287
+ 2. **Create git tag**:
288
+ ```bash
289
+ git tag v0.1.1
290
+ git push origin v0.1.1
291
+ ```
292
+ 3. **Publish to npm** (if you have access):
293
+ ```bash
294
+ npm publish
295
+ ```
296
+
297
+ ## 🆘 Getting Help
298
+
299
+ - **Check existing issues** for similar problems
300
+ - **Read the README.md** for usage examples
301
+ - **Look at test files** for implementation patterns
302
+ - **Review TypeScript types** in `src/types.ts`
303
+
304
+ ## 📚 Additional Resources
305
+
306
+ - [TypeScript Handbook](https://www.typescriptlang.org/docs/)
307
+ - [Vitest Documentation](https://vitest.dev/)
308
+ - [ESLint Configuration](https://eslint.org/docs/latest/)
309
+ - [Semantic Versioning](https://semver.org/)
310
+
311
+ ---
312
+
313
+ Thank you for contributing to the Hierarchical Area Logger project! Your contributions help make this library better for everyone. 🎉
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Roman Jankowski
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # 🌲 Hierarchical Area Logger
2
+
3
+ A lightweight, structured logging utility for TypeScript applications. It allows you to scope logs to specific **Areas**, track request flows via **Event IDs**, and **dump** the entire execution history for debugging or monitoring.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **Scoped Logging:** Group logs by logical "areas" (e.g., `db-layer`, `auth-service`).
8
+ - **Traceability:** Automatic Event ID generation and Parent Event ID mapping for distributed tracing.
9
+ - **Structured Payloads:** Log rich objects and Error instances without losing metadata.
10
+ - **Snapshot Dumping:** Retrieve the entire log state at any time for analysis or reporting.
11
+ - **Lightweight:** Designed to be dependency-lite and predictable.
12
+
13
+ ---
14
+
15
+ ## 🛠 Installation
16
+
17
+ ```bash
18
+ npm install hierarchical-area-logger
19
+ # or
20
+ yarn add hierarchical-area-logger
21
+
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 💡 Functionality Showcase
27
+
28
+ ### 1. Basic Scoped Logging
29
+
30
+ Instead of a flat stream of text, the logger categorizes logs into logical areas.
31
+
32
+ ```typescript
33
+ import { createLogger } from 'hierarchical-area-logger';
34
+
35
+ const logger = createLogger({
36
+ details: { service: 'payment-gateway' },
37
+ });
38
+
39
+ const checkout = logger.getArea('checkout-process');
40
+
41
+ checkout.info('User started checkout');
42
+ checkout.warn('Retry attempt 1 for payment');
43
+ checkout.error('Transaction failed', new Error('Timeout'));
44
+
45
+ // View the structured output
46
+ console.log(logger.dump());
47
+ ```
48
+
49
+ ### 2. Request Traceability
50
+
51
+ Track a request across your system by linking `eventId` and `parentEventId`.
52
+
53
+ ```typescript
54
+ const logger = createLogger({
55
+ details: { service: 'payment-gateway' }
56
+ path: '/api/v1/user',
57
+ parentEventId: 'incoming-request-id-001'
58
+ });
59
+
60
+ console.log(logger.eventId); // Automatically generated unique ID
61
+ console.log(logger.parentEventId); // 'incoming-request-id-001'
62
+
63
+ ```
64
+
65
+ ### 3. Log Merging & State Management
66
+
67
+ You can append existing log data to a logger instance, which is useful for consolidating logs from multiple micro-tasks.
68
+
69
+ ```typescript
70
+ const mainLogger = createLogger({ details: { service: 'orchestrator' } });
71
+
72
+ const externalLogs = {
73
+ 'worker-1': [
74
+ { type: 'info', message: 'Task complete', timestamp: Date.now() },
75
+ ],
76
+ };
77
+
78
+ mainLogger.appendLogData(externalLogs);
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 📖 API Reference
84
+
85
+ ### `createLogger(options)`
86
+
87
+ Factory function to initialize a new Logger instance.
88
+
89
+ | Option | Type | Description |
90
+ | --------------- | --------- | ------------------------------------------ |
91
+ | `details` | `Details` | Metadata about the service or environment. |
92
+ | `path` | `string` | (Optional) The execution path/route. |
93
+ | `parentEventId` | `string` | (Optional) ID of the triggering event. |
94
+
95
+ ### `LoggerInstance` Methods
96
+
97
+ - **`getArea(name: string)`**: Returns a scoped logger for a specific logic block.
98
+ - `.info(msg, payload?)`
99
+ - `.warn(msg, payload?)`
100
+ - `.error(msg, error?)`
101
+
102
+ - **`dump()`**: Returns an object containing all logs indexed by their area names.
103
+ - **`appendLogData(data)`**: Manually injects log entries into the current instance.
104
+
105
+ ---
106
+
107
+ ## 🧪 Development & Testing
108
+
109
+ This project uses **Vitest** for unit testing.
110
+
111
+ ```bash
112
+ # Run tests
113
+ npm test
114
+
115
+ # Run tests with coverage
116
+ npm run coverage
117
+
118
+ ```
119
+
120
+ > **Note:** The logger automatically creates a `root` area log entry labeled "Request received" if a `path` is provided during initialization.
package/dist/index.cjs ADDED
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Logger: () => Logger,
24
+ createLogger: () => createLogger
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/Logger.ts
29
+ var import_cuid2 = require("@paralleldrive/cuid2");
30
+
31
+ // src/utils.ts
32
+ var prettyStack = (stack) => {
33
+ if (!stack) return [];
34
+ let toReplace = "";
35
+ const regex = /file:\/\/\/(.*)(\.wrangler|node_modules)\/.*\)/gm;
36
+ const m = regex.exec(stack);
37
+ if (m && m.length > 1) {
38
+ toReplace = m[1];
39
+ }
40
+ return stack.split("\n").map((line) => line.trim()).filter((line) => !line.startsWith("Error: ")).map((line) => line.replace(toReplace, "")).map((line) => line.replace("file://", ""));
41
+ };
42
+ var prettyError = (err) => {
43
+ const stack = prettyStack(err.stack);
44
+ const message = err.message;
45
+ return { message, stack };
46
+ };
47
+ var createRootLogEntry = ({
48
+ path,
49
+ method,
50
+ details,
51
+ eventId,
52
+ parentEventId,
53
+ withParentEventId
54
+ }) => {
55
+ const url = new URL(`http://example.com${path ?? "/"}`);
56
+ const rootLogEntry = {
57
+ root: [
58
+ {
59
+ type: "info",
60
+ message: "Request received",
61
+ payload: {
62
+ path: `${url.pathname}${url.search}`,
63
+ method,
64
+ details,
65
+ eventId,
66
+ ...parentEventId && { parentEventId }
67
+ },
68
+ timestamp: Date.now()
69
+ }
70
+ ]
71
+ };
72
+ if (withParentEventId && !parentEventId) {
73
+ rootLogEntry.root.push({
74
+ type: "error",
75
+ message: "Parent event ID expected but not found",
76
+ timestamp: Date.now()
77
+ });
78
+ }
79
+ return rootLogEntry;
80
+ };
81
+
82
+ // src/Logger.ts
83
+ var Logger = class {
84
+ constructor(options) {
85
+ this.parentEventId = options.parentEventId;
86
+ this.eventId = (0, import_cuid2.init)({ fingerprint: options.details.service })();
87
+ this.log = createRootLogEntry({
88
+ path: options.path || "/",
89
+ method: options.method,
90
+ details: options.details,
91
+ eventId: this.eventId,
92
+ parentEventId: options.parentEventId,
93
+ withParentEventId: options.withParentEventId
94
+ });
95
+ }
96
+ // Area function that returns area-specific logger methods
97
+ getArea(name = "dummy") {
98
+ if (!this.log[name]) {
99
+ this.log[name] = [];
100
+ }
101
+ return {
102
+ info: (message, payload) => {
103
+ this.log[name].push({
104
+ type: "info",
105
+ message,
106
+ payload,
107
+ timestamp: Date.now()
108
+ });
109
+ },
110
+ warn: (message, payload) => {
111
+ this.log[name].push({
112
+ type: "warn",
113
+ message,
114
+ payload,
115
+ timestamp: Date.now()
116
+ });
117
+ },
118
+ error: (message, payload) => {
119
+ this.log[name].push({
120
+ type: "error",
121
+ message,
122
+ payload: payload instanceof Error ? prettyError(payload) : payload,
123
+ timestamp: Date.now()
124
+ });
125
+ }
126
+ };
127
+ }
128
+ // Public methods on main instance
129
+ dump() {
130
+ return this.log;
131
+ }
132
+ appendLogData(logData) {
133
+ delete logData.root;
134
+ this.log = { ...logData, ...this.log };
135
+ }
136
+ };
137
+ var createLogger = (options) => {
138
+ return new Logger(options);
139
+ };
140
+ // Annotate the CommonJS export names for ESM import in node:
141
+ 0 && (module.exports = {
142
+ Logger,
143
+ createLogger
144
+ });
145
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/Logger.ts","../src/utils.ts"],"sourcesContent":["export { Logger, createLogger } from './Logger';\nexport { LogData, LogEntry } from './types';\n","import { init } from '@paralleldrive/cuid2';\nimport { createRootLogEntry, prettyError } from './utils';\nimport { LogData, LoggerOptions, LogEntry } from './types';\n\nexport class Logger {\n public eventId: string;\n private log: LogData;\n public parentEventId?: string;\n\n constructor(options: LoggerOptions) {\n this.parentEventId = options.parentEventId;\n this.eventId = init({ fingerprint: options.details.service })();\n\n this.log = createRootLogEntry({\n path: options.path || '/',\n method: options.method,\n details: options.details,\n eventId: this.eventId,\n parentEventId: options.parentEventId,\n withParentEventId: options.withParentEventId,\n });\n }\n\n // Area function that returns area-specific logger methods\n public getArea(name = 'dummy') {\n if (!this.log[name]) {\n this.log[name] = [];\n }\n\n return {\n info: (message: string, payload?: LogEntry['payload']) => {\n this.log[name]!.push({\n type: 'info',\n message,\n payload,\n timestamp: Date.now(),\n });\n },\n warn: (message: string, payload?: LogEntry['payload']) => {\n this.log[name]!.push({\n type: 'warn',\n message,\n payload,\n timestamp: Date.now(),\n });\n },\n error: (message: string, payload?: LogEntry['payload'] | Error) => {\n this.log[name]!.push({\n type: 'error',\n message,\n payload: payload instanceof Error ? prettyError(payload) : payload,\n timestamp: Date.now(),\n });\n },\n };\n }\n\n // Public methods on main instance\n public dump(): LogData {\n return this.log;\n }\n\n public appendLogData(logData: LogData): void {\n delete logData.root;\n this.log = { ...logData, ...this.log };\n }\n}\n\n// Factory function for convenience\nexport const createLogger = (options: LoggerOptions): Logger => {\n return new Logger(options);\n};\n","import { CreateRootLogEntryOptions, LogData, RootPayload } from './types';\n\nexport const prettyStack = (stack?: string): string[] => {\n if (!stack) return [];\n let toReplace = '';\n\n const regex = /file:\\/\\/\\/(.*)(\\.wrangler|node_modules)\\/.*\\)/gm;\n const m = regex.exec(stack);\n\n if (m && m.length > 1) {\n toReplace = m[1];\n }\n\n return stack\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => !line.startsWith('Error: '))\n .map((line) => line.replace(toReplace, ''))\n .map((line) => line.replace('file://', ''));\n};\n\nexport const prettyError = (err: Error) => {\n const stack = prettyStack(err.stack);\n const message = err.message;\n return { message, stack };\n};\n\nexport const createRootLogEntry = ({\n path,\n method,\n details,\n eventId,\n parentEventId,\n withParentEventId,\n}: CreateRootLogEntryOptions): LogData => {\n const url = new URL(`http://example.com${path ?? '/'}`);\n\n const rootLogEntry: LogData = {\n root: [\n {\n type: 'info',\n message: 'Request received',\n payload: {\n path: `${url.pathname}${url.search}`,\n method,\n details,\n eventId,\n ...(parentEventId && { parentEventId }),\n } as RootPayload,\n timestamp: Date.now(),\n },\n ],\n };\n\n if (withParentEventId && !parentEventId) {\n rootLogEntry.root.push({\n type: 'error',\n message: 'Parent event ID expected but not found',\n timestamp: Date.now(),\n });\n }\n\n return rootLogEntry;\n};\n"],"mappings":"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","names":[]}
@@ -0,0 +1,35 @@
1
+ type Details = {
2
+ service: string;
3
+ } & Record<string, unknown>;
4
+ type Method = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'options' | 'trace' | 'connect';
5
+ type LogEntry = {
6
+ type: 'info' | 'warn' | 'error';
7
+ message: string;
8
+ payload?: object;
9
+ timestamp: number;
10
+ };
11
+ type LogData = Record<string, LogEntry[]>;
12
+ interface LoggerOptions {
13
+ details: Details;
14
+ path?: string;
15
+ parentEventId?: string;
16
+ withParentEventId?: boolean;
17
+ method?: Method;
18
+ }
19
+
20
+ declare class Logger {
21
+ eventId: string;
22
+ private log;
23
+ parentEventId?: string;
24
+ constructor(options: LoggerOptions);
25
+ getArea(name?: string): {
26
+ info: (message: string, payload?: LogEntry["payload"]) => void;
27
+ warn: (message: string, payload?: LogEntry["payload"]) => void;
28
+ error: (message: string, payload?: LogEntry["payload"] | Error) => void;
29
+ };
30
+ dump(): LogData;
31
+ appendLogData(logData: LogData): void;
32
+ }
33
+ declare const createLogger: (options: LoggerOptions) => Logger;
34
+
35
+ export { type LogData, type LogEntry, Logger, createLogger };
@@ -0,0 +1,35 @@
1
+ type Details = {
2
+ service: string;
3
+ } & Record<string, unknown>;
4
+ type Method = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'options' | 'trace' | 'connect';
5
+ type LogEntry = {
6
+ type: 'info' | 'warn' | 'error';
7
+ message: string;
8
+ payload?: object;
9
+ timestamp: number;
10
+ };
11
+ type LogData = Record<string, LogEntry[]>;
12
+ interface LoggerOptions {
13
+ details: Details;
14
+ path?: string;
15
+ parentEventId?: string;
16
+ withParentEventId?: boolean;
17
+ method?: Method;
18
+ }
19
+
20
+ declare class Logger {
21
+ eventId: string;
22
+ private log;
23
+ parentEventId?: string;
24
+ constructor(options: LoggerOptions);
25
+ getArea(name?: string): {
26
+ info: (message: string, payload?: LogEntry["payload"]) => void;
27
+ warn: (message: string, payload?: LogEntry["payload"]) => void;
28
+ error: (message: string, payload?: LogEntry["payload"] | Error) => void;
29
+ };
30
+ dump(): LogData;
31
+ appendLogData(logData: LogData): void;
32
+ }
33
+ declare const createLogger: (options: LoggerOptions) => Logger;
34
+
35
+ export { type LogData, type LogEntry, Logger, createLogger };