diff --git a/src/main/webui/.eslintignore b/src/main/webui/.eslintignore index 55af28b..35c3afb 100644 --- a/src/main/webui/.eslintignore +++ b/src/main/webui/.eslintignore @@ -1,5 +1,6 @@ **/*.css **/*.json **/*.ico +**/*.bak **/index.html **/README.md diff --git a/src/main/webui/package.json b/src/main/webui/package.json index f46df2e..82feadc 100644 --- a/src/main/webui/package.json +++ b/src/main/webui/package.json @@ -72,7 +72,7 @@ "dev": "webpack-dev-server --open --hot", "lint": "eslint './src/**'", "lint-fix": "eslint './src/**' --fix", - "server": "npm run build-dev && nodemon src/server/app.js --exec babel-node --presets @babel/preset-env", + "server": "nodemon src/server/app.js --exec babel-node --presets @babel/preset-env", "test": "NODE_ENV=test jest" } } diff --git a/src/main/webui/src/app/components/content/Main.jsx b/src/main/webui/src/app/components/content/Main.jsx index 80e30fe..d68fec5 100644 --- a/src/main/webui/src/app/components/content/Main.jsx +++ b/src/main/webui/src/app/components/content/Main.jsx @@ -63,8 +63,6 @@ export const Main = () => } /> { // - // - // } ; diff --git a/src/main/webui/src/app/components/content/addons/Cache.jsx b/src/main/webui/src/app/components/content/addons/Cache.jsx index 89efbae..9adfa67 100644 --- a/src/main/webui/src/app/components/content/addons/Cache.jsx +++ b/src/main/webui/src/app/components/content/addons/Cache.jsx @@ -63,7 +63,7 @@ export default function Cache() { (Can be a full or a relative url like "/api/content/maven/group/central/org/foo/bar/maven-metadata.xml. Be noticed that this will trigger the deletions of the target path from all affected groups.") - {errors.path?.type === "required" && Metadata url is required} + {errors.path?.type === "required" && Metadata url is required}
diff --git a/src/main/webui/src/app/components/content/addons/NFC.jsx b/src/main/webui/src/app/components/content/addons/NFC.jsx index 68b7653..8c226ce 100644 --- a/src/main/webui/src/app/components/content/addons/NFC.jsx +++ b/src/main/webui/src/app/components/content/addons/NFC.jsx @@ -14,8 +14,326 @@ * limitations under the License. */ -import React from 'react'; +import React, {useState, useEffect, useRef, Fragment} from 'react'; +import {LoadingSpiner} from '../common/LoadingSpiner.jsx'; +import {IndyRest} from '#utils/RestClient.js'; +import {Utils} from '#utils/AppUtils.js'; + +const {storeQueryRes, nfcRes} = IndyRest; export default function NFC() { - return
This is not implemented yet!
; + const [nfcStoreKeys, setNfcStoreKeys] = useState([]); + const [message, setMessage] = useState(''); + const [error, setError] = useState(''); + const [currentKey, setCurrentKey] = useState(""); + const [sections, setSections] = useState([]); + const pageSizes = [10, 50, 100]; + const page = useRef({ + index: 0, + size: pageSizes[0] + }); + const [prevDisabled, setPrevDisabled] = useState(true); + const [paginationHidden, setPagginationHidden] = useState(true); + const [isShowAll, setShowAll] = useState(true); + const [loading, setLoading] = useState(false); + const [loadingSection, setLoadingSection] = useState(false); + + const updatePage = partialPage => { + const newPage = Utils.cloneObj(page.current); + for (let key in partialPage) { + if (Object.hasOwn(partialPage, key)){ + newPage[key] = partialPage[key]; + } + } + page.current = newPage; + }; + useEffect(()=>{ + setLoadingSection(true); + (async () =>{ + const res = await storeQueryRes.getEndpoints("all"); + if (res.success){ + const raw = await res.result; + const allKeys = raw.items.filter(item=>item.type!=="group").map(item=>item.key); + setNfcStoreKeys(allKeys); + setLoadingSection(false); + }else{ + setError(res.error.message); + } + })(); + }, []); + + const clearMessage = () => { + setMessage(''); + setError(''); + }; + + const labelSections = secs => { + secs.forEach(s => { + s.label = Utils.keyLabel(s.key); + s.paths.sort(); + }); + }; + + const showSection = e => { + const selectKey = e.target.value; + if (!selectKey){ + return; + } + clearMessage(); + setCurrentKey(selectKey); + setPagginationHidden(true); + setLoading(true); + const [packageType, type, name] = selectKey.split(':'); + setSections([]); + (async ()=> { + const resp = await nfcRes.get(packageType, type, name, ""); + if(resp.success){ + if(resp.result && resp.result.sections !== undefined){ + labelSections(resp.result.sections); + setSections(Utils.sortByEmbeddedKey(resp.result.sections)); + setShowAll(false); + } + } + setLoading(false); + })(); + }; + + const showAll = e => { + e.preventDefault(); + clearMessage(); + const [index, size] = [page.current.index, page.current.size]; + setPagginationHidden(false); + setLoading(true); + setSections([]); + (async ()=> { + const resp = await nfcRes.query(index, size); + if(resp.success){ + if(resp.result && resp.result.sections !== undefined){ + labelSections(resp.result.sections); + setSections(Utils.sortByEmbeddedKey(resp.result.sections)); + setShowAll(true); + setCurrentKey(""); + } + } + setLoading(false); + })(); + }; + + const clearAllNFC = e => { + e.preventDefault(); + (async () => { + const result = await nfcRes.deleteAll(); + if(result.success){ + setSections([]); + setPagginationHidden(true); + setMessage("All NFC entries cleared successfully."); + }else{ + Utils.logMessage(`Failed to clear all NFC! Error reason: ${result.error.message}`); + } + })(); + }; + + const clearSection = (section, secs) => { + setMessage(""); + let key = section.key; + // alert( "Clear all NFC entries for: " + key ); + + let name = Utils.nameFromKey(key); + let packageType = Utils.packageTypeFromKey(key); + let type = Utils.typeFromKey(key); + (async () => { + const result = await nfcRes.delete(packageType, type, name, ""); + if(result.success){ + setMessage(`Cleared NFC for ${key}`); + section.paths = []; + const index = secs.indexOf(section); + secs.splice(index, 1); + }else{ + setMessage(`Failed to clear NFC for ${key}`); + setError(result.error); + } + })(); + }; + + const clearSectionPath = (section, path) => { + const subPath = path.substring(1); + let key = section.key; + + // alert( "Clear all NFC entries for: " + key + ", path: " + path ); + + let name = Utils.nameFromKey(key); + let packageType = Utils.packageTypeFromKey(key); + let type = Utils.typeFromKey(key); + + (async () => { + const result = await nfcRes.delete(packageType, type, name, subPath); + if(result.success){ + setMessage(`Cleared NFC for ${key}, path: ${subPath}`); + let idx = section.paths.indexOf(subPath); + section.paths.splice(idx,1); + }else{ + setError(result.error); + } + })(); + }; + + const queryByPageIndexAndSize = (index, size) =>{ + setMessage(""); + setPagginationHidden(true); + setLoading(true); + setSections([]); + if (isShowAll){ + // alert( "showing all NFC entries"); + // delete $scope.currentKey; + (async () => { + const resp = await nfcRes.query(index, size); + if(resp.success){ + if (resp.result && resp.result.sections !== undefined){ + labelSections(resp.result.sections); + setSections(Utils.sortByEmbeddedKey(resp.result.sections)); + setPagginationHidden(false); + setPrevDisabled(index <= 0); + } + } + setLoading(false); + })(); + }else{ + const packageType = Utils.packageTypeFromKey(currentKey); + const type = Utils.typeFromKey(currentKey); + const name = Utils.nameFromKey(currentKey); + if (type !== undefined && name !== undefined){ + (async () => { + const resp = await nfcRes.get(packageType, type, name, "", index, size); + if(resp.success){ + if(resp.result && resp.result.sections !== undefined){ + labelSections(resp.result.sections); + setSections(Utils.sortByEmbeddedKey(resp.result.sections)); + setPagginationHidden(false); + // TODO: check if need to setCurrentKey here + setCurrentKey(Utils.formatKey(packageType, type, name)); + setPrevDisabled(index <= 0); + } + } + setLoading(false); + })(); + // alert( "showing NFC entries for: " + $scope.currentKey); + } + } + }; + const changePageSize = currentSize => { + updatePage({"size": currentSize, "index": 0}); + queryByPageIndexAndSize(page.current.index, page.current.size); + }; + const changePageNumber = e => { + if(e.keyCode === 13) { + const pageIndex = parseInt(e.target.value, 10); + updatePage({"index": pageIndex}); + queryByPageIndexAndSize(page.current.index, page.current.size); + } + }; + const prevPage = () => { + const [curIndex, curSize] = [page.current.index-1, page.current.size]; + queryByPageIndexAndSize(curIndex, curSize); + updatePage({"index": curIndex, "size": curSize}); + }; + const nextPage = () => { + const curIndex = page.current.index + 1; + queryByPageIndexAndSize(curIndex, page.current.size); + updatePage({"index": curIndex}); + }; + + const handleSearch = e => { + e.preventDefault(); + // TODO: not implemented yet! + }; + + return +
+ { + loadingSection && + } +
+ Not-Found Cache Entries for: +
+
+ {' '} +
+
+ + +
+
+
+ Search: +
+
+
+ Debug Data +
+
+
+ {loading && } + {message && message.trim() !== "" &&
{message}
} + {error && error.trim() !== "" &&
{error}
} + {(message && message.trim() !== "" || error && error.trim() !== "") &&
} + { + sections && sections.length > 0 && + + } + { + !paginationHidden &&
+   +     + { + !prevDisabled &&   + } +   + +
+ } +
+
; } diff --git a/src/main/webui/src/app/components/content/addons/NFC.test.jsx b/src/main/webui/src/app/components/content/addons/NFC.test.jsx new file mode 100644 index 0000000..1d59b9f --- /dev/null +++ b/src/main/webui/src/app/components/content/addons/NFC.test.jsx @@ -0,0 +1,130 @@ +/** + * Copyright (C) 2023 Red Hat, Inc. (https://github.com/Commonjava/indy-ui-service) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from "react"; +import {render, screen, cleanup, waitFor, within} from '@testing-library/react'; +import userEvent from "@testing-library/user-event"; +import '@testing-library/jest-dom'; +import fetchMock from "fetch-mock"; +import NFC from "./NFC.jsx"; + +beforeEach(()=>{ + fetchMock.restore(); +}); + +afterEach(() => { + cleanup(); +}); + +const mockEndpoints = {items: [ + { + "packageType": "maven", + "name": "central", + "type": "remote", + "key": "maven:remote:central", + "storeKey": "maven:remote:central", + "storeType": "remote", + "resource_uri": "http://localhost:4000/api/content/maven/remote/central" + }, + { + "packageType": "maven", + "name": "public", + "type": "group", + "key": "maven:group:public", + "storeKey": "maven:group:public", + "storeType": "group", + "resource_uri": "http://localhost:4000/api/content/maven/group/public" + }, + { + "packageType": "maven", + "name": "tYMtROxQUA", + "type": "hosted", + "key": "maven:hosted:tYMtROxQUA", + "storeKey": "maven:hosted:tYMtROxQUA", + "storeType": "hosted", + "resource_uri": "http://localhost:4000/api/content/maven/hosted/tYMtROxQUA" + } +]}; + +const mockAllNFCItems = { + sections: [ + { + "key": "maven:remote:central", + "paths": [ + "/8852/5330", + "/5687/5449", + "/6781/5509" + ] + }, + { + "key": "maven:group:public", + "paths": [ + "/5071/7765", + "/9606/6819", + "/9647/3899", + "/2185/2201" + ] + }, + { + "key": "maven:hosted:tYMtROxQUA", + "paths": [ + "/4960/9412", + "/1687/3470", + "/2960/4280", + "/1140/8242", + "/8854/5915", + "/9425/1833", + "/8009/6333", + "/7481/6826", + "/3495/8758" + ] + } + ] +}; + +describe('NFC tests', () => { + it("Verify NFC", async () => { + const user = userEvent.setup(); + fetchMock.mock(`/api/admin/stores/query/endpoints/all`, {status: 200, body: JSON.stringify(mockEndpoints)}); + fetchMock.mock("/api/nfc?pageIndex=0&pageSize=10", {status: 200, body: JSON.stringify(mockAllNFCItems)}); + render(); + const nfcSelect = screen.getByRole("nfcSel"); + await waitFor(() => { + expect(nfcSelect).toHaveValue(""); + }); + const showAllButton = screen.getByRole("button", {name: "Show All"}); + + await waitFor(() => { + expect(screen.getByRole("option", {name: "central (remote; maven)"})).toBeInTheDocument(); + expect(showAllButton).toBeInTheDocument(); + }); + + await user.click(showAllButton); + await waitFor(() => { + let section = screen.getByRole("section-maven:remote:central"); + expect(section).toBeInTheDocument(); + expect(within(section).getByText("/8852/5330")).toBeInTheDocument(); + + section = screen.getByRole("section-maven:group:public"); + expect(section).toBeInTheDocument(); + expect(within(section).getByText("/5071/7765")).toBeInTheDocument(); + + section = screen.getByRole("section-maven:hosted:tYMtROxQUA"); + expect(section).toBeInTheDocument(); + expect(within(section).getByText("/9425/1833")).toBeInTheDocument(); + }); + }); +}); diff --git a/src/main/webui/src/app/components/content/common/PackageTypeSelect.jsx b/src/main/webui/src/app/components/content/common/PackageTypeSelect.jsx index 21f023c..219bcda 100644 --- a/src/main/webui/src/app/components/content/common/PackageTypeSelect.jsx +++ b/src/main/webui/src/app/components/content/common/PackageTypeSelect.jsx @@ -51,7 +51,7 @@ export const PackageTypeSelect = ({register, formErrors}) =>{ state.pkgTypes.map(type => ) } {' '} - {formErrors && formErrors.packageType?.type === "required" && Package Type is required} + {formErrors && formErrors.packageType?.type === "required" && Package Type is required} ; }; diff --git a/src/main/webui/src/app/components/content/common/PackageTypeSelect.test.jsx b/src/main/webui/src/app/components/content/common/PackageTypeSelect.test.jsx index 01cbd3a..a8a08f0 100644 --- a/src/main/webui/src/app/components/content/common/PackageTypeSelect.test.jsx +++ b/src/main/webui/src/app/components/content/common/PackageTypeSelect.test.jsx @@ -61,9 +61,7 @@ describe('PackageTypeSelect tests', () => { it("Verify PackageTypeSelect for value change", async ()=>{ const {selectOptions} = userEvent.setup(); - let value = ""; render(); - expect(value).toBe(""); await waitFor(() => { expect(screen.getByRole("pkgTypeSel")).toHaveValue(""); }); diff --git a/src/main/webui/src/app/components/content/hosted/HostedEdit.jsx b/src/main/webui/src/app/components/content/hosted/HostedEdit.jsx index 427463a..8c31943 100644 --- a/src/main/webui/src/app/components/content/hosted/HostedEdit.jsx +++ b/src/main/webui/src/app/components/content/hosted/HostedEdit.jsx @@ -159,8 +159,8 @@ export default function HostedEdit() { {' '} - {errors.name?.type === "required" && Name is required} - {errors.name?.type === "maxLength" && Name's length should be less than 50} + {errors.name?.type === "required" && Name is required} + {errors.name?.type === "maxLength" && Name's length should be less than 50} : {store.name} } @@ -190,7 +190,7 @@ export default function HostedEdit() { {' '} - {errors.disable_timeout && Not a valid number}
+ {errors.disable_timeout && Not a valid number}
diff --git a/src/main/webui/src/app/components/content/remote/RemoteEdit.jsx b/src/main/webui/src/app/components/content/remote/RemoteEdit.jsx index 631cc46..59cb92f 100644 --- a/src/main/webui/src/app/components/content/remote/RemoteEdit.jsx +++ b/src/main/webui/src/app/components/content/remote/RemoteEdit.jsx @@ -132,8 +132,8 @@ export default function RemoteEdit() { {' '} - {errors.name?.type === "required" && Name is required} - {errors.name?.type === "maxLength" && Name's length should be less than 50} + {errors.name?.type === "required" && Name is required} + {errors.name?.type === "maxLength" && Name's length should be less than 50} : {store.name} } @@ -158,7 +158,7 @@ export default function RemoteEdit() { {' '} - {errors.disable_timeout && Not a valid number}
+ {errors.disable_timeout && Not a valid number}
@@ -167,8 +167,8 @@ export default function RemoteEdit() { {' '} - {errors.url?.type==="required" && Remote URL is required} - {errors.url?.type==="pattern" && Not a valid URL} + {errors.url?.type==="required" && Remote URL is required} + {errors.url?.type==="pattern" && Not a valid URL}
diff --git a/src/main/webui/src/app/components/styles/indy.css b/src/main/webui/src/app/components/styles/indy.css index cd4b900..4283868 100644 --- a/src/main/webui/src/app/components/styles/indy.css +++ b/src/main/webui/src/app/components/styles/indy.css @@ -442,8 +442,8 @@ label, .label{ } .pagination{ - float: right; - margin-bottom: 6px; + float: right; + margin-bottom: 6px; } .loader { @@ -455,6 +455,6 @@ label, .label{ box-sizing: border-box; } -.alert { +.indy-alert { color: red; } \ No newline at end of file diff --git a/src/main/webui/src/app/utils/AppUtils.js b/src/main/webui/src/app/utils/AppUtils.js index dab87dc..6d0468e 100644 --- a/src/main/webui/src/app/utils/AppUtils.js +++ b/src/main/webui/src/app/utils/AppUtils.js @@ -196,5 +196,43 @@ export const Utils = { desc = 'No description provided.'; } return desc; - } + }, + formatKey: (packageType, type, name)=>`${packageType}:${type}:${name}`, + keyLabel: key => { + const parts = key.split(':'); + return parts[2] + " (" + parts[1] + "; " + parts[0] + ")"; + }, + // Sort by: type (group, remote, hosted), packageType, name + sortByEmbeddedKey: items => { + if (items === undefined){ + return items; + } + + const typeOrder = ['group', 'remote', 'hosted']; + return items.sort((a, b) =>{ + const ap = a.key.split(':'); + const bp = b.key.split(':'); + + const ati = typeOrder.indexOf(ap[1]); + const bti = typeOrder.indexOf(bp[1]); + + if (ati !== bti){ + return ati < bti ? -1 : 1; + } + + if (ap[0] < bp[0]){ + return -1; + }else if (bp[0] < ap[0]){ + return 1; + } + + if (ap[2] < bp[2]){ + return -1; + }else if (bp[2] < ap[2]){ + return 1; + } + + return 0; + }); + }, }; diff --git a/src/main/webui/src/app/utils/RestClient.js b/src/main/webui/src/app/utils/RestClient.js index 16227d5..35353b4 100644 --- a/src/main/webui/src/app/utils/RestClient.js +++ b/src/main/webui/src/app/utils/RestClient.js @@ -45,6 +45,30 @@ const jsonRest ={ const BASE_STORE_API_PATH = "/api/admin/stores"; const storeAPIEndpoint = (pkgType, type, name) => `${BASE_STORE_API_PATH}/${pkgType}/${type}/${name}`; +const BASE_NFC_API_PATH = "/api/nfc"; +const nfcAPIEndpoint = (pkgType, type, name, path) => { + let result = `${BASE_NFC_API_PATH}/${pkgType}/${type}/${name}`; + if(path.trim() !== ""){ + const encodedPath = encodeURIComponent(path); + result += `/${encodedPath}`; + } + return result; +}; + +const genPageParam = (index, size) => { + let queryParam = ""; + if(index >= 0) { + queryParam = `pageIndex=${index}`; + } + if(size > 0){ + if(queryParam.length > 0){ + queryParam += `&`; + } + queryParam += `pageSize=${size}`; + } + return queryParam; +}; + const handleResponse = async response => { if (response.ok){ let result = {}; @@ -147,7 +171,35 @@ const IndyRest = { const response = await jsonRest.get('/api/admin/auth/userinfo'); return handleResponse(response); } - } + }, + nfcRes: { + query: async (index, size) => { + const queryParam = genPageParam(index,size); + let apiPath = `${BASE_NFC_API_PATH}`; + if(queryParam.length > 0){ + apiPath += `?${queryParam}`; + } + const response = await jsonRest.get(`${apiPath}`); + return handleResponse(response); + }, + get: async (pkgType, type, name, path, index, size) => { + const queryParam = genPageParam(index,size); + let apiPath = nfcAPIEndpoint(pkgType, type, name, path); + if(queryParam.length > 0){ + apiPath += `?${queryParam}`; + } + const response = await jsonRest.get(apiPath); + return handleResponse(response); + }, + deleteAll: async () => { + const response = await http.delete(`${BASE_NFC_API_PATH}`); + return handleResponse(response); + }, + delete: async (pkgType, type, name, path) => { + const response = await http.delete(nfcAPIEndpoint(pkgType, type, name, path)); + return handleResponse(response); + } + }, }; export {IndyRest, BASE_STORE_API_PATH}; diff --git a/src/main/webui/src/server/app.js b/src/main/webui/src/server/app.js index af8893b..881a180 100644 --- a/src/main/webui/src/server/app.js +++ b/src/main/webui/src/server/app.js @@ -20,6 +20,8 @@ const server = app.listen(Config.SERVER_PORT, () => { }); app.use(express.static('dist')); +const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); + // For direct url bar addressing, will send home page directly for client router rendering app.get([Config.APP_ROOT, `${Config.APP_ROOT}/*`, '/'], (req, res) => { res.sendFile(indexHtml); @@ -48,7 +50,8 @@ app.get('/api/stats/all-endpoints', (req, res) => { // stats APIs end // endpoints and storekeys -app.get('/api/admin/stores/query/endpoints/:packageType', (req, res) => { +app.get('/api/admin/stores/query/endpoints/:packageType', async (req, res) => { + await sleep(2000); const [pkgType] = [req.params.packageType]; const statsEndpointsFile = path.resolve(__dirname, `./mock/list/FakeAllEndPoints.json`); const list = require(statsEndpointsFile); @@ -87,8 +90,6 @@ const decideMockListFile = (packgeType, type) => { }; -const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - // For store listing app.get(`${STORE_API_BASE}/:packageType/:type`, async (req, res) => { await sleep(2000); @@ -195,3 +196,58 @@ app.get('/api/admin/auth/userinfo', (req, res) => { const testUser = {userName: "indy", roles: ["admin", "power-user", "user"]}; res.status(200).json(testUser); }); + +// Mock NFC APIs +app.get(`/api/nfc/:packageType/:type/:name`, async (req, res) => { + await sleep(2000); + const [pkgType, type, name] = [req.params.packageType, req.params.type, req.params.name]; + const storeKey = `${pkgType}:${type}:${name}`; + console.log(`Fetching nfc for ${storeKey}`); + const allNFCItems = require('./mock/list/FakeNFCItems.json'); + const nfcItems = allNFCItems.sections.filter(s=>s.key===storeKey); + console.log(`Returning nfc items for ${storeKey}: ${nfcItems}`); + const result = { + sections: nfcItems + }; + res.status(200).json(result); +}); + +app.get('/api/nfc', async (req, res) => { + await sleep(2000); + const [pageIndex, pageSize] = [req.query.pageIndex, req.query.pageSize]; + const allNFCItems = require('./mock/list/FakeNFCItems.json'); + allNFCItems.sections.sort(); + if(pageIndex && pageSize){ + let [start, size] = [parseInt(pageIndex, 10), parseInt(pageSize, 10)]; + let end = start+size; + const sections = allNFCItems.sections; + if(end > sections.length){ + end = sections.length; + } + const result = { + sections: allNFCItems.sections.slice(start, end) + }; + res.status(200).json(result); + }else{ + res.status(200).json(allNFCItems); + } +}); + +app.delete('/api/nfc', (req, res)=>{ + console.log("Deleting all nfc setcions"); + res.status(204).json({"msg": "All sections deleted"}); +}); + +app.delete(`/api/nfc/:packageType/:type/:name`, (req, res) => { + const [pkgType, type, name] = [req.params.packageType, req.params.type, req.params.name]; + const storeKey = `${pkgType}:${type}:${name}`; + console.log(`Deleting nfc for section ${storeKey}`); + res.status(204).json({"msg": "section deleted"}); +}); + +app.delete(`/api/nfc/:packageType/:type/:name/:path`, (req, res) => { + const [pkgType, type, name, nfcPath] = [req.params.packageType, req.params.type, req.params.name, req.params.path]; + const storeKey = `${pkgType}:${type}:${name}`; + console.log(`Deleting nfc path ${nfcPath} for ${storeKey}`); + res.status(204).json({"msg": "Path in section deleted"}); +}); diff --git a/src/main/webui/src/server/mock/list/FakeNFCItems.json b/src/main/webui/src/server/mock/list/FakeNFCItems.json new file mode 100644 index 0000000..712432e --- /dev/null +++ b/src/main/webui/src/server/mock/list/FakeNFCItems.json @@ -0,0 +1,1913 @@ +{ + "sections":[ + { + "key": "maven:group:build_org-keycloak-keycloak-parent-4-x_20180515.1724", + "paths": [ + "/7045/2311", + "/6607/7336", + "/6308/791", + "/833/7285", + "/211/4668", + "/4337/2074", + "/2967/6828", + "/1905/2667" + ] + }, + { + "key": "maven:group:build_org-keycloak-keycloak-parent-4-x_20180531.0218", + "paths": [ + "/4184/937", + "/4403/2420" + ] + }, + { + "key": "maven:group:build_org-keycloak-keycloak-nodejs-auth-utils-3-xnpm_1-2-stage-4_20180104.1216", + "paths": [ + "/884/2478", + "/3933/1959", + "/3851/8130", + "/7357/5585", + "/159/1806", + "/6702/5613" + ] + }, + { + "key": "maven:group:build_vertx-infinispan-3-5-1_20180705.1313", + "paths": [ + "/3747/1062", + "/5989/1327", + "/8487/7893", + "/6434/3515" + ] + }, + { + "key": "maven:group:public", + "paths": [ + "/5071/7765", + "/9606/6819", + "/9647/3899", + "/2185/2201" + ] + }, + { + "key": "maven:hosted:FisZYfNgpR", + "paths": [ + "/7541/6638", + "/1843/2390", + "/5382/8116", + "/8569/7908", + "/6127/9393", + "/333/8221", + "/5357/204", + "/3282/9908", + "/4257/9673" + ] + }, + { + "key": "maven:hosted:tYMtROxQUA", + "paths": [ + "/4960/9412", + "/1687/3470", + "/2960/4280", + "/1140/8242", + "/8854/5915", + "/9425/1833", + "/8009/6333", + "/7481/6826", + "/3495/8758" + ] + }, + { + "key": "maven:hosted:LYnrVCMAZP", + "paths": [ + "/8580/9454", + "/5024/7120", + "/9500/9566" + ] + }, + { + "key": "maven:hosted:build_kie-soup_20180628.0657", + "paths": [ + "/5077/9078", + "/8247/290", + "/8927/8530", + "/9149/5895", + "/1164/2209", + "/6663/4733", + "/3880/214" + ] + }, + { + "key": "maven:remote:central", + "paths": [ + "/8852/5330", + "/5687/5449", + "/6781/5509" + ] + }, + { + "key": "maven:remote:i-maven-restlet-4", + "paths": [ + "/4080/972", + "/4409/1410", + "/9726/643", + "/3016/8850", + "/4420/2007", + "/3667/1977", + "/618/5355" + ] + }, + { + "key": "maven:remote:mrrc-ga", + "paths": [ + "/9698/9050", + "/888/1548", + "/8964/2527", + "/9809/3278", + "/7962/8260" + ] + }, + { + "key": "maven:remote:repo.eclipse.org", + "paths": [] + }, + { + "key": "maven:remote:microprofile.repo.eclipse.org", + "paths": [] + }, + { + "key": "maven:remote:japidiff", + "paths": [ + "/1640/7396", + "/3562/9538", + "/1953/9558", + "/9536/1142", + "/964/7177", + "/4592/6827" + ] + }, + { + "key": "maven:remote:spring-plugins-snapshot", + "paths": [] + }, + { + "key": "maven:remote:sonatype-snapshots", + "paths": [ + "/5487/6422", + "/1835/1461", + "/1545/4789", + "/8588/9113", + "/9905/1789", + "/61/4934", + "/6239/8484" + ] + }, + { + "key": "maven:remote:snapshots", + "paths": [ + "/5437/6917", + "/4124/1403", + "/674/7716", + "/3373/3110", + "/6068/2136", + "/3380/4919", + "/212/7310", + "/2086/4811", + "/7137/86" + ] + }, + { + "key": "maven:remote:apache.snapshots", + "paths": [ + "/1494/2689", + "/1012/7775" + ] + }, + { + "key": "maven:remote:repository.jboss.com", + "paths": [ + "/9809/1735", + "/6647/6556", + "/2796/4724", + "/1900/3102", + "/5350/8259" + ] + }, + { + "key": "maven:remote:eclipse.m2", + "paths": [ + "/4069/819", + "/2897/832", + "/4688/207", + "/3175/7070", + "/5887/9431", + "/4599/1725" + ] + }, + { + "key": "maven:remote:snmp4j.repo", + "paths": [ + "/877/1285", + "/7511/193" + ] + }, + { + "key": "npm:group:DA-temporary-builds", + "paths": [ + "/2532/5485" + ] + }, + { + "key": "npm:group:build-172077677927211008", + "paths": [ + "/3795/6847", + "/5177/3262", + "/8151/6912", + "/7851/7836", + "/473/700" + ] + }, + { + "key": "npm:group:DA", + "paths": [ + "/7120/66", + "/5917/525" + ] + }, + { + "key": "npm:group:builds-untested+shared-imports", + "paths": [ + "/94/6225", + "/9872/6069", + "/3669/6534" + ] + }, + { + "key": "npm:group:builds-untested+shared-imports+public", + "paths": [ + "/5419/3179" + ] + }, + { + "key": "npm:group:DApublic", + "paths": [ + "/5934/1785", + "/7180/97", + "/5531/1512", + "/9666/6277", + "/283/8396", + "/2382/1541" + ] + }, + { + "key": "npm:group:build-A4RWJFXAWIAAA", + "paths": [ + "/6857/2411", + "/6053/2969" + ] + }, + { + "key": "npm:group:public", + "paths": [] + }, + { + "key": "npm:group:shared-imports+public", + "paths": [ + "/4727/4729", + "/1768/3557" + ] + }, + { + "key": "npm:group:build-A4SLH57TGIAAA", + "paths": [ + "/5602/4442", + "/6855/3009", + "/3756/231", + "/6151/5530" + ] + }, + { + "key": "npm:group:temporary-builds", + "paths": [ + "/730/813", + "/7673/9931", + "/3031/9943", + "/787/621", + "/8709/8731", + "/9130/3457" + ] + }, + { + "key": "npm:group:build-175689795468152832", + "paths": [ + "/4489/46", + "/8604/9060", + "/7741/877", + "/610/3812", + "/9103/3664", + "/9313/9351" + ] + }, + { + "key": "npm:group:build-175645950118350848", + "paths": [ + "/7320/7340", + "/7020/2412" + ] + }, + { + "key": "npm:group:build-A4SLDYLJGIAAA", + "paths": [ + "/3643/8688", + "/5951/7721", + "/469/4289" + ] + }, + { + "key": "npm:group:shared-imports+yarn-public", + "paths": [ + "/8981/625", + "/8026/1119", + "/9135/2008" + ] + }, + { + "key": "npm:group:build-172056280052015104", + "paths": [ + "/3533/1554", + "/9637/9139", + "/2634/8178", + "/9194/5170", + "/6130/2956", + "/937/5879", + "/5925/8665" + ] + }, + { + "key": "npm:group:builds-untested", + "paths": [ + "/2152/8121", + "/3686/3320", + "/4418/8988", + "/5210/1200", + "/2973/3302", + "/2046/9995" + ] + }, + { + "key": "npm:group:yarn-public", + "paths": [ + "/6883/9086", + "/2452/8206", + "/6592/6326", + "/1749/8920", + "/7765/634", + "/5626/8808" + ] + }, + { + "key": "npm:hosted:build-1039", + "paths": [ + "/7366/9797", + "/1715/8308", + "/9955/8753", + "/1173/6058", + "/7706/9953", + "/47/9725", + "/1670/8546", + "/2398/5207" + ] + }, + { + "key": "npm:hosted:build-1545", + "paths": [ + "/8571/7507", + "/3284/6197" + ] + }, + { + "key": "npm:hosted:build-ARH4LMNVUVQAA", + "paths": [ + "/8040/9846", + "/9935/4552", + "/3317/4077", + "/1180/3821", + "/9844/2167" + ] + }, + { + "key": "npm:hosted:build-ATMXTBCK2JIAA", + "paths": [ + "/5692/2953", + "/6638/6050", + "/9228/7401", + "/4208/8100", + "/1033/9842", + "/2555/8480", + "/1665/5568", + "/7998/1822", + "/4652/9760" + ] + }, + { + "key": "npm:hosted:build-ATKLVX3EKJIAA", + "paths": [ + "/7281/5044", + "/9147/5255", + "/8425/2648", + "/9262/1995", + "/9849/806", + "/4151/6608", + "/2253/4514", + "/4443/8784", + "/5788/9332" + ] + }, + { + "key": "npm:hosted:build-1751", + "paths": [ + "/5805/3267", + "/1386/4687", + "/7528/6687", + "/27/7292", + "/8250/1508", + "/2789/4885", + "/9947/7134", + "/3492/6033" + ] + }, + { + "key": "npm:hosted:build-172056280052015104", + "paths": [ + "/8691/9175", + "/8094/1194" + ] + }, + { + "key": "npm:hosted:build-ATIPTNJS4TIAA", + "paths": [ + "/40/5502", + "/4830/9390", + "/9239/2535", + "/3443/3372", + "/6421/8472" + ] + }, + { + "key": "npm:hosted:build-A4RWJFXAWIAAA", + "paths": [ + "/4466/3948", + "/7240/9489", + "/2628/3016", + "/7515/9261", + "/2000/1139", + "/8605/1663", + "/7237/9386", + "/9390/6686", + "/4862/7377" + ] + }, + { + "key": "npm:hosted:build-1318", + "paths": [ + "/2462/7485", + "/674/7204", + "/815/1361" + ] + }, + { + "key": "npm:hosted:shared-imports", + "paths": [ + "/7435/807", + "/2634/7315", + "/4710/8132", + "/9410/3637", + "/9291/5149", + "/1347/3965", + "/9051/4278" + ] + }, + { + "key": "npm:hosted:build-ATJMS5VM2JIAA", + "paths": [ + "/6478/3575", + "/5403/5068" + ] + }, + { + "key": "npm:hosted:build-ATJVTFPY2JIAA", + "paths": [ + "/1267/8161", + "/8585/258", + "/6081/8349", + "/2044/7296", + "/8451/2814", + "/2007/6289" + ] + }, + { + "key": "npm:hosted:build-1892", + "paths": [ + "/6014/5116", + "/7055/7188", + "/3556/3185", + "/9565/7162", + "/5426/4271", + "/5137/4781", + "/3953/9676" + ] + }, + { + "key": "npm:hosted:build-ANSJXFPXWUIAA", + "paths": [ + "/3248/676", + "/7731/9787", + "/9108/8995", + "/6919/6707", + "/9624/2504", + "/8122/4777", + "/3073/5071", + "/9900/2138", + "/9184/4346" + ] + }, + { + "key": "npm:hosted:build-ATM6LQ22CJIAA", + "paths": [] + }, + { + "key": "npm:hosted:build-ATJEAVIZYHIAA", + "paths": [ + "/7218/5841", + "/9869/873" + ] + }, + { + "key": "npm:hosted:build-ANW6HFU3Y3AAA", + "paths": [ + "/1869/6734", + "/4186/7624", + "/9289/3926", + "/5908/418", + "/19/8903", + "/7733/7094", + "/3328/2604", + "/6217/3960", + "/6692/4920" + ] + }, + { + "key": "npm:hosted:build-A4SK7ID3WIAAA", + "paths": [ + "/5025/409", + "/240/7555", + "/7429/4259", + "/8115/1398", + "/9828/8498", + "/5514/8589" + ] + }, + { + "key": "npm:hosted:build-ASJNWOAV2MQAA", + "paths": [ + "/5455/1996", + "/2148/4045", + "/1703/2169", + "/2290/3783" + ] + }, + { + "key": "npm:hosted:build-177728051542118400", + "paths": [ + "/8741/101", + "/9597/6115", + "/75/1146", + "/7240/7552", + "/3679/7627", + "/2114/4608" + ] + }, + { + "key": "npm:hosted:build-ASE5VFCHXYIAA", + "paths": [ + "/7333/7332", + "/7627/1315", + "/2412/3561", + "/61/8843", + "/853/6435", + "/8356/8774", + "/155/9193" + ] + }, + { + "key": "npm:hosted:build-1915", + "paths": [ + "/1352/8449", + "/1926/4166", + "/8595/829", + "/2063/3919", + "/5862/4623", + "/3419/4920", + "/2316/7720", + "/188/6402", + "/4162/6088" + ] + }, + { + "key": "npm:hosted:build-AUS2H4JNNWIAA", + "paths": [ + "/3434/5497", + "/1043/1269", + "/7394/5209", + "/2711/8158", + "/9335/8377", + "/8397/1743" + ] + }, + { + "key": "npm:hosted:build-1726", + "paths": [ + "/1640/2534", + "/6483/3469", + "/6031/7906", + "/6625/7475", + "/4565/3227", + "/742/3015", + "/9839/9032", + "/2860/5064" + ] + }, + { + "key": "npm:hosted:build-1393", + "paths": [ + "/514/8902", + "/1537/8107", + "/777/6694", + "/289/1073", + "/3083/2577", + "/7105/7506" + ] + }, + { + "key": "npm:hosted:build-1918", + "paths": [] + }, + { + "key": "npm:hosted:build-ANSHZIJ2WUIAA", + "paths": [ + "/6711/260", + "/8061/7994" + ] + }, + { + "key": "npm:hosted:build-ANSC3XNBIJYAA", + "paths": [ + "/2103/5271", + "/5093/6122", + "/3642/5495", + "/9321/7848", + "/982/3839", + "/2394/7618" + ] + }, + { + "key": "npm:hosted:build-ATKLTMUYKJIAA", + "paths": [ + "/9106/5185", + "/1264/9234", + "/8081/6919" + ] + }, + { + "key": "npm:hosted:build-ATJVZRQA2JIAA", + "paths": [ + "/5664/7303", + "/9531/3855", + "/6889/418", + "/4832/3089" + ] + }, + { + "key": "npm:hosted:build-ANSDID7VAJYAA", + "paths": [] + }, + { + "key": "npm:hosted:build-1753", + "paths": [ + "/7828/113", + "/5130/4531", + "/1053/4432" + ] + }, + { + "key": "npm:hosted:build-ANWPAJ33IEQAA", + "paths": [ + "/4113/3700", + "/8757/828", + "/4349/8003", + "/7147/4678", + "/787/924", + "/3836/5182" + ] + }, + { + "key": "npm:hosted:build-ATSAZTZKHQAAA", + "paths": [ + "/597/8052", + "/4762/56", + "/1018/9904", + "/3429/9827", + "/8792/6756", + "/1678/5020", + "/2563/4432", + "/4143/6586" + ] + }, + { + "key": "npm:hosted:build-1325", + "paths": [ + "/3034/5040", + "/9662/6070" + ] + }, + { + "key": "npm:hosted:build-1403", + "paths": [ + "/7518/9829", + "/9919/738", + "/2861/7632" + ] + }, + { + "key": "npm:hosted:build-1908", + "paths": [ + "/1339/6792", + "/3390/6982", + "/5157/3055", + "/7272/35", + "/5981/2542", + "/2794/398", + "/9055/3232", + "/2392/913", + "/4190/249" + ] + }, + { + "key": "npm:hosted:build-ATMXX5UNCJIAA", + "paths": [ + "/1616/6354", + "/9626/9828", + "/9118/322" + ] + }, + { + "key": "npm:hosted:build-ATJVZHAOSJIAA", + "paths": [ + "/7958/9283", + "/2614/5936", + "/1213/6894", + "/3481/3259", + "/7087/8271", + "/610/1333" + ] + }, + { + "key": "npm:hosted:build-ATKLN4KE2JIAA", + "paths": [ + "/9664/8071", + "/829/1391", + "/2572/4928", + "/2320/5577", + "/9265/360", + "/1715/1408" + ] + }, + { + "key": "npm:hosted:build-ATJBPKAUIHIAA", + "paths": [ + "/2388/6544" + ] + }, + { + "key": "npm:hosted:build-AUSSLL6X5WIAA", + "paths": [] + }, + { + "key": "npm:hosted:build-ATJV3HRICJIAA", + "paths": [] + }, + { + "key": "npm:hosted:build-1725", + "paths": [] + }, + { + "key": "npm:hosted:build-162851312008671232", + "paths": [ + "/841/8684", + "/845/9655", + "/4369/5577", + "/9071/7000", + "/5127/7946", + "/6979/1622", + "/5239/1888", + "/7134/4518", + "/8285/8989" + ] + }, + { + "key": "npm:hosted:build-ATIMRBRAMTIAA", + "paths": [ + "/2038/1853", + "/2491/7428", + "/2116/4192" + ] + }, + { + "key": "npm:hosted:build-1255", + "paths": [ + "/4744/3421", + "/2614/1160", + "/3061/9047" + ] + }, + { + "key": "npm:hosted:build-1471", + "paths": [ + "/6542/4313", + "/5011/2866", + "/334/356", + "/8906/530", + "/896/8002", + "/2915/4057", + "/9232/7390" + ] + }, + { + "key": "npm:hosted:build-1537", + "paths": [ + "/6969/2663", + "/4715/5023", + "/9177/8061", + "/9569/5914" + ] + }, + { + "key": "npm:hosted:build-ALNRDMIQY7QAA", + "paths": [] + }, + { + "key": "npm:hosted:build-ANSJXYBWOUIAA", + "paths": [ + "/9236/6613", + "/5886/5751", + "/7376/9518", + "/2869/6558", + "/6518/2745" + ] + }, + { + "key": "npm:hosted:build-850", + "paths": [] + }, + { + "key": "npm:hosted:build-ANSJYI4V6UIAA", + "paths": [ + "/2088/5222", + "/9137/5512", + "/4801/5744", + "/3277/2873", + "/2446/4701", + "/4156/6649", + "/7405/1121" + ] + }, + { + "key": "npm:hosted:build-ATJVU4NKCJIAA", + "paths": [ + "/3614/2561", + "/6462/2127", + "/5561/4832", + "/6803/8661", + "/8667/7716", + "/7680/2946", + "/7329/534", + "/2103/9142" + ] + }, + { + "key": "npm:hosted:build-1081", + "paths": [ + "/1432/7678" + ] + }, + { + "key": "npm:hosted:build-ATSAH55UPQAAA", + "paths": [ + "/261/5896", + "/9235/981", + "/5728/2967", + "/5929/1503", + "/4715/8313" + ] + }, + { + "key": "npm:hosted:build-1961", + "paths": [ + "/233/5567", + "/1150/2992" + ] + }, + { + "key": "npm:hosted:build-1302", + "paths": [ + "/6428/8891", + "/2252/6592", + "/4104/9200", + "/3231/3756", + "/4590/1587", + "/566/1303", + "/2374/2811", + "/5495/8175" + ] + }, + { + "key": "npm:hosted:build-1714", + "paths": [ + "/4786/8198", + "/1848/3316", + "/3136/1268", + "/7155/6406", + "/1373/7627" + ] + }, + { + "key": "npm:hosted:build-1780", + "paths": [ + "/7682/3146", + "/867/6529", + "/6690/6736", + "/6711/9153", + "/7779/6830" + ] + }, + { + "key": "npm:hosted:build-1397", + "paths": [ + "/165/135", + "/2080/5820", + "/4992/7631", + "/8943/9160", + "/442/9855", + "/7896/7750", + "/133/8997", + "/5119/1354", + "/6513/7799" + ] + }, + { + "key": "npm:hosted:build-1007", + "paths": [ + "/8104/6197", + "/7066/3629" + ] + }, + { + "key": "npm:hosted:build-1128", + "paths": [ + "/5006/8730", + "/1568/6018", + "/9665/1176" + ] + }, + { + "key": "npm:hosted:build-174864544753614848", + "paths": [ + "/5477/4631", + "/884/3081", + "/852/7358", + "/817/6218", + "/7573/971", + "/2300/5125", + "/8009/1477", + "/3617/3146" + ] + }, + { + "key": "npm:hosted:build-1309", + "paths": [ + "/7050/8234", + "/3339/209", + "/5276/1922", + "/4288/1376", + "/2470/14" + ] + }, + { + "key": "npm:hosted:build-ATI7SHYMQHIAA", + "paths": [ + "/1778/9925", + "/7491/9308", + "/5483/1679", + "/4923/7673" + ] + }, + { + "key": "npm:hosted:build-ALNRRNKMA7QAA", + "paths": [ + "/1433/2130", + "/4476/615", + "/5976/9864", + "/2928/5219", + "/4147/8670", + "/2822/5688" + ] + }, + { + "key": "npm:hosted:build-1788", + "paths": [ + "/4644/9686", + "/2052/3553", + "/4791/5024", + "/3333/6380", + "/5356/916", + "/1605/6810", + "/7903/9070", + "/2958/1861" + ] + }, + { + "key": "npm:hosted:build-ATKLUBI5KJIAA", + "paths": [ + "/9164/5841", + "/5008/6385", + "/3493/9524", + "/4989/6031", + "/7989/2740" + ] + }, + { + "key": "npm:hosted:build-ATMUGZX4KJIAA", + "paths": [ + "/2721/5045", + "/9281/1871", + "/1855/3741", + "/8809/710", + "/6597/546" + ] + }, + { + "key": "npm:hosted:build-A4RWOQJKGIAAA", + "paths": [ + "/708/4711", + "/8261/2332", + "/2709/8995", + "/2341/5661", + "/4302/5123" + ] + }, + { + "key": "npm:hosted:build-ATKLPKQC2JIAA", + "paths": [ + "/1194/6360", + "/8033/3958" + ] + }, + { + "key": "npm:hosted:build-1791", + "paths": [ + "/9235/1238", + "/8854/8574" + ] + }, + { + "key": "npm:hosted:build-1300", + "paths": [ + "/460/5198", + "/8168/7737" + ] + }, + { + "key": "npm:hosted:build-ANWONZKHYEQAA", + "paths": [ + "/5376/1247" + ] + }, + { + "key": "npm:hosted:build-ATSCG6OIXQAAA", + "paths": [ + "/541/7610", + "/7146/2160", + "/1523/6617", + "/919/6392", + "/4360/2592", + "/8258/4222", + "/4503/5309", + "/6871/3841", + "/3130/178" + ] + }, + { + "key": "npm:hosted:build-815", + "paths": [ + "/6083/442", + "/2779/8732", + "/6823/9298", + "/4212/3962", + "/7144/7742", + "/7425/1409", + "/4343/3142", + "/8197/6634" + ] + }, + { + "key": "npm:hosted:build-ATI7SK7FAHIAA", + "paths": [ + "/9450/2713", + "/412/3033", + "/5952/8680", + "/6153/665" + ] + }, + { + "key": "npm:hosted:build-898", + "paths": [ + "/8419/1243", + "/6197/6912", + "/4656/2703", + "/4139/7466", + "/3575/490", + "/5255/5490" + ] + }, + { + "key": "npm:hosted:build-ANSDHMTDYJYAA", + "paths": [ + "/9629/8148" + ] + }, + { + "key": "npm:hosted:build-1321", + "paths": [ + "/7418/7008", + "/7043/8010", + "/9882/4756", + "/2806/6502", + "/8677/1845", + "/3312/5444" + ] + }, + { + "key": "npm:hosted:build-ATJVTBYBSJIAA", + "paths": [ + "/7694/121", + "/8577/7733" + ] + }, + { + "key": "npm:hosted:build-1080", + "paths": [ + "/9000/5123", + "/3767/2870", + "/2222/445", + "/8007/7712" + ] + }, + { + "key": "npm:hosted:build-AVWZQUIFB7YAA", + "paths": [ + "/7379/139" + ] + }, + { + "key": "npm:hosted:build-ATRRSYMTXQAAA", + "paths": [ + "/2257/2126" + ] + }, + { + "key": "npm:hosted:build-A4SLDYLJGIAAA", + "paths": [ + "/6343/4377", + "/7783/2333", + "/2225/3707", + "/7110/5449", + "/5176/6552", + "/9861/7463" + ] + }, + { + "key": "npm:hosted:build-ALNRJQYOA7QAA", + "paths": [ + "/8971/1822", + "/8429/2114", + "/1189/8664", + "/4017/8133", + "/8687/7722", + "/4837/3345", + "/3239/9202", + "/2488/8783", + "/6154/8087" + ] + }, + { + "key": "npm:hosted:build-ALNRIIWSY7QAA", + "paths": [ + "/9051/6268", + "/4788/4718", + "/4443/7570", + "/9153/3226", + "/1535/1389", + "/4697/8901", + "/4230/1284", + "/8178/2066" + ] + }, + { + "key": "npm:hosted:build-1588", + "paths": [ + "/8871/2307" + ] + }, + { + "key": "npm:hosted:build-1888", + "paths": [ + "/180/7556", + "/7689/930", + "/1454/7984", + "/8951/9553", + "/6652/1770", + "/1489/1149", + "/4676/2319", + "/5087/9780" + ] + }, + { + "key": "npm:hosted:build-1768", + "paths": [ + "/7000/2411", + "/8833/1134", + "/8019/4018" + ] + }, + { + "key": "npm:hosted:build-ATERVB5IMBIAA", + "paths": [ + "/7323/5206", + "/1766/2295", + "/4708/3391", + "/423/1953", + "/4449/6134", + "/8523/9346", + "/1720/4282", + "/3477/9340" + ] + }, + { + "key": "npm:hosted:build-1777", + "paths": [ + "/9318/8809", + "/6015/863", + "/7576/5250" + ] + }, + { + "key": "npm:hosted:build-177141949236137984", + "paths": [ + "/8105/754", + "/6977/2537", + "/6124/7015", + "/7383/8261" + ] + }, + { + "key": "npm:hosted:build-1201", + "paths": [ + "/5509/5416", + "/844/3277", + "/4798/8043", + "/4658/4538", + "/3586/9544", + "/9113/8226" + ] + }, + { + "key": "npm:hosted:build-ATKLNQ54CJIAA", + "paths": [] + }, + { + "key": "npm:hosted:build-1349", + "paths": [ + "/1394/7820", + "/9718/7582", + "/1124/729", + "/9791/8173", + "/6249/5793", + "/4807/2059" + ] + }, + { + "key": "npm:hosted:build-899", + "paths": [ + "/3733/5282", + "/2386/7016" + ] + }, + { + "key": "npm:hosted:build-ALNQ7FCSA7QAA", + "paths": [] + }, + { + "key": "npm:hosted:build-ALNRN7GQA7QAA", + "paths": [ + "/386/7375", + "/9560/8810", + "/8379/834", + "/3713/2839" + ] + }, + { + "key": "npm:hosted:build-1940", + "paths": [ + "/8814/3418" + ] + }, + { + "key": "npm:hosted:build-AVWYYBKEB7YAA", + "paths": [ + "/1259/9374", + "/1251/5030", + "/8942/5735" + ] + }, + { + "key": "npm:hosted:build-1746", + "paths": [ + "/1131/2067", + "/578/2344", + "/7288/1044", + "/4440/9009", + "/8599/651", + "/3040/299", + "/3323/3012", + "/9435/4948", + "/3481/5532" + ] + }, + { + "key": "npm:hosted:build-ALNZBOJ6XEAAA", + "paths": [ + "/8031/2684", + "/1653/5646", + "/8256/7887" + ] + }, + { + "key": "npm:hosted:build-175002848044564480", + "paths": [ + "/3336/5031", + "/8820/3610", + "/108/5717", + "/2573/8745", + "/9221/4499", + "/7103/5797", + "/4587/291", + "/5493/6446" + ] + }, + { + "key": "npm:hosted:build-1723", + "paths": [ + "/4428/4602", + "/8957/7512", + "/3948/2302", + "/5624/7382", + "/2102/1687", + "/8098/7513", + "/8687/3014" + ] + }, + { + "key": "npm:hosted:build-ATJ2HX732JIAA", + "paths": [ + "/4959/5619", + "/8727/2177", + "/3327/8346", + "/9916/8243", + "/3259/6035" + ] + }, + { + "key": "npm:hosted:build-ATKLQVNBSJIAA", + "paths": [ + "/6949/437", + "/5657/8572", + "/4570/1364", + "/6790/3600", + "/4187/7119", + "/1793/2573" + ] + }, + { + "key": "npm:hosted:build-ALNRYNBKI7QAA", + "paths": [] + }, + { + "key": "npm:hosted:build-826", + "paths": [] + }, + { + "key": "npm:hosted:build-172293563091640320", + "paths": [ + "/5135/715", + "/1354/5791", + "/8703/6245", + "/5219/3046", + "/5000/4925", + "/2577/1222", + "/553/502", + "/8307/8602", + "/4949/2271" + ] + }, + { + "key": "npm:hosted:build-1755", + "paths": [ + "/8161/2153", + "/2752/1107", + "/243/9629", + "/5776/5724", + "/9577/4215", + "/9614/3838", + "/6318/3457" + ] + }, + { + "key": "npm:hosted:build-AY7DGR2EPHAAA", + "paths": [ + "/1631/9529", + "/6907/6726", + "/5442/307", + "/1189/7605", + "/6119/139", + "/6542/3683", + "/2157/490", + "/4482/6063", + "/6704/8441" + ] + }, + { + "key": "npm:hosted:pnc-builds", + "paths": [ + "/987/1200", + "/1362/1393", + "/2937/7776", + "/2849/7073", + "/4231/2999", + "/7519/9820", + "/181/5888" + ] + }, + { + "key": "npm:hosted:build-1160", + "paths": [] + }, + { + "key": "npm:hosted:build-1715", + "paths": [ + "/6710/2175", + "/7669/1683", + "/7603/7003", + "/7314/278", + "/1846/5332", + "/3509/3716", + "/59/5331", + "/7679/5702", + "/5645/3760" + ] + }, + { + "key": "npm:hosted:build-A4SLH57TGIAAA", + "paths": [ + "/2141/475", + "/4188/2365", + "/4443/4797", + "/467/8808", + "/7859/5778", + "/85/7377", + "/9595/3845", + "/5352/6526", + "/282/5169" + ] + }, + { + "key": "npm:hosted:build-ALN37FAJ6DQAA", + "paths": [ + "/4031/9874", + "/3292/5903", + "/6923/5299", + "/788/2285", + "/512/3937", + "/5764/7828", + "/2302/1904" + ] + }, + { + "key": "npm:hosted:build-1200", + "paths": [ + "/9215/9467", + "/7586/3755" + ] + }, + { + "key": "npm:hosted:temporary-builds", + "paths": [ + "/3337/9501", + "/4283/3505", + "/6990/8820", + "/4867/1243", + "/3747/8580", + "/9968/570", + "/4562/9201" + ] + }, + { + "key": "npm:hosted:build-1287", + "paths": [] + }, + { + "key": "npm:hosted:build-1189", + "paths": [ + "/5563/896", + "/6938/4271", + "/4516/239" + ] + }, + { + "key": "npm:hosted:build-ALNZDFZSHEAAA", + "paths": [ + "/2145/5314", + "/1882/5515" + ] + }, + { + "key": "npm:hosted:build-infinispan-js-client", + "paths": [ + "/404/3846", + "/6371/2803", + "/4911/4005", + "/8842/899", + "/4563/3058", + "/5267/9139", + "/1370/1824", + "/5227/601" + ] + }, + { + "key": "npm:hosted:build-1742", + "paths": [ + "/3754/436", + "/5887/1101", + "/7276/9905", + "/767/5849", + "/1320/5391", + "/672/202", + "/1183/280", + "/2728/6354", + "/4930/4522" + ] + }, + { + "key": "npm:hosted:build-1030", + "paths": [ + "/4447/2387", + "/8133/5548", + "/5584/7238", + "/3940/2116", + "/8951/4697", + "/7927/4694", + "/2620/8727", + "/1991/9833" + ] + }, + { + "key": "npm:hosted:build-ANSIHDLHGUIAA", + "paths": [ + "/1399/5130", + "/8425/2612", + "/5601/1772", + "/9603/3327", + "/1448/9029", + "/8131/6892" + ] + }, + { + "key": "npm:hosted:build-1770", + "paths": [ + "/1161/7992", + "/2000/7532" + ] + }, + { + "key": "npm:hosted:build-ANSJWTPYOUIAA", + "paths": [ + "/7112/8901", + "/7914/1009", + "/1330/3103" + ] + }, + { + "key": "npm:hosted:build-1400", + "paths": [ + "/5403/8728", + "/6309/9798", + "/163/7812", + "/7217/2127", + "/9193/7170" + ] + }, + { + "key": "npm:hosted:build-1526", + "paths": [] + }, + { + "key": "npm:hosted:build-172077677927211008", + "paths": [ + "/6777/8119", + "/1086/9145", + "/3259/9414" + ] + }, + { + "key": "npm:hosted:build-590", + "paths": [ + "/6725/6972", + "/9156/352", + "/7704/8740", + "/8358/9718" + ] + }, + { + "key": "npm:hosted:build-1728", + "paths": [ + "/5722/3382", + "/4209/1883", + "/6498/1858", + "/308/8113", + "/1673/6525" + ] + }, + { + "key": "npm:hosted:build-ALNRSR4LQ7QAA", + "paths": [ + "/9399/8104", + "/8740/7770", + "/4237/9057", + "/824/4308", + "/7155/2363", + "/2431/5435", + "/1393/2500", + "/6557/7342" + ] + }, + { + "key": "npm:hosted:build-ANSDJOOKAJYAA", + "paths": [ + "/4659/5707", + "/2591/3284", + "/5675/9053" + ] + }, + { + "key": "npm:hosted:build-1745", + "paths": [] + }, + { + "key": "npm:hosted:build-ALNRWOK2I7QAA", + "paths": [ + "/5039/2856", + "/5054/4541", + "/3187/6294" + ] + }, + { + "key": "npm:hosted:build-1832", + "paths": [ + "/4827/6256", + "/1462/1782", + "/7989/8405", + "/3197/284" + ] + }, + { + "key": "npm:hosted:build-1774", + "paths": [ + "/5767/6271", + "/7732/8299" + ] + }, + { + "key": "npm:hosted:build-1036", + "paths": [ + "/9393/1455", + "/575/2127", + "/1462/78", + "/1812/2321", + "/8693/6705", + "/9126/7374" + ] + }, + { + "key": "npm:hosted:build-1402", + "paths": [ + "/4737/3715" + ] + }, + { + "key": "npm:hosted:build-1957", + "paths": [ + "/596/1296" + ] + }, + { + "key": "npm:hosted:build-1747", + "paths": [ + "/6536/981" + ] + }, + { + "key": "npm:hosted:build-ATI7OKHBYHIAA", + "paths": [ + "/4116/5386", + "/1567/5963", + "/1467/2234", + "/8051/4136", + "/1628/2702" + ] + }, + { + "key": "npm:hosted:build-831", + "paths": [ + "/426/4891", + "/7870/2455", + "/1359/746", + "/4886/9848", + "/3801/81", + "/6379/8621" + ] + }, + { + "key": "npm:hosted:build-1716", + "paths": [ + "/17/6843", + "/4144/8436", + "/2967/9194", + "/4838/9003", + "/9635/7965" + ] + }, + { + "key": "npm:hosted:build-1086", + "paths": [ + "/458/1465", + "/5735/8555", + "/5946/4183", + "/3023/7786", + "/7060/4980", + "/3646/2320" + ] + }, + { + "key": "npm:hosted:build-ATM6P7AOSJIAA", + "paths": [ + "/9282/2146" + ] + }, + { + "key": "npm:hosted:build-1916", + "paths": [ + "/7574/2017", + "/3687/3047" + ] + }, + { + "key": "npm:hosted:build-ATJMWZV2SJIAA", + "paths": [ + "/9319/1184" + ] + }, + { + "key": "npm:hosted:build-ATJL6BNJKJIAA", + "paths": [ + "/4169/488", + "/5826/2700" + ] + }, + { + "key": "npm:hosted:build-ALNRLW24Y7QAA", + "paths": [ + "/6975/3557", + "/6721/7296", + "/8993/9666", + "/8392/2557", + "/7244/5638", + "/4323/3185", + "/9434/2979", + "/4/6259" + ] + }, + { + "key": "npm:hosted:build-175716749567217664", + "paths": [ + "/9193/1622" + ] + }, + { + "key": "npm:hosted:build-ATJCSYAPAHIAA", + "paths": [ + "/4413/4821", + "/9041/1025", + "/8178/5054", + "/3139/4495", + "/9155/5885", + "/3752/7107" + ] + }, + { + "key": "npm:hosted:build-ANSDI2U7QJYAA", + "paths": [] + }, + { + "key": "npm:hosted:build-1914", + "paths": [ + "/9753/1944", + "/1189/7810", + "/5403/4896", + "/3546/8003", + "/7833/222", + "/4537/6764", + "/38/4498", + "/2512/3527" + ] + }, + { + "key": "npm:hosted:build-ATJVVTBOKJIAA", + "paths": [ + "/8683/2712", + "/6243/5188" + ] + }, + { + "key": "npm:hosted:build-ATMVKBEFCJIAA", + "paths": [ + "/7309/3782" + ] + }, + { + "key": "npm:hosted:build-175699223500181504", + "paths": [ + "/435/1920", + "/1308/8905", + "/3486/8840", + "/6146/4964", + "/6420/3358", + "/1904/7456" + ] + }, + { + "key": "npm:remote:test-npmjs", + "paths": [ + "/8719/4345", + "/2872/1051", + "/8189/622", + "/7741/3948", + "/8041/8588", + "/9998/2562", + "/6711/5579", + "/8819/1062", + "/5251/5020" + ] + }, + { + "key": "npm:remote:yarnpkg", + "paths": [ + "/432/9585", + "/5960/8549", + "/1757/9381", + "/2579/5945", + "/2676/4713", + "/6595/4424", + "/7932/1187", + "/869/9556" + ] + }, + { + "key": "npm:remote:npmjs", + "paths": [ + "/5199/4119", + "/7090/2598", + "/3606/3262", + "/8722/3798" + ] + } + ] +} \ No newline at end of file