├── pyproject.toml ├── LICENSE ├── .github └── workflows │ ├── test.yml │ └── release.yml ├── .gitignore ├── README.md ├── unwebpack_sourcemap.py └── poetry.lock /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "unwebpack-sourcemap" 3 | version = "0.0.0" 4 | description = "Recovers uncompiled TypeScript sources from Webpack sourcemaps. A fork of rarecoil's work." 5 | authors = ["James Mishra "] 6 | license = "MIT" 7 | readme = "README.md" 8 | packages = [{include = "unwebpack_sourcemap.py"}] 9 | 10 | [tool.poetry.dependencies] 11 | python = ">=3.8,<3.12" 12 | beautifulsoup4 = "4.7.1" 13 | certifi = ">=2022.12.7" 14 | chardet = "3.0.4" 15 | idna = "2.8" 16 | requests = "2.22.0" 17 | soupsieve = "*" 18 | urllib3 = "*" 19 | 20 | [tool.poetry.group.dev.dependencies] 21 | mypy = "^0.991" 22 | black = "^22.12.0" 23 | isort = "^5.11.4" 24 | pyinstaller = "^5.7.0" 25 | 26 | [build-system] 27 | requires = ["poetry-core"] 28 | build-backend = "poetry.core.masonry.api" 29 | 30 | [tool.poetry.scripts] 31 | unwebpack-sourcemap = "unwebpack_sourcemap:main" 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2023 James Mishra, rarecoil, and the unwebpack-sourcemap authors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | tags-ignore: 9 | - 'v*' # Don't run these tests twice when cutting a new version. 10 | 11 | jobs: 12 | test: 13 | runs-on: ${{ matrix.os }} 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | python-version: 18 | - "3.8" 19 | - "3.9" 20 | - "3.10" 21 | - "3.11" 22 | os: 23 | - "ubuntu-20.04" 24 | - "ubuntu-22.04" 25 | - "macos-11" 26 | - "macos-12" 27 | 28 | steps: 29 | - name: Check out the codebase. 30 | uses: actions/checkout@v3 31 | 32 | - name: Set up Node.js 16. 33 | uses: actions/setup-node@v3 34 | with: 35 | node-version: "16" 36 | 37 | - name: Set up Python. 38 | uses: actions/setup-python@v4 39 | with: 40 | python-version: ${{ matrix.python-version }} 41 | 42 | - name: Install pip and poetry. 43 | run: | 44 | python3 -m pip install --upgrade pip wheel poetry 45 | python3 -m poetry config virtualenvs.in-project true 46 | 47 | - name: Install unpackweb-sourcemap. 48 | run: | 49 | python3 -m poetry install 50 | 51 | - name: Download and build an example local app. 52 | run: | 53 | git clone https://github.com/vikpe/react-webpack-typescript-starter 54 | cd react-webpack-typescript-starter 55 | npm install 56 | npm run build 57 | cd .. 58 | 59 | - name: Get a source map from the local app. 60 | run: | 61 | python3 -m poetry run unwebpack-sourcemap --make-directory --local ./react-webpack-typescript-starter/dist/js/*.min.js.map local-dir 62 | 63 | - name: "Assume everything worked (TODO: add assertions)." 64 | run: echo ":)" 65 | 66 | - name: "Get a source map from a remote website (GitHub.com)." 67 | run: | 68 | python3 -m poetry run unwebpack-sourcemap --make-directory --detect https://github.com/ github-dir 69 | 70 | - name: "Assume everything worked (TODO: add assertions)." 71 | run: echo ":)" 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | 53 | # Translations 54 | *.mo 55 | *.pot 56 | 57 | # Django stuff: 58 | *.log 59 | local_settings.py 60 | db.sqlite3 61 | db.sqlite3-journal 62 | 63 | # Flask stuff: 64 | instance/ 65 | .webassets-cache 66 | 67 | # Scrapy stuff: 68 | .scrapy 69 | 70 | # Sphinx documentation 71 | docs/_build/ 72 | 73 | # PyBuilder 74 | target/ 75 | 76 | # Jupyter Notebook 77 | .ipynb_checkpoints 78 | 79 | # IPython 80 | profile_default/ 81 | ipython_config.py 82 | 83 | # pyenv 84 | .python-version 85 | 86 | # pipenv 87 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 88 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 89 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 90 | # install all needed dependencies. 91 | #Pipfile.lock 92 | 93 | # celery beat schedule file 94 | celerybeat-schedule 95 | 96 | # SageMath parsed files 97 | *.sage.py 98 | 99 | # Environments 100 | .env 101 | .venv 102 | env/ 103 | venv/ 104 | ENV/ 105 | env.bak/ 106 | venv.bak/ 107 | 108 | # Spyder project settings 109 | .spyderproject 110 | .spyproject 111 | 112 | # Rope project settings 113 | .ropeproject 114 | 115 | # mkdocs documentation 116 | /site 117 | 118 | # mypy 119 | .mypy_cache/ 120 | .dmypy.json 121 | dmypy.json 122 | 123 | # Pyre type checker 124 | .pyre/ 125 | 126 | .vscode/ 127 | output/ 128 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | defaults: 4 | run: 5 | shell: bash 6 | 7 | on: 8 | push: 9 | tags: 10 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 11 | 12 | permissions: 13 | contents: write 14 | 15 | jobs: 16 | release: 17 | runs-on: ${{ matrix.os }} 18 | strategy: 19 | fail-fast: true 20 | matrix: 21 | os: 22 | - "ubuntu-20.04" 23 | - "macos-11" 24 | 25 | steps: 26 | - name: Check out the codebase. 27 | uses: actions/checkout@v3 28 | 29 | - name: Set up Python 3.8. 30 | uses: actions/setup-python@v4 31 | with: 32 | python-version: "3.8" 33 | 34 | - name: Install pip and poetry. 35 | run: | 36 | python3 -m pip install --upgrade pip 37 | python3 -m pip install poetry 38 | python3 -m poetry config virtualenvs.in-project true 39 | 40 | - name: Install unpackweb-sourcemap. 41 | run: | 42 | python3 -m poetry install 43 | 44 | - name: Get the wheel version from the GitHub tag. 45 | id: get_version 46 | run: echo VERSION=${GITHUB_REF/refs\/tags\/v/} >> $GITHUB_OUTPUT 47 | 48 | - name: Build the Python wheel (Ubuntu only). 49 | id: publish_to_pypi 50 | run: | 51 | python3 -m poetry version ${{ steps.get_version.outputs.VERSION }} 52 | python3 -m poetry build 53 | if: startsWith(matrix.os,'ubuntu') 54 | 55 | - name: Build PyInstaller binary. 56 | id: build_pyinstaller_binary 57 | run: python3 -m poetry run pyinstaller --name=unwebpack-sourcemap-${{ steps.get_version.outputs.VERSION }}-${{ runner.os }}-${{ runner.arch }} --onefile --clean --noconfirm unwebpack_sourcemap.py 58 | 59 | - name: Create GitHub release and upload assets (Ubuntu). 60 | id: create_release_ubuntu 61 | uses: softprops/action-gh-release@v1 62 | with: 63 | name: Release v${{ steps.get_version.outputs.VERSION }} 64 | draft: false 65 | prerelease: false 66 | fail_on_unmatched_files: true 67 | files: | 68 | dist/unwebpack-sourcemap-* 69 | dist/unwebpack_sourcemap-${{ steps.get_version.outputs.VERSION }}*.whl 70 | dist/unwebpack_sourcemap-${{ steps.get_version.outputs.VERSION }}.tar.gz 71 | if: startsWith(matrix.os,'ubuntu') 72 | 73 | - name: Create GitHub release and upload assets (macOS). 74 | id: create_release_macos 75 | uses: softprops/action-gh-release@v1 76 | with: 77 | fail_on_unmatched_files: true 78 | append_body: true 79 | files: | 80 | dist/unwebpack-sourcemap-* 81 | if: startsWith(matrix.os,'macos') 82 | 83 | - name: Publish wheel to PyPI (Ubuntu only). 84 | id: publish_wheel_to_poetry 85 | run: python3 -m poetry publish -vvv --no-interaction 86 | if: startsWith(matrix.os,'ubuntu') 87 | env: 88 | POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # unwebpack-sourcemap 2 | 3 | ### Recover uncompiled TypeScript sources, JSX, and more from Webpack sourcemaps. 4 | 5 | This is a Python command line application that parses Webpack sourcemaps and returns uncompiled TypeScript sources. 6 | 7 | unwebpack-sourcemap can process source maps on the local filesystem, or it can discover source maps on a remote website. 8 | 9 | This repository is a fork. The original unwebpack-sourcemap was authored by [rarecoil][2]. 10 | 11 | ## Introduction 12 | If you're unfamiliar with source maps, you can read: 13 | * ["Introduction to JavaScript Source Maps"][5] by Google Chrome Developers 14 | * ["Use a source map"][6] by Firefox Source Docs 15 | 16 | ## Installation 17 | #### 1. Create a new Python virtualenv in a directory named `venv`. 18 | ``` 19 | python3 -m venv venv 20 | ``` 21 | 22 | #### 2. Activate the virtualenv. 23 | ``` 24 | source venv/bin/activate 25 | ``` 26 | 27 | #### 3. Install unwebpack-sourcemap from PyPI. 28 | ``` 29 | python3 -m pip install unwebpack-sourcemap 30 | ``` 31 | Note: unwebpack-sourcemap comes with Python dependencies that may conflict with the dependencies in your system installation of Python. That is why it is important to **always install unwebpack-sourcemap inside of a virtualenv,** 32 | which won't make any changes to your surrounding system. 33 | 34 | #### 4. Try running unwebpack-sourcemap. 35 | ``` 36 | unwebpack-sourcemap --help 37 | ``` 38 | 39 | The below examples assume that you are inside of an **activated virtualenv**. 40 | 41 | If you have installed unwebpack-sourcemap in a virtualenv, but want to avoid activating it, you can find the unwebpack-sourcemap command in the location `venv/bin/unwebpack-sourcemap`. 42 | 43 | ## Usage 44 | These examples use the `--make-directory` flag to create a subdirectory named `output_dir`. 45 | You can omit the `--make-directory` if you want to use an existing empty directory. 46 | 47 | #### Example #1: Unpacking a sourcemap on the local filesystem 48 | ``` 49 | unwebpack-sourcemap --make-directory --local /path/to/source.map output_dir 50 | ``` 51 | 52 | #### Example #2: Unpacking a sourcemap on a remote website 53 | ``` 54 | unwebpack-sourcemap --make-directory https://pathto.example.com/source.map output_dir 55 | ``` 56 | 57 | #### Example #3: Unpacking a sourcemap on a remote website (*with autodetection*) 58 | To attempt to read all `