@observa/sdk 2.4.0 → 2.4.5
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 +140 -176
- package/dist/apis/ingestApi.d.ts +1 -15
- package/dist/apis/ingestApi.d.ts.map +1 -1
- package/dist/apis/ingestApi.js +2 -151
- package/dist/apis/ingestApi.js.map +1 -1
- package/dist/apis/uptimeApi.js +1 -1
- package/dist/apis/uptimeApi.js.map +1 -1
- package/dist/domain/ingest.d.ts +4 -33
- package/dist/domain/ingest.d.ts.map +1 -1
- package/dist/http/httpClient.d.ts +5 -2
- package/dist/http/httpClient.d.ts.map +1 -1
- package/dist/http/httpClient.js +44 -8
- package/dist/http/httpClient.js.map +1 -1
- package/dist/index.d.ts +18 -507
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -582
- package/dist/index.js.map +1 -1
- package/dist/sdk.d.ts +4 -9
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +7 -19
- package/dist/sdk.js.map +1 -1
- package/package.json +9 -16
- package/dist/src/apis/ingestApi.d.ts +0 -22
- package/dist/src/apis/ingestApi.js +0 -167
- package/dist/src/apis/ingestApi.js.map +0 -1
- package/dist/src/apis/uptimeApi.d.ts +0 -11
- package/dist/src/apis/uptimeApi.js +0 -39
- package/dist/src/apis/uptimeApi.js.map +0 -1
- package/dist/src/domain/ingest.d.ts +0 -47
- package/dist/src/domain/ingest.js +0 -2
- package/dist/src/domain/ingest.js.map +0 -1
- package/dist/src/domain/uptime.d.ts +0 -23
- package/dist/src/domain/uptime.js +0 -2
- package/dist/src/domain/uptime.js.map +0 -1
- package/dist/src/http/errors.d.ts +0 -33
- package/dist/src/http/errors.js +0 -54
- package/dist/src/http/errors.js.map +0 -1
- package/dist/src/http/httpClient.d.ts +0 -45
- package/dist/src/http/httpClient.js +0 -165
- package/dist/src/http/httpClient.js.map +0 -1
- package/dist/src/index.d.ts +0 -12
- package/dist/src/index.js +0 -7
- package/dist/src/index.js.map +0 -1
- package/dist/src/sdk.d.ts +0 -23
- package/dist/src/sdk.js +0 -40
- package/dist/src/sdk.js.map +0 -1
- package/dist/src/utils/processContext.d.ts +0 -34
- package/dist/src/utils/processContext.js +0 -47
- package/dist/src/utils/processContext.js.map +0 -1
- package/dist/src/utils/validate.d.ts +0 -2
- package/dist/src/utils/validate.js +0 -12
- package/dist/src/utils/validate.js.map +0 -1
- package/dist/tests/httpClient.test.d.ts +0 -1
- package/dist/tests/httpClient.test.js +0 -47
- package/dist/tests/httpClient.test.js.map +0 -1
- package/dist/tests/ingestApi.test.d.ts +0 -1
- package/dist/tests/ingestApi.test.js +0 -65
- package/dist/tests/ingestApi.test.js.map +0 -1
- package/dist/tests/observaSdk.integration.test.d.ts +0 -1
- package/dist/tests/observaSdk.integration.test.js +0 -51
- package/dist/tests/observaSdk.integration.test.js.map +0 -1
- package/dist/tests/sdk.test.d.ts +0 -1
- package/dist/tests/sdk.test.js +0 -104
- package/dist/tests/sdk.test.js.map +0 -1
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/dist/utils/processContext.d.ts +0 -35
- package/dist/utils/processContext.d.ts.map +0 -1
- package/dist/utils/processContext.js +0 -47
- package/dist/utils/processContext.js.map +0 -1
- package/src/apis/ingestApi.ts +0 -199
- package/src/apis/uptimeApi.ts +0 -58
- package/src/domain/ingest.ts +0 -93
- package/src/domain/uptime.ts +0 -86
- package/src/http/errors.ts +0 -88
- package/src/http/httpClient.ts +0 -284
- package/src/index.ts +0 -68
- package/src/sdk.ts +0 -107
- package/src/utils/processContext.ts +0 -84
- package/src/utils/validate.ts +0 -19
package/README.md
CHANGED
|
@@ -1,176 +1,140 @@
|
|
|
1
|
-
# Observa SDK for Node.js
|
|
2
|
-
|
|
3
|
-
Official SDK for sending ingest events and uptime heartbeats to Observa.
|
|
4
|
-
|
|
5
|
-
## Who is this for?
|
|
6
|
-
|
|
7
|
-
This SDK
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **dsnKey**: Project-level identifier used to route events and heartbeats.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
- `
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
##
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
sdk.setApiKey('new_api_key')
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Error Handling
|
|
147
|
-
|
|
148
|
-
The SDK throws typed errors you can catch explicitly:
|
|
149
|
-
|
|
150
|
-
```ts
|
|
151
|
-
import { RateLimitError, AuthError } from '@observa/sdk'
|
|
152
|
-
|
|
153
|
-
try {
|
|
154
|
-
await sdk.ingest.event({ event: { level: 'error', message: 'boom' } })
|
|
155
|
-
} catch (error) {
|
|
156
|
-
if (error instanceof RateLimitError) {
|
|
157
|
-
console.log('Retry after seconds:', error.retryAfter)
|
|
158
|
-
}
|
|
159
|
-
if (error instanceof AuthError) {
|
|
160
|
-
console.log('Authentication failed')
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Requirements
|
|
166
|
-
|
|
167
|
-
- Node.js >= 18
|
|
168
|
-
|
|
169
|
-
## License
|
|
170
|
-
|
|
171
|
-
MIT
|
|
172
|
-
|
|
173
|
-
## Links
|
|
174
|
-
|
|
175
|
-
- Documentation: ...
|
|
176
|
-
- GitHub: https://github.com/ObservaSolutions/sdk-observa
|
|
1
|
+
# Observa SDK for Node.js
|
|
2
|
+
|
|
3
|
+
Official SDK for sending ingest events and uptime heartbeats to Observa.
|
|
4
|
+
|
|
5
|
+
## Who is this for?
|
|
6
|
+
|
|
7
|
+
This SDK supports both server-side and browser usage:
|
|
8
|
+
|
|
9
|
+
- **Server-side** (Node.js workers, backend services): initialize with `apiKey` + `dsnKey` for full privileged access.
|
|
10
|
+
- **Browser / frontend**: initialize with `dsnKey` only — your org-level `apiKey` stays on the server.
|
|
11
|
+
|
|
12
|
+
## SDK Contract
|
|
13
|
+
|
|
14
|
+
This SDK is an official client for the Observa backend.
|
|
15
|
+
It targets a fixed API and does not support custom base URLs.
|
|
16
|
+
|
|
17
|
+
## Concepts
|
|
18
|
+
|
|
19
|
+
- **dsnKey**: Project-level identifier used to route events and heartbeats. Required for all write operations.
|
|
20
|
+
- **apiKey**: Organization-level credential for privileged server-side access. Optional — omit it for browser/public usage.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install @observa/sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
### Browser / Frontend (DSN-only)
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { ObservaSDK } from '@observa/sdk'
|
|
34
|
+
|
|
35
|
+
const sdk = new ObservaSDK({ dsnKey: 'dsn_your_key' })
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The DSN is a project-scoped key safe to use in browser environments.
|
|
39
|
+
|
|
40
|
+
### Server-side (apiKey + dsnKey)
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { ObservaSDK } from '@observa/sdk'
|
|
44
|
+
|
|
45
|
+
const sdk = new ObservaSDK({
|
|
46
|
+
apiKey: 'org_api_key',
|
|
47
|
+
dsnKey: 'project_dsn',
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Use the `apiKey` in privileged server-side contexts (workers, backend services). Never expose your `apiKey` to the browser.
|
|
52
|
+
|
|
53
|
+
The SDK triggers a startup health check (`/health`) as a best-effort diagnostic.
|
|
54
|
+
This check is non-blocking: if it fails, normal SDK API calls still run with their regular timeout/retry/error behavior.
|
|
55
|
+
|
|
56
|
+
## Defaults
|
|
57
|
+
|
|
58
|
+
- Timeout: 5 seconds
|
|
59
|
+
- Retries: disabled by default
|
|
60
|
+
- `dsnKey` is required
|
|
61
|
+
- `apiKey` is optional (server-side only)
|
|
62
|
+
|
|
63
|
+
## Ingest Events
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const result = await sdk.ingest.event({
|
|
67
|
+
event: {
|
|
68
|
+
level: 'error',
|
|
69
|
+
message: 'Something went wrong',
|
|
70
|
+
payload: { requestId: 'req_123' },
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
console.log(result.event_id)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Required:
|
|
78
|
+
- `dsnKey` is sent in the body as `dsnKey` (always)
|
|
79
|
+
- `apiKey` is sent as `x-api-key` header (only when provided)
|
|
80
|
+
|
|
81
|
+
## Uptime Heartbeats
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
const heartbeat = await sdk.uptime.recordHeartbeat({
|
|
85
|
+
status: 'up',
|
|
86
|
+
responseTimeMs: 120,
|
|
87
|
+
checkedAt: new Date().toISOString(),
|
|
88
|
+
message: 'Service healthy',
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
console.log(heartbeat.id)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Uptime Queries
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
const history = await sdk.uptime.history('project_id', '2026-02-08')
|
|
98
|
+
const latest = await sdk.uptime.latest('project_id')
|
|
99
|
+
const summary = await sdk.uptime.summary('project_id', 30)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
These endpoints are public and do not require authentication.
|
|
103
|
+
|
|
104
|
+
## Updating Credentials
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
sdk.setApiKey('new_api_key')
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Error Handling
|
|
111
|
+
|
|
112
|
+
The SDK throws typed errors you can catch explicitly:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import { RateLimitError, AuthError } from '@observa/sdk'
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
await sdk.ingest.event({ event: { level: 'error', message: 'boom' } })
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error instanceof RateLimitError) {
|
|
121
|
+
console.log('Retry after seconds:', error.retryAfter)
|
|
122
|
+
}
|
|
123
|
+
if (error instanceof AuthError) {
|
|
124
|
+
console.log('Authentication failed')
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Requirements
|
|
130
|
+
|
|
131
|
+
- Node.js >= 18
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
MIT
|
|
136
|
+
|
|
137
|
+
## Links
|
|
138
|
+
|
|
139
|
+
- Documentation: ...
|
|
140
|
+
- GitHub: https://github.com/ObservaSolutions/sdk-observa
|
package/dist/apis/ingestApi.d.ts
CHANGED
|
@@ -1,32 +1,18 @@
|
|
|
1
1
|
import type { IngestRequest, IngestResponse } from '../domain/ingest';
|
|
2
2
|
import type { HttpClient } from '../http/httpClient';
|
|
3
|
-
export type IngestNormalizationOptions = {
|
|
4
|
-
schemaVersion?: number;
|
|
5
|
-
includeContext?: boolean;
|
|
6
|
-
includeSystemContext?: boolean;
|
|
7
|
-
includeRuntimeContext?: boolean;
|
|
8
|
-
maxEventBytes?: number;
|
|
9
|
-
maxFrames?: number;
|
|
10
|
-
maxMessageLength?: number;
|
|
11
|
-
maxExceptionValueLength?: number;
|
|
12
|
-
};
|
|
13
3
|
/**
|
|
14
4
|
* Event ingestion API.
|
|
15
5
|
*/
|
|
16
6
|
export declare class IngestApi {
|
|
17
7
|
private readonly http;
|
|
18
8
|
private readonly defaultDsnKey?;
|
|
19
|
-
private readonly normalization?;
|
|
20
9
|
/**
|
|
21
10
|
* Creates the ingestion client with an optional default DSN.
|
|
22
11
|
*/
|
|
23
|
-
constructor(http: HttpClient, defaultDsnKey?: string | undefined
|
|
12
|
+
constructor(http: HttpClient, defaultDsnKey?: string | undefined);
|
|
24
13
|
/**
|
|
25
14
|
* Sends an event to the ingestion backend.
|
|
26
15
|
*/
|
|
27
16
|
event(input: IngestRequest): Promise<IngestResponse>;
|
|
28
|
-
health(dsnKey?: string): Promise<{
|
|
29
|
-
ok: boolean;
|
|
30
|
-
}>;
|
|
31
17
|
}
|
|
32
18
|
//# sourceMappingURL=ingestApi.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingestApi.d.ts","sourceRoot":"","sources":["../../src/apis/ingestApi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ingestApi.d.ts","sourceRoot":"","sources":["../../src/apis/ingestApi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAErE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEpD;;GAEG;AACH,qBAAa,SAAS;IAIN,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAc,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAH9E;;OAEG;gBAC0B,IAAI,EAAE,UAAU,EAAmB,aAAa,CAAC,EAAE,MAAM,YAAA;IAEtF;;OAEG;IACG,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;CAQ7D"}
|
package/dist/apis/ingestApi.js
CHANGED
|
@@ -1,31 +1,16 @@
|
|
|
1
|
-
import { randomUUID } from 'crypto';
|
|
2
|
-
import { ValidationError } from '../http/errors';
|
|
3
|
-
import { getProcessContextDynamic, getProcessContextStatic } from '../utils/processContext';
|
|
4
1
|
import { ensureDefined, ensureNonEmpty } from '../utils/validate';
|
|
5
|
-
const DEFAULT_NORMALIZATION = {
|
|
6
|
-
schemaVersion: 1,
|
|
7
|
-
includeContext: true,
|
|
8
|
-
includeSystemContext: true,
|
|
9
|
-
includeRuntimeContext: true,
|
|
10
|
-
maxEventBytes: 64 * 1024,
|
|
11
|
-
maxFrames: 60,
|
|
12
|
-
maxMessageLength: 4000,
|
|
13
|
-
maxExceptionValueLength: 4000,
|
|
14
|
-
};
|
|
15
2
|
/**
|
|
16
3
|
* Event ingestion API.
|
|
17
4
|
*/
|
|
18
5
|
export class IngestApi {
|
|
19
6
|
http;
|
|
20
7
|
defaultDsnKey;
|
|
21
|
-
normalization;
|
|
22
8
|
/**
|
|
23
9
|
* Creates the ingestion client with an optional default DSN.
|
|
24
10
|
*/
|
|
25
|
-
constructor(http, defaultDsnKey
|
|
11
|
+
constructor(http, defaultDsnKey) {
|
|
26
12
|
this.http = http;
|
|
27
13
|
this.defaultDsnKey = defaultDsnKey;
|
|
28
|
-
this.normalization = normalization;
|
|
29
14
|
}
|
|
30
15
|
/**
|
|
31
16
|
* Sends an event to the ingestion backend.
|
|
@@ -36,141 +21,7 @@ export class IngestApi {
|
|
|
36
21
|
ensureDefined(dsnKey, 'dsnKey');
|
|
37
22
|
ensureNonEmpty(dsnKey, 'dsnKey');
|
|
38
23
|
ensureDefined(input.event, 'event');
|
|
39
|
-
|
|
40
|
-
throw new ValidationError('idempotencyKey must be at most 128 characters');
|
|
41
|
-
}
|
|
42
|
-
const headers = {};
|
|
43
|
-
if (input.idempotencyKey)
|
|
44
|
-
headers['x-idempotency-key'] = input.idempotencyKey;
|
|
45
|
-
if (input.sdkVersion)
|
|
46
|
-
headers['x-sdk-version'] = input.sdkVersion;
|
|
47
|
-
const { idempotencyKey, sdkVersion, event, ...body } = input;
|
|
48
|
-
const normalizedEvent = normalizeEvent(event, this.normalization);
|
|
49
|
-
return this.http.post('/ingest/events', { ...body, dsnKey, event: normalizedEvent }, { auth: 'apiKey', headers });
|
|
24
|
+
return this.http.post('/ingest/events', { ...input, dsnKey }, { auth: 'dsn' });
|
|
50
25
|
}
|
|
51
|
-
async health(dsnKey) {
|
|
52
|
-
const resolvedDsnKey = dsnKey ?? this.defaultDsnKey;
|
|
53
|
-
ensureDefined(resolvedDsnKey, 'dsnKey');
|
|
54
|
-
ensureNonEmpty(resolvedDsnKey, 'dsnKey');
|
|
55
|
-
return this.http.post('/ingest/health', { dsnKey: resolvedDsnKey }, { auth: 'apiKey' });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function normalizeEvent(event, options) {
|
|
59
|
-
const config = { ...DEFAULT_NORMALIZATION, ...options };
|
|
60
|
-
const normalizedTimestamp = normalizeTimestamp(event.timestamp);
|
|
61
|
-
const normalizedLevel = event.level ? event.level.toLowerCase() : undefined;
|
|
62
|
-
const normalizedMessage = event.message ? truncate(event.message, config.maxMessageLength) : undefined;
|
|
63
|
-
const normalizedException = normalizeException(event.exception, config);
|
|
64
|
-
if (!normalizedMessage && !normalizedException) {
|
|
65
|
-
throw new ValidationError('event message or exception is required');
|
|
66
|
-
}
|
|
67
|
-
const normalizedContext = normalizeContext(event.context, config);
|
|
68
|
-
const normalizedEvent = {
|
|
69
|
-
...event,
|
|
70
|
-
event_id: event.event_id ?? randomUUID(),
|
|
71
|
-
timestamp: normalizedTimestamp,
|
|
72
|
-
schema_version: event.schema_version ?? config.schemaVersion,
|
|
73
|
-
level: normalizedLevel,
|
|
74
|
-
message: normalizedMessage,
|
|
75
|
-
exception: normalizedException,
|
|
76
|
-
context: normalizedContext,
|
|
77
|
-
};
|
|
78
|
-
return enforceSizeLimit(normalizedEvent, config);
|
|
79
|
-
}
|
|
80
|
-
function normalizeTimestamp(timestamp) {
|
|
81
|
-
if (!timestamp)
|
|
82
|
-
return new Date().toISOString();
|
|
83
|
-
const parsed = new Date(timestamp);
|
|
84
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
85
|
-
throw new ValidationError('timestamp must be a valid ISO date');
|
|
86
|
-
}
|
|
87
|
-
return parsed.toISOString();
|
|
88
|
-
}
|
|
89
|
-
function normalizeException(exception, config) {
|
|
90
|
-
if (!exception)
|
|
91
|
-
return undefined;
|
|
92
|
-
if (!exception.type || !exception.value) {
|
|
93
|
-
throw new ValidationError('exception.type and exception.value are required');
|
|
94
|
-
}
|
|
95
|
-
return {
|
|
96
|
-
...exception,
|
|
97
|
-
value: truncate(exception.value, config.maxExceptionValueLength),
|
|
98
|
-
stacktrace: normalizeStacktrace(exception.stacktrace, config.maxFrames),
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
function normalizeStacktrace(stacktrace, maxFrames) {
|
|
102
|
-
if (!stacktrace || !Array.isArray(stacktrace.frames))
|
|
103
|
-
return undefined;
|
|
104
|
-
const frames = stacktrace.frames;
|
|
105
|
-
const normalizedFrames = frames.slice(0, maxFrames).map((frame) => {
|
|
106
|
-
const filename = typeof frame?.filename === 'string' ? frame.filename : undefined;
|
|
107
|
-
const functionName = typeof frame?.function === 'string' ? frame.function : undefined;
|
|
108
|
-
const lineno = typeof frame?.lineno === 'number' ? frame.lineno : undefined;
|
|
109
|
-
const colno = typeof frame?.colno === 'number' ? frame.colno : undefined;
|
|
110
|
-
const inferredInApp = filename ? !filename.includes('node_modules') : false;
|
|
111
|
-
return {
|
|
112
|
-
filename,
|
|
113
|
-
function: functionName,
|
|
114
|
-
lineno,
|
|
115
|
-
colno,
|
|
116
|
-
in_app: typeof frame?.in_app === 'boolean' ? frame.in_app : inferredInApp,
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
return { frames: normalizedFrames };
|
|
120
|
-
}
|
|
121
|
-
function normalizeContext(context, config) {
|
|
122
|
-
if (!config.includeContext)
|
|
123
|
-
return context;
|
|
124
|
-
const systemContext = config.includeSystemContext ? getProcessContextDynamic() : undefined;
|
|
125
|
-
const runtimeContext = config.includeRuntimeContext ? getProcessContextStatic({ includeVersions: false }) : undefined;
|
|
126
|
-
const mergedContext = {
|
|
127
|
-
...context,
|
|
128
|
-
system: context?.system ?? systemContext,
|
|
129
|
-
runtime: context?.runtime ?? runtimeContext,
|
|
130
|
-
};
|
|
131
|
-
return mergedContext;
|
|
132
|
-
}
|
|
133
|
-
function enforceSizeLimit(event, config) {
|
|
134
|
-
let normalized = event;
|
|
135
|
-
if (getSize(normalized) <= config.maxEventBytes)
|
|
136
|
-
return normalized;
|
|
137
|
-
if (normalized.extra) {
|
|
138
|
-
normalized = { ...normalized, extra: undefined };
|
|
139
|
-
}
|
|
140
|
-
if (getSize(normalized) <= config.maxEventBytes)
|
|
141
|
-
return normalized;
|
|
142
|
-
if (normalized.tags) {
|
|
143
|
-
normalized = { ...normalized, tags: undefined };
|
|
144
|
-
}
|
|
145
|
-
if (getSize(normalized) <= config.maxEventBytes)
|
|
146
|
-
return normalized;
|
|
147
|
-
if (normalized.exception?.stacktrace) {
|
|
148
|
-
normalized = {
|
|
149
|
-
...normalized,
|
|
150
|
-
exception: { ...normalized.exception, stacktrace: undefined },
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
if (getSize(normalized) <= config.maxEventBytes)
|
|
154
|
-
return normalized;
|
|
155
|
-
if (normalized.message) {
|
|
156
|
-
normalized = { ...normalized, message: truncate(normalized.message, config.maxMessageLength) };
|
|
157
|
-
}
|
|
158
|
-
if (normalized.exception?.value) {
|
|
159
|
-
normalized = {
|
|
160
|
-
...normalized,
|
|
161
|
-
exception: { ...normalized.exception, value: truncate(normalized.exception.value, config.maxExceptionValueLength) },
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
if (getSize(normalized) <= config.maxEventBytes)
|
|
165
|
-
return normalized;
|
|
166
|
-
throw new ValidationError('event payload exceeds size limit');
|
|
167
|
-
}
|
|
168
|
-
function getSize(value) {
|
|
169
|
-
return Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
170
|
-
}
|
|
171
|
-
function truncate(value, maxLength) {
|
|
172
|
-
if (value.length <= maxLength)
|
|
173
|
-
return value;
|
|
174
|
-
return value.slice(0, maxLength);
|
|
175
26
|
}
|
|
176
27
|
//# sourceMappingURL=ingestApi.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingestApi.js","sourceRoot":"","sources":["../../src/apis/ingestApi.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ingestApi.js","sourceRoot":"","sources":["../../src/apis/ingestApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGjE;;GAEG;AACH,MAAM,OAAO,SAAS;IAIW;IAAmC;IAHhE;;OAEG;IACH,YAA6B,IAAgB,EAAmB,aAAsB;QAAzD,SAAI,GAAJ,IAAI,CAAY;QAAmB,kBAAa,GAAb,aAAa,CAAS;IAAI,CAAC;IAE3F;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,KAAoB;QAC5B,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAA;QACjD,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAChC,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAiB,gBAAgB,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAClG,CAAC;CACJ"}
|
package/dist/apis/uptimeApi.js
CHANGED
|
@@ -21,7 +21,7 @@ export class UptimeApi {
|
|
|
21
21
|
ensureDefined(dsnKey, 'dsnKey');
|
|
22
22
|
ensureNonEmpty(dsnKey, 'dsnKey');
|
|
23
23
|
ensureNonEmpty(input.status, 'status');
|
|
24
|
-
return this.http.post('/uptime/heartbeats', { ...input, dsnKey }, { auth: '
|
|
24
|
+
return this.http.post('/uptime/heartbeats', { ...input, dsnKey }, { auth: 'dsn' });
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Lists a project's daily uptime history.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uptimeApi.js","sourceRoot":"","sources":["../../src/apis/uptimeApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGjE;;GAEG;AACH,MAAM,OAAO,SAAS;IAIW;IAAmC;IAHhE;;OAEG;IACH,YAA6B,IAAgB,EAAmB,aAAsB;QAAzD,SAAI,GAAJ,IAAI,CAAY;QAAmB,kBAAa,GAAb,aAAa,CAAS;IAAI,CAAC;IAE3F;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,KAA2B;QAC7C,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAA;QACjD,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAChC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAc,oBAAoB,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"uptimeApi.js","sourceRoot":"","sources":["../../src/apis/uptimeApi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGjE;;GAEG;AACH,MAAM,OAAO,SAAS;IAIW;IAAmC;IAHhE;;OAEG;IACH,YAA6B,IAAgB,EAAmB,aAAsB;QAAzD,SAAI,GAAJ,IAAI,CAAY;QAAmB,kBAAa,GAAb,aAAa,CAAS;IAAI,CAAC;IAE3F;;OAEG;IACH,KAAK,CAAC,eAAe,CAAC,KAA2B;QAC7C,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;QAC7B,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAA;QACjD,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAC/B,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAChC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAc,oBAAoB,EAAE,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACnG,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,IAAY;QACzC,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;QACtC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAgB,aAAa,kBAAkB,CAAC,SAAS,CAAC,iBAAiB,EAAE;YAC7F,KAAK,EAAE,EAAE,IAAI,EAAE;YACf,IAAI,EAAE,MAAM;SACf,CAAC,CAAA;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC1B,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAqB,aAAa,kBAAkB,CAAC,SAAS,CAAC,gBAAgB,EAAE;YACjG,IAAI,EAAE,MAAM;SACf,CAAC,CAAA;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,SAAiB,EAAE,IAAa,EAAE,qBAA8B;QAC1E,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;QACtC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAkB,aAAa,kBAAkB,CAAC,SAAS,CAAC,iBAAiB,EAAE;YAC/F,KAAK,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE;YACtC,IAAI,EAAE,MAAM;SACf,CAAC,CAAA;IACN,CAAC;CACJ"}
|
package/dist/domain/ingest.d.ts
CHANGED
|
@@ -1,33 +1,7 @@
|
|
|
1
|
-
import type { ProcessContextDynamic, ProcessContextStatic } from '../utils/processContext';
|
|
2
1
|
/**
|
|
3
2
|
* Severity levels for events.
|
|
4
3
|
*/
|
|
5
4
|
export type IngestLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
6
|
-
export type StacktraceFrame = {
|
|
7
|
-
filename?: string;
|
|
8
|
-
function?: string;
|
|
9
|
-
lineno?: number;
|
|
10
|
-
colno?: number;
|
|
11
|
-
in_app?: boolean;
|
|
12
|
-
};
|
|
13
|
-
export type Stacktrace = {
|
|
14
|
-
frames: StacktraceFrame[];
|
|
15
|
-
};
|
|
16
|
-
export type IngestException = {
|
|
17
|
-
type: string;
|
|
18
|
-
value: string;
|
|
19
|
-
stacktrace?: Stacktrace;
|
|
20
|
-
};
|
|
21
|
-
export type RequestContext = {
|
|
22
|
-
requestId?: string;
|
|
23
|
-
userId?: string;
|
|
24
|
-
[key: string]: unknown;
|
|
25
|
-
};
|
|
26
|
-
export type IngestEventContext = {
|
|
27
|
-
system?: ProcessContextDynamic;
|
|
28
|
-
runtime?: ProcessContextStatic;
|
|
29
|
-
request?: RequestContext;
|
|
30
|
-
};
|
|
31
5
|
/**
|
|
32
6
|
* Ingestion event.
|
|
33
7
|
*/
|
|
@@ -40,7 +14,6 @@ export type IngestEvent = {
|
|
|
40
14
|
* Event ISO timestamp.
|
|
41
15
|
*/
|
|
42
16
|
timestamp?: string;
|
|
43
|
-
schema_version?: number;
|
|
44
17
|
/**
|
|
45
18
|
* Severity level.
|
|
46
19
|
*/
|
|
@@ -49,10 +22,10 @@ export type IngestEvent = {
|
|
|
49
22
|
* Main message.
|
|
50
23
|
*/
|
|
51
24
|
message?: string;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Free-form context payload.
|
|
27
|
+
*/
|
|
28
|
+
payload?: unknown;
|
|
56
29
|
};
|
|
57
30
|
/**
|
|
58
31
|
* Payload for sending an event to the backend.
|
|
@@ -66,8 +39,6 @@ export type IngestRequest = {
|
|
|
66
39
|
* Event to record.
|
|
67
40
|
*/
|
|
68
41
|
event: IngestEvent;
|
|
69
|
-
idempotencyKey?: string;
|
|
70
|
-
sdkVersion?: string;
|
|
71
42
|
};
|
|
72
43
|
/**
|
|
73
44
|
* Response after sending an event.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/domain/ingest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/domain/ingest.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAEvE;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACtB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,KAAK,EAAE,WAAW,CAAA;CACrB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IACzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;CACnB,CAAA"}
|