From 9d2485caee7d997087764bc8010429f8831bba4c Mon Sep 17 00:00:00 2001 From: Christian Kaltenbach Date: Fri, 14 Aug 2026 14:05:17 +0200 Subject: [PATCH 1/2] PFM-ISSUE-34453 - github-actions: add package-lock.json normalizer, invariant check and PR guard --- .github/actions/use-npmrc/action.yml | 37 +- .github/workflows/pr-checks.yml | 61 ++ .prettierignore | 1 + tools/scripts/lockfile/README.md | 218 +++++++ tools/scripts/lockfile/check-lockfile.bats | 556 ++++++++++++++++++ tools/scripts/lockfile/check-lockfile.sh | 316 ++++++++++ tools/scripts/lockfile/fingerprint.jq | 36 ++ tools/scripts/lockfile/lib.sh | 194 ++++++ .../scripts/lockfile/normalize-lockfile.bats | 247 ++++++++ tools/scripts/lockfile/normalize-lockfile.sh | 100 ++++ tools/scripts/lockfile/test-helper.bash | 66 +++ .../lockfile/warn-foreign-registry.bats | 166 ++++++ .../scripts/lockfile/warn-foreign-registry.sh | 106 ++++ 13 files changed, 2102 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/pr-checks.yml create mode 100644 tools/scripts/lockfile/README.md create mode 100644 tools/scripts/lockfile/check-lockfile.bats create mode 100755 tools/scripts/lockfile/check-lockfile.sh create mode 100644 tools/scripts/lockfile/fingerprint.jq create mode 100644 tools/scripts/lockfile/lib.sh create mode 100644 tools/scripts/lockfile/normalize-lockfile.bats create mode 100755 tools/scripts/lockfile/normalize-lockfile.sh create mode 100644 tools/scripts/lockfile/test-helper.bash create mode 100644 tools/scripts/lockfile/warn-foreign-registry.bats create mode 100755 tools/scripts/lockfile/warn-foreign-registry.sh diff --git a/.github/actions/use-npmrc/action.yml b/.github/actions/use-npmrc/action.yml index effe5c40..40fa5623 100644 --- a/.github/actions/use-npmrc/action.yml +++ b/.github/actions/use-npmrc/action.yml @@ -1,5 +1,5 @@ name: 'Use .npmrc' -description: 'Writes the given .npmrc content to ~/.npmrc' +description: 'Writes the given .npmrc content to ~/.npmrc and warns about lockfile entries outside the cplace npm proxy' inputs: dot-npmrc: description: 'Content of the .npmrc file' @@ -11,4 +11,37 @@ runs: shell: bash env: DOT_NPMRC: ${{ inputs.dot-npmrc }} - run: echo "$DOT_NPMRC" > ~/.npmrc + run: | + echo "$DOT_NPMRC" > ~/.npmrc + # PFM-ISSUE-34453 mitigation. npm's default `replace-registry-host=npmjs` + # rewrites a lockfile's registry.npmjs.org URLs onto the configured + # registry. npm 10.2.4 does that correctly and the entry resolves through + # the proxy; npm 11.3.0 DROPS that registry's path prefix, producing an + # E404 masked as *** because the prefix is the JFROG_URL secret. Measured + # 2026-08-14 on a runner and locally with the same one-package fixture. + # + # `never` makes npm fetch each `resolved` URL verbatim, which survives + # both versions - at a cost: an entry still on npmjs is then fetched FROM + # npmjs, outside the proxy. This line buys npm-11 compatibility and + # spends proxy routing; normalizing the lockfile buys both. + # + # This is a no-op on a lockfile that already resolves entirely through + # the proxy, so it is safe to leave in place, and it is removable once + # the warning below stops firing anywhere. + echo 'replace-registry-host=never' >> ~/.npmrc + + - name: Warn on lockfile entries outside the cplace npm proxy + shell: bash + # Advisory only - never fails the build. The warnings are the inventory of + # lockfiles that still need normalizing; when none report, the mitigation + # above can be dropped. + # + # Invoked as `bash "" || true`, not as a bare path. The script's own + # "every precondition is a silent success" contract cannot cover NOT BEING + # REACHABLE - a missing exec bit after checkout, a path containing spaces, + # or a runner where action_path is a backslashed Windows path. That is an + # exit 127 from the shell rather than from the script, and it would fail + # the consumer's job before `npm ci` in all seven workflows using this + # action. `continue-on-error:` is not honoured on composite steps, so + # `|| true` is the mechanism that actually works here. + run: bash "$GITHUB_ACTION_PATH/../../../tools/scripts/lockfile/warn-foreign-registry.sh" || true diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml new file mode 100644 index 00000000..5be329c3 --- /dev/null +++ b/.github/workflows/pr-checks.yml @@ -0,0 +1,61 @@ +name: PR Checks + +# This repository's first `on: pull_request` workflow. Everything under +# .github/workflows/ is otherwise `workflow_call`-only, and the `pull_request` +# trigger lives in .github/workflow-templates/fe/fe-pr.yml, which GitHub never +# executes. +# +# No `paths:` filter on purpose: a path-filtered workflow reports as pending +# rather than success, and would permanently block merges once it becomes a +# required check. +on: + pull_request: + branches: + - '**' + +permissions: + contents: read + +jobs: + lockfile: + name: Lockfile registry invariant + runs-on: ${{ vars.SMALL_RUNNER || 'ubuntu-latest' }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + # --prefix-only, NOT a baseline comparison. The ongoing guard must answer + # only "does every entry resolve via the proxy?" - a pull request has to + # stay free to add, remove or update dependencies. + # + # Comparing against the base branch would fail every legitimate dependency + # change, and would then advise running the normalizer, which cannot fix a + # graph difference. Graph invariance belongs to verifying a normalization + # commit (`--baseline HEAD~1`), not to everyday pull requests. + # + # With no baseline there is nothing to fetch, so the default shallow + # checkout is enough. jq is pre-installed on GitHub-hosted ubuntu runners, + # and this job runs no node and no `npm ci` - the guard has to be + # trustworthy precisely when the lockfile is broken. + - name: Check package-lock.json resolved URLs + run: ./tools/scripts/lockfile/check-lockfile.sh --prefix-only + + scripts: + name: Shell scripts + runs-on: ${{ vars.SMALL_RUNNER || 'ubuntu-latest' }} + steps: + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + + # Never npm devDependencies: adding them would mutate package-lock.json on + # all seven branches and break the invariant this workflow exists to guard. + # shellcheck ships in the ubuntu image, but is installed here anyway so the + # job does not silently depend on image contents. + - name: Install bats and shellcheck + run: | + sudo apt-get update + sudo apt-get install -y bats shellcheck + + - name: shellcheck + run: shellcheck tools/scripts/lockfile/*.sh tools/scripts/lockfile/test-helper.bash + + - name: bats + run: bats tools/scripts/lockfile/ diff --git a/.prettierignore b/.prettierignore index eb79dd5f..0433bbc0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,3 @@ node_modules .idea +package-lock.json diff --git a/tools/scripts/lockfile/README.md b/tools/scripts/lockfile/README.md new file mode 100644 index 00000000..7556a1b7 --- /dev/null +++ b/tools/scripts/lockfile/README.md @@ -0,0 +1,218 @@ +# `package-lock.json` registry normalization + +Every `resolved` URL in this repository's `package-lock.json` must point at the cplace JFrog npm **proxy**. This +directory contains the tooling that enforces that. + +## Why this exists + +The composite actions in `.github/actions/` run `npm ci` **inside the action directory, on the consumer's runner**, +while that consumer's `~/.npmrc` is active. When a lockfile entry resolves via `https://registry.npmjs.org/`, npm +rewrites the host onto the configured registry and **discards the registry's path prefix** +(`pacote/lib/remote.js`: `new URL(resolvedURL.pathname, this.registry)`), producing a 404: + +| | | +| --- | --- | +| lockfile | `https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz` | +| requested | `https://cplace.jfrog.io/update-browserslist-db/-/…` → **404** | +| correct | `https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/update-browserslist-db/-/…` → 200 | + +The failure is hard to read because the broken URL's prefix is the `JFROG_URL` secret, so CI masks it as `***`. That +is why **every message these scripts print names a package path, never a URL.** + +## Why bash and jq, in a repository that is otherwise TypeScript + +Bootstrap independence. `npx ts-node` needs `node_modules`, which needs `npm ci` — which is exactly what is broken when +the lockfile carries npmjs URLs and your `~/.npmrc` points at JFrog. A TypeScript normalizer could not repair the +lockfile it exists to repair. These scripts need only `bash`, `jq` and `git`, all of which work on a fresh clone with +nothing installed. + +**Prerequisite:** `jq`. macOS: `brew install jq`. It is pre-installed on GitHub-hosted ubuntu runners. + +## The scripts + +| script | what it does | +| --- | --- | +| `normalize-lockfile.sh []` | Rewrites every `resolved` prefix onto the proxy. Idempotent. Changes nothing else. | +| `check-lockfile.sh [--baseline ] []` | Proves a lockfile differs from its baseline **only** in registry prefixes. Exit 0 or 1. | +| `check-lockfile.sh --prefix-only []` | Asserts only that every entry resolves via the proxy. **This is the PR guard.** | +| `warn-foreign-registry.sh []` | Advisory. Warns when a lockfile has entries outside the proxy. Never fails. Run by `use-npmrc`. | + +All three default to `./package-lock.json`. Call the normalizer and the check by path: they have no npm script and no +composite action wrapper, so that they keep working when `npm ci` does not. The advisory is the exception — it is +wrapped, run by `use-npmrc` on every consumer's runner, and can also be called by hand the same way. + +--- + +## The interim mitigation in `use-npmrc` + +`.github/actions/use-npmrc` appends one line to the `~/.npmrc` it writes: + +``` +replace-registry-host=never +``` + +This tells npm to fetch each `resolved` URL **verbatim** rather than rewriting its host onto the configured registry. +It makes an un-normalized lockfile install on any npm version, so it protects **consumer** repositories too, not just +this one. JFrog URLs stay authenticated by the secret, so it introduces no dependency on anonymous JFrog access. + +**The rewrite it disables is only broken on newer npm.** Measured 2026-08-14 with a one-package fixture, on a runner +and locally: + +| npm | un-normalized entry, no mitigation | tarball served by | +| --- | --- | --- | +| 10.2.4 (node 18.19.1 — what every pipeline pins today) | installs | the **proxy** — the rewrite keeps its path prefix | +| 11.3.0 (developer machines; any runner on node 24) | **`E404`**, masked as `***` | — prefix dropped | + +**It is a mitigation, not the fix**, and it is not free on either version. Under it, an entry still pointing at +`registry.npmjs.org` is fetched *directly from npmjs*, bypassing the proxy — no Xray, no curation. On npm 10 that is +its only effect, because the rewrite it disables was working. On npm 11 it buys compatibility and spends proxy +routing. Normalizing buys both: the entry resolves through the proxy on every version, flag or no flag. + +**This is why the Node 24 migration depends on the rollout, not the other way round.** Nothing fails in CI today; +everything un-normalized fails the moment runners move to npm 11. + +Because of that, `use-npmrc` also runs `warn-foreign-registry.sh` against the consumer's own `package-lock.json` and +emits a `::warning` annotation plus a job summary listing the offending package paths. **Those warnings are the +inventory of lockfiles still to normalize.** When no pipeline reports one any more, the `replace-registry-host=never` +line can be deleted. + +The two mechanisms compose safely and in either order: on a normalized lockfile the flag is a no-op, because there are +no foreign URLs left to rewrite. So the mitigation can be removed lazily, per branch, rather than in a coordinated +switchover. + +The check is **advisory and must stay that way** — it runs in every consumer's pipeline, so a missing lockfile, +missing `jq`, or malformed JSON all exit 0 silently. It never becomes a new way for someone else's build to fail. + +--- + +## Flow 1 — normalizing a branch + +```bash +./tools/scripts/lockfile/normalize-lockfile.sh +git add package-lock.json +git commit -m 'PFM-ISSUE-34453 - github-actions: normalize package-lock.json resolved URLs onto the JFrog npm proxy' +./tools/scripts/lockfile/check-lockfile.sh --baseline HEAD~1 +``` + +Commit the lockfile **on its own**, separate from any tooling change. Then the commit's parent *is* the baseline, and +verification is exactly `--baseline HEAD~1` with no ref to remember. + +Expect: `entries rewritten: 171`, `byte delta: 4788`, 342 changed lines, none of them outside a `"resolved"` line. + +## Flow 2 — resolving an upmerge conflict on `package-lock.json` + +```bash +git checkout --ours -- package-lock.json # keep this branch's lockfile +./tools/scripts/lockfile/normalize-lockfile.sh +./tools/scripts/lockfile/check-lockfile.sh --baseline :2: # :2: = ours, :3: = theirs +``` + +Proceed **only** on exit 0. Never `--theirs`, never a hand edit: the point of the check is that correctness does not +depend on anyone reading a 262 KB diff. + +`--baseline` accepts a git ref (`HEAD~1`, `origin/release/25.2`), a merge stage (`:2:`, `:3:`), or a plain file path. +Whatever it resolves to is printed on every run, so a wrong baseline is visible rather than silent. + +## Two modes, and when each applies + +This distinction matters, and getting it wrong blocks every dependency update. + +| mode | asserts | use for | +| --- | --- | --- | +| `--prefix-only` | every entry resolves via the proxy | **the PR guard** — runs on every pull request | +| `--baseline ` | the above **plus** the dependency graph is unchanged | **verifying a normalization commit** | + +Graph invariance deliberately forbids *any* change to the dependency graph. That is exactly what you want when proving +a normalization commit touched nothing but registry prefixes — and exactly what you do **not** want on an everyday pull +request, where adding, updating or removing a dependency is the whole point. `pr-checks.yml` therefore uses +`--prefix-only`, and the baseline form is a manual/verification tool. + +A graph failure is also **not** fixed by running the normalizer, so the message for it deliberately does not suggest +that. If you see one on a pull request that legitimately changes dependencies, you are using the wrong mode. + +--- + +## Flow 3 — interpreting a guard failure + +`.github/workflows/pr-checks.yml` runs `check-lockfile.sh --prefix-only` on every pull request, so **the PR guard +makes assertion 2 only**. Assertion 1 runs when you pass `--baseline ` by hand, to verify a normalization +commit — see "Two modes" above. + +> **A pull request passing CI is therefore not evidence that its lockfile changed only prefixes.** Where that matters +> — a normalization commit, or an upmerge conflict resolution — run the baseline form locally. CI deliberately does +> not assert it, because doing so would fail every legitimate dependency change. + +**1. Graph invariance** — `--baseline` only; **not** run on pull requests. The whole document, with every `resolved` +reduced to its bare tarball path, must equal the baseline's. This catches a changed version, a poisoned `integrity`, a +changed tarball filename, a changed dependency edge, an added or dropped entry. + +``` +FAIL: the dependency graph differs from the baseline. Drifted entries: + node_modules/@ampproject/remapping +``` + +→ Something other than a registry prefix changed. This is the bad-merge case. Do not "fix" it by re-running the +normalizer; work out why that entry moved. + +**2. Prefix exactness.** Every `resolved` must carry exactly the one proxy prefix. + +``` +FAIL: 2 distinct registry prefixes found (expected exactly 1). +These entries do not resolve via the cplace npm proxy: + node_modules/jest +``` + +→ An entry is on npmjs, or on a typo'd proxy path. Run `normalize-lockfile.sh`. + +Neither assertion subsumes the other. Graph invariance deliberately strips the host, so it cannot see an entry left on +npmjs or a typo'd `cplace-nmp`; prefix exactness sees nothing *but* the host. Both are required, and +`check-lockfile.bats` asserts that each drift class fails via the correct one. + +### "no usable tarball URL" + +``` +ERROR: these entries in package-lock.json have no usable tarball URL: + node_modules/foo +``` + +A non-root entry has no `resolved`, or resolves over `link:` / `file:` / `git+ssh:`. There are none today (measured: 0 +on all seven branches), and this is a **deliberate** hard failure rather than a silent skip. Introducing such a +dependency legitimately means loosening `assert_resolvable` in `lib.sh` as a reviewed edit — not working around it. + +**This fires on the `--baseline` path and on the normalizer, not on the PR guard.** `assert_resolvable` is a +precondition for *fingerprinting* — every entry needs a tarball path to compare on — so `--prefix-only` deliberately +does not run it, and passes over non-http values instead. That is what lets an npm workspace through the guard; it +also means CI is not the thing that would catch such an entry. + +--- + +## Files + +| file | role | +| --- | --- | +| `lib.sh` | Shared constants and helpers. Sourced, never executed. | +| `fingerprint.jq` | Reduces a lockfile to its registry-independent comparable form. | +| `normalize-lockfile.sh` | The normalizer. | +| `check-lockfile.sh` | The invariant check. | +| `test-helper.bash` | bats fixture builders. | +| `*.bats` | Behavioural tests, including the six injected-drift cases. | + +Run the tests with `bats tools/scripts/lockfile/` and the linter with `shellcheck tools/scripts/lockfile/*.sh`. Both +also run in CI on every pull request. + +**The proxy URL is a hard-coded constant in `lib.sh`, on purpose.** It *is* the invariant being asserted; if it were +caller-supplied, a typo'd prefix passed to both scripts would validate itself. It is not a secret — it is already +committed in plaintext in hundreds of lockfile entries — and it is **not** `JFROG_URL`, which is the *publish* target +(`…/artifactory/cplace-npm-local`), a different path entirely. + +These files are intended to be **byte-identical across all seven long-lived branches**, so that a future upmerge sees a +conflict-free add/add. Change them on one branch and the change has to reach the others. + +## Related + +- `specs/2026-08-10_normalize-package-lock-resolved-urls/` — research, design and implementation plan +- `specs/2026-08-10_normalize-package-lock-resolved-urls/overview.md` — **start here for the whole picture**: the + rewrite that breaks `npm ci`, the two-part fix, the two assertions, the two modes and the seven-branch rollout, with + diagrams. `overview.html` beside it is the same document with hand-drawn figures +- PFM-ISSUE-34453 — the ticket +- PFM-ISSUE-34454 — `DOT_NPMRC` standardization and the JFrog anonymous-access shutdown diff --git a/tools/scripts/lockfile/check-lockfile.bats b/tools/scripts/lockfile/check-lockfile.bats new file mode 100644 index 00000000..a697f48d --- /dev/null +++ b/tools/scripts/lockfile/check-lockfile.bats @@ -0,0 +1,556 @@ +#!/usr/bin/env bats +# +# Behavioural tests for check-lockfile.sh. +# +# The drift cases t1-t6 are the measured evidence behind the two-assertion +# design (design.md Dimension 2): graph invariance is blind to WHICH host an +# entry moved to, prefix exactness is blind to everything else. Each test below +# asserts not merely that the check fails, but that it fails via the RIGHT +# assertion - otherwise the two could silently collapse into one. +# +# Run with: bats tools/scripts/lockfile/ + +setup() { + load 'test-helper' + CHECK="${BATS_TEST_DIRNAME}/check-lockfile.sh" + NORMALIZE="${BATS_TEST_DIRNAME}/normalize-lockfile.sh" + + # Mirrors reality: the baseline is the un-normalized base branch, the + # candidate is the normalized PR. + BASE="${BATS_TEST_TMPDIR}/base.json" + CAND="${BATS_TEST_TMPDIR}/candidate.json" + write_mixed_lockfile "${BASE}" + write_mixed_lockfile "${CAND}" + "${NORMALIZE}" "${CAND}" >/dev/null +} + +@test "passes on a clean normalization" { + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'PASS: dependency graph identical to baseline'* ]] + [[ "${output}" == *'PASS: exactly 1 registry prefix'* ]] +} + +@test "t1: a changed tarball filename fails GRAPH INVARIANCE" { + mutate "${CAND}" '.packages["node_modules/@scope/alpha"].resolved |= + sub("alpha-1\\.0\\.0"; "alpha-9.9.9")' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'FAIL: the dependency graph differs'* ]] + [[ "${output}" == *'node_modules/@scope/alpha'* ]] + [[ "${output}" != *'distinct registry prefixes'* ]] +} + +@test "t2: a typo'd proxy repo name fails PREFIX EXACTNESS" { + mutate "${CAND}" '.packages["node_modules/beta"].resolved |= + sub("cplace-npm"; "cplace-nmp")' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'must carry exactly the cplace npm proxy prefix'* ]] + [[ "${output}" == *'node_modules/beta'* ]] + [[ "${output}" == *'PASS: dependency graph identical to baseline'* ]] +} + +@test "t3: a changed dependency edge fails GRAPH INVARIANCE" { + mutate "${CAND}" '.packages["node_modules/@scope/alpha"].dependencies.beta = "^9.0.0"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'FAIL: the dependency graph differs'* ]] + [[ "${output}" == *'node_modules/@scope/alpha'* ]] +} + +@test "t4: an entry left on npmjs fails PREFIX EXACTNESS" { + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "https://registry.npmjs.org/beta/-/beta-2.0.0.tgz"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'must carry exactly the cplace npm proxy prefix'* ]] + [[ "${output}" == *'node_modules/beta'* ]] + [[ "${output}" == *'PASS: dependency graph identical to baseline'* ]] +} + +@test "t5: a poisoned integrity fails GRAPH INVARIANCE" { + mutate "${CAND}" '.packages["node_modules/beta"].integrity = "sha512-POISONED=="' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'FAIL: the dependency graph differs'* ]] + [[ "${output}" == *'node_modules/beta'* ]] +} + +@test "t6: a poisoned version fails GRAPH INVARIANCE" { + mutate "${CAND}" '.packages["node_modules/beta"].version = "9.9.9"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'FAIL: the dependency graph differs'* ]] + [[ "${output}" == *'node_modules/beta'* ]] +} + +@test "a dropped entry fails GRAPH INVARIANCE, naming the missing path" { + mutate "${CAND}" 'del(.packages["node_modules/beta"])' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/beta'* ]] +} + +@test "a PREFIX failure names the normalizer, which does fix it" { + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "https://registry.npmjs.org/beta/-/beta-2.0.0.tgz"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'normalize-lockfile.sh'* ]] + [[ "${output}" == *'tools/scripts/lockfile/README.md'* ]] +} + +@test "every failure names the README" { + mutate "${CAND}" '.packages["node_modules/beta"].version = "9.9.9"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'tools/scripts/lockfile/README.md'* ]] +} + +@test "resolves a baseline from a git ref" { + cd "${BATS_TEST_TMPDIR}" + git init -q -b main . + git config user.email 'test@example.com' + git config user.name 'test' + write_mixed_lockfile package-lock.json + git add package-lock.json + git commit -qm 'baseline' + "${NORMALIZE}" package-lock.json >/dev/null + + run "${CHECK}" --baseline HEAD + + [ "${status}" -eq 0 ] + [[ "${output}" == *'baseline: HEAD:package-lock.json'* ]] +} + +@test "accepts two explicit file paths and prints both" { + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *"baseline: file ${BASE}"* ]] + [[ "${output}" == *"candidate: ${CAND}"* ]] +} + +@test "fails readably on a baseline ref that cannot be resolved" { + cd "${BATS_TEST_TMPDIR}" + + run "${CHECK}" --baseline no-such-ref "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'cannot read baseline'* ]] +} + +@test "fails cleanly when the candidate does not exist" { + run "${CHECK}" --baseline "${BASE}" "${BATS_TEST_TMPDIR}/absent.json" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'no such lockfile'* ]] +} + +# --- the ongoing PR guard: --prefix-only ------------------------------------ +# +# Raised in review of PR #163: comparing against the base branch fails every +# pull request that legitimately adds or updates a dependency. Graph invariance +# is for verifying a normalization commit, not for guarding everyday PRs. + +@test "prefix-only accepts a PR that legitimately ADDS a dependency" { + mutate "${CAND}" '.packages["node_modules/gamma"] = { + "version": "3.0.0", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/gamma/-/gamma-3.0.0.tgz", + "integrity": "sha512-CCCC==" + }' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] +} + +@test "prefix-only accepts a PR that UPDATES a dependency's version" { + mutate "${CAND}" '.packages["node_modules/beta"].version = "2.1.0" + | .packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/beta/-/beta-2.1.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] +} + +@test "prefix-only accepts a PR that REMOVES a dependency" { + mutate "${CAND}" 'del(.packages["node_modules/beta"])' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] +} + +@test "prefix-only still rejects a newly added entry that is NOT on the proxy" { + mutate "${CAND}" '.packages["node_modules/gamma"] = { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gamma/-/gamma-3.0.0.tgz", + "integrity": "sha512-CCCC==" + }' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/gamma'* ]] +} + +@test "prefix-only needs no baseline, so it works outside a git repository" { + cd "${BATS_TEST_TMPDIR}" + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] + [[ "${output}" != *'baseline'* ]] +} + +# --- the root package entry -------------------------------------------------- +# +# The root package's key is the empty string. Emitted verbatim it produced a +# blank line that `[[ -n ... ]]` read as "no drift", so changes to the project's +# OWN declared dependencies passed silently. + +@test "a change to the root package's declared dependencies fails GRAPH INVARIANCE" { + mutate "${CAND}" '.packages[""].dependencies["@scope/alpha"] = "^9.0.0"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'FAIL: the dependency graph differs'* ]] + [[ "${output}" == *''* ]] +} + +@test "a graph failure does not advise running the normalizer, which cannot fix it" { + mutate "${CAND}" '.packages["node_modules/beta"].version = "9.9.9"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'NOT fixed by normalizing'* ]] + [[ "${output}" == *'--prefix-only'* ]] +} + +@test "no failure message leaks the JFrog host, which CI masks as ***" { + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "https://registry.npmjs.org/beta/-/beta-2.0.0.tgz"' + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" != *'cplace.jfrog.io'* ]] +} + +# --- review of PR #163, second round ----------------------------------------- +# +# Every test below pins a defect that reproduced. Several of these FAILED OPEN: +# the check reported success on a lockfile it had not actually verified, which +# is worse than any false positive. + +@test "graph invariance FAILS CLOSED when its own jq cannot run" { + # main() calls the assertion inside a `||` list, which disables `set -e` for + # the function body. An unchecked jq failure therefore left `drift` empty and + # fell through to PASS - on a poisoned lockfile. + mutate "${CAND}" '.packages["node_modules/beta"].integrity = "sha512-POISONED=="' + local hidden="${BATS_TEST_TMPDIR}/fingerprint.jq.hidden" + mv "${BATS_TEST_DIRNAME}/fingerprint.jq" "${hidden}" + + run "${CHECK}" --baseline "${BASE}" "${CAND}" + local rc="${status}" out="${output}" + + mv "${hidden}" "${BATS_TEST_DIRNAME}/fingerprint.jq" + + [ "${rc}" -ne 0 ] + [[ "${out}" != *'PASS: dependency graph identical'* ]] + [[ "${out}" == *'cannot fingerprint'* ]] +} + +@test "--prefix-only and --baseline are rejected together, not silently ranked" { + mutate "${CAND}" '.packages["node_modules/beta"].integrity = "sha512-POISONED=="' + + run "${CHECK}" --baseline "${BASE}" --prefix-only "${CAND}" + + [ "${status}" -eq 2 ] + [[ "${output}" == *'mutually exclusive'* ]] +} + +@test "a second positional is rejected rather than silently replacing the first" { + run "${CHECK}" "${BASE}" "${CAND}" + + [ "${status}" -eq 2 ] + [[ "${output}" == *'only one candidate lockfile'* ]] + [[ "${output}" == *'--baseline'* ]] +} + +@test "the baseline is read from the candidate's own path, not a hardcoded one" { + cd "${BATS_TEST_TMPDIR}" + git init -q -b main . + git config user.email 'test@example.com' + git config user.name 'test' + mkdir -p sub + write_mixed_lockfile sub/package-lock.json + git add -A + git commit -qm 'baseline' + "${NORMALIZE}" sub/package-lock.json >/dev/null + + run "${CHECK}" --baseline HEAD sub/package-lock.json + + [ "${status}" -eq 0 ] + [[ "${output}" == *'baseline: HEAD:sub/package-lock.json'* ]] +} + +@test "--prefix-only tolerates workspace and link: entries" { + # These are not registry references at all. Rejecting them blocked the first + # PR introducing an npm workspace, and contradicted warn-foreign-registry.sh, + # which passes over the same class. + mutate "${CAND}" '.packages["tools/eslint-rules"] = {"version":"1.0.0"} + | .packages["node_modules/eslint-rules"] = {"resolved":"tools/eslint-rules","link":true}' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] +} + +@test "an unsupported lockfileVersion fails readably instead of a jq trace" { + printf '{"name":"x","lockfileVersion":1}\n' >"${CAND}" + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'lockfileVersion 1'* ]] + [[ "${output}" != *'jq: error'* ]] + # Must not pass vacuously by treating a missing .packages as "nothing wrong". + [[ "${output}" != *'resolves entirely via'* ]] +} + +@test "an uppercase URL scheme does not slip past the PR guard" { + # npm reads the scheme case-insensitively, so a case-sensitive predicate made + # such an entry invisible to --prefix-only - the sole automated guard on every + # pull request - and reported OK on a lockfile pointing at an arbitrary host. + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "HTTPS://attacker.example.com/evil/-/evil-1.0.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/beta'* ]] + [[ "${output}" != *'resolves entirely via'* ]] +} + +@test "the normalizer rewrites an uppercase-scheme entry onto the proxy" { + # The guard's remediation advice is "run the normalizer", so the normalizer + # has to recognize the same entries the guard rejects. + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "HTTPS://attacker.example.com/beta/-/beta-2.0.0.tgz"' + + run "${NORMALIZE}" "${CAND}" + + [ "${status}" -eq 0 ] + [ "$(jq -r '.packages["node_modules/beta"].resolved' "${CAND}")" = "${PROXY}beta/-/beta-2.0.0.tgz" ] +} + +@test "the prefix failure message does not contradict itself" { + # `distinct` counts prefixes present, not wrong ones, so a lockfile uniformly + # on npmjs used to fail with "1 distinct registry prefixes found (expected + # exactly 1)" - the rollout case, reading as though the check were broken. + mutate "${CAND}" '.packages["node_modules/@scope/alpha"].resolved = + "https://registry.npmjs.org/@scope/alpha/-/alpha-1.0.0.tgz" + | .packages["node_modules/beta"].resolved = + "https://registry.npmjs.org/beta/-/beta-2.0.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'must carry exactly the cplace npm proxy prefix'* ]] + [[ "${output}" != *'distinct registry prefixes found (expected exactly 1)'* ]] +} + +@test "an entry whose tarball path repeats the scope passes the guard" { + # Measured on cplace-paw-fe release/25.2, where npm installs it without + # complaint: JFrog serves some privately published scoped packages with the + # scope repeated after `/-/`. Requiring `[^/]+` there reported an entry that + # was already on the proxy as foreign. + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@cplace-next/beta/-/@cplace-next/beta-2.0.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'PASS: exactly 1 registry prefix'* ]] +} + +@test "an entry with a version segment in its tarball path passes the guard" { + # The other real shape from the same lockfile: `/-//.tgz`. + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@fortawesome/beta/-/2.0.0/beta-2.0.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'PASS: exactly 1 registry prefix'* ]] +} + +@test "the same entry on a foreign host is still rejected" { + # The widening must not turn into "anything ending in .tgz is fine". + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "https://registry.npmjs.org/@cplace-next/beta/-/@cplace-next/beta-2.0.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/beta'* ]] +} + +@test "a prefix containing its own /-/ keeps the debris in the compared path" { + # `.+` may cross a `/-/`, so the match anchors on the first one. No registry + # in use has `/-/` in its prefix; this pins which way the ambiguity resolves, + # and the direction is fail-loud: the retained path carries prefix debris, so + # the entry cannot silently compare equal to a proxy-hosted one. + source "${BATS_TEST_DIRNAME}/lib.sh" + + run jq -rn --arg re "${TARBALL_PATH_RE}" \ + --arg u 'https://host/a/-/b/beta/-/beta-2.0.0.tgz' '$u | capture($re) | .t' + + [ "${status}" -eq 0 ] + [ "${output}" = 'a/-/b/beta/-/beta-2.0.0.tgz' ] +} + +@test "every URL assert_resolvable accepts can be captured by the tarball regex" { + # The lockstep invariant between RESOLVED_URL_RE and TARBALL_PATH_RE. If a URL + # passes validation but the capture misses it, jq's capture yields empty and + # `|= empty` DELETES the resolved key instead of raising - a silent loss, not + # a loud failure. Widening one regex without the other reintroduces exactly + # that, so assert it directly rather than trusting the two to stay aligned. + source "${BATS_TEST_DIRNAME}/lib.sh" + + local urls=( + "${PROXY}beta/-/beta-2.0.0.tgz" + "${PROXY}@scope/beta/-/beta-2.0.0.tgz" + "${PROXY}@cplace-next/beta/-/@cplace-next/beta-2.0.0.tgz" + "${PROXY}@fortawesome/beta/-/2.0.0/beta-2.0.0.tgz" + "HTTPS://attacker.example.com/beta/-/beta-2.0.0.tgz" + ) + + local url + for url in "${urls[@]}"; do + echo "validating: ${url}" + jq -en --arg u "${url}" --arg url_re "${RESOLVED_URL_RE}" '$u | test($url_re)' >/dev/null + jq -en --arg u "${url}" --arg re "${TARBALL_PATH_RE}" '$u | test($re)' >/dev/null + done +} + +@test "resolves a baseline from a :2: merge stage" { + # The Flow 2 conflict runbook: `git checkout --ours`, re-normalize, verify + # against `:2:`. That is the arm of resolve_baseline that appends the + # candidate's path to a spec ending in a colon, and it runs when someone is + # mid-upmerge and least able to debug the guard. + cd "${BATS_TEST_TMPDIR}" + git init -q -b main . + git config user.email 'test@example.com' + git config user.name 'test' + write_mixed_lockfile package-lock.json + git add package-lock.json + git commit -qm 'base' + + git checkout -q -b theirs + mutate package-lock.json '.packages["node_modules/@scope/alpha"].resolved = + "https://registry.npmjs.org/@scope/alpha/-/alpha-1.0.1.tgz" + | .packages["node_modules/@scope/alpha"].version = "1.0.1"' + git commit -qam 'theirs' + + git checkout -q main + "${NORMALIZE}" package-lock.json >/dev/null + git commit -qam 'ours' + + run git merge theirs + [ "${status}" -ne 0 ] + + git checkout -q --ours -- package-lock.json + "${NORMALIZE}" package-lock.json >/dev/null + + run "${CHECK}" --baseline :2: + + [ "${status}" -eq 0 ] + [[ "${output}" == *'baseline: :2:package-lock.json'* ]] + [[ "${output}" == *'PASS: dependency graph identical to baseline'* ]] +} + +@test "a lockfile with no lockfileVersion at all fails readably" { + # The `missing` arm of assert_supported_lockfile, distinct from its + # unsupported-version sibling: this message asks whether the file is a + # package-lock.json in the first place. + printf '{"name":"x","packages":{}}\n' >"${CAND}" + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'is it a package-lock.json?'* ]] +} + +@test "a lockfileVersion 1 baseline fails readably instead of a jq trace" { + # The baseline used to reach fingerprint.jq unchecked, where `.packages` is + # absent in a v1 file: `null (null) has no keys`, then "cannot fingerprint the + # baseline (is fingerprint.jq present?)" - a jq trace and a wrong diagnosis. + printf '{"name":"x","lockfileVersion":1,"dependencies":{}}\n' >"${BATS_TEST_TMPDIR}/v1.json" + + run "${CHECK}" --baseline "${BATS_TEST_TMPDIR}/v1.json" "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'baseline'* ]] + [[ "${output}" == *'lockfileVersion 1'* ]] + [[ "${output}" != *'has no keys'* ]] + [[ "${output}" != *'fingerprint.jq present'* ]] +} + +@test "a lockfile with no registry entries does not claim proxy compliance" { + # Zero entries examined used to print "exactly 0 registry prefix, matching the + # expected proxy" and "resolves entirely via the cplace npm proxy" - a fact + # asserted from an empty set. + printf '%s\n' '{"name":"x","lockfileVersion":3,"packages":{"":{"name":"x"},"node_modules/a":{"resolved":"link:../a","link":true}}}' >"${CAND}" + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'no registry entries to check'* ]] + [[ "${output}" != *'resolves entirely via'* ]] +} + +@test "the pass line reports how many entries were examined" { + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'(2 entries examined)'* ]] +} + +@test "an http entry on the proxy host is named as a scheme downgrade" { + # It fails the exact-prefix comparison either way; without the extra line the + # message sends the reader looking for a path mistake that is not there. + mutate "${CAND}" '.packages["node_modules/beta"].resolved = + "http://cplace.jfrog.io/artifactory/api/npm/cplace-npm/beta/-/beta-2.0.0.tgz"' + + run "${CHECK}" --prefix-only "${CAND}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'ONLY in scheme'* ]] + [[ "${output}" == *'plain http'* ]] +} diff --git a/tools/scripts/lockfile/check-lockfile.sh b/tools/scripts/lockfile/check-lockfile.sh new file mode 100755 index 00000000..3ce80c70 --- /dev/null +++ b/tools/scripts/lockfile/check-lockfile.sh @@ -0,0 +1,316 @@ +#!/usr/bin/env bash +# +# Proves that a package-lock.json differs from its baseline ONLY in registry +# prefixes, and that every `resolved` URL points at the one correct proxy. +# +# Usage: +# ./tools/scripts/lockfile/check-lockfile.sh [--baseline ] [] +# ./tools/scripts/lockfile/check-lockfile.sh --prefix-only [] +# +# --baseline HEAD~1 the commit before the lockfile commit (default: HEAD) +# --baseline :2: "ours" during a merge conflict +# --baseline :3: "theirs" during a merge conflict +# --baseline path/to/other.json an explicit file +# --prefix-only assertion 2 only; THE PR GUARD +# +# The two modes are mutually exclusive, and the difference matters: +# +# 1. graph invariance - the whole document, with every `resolved` reduced to a +# registry-independent tarball path, must equal the baseline. Forbids ANY +# dependency change, so it verifies a normalization commit and must never +# gate an everyday pull request. +# 2. prefix exactness - every `resolved` that is an http(s) URL must carry +# exactly the one proxy prefix. This is what CI asserts. +# +# Neither alone is sufficient for a normalization commit: (1) is blind to WHICH +# host an entry moved to, and (2) is blind to everything except the host. +# See design.md Dimension 2. +# +# See tools/scripts/lockfile/README.md + +set -euo pipefail + +# shellcheck source=tools/scripts/lockfile/lib.sh +source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" + +usage() { + err "usage: ${0##*/} [--baseline ] [--prefix-only] []" + exit 2 +} + +# Writes the baseline lockfile to ${2}, resolving ${1} as a file path if one +# exists, otherwise as a git ref. Always prints what it resolved, so a wrong +# baseline is visible rather than silent. +resolve_baseline() { + local ref="$1" out="$2" + # The candidate's own path, so a nested lockfile compares against the same + # path in the baseline ref. Hardcoding `package-lock.json` made + # `--baseline HEAD sub/package-lock.json` either fail outright or, in a repo + # with both a root and a nested lockfile, silently compare two different files + # and report every entry as drifted. + local lockfile_path="${3:-package-lock.json}" + + if [[ -f "${ref}" ]]; then + cat "${ref}" >"${out}" + info "baseline: file ${ref}" + return + fi + + local spec="${ref}" + if [[ "${spec}" == *: ]]; then + spec="${spec}${lockfile_path}" # `:2:` -> `:2:` + elif [[ "${spec}" != *:* ]]; then + spec="${spec}:${lockfile_path}" # `HEAD~1` -> `HEAD~1:` + fi + + if ! git show "${spec}" >"${out}" 2>/dev/null; then + die "cannot read baseline '${ref}' (tried '${spec}'); pass a git ref or an existing file" + fi + info "baseline: ${spec}" +} + +# Assertion 1. Prints every drifted package path; returns 1 if any. +assert_graph_invariant() { + local baseline="$1" candidate="$2" fp_base="$3" fp_cand="$4" + local drift + + # Every step below is checked. main() calls this function inside a `||` list, + # which disables `set -e` for its whole body, so an unchecked failure here does + # not abort - it leaves `drift` empty and falls through to "PASS: dependency + # graph identical to baseline". This is the strongest assertion in the toolkit + # and the only one that ever looks at integrity hashes; it must fail CLOSED. + fingerprint_of "${baseline}" >"${fp_base}" \ + || die "internal error: cannot fingerprint the baseline (is ${FINGERPRINT_JQ} present?)" + fingerprint_of "${candidate}" >"${fp_cand}" \ + || die "internal error: cannot fingerprint ${candidate} (is ${FINGERPRINT_JQ} present?)" + + drift="$(jq -n -r --slurpfile a "${fp_base}" --slurpfile b "${fp_cand}" ' + ($a[0]) as $A | ($b[0]) as $B + | [ ((($A | keys) + ($B | keys)) | unique)[] + | select(. != "packages") + | select(($A[.] | tojson) != ($B[.] | tojson)) + | "top-level key: " + . ] + + [ (((($A.packages // {}) | keys) + (($B.packages // {}) | keys)) | unique)[] + | select((($A.packages[.]) | tojson) != (($B.packages[.]) | tojson)) + # The root package uses the empty string as its key. Emitted verbatim + # that is a blank line, which the caller test reads as "no drift", + # silently hiding any change to the declared dependencies of this + # project. Name it so it is both detectable and readable. + | if . == "" then "" else . end ] + | .[] + ')" || die "internal error: graph comparison failed" + + if [[ -n "${drift}" ]]; then + err "FAIL: the dependency graph differs from the baseline. Drifted entries:" + while IFS= read -r package_path; do + err " ${package_path}" + done <<<"${drift}" + return 1 + fi + + info "PASS: dependency graph identical to baseline" +} + +# Assertion 2. Prints every package path not on the one correct proxy. +assert_prefix_exactness() { + local candidate="$1" + local offenders distinct examined scheme_only + + # Single-quoted jq programs with the shared predicate spliced between them. + # Written as one double-quoted string, every jq `$var` in the literal text had + # to be backslash-escaped, which is the fragile spelling in a file where every + # other jq call is a plain single-quoted program. + # + # Considers only entries whose `resolved` is an http(s) URL. A `link:`/`file:`/ + # workspace entry is not a registry reference at all, so rejecting it here + # would block the first pull request introducing an npm workspace - and would + # contradict warn-foreign-registry.sh, which passes over the same class. + examined="$(jq -r '[ '"${JQ_REGISTRY_ENTRIES}"' ] | length' "${candidate}")" \ + || die "cannot read ${candidate} as a lockfile (is it valid JSON?)" + + # An empty set proves nothing, and saying "resolves entirely via the proxy" + # about it is the vacuous pass assert_supported_lockfile exists to prevent: + # every entry examined, zero examined, same message. + # + # Returns 2, not 1: the caller must not answer this with "run the normalizer", + # which would rewrite the same zero entries and change nothing. + if ((examined == 0)); then + err "FAIL: ${candidate} has no registry entries to check." + err " Refusing to report proxy compliance from an empty set - nothing was examined." + err "A lockfile that is genuinely all workspace/link: entries needs a deliberate," + err "reviewed loosening here rather than a silent pass." + return 2 + fi + + # shellcheck disable=SC2016 # $proxy/$tarball_re are jq variables, bound via --arg + offenders="$(jq -r --arg proxy "${JFROG_NPM_PROXY}" --arg tarball_re "${TARBALL_PATH_RE}" \ + '[ '"${JQ_REGISTRY_ENTRIES}"' | select((.value.resolved | sub($tarball_re; "")) != $proxy) | .key ] | .[]' \ + "${candidate}")" || die "cannot read ${candidate} as a lockfile (is it valid JSON?)" + + # shellcheck disable=SC2016 # $tarball_re is a jq variable, bound via --arg + distinct="$(jq -r --arg tarball_re "${TARBALL_PATH_RE}" \ + '[ '"${JQ_REGISTRY_ENTRIES}"' | (.value.resolved | sub($tarball_re; "")) ] | unique | length' \ + "${candidate}")" || die "cannot read ${candidate} as a lockfile (is it valid JSON?)" + + if [[ -n "${offenders}" ]]; then + # Name the expectation, not the cardinality. `distinct` counts how many + # prefixes exist, not how many are wrong, so a lockfile uniformly on npmjs + # used to fail with "1 distinct registry prefixes found (expected exactly 1)" + # - which reads as though the check itself is broken. That is the state of + # every branch before this tooling lands, i.e. the rollout case. + err "FAIL: every 'resolved' must carry exactly the cplace npm proxy prefix" + err " (${distinct} distinct prefix(es) present in ${candidate})." + err "These entries do not resolve via the cplace npm proxy:" + while IFS= read -r package_path; do + err " ${package_path}" + done <<<"${offenders}" + + # An entry on the right host over plain http fails the exact-prefix + # comparison like any other, but "does not resolve via the cplace npm proxy" + # sends the reader looking for a path problem that is not there. + # shellcheck disable=SC2016 # $proxy/$tarball_re are jq variables, bound via --arg + scheme_only="$(jq -r --arg proxy "${JFROG_NPM_PROXY}" --arg tarball_re "${TARBALL_PATH_RE}" \ + '[ '"${JQ_REGISTRY_ENTRIES}"' | (.value.resolved | sub($tarball_re; "")) + | select(. != $proxy) | select(sub("^http://"; "https://") == $proxy) ] | length' \ + "${candidate}")" || scheme_only=0 + if ((scheme_only > 0)); then + err "" + err "${scheme_only} of these differ from the proxy ONLY in scheme: they use plain http." + err "The proxy prefix is https; an http URL is a downgrade, not a path mistake." + fi + return 1 + fi + + info "PASS: exactly ${distinct} registry prefix, matching the expected proxy (${examined} entries examined)" +} + +main() { + local baseline='HEAD' candidate='package-lock.json' prefix_only=0 + local baseline_given=0 candidate_given=0 + + while (($# > 0)); do + case "$1" in + --baseline) + [[ $# -ge 2 ]] || usage + baseline="$2" + baseline_given=1 + shift 2 + ;; + --prefix-only) + prefix_only=1 + shift + ;; + -h | --help) usage ;; + -*) usage ;; + *) + # A second positional used to silently replace the first, so the natural + # two-file form `check base.json cand.json` dropped the baseline, fell + # back to HEAD, and printed a drift report naming every package in the + # repo - reading as catastrophic corruption of a file that is fine. + if ((candidate_given)); then + err "ERROR: only one candidate lockfile may be given (got '${candidate}' and '$1')." + err "To compare two files, pass the baseline explicitly: --baseline '${candidate}' '$1'" + usage + fi + candidate="$1" + candidate_given=1 + shift + ;; + esac + done + + # --baseline asks for a graph comparison; --prefix-only says not to make one. + # Silently honouring the second reported OK on a poisoned integrity hash, and + # `--baseline HEAD~1 --prefix-only` is the natural thing to type once the + # README calls --prefix-only "the PR guard". + if ((prefix_only)) && ((baseline_given)); then + err "ERROR: --prefix-only and --baseline are mutually exclusive." + err " --prefix-only asserts only that every entry resolves via the proxy (the PR guard)" + err " --baseline additionally asserts the dependency graph is unchanged" + usage + fi + + require_jq + [[ -f "${candidate}" ]] || die "no such lockfile: ${candidate}" + assert_supported_lockfile "${candidate}" + + # --prefix-only is the ONGOING guard: it answers "does every entry resolve via + # the proxy?" and nothing else, so a pull request may freely add, remove or + # update dependencies. Graph invariance deliberately forbids exactly that, which + # makes it the wrong gate for everyday pull requests - it belongs to verifying a + # normalization commit, where the graph genuinely must not move. + if ((prefix_only)); then + info "candidate: ${candidate} (prefix-exactness only; dependency changes allowed)" + local prefix_rc=0 + assert_prefix_exactness "${candidate}" || prefix_rc=$? + if ((prefix_rc != 0)); then + err "" + # Status 2 is the "nothing to examine" refusal, which the normalizer cannot + # fix - it would rewrite the same zero entries. Only offer the command when + # rewriting is actually the remedy. + if ((prefix_rc == 1)); then + err "To fix: run ${NORMALIZE_CMD}" + fi + err "See ${README_PATH}" + exit 1 + fi + info "OK: ${candidate} resolves entirely via the cplace npm proxy" + return 0 + fi + + command -v git >/dev/null 2>&1 || die "git is required but not installed" + + local baseline_file fp_base fp_cand + baseline_file="$(mktemp)" + fp_base="$(mktemp)" || die "internal error: mktemp failed" + fp_cand="$(mktemp)" || die "internal error: mktemp failed" + # The fingerprint scratch files belong to assert_graph_invariant but are made + # and trapped here: every `|| die` in that function exits, so a cleanup at its + # end is bypassed on exactly the fail-closed paths it exists to take. + # shellcheck disable=SC2064 # expand paths now, not when the trap fires + trap "rm -f '${baseline_file}' '${fp_base}' '${fp_cand}'" EXIT + + resolve_baseline "${baseline}" "${baseline_file}" "${candidate}" + # The baseline is a lockfile too, and fingerprint.jq reduces `.packages` - + # absent in lockfileVersion 1. Unchecked, a baseline ref predating the v2/v3 + # upgrade produced a raw `null (null) has no keys` jq trace followed by + # "cannot fingerprint the baseline (is fingerprint.jq present?)", which is the + # wrong diagnosis as well as the unreadable failure this toolkit replaces. + assert_supported_lockfile "${baseline_file}" "baseline ${baseline}" + info "candidate: ${candidate}" + + # assert_resolvable is a precondition for FINGERPRINTING - every entry must + # have a tarball path to compare on - not for prefix exactness. It therefore + # belongs here, on the baseline path, and not in front of --prefix-only, where + # it hard-failed on exactly the workspace and link: entries that mode promises + # to allow. + assert_resolvable "${baseline_file}" + assert_resolvable "${candidate}" + + # Run BOTH assertions before failing, so one run reports every problem. + local failed=0 graph_failed=0 + assert_graph_invariant "${baseline_file}" "${candidate}" "${fp_base}" "${fp_cand}" \ + || { failed=1; graph_failed=1; } + assert_prefix_exactness "${candidate}" || failed=1 + + if ((failed != 0)); then + err "" + if ((graph_failed)); then + # Do not tell people to run the normalizer here: it rewrites prefixes and + # would not touch a graph difference, so the advice would be misleading. + err "A graph difference is NOT fixed by normalizing. Either the baseline is" + err "wrong for what you are checking, or something other than a registry" + err "prefix really did change - work out which before proceeding." + err "For a pull request that legitimately changes dependencies, use --prefix-only." + else + err "To fix: run ${NORMALIZE_CMD}" + err "then re-run: ${0} --baseline ${baseline}" + fi + err "See ${README_PATH}" + exit 1 + fi + + info "OK: ${candidate} is normalized and graph-identical to its baseline" +} + +main "$@" diff --git a/tools/scripts/lockfile/fingerprint.jq b/tools/scripts/lockfile/fingerprint.jq new file mode 100644 index 00000000..c0c1911b --- /dev/null +++ b/tools/scripts/lockfile/fingerprint.jq @@ -0,0 +1,36 @@ +# Reduces a package-lock.json to a registry-independent, comparable form: every +# `resolved` URL is replaced by its bare tarball path. A legitimately rehosted +# entry therefore compares EQUAL, while a changed version, integrity, tarball +# filename or dependency edge does not. +# +# Requires: --arg tarball_re '' (see lib.sh) +# +# Requires also that the caller has already run `assert_resolvable`. A +# non-matching `capture` yields `empty`, and `|= empty` deletes the key, so an +# unvalidated entry would lose its `resolved` here rather than raising - on both +# sides of the comparison at once, which is precisely what this transform exists +# to detect. +# +# This transform is deliberately BLIND to which host an entry was rehosted onto +# - a typo'd proxy repo name and an entry left on npmjs both survive it. That +# blindness is exactly why check-lockfile.sh runs a second, independent prefix +# assertion; the two together are what design.md Dimension 2 requires. +# +# The whole entry is compared, not a version/integrity/tarball subset, because +# the subset misses dependency-edge drift (drift case t3). + +# The three guards are the shared predicate's own terms (lib.sh's +# JQ_REGISTRY_ENTRIES): the root entry is keyed by the empty string and +# `assert_resolvable` deliberately skips it, and a `link:`/workspace value is not +# a registry reference. Reducing either of those would compare it to nothing. +.packages |= with_entries( + if .key != "" + and (.value | type) == "object" + and (.value.resolved | type) == "string" + and (.value.resolved | test("^https?://"; "i")) + then + .value.resolved |= (capture($tarball_re) | .t) + else + . + end +) diff --git a/tools/scripts/lockfile/lib.sh b/tools/scripts/lockfile/lib.sh new file mode 100644 index 00000000..b96c1bc0 --- /dev/null +++ b/tools/scripts/lockfile/lib.sh @@ -0,0 +1,194 @@ +#!/usr/bin/env bash +# +# Shared constants and helpers for the package-lock.json normalizer and checker. +# +# This file is sourced, never executed. It deliberately depends on nothing but +# bash and jq: the scripts that source it exist to repair the lockfile that +# makes `npm ci` fail, so they cannot require `npm ci` to have succeeded. +# +# See tools/scripts/lockfile/README.md + +# The one npm proxy every `resolved` URL in this repository's package-lock.json +# must point at. +# +# Hard-coded on purpose. This constant *is* the invariant that check-lockfile.sh +# asserts; if it were caller-supplied, a typo'd prefix handed to both scripts +# would validate itself. It is not a secret - it is already committed in +# plaintext in every JFrog-hosted lockfile entry - and it is NOT the JFROG_URL +# publish target (`.../artifactory/cplace-npm-local`, see +# tools/scripts/artifacts/configuration.ts:2), which points somewhere else. +readonly JFROG_NPM_PROXY='https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/' + +# Extracts the registry-independent tarball path from a `resolved` URL: +# https:////@scope/name/-/name-1.2.3.tgz -> @scope/name/-/name-1.2.3.tgz +# https:////name/-/name-1.2.3.tgz -> name/-/name-1.2.3.tgz +# +# The segment after `/-/` may contain slashes, because JFrog serves two real +# shapes this repository's own lockfiles happen not to contain: +# .../@cplace-next/cf-frontend-sdk/-/@cplace-next/cf-frontend-sdk-25.2.30.tgz +# .../@fortawesome/fontawesome-pro/-/5.15.4/fontawesome-pro-5.15.4.tgz +# Requiring `[^/]+` there rejected both: the advisory reported four entries that +# were already on the proxy, and the normalizer refused to touch the lockfile +# carrying them - measured on cplace-paw-fe release/25.2, where npm installs all +# four without complaint. +# +# Consequence, pinned by a test: `.+` may cross a `/-/`, so a prefix that itself +# contained one would anchor the match on the FIRST rather than the last. The +# retained path then keeps prefix debris, so such an entry fails graph +# invariance loudly instead of comparing equal by accident. No registry in use +# has `/-/` in its prefix. +# +# The `\.tgz` suffix is required rather than accepting any filename, so the +# regex matches what the documentation and error messages promise. Anything else +# is an unexpected shape that should fail loudly rather than be silently +# rehosted. +# +# Defined once, here, and passed to jq via --arg, so that the normalizer and +# fingerprint.jq can never drift apart. +readonly TARBALL_PATH_RE='(?(?:@[^/]+/)?[^/]+/-/.+\.tgz)$' + +# Shape every non-root entry's `resolved` must have. Checked BEFORE any +# `capture`, because a non-matching `capture` does not raise: it produces +# `empty`, and `.value.resolved |= empty` DELETES the key. Unvalidated, an +# unexpected shape would therefore lose its `resolved` silently - and +# fingerprint.jq makes the identical deletion on both sides of a comparison, so +# neither the self-assertion nor graph invariance can see it happen. +# +# The scheme is matched case-insensitively because npm treats it that way: a +# `HTTPS://` entry is a registry reference and must be normalized like any +# other. The `\.tgz` suffix stays case-sensitive - an unexpected shape should +# fail loudly rather than be silently rehosted. +# +# The tail must be widened in LOCKSTEP with TARBALL_PATH_RE. Everything this +# accepts has to be capturable by that one, or an entry passes validation and is +# then handed to `capture`, which yields empty on a non-match - and `|= empty` +# DELETES the key rather than raising. A test asserts the two agree. +readonly RESOLVED_URL_RE='^(?i:https?)://[^/]+/.*(?:@[^/]+/)?[^/]+/-/.+\.tgz$' + +# The single definition of "which entries this tooling has an opinion about", +# and of "what a normalized entry looks like". Three hand-written copies of this +# predicate had drifted apart: `count_foreign_entries` asked `startswith($proxy)` +# while the rewrite asked "does $proxy + differ from the +# current value?", so an entry already under the proxy host but with a stray path +# segment was counted as normalized and then silently rewritten anyway. +# +# Requires --arg proxy and --arg tarball_re. Selects only entries whose `resolved` +# is an http(s) URL: `link:`/`file:`/workspace values are not registry references +# and must be passed over rather than rejected. The scheme test carries "i" +# because npm reads it case-insensitively - without the flag a `HTTPS://` entry +# was not a registry entry at all, so --prefix-only reported OK on a lockfile +# pointing at an arbitrary host. +# shellcheck disable=SC2016 # $proxy/$tarball_re are jq variables, bound via --arg +readonly JQ_REGISTRY_ENTRIES=' + (.packages // {}) + | to_entries[] + | select(.key != "") + | select((.value.resolved | type) == "string") + | select(.value.resolved | test("^https?://"; "i")) +' + +# Given such an entry, true when the rewrite would change it. +# shellcheck disable=SC2016 # $proxy/$tarball_re are jq variables, bound via --arg +readonly JQ_NEEDS_REWRITE=' + select((.value.resolved | test($tarball_re)) + and (.value.resolved != ($proxy + (.value.resolved | capture($tarball_re) | .t)))) +' + +readonly README_PATH='tools/scripts/lockfile/README.md' +# shellcheck disable=SC2034 # consumed by check-lockfile.sh, which shellcheck cannot see from here +readonly NORMALIZE_CMD='./tools/scripts/lockfile/normalize-lockfile.sh' + +LOCKFILE_TOOLS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +readonly LOCKFILE_TOOLS_DIR +readonly FINGERPRINT_JQ="${LOCKFILE_TOOLS_DIR}/fingerprint.jq" + +info() { + printf '%s\n' "$*" +} + +err() { + printf '%s\n' "$*" >&2 +} + +die() { + err "ERROR: $*" + exit 1 +} + +require_jq() { + if ! command -v jq >/dev/null 2>&1; then + die "jq is required but not installed (macOS: brew install jq). See ${README_PATH}" + fi +} + +byte_size() { + wc -c <"$1" | tr -d '[:space:]' +} + +# These scripts operate on `.packages`, which exists only from lockfileVersion 2. +# Guarding `.packages` alone would make a v1 file pass vacuously - reporting +# "resolves entirely via the proxy" having examined nothing at all, which is a +# worse outcome than the raw jq trace it replaced. Fail loudly instead. +# +# The optional second argument names the file in the message. The baseline is +# checked through a `mktemp` copy, and "/var/folders/.../tmp.4Xh2 has no +# lockfileVersion" tells the reader nothing about which ref they passed. +assert_supported_lockfile() { + local lockfile="$1" label="${2:-$1}" version + version="$(jq -r '.lockfileVersion // "missing"' "${lockfile}" 2>/dev/null)" \ + || die "cannot read ${label} as JSON" + + case "${version}" in + 2 | 3) return 0 ;; + missing) die "${label} has no lockfileVersion - is it a package-lock.json? See ${README_PATH}" ;; + *) die "${label} is lockfileVersion ${version}; these scripts need 2 or 3 (they operate on '.packages'). See ${README_PATH}" ;; + esac +} + +# Fails, naming every offending package path, if any non-root entry lacks a +# usable tarball URL. Never echoes a URL: CI masks the JFrog host as ***, so a +# message built from one is unreadable exactly when it matters most. +assert_resolvable() { + local lockfile="$1" + local offenders + # `(.packages // {})`, not `.packages`: a lockfileVersion 1 or hand-truncated + # file has no such section, and dereferencing it raises a raw jq trace with + # exit 5 - the unreadable failure these scripts exist to eliminate. + offenders="$(jq -r --arg url_re "${RESOLVED_URL_RE}" ' + (.packages // {}) + | to_entries[] + | select(.key != "") + | select(((.value.resolved | type) != "string") + or ((.value.resolved | test($url_re)) | not)) + | .key + ' "${lockfile}")" || die "cannot read ${lockfile} as a lockfile (is it valid JSON?)" + + if [[ -n "${offenders}" ]]; then + err "ERROR: these entries in ${lockfile} have no usable tarball URL:" + while IFS= read -r package_path; do + err " ${package_path}" + done <<<"${offenders}" + err "" + err 'Every non-root entry must carry a standard /-/.tgz "resolved" URL.' + err "A link:/file:/git+ssh: dependency is a deliberate, reviewed loosening of this" + err "assertion - see ${README_PATH}." + exit 1 + fi +} + +# Reduces a lockfile to its registry-independent comparable form. Sorted keys so +# the output is diffable and order-insensitive. +fingerprint_of() { + jq -S --arg tarball_re "${TARBALL_PATH_RE}" -f "${FINGERPRINT_JQ}" "$1" +} + +# Number of entries the rewrite would actually change - i.e. how much work there +# is to do. Uses the rewrite's own predicate, so the reported count cannot +# disagree with what the normalizer does to the file. README Flow 1 makes this +# number the documented verification signal for a normalization commit, so it +# must not be able to say "untouched" about a file that was modified. +count_foreign_entries() { + jq --arg proxy "${JFROG_NPM_PROXY}" --arg tarball_re "${TARBALL_PATH_RE}" \ + "[ ${JQ_REGISTRY_ENTRIES} | ${JQ_NEEDS_REWRITE} ] | length" "$1" \ + || die "cannot read $1 as a lockfile (is it valid JSON?)" +} diff --git a/tools/scripts/lockfile/normalize-lockfile.bats b/tools/scripts/lockfile/normalize-lockfile.bats new file mode 100644 index 00000000..b7a986ba --- /dev/null +++ b/tools/scripts/lockfile/normalize-lockfile.bats @@ -0,0 +1,247 @@ +#!/usr/bin/env bats +# +# Behavioural tests for normalize-lockfile.sh. +# +# Run with: bats tools/scripts/lockfile/ + +setup() { + load 'test-helper' + NORMALIZE="${BATS_TEST_DIRNAME}/normalize-lockfile.sh" + TMP="${BATS_TEST_TMPDIR}/package-lock.json" +} + +@test "rewrites npmjs entries onto the proxy and leaves proxy entries alone" { + write_mixed_lockfile "${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [ "$(grep -c 'registry.npmjs.org' "${TMP}" || true)" -eq 0 ] + [ "$(jq -r '.packages["node_modules/@scope/alpha"].resolved' "${TMP}")" \ + = "${PROXY}@scope/alpha/-/alpha-1.0.0.tgz" ] + [ "$(jq -r '.packages["node_modules/beta"].resolved' "${TMP}")" \ + = "${PROXY}beta/-/beta-2.0.0.tgz" ] + [ "$(jq -r '.packages["node_modules/@scope/alpha"].integrity' "${TMP}")" = 'sha512-AAAA==' ] +} + +@test "reports how many entries it rewrote" { + write_mixed_lockfile "${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'entries rewritten: 1'* ]] +} + +@test "is idempotent - a second run rewrites nothing and changes no bytes" { + write_mixed_lockfile "${TMP}" + "${NORMALIZE}" "${TMP}" >/dev/null + local before + before="$(wc -c <"${TMP}")" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'entries rewritten: 0'* ]] + [[ "${output}" == *'already normalized'* ]] + [ "$(wc -c <"${TMP}")" -eq "${before}" ] +} + +@test "leaves version, integrity and dependency edges untouched" { + write_mixed_lockfile "${TMP}" + local before + before="$(jq -S 'del(.packages[].resolved)' "${TMP}")" + + "${NORMALIZE}" "${TMP}" >/dev/null + + [ "$(jq -S 'del(.packages[].resolved)' "${TMP}")" = "${before}" ] +} + +@test "preserves the trailing newline" { + write_mixed_lockfile "${TMP}" + + "${NORMALIZE}" "${TMP}" >/dev/null + + # od, not xxd: the workflow installs only bats and shellcheck, so anything + # outside coreutils is an undeclared dependency on the runner image. + [ "$(tail -c 1 "${TMP}" | od -An -tx1 | tr -d '[:space:]')" = '0a' ] +} + +@test "fails, naming the package path, when an entry has no resolved URL" { + write_unresolvable_lockfile "${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/beta'* ]] + [[ "${output}" == *'no usable tarball URL'* ]] +} + +@test "fails, naming the package path, on a git+ssh resolved URL" { + write_git_protocol_lockfile "${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/beta'* ]] + # A jq capture stack trace would leak through here instead of a named path. + [[ "${output}" != *'jq: error'* ]] +} + +@test "fails, naming the package path, on a tarball URL that is not .tgz" { + write_mixed_lockfile "${TMP}" + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/beta/-/beta-2.0.0.zip"' + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'node_modules/beta'* ]] + [[ "${output}" != *'jq: error'* ]] +} + +@test "leaves the lockfile untouched when it refuses to normalize" { + write_git_protocol_lockfile "${TMP}" + local before + before="$(cat "${TMP}")" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [ "$(cat "${TMP}")" = "${before}" ] +} + +@test "fails cleanly when the lockfile does not exist" { + run "${NORMALIZE}" "${BATS_TEST_TMPDIR}/absent.json" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'no such lockfile'* ]] +} + +@test "no failure message leaks the JFrog host, which CI masks as ***" { + write_unresolvable_lockfile "${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [[ "${output}" != *'cplace.jfrog.io'* ]] +} + +@test "the reported count matches what the rewrite actually changes" { + # count_foreign_entries used `startswith($proxy)` while the rewrite asked + # whether $proxy + differed. An entry already under + # the proxy host but with a stray path segment satisfied the first and not the + # second, so the normalizer reported "0 rewritten / already normalized" while + # silently rewriting the file - and README Flow 1 makes that count the + # documented verification signal. + write_mixed_lockfile "${TMP}" + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/extra/beta/-/beta-2.0.0.tgz"' + local before + before="$(wc -c <"${TMP}")" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'entries rewritten: 2'* ]] + [[ "${output}" != *'already normalized'* ]] + [ "$(wc -c <"${TMP}")" -ne "${before}" ] +} + +@test "an unsupported lockfileVersion fails readably instead of a jq trace" { + printf '{"name":"x","lockfileVersion":1}\n' >"${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'lockfileVersion 1'* ]] + [[ "${output}" != *'jq: error'* ]] +} + +@test "the self-assertion FAILS CLOSED and leaves the lockfile untouched when it cannot run" { + # `if ! diff -q <(fingerprint_of A) <(fingerprint_of B)` disabled `set -e` for + # the condition, so a failing fingerprint_of produced two empty streams, diff + # called them identical, and the file was overwritten unverified with exit 0. + write_mixed_lockfile "${TMP}" + local before + before="$(cat "${TMP}")" + local hidden="${BATS_TEST_TMPDIR}/fingerprint.jq.hidden" + mv "${BATS_TEST_DIRNAME}/fingerprint.jq" "${hidden}" + + run "${NORMALIZE}" "${TMP}" + local rc="${status}" out="${output}" + + mv "${hidden}" "${BATS_TEST_DIRNAME}/fingerprint.jq" + + [ "${rc}" -ne 0 ] + [[ "${out}" == *'left untouched'* ]] + [ "$(cat "${TMP}")" = "${before}" ] +} + +@test "rewrites a scope-repeating tarball path onto the proxy" { + # The npmjs form of the shape JFrog serves for privately published scoped + # packages. The captured path must keep the repeated scope verbatim. + write_mixed_lockfile "${TMP}" + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://registry.npmjs.org/@cplace-next/beta/-/@cplace-next/beta-2.0.0.tgz"' + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [ "$(jq -r '.packages["node_modules/beta"].resolved' "${TMP}")" \ + = "${PROXY}@cplace-next/beta/-/@cplace-next/beta-2.0.0.tgz" ] +} + +@test "a lockfile with no lockfileVersion at all fails readably" { + printf '{"name":"x","packages":{}}\n' >"${TMP}" + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 1 ] + [[ "${output}" == *'is it a package-lock.json?'* ]] +} + +@test "the root entry is left alone, and the reported count says so" { + # The rewrite used to run on every entry with a string `resolved` while + # count_foreign_entries excluded the root key, so a run that rewrote the root + # still printed "entries rewritten: 0" and "already normalized" about a file + # it had changed - and README Flow 1 makes that count the verification signal. + write_mixed_lockfile "${TMP}" + mutate "${TMP}" '.packages[""].resolved = "https://registry.npmjs.org/x/-/x-1.0.0.tgz"' + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [ "$(jq -r '.packages[""].resolved' "${TMP}")" = 'https://registry.npmjs.org/x/-/x-1.0.0.tgz' ] + [[ "${output}" == *'entries rewritten: 1'* ]] +} + +@test "a root entry whose resolved is not a tarball URL keeps its key" { + # assert_resolvable deliberately skips the root entry, so this value reached + # `capture` unvalidated - which yields empty on a non-match, and `|= empty` + # deletes the key. The loss was silent: fingerprint.jq dropped it on both + # sides, so the self-assertion compared equal and the run reported success. + write_mixed_lockfile "${TMP}" + mutate "${TMP}" '.packages[""].resolved = "packages/root"' + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [ "$(jq -r '.packages[""].resolved' "${TMP}")" = 'packages/root' ] +} + +@test "leaves an odd-shaped entry already on the proxy untouched" { + # This is what the pre-widening regex got wrong: the entry is already correct, + # so the normalizer must neither rewrite it nor - via a capture that matches + # nothing - drop its resolved key. + write_mixed_lockfile "${TMP}" + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@fortawesome/beta/-/2.0.0/beta-2.0.0.tgz"' + + run "${NORMALIZE}" "${TMP}" + + [ "${status}" -eq 0 ] + [ "$(jq -r '.packages["node_modules/beta"].resolved' "${TMP}")" \ + = "${PROXY}@fortawesome/beta/-/2.0.0/beta-2.0.0.tgz" ] + [[ "${output}" == *'entries rewritten: 1'* ]] +} diff --git a/tools/scripts/lockfile/normalize-lockfile.sh b/tools/scripts/lockfile/normalize-lockfile.sh new file mode 100755 index 00000000..81e64954 --- /dev/null +++ b/tools/scripts/lockfile/normalize-lockfile.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash +# +# Rewrites every `resolved` URL in a package-lock.json onto the cplace JFrog npm +# proxy, changing nothing else. Idempotent. +# +# Usage: +# ./tools/scripts/lockfile/normalize-lockfile.sh [] +# +# Defaults to ./package-lock.json. +# +# Requires only bash and jq - no node, no `npm ci`. That is the point: this +# script repairs the lockfile whose npmjs URLs make `npm ci` fail against a +# JFrog ~/.npmrc, so it cannot depend on `npm ci` having worked. +# +# See tools/scripts/lockfile/README.md + +set -euo pipefail + +# shellcheck source=tools/scripts/lockfile/lib.sh +source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" + +main() { + local lockfile="${1:-package-lock.json}" + + require_jq + [[ -f "${lockfile}" ]] || die "no such lockfile: ${lockfile}" + assert_supported_lockfile "${lockfile}" + + assert_resolvable "${lockfile}" + + local before_bytes rewritten + before_bytes="$(byte_size "${lockfile}")" + rewritten="$(count_foreign_entries "${lockfile}")" + + local tmp + tmp="$(mktemp)" + # shellcheck disable=SC2064 # expand ${tmp} now, not when the trap fires + trap "rm -f '${tmp}'" EXIT + + # The guards are the shared predicate's own terms (lib.sh's + # JQ_REGISTRY_ENTRIES), so that what this rewrites and what + # count_foreign_entries reports cannot disagree. Without the `.key != ""` arm + # the root entry was rewritten while the count - which excludes it - still + # said "entries rewritten: 0, already normalized" about a changed file; and a + # root `resolved` that is not a tarball URL lost its key entirely, because a + # non-matching capture yields empty and `|= empty` deletes. + jq --arg proxy "${JFROG_NPM_PROXY}" --arg tarball_re "${TARBALL_PATH_RE}" ' + .packages |= with_entries( + if .key != "" + and (.value | type) == "object" + and (.value.resolved | type) == "string" + and (.value.resolved | test("^https?://"; "i")) + then + .value.resolved |= ($proxy + (capture($tarball_re) | .t)) + else + . + end + ) + ' "${lockfile}" >"${tmp}" || die "internal error: the rewrite failed; ${lockfile} left untouched" + + # Self-assertion. Secondary by design: it cannot see drift that arrived BEFORE + # this run (a bad merge), which is why check-lockfile.sh compares against a git + # baseline instead. It does make this script safe to run standalone. + # + # Both fingerprints are materialised and CHECKED first, rather than compared + # through process substitution inside `if !`. That construct disables `set -e` + # for the condition, so if fingerprint_of failed, both substitutions produced + # empty output, `diff` called them identical, the assertion "passed" - and the + # lockfile was overwritten unverified, exit 0. It has to fail CLOSED: this is + # the step that decides whether to write the file at all. + local fp_before fp_after + fp_before="$(mktemp)" || die "internal error: mktemp failed" + fp_after="$(mktemp)" || die "internal error: mktemp failed" + # shellcheck disable=SC2064 # expand paths now, not when the trap fires + trap "rm -f '${tmp}' '${fp_before}' '${fp_after}'" EXIT + + fingerprint_of "${lockfile}" >"${fp_before}" \ + || die "internal error: cannot fingerprint ${lockfile} (is ${FINGERPRINT_JQ} present?); left untouched" + fingerprint_of "${tmp}" >"${fp_after}" \ + || die "internal error: cannot fingerprint the rewritten lockfile (is ${FINGERPRINT_JQ} present?); ${lockfile} left untouched" + + if ! diff -q "${fp_before}" "${fp_after}" >/dev/null; then + die "internal error: normalization altered the dependency graph; ${lockfile} left untouched" + fi + + # `cat >` rather than `mv`, to preserve the file's existing permissions. + cat "${tmp}" >"${lockfile}" + + local after_bytes + after_bytes="$(byte_size "${lockfile}")" + + info "normalized ${lockfile}" + info " entries rewritten: ${rewritten}" + info " byte delta: $((after_bytes - before_bytes)) (${before_bytes} -> ${after_bytes})" + if ((rewritten == 0)); then + info " already normalized - nothing to do" + fi +} + +main "$@" diff --git a/tools/scripts/lockfile/test-helper.bash b/tools/scripts/lockfile/test-helper.bash new file mode 100644 index 00000000..8704f94d --- /dev/null +++ b/tools/scripts/lockfile/test-helper.bash @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# +# Shared bats fixture builders. Fixtures are tiny hand-written lockfiles, not +# copies of the real 262 KB one: the tests assert behaviour, not byte counts. +# +# shellcheck disable=SC2034 # PROXY/NPMJS are consumed by the .bats files that load this + +readonly PROXY='https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/' +readonly NPMJS='https://registry.npmjs.org/' + +# A three-entry mixed lockfile: one npmjs entry (scoped, with a dependency edge), +# one already on the proxy, plus the root entry which carries no `resolved`. +write_mixed_lockfile() { + cat >"$1" <<'JSON' +{ + "name": "fixture", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fixture", + "version": "1.0.0", + "dependencies": { + "@scope/alpha": "^1.0.0" + } + }, + "node_modules/@scope/alpha": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@scope/alpha/-/alpha-1.0.0.tgz", + "integrity": "sha512-AAAA==", + "dependencies": { + "beta": "^2.0.0" + } + }, + "node_modules/beta": { + "version": "2.0.0", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/beta/-/beta-2.0.0.tgz", + "integrity": "sha512-BBBB==" + } + } +} +JSON +} + +# Applies a jq filter to a lockfile in place. Used to inject drift. +mutate() { + local file="$1" filter="$2" tmp + tmp="$(mktemp)" + jq "${filter}" "${file}" >"${tmp}" + mv "${tmp}" "${file}" +} + +# A lockfile whose non-root entry carries no `resolved` at all. +write_unresolvable_lockfile() { + write_mixed_lockfile "$1" + mutate "$1" 'del(.packages["node_modules/beta"].resolved)' +} + +# A lockfile whose non-root entry resolves over a protocol this tool does not +# handle. Must fail by NAME, not with a jq capture stack trace. +write_git_protocol_lockfile() { + write_mixed_lockfile "$1" + mutate "$1" '.packages["node_modules/beta"].resolved = + "git+ssh://git@github.com/example/beta.git#0123456789abcdef"' +} diff --git a/tools/scripts/lockfile/warn-foreign-registry.bats b/tools/scripts/lockfile/warn-foreign-registry.bats new file mode 100644 index 00000000..034baeef --- /dev/null +++ b/tools/scripts/lockfile/warn-foreign-registry.bats @@ -0,0 +1,166 @@ +#!/usr/bin/env bats +# +# Behavioural tests for warn-foreign-registry.sh. +# +# The overriding property is that this check is ADVISORY: it runs inside +# use-npmrc in every consumer's pipeline, so it must never fail a build no +# matter what it is pointed at. +# +# Run with: bats tools/scripts/lockfile/ + +setup() { + load 'test-helper' + WARN="${BATS_TEST_DIRNAME}/warn-foreign-registry.sh" + TMP="${BATS_TEST_TMPDIR}/package-lock.json" + SUMMARY="${BATS_TEST_TMPDIR}/summary.md" +} + +@test "is silent on a lockfile that resolves entirely through the proxy" { + write_mixed_lockfile "${TMP}" + "${BATS_TEST_DIRNAME}/normalize-lockfile.sh" "${TMP}" >/dev/null + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [ -z "${output}" ] +} + +@test "warns, with a count, when entries resolve elsewhere" { + write_mixed_lockfile "${TMP}" + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'::warning'* ]] + [[ "${output}" == *'1 entries'* ]] +} + +@test "ignores local-path resolved values, which are not registry references" { + write_mixed_lockfile "${TMP}" + "${BATS_TEST_DIRNAME}/normalize-lockfile.sh" "${TMP}" >/dev/null + mutate "${TMP}" '.packages["node_modules/local-plugin"] = + {"version":"1.0.0","resolved":"tools/eslint-rules","link":true}' + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [ -z "${output}" ] +} + +@test "writes a job summary when GITHUB_STEP_SUMMARY is set" { + write_mixed_lockfile "${TMP}" + + GITHUB_STEP_SUMMARY="${SUMMARY}" run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [ -f "${SUMMARY}" ] + grep -q 'outside the cplace npm proxy' "${SUMMARY}" + grep -q 'node_modules/@scope/alpha' "${SUMMARY}" +} + +@test "the warning names no URL, so it survives *** masking" { + write_mixed_lockfile "${TMP}" + + GITHUB_STEP_SUMMARY="${SUMMARY}" run "${WARN}" "${TMP}" + + [[ "${output}" != *'cplace.jfrog.io'* ]] + [[ "${output}" != *'registry.npmjs.org'* ]] +} + +# --- advisory guarantee: none of these may fail a build ----------------------- + +@test "exits 0 and says nothing when the lockfile does not exist" { + run "${WARN}" "${BATS_TEST_TMPDIR}/absent.json" + + [ "${status}" -eq 0 ] + [ -z "${output}" ] +} + +@test "exits 0 on a lockfile that is not valid JSON" { + printf 'not json at all\n' >"${TMP}" + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] +} + +@test "exits 0 on a lockfile with no packages section" { + printf '{"name":"x","lockfileVersion":3}\n' >"${TMP}" + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [ -z "${output}" ] +} + +@test "falls back to GITHUB_WORKSPACE when given no argument" { + write_mixed_lockfile "${BATS_TEST_TMPDIR}/package-lock.json" + + GITHUB_WORKSPACE="${BATS_TEST_TMPDIR}" run "${WARN}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'::warning'* ]] +} + +@test "reports an entry on the right host but with a stray path segment" { + # `startswith($proxy)` passed this and reported nothing, while + # check-lockfile.sh correctly rejected it. The advisory inventory decides when + # the replace-registry-host mitigation can be removed, so a false negative + # here could green-light removing it while lockfiles are still broken. + write_mixed_lockfile "${TMP}" + "${BATS_TEST_DIRNAME}/normalize-lockfile.sh" "${TMP}" >/dev/null + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/extra/beta/-/beta-2.0.0.tgz"' + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [[ "${output}" == *'::warning'* ]] + [[ "${output}" == *'1 entries'* ]] +} + +@test "agrees with check-lockfile.sh about what is an offender" { + write_mixed_lockfile "${TMP}" + "${BATS_TEST_DIRNAME}/normalize-lockfile.sh" "${TMP}" >/dev/null + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/extra/beta/-/beta-2.0.0.tgz"' + + run "${BATS_TEST_DIRNAME}/check-lockfile.sh" --prefix-only "${TMP}" + local check_rc="${status}" + run "${WARN}" "${TMP}" + + # check-lockfile fails (1) exactly when the advisory warns (non-empty output). + [ "${check_rc}" -eq 1 ] + [[ "${output}" == *'::warning'* ]] +} + +@test "exits 0 silently when lib.sh cannot be sourced" { + write_mixed_lockfile "${TMP}" + local hidden="${BATS_TEST_TMPDIR}/lib.sh.hidden" + mv "${BATS_TEST_DIRNAME}/lib.sh" "${hidden}" + + run "${WARN}" "${TMP}" + local rc="${status}" out="${output}" + + mv "${hidden}" "${BATS_TEST_DIRNAME}/lib.sh" + + [ "${rc}" -eq 0 ] + [ -z "${out}" ] +} + +@test "does not report an odd-shaped entry that is already on the proxy" { + # The inventory these warnings produce is what decides when the + # replace-registry-host=never mitigation can be removed, so a false positive + # is not cosmetic: it keeps the count above zero forever. Measured on + # cplace-paw-fe release/25.2, which reported 18 entries where only 14 were + # actually foreign. + write_mixed_lockfile "${TMP}" + "${BATS_TEST_DIRNAME}/normalize-lockfile.sh" "${TMP}" >/dev/null + mutate "${TMP}" '.packages["node_modules/beta"].resolved = + "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@cplace-next/beta/-/@cplace-next/beta-2.0.0.tgz"' + + run "${WARN}" "${TMP}" + + [ "${status}" -eq 0 ] + [ -z "${output}" ] +} diff --git a/tools/scripts/lockfile/warn-foreign-registry.sh b/tools/scripts/lockfile/warn-foreign-registry.sh new file mode 100755 index 00000000..a26ca42f --- /dev/null +++ b/tools/scripts/lockfile/warn-foreign-registry.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# +# Advisory check: warn when a lockfile has `resolved` URLs that do NOT go +# through the cplace JFrog npm proxy. +# +# Usage: +# ./tools/scripts/lockfile/warn-foreign-registry.sh [] +# +# Runs inside the `use-npmrc` composite, so it inspects the CONSUMER's lockfile +# on the runner. Under `replace-registry-host=never`, which `use-npmrc` sets, +# those entries are fetched verbatim from the registry they name - outside the +# proxy. Without that flag the outcome depends on the npm version: 10.2.4 +# rewrites the host onto the configured registry correctly and resolves THROUGH +# the proxy, while 11.3.0 drops the registry's path prefix and fails with an +# E404 masked as *** (PFM-ISSUE-34453). Measured 2026-08-14, both ways. +# +# ADVISORY ONLY - this must never fail a consumer's build. Every exit is 0. +# It is a discovery mechanism: the warnings are the inventory of lockfiles that +# still need normalizing, and the moment that inventory is empty the +# `replace-registry-host=never` mitigation can be dropped. +# +# Emits a `::warning` annotation (surfaces at the top of the run and against the +# file) plus a job-summary table. Names package paths only, never URLs, so the +# message survives *** masking of the JFrog host. +# +# See tools/scripts/lockfile/README.md + +set -uo pipefail + +# Sourced, not re-implemented. This script previously carried its own copy of the +# proxy URL and its own `startswith($proxy)` predicate - which is the exact bug +# lib.sh documents as already found and fixed once: an entry on the right host +# but with a stray path segment satisfies `startswith` and was silently reported +# as compliant. That mattered here more than anywhere else, because these +# warnings are the inventory that decides when the mitigation can be removed. +# +# Sourcing is guarded on both sides: an unreachable or unloadable lib.sh exits 0 +# silently rather than failing a consumer's build, which the advisory contract +# below requires and which the script's own care cannot cover once it has to +# reference an undefined constant under `set -u`. +LIB="$(dirname "${BASH_SOURCE[0]}")/lib.sh" +readonly LIB +[[ -r "${LIB}" ]] || exit 0 +# shellcheck source=tools/scripts/lockfile/lib.sh +source "${LIB}" || exit 0 + +readonly MAX_LISTED=10 + +main() { + local lockfile="${1:-${GITHUB_WORKSPACE:-.}/package-lock.json}" + + # Every precondition is a silent success: an advisory check must not become a + # new way for consumer pipelines to fail. + [[ -f "${lockfile}" ]] || return 0 + command -v jq >/dev/null 2>&1 || return 0 + + local offenders total + # The SAME predicate check-lockfile.sh asserts on, via lib.sh: strip the + # tarball path and require the remaining prefix to equal the proxy exactly. + # `startswith` was wrong here - it passes an entry on the right host with a + # stray path segment, e.g. `.../cplace-npm/extra/beta/-/beta-2.0.0.tgz`, which + # check-lockfile.sh correctly rejects. The two must agree, or this inventory + # under-reports the very lockfiles it exists to find. + # + # JQ_REGISTRY_ENTRIES considers only http(s) `resolved` values: local-path + # values (e.g. "tools/eslint-rules" for a workspace-local plugin) are not + # hosted anywhere and must not be reported - 4 of 41 FE repos have them. + offenders="$(jq -r --arg proxy "${JFROG_NPM_PROXY}" --arg tarball_re "${TARBALL_PATH_RE}" \ + "[ ${JQ_REGISTRY_ENTRIES} | select((.value.resolved | sub(\$tarball_re; \"\")) != \$proxy) | .key ] | .[]" \ + "${lockfile}" 2>/dev/null)" || return 0 + + [[ -n "${offenders}" ]] || return 0 + + total="$(printf '%s\n' "${offenders}" | wc -l | tr -d '[:space:]')" + + printf '::warning file=%s::%s entries in package-lock.json do not resolve via the cplace npm proxy. Under replace-registry-host=never (set by use-npmrc) they are fetched from the registry they name, bypassing the proxy; without that flag they fail on npm 11 and newer. Normalize this lockfile - see PFM-ISSUE-34453.\n' \ + "$(basename "${lockfile}")" "${total}" + + if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then + # shellcheck disable=SC2016 # backticks here are markdown for the job summary, not command substitution + { + printf '### Lockfile entries outside the cplace npm proxy\n\n' + printf '**%s** `resolved` entries in `%s` point somewhere other than the cplace npm proxy.\n\n' \ + "${total}" "${lockfile#"${GITHUB_WORKSPACE:-}/"}" + printf '`use-npmrc` sets `replace-registry-host=never`, so npm fetches each of these URLs verbatim ' + printf '**from the registry the lockfile names, not through the cplace proxy**.\n\n' + printf 'What would happen without that flag depends on the npm version: **npm 10.2.4** rewrites the ' + printf 'host onto the configured registry correctly, and the entry resolves *through* the proxy; ' + printf '**npm 11.3.0** drops the path prefix and fails with an `E404` masked as `***`. Both measured ' + printf '2026-08-14. Runners pinned to node 18.19.1 are on npm 10; developer machines, and any runner ' + printf 'moving to node 24, are not.\n\n' + printf 'Fix by normalizing the lockfile onto the proxy (PFM-ISSUE-34453) - it then resolves through ' + printf 'the proxy on every npm version, with or without the flag, and the mitigation can be removed ' + printf 'once no lockfile reports this.\n\n' + printf '
First %s affected packages\n\n' "${MAX_LISTED}" + printf '```\n' + printf '%s\n' "${offenders}" | head -n "${MAX_LISTED}" + (( total > MAX_LISTED )) && printf '… and %s more\n' "$((total - MAX_LISTED))" + printf '```\n\n
\n\n' + } >>"${GITHUB_STEP_SUMMARY}" + fi + + return 0 +} + +main "$@" From e35f06fe310b4015e7dfe83fcb51b9ae6a7ff671 Mon Sep 17 00:00:00 2001 From: Christian Kaltenbach Date: Fri, 14 Aug 2026 14:05:17 +0200 Subject: [PATCH 2/2] PFM-ISSUE-34453 - github-actions: normalize package-lock.json resolved URLs onto the JFrog npm proxy --- package-lock.json | 342 +++++++++++++++++++++++----------------------- 1 file changed, 171 insertions(+), 171 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53558eb1..3fdfc23b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ }, "node_modules/@ampproject/remapping": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@ampproject/remapping/-/remapping-2.2.0.tgz", "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, "dependencies": { @@ -58,7 +58,7 @@ }, "node_modules/@ampproject/remapping/node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, "dependencies": { @@ -71,7 +71,7 @@ }, "node_modules/@babel/code-frame": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/code-frame/-/code-frame-7.18.6.tgz", "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, "dependencies": { @@ -83,7 +83,7 @@ }, "node_modules/@babel/compat-data": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/compat-data/-/compat-data-7.19.4.tgz", "integrity": "sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==", "dev": true, "engines": { @@ -92,7 +92,7 @@ }, "node_modules/@babel/core": { "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/core/-/core-7.19.3.tgz", "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", "dev": true, "dependencies": { @@ -118,7 +118,7 @@ }, "node_modules/@babel/generator": { "version": "7.19.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/generator/-/generator-7.19.5.tgz", "integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==", "dev": true, "dependencies": { @@ -132,7 +132,7 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", "dev": true, "dependencies": { @@ -144,7 +144,7 @@ }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz", "integrity": "sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==", "dev": true, "dependencies": { @@ -157,7 +157,7 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", "dev": true, "dependencies": { @@ -175,7 +175,7 @@ }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", "dev": true, "dependencies": { @@ -196,7 +196,7 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", "dev": true, "dependencies": { @@ -212,7 +212,7 @@ }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz", "integrity": "sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==", "dev": true, "dependencies": { @@ -229,7 +229,7 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, "engines": { @@ -238,7 +238,7 @@ }, "node_modules/@babel/helper-explode-assignable-expression": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz", "integrity": "sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==", "dev": true, "dependencies": { @@ -250,7 +250,7 @@ }, "node_modules/@babel/helper-function-name": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "dependencies": { @@ -263,7 +263,7 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { @@ -275,7 +275,7 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", "dev": true, "dependencies": { @@ -287,7 +287,7 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "dependencies": { @@ -299,7 +299,7 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", "dev": true, "dependencies": { @@ -318,7 +318,7 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz", "integrity": "sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==", "dev": true, "dependencies": { @@ -339,7 +339,7 @@ }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz", "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==", "dev": true, "dependencies": { @@ -357,7 +357,7 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", "dev": true, "dependencies": { @@ -373,7 +373,7 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-simple-access/-/helper-simple-access-7.19.4.tgz", "integrity": "sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==", "dev": true, "dependencies": { @@ -385,7 +385,7 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", "dev": true, "dependencies": { @@ -397,7 +397,7 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { @@ -427,7 +427,7 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true, "engines": { @@ -436,7 +436,7 @@ }, "node_modules/@babel/helper-wrap-function": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", "dev": true, "dependencies": { @@ -451,7 +451,7 @@ }, "node_modules/@babel/helpers": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/helpers/-/helpers-7.19.4.tgz", "integrity": "sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==", "dev": true, "dependencies": { @@ -465,7 +465,7 @@ }, "node_modules/@babel/highlight": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/highlight/-/highlight-7.18.6.tgz", "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { @@ -491,7 +491,7 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz", "integrity": "sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==", "dev": true, "dependencies": { @@ -506,7 +506,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", "dev": true, "dependencies": { @@ -523,7 +523,7 @@ }, "node_modules/@babel/plugin-proposal-async-generator-functions": { "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", "dev": true, "dependencies": { @@ -541,7 +541,7 @@ }, "node_modules/@babel/plugin-proposal-class-properties": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz", "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==", "dev": true, "dependencies": { @@ -557,7 +557,7 @@ }, "node_modules/@babel/plugin-proposal-class-static-block": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", "dev": true, "dependencies": { @@ -574,7 +574,7 @@ }, "node_modules/@babel/plugin-proposal-dynamic-import": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz", "integrity": "sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==", "dev": true, "dependencies": { @@ -590,7 +590,7 @@ }, "node_modules/@babel/plugin-proposal-export-namespace-from": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz", "integrity": "sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==", "dev": true, "dependencies": { @@ -606,7 +606,7 @@ }, "node_modules/@babel/plugin-proposal-json-strings": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz", "integrity": "sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==", "dev": true, "dependencies": { @@ -622,7 +622,7 @@ }, "node_modules/@babel/plugin-proposal-logical-assignment-operators": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", "dev": true, "dependencies": { @@ -638,7 +638,7 @@ }, "node_modules/@babel/plugin-proposal-nullish-coalescing-operator": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz", "integrity": "sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==", "dev": true, "dependencies": { @@ -654,7 +654,7 @@ }, "node_modules/@babel/plugin-proposal-numeric-separator": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz", "integrity": "sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==", "dev": true, "dependencies": { @@ -670,7 +670,7 @@ }, "node_modules/@babel/plugin-proposal-object-rest-spread": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.19.4.tgz", "integrity": "sha512-wHmj6LDxVDnL+3WhXteUBaoM1aVILZODAUjg11kHqG4cOlfgMQGxw6aCgvrXrmaJR3Bn14oZhImyCPZzRpC93Q==", "dev": true, "dependencies": { @@ -689,7 +689,7 @@ }, "node_modules/@babel/plugin-proposal-optional-catch-binding": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz", "integrity": "sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==", "dev": true, "dependencies": { @@ -705,7 +705,7 @@ }, "node_modules/@babel/plugin-proposal-optional-chaining": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", "dev": true, "dependencies": { @@ -722,7 +722,7 @@ }, "node_modules/@babel/plugin-proposal-private-methods": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz", "integrity": "sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==", "dev": true, "dependencies": { @@ -738,7 +738,7 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", "dev": true, "dependencies": { @@ -756,7 +756,7 @@ }, "node_modules/@babel/plugin-proposal-unicode-property-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz", "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==", "dev": true, "dependencies": { @@ -772,7 +772,7 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "dependencies": { @@ -796,7 +796,7 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "dependencies": { @@ -808,7 +808,7 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "dependencies": { @@ -823,7 +823,7 @@ }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "dev": true, "dependencies": { @@ -835,7 +835,7 @@ }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", "dev": true, "dependencies": { @@ -847,7 +847,7 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", "dev": true, "dependencies": { @@ -874,7 +874,7 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "dependencies": { @@ -901,7 +901,7 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "dependencies": { @@ -913,7 +913,7 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "dependencies": { @@ -925,7 +925,7 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "dependencies": { @@ -937,7 +937,7 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "dependencies": { @@ -949,7 +949,7 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "dependencies": { @@ -961,7 +961,7 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "dependencies": { @@ -973,7 +973,7 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "dependencies": { @@ -988,7 +988,7 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "dependencies": { @@ -1003,7 +1003,7 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "dependencies": { @@ -1018,7 +1018,7 @@ }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", "dev": true, "dependencies": { @@ -1033,7 +1033,7 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", "dev": true, "dependencies": { @@ -1050,7 +1050,7 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz", "integrity": "sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==", "dev": true, "dependencies": { @@ -1065,7 +1065,7 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.19.4.tgz", "integrity": "sha512-934S2VLLlt2hRJwPf4MczaOr4hYF0z+VKPwqTNxyKX7NthTiPfhuKFWQZHXRM0vh/wo/VyXB3s4bZUNA08l+tQ==", "dev": true, "dependencies": { @@ -1080,7 +1080,7 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", "dev": true, "dependencies": { @@ -1103,7 +1103,7 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", "dev": true, "dependencies": { @@ -1118,7 +1118,7 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.19.4.tgz", "integrity": "sha512-t0j0Hgidqf0aM86dF8U+vXYReUgJnlv4bZLsyoPnwZNrGY+7/38o8YjaELrvHeVfTZao15kjR0PVv0nju2iduA==", "dev": true, "dependencies": { @@ -1133,7 +1133,7 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz", "integrity": "sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==", "dev": true, "dependencies": { @@ -1149,7 +1149,7 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz", "integrity": "sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==", "dev": true, "dependencies": { @@ -1164,7 +1164,7 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz", "integrity": "sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==", "dev": true, "dependencies": { @@ -1180,7 +1180,7 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", "dev": true, "dependencies": { @@ -1195,7 +1195,7 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz", "integrity": "sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==", "dev": true, "dependencies": { @@ -1212,7 +1212,7 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz", "integrity": "sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==", "dev": true, "dependencies": { @@ -1227,7 +1227,7 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz", "integrity": "sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==", "dev": true, "dependencies": { @@ -1242,7 +1242,7 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", "dev": true, "dependencies": { @@ -1259,7 +1259,7 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", "dev": true, "dependencies": { @@ -1277,7 +1277,7 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", "dev": true, "dependencies": { @@ -1296,7 +1296,7 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz", "integrity": "sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==", "dev": true, "dependencies": { @@ -1312,7 +1312,7 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", "dev": true, "dependencies": { @@ -1328,7 +1328,7 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz", "integrity": "sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==", "dev": true, "dependencies": { @@ -1343,7 +1343,7 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz", "integrity": "sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==", "dev": true, "dependencies": { @@ -1359,7 +1359,7 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.18.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", "dev": true, "dependencies": { @@ -1374,7 +1374,7 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz", "integrity": "sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==", "dev": true, "dependencies": { @@ -1389,7 +1389,7 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", "dev": true, "dependencies": { @@ -1405,7 +1405,7 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz", "integrity": "sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==", "dev": true, "dependencies": { @@ -1420,7 +1420,7 @@ }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz", "integrity": "sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==", "dev": true, "dependencies": { @@ -1435,7 +1435,7 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", "dev": true, "dependencies": { @@ -1451,7 +1451,7 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz", "integrity": "sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==", "dev": true, "dependencies": { @@ -1466,7 +1466,7 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz", "integrity": "sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==", "dev": true, "dependencies": { @@ -1481,7 +1481,7 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz", "integrity": "sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==", "dev": true, "dependencies": { @@ -1496,7 +1496,7 @@ }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz", "integrity": "sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w==", "dev": true, "dependencies": { @@ -1513,7 +1513,7 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz", "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==", "dev": true, "dependencies": { @@ -1528,7 +1528,7 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz", "integrity": "sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==", "dev": true, "dependencies": { @@ -1544,7 +1544,7 @@ }, "node_modules/@babel/preset-env": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/preset-env/-/preset-env-7.19.4.tgz", "integrity": "sha512-5QVOTXUdqTCjQuh2GGtdd7YEhoRXBMVGROAtsBeLGIbIz3obCBIfRMT1I3ZKkMgNzwkyCkftDXSSkHxnfVf4qg==", "dev": true, "dependencies": { @@ -1633,7 +1633,7 @@ }, "node_modules/@babel/preset-modules": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/preset-modules/-/preset-modules-0.1.5.tgz", "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==", "dev": true, "dependencies": { @@ -1649,7 +1649,7 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", "dev": true, "dependencies": { @@ -1666,7 +1666,7 @@ }, "node_modules/@babel/runtime": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/runtime/-/runtime-7.19.4.tgz", "integrity": "sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==", "dev": true, "dependencies": { @@ -1678,7 +1678,7 @@ }, "node_modules/@babel/template": { "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/template/-/template-7.18.10.tgz", "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { @@ -1692,7 +1692,7 @@ }, "node_modules/@babel/traverse": { "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@babel/traverse/-/traverse-7.19.4.tgz", "integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==", "dev": true, "dependencies": { @@ -2370,7 +2370,7 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, "dependencies": { @@ -2384,7 +2384,7 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, "engines": { @@ -2393,7 +2393,7 @@ }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@jridgewell/set-array/-/set-array-1.1.2.tgz", "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, "engines": { @@ -2402,7 +2402,7 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, @@ -2626,7 +2626,7 @@ }, "node_modules/@types/jest": { "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/@types/jest/-/jest-29.5.14.tgz", "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, "dependencies": { @@ -2691,7 +2691,7 @@ }, "node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { @@ -2725,7 +2725,7 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { @@ -2838,7 +2838,7 @@ }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "dev": true, "dependencies": { @@ -2894,7 +2894,7 @@ }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz", "integrity": "sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==", "dev": true, "dependencies": { @@ -2908,7 +2908,7 @@ }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz", "integrity": "sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==", "dev": true, "dependencies": { @@ -2921,7 +2921,7 @@ }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz", "integrity": "sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==", "dev": true, "dependencies": { @@ -3001,7 +3001,7 @@ }, "node_modules/browserslist": { "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/browserslist/-/browserslist-4.21.4.tgz", "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", "dev": true, "dependencies": { @@ -3019,7 +3019,7 @@ }, "node_modules/bs-logger": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "dependencies": { @@ -3046,7 +3046,7 @@ }, "node_modules/call-bind": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "dependencies": { @@ -3074,13 +3074,13 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001418", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz", "integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==", "dev": true }, "node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { @@ -3148,7 +3148,7 @@ }, "node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { @@ -3157,13 +3157,13 @@ }, "node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { "delayed-stream": "~1.0.0" @@ -3180,13 +3180,13 @@ }, "node_modules/convert-source-map": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, "node_modules/core-js-compat": { "version": "3.25.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.25.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/core-js-compat/-/core-js-compat-3.25.5.tgz", "integrity": "sha512-ovcyhs2DEBUIE0MGEKHP4olCUW/XYte3Vroyxuh38rD1wAO4dHohsovUC4eAOuzFxE6b+RXvBU3UZ9o0YhUTkA==", "dev": true, "dependencies": { @@ -3294,7 +3294,7 @@ }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { @@ -3334,7 +3334,7 @@ }, "node_modules/define-properties": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/define-properties/-/define-properties-1.1.4.tgz", "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "dependencies": { @@ -3347,7 +3347,7 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { "node": ">=0.4.0" @@ -3373,7 +3373,7 @@ }, "node_modules/electron-to-chromium": { "version": "1.4.276", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/electron-to-chromium/-/electron-to-chromium-1.4.276.tgz", "integrity": "sha512-EpuHPqu8YhonqLBXHoU6hDJCD98FCe6KDoet3/gY1qsQ6usjJoHqBH2YIVs8FXaAtHwVL8Uqa/fsYao/vq9VWQ==", "dev": true }, @@ -3403,7 +3403,7 @@ }, "node_modules/escalade": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { @@ -3412,7 +3412,7 @@ }, "node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { @@ -3434,7 +3434,7 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { @@ -3510,7 +3510,7 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, @@ -3580,13 +3580,13 @@ }, "node_modules/function-bind": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "engines": { @@ -3604,7 +3604,7 @@ }, "node_modules/get-intrinsic": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/get-intrinsic/-/get-intrinsic-1.1.3.tgz", "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { @@ -3663,7 +3663,7 @@ }, "node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { @@ -3678,7 +3678,7 @@ }, "node_modules/has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { @@ -3690,7 +3690,7 @@ }, "node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { @@ -3699,7 +3699,7 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, "dependencies": { @@ -3708,7 +3708,7 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, "engines": { @@ -3779,7 +3779,7 @@ }, "node_modules/is-core-module": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/is-core-module/-/is-core-module-2.10.0.tgz", "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "dev": true, "dependencies": { @@ -5430,7 +5430,7 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, @@ -5449,7 +5449,7 @@ }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, "bin": { @@ -5573,7 +5573,7 @@ }, "node_modules/lodash.debounce": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "dev": true }, @@ -5633,7 +5633,7 @@ }, "node_modules/make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, @@ -5678,7 +5678,7 @@ }, "node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "engines": { "node": ">= 0.6" @@ -5686,7 +5686,7 @@ }, "node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { "mime-db": "1.52.0" @@ -5718,7 +5718,7 @@ }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, @@ -5736,7 +5736,7 @@ }, "node_modules/node-releases": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/node-releases/-/node-releases-2.0.6.tgz", "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, @@ -5763,7 +5763,7 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "engines": { @@ -5772,7 +5772,7 @@ }, "node_modules/object.assign": { "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/object.assign/-/object.assign-4.1.4.tgz", "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { @@ -5943,13 +5943,13 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/picocolors/-/picocolors-1.0.0.tgz", "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, @@ -5985,7 +5985,7 @@ }, "node_modules/prettier": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/prettier/-/prettier-2.8.1.tgz", "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "dev": true, "bin": { @@ -6074,13 +6074,13 @@ }, "node_modules/regenerate": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regenerate/-/regenerate-1.4.2.tgz", "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "dev": true }, "node_modules/regenerate-unicode-properties": { "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", "dev": true, "dependencies": { @@ -6092,13 +6092,13 @@ }, "node_modules/regenerator-runtime": { "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, "node_modules/regenerator-transform": { "version": "0.15.0", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regenerator-transform/-/regenerator-transform-0.15.0.tgz", "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", "dev": true, "dependencies": { @@ -6107,7 +6107,7 @@ }, "node_modules/regexpu-core": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regexpu-core/-/regexpu-core-5.2.1.tgz", "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", "dev": true, "dependencies": { @@ -6124,13 +6124,13 @@ }, "node_modules/regjsgen": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.7.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regjsgen/-/regjsgen-0.7.1.tgz", "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==", "dev": true }, "node_modules/regjsparser": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/regjsparser/-/regjsparser-0.9.1.tgz", "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", "dev": true, "dependencies": { @@ -6142,7 +6142,7 @@ }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, "bin": { @@ -6160,7 +6160,7 @@ }, "node_modules/resolve": { "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dev": true, "dependencies": { @@ -6247,7 +6247,7 @@ }, "node_modules/semver": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { @@ -6410,7 +6410,7 @@ }, "node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { @@ -6422,7 +6422,7 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "engines": { @@ -6451,7 +6451,7 @@ }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, "engines": { @@ -6557,7 +6557,7 @@ }, "node_modules/typescript": { "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/typescript/-/typescript-5.4.5.tgz", "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, "bin": { @@ -6586,7 +6586,7 @@ }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", "dev": true, "engines": { @@ -6595,7 +6595,7 @@ }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "dev": true, "dependencies": { @@ -6608,7 +6608,7 @@ }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", "dev": true, "engines": { @@ -6617,7 +6617,7 @@ }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "dev": true, "engines": { @@ -6626,7 +6626,7 @@ }, "node_modules/update-browserslist-db": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "resolved": "https://cplace.jfrog.io/artifactory/api/npm/cplace-npm/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "dependencies": {