@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/src/apis/ingestApi.ts
DELETED
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'crypto'
|
|
2
|
-
import type { IngestEvent, IngestRequest, IngestResponse, StacktraceFrame } from '../domain/ingest'
|
|
3
|
-
import { ValidationError } from '../http/errors'
|
|
4
|
-
import { getProcessContextDynamic, getProcessContextStatic } from '../utils/processContext'
|
|
5
|
-
import { ensureDefined, ensureNonEmpty } from '../utils/validate'
|
|
6
|
-
import type { HttpClient } from '../http/httpClient'
|
|
7
|
-
|
|
8
|
-
export type IngestNormalizationOptions = {
|
|
9
|
-
schemaVersion?: number
|
|
10
|
-
includeContext?: boolean
|
|
11
|
-
includeSystemContext?: boolean
|
|
12
|
-
includeRuntimeContext?: boolean
|
|
13
|
-
maxEventBytes?: number
|
|
14
|
-
maxFrames?: number
|
|
15
|
-
maxMessageLength?: number
|
|
16
|
-
maxExceptionValueLength?: number
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const DEFAULT_NORMALIZATION: Required<IngestNormalizationOptions> = {
|
|
20
|
-
schemaVersion: 1,
|
|
21
|
-
includeContext: true,
|
|
22
|
-
includeSystemContext: true,
|
|
23
|
-
includeRuntimeContext: true,
|
|
24
|
-
maxEventBytes: 64 * 1024,
|
|
25
|
-
maxFrames: 60,
|
|
26
|
-
maxMessageLength: 4000,
|
|
27
|
-
maxExceptionValueLength: 4000,
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Event ingestion API.
|
|
32
|
-
*/
|
|
33
|
-
export class IngestApi {
|
|
34
|
-
/**
|
|
35
|
-
* Creates the ingestion client with an optional default DSN and PublicKey.
|
|
36
|
-
*/
|
|
37
|
-
constructor(
|
|
38
|
-
private readonly http: HttpClient,
|
|
39
|
-
private readonly defaultDsnKey?: string,
|
|
40
|
-
private readonly normalization?: IngestNormalizationOptions,
|
|
41
|
-
private readonly defaultPublicKey?: string
|
|
42
|
-
) { }
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Sends an event to the ingestion backend.
|
|
46
|
-
*/
|
|
47
|
-
async event(input: IngestRequest): Promise<IngestResponse> {
|
|
48
|
-
ensureDefined(input, 'input')
|
|
49
|
-
const dsnKey = input.dsnKey ?? this.defaultDsnKey
|
|
50
|
-
const publicKey = input.publicKey ?? this.defaultPublicKey
|
|
51
|
-
|
|
52
|
-
ensureDefined(dsnKey, 'dsnKey')
|
|
53
|
-
ensureNonEmpty(dsnKey, 'dsnKey')
|
|
54
|
-
ensureDefined(input.event, 'event')
|
|
55
|
-
|
|
56
|
-
if (!this.http.hasApiKey() && !publicKey) {
|
|
57
|
-
throw new ValidationError('publicKey is required when apiKey is not provided')
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (input.idempotencyKey && input.idempotencyKey.length > 128) {
|
|
61
|
-
throw new ValidationError('idempotencyKey must be at most 128 characters')
|
|
62
|
-
}
|
|
63
|
-
const headers: Record<string, string> = {}
|
|
64
|
-
if (input.idempotencyKey) headers['x-idempotency-key'] = input.idempotencyKey
|
|
65
|
-
if (input.sdkVersion) headers['x-sdk-version'] = input.sdkVersion
|
|
66
|
-
const { idempotencyKey, sdkVersion, event, ...body } = input
|
|
67
|
-
const normalizedEvent = normalizeEvent(event, this.normalization)
|
|
68
|
-
|
|
69
|
-
const authMode = this.http.hasApiKey() ? 'apiKey' : 'none'
|
|
70
|
-
return this.http.post<IngestResponse>('/ingest/events', { ...body, dsnKey, publicKey, event: normalizedEvent }, { auth: authMode, headers })
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
async health(dsnKey?: string, publicKey?: string): Promise<{ ok: boolean }> {
|
|
74
|
-
const resolvedDsnKey = dsnKey ?? this.defaultDsnKey
|
|
75
|
-
const resolvedPublicKey = publicKey ?? this.defaultPublicKey
|
|
76
|
-
|
|
77
|
-
ensureDefined(resolvedDsnKey, 'dsnKey')
|
|
78
|
-
ensureNonEmpty(resolvedDsnKey, 'dsnKey')
|
|
79
|
-
|
|
80
|
-
const authMode = this.http.hasApiKey() ? 'apiKey' : 'none'
|
|
81
|
-
return this.http.post<{ ok: boolean }>('/ingest/health', { dsnKey: resolvedDsnKey, publicKey: resolvedPublicKey }, { auth: authMode })
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function normalizeEvent(event: IngestEvent, options?: IngestNormalizationOptions): IngestEvent {
|
|
86
|
-
const config = { ...DEFAULT_NORMALIZATION, ...options }
|
|
87
|
-
const normalizedTimestamp = normalizeTimestamp(event.timestamp)
|
|
88
|
-
const normalizedLevel = event.level ? event.level.toLowerCase() : undefined
|
|
89
|
-
const normalizedMessage = event.message ? truncate(event.message, config.maxMessageLength) : undefined
|
|
90
|
-
const normalizedException = normalizeException(event.exception, config)
|
|
91
|
-
if (!normalizedMessage && !normalizedException) {
|
|
92
|
-
throw new ValidationError('event message or exception is required')
|
|
93
|
-
}
|
|
94
|
-
const normalizedContext = normalizeContext(event.context, config)
|
|
95
|
-
const normalizedEvent: IngestEvent = {
|
|
96
|
-
...event,
|
|
97
|
-
event_id: event.event_id ?? randomUUID(),
|
|
98
|
-
timestamp: normalizedTimestamp,
|
|
99
|
-
schema_version: event.schema_version ?? config.schemaVersion,
|
|
100
|
-
level: normalizedLevel as IngestEvent['level'],
|
|
101
|
-
message: normalizedMessage,
|
|
102
|
-
exception: normalizedException,
|
|
103
|
-
context: normalizedContext,
|
|
104
|
-
}
|
|
105
|
-
return enforceSizeLimit(normalizedEvent, config)
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function normalizeTimestamp(timestamp?: string) {
|
|
109
|
-
if (!timestamp) return new Date().toISOString()
|
|
110
|
-
const parsed = new Date(timestamp)
|
|
111
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
112
|
-
throw new ValidationError('timestamp must be a valid ISO date')
|
|
113
|
-
}
|
|
114
|
-
return parsed.toISOString()
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function normalizeException(exception: IngestEvent['exception'], config: Required<IngestNormalizationOptions>) {
|
|
118
|
-
if (!exception) return undefined
|
|
119
|
-
if (!exception.type || !exception.value) {
|
|
120
|
-
throw new ValidationError('exception.type and exception.value are required')
|
|
121
|
-
}
|
|
122
|
-
return {
|
|
123
|
-
...exception,
|
|
124
|
-
value: truncate(exception.value, config.maxExceptionValueLength),
|
|
125
|
-
stacktrace: normalizeStacktrace(exception.stacktrace, config.maxFrames),
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function normalizeStacktrace(stacktrace: { frames?: StacktraceFrame[] } | undefined, maxFrames: number) {
|
|
130
|
-
if (!stacktrace || !Array.isArray(stacktrace.frames)) return undefined
|
|
131
|
-
const frames = stacktrace.frames
|
|
132
|
-
const normalizedFrames = frames.slice(0, maxFrames).map((frame) => {
|
|
133
|
-
const filename = typeof frame?.filename === 'string' ? frame.filename : undefined
|
|
134
|
-
const functionName = typeof frame?.function === 'string' ? frame.function : undefined
|
|
135
|
-
const lineno = typeof frame?.lineno === 'number' ? frame.lineno : undefined
|
|
136
|
-
const colno = typeof frame?.colno === 'number' ? frame.colno : undefined
|
|
137
|
-
const inferredInApp = filename ? !filename.includes('node_modules') : false
|
|
138
|
-
return {
|
|
139
|
-
filename,
|
|
140
|
-
function: functionName,
|
|
141
|
-
lineno,
|
|
142
|
-
colno,
|
|
143
|
-
in_app: typeof frame?.in_app === 'boolean' ? frame.in_app : inferredInApp,
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
return { frames: normalizedFrames }
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function normalizeContext(context: IngestEvent['context'] | undefined, config: Required<IngestNormalizationOptions>) {
|
|
150
|
-
if (!config.includeContext) return context
|
|
151
|
-
const systemContext = config.includeSystemContext ? getProcessContextDynamic() : undefined
|
|
152
|
-
const runtimeContext = config.includeRuntimeContext ? getProcessContextStatic({ includeVersions: false }) : undefined
|
|
153
|
-
const mergedContext = {
|
|
154
|
-
...context,
|
|
155
|
-
system: context?.system ?? systemContext,
|
|
156
|
-
runtime: context?.runtime ?? runtimeContext,
|
|
157
|
-
}
|
|
158
|
-
return mergedContext
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function enforceSizeLimit(event: IngestEvent, config: Required<IngestNormalizationOptions>) {
|
|
162
|
-
let normalized = event
|
|
163
|
-
if (getSize(normalized) <= config.maxEventBytes) return normalized
|
|
164
|
-
if (normalized.extra) {
|
|
165
|
-
normalized = { ...normalized, extra: undefined }
|
|
166
|
-
}
|
|
167
|
-
if (getSize(normalized) <= config.maxEventBytes) return normalized
|
|
168
|
-
if (normalized.tags) {
|
|
169
|
-
normalized = { ...normalized, tags: undefined }
|
|
170
|
-
}
|
|
171
|
-
if (getSize(normalized) <= config.maxEventBytes) return normalized
|
|
172
|
-
if (normalized.exception?.stacktrace) {
|
|
173
|
-
normalized = {
|
|
174
|
-
...normalized,
|
|
175
|
-
exception: { ...normalized.exception, stacktrace: undefined },
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (getSize(normalized) <= config.maxEventBytes) return normalized
|
|
179
|
-
if (normalized.message) {
|
|
180
|
-
normalized = { ...normalized, message: truncate(normalized.message, config.maxMessageLength) }
|
|
181
|
-
}
|
|
182
|
-
if (normalized.exception?.value) {
|
|
183
|
-
normalized = {
|
|
184
|
-
...normalized,
|
|
185
|
-
exception: { ...normalized.exception, value: truncate(normalized.exception.value, config.maxExceptionValueLength) },
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
if (getSize(normalized) <= config.maxEventBytes) return normalized
|
|
189
|
-
throw new ValidationError('event payload exceeds size limit')
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
function getSize(value: unknown) {
|
|
193
|
-
return Buffer.byteLength(JSON.stringify(value), 'utf8')
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function truncate(value: string, maxLength: number) {
|
|
197
|
-
if (value.length <= maxLength) return value
|
|
198
|
-
return value.slice(0, maxLength)
|
|
199
|
-
}
|
package/src/apis/uptimeApi.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import type { UptimeEvent, UptimeHeartbeatInput, UptimeSummary } from '../domain/uptime'
|
|
2
|
-
import { ensureDefined, ensureNonEmpty } from '../utils/validate'
|
|
3
|
-
import type { HttpClient } from '../http/httpClient'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Uptime API for heartbeats and public reads.
|
|
7
|
-
*/
|
|
8
|
-
export class UptimeApi {
|
|
9
|
-
/**
|
|
10
|
-
* Creates the uptime client with an optional default DSN.
|
|
11
|
-
*/
|
|
12
|
-
constructor(private readonly http: HttpClient, private readonly defaultDsnKey?: string) { }
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Records an uptime heartbeat.
|
|
16
|
-
*/
|
|
17
|
-
async recordHeartbeat(input: UptimeHeartbeatInput): Promise<UptimeEvent> {
|
|
18
|
-
ensureDefined(input, 'input')
|
|
19
|
-
const dsnKey = input.dsnKey ?? this.defaultDsnKey
|
|
20
|
-
ensureDefined(dsnKey, 'dsnKey')
|
|
21
|
-
ensureNonEmpty(dsnKey, 'dsnKey')
|
|
22
|
-
ensureNonEmpty(input.status, 'status')
|
|
23
|
-
return this.http.post<UptimeEvent>('/uptime/heartbeats', { ...input, dsnKey }, { auth: 'apiKey' })
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Lists a project's daily uptime history.
|
|
28
|
-
*/
|
|
29
|
-
async history(projectId: string, date: string): Promise<UptimeEvent[]> {
|
|
30
|
-
ensureNonEmpty(projectId, 'projectId')
|
|
31
|
-
ensureNonEmpty(date, 'date')
|
|
32
|
-
return this.http.get<UptimeEvent[]>(`/projects/${encodeURIComponent(projectId)}/uptime/history`, {
|
|
33
|
-
query: { date },
|
|
34
|
-
auth: 'none',
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Gets the latest uptime event for a project.
|
|
40
|
-
*/
|
|
41
|
-
async latest(projectId: string): Promise<UptimeEvent | null> {
|
|
42
|
-
ensureNonEmpty(projectId, 'projectId')
|
|
43
|
-
return this.http.get<UptimeEvent | null>(`/projects/${encodeURIComponent(projectId)}/uptime/latest`, {
|
|
44
|
-
auth: 'none',
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Summarizes daily uptime.
|
|
50
|
-
*/
|
|
51
|
-
async summary(projectId: string, days?: number, delayThresholdMinutes?: number): Promise<UptimeSummary[]> {
|
|
52
|
-
ensureNonEmpty(projectId, 'projectId')
|
|
53
|
-
return this.http.get<UptimeSummary[]>(`/projects/${encodeURIComponent(projectId)}/uptime/summary`, {
|
|
54
|
-
query: { days, delayThresholdMinutes },
|
|
55
|
-
auth: 'none',
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
}
|
package/src/domain/ingest.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import type { ProcessContextDynamic, ProcessContextStatic } from '../utils/processContext'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Severity levels for events.
|
|
5
|
-
*/
|
|
6
|
-
export type IngestLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal'
|
|
7
|
-
|
|
8
|
-
export type StacktraceFrame = {
|
|
9
|
-
filename?: string
|
|
10
|
-
function?: string
|
|
11
|
-
lineno?: number
|
|
12
|
-
colno?: number
|
|
13
|
-
in_app?: boolean
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type Stacktrace = {
|
|
17
|
-
frames: StacktraceFrame[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type IngestException = {
|
|
21
|
-
type: string
|
|
22
|
-
value: string
|
|
23
|
-
stacktrace?: Stacktrace
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type RequestContext = {
|
|
27
|
-
requestId?: string
|
|
28
|
-
userId?: string
|
|
29
|
-
[key: string]: unknown
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type IngestEventContext = {
|
|
33
|
-
system?: ProcessContextDynamic
|
|
34
|
-
runtime?: ProcessContextStatic
|
|
35
|
-
request?: RequestContext
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Ingestion event.
|
|
40
|
-
*/
|
|
41
|
-
export type IngestEvent = {
|
|
42
|
-
/**
|
|
43
|
-
* Unique event identifier.
|
|
44
|
-
*/
|
|
45
|
-
event_id?: string
|
|
46
|
-
/**
|
|
47
|
-
* Event ISO timestamp.
|
|
48
|
-
*/
|
|
49
|
-
timestamp?: string
|
|
50
|
-
schema_version?: number
|
|
51
|
-
/**
|
|
52
|
-
* Severity level.
|
|
53
|
-
*/
|
|
54
|
-
level?: IngestLevel
|
|
55
|
-
/**
|
|
56
|
-
* Main message.
|
|
57
|
-
*/
|
|
58
|
-
message?: string
|
|
59
|
-
exception?: IngestException
|
|
60
|
-
context?: IngestEventContext
|
|
61
|
-
tags?: Record<string, string>
|
|
62
|
-
extra?: Record<string, unknown>
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Payload for sending an event to the backend.
|
|
67
|
-
*/
|
|
68
|
-
export type IngestRequest = {
|
|
69
|
-
/**
|
|
70
|
-
* Project DSN. Uses the SDK default when omitted.
|
|
71
|
-
*/
|
|
72
|
-
dsnKey?: string
|
|
73
|
-
/**
|
|
74
|
-
* Public key for frontend/mobile projects.
|
|
75
|
-
*/
|
|
76
|
-
publicKey?: string
|
|
77
|
-
/**
|
|
78
|
-
* Event to record.
|
|
79
|
-
*/
|
|
80
|
-
event: IngestEvent
|
|
81
|
-
idempotencyKey?: string
|
|
82
|
-
sdkVersion?: string
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Response after sending an event.
|
|
87
|
-
*/
|
|
88
|
-
export type IngestResponse = {
|
|
89
|
-
/**
|
|
90
|
-
* Assigned event identifier.
|
|
91
|
-
*/
|
|
92
|
-
event_id: string
|
|
93
|
-
}
|
package/src/domain/uptime.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Possible uptime statuses.
|
|
3
|
-
*/
|
|
4
|
-
export type UptimeStatus = 'up' | 'down' | 'degraded'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Recorded uptime event.
|
|
8
|
-
*/
|
|
9
|
-
export type UptimeEvent = {
|
|
10
|
-
/**
|
|
11
|
-
* Event identifier.
|
|
12
|
-
*/
|
|
13
|
-
id: string
|
|
14
|
-
/**
|
|
15
|
-
* Project the event belongs to.
|
|
16
|
-
*/
|
|
17
|
-
projectId: string
|
|
18
|
-
/**
|
|
19
|
-
* Uptime status.
|
|
20
|
-
*/
|
|
21
|
-
status: UptimeStatus
|
|
22
|
-
/**
|
|
23
|
-
* Optional message for the event.
|
|
24
|
-
*/
|
|
25
|
-
message?: string
|
|
26
|
-
/**
|
|
27
|
-
* Response time in milliseconds.
|
|
28
|
-
*/
|
|
29
|
-
responseTimeMs?: number
|
|
30
|
-
/**
|
|
31
|
-
* ISO timestamp of the check.
|
|
32
|
-
*/
|
|
33
|
-
checkedAt?: string
|
|
34
|
-
/**
|
|
35
|
-
* ISO timestamp of backend creation.
|
|
36
|
-
*/
|
|
37
|
-
createdAt?: string
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Payload for sending an uptime heartbeat.
|
|
42
|
-
*/
|
|
43
|
-
export type UptimeHeartbeatInput = {
|
|
44
|
-
/**
|
|
45
|
-
* Project DSN. Uses the SDK default when omitted.
|
|
46
|
-
*/
|
|
47
|
-
dsnKey?: string
|
|
48
|
-
/**
|
|
49
|
-
* Reported status.
|
|
50
|
-
*/
|
|
51
|
-
status: UptimeStatus
|
|
52
|
-
/**
|
|
53
|
-
* Response time in milliseconds.
|
|
54
|
-
*/
|
|
55
|
-
responseTimeMs?: number
|
|
56
|
-
/**
|
|
57
|
-
* ISO timestamp of the check.
|
|
58
|
-
*/
|
|
59
|
-
checkedAt?: string
|
|
60
|
-
/**
|
|
61
|
-
* Optional message.
|
|
62
|
-
*/
|
|
63
|
-
message?: string
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Daily uptime summary.
|
|
68
|
-
*/
|
|
69
|
-
export type UptimeSummary = {
|
|
70
|
-
/**
|
|
71
|
-
* ISO date of the summary.
|
|
72
|
-
*/
|
|
73
|
-
date: string
|
|
74
|
-
/**
|
|
75
|
-
* Hours without data.
|
|
76
|
-
*/
|
|
77
|
-
missingHours?: number
|
|
78
|
-
/**
|
|
79
|
-
* Accumulated delay minutes.
|
|
80
|
-
*/
|
|
81
|
-
delayMinutes?: number
|
|
82
|
-
/**
|
|
83
|
-
* Number of delayed events.
|
|
84
|
-
*/
|
|
85
|
-
delayedCount?: number
|
|
86
|
-
}
|
package/src/http/errors.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Additional data to enrich SDK errors.
|
|
3
|
-
*/
|
|
4
|
-
export type ErrorDetails = {
|
|
5
|
-
status?: number
|
|
6
|
-
code?: string
|
|
7
|
-
details?: unknown
|
|
8
|
-
retryAfter?: number
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Base SDK error.
|
|
13
|
-
*/
|
|
14
|
-
export class SdkError extends Error {
|
|
15
|
-
readonly status?: number
|
|
16
|
-
readonly code?: string
|
|
17
|
-
readonly details?: unknown
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Creates an error with optional metadata.
|
|
21
|
-
*/
|
|
22
|
-
constructor(message: string, details?: ErrorDetails) {
|
|
23
|
-
super(message)
|
|
24
|
-
this.name = new.target.name
|
|
25
|
-
this.status = details?.status
|
|
26
|
-
this.code = details?.code
|
|
27
|
-
this.details = details?.details
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Input validation error.
|
|
33
|
-
*/
|
|
34
|
-
export class ValidationError extends SdkError { }
|
|
35
|
-
/**
|
|
36
|
-
* Authentication error.
|
|
37
|
-
*/
|
|
38
|
-
export class AuthError extends SdkError { }
|
|
39
|
-
/**
|
|
40
|
-
* Error caused by insufficient permissions.
|
|
41
|
-
*/
|
|
42
|
-
export class ForbiddenError extends SdkError { }
|
|
43
|
-
/**
|
|
44
|
-
* Error when a resource does not exist.
|
|
45
|
-
*/
|
|
46
|
-
export class NotFoundError extends SdkError { }
|
|
47
|
-
/**
|
|
48
|
-
* Error caused by a state conflict.
|
|
49
|
-
*/
|
|
50
|
-
export class ConflictError extends SdkError { }
|
|
51
|
-
/**
|
|
52
|
-
* Error caused by rate limiting.
|
|
53
|
-
*/
|
|
54
|
-
export class RateLimitError extends SdkError {
|
|
55
|
-
readonly retryAfter?: number
|
|
56
|
-
|
|
57
|
-
constructor(message: string, details?: ErrorDetails) {
|
|
58
|
-
super(message, details)
|
|
59
|
-
this.retryAfter = details?.retryAfter
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Server-side error.
|
|
64
|
-
*/
|
|
65
|
-
export class ServerError extends SdkError { }
|
|
66
|
-
/**
|
|
67
|
-
* Network error.
|
|
68
|
-
*/
|
|
69
|
-
export class NetworkError extends SdkError { }
|
|
70
|
-
/**
|
|
71
|
-
* Request timeout error.
|
|
72
|
-
*/
|
|
73
|
-
export class TimeoutError extends SdkError { }
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Maps HTTP status codes to typed SDK errors.
|
|
77
|
-
*/
|
|
78
|
-
export function mapHttpError(status: number, details?: unknown, retryAfter?: number): SdkError {
|
|
79
|
-
const info = { status, details, retryAfter }
|
|
80
|
-
if (status === 400) return new ValidationError('Invalid request', info)
|
|
81
|
-
if (status === 401) return new AuthError('Unauthorized', info)
|
|
82
|
-
if (status === 403) return new ForbiddenError('Forbidden', info)
|
|
83
|
-
if (status === 404) return new NotFoundError('Resource not found', info)
|
|
84
|
-
if (status === 409) return new ConflictError('Conflict', info)
|
|
85
|
-
if (status === 429) return new RateLimitError('Rate limit exceeded', info)
|
|
86
|
-
if (status >= 500) return new ServerError('Server error', info)
|
|
87
|
-
return new SdkError('HTTP error', info)
|
|
88
|
-
}
|