-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(utils): Introduce envelope helper functions #4587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
24240e9
b342328
d7d551e
7fe5ed1
4baeaa0
a4b5541
a9ac0ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { Envelope } from '@sentry/types'; | ||
|
||
/** | ||
* Creates an envelope. | ||
* Make sure to always explicitly provide the generic to this function | ||
* so that the envelope types resolve correctly. | ||
*/ | ||
export function createEnvelope<E extends Envelope>(headers: E[0], items: E[1] = []): E { | ||
return [headers, items] as E; | ||
} | ||
|
||
/** | ||
* Add an item to an envelope. | ||
* Make sure to always explicitly provide the generic to this function | ||
* so that the envelope types resolve correctly. | ||
*/ | ||
export function addItemToEnvelope<E extends Envelope>(envelope: E, newItem: E[1][number]): E { | ||
const [headers, items] = envelope; | ||
return [headers, [...items, newItem]] as E; | ||
} | ||
|
||
/** | ||
* Serializes an envelope into a string. | ||
*/ | ||
export function serializeEnvelope(envelope: Envelope): string { | ||
const [headers, items] = envelope; | ||
const serializedHeaders = JSON.stringify(headers); | ||
|
||
// Have to cast items to any here since Envelope is a union type | ||
// Fixed in Typescript 4.2 | ||
// TODO: Remove any[] cast when we upgrade to TS 4.2 | ||
// https://github.com/microsoft/TypeScript/issues/36390 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
return (items as any[]).reduce((acc, item: typeof items[number]) => { | ||
const [itemHeaders, payload] = item; | ||
return `${acc}\n${JSON.stringify(itemHeaders)}\n${JSON.stringify(payload)}`; | ||
}, serializedHeaders); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { EventEnvelope } from '@sentry/types'; | ||
|
||
import { addItemToEnvelope, createEnvelope, serializeEnvelope } from '../src/envelope'; | ||
import { parseEnvelope } from './testutils'; | ||
|
||
describe('envelope', () => { | ||
describe('createEnvelope()', () => { | ||
const testTable: Array<[string, Parameters<typeof createEnvelope>[0], Parameters<typeof createEnvelope>[1]]> = [ | ||
['creates an empty envelope', {}, []], | ||
['creates an envelope with a header but no items', { dsn: 'https://[email protected]/1', sdk: {} }, []], | ||
]; | ||
it.each(testTable)('%s', (_: string, headers, items) => { | ||
const env = createEnvelope(headers, items); | ||
expect(env).toHaveLength(2); | ||
expect(env[0]).toStrictEqual(headers); | ||
expect(env[1]).toStrictEqual(items); | ||
}); | ||
}); | ||
|
||
describe('serializeEnvelope()', () => { | ||
it('serializes an envelope', () => { | ||
const env = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, []); | ||
expect(serializeEnvelope(env)).toMatchInlineSnapshot( | ||
`"{\\"event_id\\":\\"aa3ff046696b4bc6b609ce6d28fde9e2\\",\\"sent_at\\":\\"123\\"}"`, | ||
); | ||
}); | ||
}); | ||
|
||
describe('addItemToEnvelope()', () => { | ||
it('adds an item to an envelope', () => { | ||
const env = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, []); | ||
const parsedEnvelope = parseEnvelope(serializeEnvelope(env)); | ||
expect(parsedEnvelope).toHaveLength(1); | ||
expect(parsedEnvelope[0]).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }); | ||
|
||
const newEnv = addItemToEnvelope<EventEnvelope>(env, [ | ||
{ type: 'event' }, | ||
{ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }, | ||
]); | ||
const parsedNewEnvelope = parseEnvelope(serializeEnvelope(newEnv)); | ||
expect(parsedNewEnvelope).toHaveLength(3); | ||
expect(parsedNewEnvelope[0]).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }); | ||
expect(parsedNewEnvelope[1]).toEqual({ type: 'event' }); | ||
expect(parsedNewEnvelope[2]).toEqual({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -11,3 +11,7 @@ export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => { | |||||||||||||||||||
|
||||||||||||||||||||
return it; | ||||||||||||||||||||
}; | ||||||||||||||||||||
|
||||||||||||||||||||
export function parseEnvelope(env: string): Array<Record<any, any>> { | ||||||||||||||||||||
return env.split('\n').map(e => JSON.parse(e)); | ||||||||||||||||||||
} | ||||||||||||||||||||
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FWIW, we have such a function already if you want to use it: sentry-javascript/packages/core/test/lib/request.test.ts Lines 22 to 30 in bb6f865
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll leave it like this because this works with multiple envelope items - doesn't just assume a single one. Useful for when we expand the tests in the future. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After #4609, is this workaround still necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, as items is still a union type.