diff --git a/package.json b/package.json index 996651045..3bb1cc06d 100644 --- a/package.json +++ b/package.json @@ -50,14 +50,11 @@ "@microsoft/rush": "5.153.1", "@nevware21/grunt-eslint-ts": "^0.2.2", "@nevware21/grunt-ts-plugin": "^0.4.3", - "@typescript-eslint/eslint-plugin": "^5.46.1", - "@typescript-eslint/parser": "^5.46.1", "@rollup/plugin-commonjs": "^24.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.2", - "rollup": "^3.20.0", - "rollup-plugin-cleanup": "^3.2.1", - "rollup-plugin-sourcemaps": "^0.6.3", + "@typescript-eslint/eslint-plugin": "^5.46.1", + "@typescript-eslint/parser": "^5.46.1", "archiver": "^5.3.0", "connect": "^3.7.0", "eslint": "^7.29.0", @@ -66,16 +63,24 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^5.1.0", "eslint-plugin-security": "^1.4.0", + "eventemitter2": "6.4.9", "grunt": "^1.5.3", "grunt-cli": "^1.4.3", "grunt-contrib-connect": "^3.0.0", "grunt-contrib-copy": "^1.0.0", "grunt-contrib-uglify": "^5.2.1", - "eventemitter2": "6.4.9", "puppeteer": "24.8.2", + "request": "^2.88.2", + "rollup": "^3.20.0", + "rollup-plugin-cleanup": "^3.2.1", + "rollup-plugin-sourcemaps": "^0.6.3", "typedoc": "^0.26.6", "typescript": "^4.9.3", - "whatwg-fetch": "^3.6.2", - "request": "^2.88.2" + "whatwg-fetch": "^3.6.2" + }, + "dependencies": { + "@microsoft/dynamicproto-js": "^2.0.3", + "globby": "^14.1.0", + "magic-string": "^0.30.17" } } diff --git a/shared/AppInsightsCore/src/Config/IDynamicConfigHandler.ts b/shared/AppInsightsCore/src/Config/IDynamicConfigHandler.ts index 4c98979fa..150ff757e 100644 --- a/shared/AppInsightsCore/src/Config/IDynamicConfigHandler.ts +++ b/shared/AppInsightsCore/src/Config/IDynamicConfigHandler.ts @@ -109,4 +109,4 @@ export interface _IInternalDynamicConfigHandler extends IDyn * @param allowUpdate - An optional flag to enable updating config properties marked as readonly */ _block: (configHandler: WatcherFunction, allowUpdate?: boolean) => void; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/Config/IDynamicPropertyHandler.ts b/shared/AppInsightsCore/src/Config/IDynamicPropertyHandler.ts index 9195c41c2..9d991ae70 100644 --- a/shared/AppInsightsCore/src/Config/IDynamicPropertyHandler.ts +++ b/shared/AppInsightsCore/src/Config/IDynamicPropertyHandler.ts @@ -14,4 +14,4 @@ export interface IDynamicPropertyHandler { * The current collection is watcher handlers which should be called if the value changes */ h: IWatcherHandler[]; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/Config/IDynamicWatcher.ts b/shared/AppInsightsCore/src/Config/IDynamicWatcher.ts index 88c458467..767883ecd 100644 --- a/shared/AppInsightsCore/src/Config/IDynamicWatcher.ts +++ b/shared/AppInsightsCore/src/Config/IDynamicWatcher.ts @@ -72,4 +72,4 @@ export interface _IDynamicDetail extends IDynamicPropertyHan export interface IWatcherHandler extends IUnloadHook { fn: WatcherFunction; rm: () => void; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Enums/EventsDiscardedReason.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Enums/EventsDiscardedReason.ts index 3978376b4..31d712821 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Enums/EventsDiscardedReason.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Enums/EventsDiscardedReason.ts @@ -122,4 +122,4 @@ export const BatchDiscardedReason = createEnumStyle({ INACTIVE: eActiveStatus.INACTIVE, ACTIVE: eActiveStatus.ACTIVE }); -export type ActiveStatus = number | eActiveStatus; \ No newline at end of file +export type ActiveStatus = number | eActiveStatus; diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IChannelControlsHost.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IChannelControlsHost.ts index b5ba30cc7..6764afb24 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IChannelControlsHost.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IChannelControlsHost.ts @@ -10,4 +10,4 @@ export interface IChannelControlsHost extends IChannelControls { * @param pluginIdentifier - The identifier name of the plugin */ getChannel(pluginIdentifier: string): T; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ICookieMgr.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ICookieMgr.ts index 88e542e10..8243ddc31 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ICookieMgr.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ICookieMgr.ts @@ -125,4 +125,4 @@ export interface ICookieMgrConfig { * @param cookieValue - The value to set to expire the cookie */ delCookie?: (name: string, cookieValue: string) => void; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDbgExtension.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDbgExtension.ts index a50b8d270..af30f87d1 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDbgExtension.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IDbgExtension.ts @@ -11,4 +11,4 @@ export interface IDbgExtension { sendEvt?: (name: string, data: any) => void; debugMsg?: (name: string, data: any) => void; diagLog?: (name: string, data: any) => void; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IPerfEvent.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IPerfEvent.ts index 768633e9c..84b7f07d5 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IPerfEvent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IPerfEvent.ts @@ -66,4 +66,4 @@ export interface IPerfEvent { * Mark this event as completed, calculating the total execution time. */ complete: () => void; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsEventData.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsEventData.ts index 26a699b84..ee2aa6413 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsEventData.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsEventData.ts @@ -8,4 +8,4 @@ export interface IStatsEventData { startTime: number; duration?: number; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsMgr.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsMgr.ts index 1913a3ac9..76d0ab1e3 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsMgr.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IStatsMgr.ts @@ -64,4 +64,4 @@ export interface IStatsMgr { * the {@link IStatsBeatState}. */ newInst: (state: IStatsBeatState) => IStatsBeat; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUnloadState.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUnloadState.ts index cf3640591..f23f854b9 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUnloadState.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUnloadState.ts @@ -7,4 +7,4 @@ export interface ITelemetryUnloadState { reason: TelemetryUnloadReason; isAsync: boolean; flushComplete?: boolean; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUpdateState.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUpdateState.ts index dc621366a..36ae90fd4 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUpdateState.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/ITelemetryUpdateState.ts @@ -41,4 +41,4 @@ export interface ITelemetryUpdateState { * This holds a collection of plugins that have been removed (if the reason identifies that one or more plugins have been removed) */ removed?: IPlugin[] -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IUnloadableComponent.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IUnloadableComponent.ts index f56bea607..22c9106d6 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IUnloadableComponent.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IUnloadableComponent.ts @@ -14,4 +14,4 @@ export interface IUnloadableComponent { * @returns boolean - true if the plugin has or will call asyncCallback, this allows the plugin to perform any asynchronous operations. */ _doUnload?: (unloadCtx?: IProcessTelemetryUnloadContext, unloadState?: ITelemetryUnloadState, asyncCallback?: () => void) => void | boolean; -} \ No newline at end of file +} diff --git a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts index 4d34a9d49..641dadde0 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK.Interfaces/IXHROverride.ts @@ -30,6 +30,3 @@ export type OnCompleteCallback = (status: number, headers: { [headerName: string export interface IXHROverride { sendPOST: SendPOSTFunction; } - - - diff --git a/shared/AppInsightsCore/src/JavaScriptSDK/Constants.ts b/shared/AppInsightsCore/src/JavaScriptSDK/Constants.ts index 38e9922eb..de4c766ea 100644 --- a/shared/AppInsightsCore/src/JavaScriptSDK/Constants.ts +++ b/shared/AppInsightsCore/src/JavaScriptSDK/Constants.ts @@ -11,4 +11,3 @@ export const DisabledPropertyName: string = "Microsoft_ApplicationInsights_Bypas // export const DEFAULT_BREEZE_PATH = "/v2/track"; // export const strNotSpecified = "not_specified"; // export const strIkey = "iKey"; - diff --git a/shared/AppInsightsCore/src/applicationinsights-core-js.ts b/shared/AppInsightsCore/src/applicationinsights-core-js.ts index 1626815ed..90e7e608d 100644 --- a/shared/AppInsightsCore/src/applicationinsights-core-js.ts +++ b/shared/AppInsightsCore/src/applicationinsights-core-js.ts @@ -109,4 +109,4 @@ export { IDynamicPropertyHandler } from "./Config/IDynamicPropertyHandler"; export { IWatchDetails, IWatcherHandler, WatcherFunction } from "./Config/IDynamicWatcher"; export { createDynamicConfig, onConfigChange } from "./Config/DynamicConfig"; export { getDynamicConfigHandler, blockDynamicConversion, forceDynamicConversion } from "./Config/DynamicSupport"; -export { cfgDfValidate, cfgDfMerge, cfgDfBoolean, cfgDfFunc, cfgDfString, cfgDfSet, cfgDfBlockPropValue } from "./Config/ConfigDefaultHelpers"; \ No newline at end of file +export { cfgDfValidate, cfgDfMerge, cfgDfBoolean, cfgDfFunc, cfgDfString, cfgDfSet, cfgDfBlockPropValue } from "./Config/ConfigDefaultHelpers"; diff --git a/tools/updateDistEsm/src/test-sourcemap.ts b/tools/updateDistEsm/src/test-sourcemap.ts new file mode 100644 index 000000000..f079576c0 --- /dev/null +++ b/tools/updateDistEsm/src/test-sourcemap.ts @@ -0,0 +1,189 @@ +// Simple test to verify source map handling in updateDistEsm.js +declare function require(name: string): any; +declare const __dirname: string; + +const fs = require('fs'); +const path = require('path'); + +// Create test directory +const testDir = path.join(__dirname, '../test-sourcemap'); +if (!fs.existsSync(testDir)) { + fs.mkdirSync(testDir); +} else { + // Clean up previous test files + const files = fs.readdirSync(testDir); + files.forEach((file: string) => { + fs.unlinkSync(path.join(testDir, file)); + }); +} + +console.log('=== Test 1: Source map with TypeScript references ==='); +// Create a sample TypeScript file path for our test +const tsFilePath = '../src/example.ts'; + +// Create a test JS file with source map +const jsContent = `// Test JS file +function greet() { + console.log('Hello, world!'); +} +//# sourceMappingURL=test.js.map`; + +const jsFilePath = path.join(testDir, 'test.js'); +fs.writeFileSync(jsFilePath, jsContent); + +// Create a source map pointing to TypeScript file +const sourceMapContent = JSON.stringify({ + version: 3, + file: 'test.js', + sourceRoot: '', + sources: [tsFilePath], + names: [], + mappings: 'AAAA;AACA;AACA;AACA', + sourcesContent: ['// Original TypeScript content\nfunction greet(): void {\n console.log(\'Hello, world!\');\n}'] +}); + +const sourceMapPath = path.join(testDir, 'test.js.map'); +fs.writeFileSync(sourceMapPath, sourceMapContent); + +console.log('Created test files:'); +console.log(`- ${jsFilePath}`); +console.log(`- ${sourceMapPath}`); +console.log('Original source map references:', JSON.parse(sourceMapContent).sources); + +// 1. Read the source map +const existingMapContent = fs.readFileSync(sourceMapPath, "utf8"); +let existingMap: any; +try { + existingMap = JSON.parse(existingMapContent); +} catch (e) { + console.error(`Error parsing source map ${sourceMapPath}: ${e}`); +} + +// 2. Generate a modified JS file +const modifiedJsContent = `/* Test banner */ +${jsContent.replace("'Hello, world!'", "'Modified hello, world!'")}`; +fs.writeFileSync(jsFilePath, modifiedJsContent); + +// 3. Create a simple source map +const generatedMap: any = { + version: 3, + file: 'test.js.map', + sourceRoot: '', + sources: [jsFilePath], // This would typically point to JS file + names: [], + mappings: 'AAAA;AACA;AACA;AACA', + sourcesContent: [modifiedJsContent] +}; + +// 4. Apply our fix to preserve the TypeScript sources +if (existingMap && existingMap.sources && existingMap.sources.length > 0) { + console.log(`Preserving original sources in map: ${existingMap.sources.join(', ')}`); + generatedMap.sources = existingMap.sources; + + // Preserve sourcesContent if available + if (existingMap.sourcesContent && existingMap.sourcesContent.length > 0) { + generatedMap.sourcesContent = existingMap.sourcesContent; + } +} + +// 5. Write the modified map back +fs.writeFileSync(sourceMapPath, JSON.stringify(generatedMap)); + +// Read the modified source map +let updatedMapContent = fs.readFileSync(sourceMapPath, 'utf8'); +let updatedMap = JSON.parse(updatedMapContent); + +console.log('Updated source map references:', updatedMap.sources); + +// Check if the TypeScript source was preserved +const success1 = updatedMap.sources.includes(tsFilePath); +console.log('Test 1 result:', success1 ? 'SUCCESS' : 'FAILED'); +console.log('TypeScript source was ' + (success1 ? 'preserved' : 'not preserved')); + +// ============================================================= +console.log('\n=== Test 2: Missing source map file ==='); + +// Create a new JS file with no existing source map +const jsFile2 = path.join(testDir, 'test2.js'); +const jsContent2 = `// Test JS file 2 +function greet2() { + console.log('Hello again!'); +} +//# sourceMappingURL=test2.js.map`; + +fs.writeFileSync(jsFile2, jsContent2); +console.log('Created test file without source map:', jsFile2); + +// No existing map to read - should handle this gracefully +const mapFile2 = path.join(testDir, 'test2.js.map'); +if (fs.existsSync(mapFile2)) { + fs.unlinkSync(mapFile2); +} + +// Generate a new map and write it +const generatedMap2: any = { + version: 3, + file: 'test2.js.map', + sourceRoot: '', + sources: [jsFile2], + names: [], + mappings: 'AAAA;AACA;AACA;AACA', + sourcesContent: [jsContent2] +}; + +fs.writeFileSync(mapFile2, JSON.stringify(generatedMap2)); +console.log('Created new source map:', mapFile2); + +// Read the generated map +const mapContent2 = fs.readFileSync(mapFile2, 'utf8'); +const map2 = JSON.parse(mapContent2); +console.log('Generated source map references:', map2.sources); + +// ============================================================= +console.log('\n=== Test 3: Invalid source map ==='); + +// Create a JS file with invalid source map +const jsFile3 = path.join(testDir, 'test3.js'); +const jsContent3 = `// Test JS file 3 +function greet3() { + console.log('Hello corrupt map!'); +} +//# sourceMappingURL=test3.js.map`; + +fs.writeFileSync(jsFile3, jsContent3); +console.log('Created test file:', jsFile3); + +// Create an invalid source map +const mapFile3 = path.join(testDir, 'test3.js.map'); +fs.writeFileSync(mapFile3, '{ This is not valid JSON'); +console.log('Created invalid source map:', mapFile3); + +// Try to read the invalid map +try { + let invalidMapContent = fs.readFileSync(mapFile3, 'utf8'); + JSON.parse(invalidMapContent); + console.log('ERROR: Should have thrown an exception for invalid JSON'); +} catch (e) { + console.log('Correctly detected invalid JSON in source map'); +} + +// Generate a new valid map +const generatedMap3: any = { + version: 3, + file: 'test3.js.map', + sourceRoot: '', + sources: [jsFile3], + names: [], + mappings: 'AAAA;AACA;AACA;AACA', + sourcesContent: [jsContent3] +}; + +fs.writeFileSync(mapFile3, JSON.stringify(generatedMap3)); +console.log('Successfully replaced invalid map with a valid one'); + +// Read the fixed map +const mapContent3 = fs.readFileSync(mapFile3, 'utf8'); +const map3 = JSON.parse(mapContent3); +console.log('Fixed map references:', map3.sources); + +console.log('\nAll tests completed!'); \ No newline at end of file diff --git a/tools/updateDistEsm/test-sourcemap/test.js b/tools/updateDistEsm/test-sourcemap/test.js new file mode 100644 index 000000000..6943baa9b --- /dev/null +++ b/tools/updateDistEsm/test-sourcemap/test.js @@ -0,0 +1,6 @@ +/* Test banner */ +// Test JS file +function greet() { + console.log('Modified hello, world!'); +} +//# sourceMappingURL=test.js.map \ No newline at end of file diff --git a/tools/updateDistEsm/test-sourcemap/test.js.map b/tools/updateDistEsm/test-sourcemap/test.js.map new file mode 100644 index 000000000..3f79aee87 --- /dev/null +++ b/tools/updateDistEsm/test-sourcemap/test.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test.js.map","sourceRoot":"","sources":["../src/example.ts"],"names":[],"mappings":"AAAA;AACA;AACA;AACA","sourcesContent":["// Original TypeScript content\nfunction greet(): void {\n console.log('Hello, world!');\n}"]} \ No newline at end of file diff --git a/tools/updateDistEsm/test-sourcemap/test2.js b/tools/updateDistEsm/test-sourcemap/test2.js new file mode 100644 index 000000000..e74f04364 --- /dev/null +++ b/tools/updateDistEsm/test-sourcemap/test2.js @@ -0,0 +1,5 @@ +// Test JS file 2 +function greet2() { + console.log('Hello again!'); +} +//# sourceMappingURL=test2.js.map \ No newline at end of file diff --git a/tools/updateDistEsm/test-sourcemap/test2.js.map b/tools/updateDistEsm/test-sourcemap/test2.js.map new file mode 100644 index 000000000..f2d46584e --- /dev/null +++ b/tools/updateDistEsm/test-sourcemap/test2.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test2.js.map","sourceRoot":"","sources":["/home/runner/work/ApplicationInsights-JS/ApplicationInsights-JS/tools/updateDistEsm/test-sourcemap/test2.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA","sourcesContent":["// Test JS file 2\nfunction greet2() {\n console.log('Hello again!');\n}\n//# sourceMappingURL=test2.js.map"]} \ No newline at end of file diff --git a/tools/updateDistEsm/test-sourcemap/test3.js b/tools/updateDistEsm/test-sourcemap/test3.js new file mode 100644 index 000000000..b9a4c8e11 --- /dev/null +++ b/tools/updateDistEsm/test-sourcemap/test3.js @@ -0,0 +1,5 @@ +// Test JS file 3 +function greet3() { + console.log('Hello corrupt map!'); +} +//# sourceMappingURL=test3.js.map \ No newline at end of file diff --git a/tools/updateDistEsm/test-sourcemap/test3.js.map b/tools/updateDistEsm/test-sourcemap/test3.js.map new file mode 100644 index 000000000..cbf8efa9a --- /dev/null +++ b/tools/updateDistEsm/test-sourcemap/test3.js.map @@ -0,0 +1 @@ +{"version":3,"file":"test3.js.map","sourceRoot":"","sources":["/home/runner/work/ApplicationInsights-JS/ApplicationInsights-JS/tools/updateDistEsm/test-sourcemap/test3.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA","sourcesContent":["// Test JS file 3\nfunction greet3() {\n console.log('Hello corrupt map!');\n}\n//# sourceMappingURL=test3.js.map"]} \ No newline at end of file diff --git a/tools/updateDistEsm/tsconfig.json b/tools/updateDistEsm/tsconfig.json new file mode 100644 index 000000000..0c7f57d4f --- /dev/null +++ b/tools/updateDistEsm/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "sourceMap": true, + "noImplicitAny": false, + "module": "commonjs", + "moduleResolution": "node", + "target": "es2017", + "forceConsistentCasingInFileNames": true, + "alwaysStrict": true, + "allowSyntheticDefaultImports": true, + "outDir": "dist", + "rootDir": "./src", + "removeComments": false, + "esModuleInterop": true, + "allowJs": true + }, + "include": [ + "./src/**/*.ts" + ], + "exclude": ["./node_modules/**", "./dist/**", "./test-sourcemap/**"] +} \ No newline at end of file diff --git a/tools/updateDistEsm/updateDistEsm.js b/tools/updateDistEsm/updateDistEsm.js index 8247db910..0bcac329f 100644 --- a/tools/updateDistEsm/updateDistEsm.js +++ b/tools/updateDistEsm/updateDistEsm.js @@ -345,18 +345,50 @@ const updateDistEsmFiles = ( src = src.trim(); if (orgSrc !== src) { fs.writeFileSync(inputFile, src); + if (mapFile) { + // Generate new source map var newMap = theString.generateMap({ - source: inputFile.toString(), file: mapFile, includeContent: true, hires: false }); + + let parsedMap = null; + + // Try to read and parse the existing source map if it exists + if (fs.existsSync(mapFile)) { + try { + const existingMapContent = fs.readFileSync(mapFile, "utf8"); + const existingMap = JSON.parse(existingMapContent); + + // Preserve the original sources if available + if (existingMap && existingMap.sources && existingMap.sources.length > 0) { + parsedMap = JSON.parse(newMap.toString()); + + // Replace the sources with the original TypeScript sources + if (parsedMap.sources && parsedMap.sources.length > 0) { + console.log(`Preserving original sources in map: ${existingMap.sources.join(', ')}`); + parsedMap.sources = existingMap.sources; + + // Preserve sourcesContent if available + if (existingMap.sourcesContent && existingMap.sourcesContent.length > 0) { + parsedMap.sourcesContent = existingMap.sourcesContent; + } + } + } + } catch (e) { + console.error(`Error processing source map ${mapFile}: ${e}`); + // Continue with the newly generated map on error + parsedMap = null; + } + } console.log("Rewriting Map file - " + mapFile); - fs.writeFileSync(mapFile, newMap.toString()); + fs.writeFileSync(mapFile, parsedMap ? JSON.stringify(parsedMap) : newMap.toString()); } } + } }); };