-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
63abf82
commit dd846a3
Showing
5 changed files
with
167 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
export * from './edge-api-sdk' | ||
export * from './types' | ||
export * from './config' | ||
export * from './sentry' | ||
export * from './sentry/sentry' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { posix, sep } from 'path' | ||
import { dirname } from '@sentry/utils' | ||
|
||
/** normalizes Windows paths */ | ||
function normalizeWindowsPath(path: string): string { | ||
return path | ||
.replace(/^[A-Z]:/, '') // remove Windows-style prefix | ||
.replace(/\\/g, '/') // replace all `\` instances with `/` | ||
} | ||
|
||
/** Creates a function that gets the module name from a filename */ | ||
export function createGetModuleFromFilename( | ||
basePath: string = process.argv[1] ? dirname(process.argv[1]) : process.cwd(), | ||
isWindows: boolean = sep === '\\', | ||
): (filename: string | undefined) => string | undefined { | ||
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath | ||
|
||
return (filename: string | undefined) => { | ||
if (!filename) { | ||
return | ||
} | ||
|
||
const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename | ||
|
||
// eslint-disable-next-line prefer-const | ||
let { dir, base: file, ext } = posix.parse(normalizedFilename) | ||
|
||
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') { | ||
file = file.slice(0, ext.length * -1) | ||
} | ||
|
||
if (!dir) { | ||
// No dirname whatsoever | ||
dir = '.' | ||
} | ||
|
||
const n = dir.lastIndexOf('/node_modules') | ||
if (n > -1) { | ||
return `${dir.slice(n + 14).replace(/\//g, '.')}:${file}` | ||
} | ||
|
||
// Let's see if it's a part of the main module | ||
// To be a part of main module, it has to share the same base | ||
if (dir.startsWith(normalizedBase)) { | ||
let moduleName = dir.slice(normalizedBase.length + 1).replace(/\//g, '.') | ||
|
||
if (moduleName) { | ||
moduleName += ':' | ||
} | ||
moduleName += file | ||
|
||
return moduleName | ||
} | ||
|
||
return file | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import { createGetModuleFromFilename } from './module' | ||
|
||
import { createEventEnvelope, getEnvelopeEndpointWithUrlEncodedAuth } from '@sentry/core' | ||
import { | ||
stackParserFromStackParserOptions, | ||
createStackParser, | ||
nodeStackLineParser, | ||
exceptionFromError, | ||
dsnFromString, | ||
} from '@sentry/utils' | ||
|
||
import { Envelope, SeverityLevel } from '@sentry/types' | ||
|
||
import { LogLevel, LogPayload, MinimalLogPayload, Transport } from '../logger' | ||
|
||
const encodeUTF8 = (input: string) => new TextEncoder().encode(input) | ||
|
||
export function serializeEnvelope(envelope: Envelope): string | Uint8Array { | ||
const [envHeaders, items] = envelope | ||
|
||
// Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data | ||
let parts: string | Uint8Array[] = JSON.stringify(envHeaders) | ||
|
||
function append(next: string | Uint8Array): void { | ||
if (typeof parts === 'string') { | ||
parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts), next] | ||
} else { | ||
parts.push(typeof next === 'string' ? encodeUTF8(next) : next) | ||
} | ||
} | ||
|
||
for (const item of items) { | ||
const [itemHeaders, payload] = item | ||
|
||
append(`\n${JSON.stringify(itemHeaders)}\n`) | ||
|
||
if (typeof payload === 'string' || payload instanceof Uint8Array) { | ||
append(payload) | ||
} else { | ||
append(JSON.stringify(payload)) | ||
} | ||
} | ||
|
||
return typeof parts === 'string' ? parts : concatBuffers(parts) | ||
} | ||
|
||
function concatBuffers(buffers: Uint8Array[]): Uint8Array { | ||
const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0) | ||
|
||
const merged = new Uint8Array(totalLength) | ||
let offset = 0 | ||
for (const buffer of buffers) { | ||
merged.set(buffer, offset) | ||
offset += buffer.length | ||
} | ||
|
||
return merged | ||
} | ||
|
||
const stackParser = stackParserFromStackParserOptions( | ||
createStackParser(nodeStackLineParser(createGetModuleFromFilename())), | ||
) | ||
|
||
export type InitProps = { | ||
dsn: string | ||
environment?: string | ||
release?: string | ||
} | ||
|
||
const logLevelToSeverityLevel = (logLevel: LogLevel): SeverityLevel => { | ||
if (logLevel === 'panic' || logLevel === 'critical') { | ||
return 'fatal' | ||
} | ||
return logLevel | ||
} | ||
|
||
export const init = (props: InitProps): Transport => { | ||
const components = dsnFromString(props.dsn) | ||
if (!components) { | ||
throw new Error('invalid DSN provided') | ||
} | ||
|
||
return async (payload: MinimalLogPayload | LogPayload) => { | ||
const errorEntry = payload.entries.find((entry) => !!entry.error) | ||
const exception = errorEntry?.error ? exceptionFromError(stackParser, errorEntry.error) : undefined | ||
const envelope = createEventEnvelope({ | ||
exception: exception | ||
? { | ||
values: [exception], | ||
} | ||
: undefined, | ||
timestamp: errorEntry?.timestamp.getTime(), | ||
breadcrumbs: payload.entries.map((entry) => { | ||
return { | ||
level: logLevelToSeverityLevel(entry.level), | ||
message: entry.message, | ||
timestamp: entry.timestamp.getTime(), | ||
} | ||
}), | ||
}) | ||
|
||
const endpoint = getEnvelopeEndpointWithUrlEncodedAuth(components) | ||
await fetch(endpoint, { | ||
body: serializeEnvelope(envelope), | ||
method: 'post', | ||
}) | ||
} | ||
} |