@tallyrow/safesignal 1.0.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Public type surface for the frontend logging package.
3
+ *
4
+ * Every export here is part of the SemVer-stable consumer contract documented
5
+ * in `specs/001-structured-logging-core/contracts/`. Adding new optional
6
+ * fields is a minor-version change; removals or signature changes require a
7
+ * major-version bump and a migration note.
8
+ *
9
+ * Locked invariants:
10
+ * - `Attributes` is a recursive **constrained** union — `unknown` and
11
+ * `object` are deliberately excluded so passing a raw class instance is
12
+ * type-friction. The sanitizer (T031) coerces stragglers at runtime.
13
+ * - The ONLY `unknown` parameter in the public surface is the optional
14
+ * `error` arg of `Logger.error()`.
15
+ * - The package source MUST NOT consult any ambient state
16
+ * (`process.env`, `import.meta.env`, `location`, `document.cookie`);
17
+ * enforced by `tests/contract/no-ambient-state.test.ts` (T013).
18
+ * - The public `.d.ts` MUST NOT mention `@opentelemetry/*` or any OTel
19
+ * concept name; enforced by `tests/contract/declarations-surface.test.ts`
20
+ * (T013) and `tests/security/bundle-shape.security.test.ts` (T049).
21
+ */
22
+ /** Severity levels, in increasing order. */
23
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
24
+ /**
25
+ * Per-environment level overrides. Resolved per `contracts/logger-config.md`
26
+ * (LC-3): config.level (LevelMap → environment lookup) takes precedence over
27
+ * the env-default table.
28
+ */
29
+ type LevelMap = Partial<Record<'production' | 'development' | 'test', LogLevel>>;
30
+ /**
31
+ * A value that may appear inside `LogEvent.attributes` or
32
+ * `LogContext.attributes`. Excludes `unknown`, `object`, class instances, DOM
33
+ * nodes, framework objects, functions, symbols, and bigints by design —
34
+ * passing those is allowed at runtime (TypeScript cannot fully prevent it)
35
+ * but the sanitizer (T031) reduces them to type tags before any transport
36
+ * sees the event.
37
+ */
38
+ type AttributeValue = string | number | boolean | null | AttributeValue[] | {
39
+ [key: string]: AttributeValue;
40
+ };
41
+ /** A bag of per-call or per-context structured attributes. Always an object. */
42
+ type Attributes = Record<string, AttributeValue>;
43
+ /** Application identity — the consuming app, even from a federated module. */
44
+ interface AppIdentity {
45
+ name: string;
46
+ version?: string;
47
+ }
48
+ /** Module identity — for independently deployed federated modules. */
49
+ interface ModuleIdentity {
50
+ name: string;
51
+ version?: string;
52
+ }
53
+ /**
54
+ * Merged context attached to every emitted `LogEvent`. Merge precedence
55
+ * is documented in `contracts/logger-config.md` (LC-7) and
56
+ * `data-model.md`: root config → per-logger options → logger chain
57
+ * (`child()` / `withContext()`) → `correlation()` return value.
58
+ */
59
+ interface LogContext {
60
+ application?: AppIdentity;
61
+ module?: ModuleIdentity;
62
+ environment?: string;
63
+ attributes?: Attributes;
64
+ }
65
+ /**
66
+ * Captured error information populated by `Logger.error(msg, attrs, err)`.
67
+ * The pipeline reduces an arbitrary `unknown` error value to this shape
68
+ * immediately; transports never see the original `Error` instance.
69
+ */
70
+ interface ErrorInfo {
71
+ name: string;
72
+ message: string;
73
+ stack?: string;
74
+ }
75
+ /**
76
+ * The canonical structured event produced by the pipeline. By the time a
77
+ * transport receives a `LogEvent`, it has been: (1) sanitized per
78
+ * `contracts/sanitization.md`, (2) URL-scrubbed, (3) redacted per
79
+ * `contracts/redaction.md` (fail-closed), (4) control-char-escaped, and
80
+ * (5) frozen in dev builds. See `contracts/log-event.md` LE-1..LE-11.
81
+ */
82
+ interface LogEvent {
83
+ /** ISO-8601 string assigned by the pipeline; consumer-supplied input ignored. */
84
+ timestamp: string;
85
+ /** Severity matching the logger method called. */
86
+ level: LogLevel;
87
+ /** Required. Empty string allowed. Sanitized for length and control chars. */
88
+ message: string;
89
+ /** Always an object. May be empty. Sanitized and redacted before delivery. */
90
+ attributes: Attributes;
91
+ /** Always present. Merged from config + logger chain + correlation. */
92
+ context: LogContext;
93
+ /** Populated only when `Logger.error(msg, attrs, err)` is called with `err`. */
94
+ error?: ErrorInfo;
95
+ }
96
+ /**
97
+ * Delivery interface. Consumer transports MUST follow the security contract
98
+ * in `contracts/transport.md` (T-S1..T-S5): body-only delivery (POST/PUT
99
+ * JSON or `Blob` sendBeacon), HTTPS cross-origin, no event data in URL
100
+ * paths / queries / fragments, treat events as immutable, idempotent
101
+ * `flush`/`shutdown`. Failure isolation is provided by the package's
102
+ * internal `SafeTransport` wrapper.
103
+ */
104
+ interface Transport {
105
+ /** Stable diagnostic identifier. */
106
+ name: string;
107
+ /** Receive a fully processed `LogEvent`. May be sync or async. */
108
+ send(event: LogEvent): void | Promise<void>;
109
+ /** Optional flush hook for batching transports. */
110
+ flush?(): Promise<void>;
111
+ /** Optional shutdown hook. Must be idempotent. */
112
+ shutdown?(): Promise<void>;
113
+ }
114
+ /**
115
+ * Factory that produces a `Transport`. Used by `LoggerConfig.transports`
116
+ * so configuration values can stay declarative — the factory is invoked
117
+ * once at `configureLogging()` time.
118
+ */
119
+ type TransportFactory = () => Transport;
120
+ /**
121
+ * One redaction rule. At least one of `key` or `shape` must be set.
122
+ * - `key`: case-insensitive match against the IMMEDIATE property name of
123
+ * the value being inspected (never a value substring).
124
+ * - `shape`: match against leaf string values, regardless of key.
125
+ */
126
+ interface RedactionRule {
127
+ key?: string | RegExp;
128
+ shape?: RegExp;
129
+ /** Replacement string. Default `'[REDACTED]'`. */
130
+ replacement?: string;
131
+ }
132
+ /**
133
+ * A redactor receives the post-sanitize, pre-control-char-guard `LogEvent`
134
+ * and returns either a transformed event or `null` to drop the event
135
+ * entirely. MUST be synchronous. If it throws or returns any other value,
136
+ * the dispatcher drops the event (fail-closed) and invokes
137
+ * `LoggerConfig.onInternalError`. See `contracts/redaction.md`.
138
+ */
139
+ type Redactor = (event: LogEvent) => LogEvent | null;
140
+ /**
141
+ * Configurable upper bounds for the sanitizer. Consumers MAY tighten any
142
+ * limit by passing a value below the default; values above the documented
143
+ * Max clamp to Max, values below Min clamp to Min, and both clamping events
144
+ * emit one `onInternalError` notice at `configureLogging()` time.
145
+ *
146
+ * Defaults / bounds (locked by `contracts/sanitization.md`):
147
+ * maxDepth: default 8, min 1, max 16
148
+ * maxStringLength: default 8192, min 64, max 65536
149
+ * maxArrayLength: default 1000, min 1, max 10000
150
+ * maxAttributeCount: default 256, min 1, max 4096
151
+ */
152
+ interface SanitizerLimits {
153
+ maxDepth: number;
154
+ maxStringLength: number;
155
+ maxArrayLength: number;
156
+ maxAttributeCount: number;
157
+ }
158
+ /**
159
+ * Options for `scrubUrl(url, options?)`. The default URL scrubber strips
160
+ * query and (optionally) fragment params whose names match the redaction
161
+ * denylist; `extraParams` adds project-specific names.
162
+ */
163
+ interface ScrubUrlOptions {
164
+ /** Additional query/fragment param names to scrub (case-insensitive). */
165
+ extraParams?: ReadonlyArray<string | RegExp>;
166
+ /** Whether to also scrub the URL fragment. Default `true`. */
167
+ fragment?: boolean;
168
+ }
169
+ /**
170
+ * Root logging configuration. Pass once via `configureLogging()`. Defaults
171
+ * are documented in `contracts/logger-config.md`.
172
+ */
173
+ interface LoggerConfig {
174
+ application?: AppIdentity;
175
+ module?: ModuleIdentity;
176
+ /** `'production' | 'development' | 'test'` or any string; unknown → `warn`. */
177
+ environment?: string;
178
+ /** Single level or per-environment map. Overrides env defaults. */
179
+ level?: LogLevel | LevelMap;
180
+ /** Static metadata merged into every emitted event's context. */
181
+ context?: Partial<LogContext>;
182
+ /** Per-emit dynamic context hook. Must be cheap and synchronous. */
183
+ correlation?: () => Partial<LogContext>;
184
+ /** Configured transports. Empty/undefined installs `NoopTransport`. */
185
+ transports?: Array<Transport | TransportFactory>;
186
+ /** Custom redactor. Fully replaces the default unless composed manually. */
187
+ redactor?: Redactor;
188
+ /** Tighten sanitizer bounds. Values above documented Max are clamped. */
189
+ sanitizerLimits?: Partial<SanitizerLimits>;
190
+ /**
191
+ * Diagnostics hook for internal failures (transport throws, init failure,
192
+ * redactor throw, sanitizer-limit clamp). Fires at most once per
193
+ * failing transport per session.
194
+ */
195
+ onInternalError?: (err: Error) => void;
196
+ }
197
+ /**
198
+ * Options for `createLogger()` — layered on top of the root `LoggerConfig`.
199
+ */
200
+ interface CreateLoggerOptions {
201
+ /** Optional free-form logger name for diagnostics. Not part of the event. */
202
+ name?: string;
203
+ /** Override `module` identity for this logger only (federated modules). */
204
+ module?: ModuleIdentity;
205
+ /** Additional static context for this logger. Merged with root context. */
206
+ context?: Partial<LogContext>;
207
+ /** Per-logger level override. Wins over root config and env defaults. */
208
+ level?: LogLevel;
209
+ }
210
+ /**
211
+ * The consumer-facing logger. Every method returns synchronously and never
212
+ * throws. The only `unknown` parameter in the public surface is the
213
+ * optional `error` arg of `error()`; the pipeline immediately reduces it
214
+ * to `ErrorInfo`.
215
+ */
216
+ interface Logger {
217
+ debug(message: string, attributes?: Attributes): void;
218
+ info(message: string, attributes?: Attributes): void;
219
+ warn(message: string, attributes?: Attributes): void;
220
+ error(message: string, attributes?: Attributes, error?: unknown): void;
221
+ /** Return a derived logger with additional context layered on top. */
222
+ child(context: Partial<LogContext>): Logger;
223
+ /** Alias for `child()`. */
224
+ withContext(context: Partial<LogContext>): Logger;
225
+ }
226
+
227
+ export type { AppIdentity as A, CreateLoggerOptions as C, ErrorInfo as E, LevelMap as L, ModuleIdentity as M, RedactionRule as R, SanitizerLimits as S, Transport as T, AttributeValue as a, Attributes as b, LogContext as c, LogEvent as d, LogLevel as e, Logger as f, LoggerConfig as g, Redactor as h, ScrubUrlOptions as i, TransportFactory as j };
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Public type surface for the frontend logging package.
3
+ *
4
+ * Every export here is part of the SemVer-stable consumer contract documented
5
+ * in `specs/001-structured-logging-core/contracts/`. Adding new optional
6
+ * fields is a minor-version change; removals or signature changes require a
7
+ * major-version bump and a migration note.
8
+ *
9
+ * Locked invariants:
10
+ * - `Attributes` is a recursive **constrained** union — `unknown` and
11
+ * `object` are deliberately excluded so passing a raw class instance is
12
+ * type-friction. The sanitizer (T031) coerces stragglers at runtime.
13
+ * - The ONLY `unknown` parameter in the public surface is the optional
14
+ * `error` arg of `Logger.error()`.
15
+ * - The package source MUST NOT consult any ambient state
16
+ * (`process.env`, `import.meta.env`, `location`, `document.cookie`);
17
+ * enforced by `tests/contract/no-ambient-state.test.ts` (T013).
18
+ * - The public `.d.ts` MUST NOT mention `@opentelemetry/*` or any OTel
19
+ * concept name; enforced by `tests/contract/declarations-surface.test.ts`
20
+ * (T013) and `tests/security/bundle-shape.security.test.ts` (T049).
21
+ */
22
+ /** Severity levels, in increasing order. */
23
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
24
+ /**
25
+ * Per-environment level overrides. Resolved per `contracts/logger-config.md`
26
+ * (LC-3): config.level (LevelMap → environment lookup) takes precedence over
27
+ * the env-default table.
28
+ */
29
+ type LevelMap = Partial<Record<'production' | 'development' | 'test', LogLevel>>;
30
+ /**
31
+ * A value that may appear inside `LogEvent.attributes` or
32
+ * `LogContext.attributes`. Excludes `unknown`, `object`, class instances, DOM
33
+ * nodes, framework objects, functions, symbols, and bigints by design —
34
+ * passing those is allowed at runtime (TypeScript cannot fully prevent it)
35
+ * but the sanitizer (T031) reduces them to type tags before any transport
36
+ * sees the event.
37
+ */
38
+ type AttributeValue = string | number | boolean | null | AttributeValue[] | {
39
+ [key: string]: AttributeValue;
40
+ };
41
+ /** A bag of per-call or per-context structured attributes. Always an object. */
42
+ type Attributes = Record<string, AttributeValue>;
43
+ /** Application identity — the consuming app, even from a federated module. */
44
+ interface AppIdentity {
45
+ name: string;
46
+ version?: string;
47
+ }
48
+ /** Module identity — for independently deployed federated modules. */
49
+ interface ModuleIdentity {
50
+ name: string;
51
+ version?: string;
52
+ }
53
+ /**
54
+ * Merged context attached to every emitted `LogEvent`. Merge precedence
55
+ * is documented in `contracts/logger-config.md` (LC-7) and
56
+ * `data-model.md`: root config → per-logger options → logger chain
57
+ * (`child()` / `withContext()`) → `correlation()` return value.
58
+ */
59
+ interface LogContext {
60
+ application?: AppIdentity;
61
+ module?: ModuleIdentity;
62
+ environment?: string;
63
+ attributes?: Attributes;
64
+ }
65
+ /**
66
+ * Captured error information populated by `Logger.error(msg, attrs, err)`.
67
+ * The pipeline reduces an arbitrary `unknown` error value to this shape
68
+ * immediately; transports never see the original `Error` instance.
69
+ */
70
+ interface ErrorInfo {
71
+ name: string;
72
+ message: string;
73
+ stack?: string;
74
+ }
75
+ /**
76
+ * The canonical structured event produced by the pipeline. By the time a
77
+ * transport receives a `LogEvent`, it has been: (1) sanitized per
78
+ * `contracts/sanitization.md`, (2) URL-scrubbed, (3) redacted per
79
+ * `contracts/redaction.md` (fail-closed), (4) control-char-escaped, and
80
+ * (5) frozen in dev builds. See `contracts/log-event.md` LE-1..LE-11.
81
+ */
82
+ interface LogEvent {
83
+ /** ISO-8601 string assigned by the pipeline; consumer-supplied input ignored. */
84
+ timestamp: string;
85
+ /** Severity matching the logger method called. */
86
+ level: LogLevel;
87
+ /** Required. Empty string allowed. Sanitized for length and control chars. */
88
+ message: string;
89
+ /** Always an object. May be empty. Sanitized and redacted before delivery. */
90
+ attributes: Attributes;
91
+ /** Always present. Merged from config + logger chain + correlation. */
92
+ context: LogContext;
93
+ /** Populated only when `Logger.error(msg, attrs, err)` is called with `err`. */
94
+ error?: ErrorInfo;
95
+ }
96
+ /**
97
+ * Delivery interface. Consumer transports MUST follow the security contract
98
+ * in `contracts/transport.md` (T-S1..T-S5): body-only delivery (POST/PUT
99
+ * JSON or `Blob` sendBeacon), HTTPS cross-origin, no event data in URL
100
+ * paths / queries / fragments, treat events as immutable, idempotent
101
+ * `flush`/`shutdown`. Failure isolation is provided by the package's
102
+ * internal `SafeTransport` wrapper.
103
+ */
104
+ interface Transport {
105
+ /** Stable diagnostic identifier. */
106
+ name: string;
107
+ /** Receive a fully processed `LogEvent`. May be sync or async. */
108
+ send(event: LogEvent): void | Promise<void>;
109
+ /** Optional flush hook for batching transports. */
110
+ flush?(): Promise<void>;
111
+ /** Optional shutdown hook. Must be idempotent. */
112
+ shutdown?(): Promise<void>;
113
+ }
114
+ /**
115
+ * Factory that produces a `Transport`. Used by `LoggerConfig.transports`
116
+ * so configuration values can stay declarative — the factory is invoked
117
+ * once at `configureLogging()` time.
118
+ */
119
+ type TransportFactory = () => Transport;
120
+ /**
121
+ * One redaction rule. At least one of `key` or `shape` must be set.
122
+ * - `key`: case-insensitive match against the IMMEDIATE property name of
123
+ * the value being inspected (never a value substring).
124
+ * - `shape`: match against leaf string values, regardless of key.
125
+ */
126
+ interface RedactionRule {
127
+ key?: string | RegExp;
128
+ shape?: RegExp;
129
+ /** Replacement string. Default `'[REDACTED]'`. */
130
+ replacement?: string;
131
+ }
132
+ /**
133
+ * A redactor receives the post-sanitize, pre-control-char-guard `LogEvent`
134
+ * and returns either a transformed event or `null` to drop the event
135
+ * entirely. MUST be synchronous. If it throws or returns any other value,
136
+ * the dispatcher drops the event (fail-closed) and invokes
137
+ * `LoggerConfig.onInternalError`. See `contracts/redaction.md`.
138
+ */
139
+ type Redactor = (event: LogEvent) => LogEvent | null;
140
+ /**
141
+ * Configurable upper bounds for the sanitizer. Consumers MAY tighten any
142
+ * limit by passing a value below the default; values above the documented
143
+ * Max clamp to Max, values below Min clamp to Min, and both clamping events
144
+ * emit one `onInternalError` notice at `configureLogging()` time.
145
+ *
146
+ * Defaults / bounds (locked by `contracts/sanitization.md`):
147
+ * maxDepth: default 8, min 1, max 16
148
+ * maxStringLength: default 8192, min 64, max 65536
149
+ * maxArrayLength: default 1000, min 1, max 10000
150
+ * maxAttributeCount: default 256, min 1, max 4096
151
+ */
152
+ interface SanitizerLimits {
153
+ maxDepth: number;
154
+ maxStringLength: number;
155
+ maxArrayLength: number;
156
+ maxAttributeCount: number;
157
+ }
158
+ /**
159
+ * Options for `scrubUrl(url, options?)`. The default URL scrubber strips
160
+ * query and (optionally) fragment params whose names match the redaction
161
+ * denylist; `extraParams` adds project-specific names.
162
+ */
163
+ interface ScrubUrlOptions {
164
+ /** Additional query/fragment param names to scrub (case-insensitive). */
165
+ extraParams?: ReadonlyArray<string | RegExp>;
166
+ /** Whether to also scrub the URL fragment. Default `true`. */
167
+ fragment?: boolean;
168
+ }
169
+ /**
170
+ * Root logging configuration. Pass once via `configureLogging()`. Defaults
171
+ * are documented in `contracts/logger-config.md`.
172
+ */
173
+ interface LoggerConfig {
174
+ application?: AppIdentity;
175
+ module?: ModuleIdentity;
176
+ /** `'production' | 'development' | 'test'` or any string; unknown → `warn`. */
177
+ environment?: string;
178
+ /** Single level or per-environment map. Overrides env defaults. */
179
+ level?: LogLevel | LevelMap;
180
+ /** Static metadata merged into every emitted event's context. */
181
+ context?: Partial<LogContext>;
182
+ /** Per-emit dynamic context hook. Must be cheap and synchronous. */
183
+ correlation?: () => Partial<LogContext>;
184
+ /** Configured transports. Empty/undefined installs `NoopTransport`. */
185
+ transports?: Array<Transport | TransportFactory>;
186
+ /** Custom redactor. Fully replaces the default unless composed manually. */
187
+ redactor?: Redactor;
188
+ /** Tighten sanitizer bounds. Values above documented Max are clamped. */
189
+ sanitizerLimits?: Partial<SanitizerLimits>;
190
+ /**
191
+ * Diagnostics hook for internal failures (transport throws, init failure,
192
+ * redactor throw, sanitizer-limit clamp). Fires at most once per
193
+ * failing transport per session.
194
+ */
195
+ onInternalError?: (err: Error) => void;
196
+ }
197
+ /**
198
+ * Options for `createLogger()` — layered on top of the root `LoggerConfig`.
199
+ */
200
+ interface CreateLoggerOptions {
201
+ /** Optional free-form logger name for diagnostics. Not part of the event. */
202
+ name?: string;
203
+ /** Override `module` identity for this logger only (federated modules). */
204
+ module?: ModuleIdentity;
205
+ /** Additional static context for this logger. Merged with root context. */
206
+ context?: Partial<LogContext>;
207
+ /** Per-logger level override. Wins over root config and env defaults. */
208
+ level?: LogLevel;
209
+ }
210
+ /**
211
+ * The consumer-facing logger. Every method returns synchronously and never
212
+ * throws. The only `unknown` parameter in the public surface is the
213
+ * optional `error` arg of `error()`; the pipeline immediately reduces it
214
+ * to `ErrorInfo`.
215
+ */
216
+ interface Logger {
217
+ debug(message: string, attributes?: Attributes): void;
218
+ info(message: string, attributes?: Attributes): void;
219
+ warn(message: string, attributes?: Attributes): void;
220
+ error(message: string, attributes?: Attributes, error?: unknown): void;
221
+ /** Return a derived logger with additional context layered on top. */
222
+ child(context: Partial<LogContext>): Logger;
223
+ /** Alias for `child()`. */
224
+ withContext(context: Partial<LogContext>): Logger;
225
+ }
226
+
227
+ export type { AppIdentity as A, CreateLoggerOptions as C, ErrorInfo as E, LevelMap as L, ModuleIdentity as M, RedactionRule as R, SanitizerLimits as S, Transport as T, AttributeValue as a, Attributes as b, LogContext as c, LogEvent as d, LogLevel as e, Logger as f, LoggerConfig as g, Redactor as h, ScrubUrlOptions as i, TransportFactory as j };
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@tallyrow/safesignal",
3
+ "version": "1.0.1-rc.1",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "SafeSignal — secure structured logging facade and safety boundary for browser applications and federated frontend modules. Browser-first, vendor-neutral, secure-by-default sanitization, redaction, and pluggable transports.",
8
+ "license": "MIT",
9
+ "keywords": [
10
+ "safesignal",
11
+ "logging",
12
+ "structured-logging",
13
+ "browser",
14
+ "frontend",
15
+ "federated",
16
+ "module-federation",
17
+ "sanitization",
18
+ "redaction",
19
+ "transport",
20
+ "observability",
21
+ "secure-by-default"
22
+ ],
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://gitlab.com/tallyrow/safesignal.git"
26
+ },
27
+ "type": "module",
28
+ "sideEffects": false,
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.mjs",
36
+ "require": "./dist/index.cjs"
37
+ },
38
+ "./testing": {
39
+ "types": "./dist/testing.d.ts",
40
+ "import": "./dist/testing.mjs",
41
+ "require": "./dist/testing.cjs"
42
+ },
43
+ "./transport-beacon": {
44
+ "types": "./dist/transport-beacon.d.ts",
45
+ "import": "./dist/transport-beacon.mjs",
46
+ "require": "./dist/transport-beacon.cjs"
47
+ }
48
+ },
49
+ "main": "./dist/index.cjs",
50
+ "module": "./dist/index.mjs",
51
+ "types": "./dist/index.d.ts",
52
+ "scripts": {
53
+ "build": "tsup",
54
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tests/tsconfig.json",
55
+ "typecheck:src": "tsc --noEmit",
56
+ "typecheck:tests": "tsc --noEmit -p tests/tsconfig.json",
57
+ "test": "vitest run",
58
+ "test:contract": "vitest run tests/contract",
59
+ "test:security": "vitest run tests/security",
60
+ "test:integration": "vitest run tests/integration",
61
+ "test:unit": "vitest run tests/unit",
62
+ "test:watch": "vitest"
63
+ },
64
+ "dependencies": {},
65
+ "devDependencies": {
66
+ "@opentelemetry/api": "^1.9.0",
67
+ "@opentelemetry/api-logs": "^0.57.0",
68
+ "@opentelemetry/sdk-logs": "^0.57.0",
69
+ "@types/node": "^20.0.0",
70
+ "@vitest/coverage-v8": "^2.1.0",
71
+ "happy-dom": "^15.0.0",
72
+ "tsup": "^8.3.0",
73
+ "typescript": "^5.4.0",
74
+ "vitest": "^2.1.0"
75
+ },
76
+ "engines": {
77
+ "node": ">=18.0.0"
78
+ }
79
+ }