@telemetry-tracker/vite-plugin 1.0.0 → 1.1.0
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/dist/upload.d.ts +18 -1
- package/dist/upload.js +50 -4
- package/package.json +3 -3
package/dist/upload.d.ts
CHANGED
|
@@ -24,9 +24,26 @@ export type UploadSourceMapsResult = {
|
|
|
24
24
|
files: string[];
|
|
25
25
|
};
|
|
26
26
|
export declare function resolveUploadEndpoint(baseApiUrl: string): string;
|
|
27
|
+
/** Last non-inline sourceMappingURL comment in a built file. */
|
|
28
|
+
export declare function parseSourceMappingURL(source: string): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Bundle file that points at this map via sourceMappingURL.
|
|
31
|
+
* Next.js 16 Turbopack hashes the map independently of the chunk name.
|
|
32
|
+
*/
|
|
33
|
+
export declare function bundleFileForSourceMap(mapFilePath: string, bundleSources: {
|
|
34
|
+
filePath: string;
|
|
35
|
+
source: string;
|
|
36
|
+
}[]): string | null;
|
|
27
37
|
export declare function bundleUrlForMapFile(mapFilePath: string, outDir: string, baseUrl: string,
|
|
28
38
|
/** Vite `base` path prefix (e.g. `/app/`) or absolute CDN URL. */
|
|
29
39
|
viteBase?: string): string;
|
|
40
|
+
export declare function findBundleSources(dir: string): {
|
|
41
|
+
filePath: string;
|
|
42
|
+
source: string;
|
|
43
|
+
}[];
|
|
30
44
|
export declare function findMapFiles(dir: string): string[];
|
|
31
|
-
export declare function uploadSourceMapFile(options: UploadSourceMapsOptions, mapFilePath: string
|
|
45
|
+
export declare function uploadSourceMapFile(options: UploadSourceMapsOptions, mapFilePath: string, bundleSources?: {
|
|
46
|
+
filePath: string;
|
|
47
|
+
source: string;
|
|
48
|
+
}[]): Promise<void>;
|
|
32
49
|
export declare function uploadSourceMaps(options: UploadSourceMapsOptions): Promise<UploadSourceMapsResult>;
|
package/dist/upload.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFileSync, readdirSync, statSync, unlinkSync } from "node:fs";
|
|
2
|
-
import { basename, relative, resolve } from "node:path";
|
|
2
|
+
import { basename, dirname, relative, resolve } from "node:path";
|
|
3
3
|
const DEFAULT_BASE_API_URL = "https://api.telemetry-tracker.com";
|
|
4
4
|
export function resolveUploadEndpoint(baseApiUrl) {
|
|
5
5
|
const apiUrl = new URL(baseApiUrl || DEFAULT_BASE_API_URL);
|
|
@@ -18,6 +18,35 @@ function appendToUrl(base, ...pathParts) {
|
|
|
18
18
|
url.pathname = `/${segments.join("/")}`;
|
|
19
19
|
return url.href;
|
|
20
20
|
}
|
|
21
|
+
const BUNDLE_SOURCE_EXTENSIONS = new Set([".js", ".mjs", ".cjs", ".css"]);
|
|
22
|
+
/** Last non-inline sourceMappingURL comment in a built file. */
|
|
23
|
+
export function parseSourceMappingURL(source) {
|
|
24
|
+
const matches = source.match(/[#@]\s*sourceMappingURL=([^\s*'"]+)/g);
|
|
25
|
+
if (!matches || matches.length === 0)
|
|
26
|
+
return null;
|
|
27
|
+
const last = matches[matches.length - 1] ?? "";
|
|
28
|
+
const raw = last.split("=").slice(1).join("=").replace(/[),;]+$/, "");
|
|
29
|
+
if (!raw || raw.startsWith("data:"))
|
|
30
|
+
return null;
|
|
31
|
+
return raw;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Bundle file that points at this map via sourceMappingURL.
|
|
35
|
+
* Next.js 16 Turbopack hashes the map independently of the chunk name.
|
|
36
|
+
*/
|
|
37
|
+
export function bundleFileForSourceMap(mapFilePath, bundleSources) {
|
|
38
|
+
const resolvedMap = resolve(mapFilePath);
|
|
39
|
+
for (const bundle of bundleSources) {
|
|
40
|
+
const ref = parseSourceMappingURL(bundle.source);
|
|
41
|
+
if (!ref)
|
|
42
|
+
continue;
|
|
43
|
+
const clean = ref.split("?")[0]?.split("#")[0] ?? ref;
|
|
44
|
+
if (resolve(dirname(bundle.filePath), clean) === resolvedMap) {
|
|
45
|
+
return bundle.filePath;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
21
50
|
export function bundleUrlForMapFile(mapFilePath, outDir, baseUrl,
|
|
22
51
|
/** Vite `base` path prefix (e.g. `/app/`) or absolute CDN URL. */
|
|
23
52
|
viteBase = "/") {
|
|
@@ -36,6 +65,22 @@ viteBase = "/") {
|
|
|
36
65
|
}
|
|
37
66
|
return `${prefix}/${normalizedJsPath}`;
|
|
38
67
|
}
|
|
68
|
+
export function findBundleSources(dir) {
|
|
69
|
+
const results = [];
|
|
70
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
71
|
+
const fullPath = resolve(dir, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
results.push(...findBundleSources(fullPath));
|
|
74
|
+
}
|
|
75
|
+
else if (entry.isFile()) {
|
|
76
|
+
const ext = entry.name.slice(entry.name.lastIndexOf("."));
|
|
77
|
+
if (BUNDLE_SOURCE_EXTENSIONS.has(ext)) {
|
|
78
|
+
results.push({ filePath: fullPath, source: readFileSync(fullPath, "utf8") });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return results;
|
|
83
|
+
}
|
|
39
84
|
export function findMapFiles(dir) {
|
|
40
85
|
const results = [];
|
|
41
86
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
@@ -49,7 +94,7 @@ export function findMapFiles(dir) {
|
|
|
49
94
|
}
|
|
50
95
|
return results;
|
|
51
96
|
}
|
|
52
|
-
export async function uploadSourceMapFile(options, mapFilePath) {
|
|
97
|
+
export async function uploadSourceMapFile(options, mapFilePath, bundleSources = []) {
|
|
53
98
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
54
99
|
const endpoint = resolveUploadEndpoint(options.baseApiUrl ?? DEFAULT_BASE_API_URL);
|
|
55
100
|
const content = readFileSync(mapFilePath, "utf8");
|
|
@@ -63,7 +108,7 @@ export async function uploadSourceMapFile(options, mapFilePath) {
|
|
|
63
108
|
const payload = {
|
|
64
109
|
app: options.app,
|
|
65
110
|
release: options.release,
|
|
66
|
-
bundle_url: bundleUrlForMapFile(mapFilePath, options.outDir, options.baseUrl, options.viteBase),
|
|
111
|
+
bundle_url: bundleUrlForMapFile(bundleFileForSourceMap(mapFilePath, bundleSources) ?? mapFilePath, options.outDir, options.baseUrl, options.viteBase),
|
|
67
112
|
content: parsedContent,
|
|
68
113
|
};
|
|
69
114
|
const response = await fetchImpl(endpoint, {
|
|
@@ -89,9 +134,10 @@ export async function uploadSourceMaps(options) {
|
|
|
89
134
|
if (mapFiles.length === 0) {
|
|
90
135
|
return { uploaded: 0, skipped: 0, files: [] };
|
|
91
136
|
}
|
|
137
|
+
const bundleSources = findBundleSources(resolvedOutDir);
|
|
92
138
|
const uploadedFiles = [];
|
|
93
139
|
for (const mapFile of mapFiles) {
|
|
94
|
-
await uploadSourceMapFile(options, mapFile);
|
|
140
|
+
await uploadSourceMapFile(options, mapFile, bundleSources);
|
|
95
141
|
uploadedFiles.push(mapFile);
|
|
96
142
|
}
|
|
97
143
|
if (options.deleteMapsAfterUpload) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telemetry-tracker/vite-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Vite plugin to upload source maps to Telemetry Tracker after build.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^22.9.0",
|
|
35
35
|
"typescript": "^5.6.3",
|
|
36
|
-
"vite": "^7.3.
|
|
36
|
+
"vite": "^7.3.5",
|
|
37
37
|
"vitest": "^3.2.6"
|
|
38
38
|
},
|
|
39
|
-
"
|
|
39
|
+
"gitHead": "886d9f8e0b92a78471f27b87365fc40ba7043ce1",
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "tsc",
|
|
42
42
|
"dev": "tsc --watch",
|