sloplog 0.0.3

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,217 @@
1
+ /**
2
+ * Originator module - functions for creating originators from various sources
3
+ */
4
+ /**
5
+ * Generate a nano ID for unique identifiers
6
+ */
7
+ function nanoId() {
8
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
9
+ let result = '';
10
+ for (let i = 0; i < 21; i++) {
11
+ result += chars[Math.floor(Math.random() * chars.length)];
12
+ }
13
+ return result;
14
+ }
15
+ /** Header name for propagating originator ID across services */
16
+ export const ORIGINATOR_HEADER = 'x-sloplog-originator';
17
+ /** Header name for propagating trace ID across services */
18
+ export const TRACE_ID_HEADER = 'x-sloplog-trace-id';
19
+ /**
20
+ * Create headers for propagating tracing context to downstream services
21
+ */
22
+ export function tracingHeaders(context) {
23
+ return {
24
+ [TRACE_ID_HEADER]: context.traceId,
25
+ [ORIGINATOR_HEADER]: context.originatorId,
26
+ };
27
+ }
28
+ /**
29
+ * Extract tracing context from incoming request headers
30
+ * Returns null if no tracing headers are present
31
+ */
32
+ export function extractTracingContext(headers) {
33
+ // Case-insensitive header lookup for trace ID
34
+ let traceIdValue;
35
+ let originatorIdValue;
36
+ for (const [key, value] of Object.entries(headers)) {
37
+ const lowerKey = key.toLowerCase();
38
+ if (lowerKey === TRACE_ID_HEADER.toLowerCase()) {
39
+ traceIdValue = Array.isArray(value) ? value[0] : value;
40
+ }
41
+ else if (lowerKey === ORIGINATOR_HEADER.toLowerCase()) {
42
+ originatorIdValue = Array.isArray(value) ? value[0] : value;
43
+ }
44
+ }
45
+ if (!traceIdValue || !originatorIdValue) {
46
+ return null;
47
+ }
48
+ return {
49
+ traceId: traceIdValue,
50
+ originatorId: originatorIdValue,
51
+ };
52
+ }
53
+ /** Placeholder for redacted values */
54
+ const REDACTED = '[REDACTED]';
55
+ /** Headers that should be redacted (case-insensitive) */
56
+ const SENSITIVE_HEADERS = new Set([
57
+ 'authorization',
58
+ 'x-api-key',
59
+ 'x-auth-token',
60
+ 'cookie',
61
+ 'set-cookie',
62
+ ]);
63
+ /** Query parameters that should be redacted (case-insensitive) */
64
+ const SENSITIVE_QUERY_PARAMS = new Set([
65
+ 'code',
66
+ 'token',
67
+ 'access_token',
68
+ 'refresh_token',
69
+ 'api_key',
70
+ 'apikey',
71
+ 'secret',
72
+ 'password',
73
+ ]);
74
+ /**
75
+ * Redact sensitive headers from a headers object
76
+ */
77
+ function redactHeaders(headers) {
78
+ const redacted = {};
79
+ for (const [key, value] of Object.entries(headers)) {
80
+ if (SENSITIVE_HEADERS.has(key.toLowerCase())) {
81
+ redacted[key] = REDACTED;
82
+ }
83
+ else {
84
+ redacted[key] = value;
85
+ }
86
+ }
87
+ return redacted;
88
+ }
89
+ /**
90
+ * Redact sensitive query parameters from a query string
91
+ */
92
+ function redactQueryString(query) {
93
+ if (!query)
94
+ return query;
95
+ const params = new URLSearchParams(query);
96
+ const redactedParams = new URLSearchParams();
97
+ for (const [key, value] of params.entries()) {
98
+ if (SENSITIVE_QUERY_PARAMS.has(key.toLowerCase())) {
99
+ redactedParams.set(key, REDACTED);
100
+ }
101
+ else {
102
+ redactedParams.set(key, value);
103
+ }
104
+ }
105
+ const result = redactedParams.toString();
106
+ return result || undefined;
107
+ }
108
+ /**
109
+ * Create an HTTP originator from a Web Fetch API Request
110
+ * Extracts tracing context from headers if present:
111
+ * - traceId: extracted from x-sloplog-trace-id header, or generated if not present
112
+ * - parentId: set to the incoming x-sloplog-originator header value (the caller's originatorId),
113
+ * or can be explicitly provided via options.parentId
114
+ */
115
+ export function httpOriginator(request, options = {}) {
116
+ const url = new URL(request.url);
117
+ const headers = {};
118
+ request.headers.forEach((value, key) => {
119
+ headers[key.toLowerCase()] = value;
120
+ });
121
+ // Check for incoming tracing context
122
+ const tracingContext = extractTracingContext(headers);
123
+ // Redact sensitive data
124
+ const redactedHeaders = redactHeaders(headers);
125
+ const query = url.search ? url.search.slice(1) : undefined;
126
+ const redactedQuery = redactQueryString(query);
127
+ // Determine parentId: explicit option > tracing context > undefined
128
+ const parentId = options.parentId ?? tracingContext?.originatorId;
129
+ const originator = {
130
+ originatorId: options.originatorId || `orig_${nanoId()}`,
131
+ type: 'http',
132
+ timestamp: Date.now(),
133
+ ...(parentId && { parentId }),
134
+ method: request.method.toUpperCase(),
135
+ path: url.pathname,
136
+ query: redactedQuery,
137
+ headers: redactedHeaders,
138
+ host: url.host,
139
+ userAgent: headers['user-agent'],
140
+ contentType: headers['content-type'],
141
+ contentLength: headers['content-length'] ? parseInt(headers['content-length'], 10) : undefined,
142
+ };
143
+ return {
144
+ originator,
145
+ // Use incoming traceId if present, otherwise generate a new one
146
+ traceId: tracingContext?.traceId || `trace_${nanoId()}`,
147
+ };
148
+ }
149
+ /**
150
+ * Create an HTTP originator from a Node.js IncomingMessage (http/https/express)
151
+ * Extracts tracing context from headers if present:
152
+ * - traceId: extracted from x-sloplog-trace-id header, or generated if not present
153
+ * - parentId: set to the incoming x-sloplog-originator header value (the caller's originatorId),
154
+ * or can be explicitly provided via options.parentId
155
+ */
156
+ export function nodeHttpOriginator(request, options = {}) {
157
+ const headers = {};
158
+ for (const [key, value] of Object.entries(request.headers)) {
159
+ if (value) {
160
+ headers[key.toLowerCase()] = Array.isArray(value) ? value[0] : value;
161
+ }
162
+ }
163
+ // Parse URL
164
+ const urlStr = request.url || '/';
165
+ const host = headers['host'] || 'localhost';
166
+ let path = urlStr;
167
+ let query;
168
+ const queryIndex = urlStr.indexOf('?');
169
+ if (queryIndex !== -1) {
170
+ path = urlStr.slice(0, queryIndex);
171
+ query = urlStr.slice(queryIndex + 1);
172
+ }
173
+ // Check for incoming tracing context
174
+ const tracingContext = extractTracingContext(headers);
175
+ // Get client IP (check x-forwarded-for for proxied requests)
176
+ const clientIp = headers['x-forwarded-for']?.split(',')[0].trim() || request.socket?.remoteAddress;
177
+ // Redact sensitive data
178
+ const redactedHeaders = redactHeaders(headers);
179
+ const redactedQuery = redactQueryString(query);
180
+ // Determine parentId: explicit option > tracing context > undefined
181
+ const parentId = options.parentId ?? tracingContext?.originatorId;
182
+ const originator = {
183
+ originatorId: options.originatorId || `orig_${nanoId()}`,
184
+ type: 'http',
185
+ timestamp: Date.now(),
186
+ ...(parentId && { parentId }),
187
+ method: (request.method?.toUpperCase() || 'GET'),
188
+ path,
189
+ query: redactedQuery,
190
+ headers: redactedHeaders,
191
+ host,
192
+ clientIp,
193
+ userAgent: headers['user-agent'],
194
+ contentType: headers['content-type'],
195
+ contentLength: headers['content-length'] ? parseInt(headers['content-length'], 10) : undefined,
196
+ httpVersion: request.httpVersion,
197
+ };
198
+ return {
199
+ originator,
200
+ // Use incoming traceId if present, otherwise generate a new one
201
+ traceId: tracingContext?.traceId || `trace_${nanoId()}`,
202
+ };
203
+ }
204
+ /**
205
+ * Create a cron originator for scheduled tasks
206
+ */
207
+ export function cronOriginator(cron, jobName, options = {}) {
208
+ return {
209
+ originatorId: `orig_${nanoId()}`,
210
+ type: 'cron',
211
+ timestamp: Date.now(),
212
+ ...(options.parentId && { parentId: options.parentId }),
213
+ cron,
214
+ jobName,
215
+ scheduledTime: Date.now(),
216
+ };
217
+ }
@@ -0,0 +1,154 @@
1
+ import { z, type InferPartial } from './registry.js';
2
+ declare const error: import("./registry.js").PartialFactory<"error", {
3
+ message: z.ZodString;
4
+ stack: z.ZodOptional<z.ZodString>;
5
+ code: z.ZodOptional<z.ZodNumber>;
6
+ }, {
7
+ repeatable: true;
8
+ alwaysSample: true;
9
+ description: string;
10
+ }>;
11
+ declare const logMessage: import("./registry.js").PartialFactory<"log_message", {
12
+ message: z.ZodString;
13
+ level: z.ZodEnum<{
14
+ error: "error";
15
+ trace: "trace";
16
+ debug: "debug";
17
+ info: "info";
18
+ warn: "warn";
19
+ fatal: "fatal";
20
+ }>;
21
+ data: z.ZodOptional<z.ZodString>;
22
+ }, {
23
+ repeatable: true;
24
+ description: string;
25
+ }>;
26
+ declare const span: import("./registry.js").PartialFactory<"span", {
27
+ name: z.ZodString;
28
+ startedAt: z.ZodNumber;
29
+ endedAt: z.ZodNumber;
30
+ durationMs: z.ZodNumber;
31
+ }, {
32
+ repeatable: true;
33
+ description: string;
34
+ }>;
35
+ declare const sloplogUsageError: import("./registry.js").PartialFactory<"sloplog_usage_error", {
36
+ kind: z.ZodString;
37
+ message: z.ZodString;
38
+ partialType: z.ZodOptional<z.ZodString>;
39
+ spanName: z.ZodOptional<z.ZodString>;
40
+ startedAt: z.ZodOptional<z.ZodNumber>;
41
+ count: z.ZodOptional<z.ZodNumber>;
42
+ }, {
43
+ repeatable: true;
44
+ description: string;
45
+ }>;
46
+ /** Built-in partial definitions shipped with sloplog. */
47
+ export declare const builtInPartials: {
48
+ error: import("./registry.js").PartialFactory<"error", {
49
+ message: z.ZodString;
50
+ stack: z.ZodOptional<z.ZodString>;
51
+ code: z.ZodOptional<z.ZodNumber>;
52
+ }, {
53
+ repeatable: true;
54
+ alwaysSample: true;
55
+ description: string;
56
+ }>;
57
+ log_message: import("./registry.js").PartialFactory<"log_message", {
58
+ message: z.ZodString;
59
+ level: z.ZodEnum<{
60
+ error: "error";
61
+ trace: "trace";
62
+ debug: "debug";
63
+ info: "info";
64
+ warn: "warn";
65
+ fatal: "fatal";
66
+ }>;
67
+ data: z.ZodOptional<z.ZodString>;
68
+ }, {
69
+ repeatable: true;
70
+ description: string;
71
+ }>;
72
+ span: import("./registry.js").PartialFactory<"span", {
73
+ name: z.ZodString;
74
+ startedAt: z.ZodNumber;
75
+ endedAt: z.ZodNumber;
76
+ durationMs: z.ZodNumber;
77
+ }, {
78
+ repeatable: true;
79
+ description: string;
80
+ }>;
81
+ sloplog_usage_error: import("./registry.js").PartialFactory<"sloplog_usage_error", {
82
+ kind: z.ZodString;
83
+ message: z.ZodString;
84
+ partialType: z.ZodOptional<z.ZodString>;
85
+ spanName: z.ZodOptional<z.ZodString>;
86
+ startedAt: z.ZodOptional<z.ZodNumber>;
87
+ count: z.ZodOptional<z.ZodNumber>;
88
+ }, {
89
+ repeatable: true;
90
+ description: string;
91
+ }>;
92
+ };
93
+ /** Registry of built-in partial definitions. */
94
+ export declare const builtInRegistry: import("./registry.js").Registry<(import("./registry.js").PartialFactory<"error", {
95
+ message: z.ZodString;
96
+ stack: z.ZodOptional<z.ZodString>;
97
+ code: z.ZodOptional<z.ZodNumber>;
98
+ }, {
99
+ repeatable: true;
100
+ alwaysSample: true;
101
+ description: string;
102
+ }> | import("./registry.js").PartialFactory<"log_message", {
103
+ message: z.ZodString;
104
+ level: z.ZodEnum<{
105
+ error: "error";
106
+ trace: "trace";
107
+ debug: "debug";
108
+ info: "info";
109
+ warn: "warn";
110
+ fatal: "fatal";
111
+ }>;
112
+ data: z.ZodOptional<z.ZodString>;
113
+ }, {
114
+ repeatable: true;
115
+ description: string;
116
+ }> | import("./registry.js").PartialFactory<"span", {
117
+ name: z.ZodString;
118
+ startedAt: z.ZodNumber;
119
+ endedAt: z.ZodNumber;
120
+ durationMs: z.ZodNumber;
121
+ }, {
122
+ repeatable: true;
123
+ description: string;
124
+ }> | import("./registry.js").PartialFactory<"sloplog_usage_error", {
125
+ kind: z.ZodString;
126
+ message: z.ZodString;
127
+ partialType: z.ZodOptional<z.ZodString>;
128
+ spanName: z.ZodOptional<z.ZodString>;
129
+ startedAt: z.ZodOptional<z.ZodNumber>;
130
+ count: z.ZodOptional<z.ZodNumber>;
131
+ }, {
132
+ repeatable: true;
133
+ description: string;
134
+ }>)[]>;
135
+ /** Runtime metadata for built-in partials (repeatable, alwaysSample). */
136
+ export declare const builtInPartialMetadata: Map<string, import("./registry.js").PartialMetadata>;
137
+ /** Error partial payload type. */
138
+ export type ErrorPartial = InferPartial<typeof error>;
139
+ /** log_message partial payload type. */
140
+ export type LogMessagePartial = InferPartial<typeof logMessage>;
141
+ /** span partial payload type. */
142
+ export type SpanPartial = InferPartial<typeof span>;
143
+ /** sloplog_usage_error partial payload type. */
144
+ export type SloplogUsageErrorPartial = InferPartial<typeof sloplogUsageError>;
145
+ /** Built-in partial registry shape. */
146
+ export type BuiltInRegistry = {
147
+ error: ErrorPartial[];
148
+ log_message: LogMessagePartial[];
149
+ span: SpanPartial[];
150
+ sloplog_usage_error: SloplogUsageErrorPartial[];
151
+ };
152
+ /** Union of built-in partial names. */
153
+ export type BuiltInPartialName = keyof BuiltInRegistry;
154
+ export {};
@@ -0,0 +1,52 @@
1
+ import { extractPartialMetadata, partial, registry, z } from './registry.js';
2
+ const error = partial('error', {
3
+ message: z.string(),
4
+ stack: z.string().optional(),
5
+ code: z.number().optional(),
6
+ }, {
7
+ repeatable: true,
8
+ alwaysSample: true,
9
+ description: 'Error details captured during event processing.',
10
+ });
11
+ const logMessageLevel = z
12
+ .enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal'])
13
+ .describe('Log severity level for a log_message partial.');
14
+ const logMessage = partial('log_message', {
15
+ message: z.string().describe('Human-readable log message.'),
16
+ level: logMessageLevel,
17
+ data: z.string().optional().describe('Optional stringified payload for the log.'),
18
+ }, {
19
+ repeatable: true,
20
+ description: 'Lightweight log entry for ad-hoc logging. Prefer structured partials when possible.',
21
+ });
22
+ const span = partial('span', {
23
+ name: z.string().describe('Span name.'),
24
+ startedAt: z.number().describe('Span start time in milliseconds since epoch.'),
25
+ endedAt: z.number().describe('Span end time in milliseconds since epoch.'),
26
+ durationMs: z.number().describe('Span duration in milliseconds.'),
27
+ }, {
28
+ repeatable: true,
29
+ description: 'Timing span emitted by WideEvent span helpers.',
30
+ });
31
+ const sloplogUsageError = partial('sloplog_usage_error', {
32
+ kind: z.string().describe('Usage error category.'),
33
+ message: z.string().describe('Human-readable usage error message.'),
34
+ partialType: z.string().optional().describe('Partial type involved in the error.'),
35
+ spanName: z.string().optional().describe('Span name involved in the error.'),
36
+ startedAt: z.number().optional().describe('Span start time in ms when relevant.'),
37
+ count: z.number().optional().describe('Optional count related to the error.'),
38
+ }, {
39
+ repeatable: true,
40
+ description: 'Internal usage errors emitted by sloplog (e.g. partial overwrites or span misuse).',
41
+ });
42
+ /** Built-in partial definitions shipped with sloplog. */
43
+ export const builtInPartials = {
44
+ error,
45
+ log_message: logMessage,
46
+ span,
47
+ sloplog_usage_error: sloplogUsageError,
48
+ };
49
+ /** Registry of built-in partial definitions. */
50
+ export const builtInRegistry = registry([error, logMessage, span, sloplogUsageError]);
51
+ /** Runtime metadata for built-in partials (repeatable, alwaysSample). */
52
+ export const builtInPartialMetadata = extractPartialMetadata(builtInRegistry);
@@ -0,0 +1,89 @@
1
+ import { z, type ZodObject, type ZodRawShape } from 'zod';
2
+ export { z };
3
+ type AllowedZodPrimitive = z.ZodString | z.ZodNumber | z.ZodBoolean | z.ZodEnum<Record<string, string>>;
4
+ type AllowedZodType = AllowedZodPrimitive | z.ZodArray<AllowedZodPrimitive> | z.ZodOptional<AllowedZodPrimitive> | z.ZodOptional<z.ZodArray<AllowedZodPrimitive>>;
5
+ type AllowedShape = {
6
+ [key: string]: AllowedZodType;
7
+ };
8
+ /**
9
+ * Options for defining a partial
10
+ */
11
+ export interface PartialOptions {
12
+ /**
13
+ * If true, multiple instances of this partial can be attached to a single wide event.
14
+ * The partial will be stored as an array in the final log.
15
+ * @default false
16
+ */
17
+ repeatable?: boolean;
18
+ /**
19
+ * If true, adding this partial to an event will mark the event to always be sampled.
20
+ * Useful for error partials or other critical events that should never be dropped.
21
+ * @default false
22
+ */
23
+ alwaysSample?: boolean;
24
+ /**
25
+ * Optional description used for generated docs and schemas.
26
+ */
27
+ description?: string;
28
+ }
29
+ export interface PartialDefinition<T extends string, S extends ZodRawShape, O extends PartialOptions = PartialOptions> {
30
+ /** Partial type discriminator */
31
+ name: T;
32
+ /** Zod schema for the partial payload */
33
+ schema: ZodObject<S>;
34
+ /** Repeatable and sampling behavior */
35
+ options: O;
36
+ }
37
+ export interface Registry<T extends PartialDefinition<string, ZodRawShape, PartialOptions>[]> {
38
+ /** List of partial definitions that make up this registry */
39
+ partials: T;
40
+ }
41
+ /**
42
+ * Runtime metadata about partials, extracted from the registry for use by WideEvent
43
+ */
44
+ export interface PartialMetadata {
45
+ /** Whether this partial may appear multiple times */
46
+ repeatable: boolean;
47
+ /** Whether this partial forces alwaysSample for the event */
48
+ alwaysSample: boolean;
49
+ }
50
+ /**
51
+ * Callable partial definition that creates a partial payload from input data.
52
+ */
53
+ export type PartialFactory<T extends string, S extends ZodRawShape, O extends PartialOptions = PartialOptions> = PartialDefinition<T, S, O> & {
54
+ (data: z.input<ZodObject<S>>): z.infer<ZodObject<S>> & {
55
+ type: T;
56
+ };
57
+ };
58
+ /**
59
+ * Define a partial with a name and Zod schema
60
+ * Only allows: z.string(), z.number(), z.boolean(), and their arrays/optionals
61
+ *
62
+ * @param name - The unique name/type discriminator for this partial
63
+ * @param schema - Zod schema defining the partial's fields
64
+ * @param options - Optional configuration for repeatable and alwaysSample behavior
65
+ */
66
+ export declare function partial<T extends string, S extends AllowedShape, O extends PartialOptions = PartialOptions>(name: T, schema: S, options?: O): PartialFactory<T, S, O>;
67
+ /**
68
+ * Create a registry of partials
69
+ */
70
+ export declare function registry<T extends PartialDefinition<string, ZodRawShape, PartialOptions>[]>(partials: T): Registry<T>;
71
+ /**
72
+ * Extract runtime metadata from a registry for use by WideEvent
73
+ */
74
+ export declare function extractPartialMetadata(reg: Registry<PartialDefinition<string, ZodRawShape, PartialOptions>[]>): Map<string, PartialMetadata>;
75
+ /**
76
+ * Infer the TypeScript type from a partial definition
77
+ */
78
+ export type InferPartial<T extends PartialDefinition<string, ZodRawShape>> = z.infer<T['schema']> & {
79
+ type: T['name'];
80
+ };
81
+ type PartialValueFor<P extends PartialDefinition<string, ZodRawShape, PartialOptions>> = P['options'] extends {
82
+ repeatable: true;
83
+ } ? InferPartial<P>[] : InferPartial<P>;
84
+ /**
85
+ * Infer the registry log shape from a registry definition.
86
+ */
87
+ export type RegistryType<T extends Registry<PartialDefinition<string, ZodRawShape, PartialOptions>[]>> = {
88
+ [P in T['partials'][number] as P['name']]: PartialValueFor<P>;
89
+ };
@@ -0,0 +1,44 @@
1
+ import { z } from 'zod';
2
+ // Re-export z for schema definitions
3
+ export { z };
4
+ /**
5
+ * Define a partial with a name and Zod schema
6
+ * Only allows: z.string(), z.number(), z.boolean(), and their arrays/optionals
7
+ *
8
+ * @param name - The unique name/type discriminator for this partial
9
+ * @param schema - Zod schema defining the partial's fields
10
+ * @param options - Optional configuration for repeatable and alwaysSample behavior
11
+ */
12
+ export function partial(name, schema, options = {}) {
13
+ const objectSchema = z.object(schema);
14
+ const describedSchema = options.description
15
+ ? objectSchema.describe(options.description)
16
+ : objectSchema;
17
+ const factory = ((data) => {
18
+ const parsed = describedSchema.parse(data);
19
+ return { type: name, ...parsed };
20
+ });
21
+ Object.defineProperty(factory, 'name', { value: name, configurable: true });
22
+ factory.schema = describedSchema;
23
+ factory.options = options;
24
+ return factory;
25
+ }
26
+ /**
27
+ * Create a registry of partials
28
+ */
29
+ export function registry(partials) {
30
+ return { partials };
31
+ }
32
+ /**
33
+ * Extract runtime metadata from a registry for use by WideEvent
34
+ */
35
+ export function extractPartialMetadata(reg) {
36
+ const metadata = new Map();
37
+ for (const partial of reg.partials) {
38
+ metadata.set(partial.name, {
39
+ repeatable: partial.options.repeatable ?? false,
40
+ alwaysSample: partial.options.alwaysSample ?? false,
41
+ });
42
+ }
43
+ return metadata;
44
+ }
Binary file
Binary file
Binary file
Binary file
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "sloplog",
3
+ "version": "0.0.3",
4
+ "description": "A TypeScript library for constructing wide events",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./codegen": {
14
+ "import": "./dist/codegen.js",
15
+ "types": "./dist/codegen.d.ts"
16
+ },
17
+ "./partials": {
18
+ "import": "./dist/partials.js",
19
+ "types": "./dist/partials.d.ts"
20
+ },
21
+ "./collectors/stdio": {
22
+ "import": "./dist/collectors/stdio.js",
23
+ "types": "./dist/collectors/stdio.d.ts"
24
+ },
25
+ "./collectors/composite": {
26
+ "import": "./dist/collectors/composite.js",
27
+ "types": "./dist/collectors/composite.d.ts"
28
+ },
29
+ "./collectors/filtered": {
30
+ "import": "./dist/collectors/filtered.js",
31
+ "types": "./dist/collectors/filtered.d.ts"
32
+ },
33
+ "./collectors/file": {
34
+ "import": "./dist/collectors/file.js",
35
+ "types": "./dist/collectors/file.d.ts"
36
+ },
37
+ "./collectors/betterstack": {
38
+ "import": "./dist/collectors/betterstack.js",
39
+ "types": "./dist/collectors/betterstack.d.ts"
40
+ },
41
+ "./collectors/sentry": {
42
+ "import": "./dist/collectors/sentry.js",
43
+ "types": "./dist/collectors/sentry.d.ts"
44
+ }
45
+ },
46
+ "files": [
47
+ "dist"
48
+ ],
49
+ "scripts": {
50
+ "build": "tsc",
51
+ "test": "vitest run",
52
+ "test:watch": "vitest",
53
+ "lint": "eslint .",
54
+ "lint:fix": "eslint . --fix",
55
+ "format": "prettier --write '**/*.{ts,js,json,md}'",
56
+ "format:check": "prettier --check '**/*.{ts,js,json,md}'",
57
+ "typecheck": "tsc --noEmit",
58
+ "check": "npm run lint && npm run format:check && npm run typecheck",
59
+ "prepublishOnly": "npm run check && npm run build && npm test"
60
+ },
61
+ "keywords": [
62
+ "wide-events",
63
+ "logging",
64
+ "observability",
65
+ "tracing",
66
+ "structured-logging"
67
+ ],
68
+ "author": "",
69
+ "license": "MIT",
70
+ "repository": {
71
+ "type": "git",
72
+ "url": "https://github.com/cmsparks/sloplog.git"
73
+ },
74
+ "homepage": "https://github.com/cmsparks/sloplog#readme",
75
+ "bugs": {
76
+ "url": "https://github.com/cmsparks/sloplog/issues"
77
+ },
78
+ "devDependencies": {
79
+ "@eslint/js": "^9.39.2",
80
+ "@types/node": "^25.0.9",
81
+ "eslint": "^9.39.2",
82
+ "eslint-config-prettier": "^10.1.8",
83
+ "eslint-plugin-prettier": "^5.5.5",
84
+ "prettier": "^3.8.0",
85
+ "pyright": "^1.1.408",
86
+ "typescript": "^5.7.0",
87
+ "typescript-eslint": "^8.53.1",
88
+ "vitest": "^2.1.0"
89
+ },
90
+ "dependencies": {
91
+ "zod": "^4.3.5"
92
+ },
93
+ "peerDependencies": {
94
+ "@sentry/node": "*"
95
+ },
96
+ "peerDependenciesMeta": {
97
+ "@sentry/node": {
98
+ "optional": true
99
+ }
100
+ }
101
+ }