vestig 0.2.0 → 0.3.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.
- package/README.md +321 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +19 -6
- package/dist/context/index.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +27 -7
- package/dist/runtime.js.map +1 -1
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 👣 Vestig
|
|
4
|
+
|
|
5
|
+
**Leave a trace.**
|
|
6
|
+
|
|
7
|
+
A modern, runtime-agnostic structured logging library with automatic PII sanitization and context propagation.
|
|
8
|
+
|
|
9
|
+
[](https://github.com/Arakiss/vestig/actions/workflows/ci.yml)
|
|
10
|
+
[](https://www.npmjs.com/package/vestig)
|
|
11
|
+
[](https://github.com/Arakiss/vestig)
|
|
12
|
+
[](https://github.com/Arakiss/vestig)
|
|
13
|
+
[](https://opensource.org/licenses/MIT)
|
|
14
|
+
[](https://www.typescriptlang.org/)
|
|
15
|
+
[](https://github.com/Arakiss/vestig/blob/main/CONTRIBUTING.md)
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Why Vestig?
|
|
22
|
+
|
|
23
|
+
*Vestig* — from Latin *vestigium* (trace, footprint). Leave a trace of what happened.
|
|
24
|
+
|
|
25
|
+
| Feature | Vestig | Pino | Winston |
|
|
26
|
+
|---------|:-----:|:----:|:-------:|
|
|
27
|
+
| Runtime Agnostic | ✅ | ❌ | ❌ |
|
|
28
|
+
| Auto PII Sanitization | ✅ | ❌ | ❌ |
|
|
29
|
+
| GDPR/HIPAA/PCI-DSS Presets | ✅ | ❌ | ❌ |
|
|
30
|
+
| Zero Config | ✅ | ✅ | ❌ |
|
|
31
|
+
| TypeScript First | ✅ | ✅ | ⚠️ |
|
|
32
|
+
| Edge Runtime Support | ✅ | ❌ | ❌ |
|
|
33
|
+
| Browser Support | ✅ | ❌ | ⚠️ |
|
|
34
|
+
| Context Propagation | ✅ | ❌ | ❌ |
|
|
35
|
+
| Multiple Transports | ✅ | ✅ | ✅ |
|
|
36
|
+
| Zero Dependencies | ✅ | ❌ | ❌ |
|
|
37
|
+
|
|
38
|
+
**Vestig is the only logging library that:**
|
|
39
|
+
- Works everywhere (Node.js, Bun, Deno, Edge, Browser)
|
|
40
|
+
- Automatically sanitizes PII with compliance presets
|
|
41
|
+
- Propagates context through async operations
|
|
42
|
+
- Has zero runtime dependencies
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# bun
|
|
48
|
+
bun add vestig
|
|
49
|
+
|
|
50
|
+
# npm
|
|
51
|
+
npm install vestig
|
|
52
|
+
|
|
53
|
+
# pnpm
|
|
54
|
+
pnpm add vestig
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { log } from 'vestig'
|
|
61
|
+
|
|
62
|
+
// Simple logging
|
|
63
|
+
log.info('Hello world')
|
|
64
|
+
log.error('Something failed', { userId: 123 })
|
|
65
|
+
|
|
66
|
+
// Sensitive data is automatically redacted
|
|
67
|
+
log.info('User login', {
|
|
68
|
+
email: 'user@example.com', // → us***@example.com
|
|
69
|
+
password: 'secret123', // → [REDACTED]
|
|
70
|
+
creditCard: '4111111111111111', // → ****1111
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Features
|
|
75
|
+
|
|
76
|
+
### Multi-Transport Support
|
|
77
|
+
|
|
78
|
+
Send logs to multiple destinations simultaneously:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { createLogger, ConsoleTransport, HTTPTransport, DatadogTransport } from 'vestig'
|
|
82
|
+
|
|
83
|
+
const log = createLogger()
|
|
84
|
+
|
|
85
|
+
// Add HTTP transport for centralized logging
|
|
86
|
+
log.addTransport(new HTTPTransport({
|
|
87
|
+
name: 'api-logs',
|
|
88
|
+
url: 'https://logs.example.com/ingest',
|
|
89
|
+
headers: { 'Authorization': 'Bearer token' },
|
|
90
|
+
}))
|
|
91
|
+
|
|
92
|
+
// Add Datadog for observability
|
|
93
|
+
log.addTransport(new DatadogTransport({
|
|
94
|
+
name: 'datadog',
|
|
95
|
+
apiKey: process.env.DD_API_KEY,
|
|
96
|
+
service: 'my-app',
|
|
97
|
+
tags: ['env:production'],
|
|
98
|
+
}))
|
|
99
|
+
|
|
100
|
+
// Initialize transports (starts flush timers)
|
|
101
|
+
await log.init()
|
|
102
|
+
|
|
103
|
+
// All logs go to console, HTTP endpoint, and Datadog
|
|
104
|
+
log.info('Server started', { port: 3000 })
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Available Transports
|
|
108
|
+
|
|
109
|
+
| Transport | Description | Use Case |
|
|
110
|
+
|-----------|-------------|----------|
|
|
111
|
+
| `ConsoleTransport` | Console output with colors | Development, debugging |
|
|
112
|
+
| `HTTPTransport` | Send to any HTTP endpoint | Custom log aggregation |
|
|
113
|
+
| `FileTransport` | Write to files with rotation | Server-side logging |
|
|
114
|
+
| `DatadogTransport` | Datadog Log Management | Production observability |
|
|
115
|
+
|
|
116
|
+
### PII Sanitization with Presets
|
|
117
|
+
|
|
118
|
+
Choose from compliance-focused presets:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { Sanitizer } from 'vestig'
|
|
122
|
+
|
|
123
|
+
// GDPR compliance (EU data protection)
|
|
124
|
+
const gdprSanitizer = Sanitizer.fromPreset('gdpr')
|
|
125
|
+
|
|
126
|
+
// HIPAA compliance (healthcare)
|
|
127
|
+
const hipaaSanitizer = Sanitizer.fromPreset('hipaa')
|
|
128
|
+
|
|
129
|
+
// PCI-DSS compliance (payment cards)
|
|
130
|
+
const pciSanitizer = Sanitizer.fromPreset('pci-dss')
|
|
131
|
+
|
|
132
|
+
// Apply to logger
|
|
133
|
+
const log = createLogger({
|
|
134
|
+
sanitize: 'gdpr', // Use preset name directly
|
|
135
|
+
})
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
| Preset | Fields Protected | Patterns Applied |
|
|
139
|
+
|--------|-----------------|------------------|
|
|
140
|
+
| `none` | None | None |
|
|
141
|
+
| `minimal` | password, secret, token, key | None |
|
|
142
|
+
| `default` | 26 common fields | Email, Credit Card, JWT |
|
|
143
|
+
| `gdpr` | + name, address, phone, IP | + IP addresses, phone |
|
|
144
|
+
| `hipaa` | + patient, medical, SSN | + SSN pattern |
|
|
145
|
+
| `pci-dss` | + card, CVV, PIN | Full card detection |
|
|
146
|
+
|
|
147
|
+
### Custom Sanitization
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { Sanitizer } from 'vestig'
|
|
151
|
+
|
|
152
|
+
const sanitizer = new Sanitizer({
|
|
153
|
+
fields: [
|
|
154
|
+
'customSecret',
|
|
155
|
+
{ type: 'prefix', value: 'private_' },
|
|
156
|
+
{ type: 'contains', value: 'token' },
|
|
157
|
+
],
|
|
158
|
+
patterns: [{
|
|
159
|
+
name: 'internal-id',
|
|
160
|
+
pattern: /ID-[A-Z0-9]+/g,
|
|
161
|
+
replacement: '[ID_REDACTED]',
|
|
162
|
+
}],
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
const safe = sanitizer.sanitize({
|
|
166
|
+
private_key: 'abc123', // → [REDACTED]
|
|
167
|
+
auth_token: 'xyz789', // → [REDACTED]
|
|
168
|
+
internalId: 'ID-ABC123', // → [ID_REDACTED]
|
|
169
|
+
})
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Child Loggers
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const log = createLogger({ namespace: 'app' })
|
|
176
|
+
const dbLog = log.child('database')
|
|
177
|
+
const cacheLog = log.child('cache')
|
|
178
|
+
|
|
179
|
+
dbLog.info('Query executed') // [app:database] Query executed
|
|
180
|
+
cacheLog.info('Cache hit') // [app:cache] Cache hit
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Context & Correlation IDs
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { withContext, createCorrelationContext } from 'vestig'
|
|
187
|
+
|
|
188
|
+
// Next.js API Route
|
|
189
|
+
export async function GET(req: Request) {
|
|
190
|
+
const context = createCorrelationContext({
|
|
191
|
+
requestId: req.headers.get('x-request-id') ?? undefined
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
return withContext(context, async () => {
|
|
195
|
+
log.info('Request started')
|
|
196
|
+
// All logs include: requestId, traceId, spanId
|
|
197
|
+
|
|
198
|
+
const result = await fetchData()
|
|
199
|
+
log.info('Request completed')
|
|
200
|
+
|
|
201
|
+
return Response.json(result)
|
|
202
|
+
})
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Configuration
|
|
207
|
+
|
|
208
|
+
### Environment Variables
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
VESTIG_LEVEL=debug # trace | debug | info | warn | error
|
|
212
|
+
VESTIG_ENABLED=true # Enable/disable logging
|
|
213
|
+
VESTIG_STRUCTURED=true # JSON output (auto-enabled in production)
|
|
214
|
+
VESTIG_SANITIZE=true # PII sanitization (default: true)
|
|
215
|
+
|
|
216
|
+
# Add to context
|
|
217
|
+
VESTIG_CONTEXT_SERVICE=api
|
|
218
|
+
VESTIG_CONTEXT_VERSION=1.0.0
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Programmatic
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
const log = createLogger({
|
|
225
|
+
level: 'debug',
|
|
226
|
+
enabled: true,
|
|
227
|
+
structured: false,
|
|
228
|
+
sanitize: 'gdpr', // or true, false, or SanitizeConfig
|
|
229
|
+
context: { environment: 'development' }
|
|
230
|
+
})
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Log Levels
|
|
234
|
+
|
|
235
|
+
| Level | Description |
|
|
236
|
+
|-------|-------------|
|
|
237
|
+
| `trace` | Very detailed debugging information |
|
|
238
|
+
| `debug` | Development debugging |
|
|
239
|
+
| `info` | General information |
|
|
240
|
+
| `warn` | Warning messages |
|
|
241
|
+
| `error` | Error messages (includes stack traces) |
|
|
242
|
+
|
|
243
|
+
## Runtime Detection
|
|
244
|
+
|
|
245
|
+
Vestig automatically detects and adapts to:
|
|
246
|
+
|
|
247
|
+
- **Node.js** - Full features with AsyncLocalStorage
|
|
248
|
+
- **Bun** - Full features with AsyncLocalStorage
|
|
249
|
+
- **Deno** - Full features with AsyncLocalStorage
|
|
250
|
+
- **Edge Runtime** - Vercel Edge, Cloudflare Workers
|
|
251
|
+
- **Browser** - Client-side logging with sanitization
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
import { RUNTIME, IS_SERVER, IS_EDGE } from 'vestig'
|
|
255
|
+
|
|
256
|
+
console.log(RUNTIME) // 'node' | 'bun' | 'deno' | 'edge' | 'browser'
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Auto-Production Mode
|
|
260
|
+
|
|
261
|
+
In production (`NODE_ENV=production`), Vestig automatically:
|
|
262
|
+
|
|
263
|
+
- Sets log level to `warn`
|
|
264
|
+
- Enables structured (JSON) output
|
|
265
|
+
- Keeps sanitization enabled
|
|
266
|
+
|
|
267
|
+
## API Reference
|
|
268
|
+
|
|
269
|
+
### `createLogger(config?)`
|
|
270
|
+
|
|
271
|
+
Create a new logger instance.
|
|
272
|
+
|
|
273
|
+
### `log.trace/debug/info/warn/error(message, metadata?)`
|
|
274
|
+
|
|
275
|
+
Log at the specified level.
|
|
276
|
+
|
|
277
|
+
### `log.child(namespace, config?)`
|
|
278
|
+
|
|
279
|
+
Create a namespaced child logger.
|
|
280
|
+
|
|
281
|
+
### `log.addTransport(transport)`
|
|
282
|
+
|
|
283
|
+
Add a transport to the logger.
|
|
284
|
+
|
|
285
|
+
### `log.removeTransport(name)`
|
|
286
|
+
|
|
287
|
+
Remove a transport by name.
|
|
288
|
+
|
|
289
|
+
### `log.flush()`
|
|
290
|
+
|
|
291
|
+
Flush all buffered logs.
|
|
292
|
+
|
|
293
|
+
### `log.destroy()`
|
|
294
|
+
|
|
295
|
+
Cleanup all transports (call on shutdown).
|
|
296
|
+
|
|
297
|
+
### `withContext(context, fn)`
|
|
298
|
+
|
|
299
|
+
Run a function with the given context.
|
|
300
|
+
|
|
301
|
+
### `createCorrelationContext(existing?)`
|
|
302
|
+
|
|
303
|
+
Generate correlation IDs (requestId, traceId, spanId).
|
|
304
|
+
|
|
305
|
+
### `Sanitizer.fromPreset(preset)`
|
|
306
|
+
|
|
307
|
+
Create a sanitizer from a preset name.
|
|
308
|
+
|
|
309
|
+
## Contributing
|
|
310
|
+
|
|
311
|
+
We love contributions! Please read our [Contributing Guide](https://github.com/Arakiss/vestig/blob/main/CONTRIBUTING.md) to get started.
|
|
312
|
+
|
|
313
|
+
- 🐛 [Report bugs](https://github.com/Arakiss/vestig/issues/new?template=bug_report.md)
|
|
314
|
+
- 💡 [Request features](https://github.com/Arakiss/vestig/issues/new?template=feature_request.md)
|
|
315
|
+
- 📖 [Improve documentation](https://github.com/Arakiss/vestig/pulls)
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
MIT © [Arakiss](https://github.com/Arakiss)
|
|
320
|
+
|
|
321
|
+
See [LICENSE](https://github.com/Arakiss/vestig/blob/main/LICENSE) for more details.
|
package/dist/context/index.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export declare function withContext<T>(context: LogContext, fn: () => T): T;
|
|
|
15
15
|
export declare function withContextAsync<T>(context: LogContext, fn: () => Promise<T>): Promise<T>;
|
|
16
16
|
/**
|
|
17
17
|
* Create a new context with correlation IDs
|
|
18
|
+
*
|
|
19
|
+
* Note: We explicitly generate IDs for undefined values and don't spread
|
|
20
|
+
* the original object to avoid overwriting generated values with undefined.
|
|
18
21
|
*/
|
|
19
22
|
export declare function createCorrelationContext(existing?: Partial<LogContext>): LogContext;
|
|
20
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAsHnE;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,GAAG,SAAS,CAEnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAElE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEzF;AAED
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAG1C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAClF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAsHnE;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,GAAG,SAAS,CAEnD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAElE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAEzF;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAmBnF"}
|
package/dist/context/index.js
CHANGED
|
@@ -110,13 +110,26 @@ export function withContextAsync(context, fn) {
|
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* Create a new context with correlation IDs
|
|
113
|
+
*
|
|
114
|
+
* Note: We explicitly generate IDs for undefined values and don't spread
|
|
115
|
+
* the original object to avoid overwriting generated values with undefined.
|
|
113
116
|
*/
|
|
114
117
|
export function createCorrelationContext(existing) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
};
|
|
118
|
+
// Extract known correlation fields, generating if not provided
|
|
119
|
+
const requestId = existing?.requestId ?? generateRequestId();
|
|
120
|
+
const traceId = existing?.traceId ?? generateTraceId();
|
|
121
|
+
const spanId = existing?.spanId ?? generateSpanId();
|
|
122
|
+
// Build context with only defined extra properties
|
|
123
|
+
const context = { requestId, traceId, spanId };
|
|
124
|
+
// Add any extra properties from existing, but filter out undefined values
|
|
125
|
+
if (existing) {
|
|
126
|
+
for (const [key, value] of Object.entries(existing)) {
|
|
127
|
+
if (value !== undefined && !(key in context)) {
|
|
128
|
+
;
|
|
129
|
+
context[key] = value;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return context;
|
|
121
134
|
}
|
|
122
135
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/context/index.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,EAAE,OAAO,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;CAClB;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AAEtC;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,UAAU,EAAE,OAAO,CAAA;IACnB,cAAc,EAAE,OAAO,CAAA;IACvB,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;CAClB;AAsFD;;GAEG;AACH,eAAO,MAAM,OAAO,EAAE,OAAyB,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,mBAA0C,CAAA;AAErE;;GAEG;AACH,eAAO,MAAM,OAAO,SAAqB,CAAA;AACzC,eAAO,MAAM,MAAM,SAAoB,CAAA;AACvC,eAAO,MAAM,OAAO,SAAqB,CAAA;AACzC,eAAO,MAAM,UAAU,SAAwB,CAAA;AAC/C,eAAO,MAAM,SAAS,SAAuB,CAAA;AAC7C,eAAO,MAAM,SAAS,SAA+B,CAAA"}
|
package/dist/runtime.js
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe check for Node.js version (Edge-compatible)
|
|
3
|
+
*/
|
|
4
|
+
function hasNodeVersion() {
|
|
5
|
+
try {
|
|
6
|
+
// Use dynamic access to avoid static analysis
|
|
7
|
+
const p = globalThis.process;
|
|
8
|
+
return Boolean(p?.versions?.node);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
1
14
|
/**
|
|
2
15
|
* Detect the current runtime environment
|
|
3
16
|
*/
|
|
@@ -12,21 +25,27 @@ function detectRuntime() {
|
|
|
12
25
|
if ('EdgeRuntime' in globalThis) {
|
|
13
26
|
return 'edge';
|
|
14
27
|
}
|
|
15
|
-
// Next.js Edge
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
// Next.js Edge - check environment variable safely
|
|
29
|
+
try {
|
|
30
|
+
const p = globalThis.process;
|
|
31
|
+
if (p?.env?.NEXT_RUNTIME === 'edge') {
|
|
32
|
+
return 'edge';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// process not available, continue checking
|
|
18
37
|
}
|
|
19
38
|
// Cloudflare Workers (has caches but no window/process.versions)
|
|
20
39
|
if ('caches' in globalThis &&
|
|
21
40
|
typeof globalThis.Request === 'function' &&
|
|
22
41
|
typeof globalThis.Response === 'function' &&
|
|
23
42
|
typeof window === 'undefined' &&
|
|
24
|
-
(
|
|
43
|
+
!hasNodeVersion()) {
|
|
25
44
|
return 'edge';
|
|
26
45
|
}
|
|
27
46
|
}
|
|
28
47
|
// Node.js detection
|
|
29
|
-
if (
|
|
48
|
+
if (hasNodeVersion() && typeof window === 'undefined') {
|
|
30
49
|
return 'node';
|
|
31
50
|
}
|
|
32
51
|
// Browser detection
|
|
@@ -44,9 +63,10 @@ function detectRuntime() {
|
|
|
44
63
|
* Detect runtime capabilities
|
|
45
64
|
*/
|
|
46
65
|
function detectCapabilities() {
|
|
66
|
+
const hasProc = typeof globalThis.process !== 'undefined';
|
|
47
67
|
return {
|
|
48
|
-
hasAsyncLocalStorage:
|
|
49
|
-
hasProcess:
|
|
68
|
+
hasAsyncLocalStorage: hasProc && (RUNTIME === 'node' || RUNTIME === 'bun'),
|
|
69
|
+
hasProcess: hasProc,
|
|
50
70
|
hasPerformance: typeof performance !== 'undefined',
|
|
51
71
|
hasConsole: typeof console !== 'undefined',
|
|
52
72
|
hasCrypto: typeof crypto !== 'undefined',
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,SAAS,aAAa;IACrB,mCAAmC;IACnC,IAAI,OAAO,UAAU,KAAK,WAAW,IAAI,KAAK,IAAI,UAAU,EAAE,CAAC;QAC9D,OAAO,KAAK,CAAA;IACb,CAAC;IAED,yBAAyB;IACzB,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE,CAAC;QACvC,sBAAsB;QACtB,IAAI,aAAa,IAAI,UAAU,EAAE,CAAC;YACjC,OAAO,MAAM,CAAA;QACd,CAAC;QACD,
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vestig",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Leave a trace. A modern, runtime-agnostic structured logging library with automatic PII sanitization and context propagation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,13 +56,13 @@
|
|
|
56
56
|
"license": "MIT",
|
|
57
57
|
"repository": {
|
|
58
58
|
"type": "git",
|
|
59
|
-
"url": "git+https://github.com/Arakiss/
|
|
59
|
+
"url": "git+https://github.com/Arakiss/vestig.git",
|
|
60
60
|
"directory": "packages/vestig"
|
|
61
61
|
},
|
|
62
62
|
"bugs": {
|
|
63
|
-
"url": "https://github.com/Arakiss/
|
|
63
|
+
"url": "https://github.com/Arakiss/vestig/issues"
|
|
64
64
|
},
|
|
65
|
-
"homepage": "https://github.com/Arakiss/
|
|
65
|
+
"homepage": "https://github.com/Arakiss/vestig#readme",
|
|
66
66
|
"devDependencies": {
|
|
67
67
|
"typescript": "catalog:",
|
|
68
68
|
"@types/node": "catalog:"
|