-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathutils.ts
83 lines (74 loc) · 3.11 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
import * as fs from 'fs';
import * as path from 'path';
/**
* Find the default SDK init file for the given type (client or server).
* The sentry.server.config file is prioritized over the instrument.server file.
*/
export function findDefaultSdkInitFile(type: 'server' | 'client'): string | undefined {
const possibleFileExtensions = ['ts', 'js', 'mjs', 'cjs', 'mts', 'cts'];
const cwd = process.cwd();
const filePaths: string[] = [];
if (type === 'server') {
for (const ext of possibleFileExtensions) {
// order is important here - we want to prioritize the server.config file
filePaths.push(path.join(cwd, `sentry.${type}.config.${ext}`));
filePaths.push(path.join(cwd, 'public', `instrument.${type}.${ext}`));
}
} else {
for (const ext of possibleFileExtensions) {
filePaths.push(path.join(cwd, `sentry.${type}.config.${ext}`));
}
}
return filePaths.find(filename => fs.existsSync(filename));
}
export const SENTRY_WRAPPED_ENTRY = '?sentry-query-wrapped-entry';
export const SENTRY_FUNCTIONS_REEXPORT = '?sentry-query-functions-reexport=';
export const QUERY_END_INDICATOR = 'SENTRY-QUERY-END';
/**
* Strips the Sentry query part from a path.
* Example: example/path?sentry-query-wrapped-entry?sentry-query-functions-reexport=foo,SENTRY-QUERY-END -> /example/path
*
* Only exported for testing.
*/
export function removeSentryQueryFromPath(url: string): string {
// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor
const regex = new RegExp(`\\${SENTRY_WRAPPED_ENTRY}.*?\\${QUERY_END_INDICATOR}`);
return url.replace(regex, '');
}
/**
* Extracts and sanitizes function re-export query parameters from a query string.
* If it is a default export, it is not considered for re-exporting. This function is mostly relevant for re-exporting
* serverless `handler` functions.
*
* Only exported for testing.
*/
export function extractFunctionReexportQueryParameters(query: string): string[] {
// Regex matches the comma-separated params between the functions query
// eslint-disable-next-line @sentry-internal/sdk/no-regexp-constructor
const regex = new RegExp(`\\${SENTRY_FUNCTIONS_REEXPORT}(.*?)\\${QUERY_END_INDICATOR}`);
const match = query.match(regex);
return match && match[1]
? match[1]
.split(',')
.filter(param => param !== '')
// Sanitize, as code could be injected with another rollup plugin
.map((str: string) => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))
: [];
}
/**
* Constructs a code snippet with function reexports (can be used in Rollup plugins)
*/
export function constructFunctionReExport(pathWithQuery: string, entryId: string): string {
const functionNames = extractFunctionReexportQueryParameters(pathWithQuery);
return functionNames.reduce(
(functionsCode, currFunctionName) =>
functionsCode.concat(
'async function reExport(...args) {\n' +
` const res = await import(${JSON.stringify(entryId)});\n` +
` return res.${currFunctionName}.call(this, ...args);\n` +
'}\n' +
`export { reExport as ${currFunctionName} };\n`,
),
'',
);
}