diff --git a/.github/workflows/test-js-packages.yml b/.github/workflows/test-js-packages.yml index e2ffc5087be..31bd1219654 100644 --- a/.github/workflows/test-js-packages.yml +++ b/.github/workflows/test-js-packages.yml @@ -47,6 +47,7 @@ jobs: retention-days: 3 build-noir-wasm: + needs: [build-noirc-abi] runs-on: ubuntu-latest timeout-minutes: 30 @@ -54,28 +55,34 @@ jobs: - name: Checkout sources uses: actions/checkout@v4 - - name: Setup Nix - uses: ./.github/actions/nix + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.71.1 + + - uses: Swatinem/rust-cache@v2 with: - github-token: ${{ secrets.GITHUB_TOKEN }} - nix-cache-name: "noir" - cachix-auth-token: ${{ secrets.CACHIXAUTHTOKEN }} + key: noir-wasm + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} - - name: Build wasm package - run: | - nix build -L .#noir_wasm + - name: Download noirc_abi_wasm package artifact + uses: actions/download-artifact@v3 + with: + name: noirc_abi_wasm + path: ./tooling/noirc_abi_wasm - - name: Dereference symlink - run: echo "UPLOAD_PATH=$(readlink -f ./result/noir_wasm)" >> $GITHUB_ENV + - name: Install Yarn dependencies + uses: ./.github/actions/setup + + - name: Build noir_wasm + run: yarn workspace @noir-lang/noir_wasm build - name: Upload artifact uses: actions/upload-artifact@v3 with: name: noir_wasm - path: ${{ env.UPLOAD_PATH }} + path: ./compiler/wasm retention-days: 3 - build-acvm-js: runs-on: ubuntu-latest timeout-minutes: 30 @@ -289,25 +296,24 @@ jobs: name: noir_wasm path: ./compiler/wasm + - name: Install Yarn dependencies + uses: ./.github/actions/setup + - name: Download nargo binary uses: actions/download-artifact@v3 with: name: nargo path: ./nargo - - name: Compile fixtures with Nargo CLI - working-directory: ./compiler/wasm/fixtures + - name: Set nargo on PATH run: | - nargo_binary=${{ github.workspace }}/nargo/nargo + nargo_binary="${{ github.workspace }}/nargo/nargo" chmod +x $nargo_binary - for dir in $(ls -d */); do - pushd $dir/noir-script - $nargo_binary compile - popd - done + echo "$(dirname $nargo_binary)" >> $GITHUB_PATH + export PATH="$PATH:$(dirname $nargo_binary)" - - name: Install Yarn dependencies - uses: ./.github/actions/setup + - name: Build fixtures + run: yarn workspace @noir-lang/noir_wasm test:build_fixtures - name: Install Playwright uses: ./.github/actions/install-playwright diff --git a/Cargo.lock b/Cargo.lock index 8aca450c6cd..438d74b1b2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2872,6 +2872,7 @@ dependencies = [ "noirc_driver", "noirc_errors", "noirc_frontend", + "rust-embed", "serde", "tracing-subscriber", "tracing-web", diff --git a/Cargo.toml b/Cargo.toml index 5469a63f3dd..05139934c62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,6 +127,7 @@ jsonrpc = { version = "0.16.0", features = ["minreq_http"] } tracing = "0.1.40" tracing-web = "0.1.3" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +rust-embed = "6.6.0" [profile.dev] # This is required to be able to run `cargo test` in acvm_js due to the `locals exceeds maximum` error. diff --git a/compiler/integration-tests/test/browser/compile_prove_verify.test.ts b/compiler/integration-tests/test/browser/compile_prove_verify.test.ts index 29e2fbc55b8..0a829def09e 100644 --- a/compiler/integration-tests/test/browser/compile_prove_verify.test.ts +++ b/compiler/integration-tests/test/browser/compile_prove_verify.test.ts @@ -1,22 +1,13 @@ import { expect } from '@esm-bundle/chai'; import * as TOML from 'smol-toml'; -import newCompiler, { - CompiledProgram, - PathToFileSourceMap, - compile, - init_log_level as compilerLogLevel, -} from '@noir-lang/noir_wasm'; +import { compile, createFileManager } from '@noir-lang/noir_wasm'; import { Noir } from '@noir-lang/noir_js'; import { InputMap } from '@noir-lang/noirc_abi'; import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; import { getFile } from './utils.js'; -await newCompiler(); - -compilerLogLevel('INFO'); - const test_cases = [ { case: 'test_programs/execution_success/1_mul', @@ -32,12 +23,11 @@ const suite = Mocha.Suite.create(mocha.suite, 'Noir end to end test'); suite.timeout(60 * 20e3); //20mins -function getCircuit(noirSource: string): CompiledProgram { - const sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code('main.nr', noirSource); - - // We're ignoring this in the resolver but pass in something sensible. - const result = compile('main.nr', undefined, undefined, sourceMap); +async function getCircuit(projectPath: string) { + const fm = createFileManager('/'); + await fm.writeFile('./src/main.nr', await getFile(`${projectPath}/src/main.nr`)); + await fm.writeFile('./Nargo.toml', await getFile(`${projectPath}/Nargo.toml`)); + const result = await compile(fm); if (!('program' in result)) { throw new Error('Compilation failed'); } @@ -51,11 +41,9 @@ test_cases.forEach((testInfo) => { const base_relative_path = '../../../../..'; const test_case = testInfo.case; - const noir_source = await getFile(`${base_relative_path}/${test_case}/src/main.nr`); - - let noir_program: CompiledProgram; + let noir_program; try { - noir_program = getCircuit(noir_source); + noir_program = await getCircuit(`${base_relative_path}/${test_case}`); expect(noir_program, 'Compile output ').to.be.an('object'); } catch (e) { @@ -66,7 +54,7 @@ test_cases.forEach((testInfo) => { const backend = new BarretenbergBackend(noir_program); const program = new Noir(noir_program, backend); - const prover_toml = await getFile(`${base_relative_path}/${test_case}/Prover.toml`); + const prover_toml = await new Response(await getFile(`${base_relative_path}/${test_case}/Prover.toml`)).text(); const inputs: InputMap = TOML.parse(prover_toml) as InputMap; // JS Proving diff --git a/compiler/integration-tests/test/browser/recursion.test.ts b/compiler/integration-tests/test/browser/recursion.test.ts index 2097164ebcb..80199de5701 100644 --- a/compiler/integration-tests/test/browser/recursion.test.ts +++ b/compiler/integration-tests/test/browser/recursion.test.ts @@ -2,59 +2,46 @@ import { expect } from '@esm-bundle/chai'; import { TEST_LOG_LEVEL } from '../environment.js'; import { Logger } from 'tslog'; -import newCompiler, { - CompiledProgram, - PathToFileSourceMap, - compile, - init_log_level as compilerLogLevel, -} from '@noir-lang/noir_wasm'; import { acvm, abi, Noir } from '@noir-lang/noir_js'; import * as TOML from 'smol-toml'; import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; import { getFile } from './utils.js'; import { Field, InputMap } from '@noir-lang/noirc_abi'; +import { createFileManager, compile } from '@noir-lang/noir_wasm'; const logger = new Logger({ name: 'test', minLevel: TEST_LOG_LEVEL }); const { default: initACVM } = acvm; const { default: newABICoder } = abi; -await newCompiler(); await newABICoder(); await initACVM(); -compilerLogLevel('INFO'); - const base_relative_path = '../../../../..'; const circuit_main = 'test_programs/execution_success/assert_statement'; const circuit_recursion = 'compiler/integration-tests/circuits/recursion'; -function getCircuit(noirSource: string): CompiledProgram { - const sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code('main.nr', noirSource); - const result = compile('main.nr', undefined, undefined, sourceMap); +async function getCircuit(projectPath: string) { + const fm = createFileManager('/'); + await fm.writeFile('./src/main.nr', await getFile(`${projectPath}/src/main.nr`)); + await fm.writeFile('./Nargo.toml', await getFile(`${projectPath}/Nargo.toml`)); + const result = await compile(fm); if (!('program' in result)) { throw new Error('Compilation failed'); } - return result.program; } describe('It compiles noir program code, receiving circuit bytes and abi object.', () => { - let circuit_main_source; let circuit_main_toml; - let circuit_recursion_source; before(async () => { - circuit_main_source = await getFile(`${base_relative_path}/${circuit_main}/src/main.nr`); - circuit_main_toml = await getFile(`${base_relative_path}/${circuit_main}/Prover.toml`); - - circuit_recursion_source = await getFile(`${base_relative_path}/${circuit_recursion}/src/main.nr`); + circuit_main_toml = await new Response(await getFile(`${base_relative_path}/${circuit_main}/Prover.toml`)).text(); }); it('Should generate valid inner proof for correct input, then verify proof within a proof', async () => { - const main_program = getCircuit(circuit_main_source); + const main_program = await getCircuit(`${base_relative_path}/${circuit_main}`); const main_inputs: InputMap = TOML.parse(circuit_main_toml) as InputMap; const main_backend = new BarretenbergBackend(main_program); @@ -83,7 +70,7 @@ describe('It compiles noir program code, receiving circuit bytes and abi object. logger.debug('recursion_inputs', recursion_inputs); - const recursion_program = await getCircuit(circuit_recursion_source); + const recursion_program = await getCircuit(`${base_relative_path}/${circuit_recursion}`); const recursion_backend = new BarretenbergBackend(recursion_program); diff --git a/compiler/integration-tests/test/browser/utils.ts b/compiler/integration-tests/test/browser/utils.ts index 35588407193..a5e3fe1bc61 100644 --- a/compiler/integration-tests/test/browser/utils.ts +++ b/compiler/integration-tests/test/browser/utils.ts @@ -1,8 +1,8 @@ -export async function getFile(file_path: string): Promise { +export async function getFile(file_path: string): Promise> { const file_url = new URL(file_path, import.meta.url); const response = await fetch(file_url); if (!response.ok) throw new Error('Network response was not OK'); - return await response.text(); + return response.body as ReadableStream; } diff --git a/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts b/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts index 7a25669d22a..9cdd80edc15 100644 --- a/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts +++ b/compiler/integration-tests/test/node/onchain_recursive_verification.test.ts @@ -2,35 +2,35 @@ import { expect } from 'chai'; import { ethers } from 'hardhat'; import { readFileSync } from 'node:fs'; -import { resolve } from 'path'; +import { resolve, join } from 'path'; import toml from 'toml'; -import { - compile, - CompiledProgram, - init_log_level as compilerLogLevel, - PathToFileSourceMap, -} from '@noir-lang/noir_wasm'; import { Noir } from '@noir-lang/noir_js'; import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; import { Field, InputMap } from '@noir-lang/noirc_abi'; -compilerLogLevel('INFO'); +import { compile, createFileManager } from '@noir-lang/noir_wasm'; it(`smart contract can verify a recursive proof`, async () => { - const innerSourcePath = resolve(`../../test_programs/execution_success/assert_statement/src/main.nr`); - const sourceMapInnerProgram = new PathToFileSourceMap(); - sourceMapInnerProgram.add_source_code(innerSourcePath, readFileSync(innerSourcePath, 'utf-8')); - const innerProgram = ( - compile(innerSourcePath, undefined, undefined, sourceMapInnerProgram) as { program: CompiledProgram } - ).program; - - const recursionSourcePath = resolve(`./circuits/recursion/src/main.nr`); - const sourceMapRecursionProgram = new PathToFileSourceMap(); - sourceMapRecursionProgram.add_source_code(recursionSourcePath, readFileSync(recursionSourcePath, 'utf-8')); - const recursionProgram = ( - compile(recursionSourcePath, undefined, undefined, sourceMapRecursionProgram) as { program: CompiledProgram } - ).program; + const basePath = resolve(join(__dirname, '../../../../')); + const fm = createFileManager(basePath); + const innerCompilationResult = await compile( + fm, + join(basePath, './test_programs/execution_success/assert_statement'), + ); + if (!('program' in innerCompilationResult)) { + throw new Error('Compilation failed'); + } + const innerProgram = innerCompilationResult.program; + + const recursionCompilationResult = await compile( + fm, + join(basePath, './compiler/integration-tests/circuits/recursion'), + ); + if (!('program' in recursionCompilationResult)) { + throw new Error('Compilation failed'); + } + const recursionProgram = recursionCompilationResult.program; // Intermediate proof @@ -38,8 +38,9 @@ it(`smart contract can verify a recursive proof`, async () => { const inner = new Noir(innerProgram); const inner_prover_toml = readFileSync( - resolve(`../../test_programs/execution_success/assert_statement/Prover.toml`), + join(basePath, `./test_programs/execution_success/assert_statement/Prover.toml`), ).toString(); + const inner_inputs = toml.parse(inner_prover_toml); const { witness: main_witness } = await inner.execute(inner_inputs); diff --git a/compiler/integration-tests/test/node/smart_contract_verifier.test.ts b/compiler/integration-tests/test/node/smart_contract_verifier.test.ts index a93a2fc1508..d870956ea7a 100644 --- a/compiler/integration-tests/test/node/smart_contract_verifier.test.ts +++ b/compiler/integration-tests/test/node/smart_contract_verifier.test.ts @@ -5,11 +5,10 @@ import { readFileSync } from 'node:fs'; import { resolve } from 'path'; import toml from 'toml'; -import { PathToFileSourceMap, compile, init_log_level as compilerLogLevel } from '@noir-lang/noir_wasm'; import { Noir } from '@noir-lang/noir_js'; import { BarretenbergBackend } from '@noir-lang/backend_barretenberg'; -compilerLogLevel('INFO'); +import { compile, createFileManager } from '@noir-lang/noir_wasm'; const test_cases = [ { @@ -31,11 +30,8 @@ test_cases.forEach((testInfo) => { const base_relative_path = '../..'; const test_case = testInfo.case; - const noirSourcePath = resolve(`${base_relative_path}/${test_case}/src/main.nr`); - const sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code(noirSourcePath, readFileSync(noirSourcePath, 'utf-8')); - - const compileResult = compile(noirSourcePath, undefined, undefined, sourceMap); + const fm = createFileManager(resolve(`${base_relative_path}/${test_case}`)); + const compileResult = await compile(fm); if (!('program' in compileResult)) { throw new Error('Compilation failed'); } diff --git a/compiler/noirc_driver/Cargo.toml b/compiler/noirc_driver/Cargo.toml index 32c418b0adb..eb9650e8aec 100644 --- a/compiler/noirc_driver/Cargo.toml +++ b/compiler/noirc_driver/Cargo.toml @@ -21,7 +21,7 @@ iter-extended.workspace = true fm.workspace = true serde.workspace = true fxhash.workspace = true -rust-embed = "6.6.0" +rust-embed.workspace = true tracing.workspace = true aztec_macros = { path = "../../aztec_macros" } diff --git a/compiler/wasm/.eslintrc.js b/compiler/wasm/.eslintrc.js index 33335c2a877..5a2cc7f1ec0 100644 --- a/compiler/wasm/.eslintrc.js +++ b/compiler/wasm/.eslintrc.js @@ -1,3 +1,3 @@ module.exports = { - extends: ["../../.eslintrc.js"], + extends: ['../../.eslintrc.js'], }; diff --git a/compiler/wasm/.gitignore b/compiler/wasm/.gitignore index f968dafbcc3..f9d4af3fe3b 100644 --- a/compiler/wasm/.gitignore +++ b/compiler/wasm/.gitignore @@ -1 +1,3 @@ noir-script/target +dist +build diff --git a/compiler/wasm/.mocharc.json b/compiler/wasm/.mocharc.json index 5e3ee32d901..8009c66f9a8 100644 --- a/compiler/wasm/.mocharc.json +++ b/compiler/wasm/.mocharc.json @@ -1,7 +1,13 @@ { - "extension": [ - "ts" - ], - "spec": "test/node/**/*.test.ts", - "require": "ts-node/register" -} \ No newline at end of file + "require": "ts-node/register", + "extensions": [ + "ts" + ], + "spec": [ + "./test/**/!(browser)/*.test.ts" + ], + "node-option": [ + "loader=ts-node" + ] + } + \ No newline at end of file diff --git a/compiler/wasm/Cargo.toml b/compiler/wasm/Cargo.toml index 7ea138b60a4..7af26269106 100644 --- a/compiler/wasm/Cargo.toml +++ b/compiler/wasm/Cargo.toml @@ -30,5 +30,11 @@ tracing-web.workspace = true # so that we can enable the js feature in getrandom. getrandom = { workspace = true, features = ["js"] } +# This is an unused dependency, we are adding it +# so that we can enable the debug-embed feature in rust-embed. +# This is needed for rust-embed to include the stdlib sources in dev mode +# while simultaneously allowing us to deactivate wasm-opt for speed. +rust-embed = { workspace = true, features = ["debug-embed"] } + [build-dependencies] -build-data.workspace = true +build-data.workspace = true \ No newline at end of file diff --git a/compiler/wasm/build-fixtures.sh b/compiler/wasm/build-fixtures.sh new file mode 100755 index 00000000000..3a2330d4726 --- /dev/null +++ b/compiler/wasm/build-fixtures.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +nargo compile --program-dir ./test/fixtures/simple +nargo compile --program-dir ./test/fixtures/with-deps +nargo compile --program-dir ./test/fixtures/noir-contract \ No newline at end of file diff --git a/compiler/wasm/build.sh b/compiler/wasm/build.sh deleted file mode 100755 index 24af149bcea..00000000000 --- a/compiler/wasm/build.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -function require_command { - if ! command -v "$1" >/dev/null 2>&1; then - echo "Error: $1 is required but not installed." >&2 - exit 1 - fi -} -function check_installed { - if ! command -v "$1" >/dev/null 2>&1; then - echo "$1 is not installed. Please install it." >&2 - return 1 - fi - return 0 -} -function run_or_fail { - "$@" - local status=$? - if [ $status -ne 0 ]; then - echo "Command '$*' failed with exit code $status" >&2 - exit $status - fi -} - -require_command jq -require_command cargo -require_command wasm-bindgen -check_installed wasm-opt - -self_path=$(dirname "$(readlink -f "$0")") -export pname=$(cargo read-manifest | jq -r '.name') -export CARGO_TARGET_DIR=$self_path/target - -rm -rf $self_path/outputs >/dev/null 2>&1 -rm -rf $self_path/result >/dev/null 2>&1 - -if [ -n "$out" ]; then - echo "Will install package to $out (defined outside installPhase.sh script)" -else - export out="$self_path/outputs/out" - echo "Will install package to $out" -fi - -run_or_fail $self_path/buildPhaseCargoCommand.sh -run_or_fail $self_path/installPhase.sh - -ln -s $out $self_path/result diff --git a/compiler/wasm/buildPhaseCargoCommand.sh b/compiler/wasm/buildPhaseCargoCommand.sh deleted file mode 100755 index 2ab0f1eb3cb..00000000000 --- a/compiler/wasm/buildPhaseCargoCommand.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -function run_or_fail { - "$@" - local status=$? - if [ $status -ne 0 ]; then - echo "Command '$*' failed with exit code $status" >&2 - exit $status - fi -} -function run_if_available { - if command -v "$1" >/dev/null 2>&1; then - "$@" - else - echo "$1 is not installed. Please install it to use this feature." >&2 - fi -} - -export self_path=$(dirname "$(readlink -f "$0")") - -# Clear out the existing build artifacts as these aren't automatically removed by wasm-pack. -if [ -d ./pkg/ ]; then - rm -rf $self_path/pkg/ -fi - -TARGET=wasm32-unknown-unknown -WASM_BINARY=$CARGO_TARGET_DIR/$TARGET/release/${pname}.wasm - -NODE_DIR=$self_path/nodejs/ -BROWSER_DIR=$self_path/web/ -NODE_WASM=${NODE_DIR}/${pname}_bg.wasm -BROWSER_WASM=${BROWSER_DIR}/${pname}_bg.wasm - -# Build the new wasm package -run_or_fail cargo build --lib --release --target $TARGET --package ${pname} ${cargoExtraArgs} -run_or_fail wasm-bindgen $WASM_BINARY --out-dir $NODE_DIR --typescript --target nodejs -run_or_fail wasm-bindgen $WASM_BINARY --out-dir $BROWSER_DIR --typescript --target web -run_if_available wasm-opt $NODE_WASM -o $NODE_WASM -O -run_if_available wasm-opt $BROWSER_WASM -o $BROWSER_WASM -O \ No newline at end of file diff --git a/compiler/wasm/installPhase.sh b/compiler/wasm/installPhase.sh deleted file mode 100755 index e5be98a3339..00000000000 --- a/compiler/wasm/installPhase.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash -export self_path=$(dirname "$(readlink -f "$0")") - -export out_path=$out/noir_wasm - -mkdir -p $out_path -cp $self_path/README.md $out_path/ -cp $self_path/package.json $out_path/ -cp -r $self_path/nodejs $out_path/ -cp -r $self_path/web $out_path/ diff --git a/compiler/wasm/package.json b/compiler/wasm/package.json index 38fd118f189..1235a748d13 100644 --- a/compiler/wasm/package.json +++ b/compiler/wasm/package.json @@ -5,12 +5,16 @@ ], "version": "0.22.0", "license": "(MIT OR Apache-2.0)", - "main": "./nodejs/noir_wasm.js", - "types": "./web/noir_wasm.d.ts", - "module": "./web/noir_wasm.js", + "main": "dist/main.js", + "types": "./dist/types/src/index.d.cts", + "exports": { + "node": "./dist/node/main.js", + "default": "./dist/web/main.mjs", + "import": "./dist/web/main.mjs", + "require": "./dist/node/main.js" + }, "files": [ - "nodejs", - "web", + "dist", "package.json" ], "sideEffects": false, @@ -24,22 +28,51 @@ "url": "https://github.com/noir-lang/noir/issues" }, "scripts": { - "build": "bash ./build.sh", - "test": "yarn test:node && yarn test:browser", - "test:node": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\"}' mocha", + "build": "WASM_OPT=$(bash -c ./wasm-opt-check.sh) webpack", + "test": "yarn test:build_fixtures && yarn test:node && yarn test:browser", + "test:build_fixtures": "./build-fixtures.sh", "test:browser": "web-test-runner", - "clean": "chmod u+w web nodejs || true && rm -rf ./nodejs ./web ./target ./result", + "test:node": "NODE_NO_WARNINGS=1 mocha --config ./.mocharc.json", + "clean": "rm -rf ./build ./target ./dist public/fixtures/simple/target public/fixtures/with-deps/target", "nightly:version": "jq --arg new_version \"-$(git rev-parse --short HEAD)$1\" '.version = .version + $new_version' package.json > package-tmp.json && mv package-tmp.json package.json", "publish": "echo 📡 publishing `$npm_package_name` && yarn npm publish", - "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0", - "build:nix": "nix build -L .#noir_wasm", - "install:from:nix": "yarn clean && yarn build:nix && cp -rL ./result/noir_wasm/nodejs ./ && cp -rL ./result/noir_wasm/web ./" + "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "devDependencies": { "@esm-bundle/chai": "^4.3.4-fix.0", + "@ltd/j-toml": "^1.38.0", + "@noir-lang/noirc_abi": "workspace:*", + "@types/adm-zip": "^0.5.0", + "@types/chai": "^4", + "@types/mocha": "^10.0.6", + "@types/mocha-each": "^2", + "@types/node": "^20.10.5", + "@types/path-browserify": "^1", + "@types/readable-stream": "^4", + "@types/sinon": "^17", + "@wasm-tool/wasm-pack-plugin": "^1.7.0", "@web/dev-server-esbuild": "^0.3.6", - "@web/test-runner": "^0.15.3", - "@web/test-runner-playwright": "^0.10.0", - "mocha": "^10.2.0" + "@web/test-runner": "^0.18.0", + "@web/test-runner-playwright": "^0.11.0", + "adm-zip": "^0.5.0", + "assert": "^2.1.0", + "browserify-fs": "^1.0.0", + "chai": "^4.3.10", + "copy-webpack-plugin": "^11.0.0", + "html-webpack-plugin": "^5.5.4", + "memfs": "^4.6.0", + "mocha": "^10.2.0", + "mocha-each": "^2.0.1", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "readable-stream": "^4.4.2", + "sinon": "^17.0.1", + "ts-loader": "^9.5.1", + "ts-node": "^10.9.1", + "typescript": "~5.2.2", + "unzipit": "^1.4.3", + "url": "^0.11.3", + "webpack": "^5.49.0", + "webpack-cli": "^4.7.2" } } diff --git a/compiler/wasm/src/index.cts b/compiler/wasm/src/index.cts new file mode 100644 index 00000000000..31d169e8268 --- /dev/null +++ b/compiler/wasm/src/index.cts @@ -0,0 +1,49 @@ +import { FileManager } from './noir/file-manager/file-manager'; +import { createNodejsFileManager } from './noir/file-manager/nodejs-file-manager'; +import { NoirWasmCompiler } from './noir/noir-wasm-compiler'; +import { LogData, LogFn } from './utils'; +import { CompilationResult } from './types/noir_artifact'; + +async function compile( + fileManager: FileManager, + projectPath?: string, + logFn?: LogFn, + debugLogFn?: LogFn, +): Promise { + if (logFn && !debugLogFn) { + debugLogFn = logFn; + } + + const cjs = await require('../build/cjs'); + const compiler = await NoirWasmCompiler.new( + fileManager, + projectPath ?? fileManager.getDataDir(), + cjs, + new cjs.PathToFileSourceMap(), + { + log: + logFn ?? + function (msg: string, data?: LogData) { + if (data) { + console.log(msg, data); + } else { + console.log(msg); + } + }, + debugLog: + debugLogFn ?? + function (msg: string, data?: LogData) { + if (data) { + console.debug(msg, data); + } else { + console.debug(msg); + } + }, + }, + ); + return await compiler.compile(); +} + +const createFileManager = createNodejsFileManager; + +export { compile, createFileManager, CompilationResult }; diff --git a/compiler/wasm/src/index.mts b/compiler/wasm/src/index.mts new file mode 100644 index 00000000000..6340e2dc37a --- /dev/null +++ b/compiler/wasm/src/index.mts @@ -0,0 +1,51 @@ +import { FileManager } from './noir/file-manager/file-manager'; +import { createNodejsFileManager } from './noir/file-manager/nodejs-file-manager'; +import { NoirWasmCompiler } from './noir/noir-wasm-compiler'; +import { LogData, LogFn } from './utils'; +import { CompilationResult } from './types/noir_artifact'; + +async function compile( + fileManager: FileManager, + projectPath?: string, + logFn?: LogFn, + debugLogFn?: LogFn, +): Promise { + if (logFn && !debugLogFn) { + debugLogFn = logFn; + } + + const esm = await import(/* webpackMode: "eager" */ '../build/esm'); + await esm.default(); + + const compiler = await NoirWasmCompiler.new( + fileManager, + projectPath ?? fileManager.getDataDir(), + esm, + new esm.PathToFileSourceMap(), + { + log: + logFn ?? + function (msg: string, data?: LogData) { + if (data) { + console.log(msg, data); + } else { + console.log(msg); + } + }, + debugLog: + debugLogFn ?? + function (msg: string, data?: LogData) { + if (data) { + console.debug(msg, data); + } else { + console.debug(msg); + } + }, + }, + ); + return await compiler.compile(); +} + +const createFileManager = createNodejsFileManager; + +export { compile, createFileManager, CompilationResult }; diff --git a/compiler/wasm/src/lib.rs b/compiler/wasm/src/lib.rs index e10b992a00e..6d737a0ea6d 100644 --- a/compiler/wasm/src/lib.rs +++ b/compiler/wasm/src/lib.rs @@ -4,6 +4,7 @@ // See Cargo.toml for explanation. use getrandom as _; +use rust_embed as _; use gloo_utils::format::JsValueSerdeExt; diff --git a/compiler/wasm/src/noir/dependencies/dependency-manager.ts b/compiler/wasm/src/noir/dependencies/dependency-manager.ts new file mode 100644 index 00000000000..944ec0070c5 --- /dev/null +++ b/compiler/wasm/src/noir/dependencies/dependency-manager.ts @@ -0,0 +1,150 @@ +import { join } from 'path'; + +import { Package } from '../package'; +import { Dependency, DependencyResolver } from './dependency-resolver'; +import { DependencyConfig } from '../../types/noir_package_config'; +import { LogData, LogFn } from '../../utils'; + +/** + * Noir Dependency Resolver + */ +export class DependencyManager { + #entryPoint: Package; + #libraries = new Map(); + #dependencies = new Map(); + #log: LogFn; + #resolvers: readonly DependencyResolver[]; + + /** + * Creates a new dependency resolver + * @param resolvers - A list of dependency resolvers to use + * @param entryPoint - The entry point of the project + */ + constructor(resolvers: readonly DependencyResolver[] = [], entryPoint: Package) { + this.#resolvers = resolvers; + this.#entryPoint = entryPoint; + this.#log = (msg: string, _data?: LogData) => { + console.log(msg); + }; + } + + /** + * Gets dependencies for the entry point + */ + public getEntrypointDependencies() { + return this.#dependencies.get('') ?? []; + } + + /** + * Get transitive libraries used by the package + */ + public getLibraries() { + return Array.from(this.#libraries.entries()); + } + + /** + * A map of library dependencies + */ + public getLibraryDependencies() { + const entries = Array.from(this.#dependencies.entries()); + return Object.fromEntries(entries.filter(([name]) => name !== '')); + } + + /** + * Resolves dependencies for a package. + */ + public async resolveDependencies(): Promise { + await this.#breadthFirstResolveDependencies(); + } + + /** + * Gets the version of a dependency in the dependency tree + * @param name - Dependency name + * @returns The dependency's version + */ + public getVersionOf(name: string): string | undefined { + const dep = this.#libraries.get(name); + return dep?.version; + } + + async #breadthFirstResolveDependencies(): Promise { + /** Represents a package to resolve dependencies for */ + type Job = { + /** Package name */ + packageName: string; + /** The package location */ + noirPackage: Package; + }; + + const queue: Job[] = [ + { + packageName: '', + noirPackage: this.#entryPoint, + }, + ]; + + while (queue.length > 0) { + const { packageName, noirPackage } = queue.shift()!; + for (const [name, config] of Object.entries(noirPackage.getDependencies())) { + // TODO what happens if more than one package has the same name but different versions? + if (this.#libraries.has(name)) { + this.#log(`skipping already resolved dependency ${name}`); + this.#dependencies.set(packageName, [...(this.#dependencies.get(packageName) ?? []), name]); + + continue; + } + const dependency = await this.#resolveDependency(noirPackage, config); + if (dependency.package.getType() !== 'lib') { + this.#log(`Non-library package ${name}`, config); + throw new Error(`Dependency ${name} is not a library`); + } + + this.#libraries.set(name, dependency); + this.#dependencies.set(packageName, [...(this.#dependencies.get(packageName) ?? []), name]); + + queue.push({ + noirPackage: dependency.package, + packageName: name, + }); + } + } + } + + async #resolveDependency(pkg: Package, config: DependencyConfig): Promise { + let dependency: Dependency | null = null; + for (const resolver of this.#resolvers) { + dependency = await resolver.resolveDependency(pkg, config); + if (dependency) { + break; + } + } + + if (!dependency) { + throw new Error('Dependency not resolved'); + } + + return dependency; + } + + /** + * Gets the names of the crates in this dependency list + */ + public getPackageNames() { + return [...this.#libraries.keys()]; + } + + /** + * Looks up a dependency + * @param sourceId - The source being resolved + * @returns The path to the resolved file + */ + public findFile(sourceId: string): string | null { + const [lib, ...path] = sourceId.split('/').filter((x) => x); + const dep = this.#libraries.get(lib); + if (dep) { + return join(dep.package.getSrcPath(), ...path); + } else { + return null; + } + } +} diff --git a/compiler/wasm/src/noir/dependencies/dependency-resolver.ts b/compiler/wasm/src/noir/dependencies/dependency-resolver.ts new file mode 100644 index 00000000000..266d2075e1e --- /dev/null +++ b/compiler/wasm/src/noir/dependencies/dependency-resolver.ts @@ -0,0 +1,24 @@ +import { DependencyConfig } from '../../types/noir_package_config'; +import { Package } from '../package'; + +/** + * A Noir dependency + */ +export type Dependency = { + /** version string as determined by the resolver */ + version?: string; + /** the actual package source code */ + package: Package; +}; + +/** + * Resolves a dependency for a package. + */ +export interface DependencyResolver { + /** + * Resolve a dependency for a package. + * @param pkg - The package to resolve dependencies for + * @param dep - The dependency config to resolve + */ + resolveDependency(pkg: Package, dep: DependencyConfig): Promise; +} diff --git a/compiler/wasm/src/noir/dependencies/github-dependency-resolver.ts b/compiler/wasm/src/noir/dependencies/github-dependency-resolver.ts new file mode 100644 index 00000000000..8b08b6f0dd8 --- /dev/null +++ b/compiler/wasm/src/noir/dependencies/github-dependency-resolver.ts @@ -0,0 +1,145 @@ +import { delimiter, join, sep } from 'path'; +import { unzip } from 'unzipit'; + +import { FileManager } from '../file-manager/file-manager'; +import { Package } from '../package'; +import { Dependency, DependencyResolver } from './dependency-resolver'; +import { DependencyConfig, GitDependencyConfig } from '../../types/noir_package_config'; +import { LogData } from '../../utils'; + +/** + * Downloads dependencies from github + */ +export class GithubDependencyResolver implements DependencyResolver { + #fm: FileManager; + #log; + + constructor(fm: FileManager) { + this.#fm = fm; + this.#log = (msg: string, _data?: LogData) => { + console.log(msg); + }; + } + + /** + * Resolves a dependency from github. Returns null if URL is for a different website. + * @param _pkg - The package to resolve the dependency for + * @param dependency - The dependency configuration + * @returns asd + */ + async resolveDependency(_pkg: Package, dependency: DependencyConfig): Promise { + // TODO accept ssh urls? + // TODO github authentication? + if (!('git' in dependency) || !dependency.git.startsWith('https://github.com')) { + return null; + } + + const archivePath = await this.#fetchZipFromGithub(dependency); + const libPath = await this.#extractZip(dependency, archivePath); + return { + version: dependency.tag, + package: await Package.open(libPath, this.#fm), + }; + } + + async #fetchZipFromGithub(dependency: Pick): Promise { + if (!dependency.git.startsWith('https://github.com')) { + throw new Error('Only github dependencies are supported'); + } + + const url = resolveGithubCodeArchive(dependency, 'zip'); + const localArchivePath = join('archives', safeFilename(url.pathname)); + + // TODO should check signature before accepting any file + if (this.#fm.hasFileSync(localArchivePath)) { + this.#log('using cached archive', { url: url.href, path: localArchivePath }); + return localArchivePath; + } + + const response = await fetch(url, { + method: 'GET', + }); + + if (!response.ok || !response.body) { + throw new Error(`Failed to fetch ${url}: ${response.statusText}`); + } + + const tmpFile = localArchivePath + '.tmp'; + await this.#fm.writeFile(tmpFile, response.body); + await this.#fm.moveFile(tmpFile, localArchivePath); + + return localArchivePath; + } + + async #extractZip(dependency: GitDependencyConfig, archivePath: string): Promise { + const gitUrl = new URL(dependency.git); + // extract the archive to this location + const extractLocation = join('libs', safeFilename(gitUrl.pathname + '@' + (dependency.tag ?? 'HEAD'))); + + // where we expect to find this package after extraction + // it might already exist if the archive got unzipped previously + const packagePath = join(extractLocation, dependency.directory ?? ''); + + if (this.#fm.hasFileSync(packagePath)) { + return packagePath; + } + + const { entries } = await unzip(await this.#fm.readFile(archivePath)); + + // extract to a temporary directory, then move it to the final location + // TODO empty the temp directory first + const tmpExtractLocation = extractLocation + '.tmp'; + for (const entry of Object.values(entries)) { + if (entry.isDirectory) { + continue; + } + + // remove the first path segment, because it'll be the archive name + const name = stripSegments(entry.name, 1); + const path = join(tmpExtractLocation, name); + await this.#fm.writeFile(path, (await entry.blob()).stream()); + } + + await this.#fm.moveFile(tmpExtractLocation, extractLocation); + + return packagePath; + } +} + +/** + * Strips the first n segments from a path + */ +function stripSegments(path: string, count: number): string { + const segments = path.split(sep).filter(Boolean); + return segments.slice(count).join(sep); +} + +/** + * Returns a safe filename for a value + * @param val - The value to convert + */ +export function safeFilename(val: string): string { + if (!val) { + throw new Error('invalid value'); + } + + return val.replaceAll(sep, '_').replaceAll(delimiter, '_').replace(/^_+/, ''); +} + +/** + * Resolves a dependency's archive URL. + * @param dependency - The dependency configuration + * @returns The URL to the library archive + */ +export function resolveGithubCodeArchive(dependency: GitDependencyConfig, format: 'zip' | 'tar'): URL { + const gitUrl = new URL(dependency.git); + const [owner, repo] = gitUrl.pathname.slice(1).split('/'); + const ref = dependency.tag ?? 'HEAD'; + const extension = format === 'zip' ? 'zip' : 'tar.gz'; + + if (!owner || !repo || gitUrl.hostname !== 'github.com') { + throw new Error('Invalid Github repository URL'); + } + + return new URL(`https://github.com/${owner}/${repo}/archive/${ref}.${extension}`); +} diff --git a/compiler/wasm/src/noir/dependencies/local-dependency-resolver.ts b/compiler/wasm/src/noir/dependencies/local-dependency-resolver.ts new file mode 100644 index 00000000000..50338421143 --- /dev/null +++ b/compiler/wasm/src/noir/dependencies/local-dependency-resolver.ts @@ -0,0 +1,31 @@ +import { isAbsolute, join } from 'path'; + +import { FileManager } from '../file-manager/file-manager'; +import { Package } from '../package'; +import { Dependency, DependencyResolver } from './dependency-resolver'; +import { DependencyConfig } from '../../types/noir_package_config'; + +/** + * Resolves dependencies on-disk, relative to current package + */ +export class LocalDependencyResolver implements DependencyResolver { + #fm: FileManager; + + constructor(fm: FileManager) { + this.#fm = fm; + } + + async resolveDependency(parent: Package, config: DependencyConfig): Promise { + if ('path' in config) { + const parentPath = parent.getPackagePath(); + const dependencyPath = isAbsolute(config.path) ? config.path : join(parentPath, config.path); + return { + // unknown version, Nargo.toml doesn't have a version field + version: undefined, + package: await Package.open(dependencyPath, this.#fm), + }; + } else { + return null; + } + } +} diff --git a/compiler/wasm/src/noir/file-manager/file-manager.ts b/compiler/wasm/src/noir/file-manager/file-manager.ts new file mode 100644 index 00000000000..297e9f541e6 --- /dev/null +++ b/compiler/wasm/src/noir/file-manager/file-manager.ts @@ -0,0 +1,163 @@ +import { dirname, isAbsolute, join } from 'path'; + +/** + * A file system interface that matches the node fs module. + */ +export interface FileSystem { + /** Checks if the file exists */ + existsSync: (path: string) => boolean; + /** Creates a directory structure */ + mkdir: ( + dir: string, + opts?: { + /** Create parent directories as needed */ + recursive: boolean; + }, + ) => Promise; + /** Writes a file */ + writeFile: (path: string, data: Uint8Array) => Promise; + /** Reads a file */ + readFile: (path: string, encoding?: 'utf-8') => Promise; + /** Renames a file */ + rename: (oldPath: string, newPath: string) => Promise; + /** Reads a directory */ + readdir: ( + path: string, + options?: { + /** Traverse child directories recursively */ + recursive: boolean; + }, + ) => Promise; +} + +/** + * A file manager that writes file to a specific directory but reads globally. + */ +export class FileManager { + #fs: FileSystem; + #dataDir: string; + + constructor(fs: FileSystem, dataDir: string) { + this.#fs = fs; + this.#dataDir = dataDir; + } + + /** + * Returns the data directory + */ + getDataDir() { + return this.#dataDir; + } + + /** + * Saves a file to the data directory. + * @param name - File to save + * @param stream - File contents + */ + public async writeFile(name: string, stream: ReadableStream): Promise { + if (isAbsolute(name)) { + throw new Error("can't write absolute path"); + } + + const path = this.#getPath(name); + const chunks: Uint8Array[] = []; + const reader = stream.getReader(); + + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value } = await reader.read(); + if (done) { + break; + } + + chunks.push(value); + } + + const file = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0)); + let offset = 0; + for (const chunk of chunks) { + file.set(chunk, offset); + offset += chunk.length; + } + + await this.#fs.mkdir(dirname(path), { recursive: true }); + await this.#fs.writeFile(this.#getPath(path), file); + } + + /** + * Reads a file from the filesystem and returns a buffer + * Saves a file to the data directory. + * @param oldName - File to save + * @param newName - File contents + */ + async moveFile(oldName: string, newName: string) { + if (isAbsolute(oldName) || isAbsolute(newName)) { + throw new Error("can't move absolute path"); + } + + const oldPath = this.#getPath(oldName); + const newPath = this.#getPath(newName); + + await this.#fs.mkdir(dirname(newPath), { recursive: true }); + await this.#fs.rename(oldPath, newPath); + } + + /** + * Reads a file from the disk and returns a buffer + * @param name - File to read + */ + public async readFile(name: string): Promise; + /** + * Reads a file from the filesystem as a string + * @param name - File to read + * @param encoding - Encoding to use + */ + public async readFile(name: string, encoding: 'utf-8'): Promise; + /** + * Reads a file from the filesystem + * @param name - File to read + * @param encoding - Encoding to use + */ + public async readFile(name: string, encoding?: 'utf-8'): Promise { + const path = this.#getPath(name); + const data = await this.#fs.readFile(path, encoding); + + if (!encoding) { + return typeof data === 'string' + ? new TextEncoder().encode(data) // this branch shouldn't be hit, but just in case + : new Uint8Array(data.buffer, data.byteOffset, data.byteLength / Uint8Array.BYTES_PER_ELEMENT); + } + + return data; + } + + /** + * Checks if a file exists and is accessible + * @param name - File to check + */ + public hasFileSync(name: string): boolean { + return this.#fs.existsSync(this.#getPath(name)); + } + + #getPath(name: string) { + return isAbsolute(name) ? name : join(this.#dataDir, name); + } + + /** + * Reads a file from the filesystem + * @param dir - File to read + * @param options - Readdir options + */ + public async readdir( + dir: string, + options?: { + /** + * Traverse child directories recursively + */ + recursive: boolean; + }, + ) { + const dirPath = this.#getPath(dir); + return await this.#fs.readdir(dirPath, options); + } +} diff --git a/compiler/wasm/src/noir/file-manager/memfs-file-manager.ts b/compiler/wasm/src/noir/file-manager/memfs-file-manager.ts new file mode 100644 index 00000000000..b9ee3226be2 --- /dev/null +++ b/compiler/wasm/src/noir/file-manager/memfs-file-manager.ts @@ -0,0 +1,58 @@ +import { IFs, fs } from 'memfs'; +import { IDirent } from 'memfs/lib/node/types/misc'; + +import { FileManager } from './file-manager'; + +/** + * Creates a new FileManager instance based on a MemFS instance + * @param memFS - the memfs backing instance + * @param dataDir - where to store files + */ +export function createMemFSFileManager(memFS: IFs = fs, dataDir = '/'): FileManager { + const readdirRecursive = async (dir: string): Promise => { + const contents = await memFS.promises.readdir(dir); + let files: string[] = []; + for (const handle in contents) { + if ((handle as unknown as IDirent).isFile()) { + files.push(handle.toString()); + } else { + files = files.concat(await readdirRecursive(handle.toString())); + } + } + return files; + }; + return new FileManager( + { + existsSync: memFS.existsSync.bind(memFS), + mkdir: async ( + dir: string, + options?: { + /** + * Traverse child directories + */ + recursive: boolean; + }, + ) => { + await memFS.promises.mkdir(dir, options); + }, + writeFile: memFS.promises.writeFile.bind(memFS), + rename: memFS.promises.rename.bind(memFS), + readFile: memFS.promises.readFile.bind(memFS), + readdir: async ( + dir: string, + options?: { + /** + * Traverse child directories + */ + recursive: boolean; + }, + ) => { + if (options?.recursive) { + return readdirRecursive(dir); + } + return (await memFS.promises.readdir(dir)).map((handles) => handles.toString()); + }, + }, + dataDir, + ); +} diff --git a/compiler/wasm/src/noir/file-manager/nodejs-file-manager.ts b/compiler/wasm/src/noir/file-manager/nodejs-file-manager.ts new file mode 100644 index 00000000000..1a8250f49cc --- /dev/null +++ b/compiler/wasm/src/noir/file-manager/nodejs-file-manager.ts @@ -0,0 +1,62 @@ +import { existsSync } from 'fs'; +import { promises as fs } from 'fs'; + +import { FileManager } from './file-manager'; + +// This is needed because memfs doesn't support the recursive flag yet +export async function readdirRecursive(dir: string): Promise { + const contents = await fs.readdir(dir); + let files: string[] = []; + for (const handle of contents) { + if ((await fs.stat(`${dir}/${handle}`)).isFile()) { + files.push(`${dir}/${handle.toString()}`); + } else { + files = files.concat(await readdirRecursive(`${dir}/${handle.toString()}`)); + } + } + return files; +} + +/** + * Creates a new FileManager instance based on nodejs fs + * @param dataDir - where to store files + */ +export function createNodejsFileManager(dataDir: string): FileManager { + return new FileManager( + { + ...fs, + ...{ + // ExistsSync is not available in the fs/promises module + existsSync, + // This is added here because the node types are not compatible with the FileSystem type for mkdir + // Typescripts tries to use a different variant of the function that is not the one that has the optional options. + mkdir: async ( + dir: string, + opts?: { + /** + * Traverse child directories + */ + recursive: boolean; + }, + ) => { + await fs.mkdir(dir, opts); + }, + readdir: async ( + dir: string, + options?: { + /** + * Traverse child directories + */ + recursive: boolean; + }, + ) => { + if (options?.recursive) { + return readdirRecursive(dir); + } + return (await fs.readdir(dir)).map((handles) => handles.toString()); + }, + }, + }, + dataDir, + ); +} diff --git a/compiler/wasm/src/noir/noir-wasm-compiler.ts b/compiler/wasm/src/noir/noir-wasm-compiler.ts new file mode 100644 index 00000000000..2a0af5d8fee --- /dev/null +++ b/compiler/wasm/src/noir/noir-wasm-compiler.ts @@ -0,0 +1,173 @@ +import { isAbsolute } from 'path'; + +import { DependencyManager } from './dependencies/dependency-manager'; +import { GithubDependencyResolver as GithubCodeArchiveDependencyResolver } from './dependencies/github-dependency-resolver'; +import { LocalDependencyResolver } from './dependencies/local-dependency-resolver'; +import { FileManager } from './file-manager/file-manager'; +import { Package } from './package'; +import { LogFn } from '../utils'; +import { CompilationResult } from '../types/noir_artifact'; + +/** Compilation options */ +export type NoirWasmCompileOptions = { + /** Logging function */ + log: LogFn; + /** Log debugging information through this function */ + debugLog: LogFn; +}; + +/** + * Noir Package Compiler + */ +export class NoirWasmCompiler { + #log: LogFn; + #debugLog: LogFn; + #package: Package; + /* eslint-disable @typescript-eslint/no-explicit-any */ + #wasmCompiler: any; + #sourceMap: any; + /* eslint-disable @typescript-eslint/no-explicit-any */ + #fm: FileManager; + #dependencyManager: DependencyManager; + + private constructor( + entrypoint: Package, + dependencyManager: DependencyManager, + fileManager: FileManager, + wasmCompiler: unknown, + sourceMap: unknown, + opts: NoirWasmCompileOptions, + ) { + this.#log = opts.log; + this.#debugLog = opts.debugLog; + this.#package = entrypoint; + this.#fm = fileManager; + this.#wasmCompiler = wasmCompiler; + this.#sourceMap = sourceMap; + this.#dependencyManager = dependencyManager; + } + + /** + * Creates a new compiler instance. + * @param fileManager - The file manager to use + * @param projectPath - The path to the project + * @param opts - Compilation options + */ + public static async new( + fileManager: FileManager, + projectPath: string, + /* eslint-disable @typescript-eslint/no-explicit-any */ + wasmCompiler: any, + sourceMap: any, + /* eslint-enable @typescript-eslint/no-explicit-any */ + opts: NoirWasmCompileOptions, + ) { + // Assume the filemanager is initialized at the project root + if (!isAbsolute(projectPath)) { + throw new Error('projectPath must be an absolute path'); + } + + const noirPackage = await Package.open(projectPath, fileManager); + + const dependencyManager = new DependencyManager( + [ + new LocalDependencyResolver(fileManager), + new GithubCodeArchiveDependencyResolver(fileManager), + // TODO support actual Git repositories + ], + noirPackage, + ); + + return new NoirWasmCompiler(noirPackage, dependencyManager, fileManager, wasmCompiler, sourceMap, opts); + } + + /** + * Compile EntryPoint + */ + /** + * Compile EntryPoint + */ + public async compile(): Promise { + console.log(`Compiling at ${this.#package.getEntryPointPath()}`); + + if (!(this.#package.getType() === 'contract' || this.#package.getType() === 'bin')) { + throw new Error(`Only supports compiling "contract" and "bin" package types (${this.#package.getType()})`); + } + await this.#dependencyManager.resolveDependencies(); + this.#debugLog(`Dependencies: ${this.#dependencyManager.getPackageNames().join(', ')}`); + + try { + const isContract: boolean = this.#package.getType() === 'contract'; + + const entrypoint = this.#package.getEntryPointPath(); + const deps = { + /* eslint-disable camelcase */ + root_dependencies: this.#dependencyManager.getEntrypointDependencies(), + library_dependencies: this.#dependencyManager.getLibraryDependencies(), + /* eslint-enable camelcase */ + }; + const packageSources = await this.#package.getSources(this.#fm); + const librarySources = ( + await Promise.all( + this.#dependencyManager + .getLibraries() + .map(async ([alias, library]) => await library.package.getSources(this.#fm, alias)), + ) + ).flat(); + [...packageSources, ...librarySources].forEach((sourceFile) => { + this.#debugLog(`Adding source ${sourceFile.path}`); + this.#sourceMap.add_source_code(sourceFile.path, sourceFile.source); + }); + const result = this.#wasmCompiler.compile(entrypoint, isContract, deps, this.#sourceMap); + + if ((isContract && !('contract' in result)) || (!isContract && !('program' in result))) { + throw new Error('Invalid compilation result'); + } + + return result; + } catch (err) { + if (err instanceof Error && err.name === 'CompileError') { + const logs = await this.#processCompileError(err); + for (const log of logs) { + this.#log(log); + } + throw new Error(logs.join('\n')); + } + + throw err; + } + } + + async #resolveFile(path: string) { + try { + const libFile = this.#dependencyManager.findFile(path); + return await this.#fm.readFile(libFile ?? path, 'utf-8'); + } catch (err) { + return ''; + } + } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async #processCompileError(err: any): Promise { + const logs = []; + for (const diag of err.diagnostics) { + logs.push(` ${diag.message}`); + const contents = await this.#resolveFile(diag.file); + const lines = contents.split('\n'); + const lineOffsets = lines.reduce((accum, _, idx) => { + if (idx === 0) { + accum.push(0); + } else { + accum.push(accum[idx - 1] + lines[idx - 1].length + 1); + } + return accum; + }, []); + + for (const secondary of diag.secondaries) { + const errorLine = lineOffsets.findIndex((offset) => offset > secondary.start); + logs.push(` ${diag.file}:${errorLine}: ${contents.slice(secondary.start, secondary.end)}`); + } + } + return logs; + } +} diff --git a/compiler/wasm/src/noir/package.ts b/compiler/wasm/src/noir/package.ts new file mode 100644 index 00000000000..a2496a03b3a --- /dev/null +++ b/compiler/wasm/src/noir/package.ts @@ -0,0 +1,129 @@ +import { parse } from '@ltd/j-toml'; +import { join } from 'path'; + +import { FileManager } from './file-manager/file-manager'; +import { DependencyConfig, PackageConfig, parseNoirPackageConfig } from '../types/noir_package_config'; + +const CONFIG_FILE_NAME = 'Nargo.toml'; +const SOURCE_EXTENSIONS = ['.nr']; + +/** + * An array of sources for a package + */ +type SourceList = Array<{ + /** + * The source path, taking into account modules and aliases. Eg: mylib/mod/mysource.nr + */ + path: string; + /** + * Resolved source plaintext + */ + source: string; +}>; + +/** + * A Noir package. + */ +export class Package { + #packagePath: string; + #srcPath: string; + #config: PackageConfig; + #version: string | null = null; + + public constructor(path: string, srcDir: string, config: PackageConfig) { + this.#packagePath = path; + this.#srcPath = srcDir; + this.#config = config; + } + + /** + * Gets this package's path. + */ + public getPackagePath() { + return this.#packagePath; + } + + /** + * Gets this package's Nargo.toml (NoirPackage)Config. + */ + public getPackageConfig() { + return this.#config; + } + + /** + * The path to the source directory. + */ + public getSrcPath() { + return this.#srcPath; + } + + /** + * Gets the entrypoint path for this package. + */ + public getEntryPointPath(): string { + let entrypoint: string; + + switch (this.getType()) { + case 'lib': + // we shouldn't need to compile `lib` type, since the .nr source is read directly + // when the lib is used as a dependency elsewhere. + entrypoint = 'lib.nr'; + break; + case 'contract': + case 'bin': + entrypoint = 'main.nr'; + break; + default: + throw new Error(`Unknown package type: ${this.getType()}`); + } + // TODO check that `src` exists + return join(this.#srcPath, entrypoint); + } + + /** + * Gets the project type + */ + public getType() { + return this.#config.package.type; + } + + /** + * Gets this package's dependencies. + */ + public getDependencies(): Record { + return this.#config.dependencies; + } + + /** + * Gets this package's sources. + * @param fm - A file manager to use + * @param alias - An alias for the sources, if this package is a dependency + */ + public async getSources(fm: FileManager, alias?: string): Promise { + const handles = await fm.readdir(this.#srcPath, { recursive: true }); + return Promise.all( + handles + .filter((handle) => SOURCE_EXTENSIONS.find((ext) => handle.endsWith(ext))) + .map(async (file) => { + const suffix = file.replace(this.#srcPath, ''); + return { + path: this.getType() === 'lib' ? `${alias ? alias : this.#config.package.name}${suffix}` : file, + source: (await fm.readFile(file, 'utf-8')).toString(), + }; + }), + ); + } + + /** + * Opens a path on the filesystem. + * @param path - Path to the package. + * @param fm - A file manager to use. + * @returns The Noir package at the given location + */ + public static async open(path: string, fm: FileManager): Promise { + const fileContents = await fm.readFile(join(path, CONFIG_FILE_NAME), 'utf-8'); + const config = parseNoirPackageConfig(parse(fileContents)); + + return new Package(path, join(path, 'src'), config); + } +} diff --git a/compiler/wasm/src/types/noir_artifact.ts b/compiler/wasm/src/types/noir_artifact.ts new file mode 100644 index 00000000000..f2147cfbeda --- /dev/null +++ b/compiler/wasm/src/types/noir_artifact.ts @@ -0,0 +1,210 @@ +import { Abi, AbiType } from '@noir-lang/noirc_abi'; + +/** + * A named type. + */ +export interface ABIVariable { + /** + * The name of the variable. + */ + name: string; + /** + * The type of the variable. + */ + type: AbiType; +} + +/** + * A contract event. + */ +export interface EventAbi { + /** + * The event name. + */ + name: string; + /** + * Fully qualified name of the event. + */ + path: string; + /** + * The fields of the event. + */ + fields: ABIVariable[]; +} + +/** The Noir function types. */ +export type NoirFunctionType = 'Open' | 'Secret' | 'Unconstrained'; + +/** + * The compilation result of an Noir function. + */ +export interface NoirFunctionEntry { + /** The name of the function. */ + name: string; + /** The type of the function. */ + function_type: NoirFunctionType; + /** Whether the function is internal. */ + is_internal: boolean; + /** The ABI of the function. */ + abi: Abi; + /** The bytecode of the function in base64. */ + bytecode: string; +} + +/** + * The compilation result of an Noir contract. + */ +export interface CompiledContract { + /** The name of the contract. */ + name: string; + /** Compilation backend. */ + backend: string; + /** The functions of the contract. */ + functions: NoirFunctionEntry[]; + /** The events of the contract */ + events: EventAbi[]; +} + +/** + * The compilation result of an Noir contract. + */ +export interface CompiledCircuit { + /** The hash of the circuit. */ + hash?: number; + /** Compilation backend. */ + backend: string; + /** + * The ABI of the function. + */ + abi: Abi; + /** The bytecode of the circuit in base64. */ + bytecode: string; +} + +/** + * A file ID. It's assigned during compilation. + */ +export type FileId = number; + +/** + * A pointer to a specific section of the source code. + */ +export interface SourceCodeLocation { + /** + * The section of the source code. + */ + span: { + /** + * The byte where the section starts. + */ + start: number; + /** + * The byte where the section ends. + */ + end: number; + }; + /** + * The source code file pointed to. + */ + file: FileId; +} + +/** + * The location of an opcode in the bytecode. + * It's a string of the form `{acirIndex}` or `{acirIndex}:{brilligIndex}`. + */ +export type OpcodeLocation = string; + +/** + * The debug information for a given function. + */ +export interface DebugInfo { + /** + * A map of the opcode location to the source code location. + */ + locations: Record; +} + +/** + * Maps a file ID to its metadata for debugging purposes. + */ +export type DebugFileMap = Record< + FileId, + { + /** + * The source code of the file. + */ + source: string; + /** + * The path of the file. + */ + path: string; + } +>; + +/** + * The debug metadata of an Noir contract. + */ +export interface DebugMetadata { + /** + * The debug information for each function. + */ + debug_symbols: DebugInfo[]; + /** + * The map of file ID to the source code and path of the file. + */ + file_map: DebugFileMap; +} + +/** + * The compilation artifacts of a given contract. + */ +export interface ContractCompilationArtifacts { + /** + * The compiled contract. + */ + contract: CompiledContract; + + /** + * The artifact that contains the debug metadata about the contract. + */ + debug?: DebugMetadata; +} + +/** + * The compilation artifacts of a given program. + */ +export interface ProgramCompilationArtifacts { + /** + * not part of the compilation output, injected later + */ + name: string; + /** + * The compiled contract. + */ + program: CompiledCircuit; + + /** + * The artifact that contains the debug metadata about the contract. + */ + debug?: DebugMetadata; +} + +/** + * output of Noir Wasm compilation, can be for a contract or lib/binary + */ +export type CompilationResult = ContractCompilationArtifacts | ProgramCompilationArtifacts; + +/** + * Check if it has Contract unique property + */ +export function isContractCompilationArtifacts(artifact: CompilationResult): artifact is ContractCompilationArtifacts { + return (artifact as ContractCompilationArtifacts).contract !== undefined; +} + +/** + * Check if it has Contract unique property + */ +export function isProgramCompilationArtifacts(artifact: CompilationResult): artifact is ProgramCompilationArtifacts { + return (artifact as ProgramCompilationArtifacts).program !== undefined; +} diff --git a/compiler/wasm/src/types/noir_package_config.ts b/compiler/wasm/src/types/noir_package_config.ts new file mode 100644 index 00000000000..5f07c380cf3 --- /dev/null +++ b/compiler/wasm/src/types/noir_package_config.ts @@ -0,0 +1,53 @@ +type NoirGitDependencySchema = { + git: string; + tag: string; + directory?: string; +}; + +type NoirLocalDependencySchema = { + path: string; +}; + +type NoirPackageType = 'lib' | 'contract' | 'bin'; +type NoirPackageConfigSchema = { + package: { + name: string; + type: NoirPackageType; + entry?: string; + description?: string; + authors?: string[]; + compiler_version?: string; + backend?: string; + license?: string; + }; + dependencies: Record; +}; + +/** + * Noir package configuration. + */ +export type PackageConfig = NoirPackageConfigSchema; + +/** + * A remote package dependency. + */ +export type GitDependencyConfig = NoirGitDependencySchema; + +/** + * A local package dependency. + */ +export type LocalDependencyConfig = NoirLocalDependencySchema; + +/** + * A package dependency. + */ +export type DependencyConfig = GitDependencyConfig | LocalDependencyConfig; + +/** + * Checks that an object is a package configuration. + * @param config - Config to check + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function parseNoirPackageConfig(config: any): PackageConfig { + return config; +} diff --git a/compiler/wasm/src/utils.ts b/compiler/wasm/src/utils.ts new file mode 100644 index 00000000000..513f7c51617 --- /dev/null +++ b/compiler/wasm/src/utils.ts @@ -0,0 +1,53 @@ +import { sep } from 'path'; + +/** Structured log data to include with the message. */ +export type LogData = Record; + +/** A callable logger instance. */ +export type LogFn = (msg: string, data?: LogData) => void; + +export function fileURLToPath(uri: string): string { + if (typeof uri !== 'string' || uri.length <= 7 || uri.substring(0, 7) !== 'file://') { + throw new TypeError('must pass in a file:// URI to convert to a file path'); + } + + const rest = decodeURI(uri.substring(7)); + const firstSlash = rest.indexOf('/'); + let host = rest.substring(0, firstSlash); + let path = rest.substring(firstSlash + 1); + + // 2. Scheme Definition + // As a special case, can be the string "localhost" or the empty + // string; this is interpreted as "the machine from which the URL is + // being interpreted". + if (host === 'localhost') { + host = ''; + } + + if (host) { + host = sep + sep + host; + } + + // 3.2 Drives, drive letters, mount points, file system root + // Drive letters are mapped into the top of a file URI in various ways, + // depending on the implementation; some applications substitute + // vertical bar ("|") for the colon after the drive letter, yielding + // "file:///c|/tmp/test.txt". In some cases, the colon is left + // unchanged, as in "file:///c:/tmp/test.txt". In other cases, the + // colon is simply omitted, as in "file:///c/tmp/test.txt". + path = path.replace(/^(.+)\|/, '$1:'); + + // for Windows, we need to invert the path separators from what a URI uses + if (sep === '\\') { + path = path.replace(/\//g, '\\'); + } + + if (/^.+:/.test(path)) { + // has Windows drive at beginning of path + } else { + // unix path… + path = sep + path; + } + + return host + path; +} diff --git a/compiler/wasm/test/browser/index.test.ts b/compiler/wasm/test/browser/index.test.ts deleted file mode 100644 index 7364a8a4d11..00000000000 --- a/compiler/wasm/test/browser/index.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { expect } from '@esm-bundle/chai'; -import initNoirWasm, { PathToFileSourceMap, compile } from '@noir-lang/noir_wasm'; -import { - depsScriptExpectedArtifact, - depsScriptSourcePath, - libASourcePath, - libBSourcePath, - simpleScriptExpectedArtifact, - simpleScriptSourcePath, -} from '../shared'; - -beforeEach(async () => { - await initNoirWasm(); -}); - -async function getFileContent(path: string): Promise { - const url = new URL(path, import.meta.url); - const response = await fetch(url); - return await response.text(); -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -async function getPrecompiledSource(path: string): Promise { - const compiledData = await getFileContent(path); - return JSON.parse(compiledData); -} - -describe('noir wasm', () => { - describe('can compile script without dependencies', () => { - it('matching nargos compilation', async () => { - const sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code('main.nr', await getFileContent(simpleScriptSourcePath)); - - const wasmCircuit = await compile('main.nr', undefined, undefined, sourceMap); - const cliCircuit = await getPrecompiledSource(simpleScriptExpectedArtifact); - - if (!('program' in wasmCircuit)) { - throw Error('Expected program to be present'); - } - - // We don't expect the hashes to match due to how `noir_wasm` handles dependencies - expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); - expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); - expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); - }).timeout(20e3); // 20 seconds - }); - - describe('can compile script with dependencies', () => { - it('matching nargos compilation', async () => { - const [scriptSource, libASource, libBSource] = await Promise.all([ - getFileContent(depsScriptSourcePath), - getFileContent(libASourcePath), - getFileContent(libBSourcePath), - ]); - - const sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code('script/main.nr', scriptSource); - sourceMap.add_source_code('lib_a/lib.nr', libASource); - sourceMap.add_source_code('lib_b/lib.nr', libBSource); - - const wasmCircuit = await compile( - 'script/main.nr', - false, - { - root_dependencies: ['lib_a'], - library_dependencies: { - lib_a: ['lib_b'], - }, - }, - sourceMap, - ); - - if (!('program' in wasmCircuit)) { - throw Error('Expected program to be present'); - } - - const cliCircuit = await getPrecompiledSource(depsScriptExpectedArtifact); - - // We don't expect the hashes to match due to how `noir_wasm` handles dependencies - expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); - expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); - expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); - }).timeout(20e3); // 20 seconds - }); -}); diff --git a/compiler/wasm/test/compiler/browser/compile_with_deps.test.ts b/compiler/wasm/test/compiler/browser/compile_with_deps.test.ts new file mode 100644 index 00000000000..3580779ff1d --- /dev/null +++ b/compiler/wasm/test/compiler/browser/compile_with_deps.test.ts @@ -0,0 +1,44 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { getPaths } from '../../shared'; +import { expect } from '@esm-bundle/chai'; +import { compile, createFileManager } from '@noir-lang/noir_wasm'; +import { CompiledContract } from '../../../src/types/noir_artifact'; + +const paths = getPaths('.'); + +async function getFile(path: string) { + // @ts-ignore + const basePath = new URL('./../../', import.meta.url).toString().replace(/\/$/g, ''); + const url = `${basePath}${path.replace('.', '')}`; + const response = await fetch(url); + return response; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +async function getPrecompiledSource(path: string): Promise { + const response = await getFile(path); + const compiledData = await response.text(); + return JSON.parse(compiledData); +} + +describe('noir-compiler', () => { + it('both nargo and noir_wasm should compile identically', async () => { + const { contractExpectedArtifact } = paths; + const fm = createFileManager('/'); + const files = Object.values(paths).filter((fileOrDir) => /^\.?\/.*\..*$/.test(fileOrDir)); + for (const path of files) { + console.log(path); + await fm.writeFile(path, (await getFile(path)).body as ReadableStream); + } + const nargoArtifact = (await getPrecompiledSource(contractExpectedArtifact)) as CompiledContract; + nargoArtifact.functions.sort((a, b) => a.name.localeCompare(b.name)); + const noirWasmArtifact = await compile(fm, '/fixtures/noir-contract'); + if (!('contract' in noirWasmArtifact)) { + throw new Error('Compilation failed'); + } + const noirWasmContract = noirWasmArtifact.contract; + expect(noirWasmContract).not.to.be.undefined; + noirWasmContract.functions.sort((a, b) => a.name.localeCompare(b.name)); + expect(nargoArtifact).to.deep.eq(noirWasmContract); + }).timeout(60 * 20e3); +}); diff --git a/compiler/wasm/test/compiler/node/compile_with_deps.test.ts b/compiler/wasm/test/compiler/node/compile_with_deps.test.ts new file mode 100644 index 00000000000..546ec03c183 --- /dev/null +++ b/compiler/wasm/test/compiler/node/compile_with_deps.test.ts @@ -0,0 +1,26 @@ +import { join, resolve } from 'path'; +import { getPaths } from '../../shared'; + +import { expect } from 'chai'; +import { readFile } from 'fs/promises'; +import { compile, createFileManager } from '@noir-lang/noir_wasm'; +import { CompiledContract } from '../../../src/types/noir_artifact'; + +const basePath = resolve(join(__dirname, '../../')); +const { contractProjectPath, contractExpectedArtifact } = getPaths(basePath); + +describe('noir-compiler', () => { + it('both nargo and noir_wasm should compile identically', async () => { + const fm = createFileManager(contractProjectPath); + const nargoArtifact = JSON.parse((await readFile(contractExpectedArtifact)).toString()) as CompiledContract; + nargoArtifact.functions.sort((a, b) => a.name.localeCompare(b.name)); + const noirWasmArtifact = await compile(fm); + if (!('contract' in noirWasmArtifact)) { + throw new Error('Compilation failed'); + } + const noirWasmContract = noirWasmArtifact.contract; + expect(noirWasmContract).not.to.be.undefined; + noirWasmContract.functions.sort((a, b) => a.name.localeCompare(b.name)); + expect(nargoArtifact).to.deep.eq(noirWasmContract); + }); +}); diff --git a/compiler/wasm/test/dependencies/dependency-manager.test.ts b/compiler/wasm/test/dependencies/dependency-manager.test.ts new file mode 100644 index 00000000000..4e2fdbae515 --- /dev/null +++ b/compiler/wasm/test/dependencies/dependency-manager.test.ts @@ -0,0 +1,108 @@ +import { DependencyConfig } from '../../src/types/noir_package_config'; +import { Package } from '../../src/noir/package'; +import { DependencyManager } from '../../src/noir/dependencies/dependency-manager'; +import { Dependency, DependencyResolver } from '../../src/noir/dependencies/dependency-resolver'; + +import { expect } from 'chai'; + +describe('DependencyManager', () => { + let manager: DependencyManager; + + beforeEach(() => { + manager = new DependencyManager( + [new TestDependencyResolver()], + new Package('/test_contract', '/test_contract/src', { + dependencies: { + lib1: { + path: '/lib1', + }, + lib2: { + path: '/lib2', + }, + lib3: { + path: '/lib3', + }, + }, + package: { + name: 'test_contract', + type: 'contract', + }, + }), + ); + }); + + it('successfully resolves dependencies', async () => { + await expect(manager.resolveDependencies()).to.eventually.be.undefined; + }); + + it('resolves all libraries', async () => { + await manager.resolveDependencies(); + expect(manager.getPackageNames()).to.eql(['lib1', 'lib2', 'lib3']); + }); + + it('resolves root dependencies', async () => { + await manager.resolveDependencies(); + expect(manager.getEntrypointDependencies()).to.eql(['lib1', 'lib2', 'lib3']); + }); + + it('resolves library dependencies', async () => { + await manager.resolveDependencies(); + expect(manager.getLibraryDependencies()).to.eql({ + lib2: ['lib3'], + }); + }); +}); + +class TestDependencyResolver implements DependencyResolver { + // eslint-disable-next-line require-await + public async resolveDependency(pkg: Package, dep: DependencyConfig): Promise { + if (!('path' in dep)) { + return null; + } + + switch (dep.path) { + case '/lib1': + return { + version: '', + package: new Package('/lib1', '/lib1/src', { + dependencies: {}, + package: { + name: 'lib1', + type: 'lib', + }, + }), + }; + + case '/lib2': + return { + version: '', + package: new Package('/lib2', '/lib2/src', { + dependencies: { + lib3: { + path: '../lib3', + }, + }, + package: { + name: 'lib2', + type: 'lib', + }, + }), + }; + + case '/lib3': + return { + version: '', + package: new Package('/lib3', '/lib3/src', { + dependencies: {}, + package: { + name: 'lib3', + type: 'lib', + }, + }), + }; + + default: + throw new Error(); + } + } +} diff --git a/compiler/wasm/test/dependencies/github-dependency-resolver.test.ts b/compiler/wasm/test/dependencies/github-dependency-resolver.test.ts new file mode 100644 index 00000000000..e7fae8afe8e --- /dev/null +++ b/compiler/wasm/test/dependencies/github-dependency-resolver.test.ts @@ -0,0 +1,149 @@ +import { Volume, createFsFromVolume } from 'memfs'; +import { dirname, join, resolve } from 'path'; + +import { FileManager } from '../../src/noir/file-manager/file-manager'; +import { createMemFSFileManager } from '../../src/noir/file-manager/memfs-file-manager'; +import { readdirRecursive } from '../../src/noir/file-manager/nodejs-file-manager'; + +import { Package } from '../../src/noir/package'; +import { DependencyResolver } from '../../src/noir/dependencies/dependency-resolver'; +import { + GithubDependencyResolver, + resolveGithubCodeArchive, + safeFilename, +} from '../../src/noir/dependencies/github-dependency-resolver'; +import { GitDependencyConfig } from '../../src/types/noir_package_config'; +import Sinon, { SinonStub } from 'sinon'; +import chai, { expect } from 'chai'; +import forEach from 'mocha-each'; +import chaiAsPromised from 'chai-as-promised'; +import AdmZip from 'adm-zip'; + +chai.use(chaiAsPromised); + +const fixtures = resolve(join(__dirname, '../fixtures')); + +describe('GithubDependencyResolver', () => { + let resolver: DependencyResolver; + let fm: FileManager; + let pkg: Package; + let libDependency: GitDependencyConfig; + let fetchStub: SinonStub | undefined; + + beforeEach(() => { + fetchStub = Sinon.stub(globalThis, 'fetch'); + fm = createMemFSFileManager(createFsFromVolume(new Volume()), '/'); + + libDependency = { + git: 'https://github.com/example/repo', + tag: 'v1.0.0', + }; + + pkg = new Package('/test_contract', '/test_contract/src', { + dependencies: { + // eslint-disable-next-line camelcase + lib_c: libDependency, + }, + package: { + name: 'test_contract', + type: 'contract', + }, + }); + + resolver = new GithubDependencyResolver(fm); + + // cut off outside access + fetchStub.onCall(0).throws(new Error()); + }); + + afterEach(() => { + fetchStub?.restore(); + }); + + it("returns null if it can't resolve a dependency", async () => { + const dep = await resolver.resolveDependency(pkg, { + path: '/lib-c', + }); + + expect(dep).to.be.null; + }); + + it('resolves Github dependency', async () => { + const zip = new AdmZip(); + const testLibPath = join(fixtures, 'deps', 'lib-c'); + for (const filePath of await readdirRecursive(testLibPath)) { + zip.addLocalFile(filePath, dirname(filePath.replace(testLibPath, 'lib-c'))); + } + + fetchStub?.onCall(0).returns(new Response(zip.toBuffer(), { status: 200 })); + + const lib = await resolver.resolveDependency(pkg, libDependency); + expect(lib).not.to.be.undefined; + expect(lib!.version).to.eq(libDependency.tag); + expect(fm.hasFileSync(lib!.package.getEntryPointPath())).to.eq(true); + }); + + forEach([ + [ + 'https://github.com/example/lib.nr/archive/v1.0.0.zip', + 'zip', + { + git: 'https://github.com/example/lib.nr', + tag: 'v1.0.0', + }, + ], + [ + 'https://github.com/example/lib.nr/archive/v1.0.0.tar.gz', + 'tar', + { + git: 'https://github.com/example/lib.nr', + tag: 'v1.0.0', + }, + ], + [ + 'https://github.com/example/lib.nr/archive/HEAD.zip', + 'zip', + { + git: 'https://github.com/example/lib.nr', + tag: 'HEAD', + }, + ], + [ + 'https://github.com/example/lib.nr/archive/HEAD.tar.gz', + 'tar', + { + git: 'https://github.com/example/lib.nr', + tag: 'HEAD', + }, + ], + ]).it( + 'resolves to the correct code archive URL %s', + async (href: string, format: 'zip' | 'tar', dep: GitDependencyConfig) => { + const archiveUrl = resolveGithubCodeArchive(dep, format); + expect(archiveUrl.href).to.eq(href); + }, + ); + + forEach([ + { git: 'https://github.com/', tag: 'v1' }, + { git: 'https://github.com/foo', tag: 'v1' }, + { git: 'https://example.com', tag: 'v1' }, + ]).it('throws if the Github URL is invalid %j', (dep) => { + expect(() => resolveGithubCodeArchive(dep, 'zip')).to.throw(); + }); + + forEach([ + ['main', 'main'], + ['v1.0.0', 'v1.0.0'], + ['../../../etc/passwd', '.._.._.._etc_passwd'], + ['/etc/passwd', 'etc_passwd'], + ['/SomeOrg/some-repo@v1.0.0', 'SomeOrg_some-repo@v1.0.0'], + ['SomeOrg/some-repo@v1.0.0', 'SomeOrg_some-repo@v1.0.0'], + ]).it('generates safe file names from %s', (value, expected) => { + expect(safeFilename(value)).to.eq(expected); + }); + + forEach(['']).it('rejects invalid values', (value) => { + expect(() => safeFilename(value)).to.throw(); + }); +}); diff --git a/compiler/wasm/test/dependencies/local-dependency-resolver.test.ts b/compiler/wasm/test/dependencies/local-dependency-resolver.test.ts new file mode 100644 index 00000000000..f44f618a7cb --- /dev/null +++ b/compiler/wasm/test/dependencies/local-dependency-resolver.test.ts @@ -0,0 +1,52 @@ +import { createFsFromVolume, Volume } from 'memfs'; +import { readFile } from 'fs/promises'; + +import { FileManager } from '../../src/noir/file-manager/file-manager'; +import { createMemFSFileManager } from '../../src/noir/file-manager/memfs-file-manager'; +import { Package } from '../../src/noir/package'; +import { DependencyResolver } from '../../src/noir/dependencies/dependency-resolver'; +import { LocalDependencyResolver } from '../../src/noir/dependencies/local-dependency-resolver'; +import { expect } from 'chai'; +import forEach from 'mocha-each'; +import { join } from 'path'; + +describe('DependencyResolver', () => { + let resolver: DependencyResolver; + let fm: FileManager; + let pkg: Package; + + beforeEach(async () => { + const fixtures = join(__dirname, '../fixtures'); + const memFS = createFsFromVolume(new Volume()); + memFS.mkdirSync('/noir-contract/src', { recursive: true }); + memFS.mkdirSync('/lib-c/src', { recursive: true }); + memFS.writeFileSync('/noir-contract/Nargo.toml', await readFile(join(fixtures, 'noir-contract/Nargo.toml'))); + memFS.writeFileSync('/noir-contract/src/main.nr', await readFile(join(fixtures, 'noir-contract/src/main.nr'))); + memFS.writeFileSync('/lib-c/Nargo.toml', await readFile(join(fixtures, 'deps/lib-c/Nargo.toml'))); + memFS.writeFileSync('/lib-c/src/lib.nr', await readFile(join(fixtures, 'deps/lib-c/src/lib.nr'))); + + fm = createMemFSFileManager(memFS, '/'); + + pkg = await Package.open('/noir-contract', fm); + resolver = new LocalDependencyResolver(fm); + }); + + it("returns null if it can't resolve a dependency", async () => { + const dep = await resolver.resolveDependency(pkg, { + git: 'git@some-git-host', + directory: '/', + tag: 'v1.0.0', + }); + + expect(dep).to.be.null; + }); + + forEach(['../noir-contract', '/noir-contract']).it('resolves a known dependency %s', async (path) => { + const lib = await resolver.resolveDependency(pkg, { + path, + }); + expect(lib).not.to.be.undefined; + expect(lib!.version).to.be.undefined; + expect(fm.hasFileSync(lib!.package.getEntryPointPath())).to.eq(true); + }); +}); diff --git a/compiler/wasm/test/file-manager/file-manager.test.ts b/compiler/wasm/test/file-manager/file-manager.test.ts new file mode 100644 index 00000000000..8a80854109a --- /dev/null +++ b/compiler/wasm/test/file-manager/file-manager.test.ts @@ -0,0 +1,96 @@ +import { Volume, createFsFromVolume } from 'memfs'; +import { existsSync, mkdtempSync, rmSync } from 'fs'; +import * as fs from 'fs/promises'; +import { tmpdir } from 'os'; +import { join } from 'path'; + +import { FileManager, FileSystem } from '../../src/noir/file-manager/file-manager'; +import { createMemFSFileManager } from '../../src/noir/file-manager/memfs-file-manager'; + +import { expect } from 'chai'; +import forEach from 'mocha-each'; + +const memFS = (): { fm: FileManager; teardown: () => void } => { + const fm = createMemFSFileManager(createFsFromVolume(new Volume()), '/'); + return { + fm, + // no-op, it's all in memory + teardown: () => {}, + }; +}; + +const nodeFS = (): { fm: FileManager; teardown: () => void } => { + const fileSystem: FileSystem = { + existsSync: existsSync, + mkdir: async (dir: string, opts?: { recursive: boolean }) => { + await fs.mkdir(dir, opts); + }, + writeFile: fs.writeFile, + readFile: fs.readFile, + rename: fs.rename, + readdir: fs.readdir, + }; + + const dir = mkdtempSync(join(tmpdir(), 'noir-compiler-test')); + const fm = new FileManager(fileSystem, dir); + + return { + fm, + teardown: () => { + rmSync(dir, { + recursive: true, + }); + }, + }; +}; + +/** + * Declare the default test suite for a file manager + * @param setup - Function to setup a file manager + * @param teardown - Optional function to call at the end of the test + */ +forEach([ + ['memFs', memFS], + ['nodeFS', nodeFS], +]).describe('FileManager: %s', (name, fs) => { + let fm: FileManager; + let testFileContent: string; + let testFileBytes: Uint8Array; + let teardown: () => void; + + beforeEach(() => { + ({ fm, teardown } = fs()); + testFileContent = 'foo'; + testFileBytes = new TextEncoder().encode(testFileContent); + }); + + afterEach(() => { + return teardown?.(); + }); + + it(`saves files and correctly reads bytes back using ${name}`, async () => { + await fm.writeFile('test.txt', new Blob([testFileBytes]).stream()); + expect(fm.readFile('test.txt')).to.eventually.eq(testFileBytes); + }); + + it(`saves files and correctly reads UTF-8 string back using ${name}`, async () => { + await fm.writeFile('test.txt', new Blob([testFileBytes]).stream()); + expect(fm.readFile('test.txt', 'utf-8')).to.eventually.eq(testFileContent); + }); + + it(`correctly checks if file exists or not using ${name}`, async () => { + expect(fm.hasFileSync('test.txt')).to.eq(false); + await fm.writeFile('test.txt', new Blob([testFileBytes]).stream()); + expect(fm.hasFileSync('test.txt')).to.eq(true); + }); + + it(`moves files using ${name}`, async () => { + await fm.writeFile('test.txt.tmp', new Blob([testFileBytes]).stream()); + expect(fm.hasFileSync('test.txt.tmp')).to.eq(true); + + await fm.moveFile('test.txt.tmp', 'test.txt'); + + expect(fm.hasFileSync('test.txt.tmp')).to.eq(false); + expect(fm.hasFileSync('test.txt')).to.eq(true); + }); +}); diff --git a/compiler/wasm/fixtures/deps/lib-a/Nargo.toml b/compiler/wasm/test/fixtures/deps/lib-a/Nargo.toml similarity index 100% rename from compiler/wasm/fixtures/deps/lib-a/Nargo.toml rename to compiler/wasm/test/fixtures/deps/lib-a/Nargo.toml diff --git a/compiler/wasm/fixtures/deps/lib-a/src/lib.nr b/compiler/wasm/test/fixtures/deps/lib-a/src/lib.nr similarity index 100% rename from compiler/wasm/fixtures/deps/lib-a/src/lib.nr rename to compiler/wasm/test/fixtures/deps/lib-a/src/lib.nr diff --git a/compiler/wasm/fixtures/deps/lib-b/Nargo.toml b/compiler/wasm/test/fixtures/deps/lib-b/Nargo.toml similarity index 100% rename from compiler/wasm/fixtures/deps/lib-b/Nargo.toml rename to compiler/wasm/test/fixtures/deps/lib-b/Nargo.toml diff --git a/compiler/wasm/fixtures/deps/lib-b/src/lib.nr b/compiler/wasm/test/fixtures/deps/lib-b/src/lib.nr similarity index 100% rename from compiler/wasm/fixtures/deps/lib-b/src/lib.nr rename to compiler/wasm/test/fixtures/deps/lib-b/src/lib.nr diff --git a/compiler/wasm/test/fixtures/deps/lib-c/Nargo.toml b/compiler/wasm/test/fixtures/deps/lib-c/Nargo.toml new file mode 100644 index 00000000000..dafdb62e045 --- /dev/null +++ b/compiler/wasm/test/fixtures/deps/lib-c/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "lib_c" +authors = [""] +compiler_version = ">=0.18.0" +type = "lib" + +[dependencies] \ No newline at end of file diff --git a/compiler/wasm/test/fixtures/deps/lib-c/src/lib.nr b/compiler/wasm/test/fixtures/deps/lib-c/src/lib.nr new file mode 100644 index 00000000000..5c0b5a621e0 --- /dev/null +++ b/compiler/wasm/test/fixtures/deps/lib-c/src/lib.nr @@ -0,0 +1 @@ +mod module; \ No newline at end of file diff --git a/compiler/wasm/test/fixtures/deps/lib-c/src/module.nr b/compiler/wasm/test/fixtures/deps/lib-c/src/module.nr new file mode 100644 index 00000000000..2746c97edf0 --- /dev/null +++ b/compiler/wasm/test/fixtures/deps/lib-c/src/module.nr @@ -0,0 +1 @@ +mod foo; \ No newline at end of file diff --git a/compiler/wasm/test/fixtures/deps/lib-c/src/module/foo.nr b/compiler/wasm/test/fixtures/deps/lib-c/src/module/foo.nr new file mode 100644 index 00000000000..e0c82fb1960 --- /dev/null +++ b/compiler/wasm/test/fixtures/deps/lib-c/src/module/foo.nr @@ -0,0 +1,3 @@ +pub fn bar(param: Field) -> Field { + dep::std::hash::pedersen_hash([param]) +} diff --git a/compiler/wasm/test/fixtures/noir-contract/Nargo.toml b/compiler/wasm/test/fixtures/noir-contract/Nargo.toml new file mode 100644 index 00000000000..2e64f3ebc9c --- /dev/null +++ b/compiler/wasm/test/fixtures/noir-contract/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "test" +authors = [""] +compiler_version = ">=0.18.0" +type = "contract" + +[dependencies] +test = { path = "../deps/lib-c" } diff --git a/compiler/wasm/test/fixtures/noir-contract/src/main.nr b/compiler/wasm/test/fixtures/noir-contract/src/main.nr new file mode 100644 index 00000000000..b980af369cf --- /dev/null +++ b/compiler/wasm/test/fixtures/noir-contract/src/main.nr @@ -0,0 +1,12 @@ +contract TestContract { + use dep::test::module::foo; + + fn constructor(param: Field, pub_param: pub Field) -> pub [Field; 2] { + [foo::bar(param), param + pub_param] + } + + open fn openFunction() -> pub Field { + 42 + } + +} diff --git a/compiler/wasm/fixtures/simple/noir-script/Nargo.toml b/compiler/wasm/test/fixtures/simple/Nargo.toml similarity index 100% rename from compiler/wasm/fixtures/simple/noir-script/Nargo.toml rename to compiler/wasm/test/fixtures/simple/Nargo.toml diff --git a/compiler/wasm/fixtures/simple/noir-script/src/main.nr b/compiler/wasm/test/fixtures/simple/src/main.nr similarity index 100% rename from compiler/wasm/fixtures/simple/noir-script/src/main.nr rename to compiler/wasm/test/fixtures/simple/src/main.nr diff --git a/compiler/wasm/fixtures/deps/noir-script/Nargo.toml b/compiler/wasm/test/fixtures/with-deps/Nargo.toml similarity index 70% rename from compiler/wasm/fixtures/deps/noir-script/Nargo.toml rename to compiler/wasm/test/fixtures/with-deps/Nargo.toml index 7c8182a02ae..b7543525059 100644 --- a/compiler/wasm/fixtures/deps/noir-script/Nargo.toml +++ b/compiler/wasm/test/fixtures/with-deps/Nargo.toml @@ -4,4 +4,4 @@ type="bin" authors = [""] [dependencies] -lib_a = { path="../lib-a" } +lib_a = { path="../deps/lib-a" } diff --git a/compiler/wasm/fixtures/deps/noir-script/src/main.nr b/compiler/wasm/test/fixtures/with-deps/src/main.nr similarity index 100% rename from compiler/wasm/fixtures/deps/noir-script/src/main.nr rename to compiler/wasm/test/fixtures/with-deps/src/main.nr diff --git a/compiler/wasm/test/shared.ts b/compiler/wasm/test/shared.ts index 6fc370f7ac8..9181919ff39 100644 --- a/compiler/wasm/test/shared.ts +++ b/compiler/wasm/test/shared.ts @@ -1,8 +1,41 @@ -export const simpleScriptSourcePath = '../../fixtures/simple/noir-script/src/main.nr'; -export const simpleScriptExpectedArtifact = '../../fixtures/simple/noir-script/target/noir_wasm_testing.json'; +export function getPaths(basePath: string) { + const fixtures = `${basePath}/fixtures`; -export const depsScriptSourcePath = '../../fixtures/deps/noir-script/src/main.nr'; -export const depsScriptExpectedArtifact = '../../fixtures/deps/noir-script/target/noir_wasm_testing.json'; + const simpleScriptSourcePath = `${fixtures}/simple/src/main.nr`; + const simpleScriptExpectedArtifact = `${fixtures}/simple/target/noir_wasm_testing.json`; -export const libASourcePath = '../../fixtures/deps/lib-a/src/lib.nr'; -export const libBSourcePath = '../../fixtures/deps/lib-b/src/lib.nr'; + const depsScriptSourcePath = `${fixtures}/with-deps/src/main.nr`; + const depsScriptExpectedArtifact = `${fixtures}/with-deps/target/noir_wasm_testing.json`; + + const libASourcePath = `${fixtures}/deps/lib-a/src/lib.nr`; + const libBSourcePath = `${fixtures}/deps/lib-b/src/lib.nr`; + + const contractProjectPath = `${fixtures}/noir-contract`; + const contractSourcePath = `${contractProjectPath}/src/main.nr`; + const contractTOMLPath = `${contractProjectPath}/Nargo.toml`; + const contractExpectedArtifact = `${contractProjectPath}/target/test-TestContract.json`; + + const libCProjectPath = `${fixtures}/deps/lib-c`; + const libCSourcePath = `${libCProjectPath}/src/lib.nr`; + const libCModulePath = `${libCProjectPath}/src/module.nr`; + const libCModuleSourcePath = `${libCProjectPath}/src/module/foo.nr`; + const libCTOMLPath = `${libCProjectPath}/Nargo.toml`; + + return { + simpleScriptSourcePath, + simpleScriptExpectedArtifact, + depsScriptSourcePath, + depsScriptExpectedArtifact, + libASourcePath, + libBSourcePath, + contractProjectPath, + contractSourcePath, + contractTOMLPath, + contractExpectedArtifact, + libCProjectPath, + libCSourcePath, + libCModulePath, + libCModuleSourcePath, + libCTOMLPath, + }; +} diff --git a/compiler/wasm/test/wasm/browser/index.test.ts b/compiler/wasm/test/wasm/browser/index.test.ts new file mode 100644 index 00000000000..3122fa57945 --- /dev/null +++ b/compiler/wasm/test/wasm/browser/index.test.ts @@ -0,0 +1,159 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { getPaths } from '../../shared'; +import { expect } from '@esm-bundle/chai'; + +import init, { compile, PathToFileSourceMap, compile_, CompilerContext } from '../../../build/esm'; + +// @ts-ignore +await init(); + +const { + simpleScriptSourcePath, + simpleScriptExpectedArtifact, + depsScriptSourcePath, + depsScriptExpectedArtifact, + libASourcePath, + libBSourcePath, +} = getPaths('.'); + +async function getFileAsString(path: string) { + // @ts-ignore + const basePath = new URL('./../../', import.meta.url).toString().replace(/\/$/g, ''); + const url = `${basePath}${path.replace('.', '')}`; + const response = await fetch(url); + return response.text(); +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +async function getPrecompiledSource(path: string): Promise { + const response = await getFileAsString(path); + return JSON.parse(response); +} + +describe('noir wasm compilation', () => { + describe('can compile simple scripts', () => { + it('matching nargos compilation', async () => { + const sourceMap = new PathToFileSourceMap(); + sourceMap.add_source_code('script/main.nr', await getFileAsString(simpleScriptSourcePath)); + const wasmCircuit = compile('script/main.nr', undefined, undefined, sourceMap); + const cliCircuit = await getPrecompiledSource(simpleScriptExpectedArtifact); + + if (!('program' in wasmCircuit)) { + throw Error('Expected program to be present'); + } + + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); + expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); + }).timeout(60 * 20e3); + }); + + describe('can compile scripts with dependencies', () => { + const sourceMap = new PathToFileSourceMap(); + beforeEach(async () => { + sourceMap.add_source_code('script/main.nr', await getFileAsString(depsScriptSourcePath)); + sourceMap.add_source_code('lib_a/lib.nr', await getFileAsString(libASourcePath)); + sourceMap.add_source_code('lib_b/lib.nr', await getFileAsString(libBSourcePath)); + }); + + it('matching nargos compilation', async () => { + const wasmCircuit = compile( + 'script/main.nr', + false, + { + root_dependencies: ['lib_a'], + library_dependencies: { + lib_a: ['lib_b'], + }, + }, + sourceMap, + ); + + const cliCircuit = await getPrecompiledSource(depsScriptExpectedArtifact); + + if (!('program' in wasmCircuit)) { + throw Error('Expected program to be present'); + } + + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); + expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); + }).timeout(60 * 20e3); + }); + + describe('can compile scripts with dependencies -- context-api', () => { + let sourceMap: PathToFileSourceMap; + beforeEach(async () => { + sourceMap = new PathToFileSourceMap(); + sourceMap.add_source_code('script/main.nr', await getFileAsString(depsScriptSourcePath)); + sourceMap.add_source_code('lib_a/lib.nr', await getFileAsString(libASourcePath)); + sourceMap.add_source_code('lib_b/lib.nr', await getFileAsString(libBSourcePath)); + }); + + it('matching nargos compilation - context-api', async () => { + const compilerContext = new CompilerContext(sourceMap); + + // Process root crate + const root_crate_id = compilerContext.process_root_crate('script/main.nr'); + // Process dependencies + // + // This can be direct dependencies or transitive dependencies + // I have named these crate_id_1 and crate_id_2 instead of `lib_a_crate_id` and `lib_b_crate_id` + // because the names of crates in a dependency graph are not determined by the actual package. + // + // It is true that each package is given a name, but if I include a `lib_a` as a dependency + // in my library, I do not need to refer to it as `lib_a` in my dependency graph. + // See https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml + // + // If you have looked at graphs before, then you can think of the dependency graph as a directed acyclic graph (DAG) + const crate_id_1 = compilerContext.process_dependency_crate('lib_a/lib.nr'); + const crate_id_2 = compilerContext.process_dependency_crate('lib_b/lib.nr'); + + // Root crate depends on `crate_id_1` and this edge is called `lib_a` + compilerContext.add_dependency_edge('lib_a', root_crate_id, crate_id_1); + // `crate_id_1` depends on `crate_id_2` and this edge is called `lib_b` + compilerContext.add_dependency_edge('lib_b', crate_id_1, crate_id_2); + + const program_width = 3; + const wasmCircuit = await compilerContext.compile_program(program_width); + + const cliCircuit = await getPrecompiledSource(depsScriptExpectedArtifact); + + if (!('program' in wasmCircuit)) { + throw Error('Expected program to be present'); + } + + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); + expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); + }).timeout(60 * 20e3); + + it('matching nargos compilation - context-implementation-compile-api', async () => { + const wasmCircuit = await compile_( + 'script/main.nr', + false, + { + root_dependencies: ['lib_a'], + library_dependencies: { + lib_a: ['lib_b'], + }, + }, + sourceMap, + ); + + const cliCircuit = await getPrecompiledSource(depsScriptExpectedArtifact); + + if (!('program' in wasmCircuit)) { + throw Error('Expected program to be present'); + } + + // We don't expect the hashes to match due to how `noir_wasm` handles dependencies + expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); + expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); + expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); + }).timeout(60 * 20e3); + }); +}); diff --git a/compiler/wasm/test/node/index.test.ts b/compiler/wasm/test/wasm/node/index.test.ts similarity index 79% rename from compiler/wasm/test/node/index.test.ts rename to compiler/wasm/test/wasm/node/index.test.ts index 57c1b459d60..c73ce7477e5 100644 --- a/compiler/wasm/test/node/index.test.ts +++ b/compiler/wasm/test/wasm/node/index.test.ts @@ -1,15 +1,19 @@ +import { getPaths } from '../../shared'; +import { readFileSync } from 'fs'; +import { join, resolve } from 'path'; import { expect } from 'chai'; -import { + +import { compile, PathToFileSourceMap, compile_, CompilerContext } from '../../../build/cjs'; + +const basePath = resolve(join(__dirname, '../../')); +const { + simpleScriptSourcePath, + simpleScriptExpectedArtifact, depsScriptSourcePath, depsScriptExpectedArtifact, libASourcePath, libBSourcePath, - simpleScriptSourcePath, - simpleScriptExpectedArtifact, -} from '../shared'; -import { readFileSync } from 'node:fs'; -import { join, resolve } from 'node:path'; -import { compile, compile_, CompilerContext, PathToFileSourceMap } from '@noir-lang/noir_wasm'; +} = getPaths(basePath); // eslint-disable-next-line @typescript-eslint/no-explicit-any async function getPrecompiledSource(path: string): Promise { @@ -21,11 +25,8 @@ describe('noir wasm compilation', () => { describe('can compile simple scripts', () => { it('matching nargos compilation', async () => { const sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code( - join(__dirname, simpleScriptSourcePath), - readFileSync(join(__dirname, simpleScriptSourcePath), 'utf-8'), - ); - const wasmCircuit = await compile(join(__dirname, simpleScriptSourcePath), undefined, undefined, sourceMap); + sourceMap.add_source_code(simpleScriptSourcePath, readFileSync(simpleScriptSourcePath, 'utf-8')); + const wasmCircuit = compile(simpleScriptSourcePath, undefined, undefined, sourceMap); const cliCircuit = await getPrecompiledSource(simpleScriptExpectedArtifact); if (!('program' in wasmCircuit)) { @@ -33,22 +34,22 @@ describe('noir wasm compilation', () => { } // We don't expect the hashes to match due to how `noir_wasm` handles dependencies - expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); - }).timeout(10e3); + expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); + }).timeout(60 * 20e3); }); describe('can compile scripts with dependencies', () => { - const sourceMap: PathToFileSourceMap = new PathToFileSourceMap(); + const sourceMap = new PathToFileSourceMap(); beforeEach(() => { - sourceMap.add_source_code('script/main.nr', readFileSync(join(__dirname, depsScriptSourcePath), 'utf-8')); - sourceMap.add_source_code('lib_a/lib.nr', readFileSync(join(__dirname, libASourcePath), 'utf-8')); - sourceMap.add_source_code('lib_b/lib.nr', readFileSync(join(__dirname, libBSourcePath), 'utf-8')); + sourceMap.add_source_code('script/main.nr', readFileSync(depsScriptSourcePath, 'utf-8')); + sourceMap.add_source_code('lib_a/lib.nr', readFileSync(libASourcePath, 'utf-8')); + sourceMap.add_source_code('lib_b/lib.nr', readFileSync(libBSourcePath, 'utf-8')); }); it('matching nargos compilation', async () => { - const wasmCircuit = await compile( + const wasmCircuit = compile( 'script/main.nr', false, { @@ -67,19 +68,19 @@ describe('noir wasm compilation', () => { } // We don't expect the hashes to match due to how `noir_wasm` handles dependencies - expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); - }).timeout(10e3); + expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); + }).timeout(60 * 20e3); }); describe('can compile scripts with dependencies -- context-api', () => { let sourceMap: PathToFileSourceMap; beforeEach(() => { sourceMap = new PathToFileSourceMap(); - sourceMap.add_source_code('script/main.nr', readFileSync(join(__dirname, depsScriptSourcePath), 'utf-8')); - sourceMap.add_source_code('lib_a/lib.nr', readFileSync(join(__dirname, libASourcePath), 'utf-8')); - sourceMap.add_source_code('lib_b/lib.nr', readFileSync(join(__dirname, libBSourcePath), 'utf-8')); + sourceMap.add_source_code('script/main.nr', readFileSync(depsScriptSourcePath, 'utf-8')); + sourceMap.add_source_code('lib_a/lib.nr', readFileSync(libASourcePath, 'utf-8')); + sourceMap.add_source_code('lib_b/lib.nr', readFileSync(libBSourcePath, 'utf-8')); }); it('matching nargos compilation - context-api', async () => { @@ -117,9 +118,9 @@ describe('noir wasm compilation', () => { // We don't expect the hashes to match due to how `noir_wasm` handles dependencies expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); - expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); - }).timeout(10e3); + expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); + }).timeout(60 * 20e3); it('matching nargos compilation - context-implementation-compile-api', async () => { const wasmCircuit = await compile_( @@ -142,8 +143,8 @@ describe('noir wasm compilation', () => { // We don't expect the hashes to match due to how `noir_wasm` handles dependencies expect(wasmCircuit.program.noir_version).to.eq(cliCircuit.noir_version); - expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); expect(wasmCircuit.program.abi).to.deep.eq(cliCircuit.abi); - }).timeout(10e3); + expect(wasmCircuit.program.bytecode).to.eq(cliCircuit.bytecode); + }).timeout(60 * 20e3); }); }); diff --git a/compiler/wasm/tsconfig.esm.json b/compiler/wasm/tsconfig.esm.json new file mode 100644 index 00000000000..5826fee7c52 --- /dev/null +++ b/compiler/wasm/tsconfig.esm.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.webpack.json", + "compilerOptions": { + "module": "ESNext", + }, +} \ No newline at end of file diff --git a/compiler/wasm/tsconfig.json b/compiler/wasm/tsconfig.json index eef2ad84833..6096b419d78 100644 --- a/compiler/wasm/tsconfig.json +++ b/compiler/wasm/tsconfig.json @@ -1,17 +1,20 @@ { "compilerOptions": { - "moduleResolution": "node", - "outDir": "lib", - "target": "ESNext", - "module": "ESNext", + "declaration": true, + "declarationDir": "dist/types", "strict": true, + "baseUrl": ".", "experimentalDecorators": true, - "esModuleInterop": true, "noImplicitAny": true, "removeComments": false, "preserveConstEnums": true, "sourceMap": true, - "resolveJsonModule": true, - "importHelpers": true + "importHelpers": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "target": "ESNext", + "module": "CommonJS", + "moduleResolution": "Node", + "allowJs": true, } } \ No newline at end of file diff --git a/compiler/wasm/tsconfig.webpack.json b/compiler/wasm/tsconfig.webpack.json new file mode 100644 index 00000000000..dd1c218a352 --- /dev/null +++ b/compiler/wasm/tsconfig.webpack.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "exclude": [ + "./test/**/*", + "node_modules" + ] +} \ No newline at end of file diff --git a/compiler/wasm/wasm-opt-check.sh b/compiler/wasm/wasm-opt-check.sh new file mode 100755 index 00000000000..8612b48d3f1 --- /dev/null +++ b/compiler/wasm/wasm-opt-check.sh @@ -0,0 +1 @@ +command -v wasm-opt >/dev/null 2>&1 && echo "true" || { echo >&2 "wasm-opt is not installed, building in dev mode" && echo "false"; exit 1; } \ No newline at end of file diff --git a/compiler/wasm/web-test-runner.config.mjs b/compiler/wasm/web-test-runner.config.mjs index 3fd65d56618..4d05c95f7d6 100644 --- a/compiler/wasm/web-test-runner.config.mjs +++ b/compiler/wasm/web-test-runner.config.mjs @@ -1,14 +1,14 @@ -import { defaultReporter } from "@web/test-runner"; -import { summaryReporter } from "@web/test-runner"; -import { fileURLToPath } from "url"; -import { esbuildPlugin } from "@web/dev-server-esbuild"; -import { playwrightLauncher } from "@web/test-runner-playwright"; +import { defaultReporter } from '@web/test-runner'; +import { summaryReporter } from '@web/test-runner'; +import { fileURLToPath } from 'url'; +import { esbuildPlugin } from '@web/dev-server-esbuild'; +import { playwrightLauncher } from '@web/test-runner-playwright'; const reporter = process.env.CI ? summaryReporter() : defaultReporter(); export default { browsers: [ - playwrightLauncher({ product: "chromium" }), + playwrightLauncher({ product: 'chromium' }), // playwrightLauncher({ product: "webkit" }), // playwrightLauncher({ product: "firefox" }), ], @@ -17,15 +17,8 @@ export default { ts: true, }), ], - files: ["test/browser/**/*.test.ts"], + files: ['./test/**/browser/*.test.ts'], nodeResolve: true, - testFramework: { - config: { - ui: "bdd", - timeout: 40000, - }, - }, - rootDir: fileURLToPath(new URL('./../../', import.meta.url)), + rootDir: fileURLToPath(new URL('./../../', import.meta.url)), reporters: [reporter], - }; diff --git a/compiler/wasm/webpack.config.ts b/compiler/wasm/webpack.config.ts new file mode 100644 index 00000000000..d5d70df2b8a --- /dev/null +++ b/compiler/wasm/webpack.config.ts @@ -0,0 +1,134 @@ +import { resolve, join } from 'path'; +import webpack from 'webpack'; +import 'webpack-dev-server'; +import WasmPackPlugin from '@wasm-tool/wasm-pack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import CopyWebpackPlugin from 'copy-webpack-plugin'; + +const config: webpack.Configuration = { + output: { + path: resolve(__dirname, 'dist'), + }, + mode: 'development', + devtool: 'source-map', + optimization: { + minimize: false, + }, + resolve: { + extensions: ['.cts', '.mts', '.ts', '.js', '.json', '.wasm'], + fallback: { + path: require.resolve('path-browserify'), + stream: require.resolve('readable-stream'), + fs: require.resolve('browserify-fs'), + buffer: require.resolve('buffer'), + }, + }, +}; + +const webConfig: webpack.Configuration = { + name: 'web', + entry: './src/index.mts', + ...config, + experiments: { asyncWebAssembly: true, outputModule: true }, + output: { + filename: 'main.mjs', + ...config.output, + path: resolve(__dirname, 'dist/web'), + library: { + type: 'module', + }, + }, + plugins: [ + new WasmPackPlugin({ + crateDirectory: resolve(__dirname), + outDir: resolve(__dirname, './build/esm'), + extraArgs: '--target web', + forceMode: process.env.WASM_OPT === 'true' ? 'production' : 'development', + }), + new HtmlWebpackPlugin({ + title: 'Noir Wasm ESM', + }), + new webpack.DefinePlugin({ + 'process.env.NODE_DEBUG': JSON.stringify(process.env.NODE_DEBUG), + }), + new webpack.ProvidePlugin({ + process: 'process/browser', + }), + new webpack.ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + }), + ], + module: { + rules: [ + { + test: /.m?ts$/, + loader: 'ts-loader', + options: { + configFile: 'tsconfig.esm.json', + }, + exclude: /node_modules/, + }, + { + test: /\.wasm$/, + type: 'asset/inline', + }, + ], + }, + devServer: { + static: join(__dirname, 'dist'), + }, + resolve: { + ...config.resolve, + alias: { + fs: 'memfs', + }, + }, +}; + +const nodeConfig: webpack.Configuration = { + name: 'node', + entry: './src/index.cts', + ...config, + output: { + ...config.output, + path: resolve(__dirname, 'dist/node'), + library: { + type: 'commonjs2', + }, + }, + target: 'node', + plugins: [ + new WasmPackPlugin({ + crateDirectory: resolve(__dirname), + outDir: resolve(__dirname, './build/cjs'), + extraArgs: '--target nodejs', + forceMode: process.env.WASM_OPT === 'true' ? 'production' : 'development', + }), + new CopyWebpackPlugin({ + patterns: [ + { + from: resolve(__dirname, './build/cjs/index_bg.wasm'), + to: resolve(__dirname, 'dist/node/index_bg.wasm'), + }, + ], + }), + ], + module: { + rules: [ + { + test: /.c?ts$/, + loader: 'ts-loader', + options: { + configFile: 'tsconfig.webpack.json', + }, + exclude: /node_modules/, + }, + { + test: /\.wasm$/, + type: 'webassembly/async', + }, + ], + }, +}; + +export default [webConfig, nodeConfig]; diff --git a/flake.nix b/flake.nix index 6a146becbb8..2300d009114 100644 --- a/flake.nix +++ b/flake.nix @@ -118,9 +118,6 @@ native-cargo-artifacts = craneLib.buildDepsOnly (nativeConfig // { pname = "nargo"; }); - noir-wasm-cargo-artifacts = craneLib.buildDepsOnly (wasmConfig // { - pname = "noir_wasm"; - }); noirc-abi-wasm-cargo-artifacts = craneLib.buildDepsOnly (wasmConfig // { pname = "noirc_abi_wasm"; }); @@ -139,25 +136,6 @@ doCheck = false; }); - noir_wasm = craneLib.buildPackage (wasmConfig // { - pname = "noir_wasm"; - - inherit GIT_COMMIT GIT_DIRTY; - - cargoArtifacts = noir-wasm-cargo-artifacts; - - buildPhaseCargoCommand = '' - bash compiler/wasm/buildPhaseCargoCommand.sh release - ''; - - installPhase = '' - bash compiler/wasm/installPhase.sh - ''; - - # We don't want to run tests because they don't work in the Nix sandbox - doCheck = false; - }); - noirc_abi_wasm = craneLib.buildPackage (wasmConfig // rec { pname = "noirc_abi_wasm"; @@ -232,18 +210,16 @@ # Nix flakes cannot build more than one derivation in one command (see https://github.com/NixOS/nix/issues/5591) # so we use `symlinkJoin` to build everything as the "all" package. - all = pkgs.symlinkJoin { name = "all"; paths = [ nargo noir_wasm noirc_abi_wasm acvm_js ]; }; - all_wasm = pkgs.symlinkJoin { name = "all_wasm"; paths = [ noir_wasm noirc_abi_wasm acvm_js ]; }; + all = pkgs.symlinkJoin { name = "all"; paths = [ nargo noirc_abi_wasm acvm_js ]; }; + all_wasm = pkgs.symlinkJoin { name = "all_wasm"; paths = [ noirc_abi_wasm acvm_js ]; }; # We also export individual packages to enable `nix build .#nargo -L`, etc. inherit nargo; - inherit noir_wasm; inherit noirc_abi_wasm; inherit acvm_js; # We expose the `*-cargo-artifacts` derivations so we can cache our cargo dependencies in CI inherit native-cargo-artifacts; - inherit noir-wasm-cargo-artifacts; inherit noirc-abi-wasm-cargo-artifacts; inherit acvm-js-cargo-artifacts; }; @@ -253,7 +229,6 @@ devShells.default = pkgs.mkShell (environment // { inputsFrom = [ nargo - noir_wasm noirc_abi_wasm acvm_js ]; diff --git a/release-tests/test/utils/nargo.js b/release-tests/test/utils/nargo.js index 537cdfc8be5..6fcaccbcde7 100644 --- a/release-tests/test/utils/nargo.js +++ b/release-tests/test/utils/nargo.js @@ -1,3 +1,3 @@ -import { default as path } from "node:path"; +import { default as path } from "path"; export const NARGO_BIN = process.env.NARGO_BIN ? path.resolve(process.env.NARGO_BIN) : "nargo"; diff --git a/yarn.lock b/yarn.lock index 01860e55921..72b2dc20528 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1823,7 +1823,7 @@ __metadata: languageName: node linkType: hard -"@discoveryjs/json-ext@npm:0.5.7": +"@discoveryjs/json-ext@npm:0.5.7, @discoveryjs/json-ext@npm:^0.5.0": version: 0.5.7 resolution: "@discoveryjs/json-ext@npm:0.5.7" checksum: 2176d301cc258ea5c2324402997cf8134ebb212469c0d397591636cea8d3c02f2b3cf9fd58dcb748c7a0dade77ebdc1b10284fa63e608c033a1db52fddc69918 @@ -3615,6 +3615,13 @@ __metadata: languageName: node linkType: hard +"@ltd/j-toml@npm:^1.38.0": + version: 1.38.0 + resolution: "@ltd/j-toml@npm:1.38.0" + checksum: 34f5d0ec652e790a7a733f0d3a8d9957d63997bd0efc13a61beb9d772bae75519453884fbc3fd6a2d5fe15674834bdd57ca1824bb1de8f829e5ce195fc5fa3ea + languageName: node + linkType: hard + "@mdn/browser-compat-data@npm:^4.0.0": version: 4.2.1 resolution: "@mdn/browser-compat-data@npm:4.2.1" @@ -4060,10 +4067,40 @@ __metadata: resolution: "@noir-lang/noir_wasm@workspace:compiler/wasm" dependencies: "@esm-bundle/chai": ^4.3.4-fix.0 + "@ltd/j-toml": ^1.38.0 + "@noir-lang/noirc_abi": "workspace:*" + "@types/adm-zip": ^0.5.0 + "@types/chai": ^4 + "@types/mocha": ^10.0.6 + "@types/mocha-each": ^2 + "@types/node": ^20.10.5 + "@types/path-browserify": ^1 + "@types/readable-stream": ^4 + "@types/sinon": ^17 + "@wasm-tool/wasm-pack-plugin": ^1.7.0 "@web/dev-server-esbuild": ^0.3.6 - "@web/test-runner": ^0.15.3 - "@web/test-runner-playwright": ^0.10.0 + "@web/test-runner": ^0.18.0 + "@web/test-runner-playwright": ^0.11.0 + adm-zip: ^0.5.0 + assert: ^2.1.0 + browserify-fs: ^1.0.0 + chai: ^4.3.10 + copy-webpack-plugin: ^11.0.0 + html-webpack-plugin: ^5.5.4 + memfs: ^4.6.0 mocha: ^10.2.0 + mocha-each: ^2.0.1 + path-browserify: ^1.0.1 + process: ^0.11.10 + readable-stream: ^4.4.2 + sinon: ^17.0.1 + ts-loader: ^9.5.1 + ts-node: ^10.9.1 + typescript: ~5.2.2 + unzipit: ^1.4.3 + url: ^0.11.3 + webpack: ^5.49.0 + webpack-cli: ^4.7.2 languageName: unknown linkType: soft @@ -4529,6 +4566,28 @@ __metadata: languageName: node linkType: hard +"@puppeteer/browsers@npm:1.4.6": + version: 1.4.6 + resolution: "@puppeteer/browsers@npm:1.4.6" + dependencies: + debug: 4.3.4 + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.3.0 + tar-fs: 3.0.4 + unbzip2-stream: 1.4.3 + yargs: 17.7.1 + peerDependencies: + typescript: ">= 4.7.4" + peerDependenciesMeta: + typescript: + optional: true + bin: + browsers: lib/cjs/main-cli.js + checksum: 29569dd8a8a41737bb0dd40cce6279cfc8764afc6242d2f9d8ae610bed7e466fc77eeb27b9b3ac53dd04927a1a0e26389f282f6ba057210979b36ab455009d64 + languageName: node + linkType: hard + "@rollup/plugin-node-resolve@npm:^13.0.4": version: 13.3.0 resolution: "@rollup/plugin-node-resolve@npm:13.3.0" @@ -4545,6 +4604,25 @@ __metadata: languageName: node linkType: hard +"@rollup/plugin-node-resolve@npm:^15.0.1": + version: 15.2.3 + resolution: "@rollup/plugin-node-resolve@npm:15.2.3" + dependencies: + "@rollup/pluginutils": ^5.0.1 + "@types/resolve": 1.20.2 + deepmerge: ^4.2.2 + is-builtin-module: ^3.2.1 + is-module: ^1.0.0 + resolve: ^1.22.1 + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 730f32c2f8fdddff07cf0fca86a5dac7c475605fb96930197a868c066e62eb6388c557545e4f7d99b7a283411754c9fbf98944ab086b6074e04fc1292e234aa8 + languageName: node + linkType: hard + "@rollup/pluginutils@npm:^3.1.0": version: 3.1.0 resolution: "@rollup/pluginutils@npm:3.1.0" @@ -4558,6 +4636,113 @@ __metadata: languageName: node linkType: hard +"@rollup/pluginutils@npm:^5.0.1": + version: 5.1.0 + resolution: "@rollup/pluginutils@npm:5.1.0" + dependencies: + "@types/estree": ^1.0.0 + estree-walker: ^2.0.2 + picomatch: ^2.3.1 + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 3cc5a6d91452a6eabbfd1ae79b4dd1f1e809d2eecda6e175deb784e75b0911f47e9ecce73f8dd315d6a8b3f362582c91d3c0f66908b6ced69345b3cbe28f8ce8 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.9.4" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-android-arm64@npm:4.9.4" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-darwin-arm64@npm:4.9.4" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-darwin-x64@npm:4.9.4" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.9.4" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.9.4" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.9.4" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.9.4" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.9.4" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.9.4" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.9.4" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.9.4" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.9.4": + version: 4.9.4 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.9.4" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@scure/base@npm:~1.1.0": version: 1.1.3 resolution: "@scure/base@npm:1.1.3" @@ -4740,6 +4925,60 @@ __metadata: languageName: node linkType: hard +"@sinonjs/commons@npm:^2.0.0": + version: 2.0.0 + resolution: "@sinonjs/commons@npm:2.0.0" + dependencies: + type-detect: 4.0.8 + checksum: 5023ba17edf2b85ed58262313b8e9b59e23c6860681a9af0200f239fe939e2b79736d04a260e8270ddd57196851dde3ba754d7230be5c5234e777ae2ca8af137 + languageName: node + linkType: hard + +"@sinonjs/commons@npm:^3.0.0": + version: 3.0.0 + resolution: "@sinonjs/commons@npm:3.0.0" + dependencies: + type-detect: 4.0.8 + checksum: b4b5b73d4df4560fb8c0c7b38c7ad4aeabedd362f3373859d804c988c725889cde33550e4bcc7cd316a30f5152a2d1d43db71b6d0c38f5feef71fd8d016763f8 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^10.0.2": + version: 10.3.0 + resolution: "@sinonjs/fake-timers@npm:10.3.0" + dependencies: + "@sinonjs/commons": ^3.0.0 + checksum: 614d30cb4d5201550c940945d44c9e0b6d64a888ff2cd5b357f95ad6721070d6b8839cd10e15b76bf5e14af0bcc1d8f9ec00d49a46318f1f669a4bec1d7f3148 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^11.2.2": + version: 11.2.2 + resolution: "@sinonjs/fake-timers@npm:11.2.2" + dependencies: + "@sinonjs/commons": ^3.0.0 + checksum: 68c29b0e1856fdc280df03ddbf57c726420b78e9f943a241b471edc018fb14ff36fdc1daafd6026cba08c3c7f50c976fb7ae11b88ff44cd7f609692ca7d25158 + languageName: node + linkType: hard + +"@sinonjs/samsam@npm:^8.0.0": + version: 8.0.0 + resolution: "@sinonjs/samsam@npm:8.0.0" + dependencies: + "@sinonjs/commons": ^2.0.0 + lodash.get: ^4.4.2 + type-detect: ^4.0.8 + checksum: 95e40d0bb9f7288e27c379bee1b03c3dc51e7e78b9d5ea6aef66a690da7e81efc4715145b561b449cefc5361a171791e3ce30fb1a46ab247d4c0766024c60a60 + languageName: node + linkType: hard + +"@sinonjs/text-encoding@npm:^0.7.1": + version: 0.7.2 + resolution: "@sinonjs/text-encoding@npm:0.7.2" + checksum: fe690002a32ba06906cf87e2e8fe84d1590294586f2a7fd180a65355b53660c155c3273d8011a5f2b77209b819aa7306678ae6e4aea0df014bd7ffd4bbbcf1ab + languageName: node + linkType: hard + "@slorber/remark-comment@npm:^1.0.0": version: 1.0.0 resolution: "@slorber/remark-comment@npm:1.0.0" @@ -4936,6 +5175,13 @@ __metadata: languageName: node linkType: hard +"@tootallnate/quickjs-emscripten@npm:^0.23.0": + version: 0.23.0 + resolution: "@tootallnate/quickjs-emscripten@npm:0.23.0" + checksum: c350a2947ffb80b22e14ff35099fd582d1340d65723384a0fd0515e905e2534459ad2f301a43279a37308a27c99273c932e64649abd57d0bb3ca8c557150eccc + languageName: node + linkType: hard + "@trysound/sax@npm:0.2.0": version: 0.2.0 resolution: "@trysound/sax@npm:0.2.0" @@ -4989,6 +5235,15 @@ __metadata: languageName: node linkType: hard +"@types/adm-zip@npm:^0.5.0": + version: 0.5.5 + resolution: "@types/adm-zip@npm:0.5.5" + dependencies: + "@types/node": "*" + checksum: 808c25b8a1c2e1c594cf9b1514e7953105cf96e19e38aa7dc109ff2537bda7345b950ef1f4e54a6e824e5503e29d24b0ff6d0aa1ff9bd4afb79ef0ef2df9ebab + languageName: node + linkType: hard + "@types/babel__code-frame@npm:^7.0.2": version: 7.0.6 resolution: "@types/babel__code-frame@npm:7.0.6" @@ -5156,7 +5411,7 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:^1.0.0": +"@types/estree@npm:*, @types/estree@npm:1.0.5, @types/estree@npm:^1.0.0": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a @@ -5405,7 +5660,16 @@ __metadata: languageName: node linkType: hard -"@types/mocha@npm:^10.0.1": +"@types/mocha-each@npm:^2": + version: 2.0.4 + resolution: "@types/mocha-each@npm:2.0.4" + dependencies: + "@types/mocha": "*" + checksum: 2588284db079e2d0a17735c8fb5c12cba9feabf2de55c9ab49e1f3b38cc522691d30ed3abb1bcb21c087b27f373e3f4123ef7bd8d9a4f95cef38f6c8045c71f3 + languageName: node + linkType: hard + +"@types/mocha@npm:*, @types/mocha@npm:^10.0.1, @types/mocha@npm:^10.0.6": version: 10.0.6 resolution: "@types/mocha@npm:10.0.6" checksum: f7c836cf6cf27dc0f5970d262591b56f2a3caeaec8cfdc612c12e1cfbb207f601f710ece207e935164d4e3343b93be5054d0db5544f31f453b3923775d82099f @@ -5467,6 +5731,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.10.5": + version: 20.10.5 + resolution: "@types/node@npm:20.10.5" + dependencies: + undici-types: ~5.26.4 + checksum: e216b679f545a8356960ce985a0e53c3a58fff0eacd855e180b9e223b8db2b5bd07b744a002b8c1f0c37f9194648ab4578533b5c12df2ec10cc02f61d20948d2 + languageName: node + linkType: hard + "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -5488,6 +5761,13 @@ __metadata: languageName: node linkType: hard +"@types/path-browserify@npm:^1": + version: 1.0.2 + resolution: "@types/path-browserify@npm:1.0.2" + checksum: 7b26df1a32827f7e588009386f62e0f900e8d349722b1b8b8c100cd2c4cc1e95c64099f5ec879cd131e69869088f336998a3ddb17085b68312414431a4eace01 + languageName: node + linkType: hard + "@types/pbkdf2@npm:^3.0.0": version: 3.1.2 resolution: "@types/pbkdf2@npm:3.1.2" @@ -5594,6 +5874,16 @@ __metadata: languageName: node linkType: hard +"@types/readable-stream@npm:^4": + version: 4.0.10 + resolution: "@types/readable-stream@npm:4.0.10" + dependencies: + "@types/node": "*" + safe-buffer: ~5.1.1 + checksum: dc7cb95be737d442770fcaf1fbe3860c011f5f024c6f09c8b032f95b7ef9cce0031302715afe13e18d264b3a162e5838ce78873ec8d63eb238db49bc70906a21 + languageName: node + linkType: hard + "@types/resolve@npm:1.17.1": version: 1.17.1 resolution: "@types/resolve@npm:1.17.1" @@ -5603,6 +5893,13 @@ __metadata: languageName: node linkType: hard +"@types/resolve@npm:1.20.2": + version: 1.20.2 + resolution: "@types/resolve@npm:1.20.2" + checksum: 61c2cad2499ffc8eab36e3b773945d337d848d3ac6b7b0a87c805ba814bc838ef2f262fc0f109bfd8d2e0898ff8bd80ad1025f9ff64f1f71d3d4294c9f14e5f6 + languageName: node + linkType: hard + "@types/responselike@npm:^1.0.0": version: 1.0.3 resolution: "@types/responselike@npm:1.0.3" @@ -5681,6 +5978,22 @@ __metadata: languageName: node linkType: hard +"@types/sinon@npm:^17": + version: 17.0.2 + resolution: "@types/sinon@npm:17.0.2" + dependencies: + "@types/sinonjs__fake-timers": "*" + checksum: 3a56615f2dc7d0b67d3e4b8ae358df2ff2164d89fabb22e9b46e6afe7d4df844a354ea65d409af9baf29ac0103ea562ab44dd0176405a9cf82a4ff183939f22f + languageName: node + linkType: hard + +"@types/sinonjs__fake-timers@npm:*": + version: 8.1.5 + resolution: "@types/sinonjs__fake-timers@npm:8.1.5" + checksum: 7e3c08f6c13df44f3ea7d9a5155ddf77e3f7314c156fa1c5a829a4f3763bafe2f75b1283b887f06e6b4296996a2f299b70f64ff82625f9af5885436e2524d10c + languageName: node + linkType: hard + "@types/sockjs@npm:^0.3.33": version: 0.3.36 resolution: "@types/sockjs@npm:0.3.36" @@ -5883,6 +6196,18 @@ __metadata: languageName: node linkType: hard +"@wasm-tool/wasm-pack-plugin@npm:^1.7.0": + version: 1.7.0 + resolution: "@wasm-tool/wasm-pack-plugin@npm:1.7.0" + dependencies: + chalk: ^2.4.1 + command-exists: ^1.2.7 + watchpack: ^2.1.1 + which: ^2.0.2 + checksum: b0a09f70827b262c4b4689296aae712cc7d9fb742e32eb7e7b720a5b45be1d256864c84c37c8f97de4c762cdae9c35be4a37cdea6832281056921edf4944aea4 + languageName: node + linkType: hard + "@web/browser-logs@npm:^0.2.6": version: 0.2.6 resolution: "@web/browser-logs@npm:0.2.6" @@ -5901,6 +6226,15 @@ __metadata: languageName: node linkType: hard +"@web/browser-logs@npm:^0.4.0": + version: 0.4.0 + resolution: "@web/browser-logs@npm:0.4.0" + dependencies: + errorstacks: ^2.2.0 + checksum: 65c6c4312b1ff00ff40fd15c07708f5e113bb8b4f87c972356010546a0664287dd4f64c5475f8be27b6abb29b9272ecc4162aada90ffb732f1779ceec5fd8ad6 + languageName: node + linkType: hard + "@web/config-loader@npm:^0.1.3": version: 0.1.3 resolution: "@web/config-loader@npm:0.1.3" @@ -5910,6 +6244,13 @@ __metadata: languageName: node linkType: hard +"@web/config-loader@npm:^0.3.0": + version: 0.3.1 + resolution: "@web/config-loader@npm:0.3.1" + checksum: 3ff87dc5cf44a98be97477b1d4c36673d282e7567b61e554aff56f8674a187938c51cd8045f868ca5f4b6ff4d52c72fbbc176c26f27df4335f2341d105d2b535 + languageName: node + linkType: hard + "@web/dev-server-core@npm:^0.4.1": version: 0.4.1 resolution: "@web/dev-server-core@npm:0.4.1" @@ -5962,6 +6303,32 @@ __metadata: languageName: node linkType: hard +"@web/dev-server-core@npm:^0.7.0": + version: 0.7.0 + resolution: "@web/dev-server-core@npm:0.7.0" + dependencies: + "@types/koa": ^2.11.6 + "@types/ws": ^7.4.0 + "@web/parse5-utils": ^2.1.0 + chokidar: ^3.4.3 + clone: ^2.1.2 + es-module-lexer: ^1.0.0 + get-stream: ^6.0.0 + is-stream: ^2.0.0 + isbinaryfile: ^5.0.0 + koa: ^2.13.0 + koa-etag: ^4.0.0 + koa-send: ^5.0.1 + koa-static: ^5.0.0 + lru-cache: ^8.0.4 + mime-types: ^2.1.27 + parse5: ^6.0.1 + picomatch: ^2.2.2 + ws: ^7.4.2 + checksum: 68c4440c75eca686626182af94d40f8ffa2e7848074692abd930ae69490af1866c5d10f13e8ad6745fb7ae386ba91377b4bcdbd74604a9600ce4ab2c8df1576c + languageName: node + linkType: hard + "@web/dev-server-esbuild@npm:^0.3.6": version: 0.3.6 resolution: "@web/dev-server-esbuild@npm:0.3.6" @@ -5989,6 +6356,20 @@ __metadata: languageName: node linkType: hard +"@web/dev-server-rollup@npm:^0.6.1": + version: 0.6.1 + resolution: "@web/dev-server-rollup@npm:0.6.1" + dependencies: + "@rollup/plugin-node-resolve": ^15.0.1 + "@web/dev-server-core": ^0.7.0 + nanocolors: ^0.2.1 + parse5: ^6.0.1 + rollup: ^4.4.0 + whatwg-url: ^11.0.0 + checksum: 59536e38d8519bc1edbf4e11adf36c4f5273c02f5fbc5171962cb7acadea2cfd8c44df057ff4422282f34964668280b3564f6b053bfee5327dc0368a382f2e00 + languageName: node + linkType: hard + "@web/dev-server@npm:^0.1.38": version: 0.1.38 resolution: "@web/dev-server@npm:0.1.38" @@ -6014,6 +6395,31 @@ __metadata: languageName: node linkType: hard +"@web/dev-server@npm:^0.4.0": + version: 0.4.1 + resolution: "@web/dev-server@npm:0.4.1" + dependencies: + "@babel/code-frame": ^7.12.11 + "@types/command-line-args": ^5.0.0 + "@web/config-loader": ^0.3.0 + "@web/dev-server-core": ^0.7.0 + "@web/dev-server-rollup": ^0.6.1 + camelcase: ^6.2.0 + command-line-args: ^5.1.1 + command-line-usage: ^7.0.1 + debounce: ^1.2.0 + deepmerge: ^4.2.2 + ip: ^1.1.5 + nanocolors: ^0.2.1 + open: ^8.0.2 + portfinder: ^1.0.32 + bin: + wds: dist/bin.js + web-dev-server: dist/bin.js + checksum: 2d9f2fcef4511e9965de24fef0ff4430a525ccc7bdc2069e51a96d1aaab4a50a935e32725dd128bb3641be4d6a2acb870f0d645208b59036bfd9d7f55c0a33a4 + languageName: node + linkType: hard + "@web/parse5-utils@npm:^1.3.1": version: 1.3.1 resolution: "@web/parse5-utils@npm:1.3.1" @@ -6024,7 +6430,7 @@ __metadata: languageName: node linkType: hard -"@web/parse5-utils@npm:^2.0.2": +"@web/parse5-utils@npm:^2.0.2, @web/parse5-utils@npm:^2.1.0": version: 2.1.0 resolution: "@web/parse5-utils@npm:2.1.0" dependencies: @@ -6046,6 +6452,19 @@ __metadata: languageName: node linkType: hard +"@web/test-runner-chrome@npm:^0.15.0": + version: 0.15.0 + resolution: "@web/test-runner-chrome@npm:0.15.0" + dependencies: + "@web/test-runner-core": ^0.13.0 + "@web/test-runner-coverage-v8": ^0.8.0 + async-mutex: 0.4.0 + chrome-launcher: ^0.15.0 + puppeteer-core: ^20.0.0 + checksum: 091aa83707aa1a6ade8074c37050f9a0fae2729f223b5e7d756f86ccdadcd85e738cc47d0a4ae8ac6ea930142cc20e341f5d3ad30a3a81d6666b353a7e8c2dd4 + languageName: node + linkType: hard + "@web/test-runner-commands@npm:^0.6.6": version: 0.6.6 resolution: "@web/test-runner-commands@npm:0.6.6" @@ -6056,6 +6475,16 @@ __metadata: languageName: node linkType: hard +"@web/test-runner-commands@npm:^0.9.0": + version: 0.9.0 + resolution: "@web/test-runner-commands@npm:0.9.0" + dependencies: + "@web/test-runner-core": ^0.13.0 + mkdirp: ^1.0.4 + checksum: df226f76148c5967df68c2589549b10ffe75f3d34a31d63bea132447271cdf073de7350aa680fcbf4315737b909fc44faad23d9f8e7e3ce37e93e05e67a7f295 + languageName: node + linkType: hard + "@web/test-runner-core@npm:^0.10.20, @web/test-runner-core@npm:^0.10.29": version: 0.10.29 resolution: "@web/test-runner-core@npm:0.10.29" @@ -6124,6 +6553,40 @@ __metadata: languageName: node linkType: hard +"@web/test-runner-core@npm:^0.13.0": + version: 0.13.0 + resolution: "@web/test-runner-core@npm:0.13.0" + dependencies: + "@babel/code-frame": ^7.12.11 + "@types/babel__code-frame": ^7.0.2 + "@types/co-body": ^6.1.0 + "@types/convert-source-map": ^2.0.0 + "@types/debounce": ^1.2.0 + "@types/istanbul-lib-coverage": ^2.0.3 + "@types/istanbul-reports": ^3.0.0 + "@web/browser-logs": ^0.4.0 + "@web/dev-server-core": ^0.7.0 + chokidar: ^3.4.3 + cli-cursor: ^3.1.0 + co-body: ^6.1.0 + convert-source-map: ^2.0.0 + debounce: ^1.2.0 + dependency-graph: ^0.11.0 + globby: ^11.0.1 + ip: ^1.1.5 + istanbul-lib-coverage: ^3.0.0 + istanbul-lib-report: ^3.0.1 + istanbul-reports: ^3.0.2 + log-update: ^4.0.0 + nanocolors: ^0.2.1 + nanoid: ^3.1.25 + open: ^8.0.2 + picomatch: ^2.2.2 + source-map: ^0.7.3 + checksum: 6c2bd4962da51521dc0d2cf660bf4e1fa3a9a92166a8c71e85a9fe9160710bbe83658dfceae6108123dcf85bf41fbabd8d3b7294f350e2f732f3713fcaa9a024 + languageName: node + linkType: hard + "@web/test-runner-coverage-v8@npm:^0.5.0": version: 0.5.0 resolution: "@web/test-runner-coverage-v8@npm:0.5.0" @@ -6149,6 +6612,19 @@ __metadata: languageName: node linkType: hard +"@web/test-runner-coverage-v8@npm:^0.8.0": + version: 0.8.0 + resolution: "@web/test-runner-coverage-v8@npm:0.8.0" + dependencies: + "@web/test-runner-core": ^0.13.0 + istanbul-lib-coverage: ^3.0.0 + lru-cache: ^8.0.4 + picomatch: ^2.2.2 + v8-to-istanbul: ^9.0.1 + checksum: 343f834372b3aeb2c24f4b03ce956d8ad851ef2a85b94507651c2a65321fcdff1b26a2c44d7516e97d9c42786bb003b9c245ad0798a414a814d0264fdbe0761e + languageName: node + linkType: hard + "@web/test-runner-mocha@npm:^0.7.5": version: 0.7.5 resolution: "@web/test-runner-mocha@npm:0.7.5" @@ -6159,6 +6635,15 @@ __metadata: languageName: node linkType: hard +"@web/test-runner-mocha@npm:^0.9.0": + version: 0.9.0 + resolution: "@web/test-runner-mocha@npm:0.9.0" + dependencies: + "@web/test-runner-core": ^0.13.0 + checksum: bcc9410ac9d679e7bb804fc5720b2a0ed3b4d08f2b49c03f2157f5b54c7f525a432712e1da644f04e5190c2480af2dc46a4c736cdba3fda3ba5fa98fd0f01a94 + languageName: node + linkType: hard + "@web/test-runner-playwright@npm:^0.10.0": version: 0.10.3 resolution: "@web/test-runner-playwright@npm:0.10.3" @@ -6170,6 +6655,17 @@ __metadata: languageName: node linkType: hard +"@web/test-runner-playwright@npm:^0.11.0": + version: 0.11.0 + resolution: "@web/test-runner-playwright@npm:0.11.0" + dependencies: + "@web/test-runner-core": ^0.13.0 + "@web/test-runner-coverage-v8": ^0.8.0 + playwright: ^1.22.2 + checksum: 3618b0b559d865af1211b3d86ec57487b32722a0dd640c9a3faca6c692cceec75176d742d0db73c823d300fbe761e5c15b2fad0c5096c3dbfedab313ed1aa7fe + languageName: node + linkType: hard + "@web/test-runner@npm:^0.15.3": version: 0.15.3 resolution: "@web/test-runner@npm:0.15.3" @@ -6197,6 +6693,33 @@ __metadata: languageName: node linkType: hard +"@web/test-runner@npm:^0.18.0": + version: 0.18.0 + resolution: "@web/test-runner@npm:0.18.0" + dependencies: + "@web/browser-logs": ^0.4.0 + "@web/config-loader": ^0.3.0 + "@web/dev-server": ^0.4.0 + "@web/test-runner-chrome": ^0.15.0 + "@web/test-runner-commands": ^0.9.0 + "@web/test-runner-core": ^0.13.0 + "@web/test-runner-mocha": ^0.9.0 + camelcase: ^6.2.0 + command-line-args: ^5.1.1 + command-line-usage: ^7.0.1 + convert-source-map: ^2.0.0 + diff: ^5.0.0 + globby: ^11.0.1 + nanocolors: ^0.2.1 + portfinder: ^1.0.32 + source-map: ^0.7.3 + bin: + web-test-runner: dist/bin.js + wtr: dist/bin.js + checksum: d5e410f08cb954f9854a3d837f5f704b578376ee8b0452cff66aeca2eb3cb98e50556ca3b958bda567b42af2ef2cd0a7424eaea40f9b3e80362ae788fbd33118 + languageName: node + linkType: hard + "@webassemblyjs/ast@npm:1.11.6, @webassemblyjs/ast@npm:^1.11.5": version: 1.11.6 resolution: "@webassemblyjs/ast@npm:1.11.6" @@ -6348,6 +6871,39 @@ __metadata: languageName: node linkType: hard +"@webpack-cli/configtest@npm:^1.2.0": + version: 1.2.0 + resolution: "@webpack-cli/configtest@npm:1.2.0" + peerDependencies: + webpack: 4.x.x || 5.x.x + webpack-cli: 4.x.x + checksum: a2726cd9ec601d2b57e5fc15e0ebf5200a8892065e735911269ac2038e62be4bfc176ea1f88c2c46ff09b4d05d4c10ae045e87b3679372483d47da625a327e28 + languageName: node + linkType: hard + +"@webpack-cli/info@npm:^1.5.0": + version: 1.5.0 + resolution: "@webpack-cli/info@npm:1.5.0" + dependencies: + envinfo: ^7.7.3 + peerDependencies: + webpack-cli: 4.x.x + checksum: 7f56fe037cd7d1fd5c7428588519fbf04a0cad33925ee4202ffbafd00f8ec1f2f67d991245e687d50e0f3e23f7b7814273d56cb9f7da4b05eed47c8d815c6296 + languageName: node + linkType: hard + +"@webpack-cli/serve@npm:^1.7.0": + version: 1.7.0 + resolution: "@webpack-cli/serve@npm:1.7.0" + peerDependencies: + webpack-cli: 4.x.x + peerDependenciesMeta: + webpack-dev-server: + optional: true + checksum: d475e8effa23eb7ff9a48b14d4de425989fd82f906ce71c210921cc3852327c22873be00c35e181a25a6bd03d424ae2b83e7f3b3f410ac7ee31b128ab4ac7713 + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -6376,6 +6932,15 @@ __metadata: languageName: node linkType: hard +"abort-controller@npm:^3.0.0": + version: 3.0.0 + resolution: "abort-controller@npm:3.0.0" + dependencies: + event-target-shim: ^5.0.0 + checksum: 170bdba9b47b7e65906a28c8ce4f38a7a369d78e2271706f020849c1bfe0ee2067d4261df8bbb66eb84f79208fd5b710df759d64191db58cfba7ce8ef9c54b75 + languageName: node + linkType: hard + "abstract-level@npm:^1.0.0, abstract-level@npm:^1.0.2, abstract-level@npm:^1.0.3": version: 1.0.3 resolution: "abstract-level@npm:1.0.3" @@ -6391,6 +6956,15 @@ __metadata: languageName: node linkType: hard +"abstract-leveldown@npm:~0.12.0, abstract-leveldown@npm:~0.12.1": + version: 0.12.4 + resolution: "abstract-leveldown@npm:0.12.4" + dependencies: + xtend: ~3.0.0 + checksum: e300f04bb638cc9c462f6e8fa925672e51beb24c1470c39ece709e54f2f499661ac5fe0119175c7dcb6e32c843423d6960009d4d24e72526478b261163e8070b + languageName: node + linkType: hard + "accepts@npm:^1.3.5, accepts@npm:~1.3.4, accepts@npm:~1.3.5, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -6449,6 +7023,13 @@ __metadata: languageName: node linkType: hard +"adm-zip@npm:^0.5.0": + version: 0.5.10 + resolution: "adm-zip@npm:0.5.10" + checksum: 07ed91cf6423bf5dca4ee63977bc7635e91b8d21829c00829d48dce4c6932e1b19e6cfcbe44f1931c956e68795ae97183fc775913883fa48ce88a1ac11fb2034 + languageName: node + linkType: hard + "aes-js@npm:3.0.0": version: 3.0.0 resolution: "aes-js@npm:3.0.0" @@ -6698,7 +7279,7 @@ __metadata: languageName: node linkType: hard -"arg@npm:5.0.2, arg@npm:^5.0.0": +"arg@npm:5.0.2, arg@npm:^5.0.0, arg@npm:^5.0.2": version: 5.0.2 resolution: "arg@npm:5.0.2" checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078 @@ -6770,6 +7351,19 @@ __metadata: languageName: node linkType: hard +"assert@npm:^2.1.0": + version: 2.1.0 + resolution: "assert@npm:2.1.0" + dependencies: + call-bind: ^1.0.2 + is-nan: ^1.3.2 + object-is: ^1.1.5 + object.assign: ^4.1.4 + util: ^0.12.5 + checksum: 1ed1cabba9abe55f4109b3f7292b4e4f3cf2953aad8dc148c0b3c3bd676675c31b1abb32ef563b7d5a19d1715bf90d1e5f09fad2a4ee655199468902da80f7c2 + languageName: node + linkType: hard + "assertion-error@npm:^1.1.0": version: 1.1.0 resolution: "assertion-error@npm:1.1.0" @@ -6777,6 +7371,15 @@ __metadata: languageName: node linkType: hard +"ast-types@npm:^0.13.4": + version: 0.13.4 + resolution: "ast-types@npm:0.13.4" + dependencies: + tslib: ^2.0.1 + checksum: 5a51f7b70588ecced3601845a0e203279ca2f5fdc184416a0a1640c93ec0a267241d6090a328e78eebb8de81f8754754e0a4f1558ba2a3d638f8ccbd0b1f0eff + languageName: node + linkType: hard + "astral-regex@npm:^2.0.0": version: 2.0.0 resolution: "astral-regex@npm:2.0.0" @@ -6793,6 +7396,15 @@ __metadata: languageName: node linkType: hard +"async-mutex@npm:0.4.0": + version: 0.4.0 + resolution: "async-mutex@npm:0.4.0" + dependencies: + tslib: ^2.4.0 + checksum: 813a71728b35a4fbfd64dba719f04726d9133c67b577fcd951b7028c4a675a13ee34e69beb82d621f87bf81f5d4f135c4c44be0448550c7db728547244ef71fc + languageName: node + linkType: hard + "async@npm:^2.6.4": version: 2.6.4 resolution: "async@npm:2.6.4" @@ -6834,6 +7446,13 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.5": + version: 1.0.5 + resolution: "available-typed-arrays@npm:1.0.5" + checksum: 20eb47b3cefd7db027b9bbb993c658abd36d4edd3fe1060e83699a03ee275b0c9b216cc076ff3f2db29073225fb70e7613987af14269ac1fe2a19803ccc97f1a + languageName: node + linkType: hard + "axios@npm:^0.25.0": version: 0.25.0 resolution: "axios@npm:0.25.0" @@ -6854,6 +7473,13 @@ __metadata: languageName: node linkType: hard +"b4a@npm:^1.6.4": + version: 1.6.4 + resolution: "b4a@npm:1.6.4" + checksum: 81b086f9af1f8845fbef4476307236bda3d660c158c201db976f19cdce05f41f93110ab6b12fd7a2696602a490cc43d5410ee36a56d6eef93afb0d6ca69ac3b2 + languageName: node + linkType: hard + "babel-loader@npm:^8.2.5": version: 8.3.0 resolution: "babel-loader@npm:8.3.0" @@ -6985,6 +7611,13 @@ __metadata: languageName: node linkType: hard +"basic-ftp@npm:^5.0.2": + version: 5.0.4 + resolution: "basic-ftp@npm:5.0.4" + checksum: 57725f24debd8c1b36f9bad1bfee39c5d9f5997f32a23e5c957389dcc64373a13b41711e5723b4a3b616a93530b345686119f480c27a115b2fde944c1652ceb1 + languageName: node + linkType: hard + "batch@npm:0.6.1": version: 0.6.1 resolution: "batch@npm:0.6.1" @@ -7038,6 +7671,15 @@ __metadata: languageName: node linkType: hard +"bl@npm:~0.8.1": + version: 0.8.2 + resolution: "bl@npm:0.8.2" + dependencies: + readable-stream: ~1.0.26 + checksum: 18767c5c861ae1cdbb000bb346e9e8e29137225e8eef97f39db78beeb236beca609f465580c5c1b177d621505f57400834fb4a17a66d264f33a0237293ec2ac5 + languageName: node + linkType: hard + "blakejs@npm:^1.1.0": version: 1.2.1 resolution: "blakejs@npm:1.2.1" @@ -7239,6 +7881,17 @@ __metadata: languageName: node linkType: hard +"browserify-fs@npm:^1.0.0": + version: 1.0.0 + resolution: "browserify-fs@npm:1.0.0" + dependencies: + level-filesystem: ^1.0.1 + level-js: ^2.1.3 + levelup: ^0.18.2 + checksum: e0c35cf42c839c0a217048b1671d91ee6e53fd05f163db4f809e46c2f6264f784768e7c850abc200b0eaca378d42e00e01876eda21fd84fc0a4280bd6200a9c3 + languageName: node + linkType: hard + "browserslist@npm:^4.0.0, browserslist@npm:^4.14.5, browserslist@npm:^4.18.1, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.21.9, browserslist@npm:^4.22.2": version: 4.22.2 resolution: "browserslist@npm:4.22.2" @@ -7411,7 +8064,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.5": +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": version: 1.0.5 resolution: "call-bind@npm:1.0.5" dependencies: @@ -7518,7 +8171,7 @@ __metadata: languageName: node linkType: hard -"chai@npm:^4.3.7, chai@npm:^4.3.8": +"chai@npm:^4.3.10, chai@npm:^4.3.7, chai@npm:^4.3.8": version: 4.3.10 resolution: "chai@npm:4.3.10" dependencies: @@ -7549,7 +8202,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^2.4.2": +"chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -7725,6 +8378,17 @@ __metadata: languageName: node linkType: hard +"chromium-bidi@npm:0.4.16": + version: 0.4.16 + resolution: "chromium-bidi@npm:0.4.16" + dependencies: + mitt: 3.0.0 + peerDependencies: + devtools-protocol: "*" + checksum: 9cbb362fdf589dbdfd1618499c5bbdac45a3aa1291c1d2faa2f1ea3768738677985175d1bb1511dfe3e188bc78e6ea2acb453564ece7e09f535bbcd2253ce06a + languageName: node + linkType: hard + "chromium-bidi@npm:0.4.7": version: 0.4.7 resolution: "chromium-bidi@npm:0.4.7" @@ -7886,6 +8550,13 @@ __metadata: languageName: node linkType: hard +"clone@npm:~0.1.9": + version: 0.1.19 + resolution: "clone@npm:0.1.19" + checksum: 5e710e16da67abe30c0664c8fd69c280635be59a4fae0a5fe58ed324e701e99348b48ce67288716fa223edd42ba574e58a3783cb2fcfa381b8b49ce7e56ac3f4 + languageName: node + linkType: hard + "clsx@npm:^1.1.1, clsx@npm:^1.2.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" @@ -7972,7 +8643,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.10": +"colorette@npm:^2.0.10, colorette@npm:^2.0.14": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d @@ -8016,7 +8687,7 @@ __metadata: languageName: node linkType: hard -"command-exists@npm:^1.2.8": +"command-exists@npm:^1.2.7, command-exists@npm:^1.2.8": version: 1.2.9 resolution: "command-exists@npm:1.2.9" checksum: 729ae3d88a2058c93c58840f30341b7f82688a573019535d198b57a4d8cb0135ced0ad7f52b591e5b28a90feb2c675080ce916e56254a0f7c15cb2395277cac3 @@ -8087,7 +8758,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^7.2.0": +"commander@npm:^7.0.0, commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" checksum: 53501cbeee61d5157546c0bef0fedb6cdfc763a882136284bed9a07225f09a14b82d2a84e7637edfd1a679fb35ed9502fd58ef1d091e6287f60d790147f68ddc @@ -8146,6 +8817,18 @@ __metadata: languageName: node linkType: hard +"concat-stream@npm:^1.4.4": + version: 1.6.2 + resolution: "concat-stream@npm:1.6.2" + dependencies: + buffer-from: ^1.0.0 + inherits: ^2.0.3 + readable-stream: ^2.2.2 + typedarray: ^0.0.6 + checksum: 1ef77032cb4459dcd5187bd710d6fc962b067b64ec6a505810de3d2b8cc0605638551b42f8ec91edf6fcd26141b32ef19ad749239b58fae3aba99187adc32285 + languageName: node + linkType: hard + "config-chain@npm:^1.1.11": version: 1.1.13 resolution: "config-chain@npm:1.1.13" @@ -8413,6 +9096,15 @@ __metadata: languageName: node linkType: hard +"cross-fetch@npm:4.0.0": + version: 4.0.0 + resolution: "cross-fetch@npm:4.0.0" + dependencies: + node-fetch: ^2.6.12 + checksum: ecca4f37ffa0e8283e7a8a590926b66713a7ef7892757aa36c2d20ffa27b0ac5c60dcf453119c809abe5923fc0bae3702a4d896bfb406ef1077b0d0018213e24 + languageName: node + linkType: hard + "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" @@ -8648,6 +9340,13 @@ __metadata: languageName: node linkType: hard +"data-uri-to-buffer@npm:^6.0.0": + version: 6.0.1 + resolution: "data-uri-to-buffer@npm:6.0.1" + checksum: 9140e68c585ae33d950f5943bd476751346c8b789ae80b01a578a33cb8f7f706d1ca7378aff2b1878b2a6d9a8c88c55cc286d88191c8b8ead8255c3c4d934530 + languageName: node + linkType: hard + "debounce@npm:^1.2.0, debounce@npm:^1.2.1": version: 1.2.1 resolution: "debounce@npm:1.2.1" @@ -8801,6 +9500,15 @@ __metadata: languageName: node linkType: hard +"deferred-leveldown@npm:~0.2.0": + version: 0.2.0 + resolution: "deferred-leveldown@npm:0.2.0" + dependencies: + abstract-leveldown: ~0.12.1 + checksum: f7690ec5b1e951e6f56998be26dd0a1331ef28cb7eaa9e090a282780d47dc006effd4b82a2a82b636cae801378047997aca10c0b44b09c8624633cdb96b07913 + languageName: node + linkType: hard + "define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1": version: 1.1.1 resolution: "define-data-property@npm:1.1.1" @@ -8826,7 +9534,7 @@ __metadata: languageName: node linkType: hard -"define-properties@npm:^1.2.1": +"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -8837,6 +9545,17 @@ __metadata: languageName: node linkType: hard +"degenerator@npm:^5.0.0": + version: 5.0.1 + resolution: "degenerator@npm:5.0.1" + dependencies: + ast-types: ^0.13.4 + escodegen: ^2.1.0 + esprima: ^4.0.1 + checksum: a64fa39cdf6c2edd75188157d32338ee9de7193d7dbb2aeb4acb1eb30fa4a15ed80ba8dae9bd4d7b085472cf174a5baf81adb761aaa8e326771392c922084152 + languageName: node + linkType: hard + "del@npm:^6.1.1": version: 6.1.1 resolution: "del@npm:6.1.1" @@ -8960,6 +9679,13 @@ __metadata: languageName: node linkType: hard +"devtools-protocol@npm:0.0.1147663": + version: 0.0.1147663 + resolution: "devtools-protocol@npm:0.0.1147663" + checksum: 0631f2b6c6cd7f56e7d62a85bfc291f7e167f0f2de90969ef61fb24e2bd546b2e9530043d2bc3fe6c4d7a9e00473004272d2c2832a10a05e4b75c03a22f549fc + languageName: node + linkType: hard + "diff@npm:5.0.0": version: 5.0.0 resolution: "diff@npm:5.0.0" @@ -8974,7 +9700,7 @@ __metadata: languageName: node linkType: hard -"diff@npm:^5.0.0": +"diff@npm:^5.0.0, diff@npm:^5.1.0": version: 5.1.0 resolution: "diff@npm:5.1.0" checksum: c7bf0df7c9bfbe1cf8a678fd1b2137c4fb11be117a67bc18a0e03ae75105e8533dbfb1cda6b46beb3586ef5aed22143ef9d70713977d5fb1f9114e21455fba90 @@ -9287,7 +10013,7 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.15.0": +"enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.15.0": version: 5.15.0 resolution: "enhanced-resolve@npm:5.15.0" dependencies: @@ -9328,6 +10054,15 @@ __metadata: languageName: node linkType: hard +"envinfo@npm:^7.7.3": + version: 7.11.0 + resolution: "envinfo@npm:7.11.0" + bin: + envinfo: dist/cli.js + checksum: c45a7d20409d5f4cda72483b150d3816b15b434f2944d72c1495d8838bd7c4e7b2f32c12128ffb9b92b5f66f436237b8a525eb3a9a5da2d20013bc4effa28aef + languageName: node + linkType: hard + "err-code@npm:^2.0.2": version: 2.0.3 resolution: "err-code@npm:2.0.3" @@ -9335,6 +10070,17 @@ __metadata: languageName: node linkType: hard +"errno@npm:^0.1.1, errno@npm:~0.1.1": + version: 0.1.8 + resolution: "errno@npm:0.1.8" + dependencies: + prr: ~1.0.1 + bin: + errno: cli.js + checksum: 1271f7b9fbb3bcbec76ffde932485d1e3561856d21d847ec613a9722ee924cdd4e523a62dc71a44174d91e898fe21fdc8d5b50823f4b5e0ce8c35c8271e6ef4a + languageName: node + linkType: hard + "error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2" @@ -9561,6 +10307,24 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^2.1.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" + dependencies: + esprima: ^4.0.1 + estraverse: ^5.2.0 + esutils: ^2.0.2 + source-map: ~0.6.1 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 096696407e161305cd05aebb95134ad176708bc5cb13d0dcc89a5fcbb959b8ed757e7f2591a5f8036f8f4952d4a724de0df14cd419e29212729fa6df5ce16bf6 + languageName: node + linkType: hard + "eslint-plugin-prettier@npm:^5.0.0": version: 5.0.1 resolution: "eslint-plugin-prettier@npm:5.0.1" @@ -9666,7 +10430,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0": +"esprima@npm:^4.0.0, esprima@npm:^4.0.1": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -9774,6 +10538,13 @@ __metadata: languageName: node linkType: hard +"estree-walker@npm:^2.0.2": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 6151e6f9828abe2259e57f5fd3761335bb0d2ebd76dc1a01048ccee22fabcfef3c0859300f6d83ff0d1927849368775ec5a6d265dde2f6de5a1be1721cd94efc + languageName: node + linkType: hard + "estree-walker@npm:^3.0.0": version: 3.0.3 resolution: "estree-walker@npm:3.0.3" @@ -9952,6 +10723,13 @@ __metadata: languageName: node linkType: hard +"event-target-shim@npm:^5.0.0": + version: 5.0.1 + resolution: "event-target-shim@npm:5.0.1" + checksum: 1ffe3bb22a6d51bdeb6bf6f7cf97d2ff4a74b017ad12284cc9e6a279e727dc30a5de6bb613e5596ff4dc3e517841339ad09a7eec44266eccb1aa201a30448166 + languageName: node + linkType: hard + "eventemitter3@npm:^4.0.0": version: 4.0.7 resolution: "eventemitter3@npm:4.0.7" @@ -9959,7 +10737,7 @@ __metadata: languageName: node linkType: hard -"events@npm:^3.2.0": +"events@npm:^3.2.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780 @@ -10104,6 +10882,13 @@ __metadata: languageName: node linkType: hard +"fast-fifo@npm:^1.1.0, fast-fifo@npm:^1.2.0": + version: 1.3.2 + resolution: "fast-fifo@npm:1.3.2" + checksum: 6bfcba3e4df5af7be3332703b69a7898a8ed7020837ec4395bb341bd96cc3a6d86c3f6071dd98da289618cf2234c70d84b2a6f09a33dd6f988b1ff60d8e54275 + languageName: node + linkType: hard + "fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.12, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" @@ -10147,6 +10932,13 @@ __metadata: languageName: node linkType: hard +"fastest-levenshtein@npm:^1.0.12": + version: 1.0.16 + resolution: "fastest-levenshtein@npm:1.0.16" + checksum: a78d44285c9e2ae2c25f3ef0f8a73f332c1247b7ea7fb4a191e6bb51aa6ee1ef0dfb3ed113616dcdc7023e18e35a8db41f61c8d88988e877cf510df8edafbc71 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.15.0 resolution: "fastq@npm:1.15.0" @@ -10376,6 +11168,22 @@ __metadata: languageName: node linkType: hard +"for-each@npm:^0.3.3": + version: 0.3.3 + resolution: "for-each@npm:0.3.3" + dependencies: + is-callable: ^1.1.3 + checksum: 6c48ff2bc63362319c65e2edca4a8e1e3483a2fabc72fbe7feaf8c73db94fc7861bd53bc02c8a66a0c1dd709da6b04eec42e0abdd6b40ce47305ae92a25e5d28 + languageName: node + linkType: hard + +"foreach@npm:~2.0.1": + version: 2.0.6 + resolution: "foreach@npm:2.0.6" + checksum: f7b68494545ee41cbd0b0425ebf5386c265dc38ef2a9b0d5cd91a1b82172e939b4cf9387f8e0ebf6db4e368fc79ed323f2198424d5c774515ac3ed9b08901c0e + languageName: node + linkType: hard + "foreground-child@npm:^3.1.0": version: 3.1.1 resolution: "foreground-child@npm:3.1.1" @@ -10546,6 +11354,17 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^8.1.0": + version: 8.1.0 + resolution: "fs-extra@npm:8.1.0" + dependencies: + graceful-fs: ^4.2.0 + jsonfile: ^4.0.0 + universalify: ^0.1.0 + checksum: bf44f0e6cea59d5ce071bba4c43ca76d216f89e402dc6285c128abc0902e9b8525135aa808adad72c9d5d218e9f4bcc63962815529ff2f684ad532172a284880 + languageName: node + linkType: hard + "fs-extra@npm:^9.0.0": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" @@ -10642,6 +11461,15 @@ __metadata: languageName: node linkType: hard +"fwd-stream@npm:^1.0.4": + version: 1.0.4 + resolution: "fwd-stream@npm:1.0.4" + dependencies: + readable-stream: ~1.0.26-4 + checksum: db4dcf68f214b3fabd6cd9658630dfd1d7ed8d43f7f45408027a90220cd75276e782d1e958821775d7a3a4a83034778e75a097bdc7002c758e8896f76213c65d + languageName: node + linkType: hard + "gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" @@ -10723,6 +11551,18 @@ __metadata: languageName: node linkType: hard +"get-uri@npm:^6.0.1": + version: 6.0.2 + resolution: "get-uri@npm:6.0.2" + dependencies: + basic-ftp: ^5.0.2 + data-uri-to-buffer: ^6.0.0 + debug: ^4.3.4 + fs-extra: ^8.1.0 + checksum: 762de3b0e3d4e7afc966e4ce93be587d70c270590da9b4c8fbff888362656c055838d926903d1774cbfeed4d392b4d6def4b2c06d48c050580070426a3a8629b + languageName: node + linkType: hard + "github-slugger@npm:^1.4.0, github-slugger@npm:^1.5.0": version: 1.5.0 resolution: "github-slugger@npm:1.5.0" @@ -11521,7 +12361,7 @@ __metadata: languageName: node linkType: hard -"html-webpack-plugin@npm:^5.5.0, html-webpack-plugin@npm:^5.5.3": +"html-webpack-plugin@npm:^5.5.0, html-webpack-plugin@npm:^5.5.3, html-webpack-plugin@npm:^5.5.4": version: 5.5.4 resolution: "html-webpack-plugin@npm:5.5.4" dependencies: @@ -11688,7 +12528,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1": +"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1, https-proxy-agent@npm:^7.0.2": version: 7.0.2 resolution: "https-proxy-agent@npm:7.0.2" dependencies: @@ -11712,6 +12552,13 @@ __metadata: languageName: node linkType: hard +"hyperdyperid@npm:^1.2.0": + version: 1.2.0 + resolution: "hyperdyperid@npm:1.2.0" + checksum: 210029d1c86926f09109f6317d143f8b056fc38e8dd11b0c3e3205fc6c6ff8429fb55b4b9c2bce065462719ed9d34366eced387aaa0035d93eb76b306a8547ef + languageName: node + linkType: hard + "iconv-lite@npm:0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" @@ -11739,6 +12586,13 @@ __metadata: languageName: node linkType: hard +"idb-wrapper@npm:^1.5.0": + version: 1.7.2 + resolution: "idb-wrapper@npm:1.7.2" + checksum: a5fa3a771166205e2d5d2b93c66bd31571dada3526b59bc0f8583efb091b6b327125f1a964a25a281b85ef1c44af10a3c511652632ad3adf8229a161132d66ae + languageName: node + linkType: hard + "ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -11809,6 +12663,18 @@ __metadata: languageName: node linkType: hard +"import-local@npm:^3.0.2": + version: 3.1.0 + resolution: "import-local@npm:3.1.0" + dependencies: + pkg-dir: ^4.2.0 + resolve-cwd: ^3.0.0 + bin: + import-local-fixture: fixtures/cli.js + checksum: bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -11823,6 +12689,13 @@ __metadata: languageName: node linkType: hard +"indexof@npm:~0.0.1": + version: 0.0.1 + resolution: "indexof@npm:0.0.1" + checksum: 0fb04e8b147b8585d981a6df1564f25bb3678d6fa74e33e5cecc1464b10f78e15e8ef6bb688f135fe5c2844a128fac8a7831cbe5adc81fdcf12681b093dfcc25 + languageName: node + linkType: hard + "infima@npm:0.2.0-alpha.43": version: 0.2.0-alpha.43 resolution: "infima@npm:0.2.0-alpha.43" @@ -11847,7 +12720,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.0, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.0, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.1, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -11919,6 +12792,13 @@ __metadata: languageName: node linkType: hard +"interpret@npm:^2.2.0": + version: 2.2.0 + resolution: "interpret@npm:2.2.0" + checksum: f51efef7cb8d02da16408ffa3504cd6053014c5aeb7bb8c223727e053e4235bf565e45d67028b0c8740d917c603807aa3c27d7bd2f21bf20b6417e2bb3e5fd6e + languageName: node + linkType: hard + "invariant@npm:^2.2.4": version: 2.2.4 resolution: "invariant@npm:2.2.4" @@ -11937,7 +12817,7 @@ __metadata: languageName: node linkType: hard -"ip@npm:^1.1.5": +"ip@npm:^1.1.5, ip@npm:^1.1.8": version: 1.1.8 resolution: "ip@npm:1.1.8" checksum: a2ade53eb339fb0cbe9e69a44caab10d6e3784662285eb5d2677117ee4facc33a64679051c35e0dfdb1a3983a51ce2f5d2cb36446d52e10d01881789b76e28fb @@ -11999,6 +12879,16 @@ __metadata: languageName: node linkType: hard +"is-arguments@npm:^1.0.4": + version: 1.1.1 + resolution: "is-arguments@npm:1.1.1" + dependencies: + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27 + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -12022,7 +12912,7 @@ __metadata: languageName: node linkType: hard -"is-builtin-module@npm:^3.1.0": +"is-builtin-module@npm:^3.1.0, is-builtin-module@npm:^3.2.1": version: 3.2.1 resolution: "is-builtin-module@npm:3.2.1" dependencies: @@ -12031,6 +12921,13 @@ __metadata: languageName: node linkType: hard +"is-callable@npm:^1.1.3": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac + languageName: node + linkType: hard + "is-ci@npm:^2.0.0": version: 2.0.0 resolution: "is-ci@npm:2.0.0" @@ -12189,6 +13086,16 @@ __metadata: languageName: node linkType: hard +"is-nan@npm:^1.3.2": + version: 1.3.2 + resolution: "is-nan@npm:1.3.2" + dependencies: + call-bind: ^1.0.0 + define-properties: ^1.1.3 + checksum: 5dfadcef6ad12d3029d43643d9800adbba21cf3ce2ec849f734b0e14ee8da4070d82b15fdb35138716d02587c6578225b9a22779cab34888a139cc43e4e3610a + languageName: node + linkType: hard + "is-npm@npm:^5.0.0": version: 5.0.0 resolution: "is-npm@npm:5.0.0" @@ -12224,6 +13131,13 @@ __metadata: languageName: node linkType: hard +"is-object@npm:~0.1.2": + version: 0.1.2 + resolution: "is-object@npm:0.1.2" + checksum: 7e500b15f4748278ea0a8d43b1283e75e866c055e4a790389087ce652eab8a9343fd74710738f0fdf13a323c31330d65bdcc106f38e9bb7bc0b9c60ae3fd2a2d + languageName: node + linkType: hard + "is-path-cwd@npm:^2.2.0": version: 2.2.0 resolution: "is-path-cwd@npm:2.2.0" @@ -12319,6 +13233,15 @@ __metadata: languageName: node linkType: hard +"is-typed-array@npm:^1.1.3": + version: 1.1.12 + resolution: "is-typed-array@npm:1.1.12" + dependencies: + which-typed-array: ^1.1.11 + checksum: 4c89c4a3be07186caddadf92197b17fda663a9d259ea0d44a85f171558270d36059d1c386d34a12cba22dfade5aba497ce22778e866adc9406098c8fc4771796 + languageName: node + linkType: hard + "is-typedarray@npm:^1.0.0": version: 1.0.0 resolution: "is-typedarray@npm:1.0.0" @@ -12370,6 +13293,13 @@ __metadata: languageName: node linkType: hard +"is@npm:~0.2.6": + version: 0.2.7 + resolution: "is@npm:0.2.7" + checksum: 45cea1e6deb41150b5753e18041a833657313e9c791c73f96fb9014b613346f5af2e6650858ef50ea6262c79555b65e09b13d30a268139863885025dd65f1059 + languageName: node + linkType: hard + "isarray@npm:0.0.1": version: 0.0.1 resolution: "isarray@npm:0.0.1" @@ -12391,6 +13321,13 @@ __metadata: languageName: node linkType: hard +"isbuffer@npm:~0.0.0": + version: 0.0.0 + resolution: "isbuffer@npm:0.0.0" + checksum: 9796296d3c493974c1f71ccf3170cc8007217a19ce8b3b9dedffd32e8ccc3ac42473b572bbf1b24b86143e826ea157aead11fd1285389518abab76c7da5f50ed + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -12595,6 +13532,29 @@ __metadata: languageName: node linkType: hard +"json-joy@npm:^9.2.0": + version: 9.9.1 + resolution: "json-joy@npm:9.9.1" + dependencies: + arg: ^5.0.2 + hyperdyperid: ^1.2.0 + peerDependencies: + quill-delta: ^5 + rxjs: 7 + tslib: 2 + bin: + jj: bin/jj.js + json-pack: bin/json-pack.js + json-pack-test: bin/json-pack-test.js + json-patch: bin/json-patch.js + json-patch-test: bin/json-patch-test.js + json-pointer: bin/json-pointer.js + json-pointer-test: bin/json-pointer-test.js + json-unpack: bin/json-unpack.js + checksum: d165398682f00019796225faf365cd8d060f3e086af39bb5081c30907b7e52eaf13697d1c0f6ee2b010fe255ae1fd776e05ad7d6ee5fb549e98fe982f560884b + languageName: node + linkType: hard + "json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" @@ -12676,6 +13636,13 @@ __metadata: languageName: node linkType: hard +"just-extend@npm:^4.0.2": + version: 4.2.1 + resolution: "just-extend@npm:4.2.1" + checksum: ff9fdede240fad313efeeeb68a660b942e5586d99c0058064c78884894a2690dc09bba44c994ad4e077e45d913fef01a9240c14a72c657b53687ac58de53b39c + languageName: node + linkType: hard + "katex@npm:^0.16.0": version: 0.16.9 resolution: "katex@npm:0.16.9" @@ -12874,6 +13841,94 @@ __metadata: languageName: node linkType: hard +"level-blobs@npm:^0.1.7": + version: 0.1.7 + resolution: "level-blobs@npm:0.1.7" + dependencies: + level-peek: 1.0.6 + once: ^1.3.0 + readable-stream: ^1.0.26-4 + checksum: e3cf78ef0bc64ff350edb4e247b2689cd4f5facf1119694ca8c96c28a05a38dc9d88e0bd065b18af65330bc22f5d588719a5c3e63adaa5feba5ea7913f87bebe + languageName: node + linkType: hard + +"level-filesystem@npm:^1.0.1": + version: 1.2.0 + resolution: "level-filesystem@npm:1.2.0" + dependencies: + concat-stream: ^1.4.4 + errno: ^0.1.1 + fwd-stream: ^1.0.4 + level-blobs: ^0.1.7 + level-peek: ^1.0.6 + level-sublevel: ^5.2.0 + octal: ^1.0.0 + once: ^1.3.0 + xtend: ^2.2.0 + checksum: a29e6a9d8c1879d43610113d1bcb59368685ec0ae413fcf0f8dcbb0a0c26b88fcf16f7481acb2b4650e5951ba0635e73a2c8fbe25cd599c50f80949a5547a367 + languageName: node + linkType: hard + +"level-fix-range@npm:2.0": + version: 2.0.0 + resolution: "level-fix-range@npm:2.0.0" + dependencies: + clone: ~0.1.9 + checksum: 250cefa69e1035d1412b4ba3e5cab83cceb894aa833fb0a93417d8d6230c60f6f8154feffbd0f116461ddd441b909e7df1323355d3e1769b3bb20a55729145b5 + languageName: node + linkType: hard + +"level-fix-range@npm:~1.0.2": + version: 1.0.2 + resolution: "level-fix-range@npm:1.0.2" + checksum: 6c9a3894ea08947fae79c41b75e8b9d57979523b656bec43c589f2dc4455276a150df445d9a7ca880a7c58c2ef19f5cea7f661d777993b870f4943af6b31d5bb + languageName: node + linkType: hard + +"level-hooks@npm:>=4.4.0 <5": + version: 4.5.0 + resolution: "level-hooks@npm:4.5.0" + dependencies: + string-range: ~1.2 + checksum: f198ad2e0901a4719e324e67f546097589af79665ebaaabee7122fda18a41ada3158bb1816b8b82430f30c68610125e4e20b5c09ec3ba7ae262d97dba34f48ab + languageName: node + linkType: hard + +"level-js@npm:^2.1.3": + version: 2.2.4 + resolution: "level-js@npm:2.2.4" + dependencies: + abstract-leveldown: ~0.12.0 + idb-wrapper: ^1.5.0 + isbuffer: ~0.0.0 + ltgt: ^2.1.2 + typedarray-to-buffer: ~1.0.0 + xtend: ~2.1.2 + checksum: 4fed784fcfad4bc6ec97d9c3897e95eaa30326fcdab9f4c7437624d10fa875fa84aafcc2acac0d53181af506cbc012c03f413b4da12ff83758d3bcbb699f8c8e + languageName: node + linkType: hard + +"level-peek@npm:1.0.6, level-peek@npm:^1.0.6": + version: 1.0.6 + resolution: "level-peek@npm:1.0.6" + dependencies: + level-fix-range: ~1.0.2 + checksum: e07d5f8b80675727204d9a226a249139da9e354e633b9d57b7a5186a7b85be445e550ca628f5133bf7a220a9311a193ded5a3f83588dc4eaa53ffb86b426154a + languageName: node + linkType: hard + +"level-sublevel@npm:^5.2.0": + version: 5.2.3 + resolution: "level-sublevel@npm:5.2.3" + dependencies: + level-fix-range: 2.0 + level-hooks: ">=4.4.0 <5" + string-range: ~1.2.1 + xtend: ~2.0.4 + checksum: f0fdffc2f9ca289aa183a1bf7f300a8f92e4f01be60eab37ab36e1f6ec33ed449519d8f69504a616e82f3ddca13a15fa4e19af1dcc1beba9044a4c60b6cd94bf + languageName: node + linkType: hard + "level-supports@npm:^4.0.0": version: 4.0.1 resolution: "level-supports@npm:4.0.1" @@ -12901,6 +13956,21 @@ __metadata: languageName: node linkType: hard +"levelup@npm:^0.18.2": + version: 0.18.6 + resolution: "levelup@npm:0.18.6" + dependencies: + bl: ~0.8.1 + deferred-leveldown: ~0.2.0 + errno: ~0.1.1 + prr: ~0.0.0 + readable-stream: ~1.0.26 + semver: ~2.3.1 + xtend: ~3.0.0 + checksum: 80e140dd83dc94050e283fc02874ae85116cb560d81e14fee0ac111f86006887835ec905dca7a081414c07eca202245a580f1e02f696367b777ecc23a9e05b86 + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -13035,6 +14105,13 @@ __metadata: languageName: node linkType: hard +"lodash.get@npm:^4.4.2": + version: 4.4.2 + resolution: "lodash.get@npm:4.4.2" + checksum: e403047ddb03181c9d0e92df9556570e2b67e0f0a930fcbbbd779370972368f5568e914f913e93f3b08f6d492abc71e14d4e9b7a18916c31fa04bd2306efe545 + languageName: node + linkType: hard + "lodash.isequal@npm:^4.5.0": version: 4.5.0 resolution: "lodash.isequal@npm:4.5.0" @@ -13174,6 +14251,13 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^7.14.1": + version: 7.18.3 + resolution: "lru-cache@npm:7.18.3" + checksum: e550d772384709deea3f141af34b6d4fa392e2e418c1498c078de0ee63670f1f46f5eee746e8ef7e69e1c895af0d4224e62ee33e66a543a14763b0f2e74c1356 + languageName: node + linkType: hard + "lru-cache@npm:^8.0.4": version: 8.0.5 resolution: "lru-cache@npm:8.0.5" @@ -13188,6 +14272,13 @@ __metadata: languageName: node linkType: hard +"ltgt@npm:^2.1.2": + version: 2.2.1 + resolution: "ltgt@npm:2.2.1" + checksum: 7e3874296f7538bc8087b428ac4208008d7b76916354b34a08818ca7c83958c1df10ec427eeeaad895f6b81e41e24745b18d30f89abcc21d228b94f6961d50a2 + languageName: node + linkType: hard + "lunr-languages@npm:^1.4.0": version: 1.14.0 resolution: "lunr-languages@npm:1.14.0" @@ -13653,6 +14744,18 @@ __metadata: languageName: node linkType: hard +"memfs@npm:^4.6.0": + version: 4.6.0 + resolution: "memfs@npm:4.6.0" + dependencies: + json-joy: ^9.2.0 + thingies: ^1.11.1 + peerDependencies: + tslib: 2 + checksum: b32a35bee9f96dc011605f3bb39e74e6d2a5de51c952a77bb38a0dfabd3381c40ae382d27f385aa290edee8081597fb1a3b41a07bb3f775fd55312dc30ac1d9d + languageName: node + linkType: hard + "memory-level@npm:^1.0.0": version: 1.0.0 resolution: "memory-level@npm:1.0.0" @@ -14212,7 +15315,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": +"micromatch@npm:^4.0.0, micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.5 resolution: "micromatch@npm:4.0.5" dependencies: @@ -14484,6 +15587,15 @@ __metadata: languageName: node linkType: hard +"mocha-each@npm:^2.0.1": + version: 2.0.1 + resolution: "mocha-each@npm:2.0.1" + dependencies: + sprintf-js: ^1.0.3 + checksum: 0de01ce517c2f7e7c3e19ef3f444809913f2f1602cb2571e6a3f8cb7ef3040f4f01b0f9f11a317e4ec1aeb9d39ceae4947c96668560cf638fe4d02ea549c2d4c + languageName: node + linkType: hard + "mocha@npm:^10.0.0, mocha@npm:^10.2.0": version: 10.2.0 resolution: "mocha@npm:10.2.0" @@ -14644,10 +15756,30 @@ __metadata: languageName: node linkType: hard -"neo-async@npm:^2.6.2": - version: 2.6.2 - resolution: "neo-async@npm:2.6.2" - checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: deac9f8d00eda7b2e5cd1b2549e26e10a0faa70adaa6fdadca701cc55f49ee9018e427f424bac0c790b7c7e2d3068db97f3093f1093975f2acb8f8818b936ed9 + languageName: node + linkType: hard + +"netmask@npm:^2.0.2": + version: 2.0.2 + resolution: "netmask@npm:2.0.2" + checksum: c65cb8d3f7ea5669edddb3217e4c96910a60d0d9a4b52d9847ff6b28b2d0277cd8464eee0ef85133cdee32605c57940cacdd04a9a019079b091b6bba4cb0ec22 + languageName: node + linkType: hard + +"nise@npm:^5.1.5": + version: 5.1.5 + resolution: "nise@npm:5.1.5" + dependencies: + "@sinonjs/commons": ^2.0.0 + "@sinonjs/fake-timers": ^10.0.2 + "@sinonjs/text-encoding": ^0.7.1 + just-extend: ^4.0.2 + path-to-regexp: ^1.7.0 + checksum: c763dc62c5796cafa5c9268e14a5b34db6e6fa2f1dbc57a891fe5d7ea632a87868e22b5bb34965006f984630793ea11368351e94971163228d9e20b2e88edce8 languageName: node linkType: hard @@ -14723,6 +15855,20 @@ __metadata: languageName: node linkType: hard +"node-fetch@npm:^2.6.12": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: ^5.0.0 + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5 + languageName: node + linkType: hard + "node-forge@npm:^1": version: 1.3.1 resolution: "node-forge@npm:1.3.1" @@ -14862,6 +16008,16 @@ __metadata: languageName: node linkType: hard +"object-is@npm:^1.1.5": + version: 1.1.5 + resolution: "object-is@npm:1.1.5" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.1.3 + checksum: 989b18c4cba258a6b74dc1d74a41805c1a1425bce29f6cabb50dcb1a6a651ea9104a1b07046739a49a5bb1bc49727bcb00efd5c55f932f6ea04ec8927a7901fe + languageName: node + linkType: hard + "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -14869,7 +16025,25 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.0": +"object-keys@npm:~0.2.0": + version: 0.2.0 + resolution: "object-keys@npm:0.2.0" + dependencies: + foreach: ~2.0.1 + indexof: ~0.0.1 + is: ~0.2.6 + checksum: 4b96bab88fe9df22a03aec3c59a084bdffc789ad1318a39081e6b8389af6b9ab8571dd3776eed3ec5831137d057fb7ba76911552c6a6efd59b5d126ac3b6e432 + languageName: node + linkType: hard + +"object-keys@npm:~0.4.0": + version: 0.4.0 + resolution: "object-keys@npm:0.4.0" + checksum: 1be3ebe9b48c0d5eda8e4a30657d887a748cb42435e0e2eaf49faf557bdd602cd2b7558b8ce90a4eb2b8592d16b875a1900bce859cbb0f35b21c67e11a45313c + languageName: node + linkType: hard + +"object.assign@npm:^4.1.0, object.assign@npm:^4.1.4": version: 4.1.5 resolution: "object.assign@npm:4.1.5" dependencies: @@ -14895,6 +16069,13 @@ __metadata: languageName: node linkType: hard +"octal@npm:^1.0.0": + version: 1.0.0 + resolution: "octal@npm:1.0.0" + checksum: d648917f4f0a1042d7a4e230262aed00274c9791fe4795e9a2ce3b64ab7f2ca93e62cd55ca5ad4e4bd3fc375ca84d6919d7bf417be461790c1042503ac2c2310 + languageName: node + linkType: hard + "on-finished@npm:2.4.1, on-finished@npm:^2.3.0": version: 2.4.1 resolution: "on-finished@npm:2.4.1" @@ -15151,6 +16332,33 @@ __metadata: languageName: node linkType: hard +"pac-proxy-agent@npm:^7.0.0": + version: 7.0.1 + resolution: "pac-proxy-agent@npm:7.0.1" + dependencies: + "@tootallnate/quickjs-emscripten": ^0.23.0 + agent-base: ^7.0.2 + debug: ^4.3.4 + get-uri: ^6.0.1 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.2 + pac-resolver: ^7.0.0 + socks-proxy-agent: ^8.0.2 + checksum: 3d4aa48ec1c19db10158ecc1c4c9a9f77792294412d225ceb3dfa45d5a06950dca9755e2db0d9b69f12769119bea0adf2b24390d9c73c8d81df75e28245ae451 + languageName: node + linkType: hard + +"pac-resolver@npm:^7.0.0": + version: 7.0.0 + resolution: "pac-resolver@npm:7.0.0" + dependencies: + degenerator: ^5.0.0 + ip: ^1.1.8 + netmask: ^2.0.2 + checksum: fa3a898c09848e93e35f5e23443fea36ddb393a851c76a23664a5bf3fcbe58ff77a0bcdae1e4f01b9ea87ea493c52e14d97a0fe39f92474d14cd45559c6e3cde + languageName: node + linkType: hard + "package-json@npm:^6.3.0": version: 6.5.0 resolution: "package-json@npm:6.5.0" @@ -15286,6 +16494,13 @@ __metadata: languageName: node linkType: hard +"path-browserify@npm:^1.0.1": + version: 1.0.1 + resolution: "path-browserify@npm:1.0.1" + checksum: c6d7fa376423fe35b95b2d67990060c3ee304fc815ff0a2dc1c6c3cfaff2bd0d572ee67e18f19d0ea3bbe32e8add2a05021132ac40509416459fffee35200699 + languageName: node + linkType: hard + "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -15443,7 +16658,7 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^4.1.0": +"pkg-dir@npm:^4.1.0, pkg-dir@npm:^4.2.0": version: 4.2.0 resolution: "pkg-dir@npm:4.2.0" dependencies: @@ -16041,6 +17256,13 @@ __metadata: languageName: node linkType: hard +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 + languageName: node + linkType: hard + "progress@npm:2.0.3": version: 2.0.3 resolution: "progress@npm:2.0.3" @@ -16112,6 +17334,22 @@ __metadata: languageName: node linkType: hard +"proxy-agent@npm:6.3.0": + version: 6.3.0 + resolution: "proxy-agent@npm:6.3.0" + dependencies: + agent-base: ^7.0.2 + debug: ^4.3.4 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.0 + lru-cache: ^7.14.1 + pac-proxy-agent: ^7.0.0 + proxy-from-env: ^1.1.0 + socks-proxy-agent: ^8.0.1 + checksum: e3fb0633d665e352ed4efe23ae5616b8301423dfa4ff1c5975d093da8a636181a97391f7a91c6a7ffae17c1a305df855e95507f73bcdafda8876198c64b88f5b + languageName: node + linkType: hard + "proxy-from-env@npm:1.1.0, proxy-from-env@npm:^1.1.0": version: 1.1.0 resolution: "proxy-from-env@npm:1.1.0" @@ -16119,6 +17357,20 @@ __metadata: languageName: node linkType: hard +"prr@npm:~0.0.0": + version: 0.0.0 + resolution: "prr@npm:0.0.0" + checksum: 6552d9d92d9d55ec1afb8952ad80f81bbb1b4379f24ff7c506ad083ea701caf1bf6d4b092a2baeb98ec3f312c5a49d8bdf1d9b20a6db2998d05c2d52aa6a82e7 + languageName: node + linkType: hard + +"prr@npm:~1.0.1": + version: 1.0.1 + resolution: "prr@npm:1.0.1" + checksum: 3bca2db0479fd38f8c4c9439139b0c42dcaadcc2fbb7bb8e0e6afaa1383457f1d19aea9e5f961d5b080f1cfc05bfa1fe9e45c97a1d3fd6d421950a73d3108381 + languageName: node + linkType: hard + "ps-tree@npm:^1.2.0": version: 1.2.0 resolution: "ps-tree@npm:1.2.0" @@ -16140,7 +17392,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^1.3.2": +"punycode@npm:^1.3.2, punycode@npm:^1.4.1": version: 1.4.1 resolution: "punycode@npm:1.4.1" checksum: fa6e698cb53db45e4628559e557ddaf554103d2a96a1d62892c8f4032cd3bc8871796cae9eabc1bc700e2b6677611521ce5bb1d9a27700086039965d0cf34518 @@ -16196,6 +17448,25 @@ __metadata: languageName: node linkType: hard +"puppeteer-core@npm:^20.0.0": + version: 20.9.0 + resolution: "puppeteer-core@npm:20.9.0" + dependencies: + "@puppeteer/browsers": 1.4.6 + chromium-bidi: 0.4.16 + cross-fetch: 4.0.0 + debug: 4.3.4 + devtools-protocol: 0.0.1147663 + ws: 8.13.0 + peerDependencies: + typescript: ">= 4.7.4" + peerDependenciesMeta: + typescript: + optional: true + checksum: d298598445b0f2032c02d0ed7d1d18a8d2d2fcaf6fc31fc96e93e2669a7fc6fbee0338bd9b8c8f8822887f18a8fb680b77bb56e96fe1928baadb52292bbd93b4 + languageName: node + linkType: hard + "qs@npm:6.11.0": version: 6.11.0 resolution: "qs@npm:6.11.0" @@ -16205,7 +17476,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.5.2": +"qs@npm:^6.11.2, qs@npm:^6.5.2": version: 6.11.2 resolution: "qs@npm:6.11.2" dependencies: @@ -16221,6 +17492,13 @@ __metadata: languageName: node linkType: hard +"queue-tick@npm:^1.0.1": + version: 1.0.1 + resolution: "queue-tick@npm:1.0.1" + checksum: 57c3292814b297f87f792fbeb99ce982813e4e54d7a8bdff65cf53d5c084113913289d4a48ec8bbc964927a74b847554f9f4579df43c969a6c8e0f026457ad01 + languageName: node + linkType: hard + "queue@npm:6.0.2": version: 6.0.2 resolution: "queue@npm:6.0.2" @@ -16493,7 +17771,19 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^2.0.1": +"readable-stream@npm:^1.0.26-4": + version: 1.1.14 + resolution: "readable-stream@npm:1.1.14" + dependencies: + core-util-is: ~1.0.0 + inherits: ~2.0.1 + isarray: 0.0.1 + string_decoder: ~0.10.x + checksum: 17dfeae3e909945a4a1abc5613ea92d03269ef54c49288599507fc98ff4615988a1c39a999dcf9aacba70233d9b7040bc11a5f2bfc947e262dedcc0a8b32b5a0 + languageName: node + linkType: hard + +"readable-stream@npm:^2.0.1, readable-stream@npm:^2.2.2": version: 2.3.8 resolution: "readable-stream@npm:2.3.8" dependencies: @@ -16519,6 +17809,31 @@ __metadata: languageName: node linkType: hard +"readable-stream@npm:^4.4.2": + version: 4.4.2 + resolution: "readable-stream@npm:4.4.2" + dependencies: + abort-controller: ^3.0.0 + buffer: ^6.0.3 + events: ^3.3.0 + process: ^0.11.10 + string_decoder: ^1.3.0 + checksum: 6f4063763dbdb52658d22d3f49ca976420e1fbe16bbd241f744383715845350b196a2f08b8d6330f8e219153dff34b140aeefd6296da828e1041a7eab1f20d5e + languageName: node + linkType: hard + +"readable-stream@npm:~1.0.26, readable-stream@npm:~1.0.26-4": + version: 1.0.34 + resolution: "readable-stream@npm:1.0.34" + dependencies: + core-util-is: ~1.0.0 + inherits: ~2.0.1 + isarray: 0.0.1 + string_decoder: ~0.10.x + checksum: 85042c537e4f067daa1448a7e257a201070bfec3dd2706abdbd8ebc7f3418eb4d3ed4b8e5af63e2544d69f88ab09c28d5da3c0b77dc76185fddd189a59863b60 + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -16544,6 +17859,15 @@ __metadata: languageName: node linkType: hard +"rechoir@npm:^0.7.0": + version: 0.7.1 + resolution: "rechoir@npm:0.7.1" + dependencies: + resolve: ^1.9.0 + checksum: 2a04aab4e28c05fcd6ee6768446bc8b859d8f108e71fc7f5bcbc5ef25e53330ce2c11d10f82a24591a2df4c49c4f61feabe1fd11f844c66feedd4cd7bb61146a + languageName: node + linkType: hard + "recursive-readdir@npm:^2.2.2": version: 2.2.3 resolution: "recursive-readdir@npm:2.2.3" @@ -16945,6 +18269,15 @@ __metadata: languageName: node linkType: hard +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: ^5.0.0 + checksum: 546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 + languageName: node + linkType: hard + "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -16952,6 +18285,13 @@ __metadata: languageName: node linkType: hard +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf + languageName: node + linkType: hard + "resolve-path@npm:^1.4.0": version: 1.4.0 resolution: "resolve-path@npm:1.4.0" @@ -16985,7 +18325,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.3.2": +"resolve@npm:^1.1.6, resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.22.1, resolve@npm:^1.3.2, resolve@npm:^1.9.0": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -17007,7 +18347,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.3.2#~builtin": +"resolve@patch:resolve@^1.1.6#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.22.1#~builtin, resolve@patch:resolve@^1.3.2#~builtin, resolve@patch:resolve@^1.9.0#~builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -17126,6 +18466,60 @@ __metadata: languageName: node linkType: hard +"rollup@npm:^4.4.0": + version: 4.9.4 + resolution: "rollup@npm:4.9.4" + dependencies: + "@rollup/rollup-android-arm-eabi": 4.9.4 + "@rollup/rollup-android-arm64": 4.9.4 + "@rollup/rollup-darwin-arm64": 4.9.4 + "@rollup/rollup-darwin-x64": 4.9.4 + "@rollup/rollup-linux-arm-gnueabihf": 4.9.4 + "@rollup/rollup-linux-arm64-gnu": 4.9.4 + "@rollup/rollup-linux-arm64-musl": 4.9.4 + "@rollup/rollup-linux-riscv64-gnu": 4.9.4 + "@rollup/rollup-linux-x64-gnu": 4.9.4 + "@rollup/rollup-linux-x64-musl": 4.9.4 + "@rollup/rollup-win32-arm64-msvc": 4.9.4 + "@rollup/rollup-win32-ia32-msvc": 4.9.4 + "@rollup/rollup-win32-x64-msvc": 4.9.4 + "@types/estree": 1.0.5 + fsevents: ~2.3.2 + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 134b1fd8886a1dc86b2cadada979174e736a39aec12d069261fe8b799ad0c4aa3213188ea49adeee155669315016617260e43eea754436c50121aa359899da4d + languageName: node + linkType: hard + "rtl-detect@npm:^1.0.4": version: 1.1.2 resolution: "rtl-detect@npm:1.1.2" @@ -17374,6 +18768,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:~2.3.1": + version: 2.3.2 + resolution: "semver@npm:2.3.2" + bin: + semver: ./bin/semver + checksum: e0649fb18a1da909df7b5a6f586314a7f6e052385fc1e6eafa7084dd77c0787e755ab35ca491f9eec986fe1d0d6d36eae85a21eb7e2ed32ae5906796acb92c56 + languageName: node + linkType: hard + "send@npm:0.18.0": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -17611,6 +19014,20 @@ __metadata: languageName: node linkType: hard +"sinon@npm:^17.0.1": + version: 17.0.1 + resolution: "sinon@npm:17.0.1" + dependencies: + "@sinonjs/commons": ^3.0.0 + "@sinonjs/fake-timers": ^11.2.2 + "@sinonjs/samsam": ^8.0.0 + diff: ^5.1.0 + nise: ^5.1.5 + supports-color: ^7.2.0 + checksum: a807c2997d6eabdcaa4409df9fd9816a3e839f96d7e5d76610a33f5e1b60cf37616c6288f0f580262da17ea4ee626c6d1600325bf423e30c5a7f0d9a203e26c0 + languageName: node + linkType: hard + "sirv@npm:^2.0.3": version: 2.0.3 resolution: "sirv@npm:2.0.3" @@ -17702,7 +19119,7 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.1": +"socks-proxy-agent@npm:^8.0.1, socks-proxy-agent@npm:^8.0.2": version: 8.0.2 resolution: "socks-proxy-agent@npm:8.0.2" dependencies: @@ -17773,14 +19190,14 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0": +"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: 59ce8640cf3f3124f64ac289012c2b8bd377c238e316fb323ea22fbfe83da07d81e000071d7242cad7a23cd91c7de98e4df8830ec3f133cb6133a5f6e9f67bc2 languageName: node linkType: hard -"source-map@npm:^0.7.0, source-map@npm:^0.7.3": +"source-map@npm:^0.7.0, source-map@npm:^0.7.3, source-map@npm:^0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 @@ -17837,6 +19254,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:^1.0.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -17927,6 +19351,16 @@ __metadata: languageName: node linkType: hard +"streamx@npm:^2.15.0": + version: 2.15.6 + resolution: "streamx@npm:2.15.6" + dependencies: + fast-fifo: ^1.1.0 + queue-tick: ^1.0.1 + checksum: 37a245f5cee4c33fcb8b018ccb935bad6eab423f05b0d14d018e63dbd2670bb109a69442e961a195b750c2c774f613c19476d11bd727d645eedb655d2dba234b + languageName: node + linkType: hard + "string-format@npm:^2.0.0": version: 2.0.0 resolution: "string-format@npm:2.0.0" @@ -17934,6 +19368,13 @@ __metadata: languageName: node linkType: hard +"string-range@npm:~1.2, string-range@npm:~1.2.1": + version: 1.2.2 + resolution: "string-range@npm:1.2.2" + checksum: 7118cc83a7e63fca5fd8bef9b61464bfc51197b5f6dc475c9e1d24a93ce02fa27f7adb4cd7adac5daf599bde442b383608078f9b051bddb108d3b45840923097 + languageName: node + linkType: hard + "string-to-stream@npm:^3.0.1": version: 3.0.1 resolution: "string-to-stream@npm:3.0.1" @@ -17965,7 +19406,7 @@ __metadata: languageName: node linkType: hard -"string_decoder@npm:^1.1.1": +"string_decoder@npm:^1.1.1, string_decoder@npm:^1.3.0": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" dependencies: @@ -17974,6 +19415,13 @@ __metadata: languageName: node linkType: hard +"string_decoder@npm:~0.10.x": + version: 0.10.31 + resolution: "string_decoder@npm:0.10.31" + checksum: fe00f8e303647e5db919948ccb5ce0da7dea209ab54702894dd0c664edd98e5d4df4b80d6fabf7b9e92b237359d21136c95bf068b2f7760b772ca974ba970202 + languageName: node + linkType: hard + "string_decoder@npm:~1.1.1": version: 1.1.1 resolution: "string_decoder@npm:1.1.1" @@ -18130,7 +19578,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^7.1.0": +"supports-color@npm:^7.1.0, supports-color@npm:^7.2.0": version: 7.2.0 resolution: "supports-color@npm:7.2.0" dependencies: @@ -18235,6 +19683,17 @@ __metadata: languageName: node linkType: hard +"tar-fs@npm:3.0.4": + version: 3.0.4 + resolution: "tar-fs@npm:3.0.4" + dependencies: + mkdirp-classic: ^0.5.2 + pump: ^3.0.0 + tar-stream: ^3.1.5 + checksum: dcf4054f9e92ca0efe61c2b3f612914fb259a47900aa908a63106513a6d006c899b426ada53eb88d9dbbf089b5724c8e90b96a2c4ca6171845fa14203d734e30 + languageName: node + linkType: hard + "tar-stream@npm:^2.1.4": version: 2.2.0 resolution: "tar-stream@npm:2.2.0" @@ -18248,6 +19707,17 @@ __metadata: languageName: node linkType: hard +"tar-stream@npm:^3.1.5": + version: 3.1.6 + resolution: "tar-stream@npm:3.1.6" + dependencies: + b4a: ^1.6.4 + fast-fifo: ^1.2.0 + streamx: ^2.15.0 + checksum: f3627f918581976e954ff03cb8d370551053796b82564f8c7ca8fac84c48e4d042026d0854fc222171a34ff9c682b72fae91be9c9b0a112d4c54f9e4f443e9c5 + languageName: node + linkType: hard + "tar@npm:^6.1.11, tar@npm:^6.1.2": version: 6.2.0 resolution: "tar@npm:6.2.0" @@ -18305,6 +19775,15 @@ __metadata: languageName: node linkType: hard +"thingies@npm:^1.11.1": + version: 1.15.0 + resolution: "thingies@npm:1.15.0" + peerDependencies: + tslib: ^2 + checksum: 9721bc0cbcf1565ba1abd70cfe5141a638c88dded74abb24d9b21749e16034af37dfa68edd37e7d1bb1b1c9c8bfb301c4699a8e4bc998a3a9c18052edb829bb2 + languageName: node + linkType: hard + "through@npm:2, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.1": version: 2.3.8 resolution: "through@npm:2.3.8" @@ -18467,6 +19946,22 @@ __metadata: languageName: node linkType: hard +"ts-loader@npm:^9.5.1": + version: 9.5.1 + resolution: "ts-loader@npm:9.5.1" + dependencies: + chalk: ^4.1.0 + enhanced-resolve: ^5.0.0 + micromatch: ^4.0.0 + semver: ^7.3.4 + source-map: ^0.7.4 + peerDependencies: + typescript: "*" + webpack: ^5.0.0 + checksum: 7cf396e656d905388ea2a9b5e82f16d3c955fda8d3df2fbf219f4bee16ff50a3c995c44ae3e584634e9443f056cec70bb3151add3917ffb4588ecd7394bac0ec + languageName: node + linkType: hard + "ts-node@npm:^10.9.1": version: 10.9.2 resolution: "ts-node@npm:10.9.2" @@ -18541,7 +20036,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": +"tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad @@ -18608,7 +20103,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": +"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 62b5628bff67c0eb0b66afa371bd73e230399a8d2ad30d852716efcc4656a7516904570cd8631a49a3ce57c10225adf5d0cbdcb47f6b0255fe6557c453925a15 @@ -18669,6 +20164,20 @@ __metadata: languageName: node linkType: hard +"typedarray-to-buffer@npm:~1.0.0": + version: 1.0.4 + resolution: "typedarray-to-buffer@npm:1.0.4" + checksum: ac6989c456a0b175c8362b3ebbd8a74af7b9bcc94f9dc9ffd34436569cd29aea6a1e0e5f5752d0d5bd855a55b2520e960d1d4cb9c9149f863ce09220540df17f + languageName: node + linkType: hard + +"typedarray@npm:^0.0.6": + version: 0.0.6 + resolution: "typedarray@npm:0.0.6" + checksum: 33b39f3d0e8463985eeaeeacc3cb2e28bc3dfaf2a5ed219628c0b629d5d7b810b0eb2165f9f607c34871d5daa92ba1dc69f49051cf7d578b4cbd26c340b9d1b1 + languageName: node + linkType: hard + "typedoc-plugin-frontmatter@npm:^0.0.2": version: 0.0.2 resolution: "typedoc-plugin-frontmatter@npm:0.0.2" @@ -19134,6 +20643,15 @@ __metadata: languageName: node linkType: hard +"unzipit@npm:^1.4.3": + version: 1.4.3 + resolution: "unzipit@npm:1.4.3" + dependencies: + uzip-module: ^1.0.2 + checksum: ce29348edab7b5fb5b7b4d43437f48e35812ac8b3cc2d76efd1acfcad6dd1b96b4f96bfd03250a724b87ba99dd531d7727ad24b590acf727dde79f54f5e779ed + languageName: node + linkType: hard + "update-browserslist-db@npm:^1.0.13": version: 1.0.13 resolution: "update-browserslist-db@npm:1.0.13" @@ -19237,6 +20755,16 @@ __metadata: languageName: node linkType: hard +"url@npm:^0.11.3": + version: 0.11.3 + resolution: "url@npm:0.11.3" + dependencies: + punycode: ^1.4.1 + qs: ^6.11.2 + checksum: f9e7886f46a16f96d2e42fbcc5d682c231c55ef5442c1ff66150c0f6556f6e3a97d094a84f51be15ec2432711d212eb60426659ce418f5fcadeaa3f601532c4e + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -19244,6 +20772,19 @@ __metadata: languageName: node linkType: hard +"util@npm:^0.12.5": + version: 0.12.5 + resolution: "util@npm:0.12.5" + dependencies: + inherits: ^2.0.3 + is-arguments: ^1.0.4 + is-generator-function: ^1.0.7 + is-typed-array: ^1.1.3 + which-typed-array: ^1.1.2 + checksum: 705e51f0de5b446f4edec10739752ac25856541e0254ea1e7e45e5b9f9b0cb105bc4bd415736a6210edc68245a7f903bf085ffb08dd7deb8a0e847f60538a38a + languageName: node + linkType: hard + "utila@npm:~0.4": version: 0.4.0 resolution: "utila@npm:0.4.0" @@ -19288,6 +20829,13 @@ __metadata: languageName: node linkType: hard +"uzip-module@npm:^1.0.2": + version: 1.0.3 + resolution: "uzip-module@npm:1.0.3" + checksum: fc286c44a04d75055577fae8293d3fee499d1e850f87e88c158b1e3657f4794a3a40ca2d34f73474ff82917176dd5ca9d1c0d1e375a083714e11afabd3afa423 + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -19409,7 +20957,7 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:^2.4.0": +"watchpack@npm:^2.1.1, watchpack@npm:^2.4.0": version: 2.4.0 resolution: "watchpack@npm:2.4.0" dependencies: @@ -19486,6 +21034,39 @@ __metadata: languageName: node linkType: hard +"webpack-cli@npm:^4.7.2": + version: 4.10.0 + resolution: "webpack-cli@npm:4.10.0" + dependencies: + "@discoveryjs/json-ext": ^0.5.0 + "@webpack-cli/configtest": ^1.2.0 + "@webpack-cli/info": ^1.5.0 + "@webpack-cli/serve": ^1.7.0 + colorette: ^2.0.14 + commander: ^7.0.0 + cross-spawn: ^7.0.3 + fastest-levenshtein: ^1.0.12 + import-local: ^3.0.2 + interpret: ^2.2.0 + rechoir: ^0.7.0 + webpack-merge: ^5.7.3 + peerDependencies: + webpack: 4.x.x || 5.x.x + peerDependenciesMeta: + "@webpack-cli/generators": + optional: true + "@webpack-cli/migrate": + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + bin: + webpack-cli: bin/cli.js + checksum: 2ff5355ac348e6b40f2630a203b981728834dca96d6d621be96249764b2d0fc01dd54edfcc37f02214d02935de2cf0eefd6ce689d970d154ef493f01ba922390 + languageName: node + linkType: hard + "webpack-dev-middleware@npm:^5.3.1": version: 5.3.3 resolution: "webpack-dev-middleware@npm:5.3.3" @@ -19548,7 +21129,7 @@ __metadata: languageName: node linkType: hard -"webpack-merge@npm:^5.8.0, webpack-merge@npm:^5.9.0": +"webpack-merge@npm:^5.7.3, webpack-merge@npm:^5.8.0, webpack-merge@npm:^5.9.0": version: 5.10.0 resolution: "webpack-merge@npm:5.10.0" dependencies: @@ -19566,7 +21147,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.73.0, webpack@npm:^5.88.1": +"webpack@npm:^5.49.0, webpack@npm:^5.73.0, webpack@npm:^5.88.1": version: 5.89.0 resolution: "webpack@npm:5.89.0" dependencies: @@ -19655,6 +21236,19 @@ __metadata: languageName: node linkType: hard +"which-typed-array@npm:^1.1.11, which-typed-array@npm:^1.1.2": + version: 1.1.13 + resolution: "which-typed-array@npm:1.1.13" + dependencies: + available-typed-arrays: ^1.0.5 + call-bind: ^1.0.4 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-tostringtag: ^1.0.0 + checksum: 3828a0d5d72c800e369d447e54c7620742a4cc0c9baf1b5e8c17e9b6ff90d8d861a3a6dd4800f1953dbf80e5e5cec954a289e5b4a223e3bee4aeb1f8c5f33309 + languageName: node + linkType: hard + "which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" @@ -19889,6 +21483,13 @@ __metadata: languageName: node linkType: hard +"xtend@npm:^2.2.0": + version: 2.2.0 + resolution: "xtend@npm:2.2.0" + checksum: 9fcd1ddabefdb3c68a698b08177525ad14a6df3423b13bad9a53900d19374e476a43c219b0756d39675776b2326a35fe477c547cfb8a05ae9fea4ba2235bebe2 + languageName: node + linkType: hard + "xtend@npm:^4.0.0, xtend@npm:^4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2" @@ -19896,6 +21497,32 @@ __metadata: languageName: node linkType: hard +"xtend@npm:~2.0.4": + version: 2.0.6 + resolution: "xtend@npm:2.0.6" + dependencies: + is-object: ~0.1.2 + object-keys: ~0.2.0 + checksum: 414531e51cbc56d4676ae2b3a4070052e0c7a36caf7ee74f2e8449fe0fc1752b971a776fca5b85ec02ef3d0a33b8e75491d900474b8407f3f4bba3f49325a785 + languageName: node + linkType: hard + +"xtend@npm:~2.1.2": + version: 2.1.2 + resolution: "xtend@npm:2.1.2" + dependencies: + object-keys: ~0.4.0 + checksum: a8b79f31502c163205984eaa2b196051cd2fab0882b49758e30f2f9018255bc6c462e32a090bf3385d1bda04755ad8cc0052a09e049b0038f49eb9b950d9c447 + languageName: node + linkType: hard + +"xtend@npm:~3.0.0": + version: 3.0.0 + resolution: "xtend@npm:3.0.0" + checksum: ecdc4dd74f26e561dbc13d4148fcc7b8f46f49b9259862fc31e42b7cede9eee62af9d869050a7b8e089475e858744a74ceae3f0da2943755ef712f3277ad2e50 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8"