{"id":13229,"library":"get-source","title":"Source Map Fetcher","description":"`get-source` is a JavaScript utility designed to fetch and resolve source-mapped source files in both Node.js and browser environments. Currently stable at version 2.0.12, it provides both synchronous and asynchronous APIs to read file contents and traverse sourcemap chains. Its core differentiating features include comprehensive sourcemap support—handling external, embedded, inline links, and long chains—and a built-in cache for performance. It's particularly useful for enhancing call stacks, advanced logging, and creating error display components in front-end development, as demonstrated by its use in libraries like `StackTracey` and `ololog`. The library ships with TypeScript types, making it suitable for modern JavaScript and TypeScript projects. While the synchronous API is designed not to throw errors, the asynchronous API utilizes standard Promise-based error handling.","status":"active","version":"2.0.12","language":"javascript","source_language":"en","source_url":"https://github.com/xpl/get-source","tags":["javascript","sources","sourcemap","read source","cached sources","typescript"],"install":[{"cmd":"npm install get-source","lang":"bash","label":"npm"},{"cmd":"yarn add get-source","lang":"bash","label":"yarn"},{"cmd":"pnpm add get-source","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This is the default export, primarily used for the synchronous API. Avoid named import or CommonJS require().","wrong":"import { getSource } from 'get-source'","symbol":"getSource","correct":"import getSource from 'get-source'"},{"note":"The asynchronous API is a property of the default export, not a separate named export. It returns awaitable Promises.","wrong":"import { async } from 'get-source'","symbol":"getSource.async","correct":"import getSource from 'get-source'; const asyncSource = getSource.async;"},{"note":"Cache reset functions are properties of the respective sync/async APIs. There are separate caches for sync and async operations.","wrong":"import { resetCache } from 'get-source'","symbol":"getSource.resetCache","correct":"import getSource from 'get-source'; getSource.resetCache(); getSource.async.resetCache();"}],"quickstart":{"code":"import getSource from 'get-source';\nimport fs from 'fs';\nimport path from 'path';\n\n// Simulate a minified file and its sourcemap for demonstration\nconst minifiedCodePath = path.resolve('./dist/index.min.js');\nconst minifiedMapPath = path.resolve('./dist/index.min.js.map');\nconst originalCodePath = path.resolve('./src/index.js');\n\n// In a real scenario, these files would exist or be fetched from a URL\nfs.mkdirSync(path.dirname(minifiedCodePath), { recursive: true });\nfs.writeFileSync(originalCodePath, 'console.log(\"Hello original source!\");\\nconst sum = (a, b) => a + b;');\nfs.writeFileSync(minifiedCodePath, 'console.log(\"Hello minified!\"); var a = 1, b = 2; console.log(a+b); //# sourceMappingURL=index.min.js.map');\nfs.writeFileSync(minifiedMapPath, JSON.stringify({\n  version: 3,\n  file: 'index.min.js',\n  sources: ['../src/index.js'],\n  sourcesContent: ['console.log(\"Hello original source!\");\\nconst sum = (a, b) => a + b;'],\n  names: [],\n  mappings: 'AAAA,aAAa;AAAb;AAAA,IAAM,KAAK,GAAG,IAAM,IAAI,EAAE,CAAC,GAAE,CAAC,MAAMA,EAAE,CAAC;AAAA,IAAM,MAAM,GAAG,CAAC,GAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAAA,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;AAAA,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAE,MAAM,CAAC;'\n}));\n\nasync function run() {\n  try {\n    // Fetch the minified file and its sourcemap asynchronously\n    const file = await getSource.async(minifiedCodePath);\n    console.log(`Fetched file: ${file.path}`);\n    console.log(`Minified text: ${file.text.substring(0, 50)}...`);\n\n    // Resolve a location in the minified file to its original source\n    // Example: The 'console.log(a+b)' statement is around line 1, column 50 in minified.\n    const location = await file.resolve({ line: 1, column: 50 });\n\n    if (location && location.sourceFile) {\n      console.log('\\nResolved original location:');\n      console.log(`  Original File: ${location.sourceFile.path}`);\n      console.log(`  Original Line: ${location.line}`);\n      console.log(`  Original Column: ${location.column}`);\n      console.log(`  Original Code: ${location.sourceLine}`);\n    } else {\n      console.log('Could not resolve location.');\n      if (file.error) console.error('Error during fetch:', file.error);\n    }\n  } catch (e) {\n    console.error('An error occurred:', e);\n  } finally {\n    // Clean up created files\n    fs.unlinkSync(minifiedCodePath);\n    fs.unlinkSync(minifiedMapPath);\n    fs.unlinkSync(originalCodePath);\n    fs.rmdirSync(path.dirname(minifiedCodePath));\n    fs.rmdirSync(path.dirname(originalCodePath));\n  }\n}\n\nrun();","lang":"typescript","description":"Demonstrates fetching a source-mapped file asynchronously and resolving a specific line/column to its original source location, including basic error handling."},"warnings":[{"fix":"Always check the `.error` property of the returned `file` object when using the synchronous API: `const file = getSource('./non-existent.js'); if (file.error) { console.error(file.error); }`","message":"The synchronous API (`getSource`) does not throw errors for operations like file not found or sourcemap parsing issues. Instead, it returns a file object where the `text` field will be an empty string and an `error` property will contain the `Error` object if an issue occurred.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Wrap asynchronous calls in `try...catch` blocks or handle Promise rejections using `.catch()`: `try { await getSource.async('./non-existent.js'); } catch (e) { console.error(e); }`","message":"The asynchronous API (`getSource.async`) throws errors for failed operations (e.g., file not found, network issues). This contrasts with the synchronous API's non-throwing behavior.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure that any `line` or `column` values originating from 0-indexed sources (like array indices) are incremented by 1 before being passed to `file.resolve()`.","message":"Line and column numbers passed to the `file.resolve()` method are 1-indexed (e.g., `line: 1`, `column: 8`). Providing 0-indexed values will result in invalid lookups or incorrect resolutions.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Use ES Module `import` syntax: `import getSource from 'get-source';` in your JavaScript files. Ensure your `package.json` has `\"type\": \"module\"` or your file is named `.mjs`.","cause":"Attempting to use CommonJS `require()` syntax to import `get-source` in a Node.js environment where it is treated as an ES Module.","error":"ERR_REQUIRE_ESM"},{"fix":"Always verify the returned `location` and its `sourceFile` property before accessing sub-properties: `const location = await file.resolve({ line: 1, column: 8 }); if (location && location.sourceFile) { console.log(location.sourceLine); } else { console.error('Could not resolve location.'); }`","cause":"Attempting to access properties of the `location` object returned by `file.resolve()` without checking if `location` itself is valid or if `location.sourceFile` exists, often because the original location could not be resolved (e.g., due to an invalid input line/column or malformed sourcemap).","error":"TypeError: Cannot read properties of undefined (reading 'sourceLine')"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}