├── .github └── workflows │ ├── build-dry-run-no-win.yml │ ├── build-dry-run.yml │ ├── build-supabase-artifacts.yml │ ├── build-wasm.yml │ ├── build.yml │ ├── generated-build-and-test.yaml │ ├── run-tests-linux.yml │ ├── run-tests-mac.yml │ └── run-tests-win.yml ├── .gitignore ├── .npmignore ├── .yamlize ├── config │ └── config.yaml └── workflows │ ├── build-and-publish.yaml │ ├── build-and-test.yaml │ └── yaml │ ├── artifacts │ ├── download.yaml │ ├── npm.yaml │ ├── prepare.yaml │ └── supabase.yaml │ ├── build-artifacts.yaml │ ├── build-wasm.yaml │ ├── emscripten │ ├── build.yaml │ └── install.yaml │ ├── git │ ├── checkout.yaml │ └── configure.yaml │ ├── node │ └── setup.yaml │ ├── prepare-and-log.yaml │ └── prepare-and-publish.yaml ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── binding.gyp ├── docker ├── Dockerfile └── readme.md ├── index.d.ts ├── index.js ├── libpg_query ├── include │ └── .gitkeep ├── linux │ └── .gitkeep ├── osx │ └── .gitkeep └── windows │ └── .gitkeep ├── package.json ├── queryparser.cc ├── script ├── buildAddon.bat ├── buildAddon.sh ├── clean.sh └── workflows.js ├── src ├── addon.cc ├── async.cc ├── async.h ├── helpers.cc ├── helpers.h ├── sync.cc └── sync.h ├── test ├── index.js └── webpack │ ├── .gitignore │ ├── dist │ └── index.html │ ├── package.json │ ├── src │ └── index.js │ ├── webpack.config.js │ └── yarn.lock ├── wasm └── index.js └── yarn.lock /.github/workflows/build-dry-run-no-win.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish Dry Run libpq-query no windows 🏗 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | make-release-candidate: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout Repository 📥 11 | uses: actions/checkout@v4 12 | 13 | - name: Setup Node.js 🌐 14 | uses: actions/setup-node@v4 15 | with: 16 | node-version: '20.x' 17 | cache: 'yarn' 18 | 19 | build-artifacts: 20 | needs: make-release-candidate 21 | runs-on: ${{ matrix.os }} 22 | strategy: 23 | matrix: 24 | os: [macos-latest, ubuntu-latest] 25 | steps: 26 | - name: Checkout Repository 📥 27 | uses: actions/checkout@v4 28 | 29 | - name: Setup Node.js 🌐 30 | uses: actions/setup-node@v4 31 | with: 32 | node-version: '20.x' 33 | cache: 'yarn' 34 | 35 | - name: Install and Build 📦 36 | run: | 37 | yarn 38 | yarn binary:build 39 | 40 | - name: Save Artifacts For Supabase CDN 🏗 41 | uses: actions/upload-artifact@v4 42 | with: 43 | name: build-supabase-artifact-${{ matrix.os }} 44 | path: './build/stage/libpg-query-node/' 45 | 46 | - name: Save Artifacts For NPM 🏗 47 | uses: actions/upload-artifact@v4 48 | with: 49 | name: build-npm-artifact-${{ matrix.os }} 50 | path: | 51 | ${{ matrix.os == 'macos-latest' && './libpg_query/osx/libpg_query.a' || 52 | matrix.os == 'ubuntu-latest' && './libpg_query/linux/libpg_query.a' }} 53 | 54 | build-wasm: 55 | needs: build-artifacts 56 | runs-on: ubuntu-latest 57 | steps: 58 | - name: Checkout Repository 📥 59 | uses: actions/checkout@v4 60 | 61 | - name: Setup Node.js 🌐 62 | uses: actions/setup-node@v4 63 | with: 64 | node-version: '20.x' 65 | cache: 'yarn' 66 | 67 | - name: Install and Build 🚀 68 | run: | 69 | yarn 70 | 71 | - name: Install Emscripten ✍🏻 72 | run: | 73 | sudo apt-get update 74 | sudo apt-get install cmake python3 python3-pip 75 | git clone --branch 3.1.59 --depth 1 https://github.com/emscripten-core/emsdk.git 76 | cd emsdk 77 | ./emsdk install 3.1.59 78 | ./emsdk activate 3.1.59 79 | source ./emsdk_env.sh 80 | 81 | - name: Build with Emscripten 🏗 82 | run: | 83 | source ./emsdk/emsdk_env.sh 84 | emmake make 85 | emmake make build 86 | 87 | - name: Archive production artifacts 🏛 88 | uses: actions/upload-artifact@v4 89 | with: 90 | name: wasm-artifacts 91 | path: wasm 92 | 93 | prepare-and-publish: 94 | needs: build-wasm 95 | runs-on: ubuntu-latest 96 | steps: 97 | - name: Checkout Repository 📥 98 | uses: actions/checkout@v4 99 | 100 | - name: Get Artifacts 📚 101 | uses: actions/download-artifact@v4 102 | with: 103 | path: downloaded-artifacts 104 | 105 | - name: Prepare artifacts 📦 106 | run: | 107 | find ./downloaded-artifacts/ 108 | cp ./downloaded-artifacts/build-npm-artifact-ubuntu-latest/libpg_query.a ./libpg_query/linux/libpg_query.a 109 | cp ./downloaded-artifacts/build-npm-artifact-macos-latest/libpg_query.a ./libpg_query/osx/libpg_query.a 110 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.js ./wasm/libpg-query.js 111 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.wasm ./wasm/libpg-query.wasm 112 | rm -rf ./downloaded-artifacts 113 | 114 | # - name: Setup AWS CLI 115 | # run: sudo apt-get update && sudo apt-get install awscli -y 116 | 117 | # - name: Configure AWS Credentials 118 | # uses: aws-actions/configure-aws-credentials@v4 119 | # with: 120 | # aws-access-key-id: ${{ secrets.SUPABASE_AWS_KEY }} 121 | # aws-secret-access-key: ${{ secrets.SUPABASE_AWS_SECRET }} 122 | # aws-region: us-east-1 123 | 124 | # - name: List Bucket Contents 125 | # run: aws s3 ls s3://supabase-public-artifacts-bucket/ 126 | 127 | # - name: Publish to NPM 🚀 128 | # run: | 129 | # npm publish 130 | # env: 131 | # NODE_AUTH_TOKEN: ${{secrets.NPM_API_KEY}} -------------------------------------------------------------------------------- /.github/workflows/build-dry-run.yml: -------------------------------------------------------------------------------- 1 | name: Build Dry Run 🏗 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-matrix: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [windows-latest, macos-latest, ubuntu-latest] 12 | steps: 13 | - name: Checkout Repository 📥 14 | uses: actions/checkout@v4 15 | 16 | - name: Setup Node.js 🌐 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: '20.x' 20 | cache: 'yarn' 21 | 22 | - name: Install Dependencies 🧶 23 | run: | 24 | yarn 25 | 26 | - name: Save Artifacts For NPM 🏗 27 | uses: actions/upload-artifact@v4 28 | with: 29 | name: build-artifact-${{ matrix.os }} 30 | path: | 31 | ${{ matrix.os == 'macos-latest' && './libpg_query/osx/libpg_query.a' || 32 | matrix.os == 'ubuntu-latest' && './libpg_query/linux/libpg_query.a' || 33 | matrix.os == 'windows-latest' && './libpg_query/windows/pg_query.lib' }} 34 | 35 | prepare-and-publish: 36 | needs: build-matrix 37 | runs-on: ubuntu-latest 38 | steps: 39 | - name: Checkout Repository 📥 40 | uses: actions/checkout@v4 41 | 42 | - name: Get Artifacts 📚 43 | uses: actions/download-artifact@v4 44 | with: 45 | path: downloaded-artifacts 46 | 47 | - name: Prepare artifacts 📦 48 | run: | 49 | cp ./downloaded-artifacts/build-artifact-windows-latest/pg_query.lib ./libpg_query/windows/queryparser.lib 50 | cp ./downloaded-artifacts/build-artifact-ubuntu-latest/libpg_query.a ./libpg_query/linux/libpg_query.a 51 | cp ./downloaded-artifacts/build-artifact-macos-latest/libpg_query.a ./libpg_query/osx/libpg_query.a 52 | rm -rf ./downloaded-artifacts 53 | find ./libpg_query 54 | 55 | # - name: Publish to NPM 🚀 56 | # run: | 57 | # # Assuming you've set up your package.json and .npmrc correctly 58 | # npm publish 59 | # env: 60 | -------------------------------------------------------------------------------- /.github/workflows/build-supabase-artifacts.yml: -------------------------------------------------------------------------------- 1 | name: Build Supabase Artifacts 🏗 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-matrix: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [windows-latest, macos-latest, ubuntu-latest] 12 | steps: 13 | - name: Checkout Repository 📥 14 | uses: actions/checkout@v4 15 | 16 | - name: Setup Node.js 🌐 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: '20.x' 20 | cache: 'yarn' 21 | 22 | - name: Configure AWS CLI for Supabase 23 | env: 24 | AWS_ACCESS_KEY_ID: ${{ secrets.SUPABASE_AWS_KEY }} 25 | AWS_SECRET_ACCESS_KEY: ${{ secrets.SUPABASE_AWS_SECRET }} 26 | AWS_EC2_METADATA_DISABLED: true 27 | run: | 28 | aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID --profile supabase-dev 29 | aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY --profile supabase-dev 30 | aws configure set region us-east-1 --profile supabase-dev 31 | 32 | - name: Install and Build Dependencies 🧶 33 | run: | 34 | yarn 35 | yarn binary:build 36 | 37 | - name: Publish binary 38 | env: 39 | AWS_ACCESS_KEY_ID: ${{ secrets.SUPABASE_ACCESS_KEY_ID }} 40 | AWS_SECRET_ACCESS_KEY: ${{ secrets.SUPABASE_SECRET_ACCESS_KEY }} 41 | AWS_REGION: 'us-east-1' 42 | run: yarn binary:publish -------------------------------------------------------------------------------- /.github/workflows/build-wasm.yml: -------------------------------------------------------------------------------- 1 | name: Build Wasm 🛠 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-wasm: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout Repository 📥 11 | uses: actions/checkout@v4 12 | 13 | - name: Setup Node.js 🌐 14 | uses: actions/setup-node@v4 15 | with: 16 | node-version: '20.x' 17 | cache: 'yarn' 18 | 19 | - name: Install and Build 🚀 20 | run: | 21 | yarn 22 | 23 | - name: Install Emscripten ✍🏻 24 | run: | 25 | sudo apt-get update 26 | sudo apt-get install cmake python3 python3-pip 27 | git clone --branch 3.1.59 --depth 1 https://github.com/emscripten-core/emsdk.git 28 | cd emsdk 29 | ./emsdk install 3.1.59 30 | ./emsdk activate 3.1.59 31 | source ./emsdk_env.sh 32 | 33 | - name: Build with Emscripten 🏗 34 | run: | 35 | source ./emsdk/emsdk_env.sh 36 | emmake make 37 | emmake make build 38 | 39 | - name: Archive production artifacts 🏛 40 | uses: actions/upload-artifact@v4 41 | with: 42 | name: compiled-files 43 | path: wasm -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish libpq-query 🏗 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | make-release-candidate: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout Repository 📥 11 | uses: actions/checkout@v4 12 | 13 | - name: Setup Node.js 🌐 14 | uses: actions/setup-node@v4 15 | with: 16 | node-version: '20.x' 17 | cache: 'yarn' 18 | 19 | - name: Configure Git 🛠 20 | run: | 21 | git config user.name "LaunchQL" 22 | git config user.email "developers@launchql.com" 23 | 24 | - name: Minor release candidate 🧪 25 | run: | 26 | git fetch 27 | npm version prerelease --preid=rc 28 | git push 29 | env: 30 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | 32 | build-artifacts: 33 | needs: make-release-candidate 34 | runs-on: ${{ matrix.os }} 35 | strategy: 36 | matrix: 37 | os: [windows-latest, macos-latest, ubuntu-latest] 38 | steps: 39 | - name: Checkout Repository 📥 40 | uses: actions/checkout@v4 41 | 42 | - name: Setup Node.js 🌐 43 | uses: actions/setup-node@v4 44 | with: 45 | node-version: '20.x' 46 | cache: 'yarn' 47 | 48 | - name: Install and Build 📦 49 | run: | 50 | yarn 51 | yarn binary:build 52 | 53 | - name: Save Artifacts For Supabase CDN 🏗 54 | uses: actions/upload-artifact@v4 55 | with: 56 | name: build-supabase-artifact-${{ matrix.os }} 57 | path: './build/stage/libpg-query-node/' 58 | 59 | - name: Save Artifacts For NPM 🏗 60 | uses: actions/upload-artifact@v4 61 | with: 62 | name: build-npm-artifact-${{ matrix.os }} 63 | path: | 64 | ${{ matrix.os == 'macos-latest' && './libpg_query/osx/libpg_query.a' || 65 | matrix.os == 'ubuntu-latest' && './libpg_query/linux/libpg_query.a' || 66 | matrix.os == 'windows-latest' && './libpg_query/windows/pg_query.lib' }} 67 | 68 | build-wasm: 69 | needs: build-artifacts 70 | runs-on: ubuntu-latest 71 | steps: 72 | - name: Checkout Repository 📥 73 | uses: actions/checkout@v4 74 | 75 | - name: Setup Node.js 🌐 76 | uses: actions/setup-node@v4 77 | with: 78 | node-version: '20.x' 79 | cache: 'yarn' 80 | 81 | - name: Install and Build 🚀 82 | run: | 83 | yarn 84 | 85 | - name: Install Emscripten ✍🏻 86 | run: | 87 | sudo apt-get update 88 | sudo apt-get install cmake python3 python3-pip 89 | git clone --branch 3.1.59 --depth 1 https://github.com/emscripten-core/emsdk.git 90 | cd emsdk 91 | ./emsdk install 3.1.59 92 | ./emsdk activate 3.1.59 93 | source ./emsdk_env.sh 94 | 95 | - name: Build with Emscripten 🏗 96 | run: | 97 | source ./emsdk/emsdk_env.sh 98 | emmake make 99 | emmake make build 100 | 101 | - name: Archive production artifacts 🏛 102 | uses: actions/upload-artifact@v4 103 | with: 104 | name: wasm-artifacts 105 | path: wasm 106 | 107 | prepare-and-publish: 108 | needs: build-wasm 109 | runs-on: ubuntu-latest 110 | steps: 111 | - name: Checkout Repository 📥 112 | uses: actions/checkout@v4 113 | 114 | - name: Get Artifacts 📚 115 | uses: actions/download-artifact@v4 116 | with: 117 | path: downloaded-artifacts 118 | 119 | - name: Prepare artifacts 📦 120 | run: | 121 | find ./downloaded-artifacts/ 122 | cp ./downloaded-artifacts/build-npm-artifact-windows-latest/pg_query.lib ./libpg_query/windows/queryparser.lib 123 | cp ./downloaded-artifacts/build-npm-artifact-ubuntu-latest/libpg_query.a ./libpg_query/linux/libpg_query.a 124 | cp ./downloaded-artifacts/build-npm-artifact-macos-latest/libpg_query.a ./libpg_query/osx/libpg_query.a 125 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.js ./wasm/libpg-query.js 126 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.wasm ./wasm/libpg-query.wasm 127 | rm -rf ./downloaded-artifacts 128 | 129 | # - name: Setup AWS CLI 130 | # run: sudo apt-get update && sudo apt-get install awscli -y 131 | 132 | # - name: Configure AWS Credentials 133 | # uses: aws-actions/configure-aws-credentials@v4 134 | # with: 135 | # aws-access-key-id: ${{ secrets.SUPABASE_AWS_KEY }} 136 | # aws-secret-access-key: ${{ secrets.SUPABASE_AWS_SECRET }} 137 | # aws-region: us-east-1 138 | 139 | # - name: List Bucket Contents 140 | # run: aws s3 ls s3://supabase-public-artifacts-bucket/ 141 | 142 | # - name: Publish to NPM 🚀 143 | # run: | 144 | # npm publish 145 | # env: 146 | # NODE_AUTH_TOKEN: ${{secrets.NPM_API_KEY}} -------------------------------------------------------------------------------- /.github/workflows/generated-build-and-test.yaml: -------------------------------------------------------------------------------- 1 | name: Build and Test 🛠 2 | 'on': 3 | workflow_dispatch: null 4 | jobs: 5 | build-artifacts: 6 | runs-on: ${{ matrix.os }} 7 | strategy: 8 | matrix: 9 | os: 10 | - windows-latest 11 | - macos-latest 12 | - ubuntu-latest 13 | steps: 14 | - name: Checkout Repository 📥 15 | uses: actions/checkout@v4 16 | - name: Setup Node.js 🌐 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: 20.x 20 | cache: yarn 21 | - name: Configure Git 🛠 22 | run: | 23 | git config user.name "Cosmology" 24 | git config user.email "developers@cosmology.zone" 25 | - name: Install and Build 📦 26 | run: | 27 | yarn 28 | yarn binary:build 29 | - name: Save Artifacts For Supabase CDN 🏗 30 | uses: actions/upload-artifact@v4 31 | with: 32 | name: build-supabase-artifact-${{ matrix.os }} 33 | path: ./build/stage/libpg-query-node/ 34 | - name: Save Artifacts For NPM 🏗 35 | uses: actions/upload-artifact@v4 36 | with: 37 | name: build-npm-artifact-${{ matrix.os }} 38 | path: | 39 | ${{ matrix.os == 'macos-latest' && './libpg_query/osx/libpg_query.a' || 40 | matrix.os == 'ubuntu-latest' && './libpg_query/linux/libpg_query.a' || 41 | matrix.os == 'windows-latest' && './libpg_query/windows/pg_query.lib' }} 42 | build-wasm: 43 | needs: build-artifacts 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Checkout Repository 📥 47 | uses: actions/checkout@v4 48 | - name: Setup Node.js 🌐 49 | uses: actions/setup-node@v4 50 | with: 51 | node-version: 20.x 52 | cache: yarn 53 | - name: Install and Build 🚀 54 | run: | 55 | yarn 56 | - name: Install Emscripten ✍🏻 57 | run: | 58 | sudo apt-get update 59 | sudo apt-get install cmake python3 python3-pip 60 | git clone --branch 3.1.59 --depth 1 https://github.com/emscripten-core/emsdk.git 61 | cd emsdk 62 | ./emsdk install 3.1.59 63 | ./emsdk activate 3.1.59 64 | source ./emsdk_env.sh 65 | - name: Build with Emscripten 🏗 66 | run: | 67 | source ./emsdk/emsdk_env.sh 68 | emmake make 69 | emmake make build 70 | - name: Archive production artifacts 🏛 71 | uses: actions/upload-artifact@v4 72 | with: 73 | name: wasm-artifacts 74 | path: wasm 75 | prepare-and-publish: 76 | needs: build-wasm 77 | runs-on: ubuntu-latest 78 | steps: 79 | - name: Checkout Repository 📥 80 | uses: actions/checkout@v4 81 | - name: Get Artifacts 📚 82 | uses: actions/download-artifact@v4 83 | with: 84 | path: downloaded-artifacts 85 | - name: Prepare artifacts 📦 86 | run: | 87 | find ./downloaded-artifacts/ 88 | cp ./downloaded-artifacts/build-npm-artifact-windows-latest/pg_query.lib ./libpg_query/windows/queryparser.lib 89 | cp ./downloaded-artifacts/build-npm-artifact-ubuntu-latest/libpg_query.a ./libpg_query/linux/libpg_query.a 90 | cp ./downloaded-artifacts/build-npm-artifact-macos-latest/libpg_query.a ./libpg_query/osx/libpg_query.a 91 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.js ./wasm/libpg-query.js 92 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.wasm ./wasm/libpg-query.wasm 93 | rm -rf ./downloaded-artifacts 94 | - name: Log 95 | run: | 96 | find ./libpg_query/ 97 | find ./wasm 98 | -------------------------------------------------------------------------------- /.github/workflows/run-tests-linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux 🧪 2 | 3 | on: 4 | pull_request: 5 | types: [opened, push, reopened] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | run-tests: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout Repository 📥 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Node.js 🌐 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: '20.x' 19 | cache: 'yarn' 20 | 21 | - name: Install Dependencies 🧶 22 | run: | 23 | yarn 24 | 25 | - name: Test 🔍 26 | run: yarn test -------------------------------------------------------------------------------- /.github/workflows/run-tests-mac.yml: -------------------------------------------------------------------------------- 1 | name: Mac 🧪 2 | 3 | on: 4 | pull_request: 5 | types: [opened, push, reopened] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | run-tests: 10 | runs-on: macos-latest 11 | steps: 12 | - name: Checkout Repository 📥 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Node.js 🌐 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: '20.x' 19 | cache: 'yarn' 20 | 21 | - name: Install Dependencies 🧶 22 | run: | 23 | yarn 24 | 25 | - name: Test 🔍 26 | run: yarn test -------------------------------------------------------------------------------- /.github/workflows/run-tests-win.yml: -------------------------------------------------------------------------------- 1 | name: Windows 🛠 2 | 3 | on: 4 | pull_request: 5 | types: [opened, push, reopened] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build-windows: 10 | runs-on: windows-latest 11 | steps: 12 | - name: Checkout Repository 📥 13 | uses: actions/checkout@v4 14 | 15 | - name: Setup Node.js 🌐 16 | uses: actions/setup-node@v4 17 | with: 18 | node-version: '20.x' 19 | cache: 'yarn' 20 | 21 | - name: Install Dependencies 🧶 22 | run: | 23 | yarn 24 | 25 | # - name: Test 🔍 26 | # run: yarn test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | libs/ 4 | npm-debug.log 5 | libpg_query/**/*.a 6 | libpg_query/**/*.h 7 | wasm/libpg-query.js 8 | *.wasm 9 | .cache 10 | libpg_query/windows/*.lib -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # project files 2 | test 3 | .gitignore 4 | .travis.yml 5 | package.json 6 | build 7 | docker 8 | libpg_query/**/*.a 9 | libpg_query/**/*.h 10 | 11 | *.log 12 | npm-debug.log* 13 | 14 | # Dependency directories 15 | node_modules 16 | 17 | # npm package lock 18 | package-lock.json 19 | yarn.lock 20 | 21 | -------------------------------------------------------------------------------- /.yamlize/config/config.yaml: -------------------------------------------------------------------------------- 1 | git: 2 | USER_NAME: Cosmology 3 | USER_EMAIL: developers@cosmology.zone 4 | EMSCRIPTEN_VERSION: '3.1.59' 5 | NODE_VERSION: '20.x' 6 | -------------------------------------------------------------------------------- /.yamlize/workflows/build-and-publish.yaml: -------------------------------------------------------------------------------- 1 | name: Build and Publish 🚀 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-artifacts: 8 | import-yaml: yaml/build-artifacts.yaml 9 | 10 | build-wasm: 11 | needs: build-artifacts 12 | import-yaml: yaml/build-wasm.yaml 13 | 14 | prepare-and-publish: 15 | needs: build-wasm 16 | import-yaml: yaml/prepare-and-publish.yaml -------------------------------------------------------------------------------- /.yamlize/workflows/build-and-test.yaml: -------------------------------------------------------------------------------- 1 | name: Build and Test 🛠 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | build-artifacts: 8 | import-yaml: yaml/build-artifacts.yaml 9 | 10 | build-wasm: 11 | needs: build-artifacts 12 | import-yaml: yaml/build-wasm.yaml 13 | 14 | prepare-and-publish: 15 | needs: build-wasm 16 | import-yaml: yaml/prepare-and-log.yaml -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/artifacts/download.yaml: -------------------------------------------------------------------------------- 1 | name: Get Artifacts 📚 2 | uses: actions/download-artifact@v4 3 | with: 4 | path: downloaded-artifacts -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/artifacts/npm.yaml: -------------------------------------------------------------------------------- 1 | name: Save Artifacts For NPM 🏗 2 | uses: actions/upload-artifact@v4 3 | with: 4 | name: build-npm-artifact-${{ matrix.os }} 5 | path: | 6 | ${{ matrix.os == 'macos-latest' && './libpg_query/osx/libpg_query.a' || 7 | matrix.os == 'ubuntu-latest' && './libpg_query/linux/libpg_query.a' || 8 | matrix.os == 'windows-latest' && './libpg_query/windows/pg_query.lib' }} -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/artifacts/prepare.yaml: -------------------------------------------------------------------------------- 1 | name: Prepare artifacts 📦 2 | run: | 3 | find ./downloaded-artifacts/ 4 | cp ./downloaded-artifacts/build-npm-artifact-windows-latest/pg_query.lib ./libpg_query/windows/queryparser.lib 5 | cp ./downloaded-artifacts/build-npm-artifact-ubuntu-latest/libpg_query.a ./libpg_query/linux/libpg_query.a 6 | cp ./downloaded-artifacts/build-npm-artifact-macos-latest/libpg_query.a ./libpg_query/osx/libpg_query.a 7 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.js ./wasm/libpg-query.js 8 | cp ./downloaded-artifacts/wasm-artifacts/libpg-query.wasm ./wasm/libpg-query.wasm 9 | rm -rf ./downloaded-artifacts 10 | -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/artifacts/supabase.yaml: -------------------------------------------------------------------------------- 1 | name: Save Artifacts For Supabase CDN 🏗 2 | uses: actions/upload-artifact@v4 3 | with: 4 | name: build-supabase-artifact-${{ matrix.os }} 5 | path: './build/stage/libpg-query-node/' 6 | -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/build-artifacts.yaml: -------------------------------------------------------------------------------- 1 | runs-on: ${{ matrix.os }} 2 | strategy: 3 | matrix: 4 | os: [windows-latest, macos-latest, ubuntu-latest] 5 | steps: 6 | - import-yaml: git/checkout.yaml 7 | - import-yaml: node/setup.yaml 8 | - import-yaml: git/configure.yaml 9 | 10 | - name: Install and Build 📦 11 | run: | 12 | yarn 13 | yarn binary:build 14 | 15 | - import-yaml: artifacts/supabase.yaml 16 | - import-yaml: artifacts/npm.yaml -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/build-wasm.yaml: -------------------------------------------------------------------------------- 1 | runs-on: ubuntu-latest 2 | steps: 3 | - import-yaml: git/checkout.yaml 4 | 5 | - import-yaml: node/setup.yaml 6 | 7 | - name: Install and Build 🚀 8 | run: | 9 | yarn 10 | 11 | - import-yaml: emscripten/install.yaml 12 | 13 | - import-yaml: emscripten/build.yaml 14 | 15 | - name: Archive production artifacts 🏛 16 | uses: actions/upload-artifact@v4 17 | with: 18 | name: wasm-artifacts 19 | path: wasm 20 | -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/emscripten/build.yaml: -------------------------------------------------------------------------------- 1 | name: Build with Emscripten 🏗 2 | run: | 3 | source ./emsdk/emsdk_env.sh 4 | emmake make 5 | emmake make build 6 | -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/emscripten/install.yaml: -------------------------------------------------------------------------------- 1 | name: Install Emscripten ✍🏻 2 | run: | 3 | sudo apt-get update 4 | sudo apt-get install cmake python3 python3-pip 5 | git clone --branch ${{yamlize.EMSCRIPTEN_VERSION}} --depth 1 https://github.com/emscripten-core/emsdk.git 6 | cd emsdk 7 | ./emsdk install ${{yamlize.EMSCRIPTEN_VERSION}} 8 | ./emsdk activate ${{yamlize.EMSCRIPTEN_VERSION}} 9 | source ./emsdk_env.sh -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/git/checkout.yaml: -------------------------------------------------------------------------------- 1 | name: Checkout Repository 📥 2 | uses: actions/checkout@v4 -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/git/configure.yaml: -------------------------------------------------------------------------------- 1 | name: Configure Git 🛠 2 | run: | 3 | git config user.name "${{yamlize.git.USER_NAME}}" 4 | git config user.email "${{yamlize.git.USER_EMAIL}}" 5 | -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/node/setup.yaml: -------------------------------------------------------------------------------- 1 | name: Setup Node.js 🌐 2 | uses: actions/setup-node@v4 3 | with: 4 | node-version: ${{yamlize.NODE_VERSION}} 5 | cache: 'yarn' -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/prepare-and-log.yaml: -------------------------------------------------------------------------------- 1 | runs-on: ubuntu-latest 2 | steps: 3 | - import-yaml: git/checkout.yaml 4 | 5 | - import-yaml: artifacts/download.yaml 6 | 7 | - import-yaml: artifacts/prepare.yaml 8 | 9 | - name: Log 10 | run: | 11 | find ./libpg_query/ 12 | find ./wasm 13 | -------------------------------------------------------------------------------- /.yamlize/workflows/yaml/prepare-and-publish.yaml: -------------------------------------------------------------------------------- 1 | runs-on: ubuntu-latest 2 | steps: 3 | - import-yaml: git/checkout.yaml 4 | 5 | - import-yaml: artifacts/download.yaml 6 | 7 | - import-yaml: artifacts/prepare.yaml 8 | 9 | - name: Publish to NPM 🚀 10 | run: | 11 | npm publish 12 | env: 13 | NODE_AUTH_TOKEN: ${{secrets.NPM_API_KEY}} -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.2.1 2 | * Rename package 3 | 4 | # 1.2.0 5 | * Add TS typings 6 | 7 | # 1.1.2 (07/23/19) 8 | * Fix build script 9 | 10 | # 1.1.0 (Republish, 07/23/19) 11 | * Rewrite to use Node-Addons-API (C++ wrapper for the stable N-API) 12 | * Support PL/PGSql Parsing 13 | * Support async parsing 14 | 15 | ## 0.0.5 (November 19, 2015) 16 | * Update libpg_query to include latest A_CONST fixes 17 | 18 | ## 0.0.4 (November 16, 2015) 19 | * Update libpg_query to include fix for empty string constants 20 | * Warning fixed in 0.0.3 is back for now until libpg_query has support for custom CFLAGS 21 | 22 | ## 0.0.3 (November 14, 2015) 23 | * Update OSX static library to include `-mmacosx-version-min=10.5` to fix warnings on installation 24 | 25 | ## 0.0.2 (November 14, 2015) 26 | * Rename repo to pg-query-native 27 | 28 | ## 0.0.1 (November 14, 2015) 29 | * First version 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Dan Lynch 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | WASM_OUT_DIR := wasm 2 | WASM_OUT_NAME := libpg-query 3 | WASM_MODULE_NAME := PgQueryModule 4 | LIBPG_QUERY_REPO := https://github.com/pganalyze/libpg_query.git 5 | LIBPG_QUERY_TAG := 16-5.1.0 6 | CACHE_DIR := .cache 7 | 8 | OS ?= $(shell uname -s) 9 | ARCH ?= $(shell uname -m) 10 | 11 | ifdef EMSCRIPTEN 12 | PLATFORM := emscripten 13 | else ifeq ($(OS),Darwin) 14 | PLATFORM := darwin 15 | else ifeq ($(OS),Linux) 16 | PLATFORM := linux 17 | else 18 | $(error Unsupported platform: $(OS)) 19 | endif 20 | 21 | ifdef EMSCRIPTEN 22 | ARCH := wasm 23 | endif 24 | 25 | PLATFORM_ARCH := $(PLATFORM)-$(ARCH) 26 | SRC_FILES := $(wildcard src/*.cc) 27 | LIBPG_QUERY_DIR := $(CACHE_DIR)/$(PLATFORM_ARCH)/libpg_query/$(LIBPG_QUERY_TAG) 28 | LIBPG_QUERY_ARCHIVE := $(LIBPG_QUERY_DIR)/libpg_query.a 29 | LIBPG_QUERY_HEADER := $(LIBPG_QUERY_DIR)/pg_query.h 30 | CXXFLAGS := -O3 31 | 32 | ifdef EMSCRIPTEN 33 | OUT_FILES := $(foreach EXT,.js .wasm,$(WASM_OUT_DIR)/$(WASM_OUT_NAME)$(EXT)) 34 | else 35 | OUT_FILES := build/Release/queryparser.node $(wildcard build/*) 36 | endif 37 | 38 | # Clone libpg_query source (lives in CACHE_DIR) 39 | $(LIBPG_QUERY_DIR): 40 | mkdir -p $(CACHE_DIR) 41 | git clone -b $(LIBPG_QUERY_TAG) --single-branch $(LIBPG_QUERY_REPO) $(LIBPG_QUERY_DIR) 42 | 43 | $(LIBPG_QUERY_HEADER): $(LIBPG_QUERY_DIR) 44 | 45 | # Build libpg_query 46 | $(LIBPG_QUERY_ARCHIVE): $(LIBPG_QUERY_DIR) 47 | cd $(LIBPG_QUERY_DIR); $(MAKE) build 48 | 49 | # Build libpg-query-node (based on platform) 50 | $(OUT_FILES): $(LIBPG_QUERY_ARCHIVE) $(LIBPG_QUERY_HEADER) $(SRC_FILES) 51 | ifdef EMSCRIPTEN 52 | @ $(CXX) \ 53 | $(CXXFLAGS) \ 54 | -DNAPI_HAS_THREADS \ 55 | -I$(LIBPG_QUERY_DIR) \ 56 | -I./node_modules/emnapi/include \ 57 | -I./node_modules/node-addon-api \ 58 | -L./node_modules/emnapi/lib/wasm32-emscripten \ 59 | -L$(LIBPG_QUERY_DIR) \ 60 | --js-library=./node_modules/emnapi/dist/library_napi.js \ 61 | -sEXPORTED_FUNCTIONS="['_malloc','_free','_napi_register_wasm_v1','_node_api_module_get_api_version_v1']" \ 62 | -sEXPORT_NAME="$(WASM_MODULE_NAME)" \ 63 | -sENVIRONMENT="web" \ 64 | -sMODULARIZE=1 \ 65 | -sEXPORT_ES6=1 \ 66 | -fexceptions \ 67 | -lpg_query \ 68 | -lemnapi-basic \ 69 | -o $@ \ 70 | $(SRC_FILES) 71 | else 72 | # if not wasm, defer to node-gyp 73 | yarn rebuild 74 | endif 75 | 76 | # Commands 77 | build: $(OUT_FILES) 78 | 79 | build-cache: $(LIBPG_QUERY_ARCHIVE) $(LIBPG_QUERY_HEADER) 80 | 81 | rebuild: clean build 82 | 83 | rebuild-cache: clean-cache build-cache 84 | 85 | clean: 86 | -@ rm -r $(OUT_FILES) > /dev/null 2>&1 87 | 88 | clean-cache: 89 | -@ rm -rf $(LIBPG_QUERY_DIR) 90 | 91 | .PHONY: build build-cache rebuild rebuild-cache clean clean-cache 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libpg-query 2 | 3 |

4 | webincubator 5 |

6 | 7 |

8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |

23 | 24 | The real PostgreSQL parser, exposed for nodejs. 25 | 26 | Primarily used for the node.js parser and deparser [pgsql-parser](https://github.com/pyramation/pgsql-parser) 27 | 28 | 29 | ## Table of Contents 30 | 31 | 1. [Installation](#installation) 32 | 2. [Example](#example) 33 | 5. [Documentation](#documentation) 34 | 3. [Versions](#versions) 35 | 4. [Building a binary distribution](#building-a-binary-distribution) 36 | 6. [Related Projects](#related-projects) 37 | 7. [Credit](#credit) 38 | 39 | 40 | ## Installation 41 | 42 | ```sh 43 | npm install libpg-query 44 | ``` 45 | 46 | ## Example 47 | 48 | ```js 49 | const parser = require('libpg-query'); 50 | parser.parseQuery('select 1').then(console.log); 51 | ``` 52 | 53 | ### Documentation 54 | 55 | ### `query.parseQuery(sql)`/`parseQuerySync` 56 | 57 | Parses the sql and returns a Promise for the parse tree (or returns the parse tree directly in the sync version). May reject with/throw a parse error. 58 | 59 | The return value is an array, as multiple queries may be provided in a single string (semicolon-delimited, as Postgres expects). 60 | 61 | ### `query.parsePlPgSQL(funcsSql)`/`query.parsePlPgSQLSync(funcsSql)` 62 | 63 | Parses the contents of a PL/PGSql function, from a `CREATE FUNCTION` declaration, and returns a Promise for the parse tree (or returns the parse tree directly in the sync version). May reject with/throw a parse error. 64 | 65 | ## Versions 66 | 67 | Our latest is built with `16-latest` branch from libpg_query 68 | 69 | 70 | | PG Major Version | libpg_query | Branch | npm 71 | |--------------------------|-------------|------------------------------------------------------------------------------------------------|---------| 72 | | 16 | 16-latest | [`16-latest`](https://github.com/launchql/libpg-query-node/tree/16-latest) | [`libpg-query@16.2.0`](https://www.npmjs.com/package/libpg-query/v/latest) 73 | | 15 | 15-latest | [`15-latest`](https://github.com/launchql/libpg-query-node/tree/15-latest) | [`libpg-query@15.1.0`](https://www.npmjs.com/package/libpg-query/v/15.1.0) 74 | | 14 | 14-latest | [`14-latest`](https://github.com/launchql/libpg-query-node/tree/14-latest) | [`libpg-query@14.0.0`](https://www.npmjs.com/package/libpg-query/v/14.0.0) 75 | | 13 | 13-latest | [`13-latest`](https://github.com/launchql/libpg-query-node/tree/13-latest) | [`libpg-query@13.3.1`](https://www.npmjs.com/package/libpg-query/v/13.3.1) 76 | | 12 | (n/a) | | 77 | | 11 | (n/a) | | 78 | | 10 | 10-latest | | `@1.3.1` ([tree](https://github.com/pyramation/pgsql-parser/tree/39b7b1adc8914253226e286a48105785219a81ca)) | 79 | 80 | 81 | ## Building a binary distribution 82 | 83 | - Install requirements (`npm i`) 84 | - `npx node-pre-gyp rebuild package` 85 | - With appropriate AWS credentials configured, `npx node-pre-gyp publish` 86 | 87 | Or you can run the scripts 88 | 89 | ``` 90 | npm run binary:build 91 | npm run binary:publish 92 | ``` 93 | 94 | ## Related Projects 95 | 96 | * [libpg_query](https://github.com/pganalyze/libpg_query) 97 | * [pgsql-parser](https://github.com/pyramation/pgsql-parser) 98 | * [pg_query](https://github.com/lfittl/pg_query) 99 | * [pg_query.go](https://github.com/lfittl/pg_query.go) 100 | 101 | ## Credit 102 | 103 | This is based on the output of [libpg_query](https://github.com/pganalyze/libpg_query). This wraps the static library output and links it into a node module for use in js. 104 | 105 | All credit for the hard problems goes to [Lukas Fittl](https://github.com/lfittl). 106 | 107 | Additional thanks for node binding [Ethan Resnick](https://github.com/ethanresnick). 108 | 109 | Original [Code](https://github.com/zhm/node-pg-query-native) and [License](https://github.com/zhm/node-pg-query-native/blob/master/LICENSE.md) 110 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "target_name": "queryparser", 5 | "sources": [ 6 | "src/addon.cc", 7 | "src/helpers.cc", 8 | "src/sync.cc", 9 | "src/async.cc" 10 | ], 11 | 'cflags!': [ '-fno-exceptions' ], 12 | 'cflags_cc!': [ '-fno-exceptions' ], 13 | 'include_dirs': [ 14 | "libpg_query/include", 15 | "; 2 | export function parsePlPgSQL(funcsSql: string): Promise; 3 | export function parseQuerySync(sql: string): any; 4 | export function parsePlPgSQLSync(funcsSql: string): any; 5 | export function fingerprint(sql: string): Promise; 6 | export function fingerprintSync(sql: string): string; 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const PgQuery = require('./build/Release/queryparser.node'); 2 | 3 | module.exports = { 4 | parseQuery(query) { 5 | return new Promise((resolve, reject) => { 6 | PgQuery.parseQueryAsync(query, (err, result) => { 7 | err ? reject(err) : resolve(JSON.parse(result)); 8 | }); 9 | }); 10 | }, 11 | 12 | parsePlPgSQL(query) { 13 | return new Promise((resolve, reject) => { 14 | PgQuery.parsePlPgSQLAsync(query, (err, result) => { 15 | err ? reject(err) : resolve(JSON.parse(result)); 16 | }); 17 | }); 18 | }, 19 | 20 | parseQuerySync(query) { 21 | return JSON.parse(PgQuery.parseQuerySync(query)); 22 | }, 23 | 24 | parsePlPgSQLSync(query) { 25 | return JSON.parse(PgQuery.parsePlPgSQLSync(query)); 26 | }, 27 | 28 | fingerprint(query) { 29 | return new Promise((resolve, reject) => { 30 | PgQuery.fingerprintAsync(query, (err, result) => { 31 | err ? reject(err) : resolve(result); 32 | }); 33 | }); 34 | }, 35 | 36 | fingerprintSync(query) { 37 | return PgQuery.fingerprintSync(query); 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /libpg_query/include/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/launchql/libpg-query-node/fd3f29be67f2dadc2458b8b4cef23552e68b7620/libpg_query/include/.gitkeep -------------------------------------------------------------------------------- /libpg_query/linux/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/launchql/libpg-query-node/fd3f29be67f2dadc2458b8b4cef23552e68b7620/libpg_query/linux/.gitkeep -------------------------------------------------------------------------------- /libpg_query/osx/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/launchql/libpg-query-node/fd3f29be67f2dadc2458b8b4cef23552e68b7620/libpg_query/osx/.gitkeep -------------------------------------------------------------------------------- /libpg_query/windows/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/launchql/libpg-query-node/fd3f29be67f2dadc2458b8b4cef23552e68b7620/libpg_query/windows/.gitkeep -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "libpg-query", 3 | "version": "16.3.0", 4 | "description": "The real PostgreSQL query parser", 5 | "homepage": "https://github.com/launchql/libpg-query-node", 6 | "main": "index.js", 7 | "typings": "index.d.ts", 8 | "publishConfig": { 9 | "access": "public" 10 | }, 11 | "files": [ 12 | "binding.gyp", 13 | "index.js", 14 | "index.d.ts", 15 | "libpg_query/*", 16 | "script/*", 17 | "src/*", 18 | "wasm/*" 19 | ], 20 | "exports": { 21 | ".": { 22 | "types": "./index.d.ts", 23 | "browser": "./wasm/index.js", 24 | "node": "./index.js", 25 | "default": "./index.js" 26 | }, 27 | "./wasm": { 28 | "types": "./index.d.ts", 29 | "default": "./wasm/index.js" 30 | } 31 | }, 32 | "scripts": { 33 | "clean": "rimraf build", 34 | "configure": "node-pre-gyp configure", 35 | "install": "node-pre-gyp install --fallback-to-build --loglevel verbose", 36 | "rebuild": "node-pre-gyp rebuild --loglevel verbose", 37 | "make:wasm": "docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emmake make", 38 | "build:wasm": "yarn make:wasm build", 39 | "rebuild:wasm": "yarn make:wasm rebuild", 40 | "clean:wasm": "yarn make:wasm clean", 41 | "clean-cache:wasm": "yarn make:wasm clean-cache", 42 | "workflows": "node script/workflows.js", 43 | "test": "mocha --timeout 5000", 44 | "binary:build": "node-pre-gyp rebuild package", 45 | "binary:publish": "AWS_PROFILE=supabase-dev node-pre-gyp publish" 46 | }, 47 | "author": "Dan Lynch (http://github.com/pyramation)", 48 | "license": "MIT", 49 | "repository": { 50 | "type": "git", 51 | "url": "git://github.com/launchql/libpg-query-node.git" 52 | }, 53 | "devDependencies": { 54 | "@yamlize/cli": "^0.8.0", 55 | "chai": "^3.5.0", 56 | "emnapi": "^0.43.1", 57 | "lodash": "^4.17.15", 58 | "mocha": "^5.2.0", 59 | "rimraf": "5.0.0" 60 | }, 61 | "dependencies": { 62 | "@emnapi/runtime": "^0.43.1", 63 | "@mapbox/node-pre-gyp": "^1.0.8", 64 | "node-addon-api": "^7.0.0", 65 | "node-gyp": "^10.0.1" 66 | }, 67 | "keywords": [ 68 | "sql", 69 | "postgres", 70 | "postgresql", 71 | "pg", 72 | "query", 73 | "plpgsql", 74 | "database" 75 | ], 76 | "binary": { 77 | "module_name": "queryparser", 78 | "module_path": "./build/Release/", 79 | "host": "https://gnbyoxcowpfpalflhptv.supabase.co/storage/v1/s3", 80 | "remote_path": "./libpg-query-node/", 81 | "bucket": "public-artifacts", 82 | "region": "us-east-1", 83 | "s3ForcePathStyle": true 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /queryparser.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "pg_query.h" 4 | #include 5 | 6 | using namespace v8; 7 | 8 | Local CreateError(Isolate* isolate, const PgQueryError& err) 9 | { 10 | v8::EscapableHandleScope handleScope(isolate); 11 | Local error = Object::New(isolate); 12 | 13 | error->Set(String::NewFromUtf8(isolate, "message"), String::NewFromUtf8(isolate, err.message)); 14 | error->Set(String::NewFromUtf8(isolate, "fileName"), String::NewFromUtf8(isolate, err.filename)); 15 | error->Set(String::NewFromUtf8(isolate, "functionName"), String::NewFromUtf8(isolate, err.funcname)); 16 | error->Set(String::NewFromUtf8(isolate, "lineNumber"), Integer::New(isolate, err.lineno)); 17 | error->Set(String::NewFromUtf8(isolate, "cursorPosition"), Integer::New(isolate, err.cursorpos)); 18 | 19 | if (err.context) { 20 | error->Set(String::NewFromUtf8(isolate, "context"), String::NewFromUtf8(isolate, err.context)); 21 | } 22 | else { 23 | error->Set(String::NewFromUtf8(isolate, "context"), Null(isolate)); 24 | } 25 | 26 | return handleScope.Escape(error); 27 | } 28 | 29 | Local QueryParseResponse(Isolate* isolate, const PgQueryParseResult& result) 30 | { 31 | v8::EscapableHandleScope handleScope(isolate); 32 | Local obj = Object::New(isolate); 33 | 34 | if (result.error) { 35 | obj->Set( 36 | String::NewFromUtf8(isolate, "error"), 37 | CreateError(isolate, *result.error) 38 | ); 39 | } 40 | 41 | if (result.parse_tree) { 42 | Local parseResult; 43 | bool parseSucceeded = JSON::Parse( 44 | isolate, 45 | String::NewFromUtf8(isolate, result.parse_tree) 46 | ).ToLocal(&parseResult); 47 | 48 | if(parseSucceeded == true) 49 | obj->Set(String::NewFromUtf8(isolate, "query"),parseResult); 50 | } 51 | 52 | if (result.stderr_buffer) { 53 | obj->Set( 54 | String::NewFromUtf8(isolate, "stderr"), 55 | String::NewFromUtf8(isolate, result.stderr_buffer) 56 | ); 57 | } 58 | 59 | pg_query_free_parse_result(result); 60 | return handleScope.Escape(obj); 61 | } 62 | 63 | Local PlPgSQLParseResponse(Isolate* isolate, const PgQueryPlpgsqlParseResult& result) 64 | { 65 | v8::EscapableHandleScope handleScope(isolate); 66 | Local obj = Object::New(isolate); 67 | 68 | if (result.error) { 69 | obj->Set( 70 | String::NewFromUtf8(isolate, "error"), 71 | CreateError(isolate, *result.error) 72 | ); 73 | } 74 | 75 | if (result.plpgsql_funcs) { 76 | Local parseResult; 77 | bool parseSucceeded = JSON::Parse( 78 | isolate, 79 | String::NewFromUtf8(isolate, result.plpgsql_funcs) 80 | ).ToLocal(&parseResult); 81 | 82 | if(parseSucceeded == true) 83 | obj->Set(String::NewFromUtf8(isolate, "functions"),parseResult); 84 | } 85 | 86 | pg_query_free_plpgsql_parse_result(result); 87 | return handleScope.Escape(obj); 88 | } 89 | 90 | void Method(const FunctionCallbackInfo& args) { 91 | Isolate* isolate = args.GetIsolate(); 92 | String::Utf8Value query(args[0]->ToString()); 93 | PgQueryParseResult result = pg_query_parse(*query); 94 | args.GetReturnValue().Set(QueryParseResponse(isolate, result)); 95 | } 96 | 97 | void MethodPlPgSQL(const FunctionCallbackInfo& args) { 98 | Isolate* isolate = args.GetIsolate(); 99 | String::Utf8Value query(args[0]->ToString()); 100 | PgQueryPlpgsqlParseResult result = pg_query_parse_plpgsql(*query); 101 | args.GetReturnValue().Set(PlPgSQLParseResponse(isolate, result)); 102 | } 103 | 104 | struct Work { 105 | uv_work_t request; 106 | Persistent callback; 107 | std::string ss; 108 | PgQueryParseResult result; 109 | }; 110 | 111 | struct WorkPlPgSQL { 112 | uv_work_t request; 113 | Persistent callback; 114 | std::string ss; 115 | PgQueryPlpgsqlParseResult result; 116 | }; 117 | 118 | // called by libuv worker in separate thread 119 | static void WorkAsync(uv_work_t* req) 120 | { 121 | Work* work = static_cast(req->data); 122 | work->result = pg_query_parse(work->ss.data()); 123 | } 124 | 125 | static void WorkPlPgSQLAsync(uv_work_t* req) 126 | { 127 | WorkPlPgSQL* work = static_cast(req->data); 128 | work->result = pg_query_parse_plpgsql(work->ss.data()); 129 | } 130 | 131 | // called by libuv in event loop when async function completes 132 | static void WorkAsyncComplete(uv_work_t *req, int status) 133 | { 134 | Isolate* isolate = Isolate::GetCurrent(); 135 | Work* work = static_cast(req->data); 136 | 137 | // Set up return arguments. 138 | // Rather than calling back to node with an error if the parse failed, 139 | // as would be more correct, we just call back object that may have an 140 | // error property; caller can deal with it. 141 | v8::HandleScope handleScope(isolate); 142 | Handle argv[1] = { 143 | QueryParseResponse(isolate, work->result) 144 | }; 145 | 146 | // execute the callback 147 | // https://stackoverflow.com/questions/13826803/calling-javascript-function-from-a-c-callback-in-v8/28554065#28554065 148 | Local::New(isolate, work->callback)->Call( 149 | isolate->GetEnteredOrMicrotaskContext()->Global(), 150 | 1, 151 | argv 152 | ); 153 | 154 | // Free up the persistent function callback 155 | work->callback.Reset(); 156 | delete work; 157 | } 158 | 159 | static void WorkPlPgSQLAsyncComplete(uv_work_t *req, int status) 160 | { 161 | Isolate* isolate = Isolate::GetCurrent(); 162 | WorkPlPgSQL* work = static_cast(req->data); 163 | 164 | // Set up return arguments. 165 | // Rather than calling back to node with an error if the parse failed, 166 | // as would be more correct, we just call back object that may have an 167 | // error property; caller can deal with it. 168 | v8::HandleScope handleScope(isolate); 169 | Handle argv[1] = { 170 | PlPgSQLParseResponse(isolate, work->result) 171 | }; 172 | 173 | // execute the callback 174 | Local::New(isolate, work->callback)->Call( 175 | isolate->GetEnteredOrMicrotaskContext()->Global(), 176 | 1, 177 | argv 178 | ); 179 | 180 | // Free up the persistent function callback 181 | work->callback.Reset(); 182 | delete work; 183 | } 184 | 185 | void MethodAsync(const v8::FunctionCallbackInfo& args) { 186 | Isolate* isolate = args.GetIsolate(); 187 | v8::EscapableHandleScope handleScope(isolate); 188 | 189 | // Set up the work object on the heap so that we can do our calculations 190 | // in WorkAsync, and put our callback there too for use in WorkAsynComplete. 191 | Work* work = new Work(); 192 | work->request.data = work; 193 | 194 | String::Utf8Value query(args[0]->ToString()); 195 | work->ss.assign(*query); 196 | 197 | // TODO: should check that this is actually a function. 198 | Local callback = Local::Cast(args[1]); 199 | work->callback.Reset(isolate, callback); 200 | 201 | // kick of the worker thread 202 | uv_queue_work(uv_default_loop(),&work->request,WorkAsync,WorkAsyncComplete); 203 | 204 | args.GetReturnValue().Set(handleScope.Escape(Undefined(isolate))); 205 | } 206 | 207 | void MethodPlPgSQLAsync(const v8::FunctionCallbackInfo& args) { 208 | Isolate* isolate = args.GetIsolate(); 209 | 210 | WorkPlPgSQL* work = new WorkPlPgSQL(); 211 | work->request.data = work; 212 | 213 | String::Utf8Value query(args[0]->ToString()); 214 | work->ss.assign(*query); 215 | 216 | // store the callback from JS in the work package so we can invoke it later 217 | // TODO: should check that this is actually a function. 218 | Local callback = Local::Cast(args[1]); 219 | work->callback.Reset(isolate, callback); 220 | 221 | // kick of the worker thread 222 | uv_queue_work(uv_default_loop(),&work->request,WorkPlPgSQLAsync,WorkPlPgSQLAsyncComplete); 223 | 224 | args.GetReturnValue().Set(Undefined(isolate)); 225 | } 226 | 227 | 228 | void init(Handle exports, Handle module) { 229 | NODE_SET_METHOD(exports, "parseQuery", Method); 230 | NODE_SET_METHOD(exports, "parseQueryAsync", MethodAsync); 231 | NODE_SET_METHOD(exports, "parsePlPgSQL", MethodPlPgSQL); 232 | NODE_SET_METHOD(exports, "parsePlPgSQLAsync", MethodPlPgSQLAsync); 233 | } 234 | 235 | NODE_MODULE(addon, init) 236 | -------------------------------------------------------------------------------- /script/buildAddon.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set commit=06670290ad39e61805ecacbc6267df61f6ae3d91 4 | set branch=16-latest 5 | 6 | setlocal enabledelayedexpansion 7 | 8 | rem Remember current's parent directory and create a new, unique, temporary directory 9 | set buildDir=%cd% 10 | set projectDir=%cd%\.. 11 | set tmpDir=%temp%\tmpdir.libpg_query 12 | rmdir /s /q %tmpDir% 13 | md %tmpDir% 14 | 15 | 16 | rem Define the make target 17 | set makeTarget=build 18 | 19 | rem Change to the newly created temp directory 20 | cd /D %tmpDir% 21 | 22 | 23 | rem Clone the selected branch of the libpg_query Git repo 24 | git clone -b %branch% --single-branch https://github.com/pganalyze/libpg_query.git 25 | cd libpg_query 26 | 27 | rem Checkout the desired commit 28 | git checkout %commit% 29 | 30 | rem needed if being invoked from within gyp 31 | set MAKEFLAGS= 32 | set MFLAGS= 33 | 34 | rem set path with Windows Developer Command Prompt 35 | echo "please ensure you are running at Windows Developer Command Prompt environments" 36 | nmake /F Makefile.msvc clean 37 | nmake /F Makefile.msvc build 38 | 39 | 40 | rem Terminate if build fails 41 | if %errorlevel% NEQ 0 ( 42 | echo ERROR: 'nmake' command failed 43 | ) 44 | 45 | rem Search for pg_query.obj (libpg_query.a), error if not found 46 | for /f "delims=" %%f in ('dir /b /s pg_query.lib') do set file=%%f 47 | if not defined file ( 48 | echo "ERROR: pg_query.lib not found" 49 | 50 | ) 51 | 52 | rem Error if pg_query.h is missing 53 | for /f "delims=" %%f in ('dir /b /s pg_query.h') do set file=%%f 54 | if not defined file ( 55 | echo "ERROR: pg_query.h not found" 56 | 57 | ) 58 | 59 | rem Copy pg_query.lib to windows dir 60 | copy /Y pg_query.lib "%projectDir%\libpg_query\windows\" 61 | 62 | rem Copy header 63 | copy /Y pg_query.h "%projectDir%\libpg_query\include\" 64 | 65 | rem Cleanup: revert to original directory 66 | cd /D %buildDir% 67 | 68 | exit /B 0 -------------------------------------------------------------------------------- /script/buildAddon.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Set the desired commit hash and branch 4 | commit=06670290ad39e61805ecacbc6267df61f6ae3d91 5 | branch=16-latest 6 | 7 | # Remember current directory and create a new, unique, temporary directory 8 | rDIR=$(pwd) 9 | tmpDir=$(mktemp -d 2>/dev/null || mktemp -d -t 'tmpdir.XXXX') 10 | 11 | # Define the make target 12 | makeTarget=build 13 | 14 | # Change to the newly created temp directory 15 | cd "$tmpDir" 16 | 17 | # Clone the selected branch of the libpg_query Git repo 18 | git clone -b $branch --single-branch https://github.com/pganalyze/libpg_query.git 19 | cd libpg_query 20 | 21 | # Checkout the desired commit 22 | git checkout $commit 23 | 24 | # needed if being invoked from within gyp 25 | unset MAKEFLAGS 26 | unset MFLAGS 27 | 28 | # Adaptively build for macOS or Linux 29 | if [ "$(uname)" == "Darwin" ]; then 30 | make CFLAGS='-mmacosx-version-min=10.7' PG_CFLAGS='-mmacosx-version-min=10.7' $makeTarget 31 | elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then 32 | make CFLAGS='' PG_CFLAGS='' $makeTarget 33 | fi 34 | 35 | # Terminate if build fails 36 | if [ $? -ne 0 ]; then 37 | echo "ERROR: 'make' command failed"; 38 | exit 1; 39 | fi 40 | 41 | # Search for libpg_query.a, error if not found 42 | file=$(ls | grep 'libpg_query.a') 43 | if [ ! $file ]; then 44 | echo "ERROR: libpg_query.a not found"; 45 | exit 1; 46 | fi 47 | 48 | # Error if pg_query.h is missing 49 | file=$(ls | grep 'pg_query.h') 50 | if [ ! $file ]; then 51 | echo "ERROR: pg_query.h not found"; 52 | exit 1; 53 | fi 54 | 55 | # Copy queryparser.cc, binding.gyp to current directory 56 | if [ "$(uname)" == "Darwin" ]; then 57 | cp $(pwd)/libpg_query.a $rDIR/libpg_query/osx/ 58 | elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then 59 | cp $(pwd)/libpg_query.a $rDIR/libpg_query/linux/ 60 | fi 61 | 62 | # Copy header 63 | cp $(pwd)/pg_query.h $rDIR/libpg_query/include/ 64 | 65 | # Cleanup: revert to original directory and remove the temp 66 | cd "$rDIR" 67 | rm -rf "$tmpDir" 68 | -------------------------------------------------------------------------------- /script/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo removing object files... 4 | find ./libpg_query/ -name "*.a" | xargs rm 5 | 6 | echo clearing build... 7 | rm -rf build/* 8 | -------------------------------------------------------------------------------- /script/workflows.js: -------------------------------------------------------------------------------- 1 | const { exec } = require('child_process'); 2 | const { join } = require('path'); 3 | 4 | // if (typeof process.argv[2] !== 'string') { 5 | // throw new Error('branchName not provided'); 6 | // } 7 | 8 | const yamldir = (s) => join(__dirname, '/../.yamlize/', s); 9 | const workflowDir = (s) => join(__dirname, '/../.github/workflows/', s); 10 | 11 | const cmd = (config, workflow) => ([ 12 | 'yamlize', 13 | '--config', 14 | yamldir(`config/${config}`), 15 | 16 | '--inFile', 17 | yamldir(`workflows/${workflow}`), 18 | 19 | '--outFile', 20 | workflowDir(`generated-${workflow}`), 21 | ].join(' ')); 22 | 23 | 24 | exec(cmd('config.yaml', 'build-and-test.yaml'), (error, _stdout, _stderr) => { 25 | if (error) { 26 | console.error(`Error: ${error.message}`); 27 | return; 28 | } 29 | }); -------------------------------------------------------------------------------- /src/addon.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "sync.h" // NOLINT(build/include) 3 | #include "async.h" // NOLINT(build/include) 4 | 5 | // Expose synchronous and asynchronous access to our parsing functions 6 | Napi::Object Init(Napi::Env env, Napi::Object exports) { 7 | exports.Set( 8 | Napi::String::New(env, "parseQuerySync"), 9 | Napi::Function::New(env, ParseQuerySync) 10 | ); 11 | 12 | exports.Set( 13 | Napi::String::New(env, "parseQueryAsync"), 14 | Napi::Function::New(env, ParseQueryAsync) 15 | ); 16 | 17 | exports.Set( 18 | Napi::String::New(env, "parsePlPgSQLSync"), 19 | Napi::Function::New(env, ParsePlPgSQLSync) 20 | ); 21 | 22 | exports.Set( 23 | Napi::String::New(env, "parsePlPgSQLAsync"), 24 | Napi::Function::New(env, ParsePlPgSQLAsync) 25 | ); 26 | 27 | exports.Set( 28 | Napi::String::New(env, "fingerprintSync"), 29 | Napi::Function::New(env, FingerprintSync) 30 | ); 31 | 32 | exports.Set( 33 | Napi::String::New(env, "fingerprintAsync"), 34 | Napi::Function::New(env, FingerprintAsync) 35 | ); 36 | 37 | return exports; 38 | } 39 | 40 | NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) 41 | -------------------------------------------------------------------------------- /src/async.cc: -------------------------------------------------------------------------------- 1 | #include "helpers.h" // NOLINT(build/include) 2 | #include "async.h" // NOLINT(build/include) 3 | #include "pg_query.h" 4 | #include 5 | 6 | class QueryWorker : public Napi::AsyncWorker { 7 | public: 8 | QueryWorker(Napi::Function& callback, const std::string& query) 9 | : Napi::AsyncWorker(callback), query(query) {} 10 | ~QueryWorker() {} 11 | 12 | // Executed inside the worker-thread. 13 | // It is not safe to access JS engine data structure 14 | // here, so everything we need for input and output 15 | // should go on `this`. 16 | void Execute () { 17 | result = pg_query_parse(query.c_str()); 18 | } 19 | 20 | // Executed when the async work is complete 21 | // this function will be run inside the main event loop 22 | // so it is safe to use JS engine data again 23 | void OnOK() { 24 | Napi::HandleScope scope(Env()); 25 | try { 26 | Callback().Call({Env().Undefined(), QueryParseResult(Env(), result) }); 27 | } catch (const Napi::Error& e) { 28 | Callback().Call({ e.Value(), Env().Undefined() }); 29 | } 30 | } 31 | 32 | private: 33 | std::string query; 34 | PgQueryParseResult result; 35 | }; 36 | 37 | class PgPlQSLWorker : public Napi::AsyncWorker { 38 | public: 39 | PgPlQSLWorker(Napi::Function& callback, const std::string& query) 40 | : Napi::AsyncWorker(callback), query(query) {} 41 | ~PgPlQSLWorker() {} 42 | 43 | // Executed inside the worker-thread. 44 | // It is not safe to access JS engine data structure 45 | // here, so everything we need for input and output 46 | // should go on `this`. 47 | void Execute () { 48 | result = pg_query_parse_plpgsql(query.c_str()); 49 | } 50 | 51 | // Executed when the async work is complete 52 | // this function will be run inside the main event loop 53 | // so it is safe to use JS engine data again 54 | void OnOK() { 55 | Napi::HandleScope scope(Env()); 56 | try { 57 | Callback().Call({Env().Undefined(), PlPgSQLParseResult(Env(), result) }); 58 | } catch (const Napi::Error& e) { 59 | Callback().Call({ e.Value(), Env().Undefined() }); 60 | } 61 | } 62 | 63 | private: 64 | std::string query; 65 | PgQueryPlpgsqlParseResult result; 66 | }; 67 | 68 | 69 | class FingeprintWorker : public Napi::AsyncWorker { 70 | public: 71 | FingeprintWorker(Napi::Function& callback, const std::string& query) 72 | : Napi::AsyncWorker(callback), query(query) {} 73 | ~FingeprintWorker() {} 74 | 75 | // Executed inside the worker-thread. 76 | // It is not safe to access JS engine data structure 77 | // here, so everything we need for input and output 78 | // should go on `this`. 79 | void Execute () { 80 | result = pg_query_fingerprint(query.c_str()); 81 | } 82 | 83 | // Executed when the async work is complete 84 | // this function will be run inside the main event loop 85 | // so it is safe to use JS engine data again 86 | void OnOK() { 87 | Napi::HandleScope scope(Env()); 88 | try { 89 | Callback().Call({Env().Undefined(), FingerprintResult(Env(), result) }); 90 | } catch (const Napi::Error& e) { 91 | Callback().Call({ e.Value(), Env().Undefined() }); 92 | } 93 | } 94 | 95 | private: 96 | std::string query; 97 | PgQueryFingerprintResult result; 98 | }; 99 | 100 | Napi::Value ParseQueryAsync(const Napi::CallbackInfo& info) { 101 | std::string query = info[0].As(); 102 | Napi::Function callback = info[1].As(); 103 | QueryWorker* worker = new QueryWorker(callback, query); 104 | worker->Queue(); 105 | return info.Env().Undefined(); 106 | } 107 | 108 | Napi::Value ParsePlPgSQLAsync(const Napi::CallbackInfo& info) { 109 | std::string query = info[0].As(); 110 | Napi::Function callback = info[1].As(); 111 | PgPlQSLWorker* worker = new PgPlQSLWorker(callback, query); 112 | worker->Queue(); 113 | return info.Env().Undefined(); 114 | } 115 | 116 | Napi::Value FingerprintAsync(const Napi::CallbackInfo& info) { 117 | std::string query = info[0].As(); 118 | Napi::Function callback = info[1].As(); 119 | FingeprintWorker* worker = new FingeprintWorker(callback, query); 120 | worker->Queue(); 121 | return info.Env().Undefined(); 122 | } 123 | -------------------------------------------------------------------------------- /src/async.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Napi::Value ParseQueryAsync(const Napi::CallbackInfo& info); 4 | Napi::Value ParsePlPgSQLAsync(const Napi::CallbackInfo& info); 5 | Napi::Value FingerprintAsync(const Napi::CallbackInfo& info); 6 | -------------------------------------------------------------------------------- /src/helpers.cc: -------------------------------------------------------------------------------- 1 | #include "helpers.h" // NOLINT(build/include) 2 | #include "pg_query.h" 3 | #include "helpers.h" 4 | #include 5 | 6 | Napi::Error CreateError(Napi::Env env, const PgQueryError& err) 7 | { 8 | auto error = Napi::Error::New(env, err.message); 9 | error.Set("fileName", err.filename); 10 | error.Set("functionName", err.funcname); 11 | error.Set("lineNumber", Napi::Value::From(env, err.lineno)); 12 | error.Set("cursorPosition", Napi::Value::From(env, err.cursorpos)); 13 | error.Set("context", err.context ? Napi::Value::From(env, err.context) : env.Null()); 14 | return error; 15 | } 16 | 17 | Napi::String QueryParseResult(Napi::Env env, const PgQueryParseResult& result) 18 | { 19 | if (result.error) { 20 | auto throwVal = CreateError(env, *result.error); 21 | pg_query_free_parse_result(result); 22 | throw throwVal; 23 | } 24 | 25 | auto returnVal = Napi::String::New(env, result.parse_tree); 26 | pg_query_free_parse_result(result); 27 | return returnVal; 28 | } 29 | 30 | Napi::String PlPgSQLParseResult(Napi::Env env, const PgQueryPlpgsqlParseResult& result) 31 | { 32 | if (result.error) { 33 | auto throwVal = CreateError(env, *result.error); 34 | pg_query_free_plpgsql_parse_result(result); 35 | throw throwVal; 36 | } 37 | 38 | auto returnVal = Napi::String::New(env, result.plpgsql_funcs); 39 | pg_query_free_plpgsql_parse_result(result); 40 | return returnVal; 41 | } 42 | 43 | 44 | Napi::String FingerprintResult(Napi::Env env, const PgQueryFingerprintResult & result) 45 | { 46 | if (result.error) { 47 | auto throwVal = CreateError(env, *result.error); 48 | pg_query_free_fingerprint_result(result); 49 | throw throwVal; 50 | } 51 | 52 | auto returnVal = Napi::String::New(env, result.fingerprint_str); 53 | pg_query_free_fingerprint_result(result); 54 | return returnVal; 55 | } 56 | -------------------------------------------------------------------------------- /src/helpers.h: -------------------------------------------------------------------------------- 1 | #include "pg_query.h" 2 | #include 3 | 4 | Napi::Error CreateError(Napi::Env env, const PgQueryError& err); 5 | Napi::String QueryParseResult(Napi::Env env, const PgQueryParseResult& result); 6 | Napi::String PlPgSQLParseResult(Napi::Env env, const PgQueryPlpgsqlParseResult& result); 7 | Napi::String FingerprintResult(Napi::Env env, const PgQueryFingerprintResult & result); 8 | -------------------------------------------------------------------------------- /src/sync.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sync.h" // NOLINT(build/include) 4 | #include "helpers.h" // NOLINT(build/include) 5 | 6 | Napi::String ParseQuerySync(const Napi::CallbackInfo& info) { 7 | std::string query = info[0].As(); 8 | PgQueryParseResult result = pg_query_parse(query.c_str()); 9 | 10 | return QueryParseResult(info.Env(), result); 11 | } 12 | 13 | Napi::String ParsePlPgSQLSync(const Napi::CallbackInfo& info) { 14 | std::string query = info[0].As(); 15 | PgQueryPlpgsqlParseResult result = pg_query_parse_plpgsql(query.c_str()); 16 | 17 | return PlPgSQLParseResult(info.Env(), result); 18 | } 19 | 20 | Napi::String FingerprintSync(const Napi::CallbackInfo& info) { 21 | std::string query = info[0].As(); 22 | PgQueryFingerprintResult result = pg_query_fingerprint(query.c_str()); 23 | 24 | return FingerprintResult(info.Env(), result); 25 | } 26 | -------------------------------------------------------------------------------- /src/sync.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | Napi::String ParseQuerySync(const Napi::CallbackInfo& info); 4 | Napi::String ParsePlPgSQLSync(const Napi::CallbackInfo& info); 5 | Napi::String FingerprintSync(const Napi::CallbackInfo& info); 6 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | const query = require("../"); 2 | const { expect } = require("chai"); 3 | const { omit, cloneDeepWith } = require("lodash"); 4 | 5 | describe("Queries", () => { 6 | describe("Sync Parsing", () => { 7 | it("should return a single-item parse result for common queries", () => { 8 | const queries = ["select 1", "select null", "select ''", "select a, b"]; 9 | const results = queries.map(query.parseQuerySync); 10 | results.forEach((res) => { 11 | expect(res.stmts).to.have.lengthOf(1); 12 | }); 13 | 14 | // Do some rough asserting on the shape of the result. 15 | // These tests aren't really meant to test the parsing functionality 16 | // itself, but doing a bit for sanity doesn't hurt. 17 | const selectedDatas = results.map( 18 | (it) => it.stmts[0].stmt.SelectStmt.targetList 19 | ); 20 | 21 | expect(selectedDatas[0][0].ResTarget.val.A_Const.ival.ival).to.eq( 22 | 1 23 | ); 24 | expect(selectedDatas[1][0].ResTarget.val.A_Const.isnull).to.eq( 25 | true 26 | ); 27 | expect(selectedDatas[2][0].ResTarget.val.A_Const.sval.sval).to.eq( 28 | "" 29 | ); 30 | expect(selectedDatas[3]).to.have.lengthOf(2); 31 | }); 32 | 33 | it("should support parsing multiple queries", () => { 34 | const res = query.parseQuerySync("select 1; select null;"); 35 | const changedProps = [ 36 | "stmt_len", 37 | "stmt_location", 38 | "stmt.SelectStmt.targetList[0].ResTarget.location", 39 | "stmt.SelectStmt.targetList[0].ResTarget.val.A_Const.location", 40 | ]; 41 | const removeChangedProps = (stmt) => omit(stmt, changedProps); 42 | expect(res.stmts.map(removeChangedProps)).to.deep.eq([ 43 | ...query.parseQuerySync("select 1;").stmts.map(removeChangedProps), 44 | ...query.parseQuerySync("select null;").stmts.map(removeChangedProps), 45 | ]); 46 | }); 47 | 48 | it("should not parse a bogus query", () => { 49 | expect(() => query.parseQuerySync("NOT A QUERY")).to.throw(Error); 50 | }); 51 | }); 52 | 53 | describe("Async parsing", () => { 54 | it("should return a promise resolving to same result", async () => { 55 | const testQuery = "select * from john;"; 56 | const resPromise = query.parseQuery(testQuery); 57 | const res = await resPromise; 58 | 59 | expect(resPromise).to.be.instanceof(Promise); 60 | expect(res).to.deep.eq(query.parseQuerySync(testQuery)); 61 | }); 62 | 63 | it("should reject on bogus queries", async () => { 64 | return query.parseQuery("NOT A QUERY").then( 65 | () => { 66 | throw new Error("should have rejected"); 67 | }, 68 | (e) => { 69 | expect(e).instanceof(Error); 70 | expect(e.message).to.match(/NOT/); 71 | } 72 | ); 73 | }); 74 | }); 75 | 76 | describe("Fingerprint", () => { 77 | context("sync", () => { 78 | it("should not fingerprint a bogus query", () => { 79 | expect(() => query.fingerprintSync("NOT A QUERY")).to.throw(Error); 80 | }); 81 | 82 | it("should fingerprint a query", () => { 83 | const queries = ["select 1", "select null", "select ''", "select a, b"]; 84 | const results = queries.map(query.fingerprintSync); 85 | 86 | results.forEach((res) => { 87 | expect(res).to.have.lengthOf(16); 88 | }); 89 | }); 90 | }); 91 | 92 | context("async", () => { 93 | it("should not fingerprint a bogus query", () => { 94 | return query.fingerprint("NOT A QUERY").then( 95 | () => { 96 | throw new Error("should have rejected"); 97 | }, 98 | (e) => { 99 | expect(e).instanceof(Error); 100 | expect(e.message).to.match(/NOT/); 101 | } 102 | ); 103 | }); 104 | 105 | it("should fingerprint a query", async () => { 106 | const queries = ["select 1", "select null", "select ''", "select a, b"]; 107 | const results = await Promise.all(queries.map(query.fingerprint)); 108 | 109 | results.forEach((res) => { 110 | expect(res).to.have.lengthOf(16); 111 | }); 112 | }); 113 | }); 114 | }); 115 | }); 116 | 117 | describe("PlPgSQL (async)", () => { 118 | it("should parse a function", async () => { 119 | const testFunction = ` 120 | CREATE FUNCTION t() RETURNS trigger AS 121 | $BODY$ 122 | DECLARE 123 | resultVal integer; 124 | finalVal integer; 125 | BEGIN 126 | resultVal = 0; 127 | IF (resultVal >= 5) 128 | THEN finalVal = 'Yes'; 129 | ELSE finalVal = 'No'; 130 | END IF; 131 | RETURN finalVal; 132 | END; 133 | $BODY$ 134 | LANGUAGE plpgsql; 135 | `; 136 | 137 | const resPromise = query.parsePlPgSQL(testFunction); 138 | const res = await resPromise; 139 | 140 | expect(resPromise).to.be.instanceof(Promise); 141 | expect(res).to.deep.have.property("0.PLpgSQL_function"); 142 | }); 143 | }); 144 | -------------------------------------------------------------------------------- /test/webpack/.gitignore: -------------------------------------------------------------------------------- 1 | dist/*.js 2 | -------------------------------------------------------------------------------- /test/webpack/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | libpg-query web 7 | 8 | 9 | 10 | 11 |

Check the console for the parsed SQL.

12 | 13 | 14 | -------------------------------------------------------------------------------- /test/webpack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-test", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "webpack serve --open", 7 | "build": "webpack" 8 | }, 9 | "devDependencies": { 10 | "webpack": "^5.89.0", 11 | "webpack-cli": "^5.1.4", 12 | "webpack-dev-server": "^4.15.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/webpack/src/index.js: -------------------------------------------------------------------------------- 1 | import { parseQuery } from '../../../wasm'; 2 | 3 | const sql = 'select * from customers;'; 4 | const result = await parseQuery(sql); 5 | 6 | console.log(sql); 7 | console.log(result); 8 | -------------------------------------------------------------------------------- /test/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: './src/index.js', 5 | output: { 6 | filename: 'main.js', 7 | path: path.resolve(__dirname, 'dist'), 8 | }, 9 | devServer: { 10 | static: './dist', 11 | client: { 12 | overlay: false, 13 | }, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /wasm/index.js: -------------------------------------------------------------------------------- 1 | import { getDefaultContext } from '@emnapi/runtime'; 2 | import PgQueryModule from './libpg-query.js'; 3 | 4 | let PgQuery; 5 | 6 | const initPromise = PgQueryModule().then((module) => { 7 | const binding = module.emnapiInit({ 8 | context: getDefaultContext(), 9 | }); 10 | 11 | PgQuery = binding; 12 | }); 13 | 14 | /** 15 | * Function wrapper that waits for the WASM module to initialize 16 | * before executing the function. 17 | */ 18 | function awaitInit(fn) { 19 | return async (...args) => { 20 | await initPromise; 21 | return fn(...args); 22 | }; 23 | } 24 | 25 | export const parseQuery = awaitInit((query) => { 26 | return new Promise(async (resolve, reject) => { 27 | PgQuery.parseQueryAsync(query, (err, result) => { 28 | err ? reject(err) : resolve(JSON.parse(result)); 29 | }); 30 | }); 31 | }); 32 | 33 | export const parsePlPgSQL = awaitInit((query) => { 34 | return new Promise(async (resolve, reject) => { 35 | PgQuery.parsePlPgSQLAsync(query, (err, result) => { 36 | err ? reject(err) : resolve(JSON.parse(result)); 37 | }); 38 | }); 39 | }); 40 | 41 | export const fingerprint = awaitInit((query) => { 42 | return new Promise(async (resolve, reject) => { 43 | PgQuery.fingerprintAsync(query, (err, result) => { 44 | err ? reject(err) : resolve(result); 45 | }); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@emnapi/runtime@^0.43.1": 6 | version "0.43.1" 7 | resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-0.43.1.tgz#c72d5e32f9331f313ae6690d8a64454647ab245b" 8 | integrity sha512-Q5sMc4Z4gsD4tlmlyFu+MpNAwpR7Gv2errDhVJ+SOhNjWcx8UTqy+hswb8L31RfC8jBvDgcnT87l3xI2w08rAg== 9 | dependencies: 10 | tslib "^2.4.0" 11 | 12 | "@isaacs/cliui@^8.0.2": 13 | version "8.0.2" 14 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" 15 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== 16 | dependencies: 17 | string-width "^5.1.2" 18 | string-width-cjs "npm:string-width@^4.2.0" 19 | strip-ansi "^7.0.1" 20 | strip-ansi-cjs "npm:strip-ansi@^6.0.1" 21 | wrap-ansi "^8.1.0" 22 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" 23 | 24 | "@mapbox/node-pre-gyp@^1.0.8": 25 | version "1.0.11" 26 | resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" 27 | integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== 28 | dependencies: 29 | detect-libc "^2.0.0" 30 | https-proxy-agent "^5.0.0" 31 | make-dir "^3.1.0" 32 | node-fetch "^2.6.7" 33 | nopt "^5.0.0" 34 | npmlog "^5.0.1" 35 | rimraf "^3.0.2" 36 | semver "^7.3.5" 37 | tar "^6.1.11" 38 | 39 | "@npmcli/agent@^2.0.0": 40 | version "2.2.1" 41 | resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-2.2.1.tgz#8aa677d0a4136d57524336a35d5679aedf2d56f7" 42 | integrity sha512-H4FrOVtNyWC8MUwL3UfjOsAihHvT1Pe8POj3JvjXhSTJipsZMtgUALCT4mGyYZNxymkUfOw3PUj6dE4QPp6osQ== 43 | dependencies: 44 | agent-base "^7.1.0" 45 | http-proxy-agent "^7.0.0" 46 | https-proxy-agent "^7.0.1" 47 | lru-cache "^10.0.1" 48 | socks-proxy-agent "^8.0.1" 49 | 50 | "@npmcli/fs@^3.1.0": 51 | version "3.1.0" 52 | resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" 53 | integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== 54 | dependencies: 55 | semver "^7.3.5" 56 | 57 | "@pkgjs/parseargs@^0.11.0": 58 | version "0.11.0" 59 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" 60 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== 61 | 62 | "@yamlize/cli@^0.8.0": 63 | version "0.8.0" 64 | resolved "https://registry.yarnpkg.com/@yamlize/cli/-/cli-0.8.0.tgz#c86673a6ee59a36f6a5621a073cb688b5db00d77" 65 | integrity sha512-OuhQ/gYLCuMjENdLMF8UXgM32p7blBB0FxwS4R2Mw4jk/9uvv87uCz2ptq9VB7GjNTNbnRTQKw+bAbwCXyngCA== 66 | dependencies: 67 | chalk "4.1.0" 68 | inquirerer "^1.9.0" 69 | js-yaml "^4.1.0" 70 | minimist "1.2.8" 71 | yamlize "^0.8.0" 72 | 73 | abbrev@1: 74 | version "1.1.1" 75 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 76 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 77 | 78 | abbrev@^2.0.0: 79 | version "2.0.0" 80 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf" 81 | integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ== 82 | 83 | agent-base@6: 84 | version "6.0.2" 85 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" 86 | integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== 87 | dependencies: 88 | debug "4" 89 | 90 | agent-base@^7.0.2, agent-base@^7.1.0: 91 | version "7.1.0" 92 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" 93 | integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== 94 | dependencies: 95 | debug "^4.3.4" 96 | 97 | aggregate-error@^3.0.0: 98 | version "3.1.0" 99 | resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" 100 | integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== 101 | dependencies: 102 | clean-stack "^2.0.0" 103 | indent-string "^4.0.0" 104 | 105 | ansi-regex@^5.0.1: 106 | version "5.0.1" 107 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 108 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 109 | 110 | ansi-regex@^6.0.1: 111 | version "6.0.1" 112 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" 113 | integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== 114 | 115 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 116 | version "4.3.0" 117 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 118 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 119 | dependencies: 120 | color-convert "^2.0.1" 121 | 122 | ansi-styles@^6.1.0: 123 | version "6.2.1" 124 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" 125 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== 126 | 127 | "aproba@^1.0.3 || ^2.0.0": 128 | version "2.0.0" 129 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" 130 | integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== 131 | 132 | are-we-there-yet@^2.0.0: 133 | version "2.0.0" 134 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" 135 | integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== 136 | dependencies: 137 | delegates "^1.0.0" 138 | readable-stream "^3.6.0" 139 | 140 | argparse@^2.0.1: 141 | version "2.0.1" 142 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 143 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 144 | 145 | assertion-error@^1.0.1: 146 | version "1.1.0" 147 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 148 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 149 | 150 | balanced-match@^1.0.0: 151 | version "1.0.2" 152 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 153 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 154 | 155 | brace-expansion@^1.1.7: 156 | version "1.1.11" 157 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 158 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 159 | dependencies: 160 | balanced-match "^1.0.0" 161 | concat-map "0.0.1" 162 | 163 | brace-expansion@^2.0.1: 164 | version "2.0.1" 165 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 166 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 167 | dependencies: 168 | balanced-match "^1.0.0" 169 | 170 | browser-stdout@1.3.1: 171 | version "1.3.1" 172 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 173 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 174 | 175 | cacache@^18.0.0: 176 | version "18.0.2" 177 | resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.2.tgz#fd527ea0f03a603be5c0da5805635f8eef00c60c" 178 | integrity sha512-r3NU8h/P+4lVUHfeRw1dtgQYar3DZMm4/cm2bZgOvrFC/su7budSOeqh52VJIC4U4iG1WWwV6vRW0znqBvxNuw== 179 | dependencies: 180 | "@npmcli/fs" "^3.1.0" 181 | fs-minipass "^3.0.0" 182 | glob "^10.2.2" 183 | lru-cache "^10.0.1" 184 | minipass "^7.0.3" 185 | minipass-collect "^2.0.1" 186 | minipass-flush "^1.0.5" 187 | minipass-pipeline "^1.2.4" 188 | p-map "^4.0.0" 189 | ssri "^10.0.0" 190 | tar "^6.1.11" 191 | unique-filename "^3.0.0" 192 | 193 | chai@^3.5.0: 194 | version "3.5.0" 195 | resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" 196 | integrity sha512-eRYY0vPS2a9zt5w5Z0aCeWbrXTEyvk7u/Xf71EzNObrjSCPgMm1Nku/D/u2tiqHBX5j40wWhj54YJLtgn8g55A== 197 | dependencies: 198 | assertion-error "^1.0.1" 199 | deep-eql "^0.1.3" 200 | type-detect "^1.0.0" 201 | 202 | chalk@4.1.0: 203 | version "4.1.0" 204 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" 205 | integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== 206 | dependencies: 207 | ansi-styles "^4.1.0" 208 | supports-color "^7.1.0" 209 | 210 | chalk@^4.1.0: 211 | version "4.1.2" 212 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 213 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 214 | dependencies: 215 | ansi-styles "^4.1.0" 216 | supports-color "^7.1.0" 217 | 218 | chownr@^2.0.0: 219 | version "2.0.0" 220 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" 221 | integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== 222 | 223 | clean-stack@^2.0.0: 224 | version "2.2.0" 225 | resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" 226 | integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== 227 | 228 | color-convert@^2.0.1: 229 | version "2.0.1" 230 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 231 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 232 | dependencies: 233 | color-name "~1.1.4" 234 | 235 | color-name@~1.1.4: 236 | version "1.1.4" 237 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 238 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 239 | 240 | color-support@^1.1.2: 241 | version "1.1.3" 242 | resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" 243 | integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== 244 | 245 | commander@2.15.1: 246 | version "2.15.1" 247 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" 248 | integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== 249 | 250 | concat-map@0.0.1: 251 | version "0.0.1" 252 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 253 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 254 | 255 | console-control-strings@^1.0.0, console-control-strings@^1.1.0: 256 | version "1.1.0" 257 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 258 | integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== 259 | 260 | cross-spawn@^7.0.0: 261 | version "7.0.3" 262 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 263 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 264 | dependencies: 265 | path-key "^3.1.0" 266 | shebang-command "^2.0.0" 267 | which "^2.0.1" 268 | 269 | debug@3.1.0: 270 | version "3.1.0" 271 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 272 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 273 | dependencies: 274 | ms "2.0.0" 275 | 276 | debug@4, debug@^4.3.4: 277 | version "4.3.4" 278 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 279 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 280 | dependencies: 281 | ms "2.1.2" 282 | 283 | deep-eql@^0.1.3: 284 | version "0.1.3" 285 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" 286 | integrity sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg== 287 | dependencies: 288 | type-detect "0.1.1" 289 | 290 | deepmerge@^4.3.1: 291 | version "4.3.1" 292 | resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" 293 | integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== 294 | 295 | delegates@^1.0.0: 296 | version "1.0.0" 297 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 298 | integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== 299 | 300 | detect-libc@^2.0.0: 301 | version "2.0.2" 302 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" 303 | integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== 304 | 305 | diff@3.5.0: 306 | version "3.5.0" 307 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 308 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 309 | 310 | eastasianwidth@^0.2.0: 311 | version "0.2.0" 312 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" 313 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== 314 | 315 | emnapi@^0.43.1: 316 | version "0.43.1" 317 | resolved "https://registry.yarnpkg.com/emnapi/-/emnapi-0.43.1.tgz#ce99a639277060cfe99b32b2ddcc9ae6d60c7aa6" 318 | integrity sha512-ZsBeBRBHPdoI4GMM2fer2qYN5He8NMc1wg4qWZRZNptRUTDH0hVl8LFu5/uYL3+Z/3qyp1cV/n1FBf+hHlt5Hg== 319 | 320 | emoji-regex@^8.0.0: 321 | version "8.0.0" 322 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 323 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 324 | 325 | emoji-regex@^9.2.2: 326 | version "9.2.2" 327 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" 328 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== 329 | 330 | encoding@^0.1.13: 331 | version "0.1.13" 332 | resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" 333 | integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== 334 | dependencies: 335 | iconv-lite "^0.6.2" 336 | 337 | env-paths@^2.2.0: 338 | version "2.2.1" 339 | resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" 340 | integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== 341 | 342 | err-code@^2.0.2: 343 | version "2.0.3" 344 | resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" 345 | integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== 346 | 347 | escape-string-regexp@1.0.5: 348 | version "1.0.5" 349 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 350 | integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 351 | 352 | exponential-backoff@^3.1.1: 353 | version "3.1.1" 354 | resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" 355 | integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== 356 | 357 | foreground-child@^3.1.0: 358 | version "3.1.1" 359 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" 360 | integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== 361 | dependencies: 362 | cross-spawn "^7.0.0" 363 | signal-exit "^4.0.1" 364 | 365 | fs-minipass@^2.0.0: 366 | version "2.1.0" 367 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" 368 | integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== 369 | dependencies: 370 | minipass "^3.0.0" 371 | 372 | fs-minipass@^3.0.0: 373 | version "3.0.3" 374 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" 375 | integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== 376 | dependencies: 377 | minipass "^7.0.3" 378 | 379 | fs.realpath@^1.0.0: 380 | version "1.0.0" 381 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 382 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 383 | 384 | gauge@^3.0.0: 385 | version "3.0.2" 386 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" 387 | integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== 388 | dependencies: 389 | aproba "^1.0.3 || ^2.0.0" 390 | color-support "^1.1.2" 391 | console-control-strings "^1.0.0" 392 | has-unicode "^2.0.1" 393 | object-assign "^4.1.1" 394 | signal-exit "^3.0.0" 395 | string-width "^4.2.3" 396 | strip-ansi "^6.0.1" 397 | wide-align "^1.1.2" 398 | 399 | glob@7.1.2: 400 | version "7.1.2" 401 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 402 | integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== 403 | dependencies: 404 | fs.realpath "^1.0.0" 405 | inflight "^1.0.4" 406 | inherits "2" 407 | minimatch "^3.0.4" 408 | once "^1.3.0" 409 | path-is-absolute "^1.0.0" 410 | 411 | glob@^10.0.0: 412 | version "10.3.12" 413 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" 414 | integrity sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg== 415 | dependencies: 416 | foreground-child "^3.1.0" 417 | jackspeak "^2.3.6" 418 | minimatch "^9.0.1" 419 | minipass "^7.0.4" 420 | path-scurry "^1.10.2" 421 | 422 | glob@^10.2.2, glob@^10.3.10: 423 | version "10.3.10" 424 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" 425 | integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== 426 | dependencies: 427 | foreground-child "^3.1.0" 428 | jackspeak "^2.3.5" 429 | minimatch "^9.0.1" 430 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 431 | path-scurry "^1.10.1" 432 | 433 | glob@^7.1.3: 434 | version "7.2.3" 435 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 436 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 437 | dependencies: 438 | fs.realpath "^1.0.0" 439 | inflight "^1.0.4" 440 | inherits "2" 441 | minimatch "^3.1.1" 442 | once "^1.3.0" 443 | path-is-absolute "^1.0.0" 444 | 445 | graceful-fs@^4.2.6: 446 | version "4.2.11" 447 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" 448 | integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== 449 | 450 | growl@1.10.5: 451 | version "1.10.5" 452 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 453 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 454 | 455 | has-flag@^3.0.0: 456 | version "3.0.0" 457 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 458 | integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== 459 | 460 | has-flag@^4.0.0: 461 | version "4.0.0" 462 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 463 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 464 | 465 | has-unicode@^2.0.1: 466 | version "2.0.1" 467 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 468 | integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== 469 | 470 | he@1.1.1: 471 | version "1.1.1" 472 | resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" 473 | integrity sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA== 474 | 475 | http-cache-semantics@^4.1.1: 476 | version "4.1.1" 477 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" 478 | integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== 479 | 480 | http-proxy-agent@^7.0.0: 481 | version "7.0.2" 482 | resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" 483 | integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== 484 | dependencies: 485 | agent-base "^7.1.0" 486 | debug "^4.3.4" 487 | 488 | https-proxy-agent@^5.0.0: 489 | version "5.0.1" 490 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" 491 | integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== 492 | dependencies: 493 | agent-base "6" 494 | debug "4" 495 | 496 | https-proxy-agent@^7.0.1: 497 | version "7.0.4" 498 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168" 499 | integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg== 500 | dependencies: 501 | agent-base "^7.0.2" 502 | debug "4" 503 | 504 | iconv-lite@^0.6.2: 505 | version "0.6.3" 506 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" 507 | integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== 508 | dependencies: 509 | safer-buffer ">= 2.1.2 < 3.0.0" 510 | 511 | imurmurhash@^0.1.4: 512 | version "0.1.4" 513 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 514 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 515 | 516 | indent-string@^4.0.0: 517 | version "4.0.0" 518 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" 519 | integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== 520 | 521 | inflight@^1.0.4: 522 | version "1.0.6" 523 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 524 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 525 | dependencies: 526 | once "^1.3.0" 527 | wrappy "1" 528 | 529 | inherits@2, inherits@^2.0.3: 530 | version "2.0.4" 531 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 532 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 533 | 534 | inquirerer@^1.9.0: 535 | version "1.9.0" 536 | resolved "https://registry.yarnpkg.com/inquirerer/-/inquirerer-1.9.0.tgz#108071773a28ea5b950271572ac3051f34e0c92e" 537 | integrity sha512-/LAn/F70YvRQZWz9r1q1seoO2oRMiSCSK8xKHGlkNebSibx5FppUKZLEjXgkCy1tgccas933q/Y7qNccFxrYkw== 538 | dependencies: 539 | chalk "^4.1.0" 540 | deepmerge "^4.3.1" 541 | js-yaml "^4.1.0" 542 | minimist "^1.2.8" 543 | 544 | ip-address@^9.0.5: 545 | version "9.0.5" 546 | resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" 547 | integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== 548 | dependencies: 549 | jsbn "1.1.0" 550 | sprintf-js "^1.1.3" 551 | 552 | is-fullwidth-code-point@^3.0.0: 553 | version "3.0.0" 554 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 555 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 556 | 557 | is-lambda@^1.0.1: 558 | version "1.0.1" 559 | resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" 560 | integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== 561 | 562 | isexe@^2.0.0: 563 | version "2.0.0" 564 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 565 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 566 | 567 | isexe@^3.1.1: 568 | version "3.1.1" 569 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-3.1.1.tgz#4a407e2bd78ddfb14bea0c27c6f7072dde775f0d" 570 | integrity sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ== 571 | 572 | jackspeak@^2.3.5, jackspeak@^2.3.6: 573 | version "2.3.6" 574 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" 575 | integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== 576 | dependencies: 577 | "@isaacs/cliui" "^8.0.2" 578 | optionalDependencies: 579 | "@pkgjs/parseargs" "^0.11.0" 580 | 581 | js-yaml@^4.1.0: 582 | version "4.1.0" 583 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 584 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 585 | dependencies: 586 | argparse "^2.0.1" 587 | 588 | jsbn@1.1.0: 589 | version "1.1.0" 590 | resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" 591 | integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== 592 | 593 | lodash@^4.17.15: 594 | version "4.17.21" 595 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 596 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 597 | 598 | lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0": 599 | version "10.2.0" 600 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" 601 | integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== 602 | 603 | lru-cache@^10.2.0: 604 | version "10.2.2" 605 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" 606 | integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== 607 | 608 | lru-cache@^6.0.0: 609 | version "6.0.0" 610 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 611 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 612 | dependencies: 613 | yallist "^4.0.0" 614 | 615 | make-dir@^3.1.0: 616 | version "3.1.0" 617 | resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" 618 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 619 | dependencies: 620 | semver "^6.0.0" 621 | 622 | make-fetch-happen@^13.0.0: 623 | version "13.0.0" 624 | resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz#705d6f6cbd7faecb8eac2432f551e49475bfedf0" 625 | integrity sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A== 626 | dependencies: 627 | "@npmcli/agent" "^2.0.0" 628 | cacache "^18.0.0" 629 | http-cache-semantics "^4.1.1" 630 | is-lambda "^1.0.1" 631 | minipass "^7.0.2" 632 | minipass-fetch "^3.0.0" 633 | minipass-flush "^1.0.5" 634 | minipass-pipeline "^1.2.4" 635 | negotiator "^0.6.3" 636 | promise-retry "^2.0.1" 637 | ssri "^10.0.0" 638 | 639 | minimatch@3.0.4: 640 | version "3.0.4" 641 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 642 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 643 | dependencies: 644 | brace-expansion "^1.1.7" 645 | 646 | minimatch@^3.0.4, minimatch@^3.1.1: 647 | version "3.1.2" 648 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 649 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 650 | dependencies: 651 | brace-expansion "^1.1.7" 652 | 653 | minimatch@^9.0.1: 654 | version "9.0.3" 655 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" 656 | integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== 657 | dependencies: 658 | brace-expansion "^2.0.1" 659 | 660 | minimist@0.0.8: 661 | version "0.0.8" 662 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 663 | integrity sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q== 664 | 665 | minimist@1.2.8, minimist@^1.2.8: 666 | version "1.2.8" 667 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 668 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 669 | 670 | minipass-collect@^2.0.1: 671 | version "2.0.1" 672 | resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" 673 | integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== 674 | dependencies: 675 | minipass "^7.0.3" 676 | 677 | minipass-fetch@^3.0.0: 678 | version "3.0.4" 679 | resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" 680 | integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== 681 | dependencies: 682 | minipass "^7.0.3" 683 | minipass-sized "^1.0.3" 684 | minizlib "^2.1.2" 685 | optionalDependencies: 686 | encoding "^0.1.13" 687 | 688 | minipass-flush@^1.0.5: 689 | version "1.0.5" 690 | resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" 691 | integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== 692 | dependencies: 693 | minipass "^3.0.0" 694 | 695 | minipass-pipeline@^1.2.4: 696 | version "1.2.4" 697 | resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" 698 | integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== 699 | dependencies: 700 | minipass "^3.0.0" 701 | 702 | minipass-sized@^1.0.3: 703 | version "1.0.3" 704 | resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" 705 | integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== 706 | dependencies: 707 | minipass "^3.0.0" 708 | 709 | minipass@^3.0.0: 710 | version "3.3.6" 711 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" 712 | integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== 713 | dependencies: 714 | yallist "^4.0.0" 715 | 716 | minipass@^5.0.0: 717 | version "5.0.0" 718 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" 719 | integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== 720 | 721 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3, minipass@^7.0.4: 722 | version "7.0.4" 723 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" 724 | integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== 725 | 726 | minizlib@^2.1.1, minizlib@^2.1.2: 727 | version "2.1.2" 728 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" 729 | integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== 730 | dependencies: 731 | minipass "^3.0.0" 732 | yallist "^4.0.0" 733 | 734 | mkdirp@0.5.1: 735 | version "0.5.1" 736 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 737 | integrity sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA== 738 | dependencies: 739 | minimist "0.0.8" 740 | 741 | mkdirp@3.0.1: 742 | version "3.0.1" 743 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" 744 | integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== 745 | 746 | mkdirp@^1.0.3: 747 | version "1.0.4" 748 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 749 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 750 | 751 | mocha@^5.2.0: 752 | version "5.2.0" 753 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" 754 | integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== 755 | dependencies: 756 | browser-stdout "1.3.1" 757 | commander "2.15.1" 758 | debug "3.1.0" 759 | diff "3.5.0" 760 | escape-string-regexp "1.0.5" 761 | glob "7.1.2" 762 | growl "1.10.5" 763 | he "1.1.1" 764 | minimatch "3.0.4" 765 | mkdirp "0.5.1" 766 | supports-color "5.4.0" 767 | 768 | ms@2.0.0: 769 | version "2.0.0" 770 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 771 | integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== 772 | 773 | ms@2.1.2: 774 | version "2.1.2" 775 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 776 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 777 | 778 | negotiator@^0.6.3: 779 | version "0.6.3" 780 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" 781 | integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== 782 | 783 | nested-obj@^0.0.1: 784 | version "0.0.1" 785 | resolved "https://registry.yarnpkg.com/nested-obj/-/nested-obj-0.0.1.tgz#efe1da127c3d00826fa10ec25673e0f9ec1224fd" 786 | integrity sha512-kB1WKTng+IePQhZVs1UXtFaHBx4QEM5a0XKGAzYfCKvdx5DhNjCytNDWMUGpNNpHLotln+tiwcA52kWCIgGq1Q== 787 | 788 | node-addon-api@^7.0.0: 789 | version "7.0.0" 790 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" 791 | integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== 792 | 793 | node-fetch@^2.6.7: 794 | version "2.7.0" 795 | resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" 796 | integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== 797 | dependencies: 798 | whatwg-url "^5.0.0" 799 | 800 | node-gyp@^10.0.1: 801 | version "10.0.1" 802 | resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-10.0.1.tgz#205514fc19e5830fa991e4a689f9e81af377a966" 803 | integrity sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg== 804 | dependencies: 805 | env-paths "^2.2.0" 806 | exponential-backoff "^3.1.1" 807 | glob "^10.3.10" 808 | graceful-fs "^4.2.6" 809 | make-fetch-happen "^13.0.0" 810 | nopt "^7.0.0" 811 | proc-log "^3.0.0" 812 | semver "^7.3.5" 813 | tar "^6.1.2" 814 | which "^4.0.0" 815 | 816 | nopt@^5.0.0: 817 | version "5.0.0" 818 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" 819 | integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== 820 | dependencies: 821 | abbrev "1" 822 | 823 | nopt@^7.0.0: 824 | version "7.2.0" 825 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" 826 | integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA== 827 | dependencies: 828 | abbrev "^2.0.0" 829 | 830 | npmlog@^5.0.1: 831 | version "5.0.1" 832 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" 833 | integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== 834 | dependencies: 835 | are-we-there-yet "^2.0.0" 836 | console-control-strings "^1.1.0" 837 | gauge "^3.0.0" 838 | set-blocking "^2.0.0" 839 | 840 | object-assign@^4.1.1: 841 | version "4.1.1" 842 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 843 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 844 | 845 | once@^1.3.0: 846 | version "1.4.0" 847 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 848 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 849 | dependencies: 850 | wrappy "1" 851 | 852 | p-map@^4.0.0: 853 | version "4.0.0" 854 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" 855 | integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== 856 | dependencies: 857 | aggregate-error "^3.0.0" 858 | 859 | path-is-absolute@^1.0.0: 860 | version "1.0.1" 861 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 862 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 863 | 864 | path-key@^3.1.0: 865 | version "3.1.1" 866 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 867 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 868 | 869 | path-scurry@^1.10.1: 870 | version "1.10.1" 871 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" 872 | integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== 873 | dependencies: 874 | lru-cache "^9.1.1 || ^10.0.0" 875 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 876 | 877 | path-scurry@^1.10.2: 878 | version "1.10.2" 879 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.2.tgz#8f6357eb1239d5fa1da8b9f70e9c080675458ba7" 880 | integrity sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA== 881 | dependencies: 882 | lru-cache "^10.2.0" 883 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0" 884 | 885 | proc-log@^3.0.0: 886 | version "3.0.0" 887 | resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" 888 | integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== 889 | 890 | promise-retry@^2.0.1: 891 | version "2.0.1" 892 | resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" 893 | integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== 894 | dependencies: 895 | err-code "^2.0.2" 896 | retry "^0.12.0" 897 | 898 | readable-stream@^3.6.0: 899 | version "3.6.2" 900 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" 901 | integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== 902 | dependencies: 903 | inherits "^2.0.3" 904 | string_decoder "^1.1.1" 905 | util-deprecate "^1.0.1" 906 | 907 | retry@^0.12.0: 908 | version "0.12.0" 909 | resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" 910 | integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== 911 | 912 | rimraf@5.0.0: 913 | version "5.0.0" 914 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.0.tgz#5bda14e410d7e4dd522154891395802ce032c2cb" 915 | integrity sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g== 916 | dependencies: 917 | glob "^10.0.0" 918 | 919 | rimraf@^3.0.2: 920 | version "3.0.2" 921 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 922 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 923 | dependencies: 924 | glob "^7.1.3" 925 | 926 | safe-buffer@~5.2.0: 927 | version "5.2.1" 928 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 929 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 930 | 931 | "safer-buffer@>= 2.1.2 < 3.0.0": 932 | version "2.1.2" 933 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 934 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 935 | 936 | semver@^6.0.0: 937 | version "6.3.1" 938 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" 939 | integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== 940 | 941 | semver@^7.3.5: 942 | version "7.6.0" 943 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" 944 | integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== 945 | dependencies: 946 | lru-cache "^6.0.0" 947 | 948 | set-blocking@^2.0.0: 949 | version "2.0.0" 950 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 951 | integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== 952 | 953 | shebang-command@^2.0.0: 954 | version "2.0.0" 955 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 956 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 957 | dependencies: 958 | shebang-regex "^3.0.0" 959 | 960 | shebang-regex@^3.0.0: 961 | version "3.0.0" 962 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 963 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 964 | 965 | signal-exit@^3.0.0: 966 | version "3.0.7" 967 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" 968 | integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== 969 | 970 | signal-exit@^4.0.1: 971 | version "4.1.0" 972 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" 973 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== 974 | 975 | smart-buffer@^4.2.0: 976 | version "4.2.0" 977 | resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" 978 | integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== 979 | 980 | socks-proxy-agent@^8.0.1: 981 | version "8.0.2" 982 | resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" 983 | integrity sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g== 984 | dependencies: 985 | agent-base "^7.0.2" 986 | debug "^4.3.4" 987 | socks "^2.7.1" 988 | 989 | socks@^2.7.1: 990 | version "2.7.3" 991 | resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.3.tgz#7d8a75d7ce845c0a96f710917174dba0d543a785" 992 | integrity sha512-vfuYK48HXCTFD03G/1/zkIls3Ebr2YNa4qU9gHDZdblHLiqhJrJGkY3+0Nx0JpN9qBhJbVObc1CNciT1bIZJxw== 993 | dependencies: 994 | ip-address "^9.0.5" 995 | smart-buffer "^4.2.0" 996 | 997 | sprintf-js@^1.1.3: 998 | version "1.1.3" 999 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" 1000 | integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== 1001 | 1002 | ssri@^10.0.0: 1003 | version "10.0.5" 1004 | resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" 1005 | integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== 1006 | dependencies: 1007 | minipass "^7.0.3" 1008 | 1009 | "string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.3: 1010 | version "4.2.3" 1011 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1012 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1013 | dependencies: 1014 | emoji-regex "^8.0.0" 1015 | is-fullwidth-code-point "^3.0.0" 1016 | strip-ansi "^6.0.1" 1017 | 1018 | string-width@^5.0.1, string-width@^5.1.2: 1019 | version "5.1.2" 1020 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" 1021 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== 1022 | dependencies: 1023 | eastasianwidth "^0.2.0" 1024 | emoji-regex "^9.2.2" 1025 | strip-ansi "^7.0.1" 1026 | 1027 | string_decoder@^1.1.1: 1028 | version "1.3.0" 1029 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1030 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1031 | dependencies: 1032 | safe-buffer "~5.2.0" 1033 | 1034 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1035 | version "6.0.1" 1036 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1037 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1038 | dependencies: 1039 | ansi-regex "^5.0.1" 1040 | 1041 | strip-ansi@^7.0.1: 1042 | version "7.1.0" 1043 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" 1044 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== 1045 | dependencies: 1046 | ansi-regex "^6.0.1" 1047 | 1048 | supports-color@5.4.0: 1049 | version "5.4.0" 1050 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" 1051 | integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== 1052 | dependencies: 1053 | has-flag "^3.0.0" 1054 | 1055 | supports-color@^7.1.0: 1056 | version "7.2.0" 1057 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1058 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1059 | dependencies: 1060 | has-flag "^4.0.0" 1061 | 1062 | tar@^6.1.11, tar@^6.1.2: 1063 | version "6.2.1" 1064 | resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" 1065 | integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== 1066 | dependencies: 1067 | chownr "^2.0.0" 1068 | fs-minipass "^2.0.0" 1069 | minipass "^5.0.0" 1070 | minizlib "^2.1.1" 1071 | mkdirp "^1.0.3" 1072 | yallist "^4.0.0" 1073 | 1074 | tr46@~0.0.3: 1075 | version "0.0.3" 1076 | resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 1077 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 1078 | 1079 | tslib@^2.4.0: 1080 | version "2.6.2" 1081 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" 1082 | integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== 1083 | 1084 | type-detect@0.1.1: 1085 | version "0.1.1" 1086 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" 1087 | integrity sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA== 1088 | 1089 | type-detect@^1.0.0: 1090 | version "1.0.0" 1091 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" 1092 | integrity sha512-f9Uv6ezcpvCQjJU0Zqbg+65qdcszv3qUQsZfjdRbWiZ7AMenrX1u0lNk9EoWWX6e1F+NULyg27mtdeZ5WhpljA== 1093 | 1094 | unique-filename@^3.0.0: 1095 | version "3.0.0" 1096 | resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" 1097 | integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== 1098 | dependencies: 1099 | unique-slug "^4.0.0" 1100 | 1101 | unique-slug@^4.0.0: 1102 | version "4.0.0" 1103 | resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" 1104 | integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== 1105 | dependencies: 1106 | imurmurhash "^0.1.4" 1107 | 1108 | util-deprecate@^1.0.1: 1109 | version "1.0.2" 1110 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1111 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1112 | 1113 | webidl-conversions@^3.0.0: 1114 | version "3.0.1" 1115 | resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 1116 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 1117 | 1118 | whatwg-url@^5.0.0: 1119 | version "5.0.0" 1120 | resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 1121 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 1122 | dependencies: 1123 | tr46 "~0.0.3" 1124 | webidl-conversions "^3.0.0" 1125 | 1126 | which@^2.0.1: 1127 | version "2.0.2" 1128 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1129 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1130 | dependencies: 1131 | isexe "^2.0.0" 1132 | 1133 | which@^4.0.0: 1134 | version "4.0.0" 1135 | resolved "https://registry.yarnpkg.com/which/-/which-4.0.0.tgz#cd60b5e74503a3fbcfbf6cd6b4138a8bae644c1a" 1136 | integrity sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg== 1137 | dependencies: 1138 | isexe "^3.1.1" 1139 | 1140 | wide-align@^1.1.2: 1141 | version "1.1.5" 1142 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" 1143 | integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== 1144 | dependencies: 1145 | string-width "^1.0.2 || 2 || 3 || 4" 1146 | 1147 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": 1148 | version "7.0.0" 1149 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1150 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1151 | dependencies: 1152 | ansi-styles "^4.0.0" 1153 | string-width "^4.1.0" 1154 | strip-ansi "^6.0.0" 1155 | 1156 | wrap-ansi@^8.1.0: 1157 | version "8.1.0" 1158 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" 1159 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== 1160 | dependencies: 1161 | ansi-styles "^6.1.0" 1162 | string-width "^5.0.1" 1163 | strip-ansi "^7.0.1" 1164 | 1165 | wrappy@1: 1166 | version "1.0.2" 1167 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1168 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1169 | 1170 | yallist@^4.0.0: 1171 | version "4.0.0" 1172 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1173 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1174 | 1175 | yamlize@^0.8.0: 1176 | version "0.8.0" 1177 | resolved "https://registry.yarnpkg.com/yamlize/-/yamlize-0.8.0.tgz#5d263fff74329b7435ff163eeee8e137298a7f5e" 1178 | integrity sha512-2sXxXTr4gZuIP1TmVmm9yJc/WirEKsqctk/gk4MzPGuochfSAY4+OxKXXqFj02HejQmEgAFRun7b0Ec6YjlE7A== 1179 | dependencies: 1180 | js-yaml "^4.1.0" 1181 | mkdirp "3.0.1" 1182 | nested-obj "^0.0.1" 1183 | --------------------------------------------------------------------------------