diff --git a/client/__tests__/e2e/__snapshots__/e2e.test.js.snap b/client/__tests__/e2e/__snapshots__/e2e.test.ts.snap similarity index 100% rename from client/__tests__/e2e/__snapshots__/e2e.test.js.snap rename to client/__tests__/e2e/__snapshots__/e2e.test.ts.snap diff --git a/client/__tests__/e2e/__snapshots__/e2eAnnotations.test.js.snap b/client/__tests__/e2e/__snapshots__/e2eAnnotations.test.ts.snap similarity index 100% rename from client/__tests__/e2e/__snapshots__/e2eAnnotations.test.js.snap rename to client/__tests__/e2e/__snapshots__/e2eAnnotations.test.ts.snap diff --git a/client/__tests__/e2e/cellxgeneActions.js b/client/__tests__/e2e/cellxgeneActions.ts similarity index 74% rename from client/__tests__/e2e/cellxgeneActions.js rename to client/__tests__/e2e/cellxgeneActions.ts index 0f5bf77c..8859eb25 100644 --- a/client/__tests__/e2e/cellxgeneActions.js +++ b/client/__tests__/e2e/cellxgeneActions.ts @@ -18,12 +18,17 @@ import { import { appUrlBase, TEST_EMAIL, TEST_PASSWORD } from "./config"; -export async function drag(testId, start, end, lasso = false) { +export async function drag(testId: any, start: any, end: any, lasso = false) { const layout = await waitByID(testId); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const elBox = await layout.boxModel(); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const x1 = elBox.content[0].x + start.x; + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const x2 = elBox.content[0].x + end.x; + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const y1 = elBox.content[0].y + start.y; + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const y2 = elBox.content[0].y + end.y; await page.mouse.move(x1, y1); await page.mouse.down(); @@ -38,7 +43,7 @@ export async function drag(testId, start, end, lasso = false) { await page.mouse.up(); } -export async function clickOnCoordinate(testId, coord) { +export async function clickOnCoordinate(testId: any, coord: any) { const layout = await expect(page).toMatchElement(getTestId(testId)); const elBox = await layout.boxModel(); @@ -51,11 +56,12 @@ export async function clickOnCoordinate(testId, coord) { await page.mouse.click(x, y); } -export async function getAllHistograms(testclass, testIds) { - const histTestIds = testIds.map((tid) => `histogram-${tid}`); +export async function getAllHistograms(testclass: any, testIds: any) { + const histTestIds = testIds.map((tid: any) => `histogram-${tid}`); // these load asynchronously, so we need to wait for each histogram individually, // and they may be quite slow in some cases. + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 2. await waitForAllByIds(histTestIds, { timeout: 4 * 60 * 1000 }); const allHistograms = await getAllByClass(testclass); @@ -71,7 +77,7 @@ export async function getAllHistograms(testclass, testIds) { return testIDs.map((id) => id.replace(/^histogram-/, "")); } -export async function getAllCategoriesAndCounts(category) { +export async function getAllCategoriesAndCounts(category: any) { // these load asynchronously, so we have to wait for the specific category. await waitByID(`category-${category}`); @@ -80,13 +86,14 @@ export async function getAllCategoriesAndCounts(category) { (rows) => Object.fromEntries( rows.map((row) => { + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const cat = row .querySelector("[data-testclass='categorical-value']") .getAttribute("aria-label"); - const count = row.querySelector( + const count = (row.querySelector( "[data-testclass='categorical-value-count']" - ).innerText; + ) as any).innerText; return [cat, count]; }) @@ -94,12 +101,12 @@ export async function getAllCategoriesAndCounts(category) { ); } -export async function getCellSetCount(num) { +export async function getCellSetCount(num: any) { await clickOn(`cellset-button-${num}`); return getOneElementInnerText(`[data-testid='cellset-count-${num}']`); } -export async function resetCategory(category) { +export async function resetCategory(category: any) { const checkboxId = `${category}:category-select`; await waitByID(checkboxId); const checkedPseudoclass = await page.$eval( @@ -110,6 +117,7 @@ export async function resetCategory(category) { const categoryRow = await waitByID(`${category}:category-expand`); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const isExpanded = await categoryRow.$( "[data-testclass='category-expand-is-expanded']" ); @@ -117,16 +125,26 @@ export async function resetCategory(category) { if (isExpanded) await clickOn(`${category}:category-expand`); } -export async function calcCoordinate(testId, xAsPercent, yAsPercent) { +export async function calcCoordinate( + testId: any, + xAsPercent: any, + yAsPercent: any +) { const el = await waitByID(testId); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const size = await el.boxModel(); return { + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. x: Math.floor(size.width * xAsPercent), + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. y: Math.floor(size.height * yAsPercent), }; } -export async function calcDragCoordinates(testId, coordinateAsPercent) { +export async function calcDragCoordinates( + testId: any, + coordinateAsPercent: any +) { return { start: await calcCoordinate( testId, @@ -141,7 +159,7 @@ export async function calcDragCoordinates(testId, coordinateAsPercent) { }; } -export async function selectCategory(category, values, reset = true) { +export async function selectCategory(category: any, values: any, reset = true) { if (reset) await resetCategory(category); await clickOn(`${category}:category-expand`); @@ -152,8 +170,9 @@ export async function selectCategory(category, values, reset = true) { } } -export async function expandCategory(category) { +export async function expandCategory(category: any) { const expand = await waitByID(`${category}:category-expand`); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const notExpanded = await expand.$( "[data-testclass='category-expand-is-not-expanded']" ); @@ -167,7 +186,7 @@ export async function clip(min = 0, max = 100) { await clickOn("clip-commit"); } -export async function createCategory(categoryName) { +export async function createCategory(categoryName: any) { await clickOnUntil("open-annotation-dialog", async () => { await expect(page).toMatchElement(getTestId("new-category-name")); }); @@ -182,17 +201,18 @@ export async function createCategory(categoryName) { */ -export async function colorByGeneset(genesetName) { +export async function colorByGeneset(genesetName: any) { await clickOn(`${genesetName}:colorby-entire-geneset`); } -export async function colorByGene(gene) { +export async function colorByGene(gene: any) { await clickOn(`colorby-${gene}`); } -export async function assertColorLegendLabel(label) { +export async function assertColorLegendLabel(label: any) { const handle = await waitByID("continuous_legend_color_by_label"); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const result = await handle.evaluate((node) => { return node.getAttribute("aria-label"); }); @@ -200,15 +220,16 @@ export async function assertColorLegendLabel(label) { return expect(result).toBe(label); } -export async function expandGeneset(genesetName) { +export async function expandGeneset(genesetName: any) { const expand = await waitByID(`${genesetName}:geneset-expand`); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const notExpanded = await expand.$( "[data-testclass='geneset-expand-is-not-expanded']" ); if (notExpanded) await clickOn(`${genesetName}:geneset-expand`); } -export async function createGeneset(genesetName) { +export async function createGeneset(genesetName: any) { await clickOnUntil("open-create-geneset-dialog", async () => { await expect(page).toMatchElement(getTestId("create-geneset-input")); }); @@ -218,7 +239,7 @@ export async function createGeneset(genesetName) { await waitByClass("autosave-complete"); } -export async function editGenesetName(genesetName, editText) { +export async function editGenesetName(genesetName: any, editText: any) { const editButton = `${genesetName}:edit-genesetName-mode`; const submitButton = `${genesetName}:submit-geneset`; await clickOnUntil(`${genesetName}:see-actions`, async () => { @@ -229,7 +250,7 @@ export async function editGenesetName(genesetName, editText) { await clickOn(submitButton); } -export async function deleteGeneset(genesetName) { +export async function deleteGeneset(genesetName: any) { const targetId = `${genesetName}:delete-geneset`; await clickOnUntil(`${genesetName}:see-actions`, async () => { @@ -242,16 +263,18 @@ export async function deleteGeneset(genesetName) { await waitByClass("autosave-complete"); } -export async function assertGenesetDoesNotExist(genesetName) { +export async function assertGenesetDoesNotExist(genesetName: any) { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const result = await isElementPresent( getTestId(`${genesetName}:geneset-name`) ); await expect(result).toBe(false); } -export async function assertGenesetExists(genesetName) { +export async function assertGenesetExists(genesetName: any) { const handle = await waitByID(`${genesetName}:geneset-name`); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const result = await handle.evaluate((node) => { return node.getAttribute("aria-label"); }); @@ -265,7 +288,7 @@ export async function assertGenesetExists(genesetName) { */ -export async function addGeneToSet(genesetName, geneToAddToSet) { +export async function addGeneToSet(genesetName: any, geneToAddToSet: any) { const submitButton = `${genesetName}:submit-gene`; await clickOn(`${genesetName}:add-new-gene-to-geneset`); @@ -273,7 +296,7 @@ export async function addGeneToSet(genesetName, geneToAddToSet) { await clickOn(submitButton); } -export async function removeGene(geneSymbol) { +export async function removeGene(geneSymbol: any) { const targetId = `delete-from-geneset:${geneSymbol}`; await clickOn(targetId); @@ -281,9 +304,10 @@ export async function removeGene(geneSymbol) { await waitByClass("autosave-complete"); } -export async function assertGeneExistsInGeneset(geneSymbol) { +export async function assertGeneExistsInGeneset(geneSymbol: any) { const handle = await waitByID(`${geneSymbol}:gene-label`); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const result = await handle.evaluate((node) => { return node.getAttribute("aria-label"); }); @@ -291,13 +315,14 @@ export async function assertGeneExistsInGeneset(geneSymbol) { return expect(result).toBe(geneSymbol); } -export async function assertGeneDoesNotExist(geneSymbol) { +export async function assertGeneDoesNotExist(geneSymbol: any) { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const result = await isElementPresent(getTestId(`${geneSymbol}:gene-label`)); await expect(result).toBe(false); } -export async function expandGene(geneSymbol) { +export async function expandGene(geneSymbol: any) { await clickOn(`maximize-${geneSymbol}`); } @@ -307,7 +332,7 @@ export async function expandGene(geneSymbol) { */ -export async function duplicateCategory(categoryName) { +export async function duplicateCategory(categoryName: any) { await clickOn("open-annotation-dialog"); await typeInto("new-category-name", categoryName); @@ -333,7 +358,10 @@ export async function duplicateCategory(categoryName) { await waitByClass("autosave-complete"); } -export async function renameCategory(oldCategoryName, newCategoryName) { +export async function renameCategory( + oldCategoryName: any, + newCategoryName: any +) { await clickOn(`${oldCategoryName}:see-actions`); await clickOn(`${oldCategoryName}:edit-category-mode`); await clearInputAndTypeInto( @@ -343,7 +371,7 @@ export async function renameCategory(oldCategoryName, newCategoryName) { await clickOn(`${oldCategoryName}:submit-category-edit`); } -export async function deleteCategory(categoryName) { +export async function deleteCategory(categoryName: any) { const targetId = `${categoryName}:delete-category`; await clickOnUntil(`${categoryName}:see-actions`, async () => { @@ -352,10 +380,11 @@ export async function deleteCategory(categoryName) { await clickOn(targetId); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0. await assertCategoryDoesNotExist(); } -export async function createLabel(categoryName, labelName) { +export async function createLabel(categoryName: any, labelName: any) { /** * (thuang): This explicit wait is needed, since currently showing * the modal again quickly after the previous action dismissing the @@ -380,13 +409,17 @@ export async function createLabel(categoryName, labelName) { await clickOn(`${categoryName}:submit-label`); } -export async function deleteLabel(categoryName, labelName) { +export async function deleteLabel(categoryName: any, labelName: any) { await expandCategory(categoryName); await clickOn(`${categoryName}:${labelName}:see-actions`); await clickOn(`${categoryName}:${labelName}:delete-label`); } -export async function renameLabel(categoryName, oldLabelName, newLabelName) { +export async function renameLabel( + categoryName: any, + oldLabelName: any, + newLabelName: any +) { await expandCategory(categoryName); await clickOn(`${categoryName}:${oldLabelName}:see-actions`); await clickOn(`${categoryName}:${oldLabelName}:edit-label`); @@ -397,13 +430,13 @@ export async function renameLabel(categoryName, oldLabelName, newLabelName) { await clickOn(`${categoryName}:${oldLabelName}:submit-label-edit`); } -export async function addGeneToSearch(geneName) { +export async function addGeneToSearch(geneName: any) { await typeInto("gene-search", geneName); await page.keyboard.press("Enter"); await page.waitForSelector(`[data-testid='histogram-${geneName}']`); } -export async function subset(coordinatesAsPercent) { +export async function subset(coordinatesAsPercent: any) { // In order to deselect the selection after the subset, make sure we have some clear part // of the scatterplot we can click on assert(coordinatesAsPercent.x2 < 0.99 || coordinatesAsPercent.y2 < 0.99); @@ -417,8 +450,8 @@ export async function subset(coordinatesAsPercent) { await clickOnCoordinate("layout-graph", clearCoordinate); } -export async function setSellSet(cellSet, cellSetNum) { - const selections = cellSet.filter((sel) => sel.kind === "categorical"); +export async function setSellSet(cellSet: any, cellSetNum: any) { + const selections = cellSet.filter((sel: any) => sel.kind === "categorical"); for (const selection of selections) { await selectCategory(selection.metadata, selection.values, true); @@ -427,19 +460,20 @@ export async function setSellSet(cellSet, cellSetNum) { await getCellSetCount(cellSetNum); } -export async function runDiffExp(cellSet1, cellSet2) { +export async function runDiffExp(cellSet1: any, cellSet2: any) { await setSellSet(cellSet1, 1); await setSellSet(cellSet2, 2); await clickOn("diffexp-button"); } -export async function bulkAddGenes(geneNames) { +export async function bulkAddGenes(geneNames: any) { await clickOn("section-bulk-add"); await typeInto("input-bulk-add", geneNames.join(",")); await page.keyboard.press("Enter"); } -export async function assertCategoryDoesNotExist(categoryName) { +export async function assertCategoryDoesNotExist(categoryName: any) { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const result = await isElementPresent( getTestId(`${categoryName}:category-label`) ); @@ -480,7 +514,7 @@ export async function logout() { await waitByID("log-in"); } -async function waitUntilFormFieldStable(selector) { +async function waitUntilFormFieldStable(selector: any) { const MAX_RETRY = 10; const WAIT_FOR_MS = 200; diff --git a/client/__tests__/e2e/config.js b/client/__tests__/e2e/config.ts similarity index 100% rename from client/__tests__/e2e/config.js rename to client/__tests__/e2e/config.ts diff --git a/client/__tests__/e2e/data.js b/client/__tests__/e2e/data.ts similarity index 100% rename from client/__tests__/e2e/data.js rename to client/__tests__/e2e/data.ts diff --git a/client/__tests__/e2e/diffexpGeneSets.js b/client/__tests__/e2e/diffexpGeneSets.ts similarity index 100% rename from client/__tests__/e2e/diffexpGeneSets.js rename to client/__tests__/e2e/diffexpGeneSets.ts diff --git a/client/__tests__/e2e/e2e.test.js b/client/__tests__/e2e/e2e.test.ts similarity index 90% rename from client/__tests__/e2e/e2e.test.js rename to client/__tests__/e2e/e2e.test.ts index bd3e852a..f8f34ca7 100644 --- a/client/__tests__/e2e/e2e.test.js +++ b/client/__tests__/e2e/e2e.test.ts @@ -58,10 +58,12 @@ describe("metadata loads", () => { const categories = await getAllCategoriesAndCounts(label); expect(Object.keys(categories)).toMatchObject( + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message Object.keys(data.categorical[label]) ); expect(Object.values(categories)).toMatchObject( + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message Object.values(data.categorical[label]) ); } @@ -159,10 +161,12 @@ describe("subset", () => { const categories = await getAllCategoriesAndCounts(label); expect(Object.keys(categories)).toMatchObject( + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message Object.keys(data.subset.categorical[label]) ); expect(Object.values(categories)).toMatchObject( + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message Object.values(data.subset.categorical[label]) ); } @@ -195,6 +199,7 @@ describe("clipping", () => { test("clip continuous", async () => { await goToPage(appUrlBase); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string' is not assignable to par... Remove this comment to see the full error message await clip(data.clip.min, data.clip.max); const histBrushableAreaId = `histogram-${data.clip.metadata}-plot-brushable-area`; const coords = await calcDragCoordinates( @@ -254,6 +259,7 @@ describe("centroid labels", () => { const generatedLabels = await getAllByClass("centroid-label"); // Number of labels generated should be equal to size of the object expect(generatedLabels).toHaveLength( + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message Object.keys(data.categorical[label]).length ); } @@ -275,6 +281,7 @@ describe("graph overlay", () => { data.pan["coordinates-as-percent"] ); + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message const categoryValue = Object.keys(data.categorical[category])[0]; const initialCoordinates = await getElementCoordinates( `${categoryValue}-centroid-label` diff --git a/client/__tests__/e2e/e2eAnnotations.test.js b/client/__tests__/e2e/e2eAnnotations.test.ts similarity index 93% rename from client/__tests__/e2e/e2eAnnotations.test.js rename to client/__tests__/e2e/e2eAnnotations.test.ts index 1430600c..2c0328a5 100644 --- a/client/__tests__/e2e/e2eAnnotations.test.js +++ b/client/__tests__/e2e/e2eAnnotations.test.ts @@ -76,7 +76,7 @@ const brushThisGeneGeneset = "brush_this_gene"; const geneBrushedCellCount = "109"; const subsetGeneBrushedCellCount = "96"; -async function setup(config) { +async function setup(config: any) { await goToPage(appUrlBase); if (config.categoricalAnno) { @@ -150,7 +150,7 @@ describe.each([ await expect(page).toClick(getTestClass("pop-1-geneset-expand")); await page.waitForFunction( - (selector) => !document.querySelector(selector), + (selector: any) => !document.querySelector(selector), {}, getTestClass("gene-loading-spinner") ); @@ -165,7 +165,7 @@ describe.each([ await expect(page).toClick(getTestClass("pop-2-geneset-expand")); await page.waitForFunction( - (selector) => !document.querySelector(selector), + (selector: any) => !document.querySelector(selector), {}, getTestClass("gene-loading-spinner") ); @@ -362,8 +362,11 @@ describe.each([ expect(actualLabelName).toBe(expectedLabelName); expect(actualLabelCount).toBe(expectedLabelCount); - async function getInnerText(element, className) { - return element.$eval(getTestClass(className), (node) => node?.innerText); + async function getInnerText(element: any, className: any) { + return element.$eval( + getTestClass(className), + (node: any) => node?.innerText + ); } }); @@ -388,7 +391,9 @@ describe.each([ `categorical-value-count-${perTestCategoryName}-${perTestLabelName}` ); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. expect(await result.evaluate((node) => node.innerText)).toBe( + // @ts-expect-error ts-migrate(2538) FIXME: Type 'boolean' cannot be used as an index type. data.categoryLabel.newCount.bySubsetConfig[config.withSubset] ); }); @@ -448,6 +453,7 @@ describe.each([ await createLabel(perTestCategoryName, labelName); await assertLabelExists(perTestCategoryName, labelName); await clickOn("undo"); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. await assertLabelDoesNotExist(perTestCategoryName); await clickOn("redo"); await assertLabelExists(perTestCategoryName, labelName); @@ -457,10 +463,12 @@ describe.each([ await setup(config); await deleteLabel(perTestCategoryName, perTestLabelName); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. await assertLabelDoesNotExist(perTestCategoryName); await clickOn("undo"); await assertLabelExists(perTestCategoryName, perTestLabelName); await clickOn("redo"); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. await assertLabelDoesNotExist(perTestCategoryName); }); @@ -523,9 +531,10 @@ describe.each([ expect(result).toMatchSnapshot(); }); - async function assertCategoryExists(categoryName) { + async function assertCategoryExists(categoryName: any) { const handle = await waitByID(`${categoryName}:category-label`); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const result = await handle.evaluate((node) => node.getAttribute("aria-label") ); @@ -533,7 +542,7 @@ describe.each([ return expect(result).toBe(categoryName); } - async function assertLabelExists(categoryName, labelName) { + async function assertLabelExists(categoryName: any, labelName: any) { await expect(page).toMatchElement( getTestId(`${categoryName}:category-expand`) ); @@ -545,11 +554,12 @@ describe.each([ ); expect( + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. await previous.evaluate((node) => node.getAttribute("aria-label")) ).toBe(labelName); } - async function assertLabelDoesNotExist(categoryName, labelName) { + async function assertLabelDoesNotExist(categoryName: any, labelName: any) { await expandCategory(categoryName); const result = await page.$( `[data-testid='categorical-value-${categoryName}-${labelName}']` diff --git a/client/__tests__/e2e/e2eJestConfig.json b/client/__tests__/e2e/e2eJestConfig.json index cc00d0db..d3db4295 100644 --- a/client/__tests__/e2e/e2eJestConfig.json +++ b/client/__tests__/e2e/e2eJestConfig.json @@ -1,10 +1,10 @@ { "testRunner": "jest-circus/runner", "preset": "jest-puppeteer", - "testMatch": ["**/__tests__/**/?(*.)(spec|test).js?(x)"], - "setupFiles": ["../setupMissingGlobals.js"], - "setupFilesAfterEnv": ["expect-puppeteer", "./puppeteer.setup.js"], - "globalSetup": "../globalSetup.js", + "testMatch": ["**/__tests__/**/?(*.)(spec|test).ts?(x)"], + "setupFiles": ["../setupMissingGlobals.ts"], + "setupFilesAfterEnv": ["expect-puppeteer", "./puppeteer.setup.ts"], + "globalSetup": "../globalSetup.ts", "globalTeardown": "jest-environment-puppeteer/teardown", "testEnvironment": "./screenshot_env.js" } diff --git a/client/__tests__/e2e/puppeteer.setup.js b/client/__tests__/e2e/puppeteer.setup.ts similarity index 89% rename from client/__tests__/e2e/puppeteer.setup.js rename to client/__tests__/e2e/puppeteer.setup.ts index 6c593b93..b8294b75 100644 --- a/client/__tests__/e2e/puppeteer.setup.js +++ b/client/__tests__/e2e/puppeteer.setup.ts @@ -23,6 +23,7 @@ beforeEach(async () => { const userAgent = await browser.userAgent(); await page.setUserAgent(`${userAgent}bot`); + // @ts-expect-error ts-migrate(2341) FIXME: Property '_client' is private and only accessible ... Remove this comment to see the full error message await page._client.send("Animation.setPlaybackRate", { playbackRate: 12 }); page.on("pageerror", (err) => { @@ -49,7 +50,7 @@ beforeEach(async () => { } const errorMsgText = await Promise.all( // TODO can we do this without internal properties? - msg.args().map((arg) => arg._remoteObject.description) + msg.args().map((arg: any) => arg._remoteObject.description) ); throw new Error(`Console error: ${errorMsgText}`); } diff --git a/client/__tests__/e2e/puppeteerUtils.js b/client/__tests__/e2e/puppeteerUtils.ts similarity index 69% rename from client/__tests__/e2e/puppeteerUtils.js rename to client/__tests__/e2e/puppeteerUtils.ts index 8d3a497f..0784cf3f 100644 --- a/client/__tests__/e2e/puppeteerUtils.js +++ b/client/__tests__/e2e/puppeteerUtils.ts @@ -1,31 +1,31 @@ /* eslint-disable no-await-in-loop -- await in loop is needed to emulate sequential user actions */ -export function getTestId(id) { +export function getTestId(id: any) { return `[data-testid='${id}']`; } -export function getTestClass(className) { +export function getTestClass(className: any) { return `[data-testclass='${className}']`; } -export async function waitByID(testId, props = {}) { +export async function waitByID(testId: any, props = {}) { return page.waitForSelector(getTestId(testId), props); } -export async function waitByClass(testClass, props = {}) { +export async function waitByClass(testClass: any, props = {}) { return page.waitForSelector(`[data-testclass='${testClass}']`, props); } -export async function waitForAllByIds(testIds) { +export async function waitForAllByIds(testIds: any) { await Promise.all( - testIds.map((testId) => page.waitForSelector(getTestId(testId))) + testIds.map((testId: any) => page.waitForSelector(getTestId(testId))) ); } -export async function getAllByClass(testClass) { +export async function getAllByClass(testClass: any) { return page.$$(`[data-testclass=${testClass}]`); } -export async function typeInto(testId, text) { +export async function typeInto(testId: any, text: any) { // blueprint's typeahead is treating typing weird, clicking & waiting first solves this // only works for text without special characters await waitByID(testId); @@ -36,7 +36,7 @@ export async function typeInto(testId, text) { await page.type(selector, text); } -export async function clearInputAndTypeInto(testId, text) { +export async function clearInputAndTypeInto(testId: any, text: any) { await waitByID(testId); const selector = getTestId(testId); // only works for text without special characters @@ -49,7 +49,7 @@ export async function clearInputAndTypeInto(testId, text) { await page.type(selector, text); } -export async function clickOn(testId, options = {}) { +export async function clickOn(testId: any, options = {}) { await expect(page).toClick(getTestId(testId), options); } @@ -57,7 +57,7 @@ export async function clickOn(testId, options = {}) { * (thuang): There are times when Puppeteer clicks on a button and the page doesn't respond. * So I added clickOnUntil() to retry clicking until a given condition is met. */ -export async function clickOnUntil(testId, assert) { +export async function clickOnUntil(testId: any, assert: any) { const MAX_RETRY = 10; const WAIT_FOR_MS = 200; @@ -81,19 +81,19 @@ export async function clickOnUntil(testId, assert) { } } -export async function getOneElementInnerHTML(selector, options = {}) { +export async function getOneElementInnerHTML(selector: any, options = {}) { await page.waitForSelector(selector, options); return page.$eval(selector, (el) => el.innerHTML); } -export async function getOneElementInnerText(selector) { +export async function getOneElementInnerText(selector: any) { expect(page).toMatchElement(selector); - return page.$eval(selector, (el) => el.innerText); + return page.$eval(selector, (el) => (el as any).innerText); } -export async function getElementCoordinates(testId) { +export async function getElementCoordinates(testId: any) { return page.$eval(getTestId(testId), (elem) => { const { left, top } = elem.getBoundingClientRect(); return [left, top]; @@ -101,12 +101,14 @@ export async function getElementCoordinates(testId) { } async function clickTermsOfService() { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. if (!(await isElementPresent(getTestId("tos-cookies-accept")))) return; await clickOn("tos-cookies-accept"); } async function nameNewAnnotation() { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. if (await isElementPresent(getTestId("annotation-dialog"))) { await typeInto("new-annotation-name", "ignoreE2E"); await clickOn("submit-annotation"); @@ -116,7 +118,7 @@ async function nameNewAnnotation() { } } -export async function goToPage(url) { +export async function goToPage(url: any) { await page.goto(url, { waitUntil: "networkidle0", }); @@ -125,7 +127,8 @@ export async function goToPage(url) { await clickTermsOfService(); } -export async function isElementPresent(selector, options) { +export async function isElementPresent(selector: any, options: any) { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 2. return Boolean(await page.$(selector, options)); } /* eslint-enable no-await-in-loop -- await in loop is needed to emulate sequential user actions */ diff --git a/client/__tests__/e2e/screenshot_env.js b/client/__tests__/e2e/screenshot_env.js index 4701d8ca..7f01ce65 100644 --- a/client/__tests__/e2e/screenshot_env.js +++ b/client/__tests__/e2e/screenshot_env.js @@ -2,6 +2,7 @@ const PuppeteerEnvironment = require("jest-environment-puppeteer"); require("jest-circus"); const ENV_DEFAULT = require("../../../environment.default.json"); +// @ts-expect-error ts-migrate(2451) FIXME: Cannot redeclare block-scoped variable 'takeScreen... Remove this comment to see the full error message const takeScreenshot = require("./takeScreenshot"); class ScreenshotEnvironment extends PuppeteerEnvironment { diff --git a/client/__tests__/globalSetup.js b/client/__tests__/globalSetup.ts similarity index 94% rename from client/__tests__/globalSetup.js rename to client/__tests__/globalSetup.ts index e5163056..d36ac152 100644 --- a/client/__tests__/globalSetup.js +++ b/client/__tests__/globalSetup.ts @@ -1,3 +1,4 @@ +// @ts-ignore FIXME revisit from ts-migrate const { SecretsManagerClient, GetSecretValueCommand, diff --git a/client/__tests__/reducers/cascade.test.js b/client/__tests__/reducers/cascade.test.ts similarity index 82% rename from client/__tests__/reducers/cascade.test.js rename to client/__tests__/reducers/cascade.test.ts index a61e579e..1826646d 100644 --- a/client/__tests__/reducers/cascade.test.js +++ b/client/__tests__/reducers/cascade.test.ts @@ -20,7 +20,12 @@ describe("cascade", () => { const reducer = cascadeReducers([ [ "foo", - (currentState, action, nextSharedState, prevSharedState) => { + ( + currentState: any, + action: any, + nextSharedState: any, + prevSharedState: any + ) => { expect(currentState).toBeUndefined(); expect(action).toEqual(topLevelAction); expect(nextSharedState).toStrictEqual({}); @@ -30,7 +35,12 @@ describe("cascade", () => { ], [ "bar", - (currentState, action, nextSharedState, prevSharedState) => { + ( + currentState: any, + action: any, + nextSharedState: any, + prevSharedState: any + ) => { expect(currentState).toBeUndefined(); expect(action).toEqual(topLevelAction); expect(nextSharedState).toStrictEqual({ foo: 0 }); diff --git a/client/__tests__/reducers/genesets.test.js b/client/__tests__/reducers/genesets.test.ts similarity index 97% rename from client/__tests__/reducers/genesets.test.js rename to client/__tests__/reducers/genesets.test.ts index ad377f6c..ede5a758 100644 --- a/client/__tests__/reducers/genesets.test.js +++ b/client/__tests__/reducers/genesets.test.ts @@ -501,6 +501,7 @@ describe("geneset: set tid", () => { test("not a number error", () => { expect(() => { genesetsReducer( + // @ts-expect-error ts-migrate(2322) FIXME: Type 'number' is not assignable to type 'undefined... Remove this comment to see the full error message { lastTid: 1 }, { type: "geneset: set tid", @@ -513,6 +514,7 @@ describe("geneset: set tid", () => { test("decrement error", () => { expect(() => { genesetsReducer( + // @ts-expect-error ts-migrate(2322) FIXME: Type 'number' is not assignable to type 'undefined... Remove this comment to see the full error message { lastTid: 1 }, { type: "geneset: set tid", diff --git a/client/__tests__/reducers/genesetsUI.test.js b/client/__tests__/reducers/genesetsUI.test.ts similarity index 100% rename from client/__tests__/reducers/genesetsUI.test.js rename to client/__tests__/reducers/genesetsUI.test.ts diff --git a/client/__tests__/reducers/undoable.test.js b/client/__tests__/reducers/undoable.test.ts similarity index 93% rename from client/__tests__/reducers/undoable.test.js rename to client/__tests__/reducers/undoable.test.ts index 5e27b5af..4259b604 100644 --- a/client/__tests__/reducers/undoable.test.js +++ b/client/__tests__/reducers/undoable.test.ts @@ -2,6 +2,7 @@ import undoable from "../../src/reducers/undoable"; describe("create", () => { test("no keys", () => { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2-3 arguments, but got 1. expect(() => undoable(() => {})).toThrow(); expect(() => undoable(() => {}, null)).toThrow(); expect(() => undoable(() => {}, [])).toThrow(); @@ -23,7 +24,7 @@ describe("create", () => { describe("undo", () => { test("expected state modifications", () => { const initialState = { a: 0, b: 1000 }; - const reducer = (state) => { + const reducer = (state: any) => { return { a: state.a + 1, b: state.b + 1 }; }; const undoableReducer = undoable(reducer, ["a"]); @@ -43,10 +44,10 @@ describe("undo", () => { describe("redo", () => { const initialState = { a: 0, b: 1000 }; - const reducer = (state) => { + const reducer = (state: any) => { return { a: state.a + 1, b: state.b + 1 }; }; - let UR; + let UR: any; beforeEach(() => { UR = undoable(reducer, ["a"]); diff --git a/client/__tests__/setupMissingGlobals.js b/client/__tests__/setupMissingGlobals.ts similarity index 61% rename from client/__tests__/setupMissingGlobals.js rename to client/__tests__/setupMissingGlobals.ts index 679cc21f..72d14319 100644 --- a/client/__tests__/setupMissingGlobals.js +++ b/client/__tests__/setupMissingGlobals.ts @@ -5,5 +5,6 @@ the jest test environment). import { TextDecoder, TextEncoder } from "util"; +// @ts-expect-error ts-migrate(2322) FIXME: Type 'typeof TextDecoder' is not assignable to typ... Remove this comment to see the full error message global.TextDecoder = TextDecoder; global.TextEncoder = TextEncoder; diff --git a/client/__tests__/util/actionHelpers.test.js b/client/__tests__/util/actionHelpers.test.ts similarity index 100% rename from client/__tests__/util/actionHelpers.test.js rename to client/__tests__/util/actionHelpers.test.ts diff --git a/client/__tests__/util/annoMatrix/annoMatrix.test.js b/client/__tests__/util/annoMatrix/annoMatrix.test.ts similarity index 89% rename from client/__tests__/util/annoMatrix/annoMatrix.test.js rename to client/__tests__/util/annoMatrix/annoMatrix.test.ts index c178a5f7..e10964a1 100644 --- a/client/__tests__/util/annoMatrix/annoMatrix.test.js +++ b/client/__tests__/util/annoMatrix/annoMatrix.test.ts @@ -14,10 +14,11 @@ import { Dataframe } from "../../../src/util/dataframe"; enableFetchMocks(); describe("AnnoMatrix", () => { - let annoMatrix; + let annoMatrix: any; beforeEach(async () => { - fetch.resetMocks(); // reset all fetch mocking state + (fetch as any).resetMocks(); // reset all fetch mocking state + // reset all fetch mocking state annoMatrix = new AnnoMatrixLoader( serverMocks.baseDataURL, serverMocks.schema.schema @@ -36,7 +37,7 @@ describe("AnnoMatrix", () => { }); test("simple single column fetch", async () => { - fetch.once(serverMocks.annotationsObs(["name_0"])); + (fetch as any).once(serverMocks.annotationsObs(["name_0"])); const df = await annoMatrix.fetch("obs", "name_0"); expect(df).toBeInstanceOf(Dataframe); @@ -45,7 +46,7 @@ describe("AnnoMatrix", () => { }); test("simple multi column fetch", async () => { - fetch + (fetch as any) .once(serverMocks.annotationsObs(["name_0"])) .once(serverMocks.annotationsObs(["n_genes"])); @@ -55,9 +56,11 @@ describe("AnnoMatrix", () => { }); describe("fetch from field", () => { - const getLastTwo = async (field) => { + const getLastTwo = async (field: any) => { const columnNames = annoMatrix.getMatrixColumns(field).slice(-2); - fetch.mockResponses(...columnNames.map(() => serverMocks.responder)); + (fetch as any).mockResponses( + ...columnNames.map(() => serverMocks.responder) + ); await expect( annoMatrix.fetch(field, columnNames) ).resolves.toBeInstanceOf(Dataframe); @@ -70,19 +73,19 @@ describe("AnnoMatrix", () => { test("fetch - test all query forms", async () => { // single string is a column name - fetch.once(serverMocks.annotationsObs(["n_genes"])); + (fetch as any).once(serverMocks.annotationsObs(["n_genes"])); await expect(annoMatrix.fetch("obs", "n_genes")).resolves.toBeInstanceOf( Dataframe ); // array of column names, expecting n_genes to be cached. - fetch.once(serverMocks.annotationsObs(["percent_mito"])); + (fetch as any).once(serverMocks.annotationsObs(["percent_mito"])); await expect( annoMatrix.fetch("obs", ["n_genes", "percent_mito"]) ).resolves.toBeInstanceOf(Dataframe); // more complex value filter query, enumerated - fetch.once(serverMocks.responder); + (fetch as any).once(serverMocks.responder); await expect( annoMatrix.fetch("X", { where: { @@ -95,7 +98,7 @@ describe("AnnoMatrix", () => { // more complex value filter query, range const varIndex = annoMatrix.schema.annotations.var.index; - fetch + (fetch as any) .once( serverMocks.withExpected("/data/var", [[`var:${varIndex}`, "SUMO3"]]) ) @@ -171,7 +174,7 @@ describe("AnnoMatrix", () => { expect(am1.nObs).toEqual(am2.nObs); expect(am1.nVar).toEqual(am2.nVar); - fetch + (fetch as any) .once(serverMocks.annotationsObs(["n_genes"])) .once(serverMocks.annotationsObs(["n_genes"])); const ng1 = await am1.fetch("obs", "n_genes"); @@ -185,9 +188,10 @@ describe("AnnoMatrix", () => { }); describe("add/drop column", () => { + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'base' implicitly has an 'any' type. async function addDrop(base) { expect(base.getMatrixColumns("obs")).not.toContain("foo"); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(base.fetch("obs", "foo")).rejects.toThrow( "unknown column name" ); @@ -212,7 +216,7 @@ describe("AnnoMatrix", () => { const am2 = am1.dropObsColumn("foo"); expect(base.getMatrixColumns("obs")).not.toContain("foo"); expect(am2.getMatrixColumns("obs")).not.toContain("foo"); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(am2.fetch("obs", "foo")).rejects.toThrow( "unknown column name" ); @@ -235,14 +239,14 @@ describe("AnnoMatrix", () => { const am4 = clip(am3, 0, 1); await addDrop(am4); - fetch.mockResponse(serverMocks.responder); + (fetch as any).mockResponse(serverMocks.responder); await am1.fetch("obs", am1.getMatrixColumns("obs")); await am2.fetch("obs", am2.getMatrixColumns("obs")); await am3.fetch("obs", am3.getMatrixColumns("obs")); await am4.fetch("obs", am4.getMatrixColumns("obs")); - fetch.resetMocks(); + (fetch as any).resetMocks(); await addDrop(am1); await addDrop(am2); @@ -252,6 +256,7 @@ describe("AnnoMatrix", () => { }); describe("setObsColumnValues", () => { + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'base' implicitly has an 'any' type. async function addSetDrop(base) { /* add column */ let am = base.addObsColumn( @@ -287,7 +292,7 @@ describe("AnnoMatrix", () => { ); /* drop column */ - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); am = am1.dropObsColumn("test"); await expect(am.fetch("obs", "test")).rejects.toThrow( "unknown column name" @@ -308,7 +313,7 @@ describe("AnnoMatrix", () => { const am3 = isubset(annoMatrix, [10, 1, 0, 30, 2]); await addSetDrop(am3); - fetch.mockResponse(serverMocks.responder); + (fetch as any).mockResponse(serverMocks.responder); await am1.fetch("obs", am1.getMatrixColumns("obs")); await am2.fetch("obs", am2.getMatrixColumns("obs")); diff --git a/client/__tests__/util/annoMatrix/crossfilter.test.js b/client/__tests__/util/annoMatrix/crossfilter.test.ts similarity index 84% rename from client/__tests__/util/annoMatrix/crossfilter.test.js rename to client/__tests__/util/annoMatrix/crossfilter.test.ts index 873334ca..a3373891 100644 --- a/client/__tests__/util/annoMatrix/crossfilter.test.js +++ b/client/__tests__/util/annoMatrix/crossfilter.test.ts @@ -17,11 +17,12 @@ import { rangeFill } from "../../../src/util/range"; enableFetchMocks(); describe("AnnoMatrixCrossfilter", () => { - let annoMatrix; - let crossfilter; + let annoMatrix: any; + let crossfilter: any; beforeEach(async () => { - fetch.resetMocks(); // reset all fetch mocking state + (fetch as any).resetMocks(); // reset all fetch mocking state + // reset all fetch mocking state annoMatrix = new AnnoMatrixLoader( serverMocks.baseDataURL, serverMocks.schema.schema @@ -67,7 +68,9 @@ describe("AnnoMatrixCrossfilter", () => { crossfilter.obsCrossfilter.hasDimension("obs/louvain") ).toBeFalsy(); - fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain])); + (fetch as any).once( + serverMocks.dataframeResponse(["louvain"], [obsLouvain]) + ); let newCrossfilter = await crossfilter.select("obs", "louvain", { mode: "none", }); @@ -76,7 +79,7 @@ describe("AnnoMatrixCrossfilter", () => { expect( newCrossfilter.obsCrossfilter.hasDimension("obs/louvain") ).toBeTruthy(); - expect(fetch.mock.calls).toHaveLength(1); + expect((fetch as any).mock.calls).toHaveLength(1); newCrossfilter = await crossfilter.select("obs", "louvain", { mode: "all", @@ -87,7 +90,9 @@ describe("AnnoMatrixCrossfilter", () => { test("simple column select", async () => { let xfltr; - fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain])); + (fetch as any).once( + serverMocks.dataframeResponse(["louvain"], [obsLouvain]) + ); xfltr = await crossfilter.select("obs", "louvain", { mode: "exact", values: ["NK cells", "B cells"], @@ -105,6 +110,7 @@ describe("AnnoMatrixCrossfilter", () => { expect(xfltr.allSelectedLabels()).toEqual( Int32Array.from( obsLouvain.reduce((acc, val, idx) => { + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number' is not assignable to par... Remove this comment to see the full error message if (val === "NK cells" || val === "B cells") acc.push(idx); return acc; }, []) @@ -124,10 +130,11 @@ describe("AnnoMatrixCrossfilter", () => { const values = df.col("louvain").asArray(); const selected = xfltr.allSelectedMask(); values.every( - (val, idx) => !["NK cells", "B cells"].includes(val) !== !selected[idx] + (val: any, idx: any) => + !["NK cells", "B cells"].includes(val) !== !selected[idx] ); - fetch.once( + (fetch as any).once( serverMocks.dataframeResponse(["n_genes"], [new Int32Array(obsNGenes)]) ); xfltr = await xfltr.select("obs", "n_genes", { @@ -146,6 +153,7 @@ describe("AnnoMatrixCrossfilter", () => { val < 500 && (louvain === "NK cells" || louvain === "B cells") ) + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number' is not assignable to par... Remove this comment to see the full error message acc.push(idx); return acc; }, []) @@ -160,7 +168,7 @@ describe("AnnoMatrixCrossfilter", () => { const varIndex = annoMatrix.schema.annotations.var.index; const { nObs } = annoMatrix.schema.dataframe; - fetch.once( + (fetch as any).once( serverMocks.dataframeResponse( ["TEST"], [rangeFill(new Float32Array(nObs), 0, 0.1)] @@ -196,14 +204,16 @@ describe("AnnoMatrixCrossfilter", () => { }); const values = df.icol(0).asArray(); const selected = xfltr.allSelectedMask(); - values.every((val, idx) => !(val >= 0 && val <= 50) !== !selected[idx]); - expect(selected.reduce((acc, val) => (val ? acc + 1 : acc), 0)).toEqual( - xfltr.countSelected() + values.every( + (val: any, idx: any) => !(val >= 0 && val <= 50) !== !selected[idx] ); + expect( + selected.reduce((acc: any, val: any) => (val ? acc + 1 : acc), 0) + ).toEqual(xfltr.countSelected()); }); test("spatial column select", async () => { - fetch.once( + (fetch as any).once( serverMocks.dataframeResponse( ["umap_0", "umap_1"], [Float32Array.from(embUmap[0]), Float32Array.from(embUmap[1])] @@ -222,6 +232,7 @@ describe("AnnoMatrixCrossfilter", () => { test("select on subset", async () => { const mask = new Uint8Array(annoMatrix.nObs).fill(0); for (let i = 0; i < mask.length; i += 2) { + // @ts-expect-error ts-migrate(2322) FIXME: Type 'boolean' is not assignable to type 'number'. mask[i] = true; } const annoMatrixSubset = isubsetMask(annoMatrix, mask); @@ -230,7 +241,9 @@ describe("AnnoMatrixCrossfilter", () => { let xfltr = new AnnoMatrixObsCrossfilter(annoMatrixSubset); expect(xfltr.countSelected()).toEqual(annoMatrixSubset.nObs); - fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain])); + (fetch as any).once( + serverMocks.dataframeResponse(["louvain"], [obsLouvain]) + ); xfltr = await xfltr.select("obs", "louvain", { mode: "exact", values: ["NK cells", "B cells"], @@ -243,7 +256,8 @@ describe("AnnoMatrixCrossfilter", () => { const values = df.col("louvain").asArray(); const selected = xfltr.allSelectedMask(); values.every( - (val, idx) => !["NK cells", "B cells"].includes(val) !== !selected[idx] + (val: any, idx: any) => + !["NK cells", "B cells"].includes(val) !== !selected[idx] ); }); @@ -256,7 +270,7 @@ describe("AnnoMatrixCrossfilter", () => { "unable to obsSelect upon the var dimension" ); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(crossfilter.select("obs", "foo")).rejects.toThrow( "unknown column name" ); @@ -267,24 +281,27 @@ describe("AnnoMatrixCrossfilter", () => { /* test the matrix mutators via crossfilter proxy */ - async function helperAddTestCol(cf, colName, colSchema = null) { + async function helperAddTestCol(cf: any, colName: any, colSchema = null) { expect( cf.annoMatrix.getMatrixColumns("obs").includes(colName) ).toBeFalsy(); if (colSchema === null) { + // @ts-expect-error ts-migrate(2322) FIXME: Type '{ name: any; type: string; categories: strin... Remove this comment to see the full error message colSchema = { name: colName, type: "categorical", categories: ["toasty"], }; } + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. colSchema.name = colName; + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const initValue = colSchema.categories[0]; const xfltr = cf.addObsColumn(colSchema, Array, initValue); expect( xfltr.annoMatrix.schema.annotations.obs.columns.filter( - (v) => v.name === colName + (v: any) => v.name === colName ) ).toHaveLength(1); const df = await xfltr.annoMatrix.fetch("obs", colName); @@ -314,7 +331,7 @@ describe("AnnoMatrixCrossfilter", () => { }); expect( xfltr.annoMatrix.schema.annotations.obs.columns.filter( - (v) => v.name === "foo" + (v: any) => v.name === "foo" ) ).toHaveLength(1); @@ -324,7 +341,7 @@ describe("AnnoMatrixCrossfilter", () => { df .col("foo") .asArray() - .every((v) => v === "A") + .every((v: any) => v === "A") ).toBeTruthy(); // check that we catch dups @@ -361,11 +378,11 @@ describe("AnnoMatrixCrossfilter", () => { xfltr = xfltr.dropObsColumn("foo"); expect( xfltr.annoMatrix.schema.annotations.obs.columns.filter( - (v) => v.name === "foo" + (v: any) => v.name === "foo" ) ).toHaveLength(0); expect(xfltr.annoMatrix.schema.annotations.obsByName.foo).toBeUndefined(); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(xfltr.annoMatrix.fetch("obs", "foo")).rejects.toThrow( "unknown column name" ); @@ -378,7 +395,7 @@ describe("AnnoMatrixCrossfilter", () => { }); xfltr = xfltr.dropObsColumn("bar"); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(xfltr.select("obs", "bar", { mode: "all" })).rejects.toThrow( "unknown column name" ); @@ -404,7 +421,7 @@ describe("AnnoMatrixCrossfilter", () => { type: "categorical", }); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(xfltr.annoMatrix.fetch("obs", "foo")).rejects.toThrow( "unknown column name" ); @@ -419,7 +436,7 @@ describe("AnnoMatrixCrossfilter", () => { }); xfltr = xfltr.renameObsColumn("bar", "xyz"); - fetch.mockRejectOnce(new Error("unknown column name")); + (fetch as any).mockRejectOnce(new Error("unknown column name")); await expect(xfltr.select("obs", "bar", { mode: "all" })).rejects.toThrow( "unknown column name" ); @@ -429,7 +446,7 @@ describe("AnnoMatrixCrossfilter", () => { }); test("addObsAnnoCategory", async () => { - let xfltr; + let xfltr: any; // catch unknown or readonly columns expect(() => crossfilter.addObsAnnoCategory("louvain", "mumble")).toThrow( @@ -440,6 +457,7 @@ describe("AnnoMatrixCrossfilter", () => { ).toThrow("Unknown or readonly obs column"); // add a column and then add category to it + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message xfltr = await helperAddTestCol(crossfilter, "foo", { name: "foo", type: "categorical", @@ -458,6 +476,7 @@ describe("AnnoMatrixCrossfilter", () => { ); // now same, but ensure we have built an index before doing the operation + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message xfltr = await helperAddTestCol(crossfilter, "bar", { name: "bar", type: "categorical", @@ -486,6 +505,7 @@ describe("AnnoMatrixCrossfilter", () => { crossfilter.removeObsAnnoCategory("undefined-name", "mumble") ).rejects.toThrow("Unknown or readonly obs column"); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message xfltr = await helperAddTestCol(crossfilter, "foo", { name: "foo", type: "categorical", @@ -496,7 +516,7 @@ describe("AnnoMatrixCrossfilter", () => { (await xfltr.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .every((v) => v === "unassigned") + .every((v: any) => v === "unassigned") ).toBeTruthy(); expect(xfltr.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({ name: "foo", @@ -515,7 +535,7 @@ describe("AnnoMatrixCrossfilter", () => { (await xfltr1.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .every((v) => v === "unassigned") + .every((v: any) => v === "unassigned") ).toBeTruthy(); expect(xfltr1.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({ name: "foo", @@ -538,7 +558,7 @@ describe("AnnoMatrixCrossfilter", () => { (await xfltr2.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .every((v) => v === "red") + .every((v: any) => v === "red") ).toBeTruthy(); expect(xfltr2.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({ name: "foo", @@ -556,6 +576,7 @@ describe("AnnoMatrixCrossfilter", () => { crossfilter.setObsColumnValues("undefined-name", [0], "mumble") ).rejects.toThrow("Unknown or readonly obs column"); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message let xfltr = await helperAddTestCol(crossfilter, "foo", { name: "foo", type: "categorical", @@ -573,7 +594,7 @@ describe("AnnoMatrixCrossfilter", () => { (await xfltr.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .every((v) => v === "unassigned") + .every((v: any) => v === "unassigned") ).toBeTruthy(); const xfltr1 = await xfltr.setObsColumnValues("foo", [0, 10], "purple"); expect( @@ -581,7 +602,7 @@ describe("AnnoMatrixCrossfilter", () => { .col("foo") .asArray() .every( - (v, i) => + (v: any, i: any) => v === "unassigned" || (v === "purple" && (i === 0 || i === 10)) ) ).toBeTruthy(); @@ -615,6 +636,7 @@ describe("AnnoMatrixCrossfilter", () => { crossfilter.resetObsColumnValues("undefined-name", "red", "blue") ).rejects.toThrow("Unknown or readonly obs column"); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{ name: string; type: string; ca... Remove this comment to see the full error message let xfltr = await helperAddTestCol(crossfilter, "foo", { name: "foo", type: "categorical", @@ -639,7 +661,7 @@ describe("AnnoMatrixCrossfilter", () => { (await xfltr1.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .filter((v) => v === "purple") + .filter((v: any) => v === "purple") ).toHaveLength(2); xfltr1 = await xfltr1.resetObsColumnValues("foo", "purple", "magenta"); @@ -647,13 +669,13 @@ describe("AnnoMatrixCrossfilter", () => { (await xfltr1.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .filter((v) => v === "magenta") + .filter((v: any) => v === "magenta") ).toHaveLength(2); expect( (await xfltr1.annoMatrix.fetch("obs", "foo")) .col("foo") .asArray() - .filter((v) => v === "purple") + .filter((v: any) => v === "purple") ).toHaveLength(0); expect(xfltr1.annoMatrix.getColumnSchema("obs", "foo")).toMatchObject({ name: "foo", @@ -673,12 +695,14 @@ describe("AnnoMatrixCrossfilter", () => { describe("edge cases", () => { test("transition from empty annoMatrix", async () => { // select before fetch needs to work - fetch.once(serverMocks.dataframeResponse(["louvain"], [obsLouvain])); + (fetch as any).once( + serverMocks.dataframeResponse(["louvain"], [obsLouvain]) + ); const xfltr = await crossfilter.select("obs", "louvain", { mode: "exact", values: "B cells", }); - expect(fetch.mock.calls).toHaveLength(1); + expect((fetch as any).mock.calls).toHaveLength(1); expect(xfltr.obsCrossfilter.hasDimension("obs/louvain")).toBeTruthy(); expect(xfltr.obsCrossfilter.all()).toBe(xfltr.annoMatrix._cache.obs); expect(xfltr.countSelected()).toEqual( diff --git a/client/__tests__/util/annoMatrix/serverMocks/index.js b/client/__tests__/util/annoMatrix/serverMocks/index.ts similarity index 86% rename from client/__tests__/util/annoMatrix/serverMocks/index.js rename to client/__tests__/util/annoMatrix/serverMocks/index.ts index a8ef1285..857b3732 100644 --- a/client/__tests__/util/annoMatrix/serverMocks/index.js +++ b/client/__tests__/util/annoMatrix/serverMocks/index.ts @@ -1,6 +1,6 @@ export const baseDataURL = "https://a.fake.url/api/v0.2"; -window.CELLXGENE = { +(window as any).CELLXGENE = { API: { prefix: baseDataURL, version: "v0.2/", diff --git a/client/__tests__/util/annoMatrix/serverMocks/routes.js b/client/__tests__/util/annoMatrix/serverMocks/routes.ts similarity index 61% rename from client/__tests__/util/annoMatrix/serverMocks/routes.js rename to client/__tests__/util/annoMatrix/serverMocks/routes.ts index 94fbe3f6..62fdbd5c 100644 --- a/client/__tests__/util/annoMatrix/serverMocks/routes.js +++ b/client/__tests__/util/annoMatrix/serverMocks/routes.ts @@ -14,7 +14,7 @@ const indexedSchema = { ), }; -function makeMockColumn(s, length) { +function makeMockColumn(s: any, length: any) { const { type } = s; switch (type) { case "int32": @@ -37,20 +37,22 @@ function makeMockColumn(s, length) { } } -function getEncodedDataframe(colNames, length, colSchemas) { +function getEncodedDataframe(colNames: any, length: any, colSchemas: any) { const colIndex = new KeyIndex(colNames); - const columns = colSchemas.map((s) => makeMockColumn(s, length)); + const columns = colSchemas.map((s: any) => makeMockColumn(s, length)); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message const df = new Dataframe([length, colNames.length], columns, null, colIndex); const body = encodeMatrixFBS(df); return body; } -export function dataframeResponse(colNames, columns) { +export function dataframeResponse(colNames: any, columns: any) { const colIndex = new KeyIndex(colNames); const df = new Dataframe( [columns[0].length, colNames.length], columns, null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message colIndex ); const body = encodeMatrixFBS(df); @@ -60,15 +62,19 @@ export function dataframeResponse(colNames, columns) { return () => Promise.resolve({ body, init: { status: 200, headers } }); } -function annotationObsResponse(request) { +function annotationObsResponse(request: any) { const url = new URL(request.url); - const params = Array.from(url.searchParams.entries()); + const params = Array.from((url.searchParams as any).entries()); const names = params + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. .filter(([k]) => k === "annotation-name") + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '([, v]: [any, any]) => any' is n... Remove this comment to see the full error message .map(([, v]) => v); + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. if (!names.every((n) => indexedSchema.obsByName[n])) { return Promise.reject(new Error("bad obs annotation name in URL")); } + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. const colSchemas = names.map((n) => indexedSchema.obsByName[n]); const body = getEncodedDataframe( names, @@ -85,15 +91,19 @@ function annotationObsResponse(request) { }); } -function annotationVarResponse(request) { +function annotationVarResponse(request: any) { const url = new URL(request.url); - const params = Array.from(url.searchParams.entries()); + const params = Array.from((url.searchParams as any).entries()); const names = params + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. .filter(([k]) => k === "annotation-name") + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '([, v]: [any, any]) => any' is n... Remove this comment to see the full error message .map(([, v]) => v); + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. if (!names.every((n) => indexedSchema.varByName[n])) { return Promise.reject(new Error("bad var annotation name in URL")); } + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. const colSchemas = names.map((n) => indexedSchema.varByName[n]); const body = getEncodedDataframe( names, @@ -110,15 +120,19 @@ function annotationVarResponse(request) { }); } -function layoutObsResponse(request) { +function layoutObsResponse(request: any) { const url = new URL(request.url); - const params = Array.from(url.searchParams.entries()); + const params = Array.from((url.searchParams as any).entries()); + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. const names = params.filter(([k]) => k === "layout-name").map(([, v]) => v); + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. if (!names.every((n) => indexedSchema.embByName[n])) { return Promise.reject(new Error("bad layout name in URL")); } + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. const dims = names.map((n) => indexedSchema.embByName[n].dims).flat(); const colSchemas = names + // @ts-expect-error ts-migrate(2538) FIXME: Type 'unknown' cannot be used as an index type. .map((n) => [indexedSchema.embByName[n], indexedSchema.embByName[n]]) .flat(); const body = getEncodedDataframe( @@ -136,11 +150,11 @@ function layoutObsResponse(request) { }); } -function dataVarResponse(request) { +function dataVarResponse(request: any) { const url = new URL(request.url); - const params = Array.from(url.searchParams.entries()); + const params = Array.from((url.searchParams as any).entries()); - const colNames = params.map((v) => `${v[0]}/${v[1]}`); + const colNames = params.map((v) => `${(v as any)[0]}/${(v as any)[1]}`); const colSchemas = colNames.map(() => schema.schema.dataframe); const body = getEncodedDataframe( colNames, @@ -157,7 +171,7 @@ function dataVarResponse(request) { }); } -export function responder(request) { +export function responder(request: any) { const url = new URL(request.url); const { pathname } = url; if (pathname.endsWith("/annotations/obs")) { @@ -175,25 +189,30 @@ export function responder(request) { return Promise.reject(new Error("bad URL")); } -export function withExpected(expectedURL, expectedParams) { +export function withExpected(expectedURL: any, expectedParams: any) { /* Do some additional error checking */ - return (request) => { + return (request: any) => { // if URL is bogus, reject the promise const url = new URL(request.url); if (!url.pathname.endsWith(expectedURL)) { return Promise.reject(new Error("Unexpected URL!")); } - const params = Array.from(url.searchParams.entries()).sort( - (a, b) => a[0] < b[0] + const params = Array.from((url.searchParams as any).entries()).sort( + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '(a: unknown, b: unknown) => bool... Remove this comment to see the full error message + (a, b) => (a as any)[0] < (b as any)[0] ); - expectedParams = expectedParams.slice().sort((a, b) => a[0] < b[0]); + expectedParams = expectedParams + .slice() + .sort((a: any, b: any) => a[0] < b[0]); if ( params.length !== expectedParams.length || !params.every( - (p, i) => p[0] === expectedParams[i][0] && p[1] === expectedParams[i][1] + (p, i) => + (p as any)[0] === expectedParams[i][0] && + (p as any)[1] === expectedParams[i][1] ) ) { return Promise.reject(new Error("unexpected name requested in URL")); @@ -203,9 +222,9 @@ export function withExpected(expectedURL, expectedParams) { }; } -export function annotationsObs(names) { +export function annotationsObs(names: any) { return withExpected( "/annotations/obs", - names.map((name) => ["annotation-name", name]) + names.map((name: any) => ["annotation-name", name]) ); } diff --git a/client/__tests__/util/annoMatrix/serverMocks/schema.js b/client/__tests__/util/annoMatrix/serverMocks/schema.ts similarity index 100% rename from client/__tests__/util/annoMatrix/serverMocks/schema.js rename to client/__tests__/util/annoMatrix/serverMocks/schema.ts diff --git a/client/__tests__/util/annoMatrix/whereCache.test.js b/client/__tests__/util/annoMatrix/whereCache.test.ts similarity index 94% rename from client/__tests__/util/annoMatrix/whereCache.test.js rename to client/__tests__/util/annoMatrix/whereCache.test.ts index e087399e..0f9d18bc 100644 --- a/client/__tests__/util/annoMatrix/whereCache.test.js +++ b/client/__tests__/util/annoMatrix/whereCache.test.ts @@ -218,10 +218,15 @@ describe("whereCache", () => { }, }) ); - expect(wc.where.field.queryField.has("queryColumn")).toEqual(true); - expect(wc.where.field.queryField.get("queryColumn")).toBeInstanceOf(Map); + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. + expect((wc.where as any).field.queryField.has("queryColumn")).toEqual(true); expect( - wc.where.field.queryField.get("queryColumn").has("queryValue") + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. + (wc.where as any).field.queryField.get("queryColumn") + ).toBeInstanceOf(Map); + expect( + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. + (wc.where as any).field.queryField.get("queryColumn").has("queryValue") ).toEqual(true); expect(_whereCacheGet(wc, schema, "field", query)).toEqual([0, 1, 2]); }); diff --git a/client/__tests__/util/centroid.test.js b/client/__tests__/util/centroid.test.ts similarity index 93% rename from client/__tests__/util/centroid.test.js rename to client/__tests__/util/centroid.test.ts index b8bee126..83ec7963 100644 --- a/client/__tests__/util/centroid.test.js +++ b/client/__tests__/util/centroid.test.ts @@ -8,9 +8,9 @@ import { indexEntireSchema } from "../../src/util/stateManager/schemaHelpers"; import { _normalizeCategoricalSchema } from "../../src/annoMatrix/schema"; describe("centroid", () => { - let schema; - let obsAnnotations; - let obsLayout; + let schema: any; + let obsAnnotations: any; + let obsLayout: any; beforeAll(() => { schema = indexEntireSchema(cloneDeep(REST.schema.schema)); @@ -44,7 +44,7 @@ describe("centroid", () => { quantile([0.5], obsLayout.col("umap_1").asArray())[0], ]; - centroidResult.forEach((coordinate) => { + centroidResult.forEach((coordinate: any) => { expect(coordinate).toEqual(expectedResult); }); }); @@ -68,7 +68,7 @@ describe("centroid", () => { quantile([0.5], obsLayout.col("umap_1").asArray())[0], ]; - centroidResult.forEach((coordinate) => { + centroidResult.forEach((coordinate: any) => { expect(coordinate).toEqual(expectedResult); }); }); diff --git a/client/__tests__/util/dataframe/dataframe.test.js b/client/__tests__/util/dataframe/dataframe.test.ts similarity index 89% rename from client/__tests__/util/dataframe/dataframe.test.js rename to client/__tests__/util/dataframe/dataframe.test.ts index 727f0a7f..8f44dd58 100644 --- a/client/__tests__/util/dataframe/dataframe.test.js +++ b/client/__tests__/util/dataframe/dataframe.test.ts @@ -29,6 +29,7 @@ describe("dataframe constructor", () => { const df = new Dataframe.Dataframe( [3, 2], [new Int32Array([0, 1, 2]), new Int32Array([3, 4, 5])], + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([2, 1, 0]), new Dataframe.KeyIndex(["A", "B"]) ); @@ -55,6 +56,7 @@ describe("simple data access", () => { new Float64Array([0.0, Number.NaN, Number.POSITIVE_INFINITY, 3.14159]), ["red", "blue", "green", "nan"], ], + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([3, 2, 1, 0]), new Dataframe.KeyIndex(["numbers", "colors"]) ); @@ -139,10 +141,12 @@ describe("dataframe subsetting", () => { ["red", "green", "blue"], ], null, // identity index + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["int32", "string", "float32", "colors"]) ); test("all rows, one column", () => { + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message const dfA = sourceDf.subset(null, ["colors"]); expect(dfA).toBeDefined(); expect(dfA.dims).toEqual([3, 1]); @@ -158,6 +162,7 @@ describe("dataframe subsetting", () => { }); test("all rows, two columns", () => { + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message const dfB = sourceDf.subset(null, ["float32", "colors"]); expect(dfB).toBeDefined(); expect(dfB.dims).toEqual([3, 2]); @@ -227,6 +232,7 @@ describe("dataframe subsetting", () => { }); test("two rows, two colums", () => { + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message const dfF = sourceDf.subset([0, 2], ["int32", "float32"]); expect(dfF).toBeDefined(); expect(dfF.dims).toEqual([2, 2]); @@ -236,6 +242,7 @@ describe("dataframe subsetting", () => { expect(dfF.colIndex.labels()).toEqual(["int32", "float32"]); // reverse the row and column order + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message const dfFr = sourceDf.subset([2, 0], ["float32", "int32"]); expect(dfFr).toBeDefined(); expect(dfFr.dims).toEqual([2, 2]); @@ -248,6 +255,7 @@ describe("dataframe subsetting", () => { test("withRowIndex", () => { const df = sourceDf.subset( null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message ["int32", "float32"], new Dataframe.DenseInt32Index([3, 2, 1]) ); @@ -258,12 +266,15 @@ describe("dataframe subsetting", () => { test("withRowIndex error checks", () => { expect(() => + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message sourceDf.subset(null, ["red"], new Dataframe.IdentityInt32Index(1)) ).toThrow(RangeError); expect(() => + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message sourceDf.subset(null, ["red"], new Dataframe.DenseInt32Index([0, 1])) ).toThrow(RangeError); expect(() => + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message sourceDf.subset(null, ["red"], new Dataframe.KeyIndex([0, 1, 2, 3])) ).toThrow(RangeError); }); @@ -278,12 +289,14 @@ describe("dataframe subsetting", () => { new Float32Array([4.4, 5.5, 6.6]), ["red", "green", "blue"], ], + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([2, 4, 6]), new Dataframe.KeyIndex(["int32", "string", "float32", "colors"]) ); const dfA = sourceDf.isubsetMask( new Uint8Array([0, 1, 1]), + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'Uint8Array' is not assignable to... Remove this comment to see the full error message new Uint8Array([1, 0, 0, 1]) ); expect(dfA.dims).toEqual([2, 2]); @@ -303,6 +316,7 @@ describe("dataframe subsetting", () => { ["red", "green", "blue"], ], null, // identity index + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["int32", "string", "float32", "colors"]) ); @@ -316,6 +330,7 @@ describe("dataframe subsetting", () => { }); test("all rows, two cols", () => { + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'number[]' is not assignable to p... Remove this comment to see the full error message const dfA = sourceDf.isubset(null, [1, 2]); expect(dfA.dims).toEqual([3, 2]); expect(dfA.icol(0).asArray()).toEqual(["A", "B", "C"]); @@ -361,6 +376,7 @@ describe("dataframe factories", () => { const dfA = new Dataframe.Dataframe( [3, 2], [new Int32Array([0, 1, 2]), new Int32Array([3, 4, 5])], + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([2, 1, 0]), new Dataframe.KeyIndex(["A", "B"]) ); @@ -385,6 +401,7 @@ describe("dataframe factories", () => { [true, false], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors", "bools"]) ); const dfA = df.withCol("numbers", [1, 0]); @@ -408,6 +425,7 @@ describe("dataframe factories", () => { [true, false], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([74, 75]) ); const dfA = df.withCol(72, [1, 0]); @@ -433,6 +451,7 @@ describe("dataframe factories", () => { [true, false], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([74, 75]) ); const dfA = df.withCol(999, [1, 0]); @@ -541,6 +560,7 @@ describe("dataframe factories", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors", "bools", "numbers"]) ); @@ -549,11 +569,14 @@ describe("dataframe factories", () => { [3, 1], [["red", "blue", "green"]], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colorsA"]) ); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. expect(() => dfA.withColsFrom(dfB)).toThrow(RangeError); /* duplicate labels should throw an error */ + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. expect(() => dfA.withColsFrom(dfA)).toThrow(Error); }); @@ -564,15 +587,18 @@ describe("dataframe factories", () => { [2, 1], [["red", "blue"]], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors"]) ); const dfB = new Dataframe.Dataframe( [2, 1], [[true, false]], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["bools"]) ); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const dfLikeA = dfEmpty.withColsFrom(dfA); expect(dfLikeA).toBeDefined(); expect(dfLikeA.dims).toEqual(dfA.dims); @@ -581,6 +607,7 @@ describe("dataframe factories", () => { expect(dfLikeA.rowIndex.labels()).toEqual(dfA.rowIndex.labels()); expect(dfLikeA.icol(0).asArray()).toEqual(dfA.icol(0).asArray()); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const dfAlsoLikeA = dfA.withColsFrom(dfEmpty); expect(dfAlsoLikeA).toBeDefined(); expect(dfAlsoLikeA.dims).toEqual(dfA.dims); @@ -589,6 +616,7 @@ describe("dataframe factories", () => { expect(dfAlsoLikeA.rowIndex.labels()).toEqual(dfA.rowIndex.labels()); expect(dfAlsoLikeA.icol(0).asArray()).toEqual(dfA.icol(0).asArray()); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const dfC = dfA.withColsFrom(dfB); expect(dfC).toBeDefined(); expect(dfC.dims).toEqual([2, 2]); @@ -605,6 +633,7 @@ describe("dataframe factories", () => { [2, 1], [["red", "blue"]], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors"]) ); const dfB = new Dataframe.Dataframe( @@ -615,6 +644,7 @@ describe("dataframe factories", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors", "bools", "numbers"]) ); @@ -647,6 +677,7 @@ describe("dataframe factories", () => { [2, 1], [["red", "blue"]], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors"]) ); const dfB = new Dataframe.Dataframe( @@ -657,6 +688,7 @@ describe("dataframe factories", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors", "bools", "numbers"]) ); @@ -680,6 +712,7 @@ describe("dataframe factories", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["colors", "bools", "numbers"]) ); const dfA = df.dropCol("colors"); @@ -751,6 +784,7 @@ describe("dataframe factories", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'DenseInt32Index' is not assignab... Remove this comment to see the full error message new Dataframe.DenseInt32Index([102, 101, 100]) ); const dfA = df.dropCol(101); @@ -777,7 +811,7 @@ describe("dataframe factories", () => { new Float64Array(3).fill(1.1), ] ); - const dfB = dfA.mapColumns((col, idx) => { + const dfB = dfA.mapColumns((col: any, idx: any) => { expect(dfA.icol(idx).asArray()).toBe(col); return col; }); @@ -822,6 +856,7 @@ describe("dataframe factories", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["A", "B"]) ); const dfB = dfA.renameCol("B", "C"); @@ -834,7 +869,7 @@ describe("dataframe factories", () => { }); describe("dataframe col", () => { - let df = null; + let df: any = null; beforeEach(() => { df = new Dataframe.Dataframe( [2, 2], @@ -843,6 +878,7 @@ describe("dataframe col", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["A", "B"]) ); }); @@ -1195,6 +1231,7 @@ describe("label indexing", () => { test("create", () => { expect(Dataframe.isLabelIndex(idx)).toBeTruthy(); expect(() => new Dataframe.KeyIndex(["dup", "dup"])).toThrow(Error); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0. expect(new Dataframe.KeyIndex().size()).toEqual(0); }); @@ -1367,6 +1404,7 @@ describe("corner cases", () => { [1, 0], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["A", "B"]) ); diff --git a/client/__tests__/util/dataframe/histogram.test.js b/client/__tests__/util/dataframe/histogram.test.ts similarity index 81% rename from client/__tests__/util/dataframe/histogram.test.js rename to client/__tests__/util/dataframe/histogram.test.ts index ce4c4943..2de3edfc 100644 --- a/client/__tests__/util/dataframe/histogram.test.js +++ b/client/__tests__/util/dataframe/histogram.test.ts @@ -6,6 +6,7 @@ describe("Dataframe column histogram", () => { [3, 3], [["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["name", "cat", "value"]) ); @@ -26,6 +27,7 @@ describe("Dataframe column histogram", () => { [3, 3], [["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["name", "cat", "value"]) ); @@ -48,6 +50,7 @@ describe("Dataframe column histogram", () => { [3, 3], [["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["name", "cat", "value"]) ); @@ -68,6 +71,7 @@ describe("Dataframe column histogram", () => { [3, 3], [["n1", "n2", "n3"], ["c1", "c2", "c3"], new Int32Array([0, 1, 2])], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["name", "cat", "value"]) ); diff --git a/client/__tests__/util/dataframe/summarize.test.js b/client/__tests__/util/dataframe/summarize.test.ts similarity index 90% rename from client/__tests__/util/dataframe/summarize.test.js rename to client/__tests__/util/dataframe/summarize.test.ts index ec98d7be..becefc9f 100644 --- a/client/__tests__/util/dataframe/summarize.test.js +++ b/client/__tests__/util/dataframe/summarize.test.ts @@ -1,6 +1,6 @@ import * as Dataframe from "../../../src/util/dataframe"; -function float32Conversion(f) { +function float32Conversion(f: any) { return new Float32Array([f])[0]; } @@ -30,6 +30,7 @@ describe("Dataframe column summary", () => { [1], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex([ "name", "nameString", @@ -106,6 +107,7 @@ describe("Dataframe column summary", () => { [1, false, "0"], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex([ "name", "nameString", @@ -174,6 +176,7 @@ describe("Dataframe column summary", () => { expect.objectContaining({ categorical: true, categories: expect.arrayContaining([1, false, "0"]), + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. categoryCounts: new Map([ [1, 1], [false, 1], @@ -201,6 +204,7 @@ describe("Dataframe column summary", () => { [1, false, "0", "0"], ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex([ "name", "nameString", @@ -269,6 +273,7 @@ describe("Dataframe column summary", () => { expect.objectContaining({ categorical: true, categories: expect.arrayContaining([1, false, "0"]), + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. categoryCounts: new Map([ [1, 1], [false, 1], diff --git a/client/__tests__/util/nameCreators.test.js b/client/__tests__/util/nameCreators.test.ts similarity index 100% rename from client/__tests__/util/nameCreators.test.js rename to client/__tests__/util/nameCreators.test.ts diff --git a/client/__tests__/util/promiseLimit.test.js b/client/__tests__/util/promiseLimit.test.ts similarity index 91% rename from client/__tests__/util/promiseLimit.test.js rename to client/__tests__/util/promiseLimit.test.ts index b22ff5b1..2464893a 100644 --- a/client/__tests__/util/promiseLimit.test.js +++ b/client/__tests__/util/promiseLimit.test.ts @@ -1,7 +1,7 @@ import PromiseLimit from "../../src/util/promiseLimit"; import { range } from "../../src/util/range"; -const delay = (t) => new Promise((resolve) => setTimeout(resolve, t)); +const delay = (t: any) => new Promise((resolve) => setTimeout(resolve, t)); describe("PromiseLimit", () => { test("simple evaluation, concurrency 1", async () => { @@ -51,7 +51,8 @@ describe("PromiseLimit", () => { running -= 1; }; - await Promise.all(range(10).map((i) => plimit.add(() => callback(i)))); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1. + await Promise.all(range(10).map((i: any) => plimit.add(() => callback(i)))); expect(maxRunning).toEqual(2); }); diff --git a/client/__tests__/util/quantile.test.js b/client/__tests__/util/quantile.test.ts similarity index 100% rename from client/__tests__/util/quantile.test.js rename to client/__tests__/util/quantile.test.ts diff --git a/client/__tests__/util/range.test.js b/client/__tests__/util/range.test.ts similarity index 73% rename from client/__tests__/util/range.test.js rename to client/__tests__/util/range.test.ts index 5da8821d..b7aa0a66 100644 --- a/client/__tests__/util/range.test.js +++ b/client/__tests__/util/range.test.ts @@ -6,14 +6,20 @@ describe("range", () => { }); test("range(stop)", () => { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1. expect(range(3)).toMatchObject([0, 1, 2]); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1. expect(range(0)).toMatchObject([]); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 1. expect(range(1)).toMatchObject([0]); }); test("range(start,stop)", () => { + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2. expect(range(0, 0)).toMatchObject([]); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2. expect(range(0, 2)).toMatchObject([0, 1]); + // @ts-expect-error ts-migrate(2554) FIXME: Expected 3 arguments, but got 2. expect(range(4, 8)).toMatchObject([4, 5, 6, 7]); }); diff --git a/client/__tests__/util/stateManager/colorHelpers.test.js b/client/__tests__/util/stateManager/colorHelpers.test.ts similarity index 80% rename from client/__tests__/util/stateManager/colorHelpers.test.js rename to client/__tests__/util/stateManager/colorHelpers.test.ts index 5ac9973c..4ef462fa 100644 --- a/client/__tests__/util/stateManager/colorHelpers.test.js +++ b/client/__tests__/util/stateManager/colorHelpers.test.ts @@ -81,6 +81,7 @@ describe("categorical color helpers", () => { ), ], null, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message new Dataframe.KeyIndex(["continuousColumn", "categoricalColumn"]) ); @@ -95,6 +96,7 @@ describe("categorical color helpers", () => { const data = obsDataframe.col("categoricalColumn").asArray(); const cats = schema.annotations.obsByName.categoricalColumn.categories; for (let i = 0; i < schema.dataframe.nObs; i += 1) { + // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message expect(makeScale(ct.rgb[i])).toEqual(ct.scale(cats.indexOf(data[i]))); } }); @@ -112,6 +114,7 @@ describe("categorical color helpers", () => { const data = obsDataframe.col("categoricalColumn").asArray(); const cats = schemaClone.annotations.obsByName.categoricalColumn.categories; for (let i = 0; i < schemaClone.dataframe.nObs; i += 1) { + // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message expect(makeScale(ct.rgb[i])).toEqual(ct.scale(cats.indexOf(data[i]))); } }); @@ -122,7 +125,7 @@ describe("categorical color helpers", () => { Array.from(schema.annotations.obsByName.categoricalColumn.categories) ); const userDefinedColorTable = { - categoricalColumn: shuffleCats.reduce((acc, label) => { + categoricalColumn: shuffleCats.reduce((acc: any, label: any) => { acc[label] = randRGBColor(); return acc; }, {}), @@ -136,12 +139,14 @@ describe("categorical color helpers", () => { "categoricalColumn", obsDataframe, schema, + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type '{}' is not assignable to paramet... Remove this comment to see the full error message userColors ); expect(ct).toBeDefined(); const data = obsDataframe.col("categoricalColumn").asArray(); for (let i = 0; i < schema.dataframe.nObs; i += 1) { expect(makeScale(ct.rgb[i])).toEqual( + // @ts-expect-error ts-migrate(2722) FIXME: Cannot invoke an object which is possibly 'undefin... Remove this comment to see the full error message ct.scale(cats.indexOf(data[i])).toString() ); } @@ -154,31 +159,31 @@ TODO: 2. user defined colors */ -function indexSchema(schema) { +function indexSchema(schema: any) { schema.annotations.obsByName = Object.fromEntries( - schema.annotations?.obs?.columns?.map((v) => [v.name, v]) ?? [] + schema.annotations?.obs?.columns?.map((v: any) => [v.name, v]) ?? [] ); schema.annotations.varByName = Object.fromEntries( - schema.annotations?.var?.columns?.map((v) => [v.name, v]) ?? [] + schema.annotations?.var?.columns?.map((v: any) => [v.name, v]) ?? [] ); schema.layout.obsByName = Object.fromEntries( - schema.layout?.obs?.map((v) => [v.name, v]) ?? [] + schema.layout?.obs?.map((v: any) => [v.name, v]) ?? [] ); schema.layout.varByName = Object.fromEntries( - schema.layout?.var?.map((v) => [v.name, v]) ?? [] + schema.layout?.var?.map((v: any) => [v.name, v]) ?? [] ); return schema; } -function makeScale(rgb) { +function makeScale(rgb: any) { // make a scale string from a rgb float triple return `rgb(${(rgb[0] * 255) >>> 0}, ${(rgb[1] * 255) >>> 0}, ${ (rgb[2] * 256) >>> 0 })`; } -function shuffle(array) { +function shuffle(array: any) { for (let i = array.length - 1; i > 0; i -= 1) { const j = (Math.random() * (i + 1)) >>> 0; [array[i], array[j]] = [array[j], array[i]]; diff --git a/client/__tests__/util/stateManager/controlsHelpers.test.js b/client/__tests__/util/stateManager/controlsHelpers.test.ts similarity index 100% rename from client/__tests__/util/stateManager/controlsHelpers.test.js rename to client/__tests__/util/stateManager/controlsHelpers.test.ts diff --git a/client/__tests__/util/stateManager/fbs.test.js b/client/__tests__/util/stateManager/fbs.test.ts similarity index 87% rename from client/__tests__/util/stateManager/fbs.test.js rename to client/__tests__/util/stateManager/fbs.test.ts index b8bd3742..156dc53f 100644 --- a/client/__tests__/util/stateManager/fbs.test.js +++ b/client/__tests__/util/stateManager/fbs.test.ts @@ -24,6 +24,7 @@ describe("encode/decode", () => { expect(dfA.columns).toEqual(columns); const colIndex = new KeyIndex(["a", "b", "c", "d"]); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'KeyIndex' is not assignable to p... Remove this comment to see the full error message const dfWithColIdx = new Dataframe([3, 4], columns, null, colIndex); const dfB = decodeMatrixFBS(encodeMatrixFBS(dfWithColIdx)); expect([dfB.nRows, dfB.nCols]).toEqual(dfWithColIdx.dims); diff --git a/client/__tests__/util/stateManager/sampleResponses.js b/client/__tests__/util/stateManager/sampleResponses.ts similarity index 86% rename from client/__tests__/util/stateManager/sampleResponses.js rename to client/__tests__/util/stateManager/sampleResponses.ts index 7c54635a..78d33417 100644 --- a/client/__tests__/util/stateManager/sampleResponses.js +++ b/client/__tests__/util/stateManager/sampleResponses.ts @@ -75,6 +75,7 @@ const aSchemaResponse = { const anAnnotationsObsJSONResponse = { names: ["name", "field1", "field2", "field3", "field4"], + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0. data: _() .range(nObs) .map((idx) => [ @@ -91,6 +92,7 @@ const anAnnotationsObsJSONResponse = { const anAnnotationsVarJSONResponse = { names: ["fieldA", "fieldB", "fieldC", "fieldD", "name"], + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0. data: _() .range(nVar) .map((idx) => [ @@ -105,7 +107,7 @@ const anAnnotationsVarJSONResponse = { .value(), }; -function encodeTypedArray(builder, uType, uData) { +function encodeTypedArray(builder: any, uType: any, uData: any) { const uTypeName = NetEncoding.TypedArray[uType]; const ArrayType = NetEncoding[uTypeName]; const dv = ArrayType.createDataVector(builder, uData); @@ -114,7 +116,7 @@ function encodeTypedArray(builder, uType, uData) { return builder.endObject(); } -function encodeMatrix(columns, colIndex = undefined) { +function encodeMatrix(columns: any, colIndex = undefined) { /* IMPORTANT: this is not a general purpose encoder. in particular, it doesn't correctly handle all column index types, nor does it @@ -123,6 +125,7 @@ function encodeMatrix(columns, colIndex = undefined) { encodeMatrixFBS in matrix.py is more general. This is used only as a testing santity check (alt implementation). */ + // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1. const utf8Encoder = new TextEncoder("utf-8"); const builder = new flatbuffers.Builder(1024); const cols = map(columns, (carr) => { @@ -172,11 +175,13 @@ function encodeMatrix(columns, colIndex = undefined) { const anAnnotationsObsFBSResponse = (() => { const columns = zip(...anAnnotationsObsJSONResponse.data).slice(1); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message return encodeMatrix(columns, anAnnotationsObsJSONResponse.names); })(); const anAnnotationsVarFBSResponse = (() => { const columns = zip(...anAnnotationsVarJSONResponse.data).slice(1); + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message return encodeMatrix(columns, anAnnotationsVarJSONResponse.names); })(); @@ -185,11 +190,13 @@ const aLayoutFBSResponse = (() => { new Float32Array(nObs).fill(Math.random()), new Float32Array(nObs).fill(Math.random()), ]; + // @ts-expect-error ts-migrate(2345) FIXME: Argument of type 'string[]' is not assignable to p... Remove this comment to see the full error message return encodeMatrix(coords, ["umap_0", "umap_1"]); })(); const aDataObsResponse = { var: [2, 4, 29], + // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0. obs: _() .range(nObs) .map((idx) => [idx, Math.random(), Math.random(), Math.random()]) diff --git a/client/__tests__/util/typedCrossfilter/bitArray.test.js b/client/__tests__/util/typedCrossfilter/bitArray.test.ts similarity index 100% rename from client/__tests__/util/typedCrossfilter/bitArray.test.js rename to client/__tests__/util/typedCrossfilter/bitArray.test.ts diff --git a/client/__tests__/util/typedCrossfilter/crossfilter.test.js b/client/__tests__/util/typedCrossfilter/crossfilter.test.ts similarity index 90% rename from client/__tests__/util/typedCrossfilter/crossfilter.test.js rename to client/__tests__/util/typedCrossfilter/crossfilter.test.ts index 58fa60bb..8cf6ba11 100644 --- a/client/__tests__/util/typedCrossfilter/crossfilter.test.js +++ b/client/__tests__/util/typedCrossfilter/crossfilter.test.ts @@ -126,7 +126,7 @@ const someData = [ }, ]; -let payments = null; +let payments: any = null; beforeEach(() => { payments = new Crossfilter(someData); }); @@ -138,7 +138,12 @@ describe("ImmutableTypedCrossfilter", () => { expect(payments.all()).toEqual(someData); const p = payments - .addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array) + .addDimension( + "quantity", + "scalar", + (i: any, d: any) => d[i].quantity, + Int32Array + ) .select("quantity", { mode: "all" }); expect(p).toBeDefined(); expect(p.all()).toEqual(someData); @@ -158,7 +163,7 @@ describe("ImmutableTypedCrossfilter", () => { const p2 = payments.addDimension( "quantity", "scalar", - (i, data) => data[i].quantity, + (i: any, data: any) => data[i].quantity, Int32Array ); @@ -175,10 +180,20 @@ describe("ImmutableTypedCrossfilter", () => { test("select all and none", () => { let p = payments - .addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array) - .addDimension("tip", "scalar", (i, d) => d[i].tip, Float32Array) - .addDimension("total", "scalar", (i, d) => d[i].total, Float32Array) - .addDimension("type", "enum", (i, d) => d[i].type); + .addDimension( + "quantity", + "scalar", + (i: any, d: any) => d[i].quantity, + Int32Array + ) + .addDimension("tip", "scalar", (i: any, d: any) => d[i].tip, Float32Array) + .addDimension( + "total", + "scalar", + (i: any, d: any) => d[i].total, + Float32Array + ) + .addDimension("type", "enum", (i: any, d: any) => d[i].type); expect(p).toBeDefined(); /* expect all records to be selected - default init state */ @@ -230,11 +245,21 @@ describe("ImmutableTypedCrossfilter", () => { }); describe("scalar dimension", () => { - let p; + let p: any; beforeEach(() => { p = payments - .addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array) - .addDimension("tip", "scalar", (i, d) => d[i].tip, Float32Array) + .addDimension( + "quantity", + "scalar", + (i: any, d: any) => d[i].quantity, + Int32Array + ) + .addDimension( + "tip", + "scalar", + (i: any, d: any) => d[i].tip, + Float32Array + ) .select("tip", { mode: "all" }); }); @@ -277,9 +302,9 @@ describe("ImmutableTypedCrossfilter", () => { }); describe("enum dimension", () => { - let p; + let p: any; beforeEach(() => { - p = payments.addDimension("type", "enum", (i, d) => d[i].type); + p = payments.addDimension("type", "enum", (i: any, d: any) => d[i].type); }); test("all", () => { @@ -317,7 +342,7 @@ describe("ImmutableTypedCrossfilter", () => { }); describe("spatial dimension", () => { - let p; + let p: any; beforeEach(() => { const X = someData.map((r) => r.coords[0]); const Y = someData.map((r) => r.coords[1]); @@ -406,14 +431,19 @@ describe("ImmutableTypedCrossfilter", () => { }); describe("non-finite scalars", () => { - let p; + let p: any; beforeEach(() => { p = payments - .addDimension("quantity", "scalar", (i, d) => d[i].quantity, Int32Array) + .addDimension( + "quantity", + "scalar", + (i: any, d: any) => d[i].quantity, + Int32Array + ) .addDimension( "nonFinite", "scalar", - (i, d) => d[i].nonFinite, + (i: any, d: any) => d[i].nonFinite, Float32Array ) .select("quantity", { mode: "all" }); diff --git a/client/__tests__/util/typedCrossfilter/positiveInterval.test.js b/client/__tests__/util/typedCrossfilter/positiveInterval.test.ts similarity index 100% rename from client/__tests__/util/typedCrossfilter/positiveInterval.test.js rename to client/__tests__/util/typedCrossfilter/positiveInterval.test.ts diff --git a/client/__tests__/util/typedCrossfilter/sort.test.js b/client/__tests__/util/typedCrossfilter/sort.test.ts similarity index 89% rename from client/__tests__/util/typedCrossfilter/sort.test.js rename to client/__tests__/util/typedCrossfilter/sort.test.ts index f7650f4f..3585d3a2 100644 --- a/client/__tests__/util/typedCrossfilter/sort.test.js +++ b/client/__tests__/util/typedCrossfilter/sort.test.ts @@ -15,7 +15,7 @@ paths for: const pInf = Number.POSITIVE_INFINITY; const nInf = Number.NEGATIVE_INFINITY; -function fillRange(arr, start = 0) { +function fillRange(arr: any, start = 0) { const larr = arr; for (let i = 0, len = larr.length; i < len; i += 1) { larr[i] = i + start; @@ -23,7 +23,7 @@ function fillRange(arr, start = 0) { return larr; } -function fillRand(arr) { +function fillRand(arr: any) { for (let i = 0, len = arr.length; i < len; i += 1) { arr[i] = Math.random(); } @@ -48,16 +48,22 @@ describe("sortArray", () => { describe("finite numbers", () => { [Array, Float32Array, Uint32Array, Int32Array, Float64Array].map((Type) => test(Type.name, () => { + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. expect(sortArray(Type.from([6, 5, 4, 3, 2, 1, 0]))).toMatchObject( + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. Type.from([0, 1, 2, 3, 4, 5, 6]) ); + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. expect(sortArray(Type.from([6, 5, 4, 3, 2, 1]))).toMatchObject( + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. Type.from([1, 2, 3, 4, 5, 6]) ); const source = fillRand(new Type(1000)); + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. expect(sortArray(Type.from(source))).toMatchObject( + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. Type.from(source).sort() ); }) @@ -130,22 +136,24 @@ describe("sortIndex", () => { describe("finite numbers", () => { [Array, Float32Array, Uint32Array, Int32Array, Float64Array].map((Type) => test(Type.name, () => { + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. const source1 = Type.from([6, 5, 4, 3, 2, 1, 0]); const index1 = fillRange(new Uint32Array(source1.length)); expect(sortIndex(index1, source1)).toMatchObject( - index1.sort((a, b) => source1[a] - source1[b]) + index1.sort((a: any, b: any) => source1[a] - source1[b]) ); + // @ts-expect-error ts-migrate(2349) FIXME: This expression is not callable. const source2 = Type.from([6, 5, 4, 3, 2, 1]); const index2 = fillRange(new Uint32Array(source2.length)); expect(sortIndex(index2, source2)).toMatchObject( - index2.sort((a, b) => source1[a] - source1[b]) + index2.sort((a: any, b: any) => source1[a] - source1[b]) ); const source3 = fillRand(new Type(1000)); const index3 = fillRange(new Uint32Array(source3.length)); expect(sortIndex(index3, source3)).toMatchObject( - index3.sort((a, b) => source1[a] - source1[b]) + index3.sort((a: any, b: any) => source1[a] - source1[b]) ); }) ); diff --git a/client/__tests__/util/typedCrossfilter/util.test.js b/client/__tests__/util/typedCrossfilter/util.test.ts similarity index 100% rename from client/__tests__/util/typedCrossfilter/util.test.js rename to client/__tests__/util/typedCrossfilter/util.test.ts diff --git a/client/configuration/babel/babel.dev.js b/client/configuration/babel/babel.dev.js index 117f6da5..dac924c6 100644 --- a/client/configuration/babel/babel.dev.js +++ b/client/configuration/babel/babel.dev.js @@ -11,6 +11,7 @@ module.exports = { }, ], "@babel/preset-react", + "@babel/preset-typescript", ], plugins: [ "@babel/plugin-proposal-function-bind", diff --git a/client/configuration/babel/babel.prod.js b/client/configuration/babel/babel.prod.js index 620cd563..926d6fdc 100644 --- a/client/configuration/babel/babel.prod.js +++ b/client/configuration/babel/babel.prod.js @@ -10,6 +10,7 @@ module.exports = { }, ], "@babel/preset-react", + "@babel/preset-typescript" ], plugins: [ "@babel/plugin-proposal-function-bind", diff --git a/client/configuration/eslint/eslint.js b/client/configuration/eslint/eslint.js index 43d98059..24ad3a37 100644 --- a/client/configuration/eslint/eslint.js +++ b/client/configuration/eslint/eslint.js @@ -1,13 +1,12 @@ module.exports = { root: true, - parser: "babel-eslint", + parser: "@typescript-eslint/parser", extends: [ - "airbnb", + "airbnb-typescript", "plugin:eslint-comments/recommended", "plugin:@blueprintjs/recommended", "plugin:compat/recommended", "plugin:prettier/recommended", - "prettier", ], settings: { // AbortController is not supported in iOS Safari 10.3, Chrome 61 @@ -32,18 +31,47 @@ module.exports = { jsx: true, generators: true, }, + project: "./tsconfig.json", }, rules: { "react/jsx-no-target-blank": "off", "eslint-comments/require-description": ["error"], "no-magic-numbers": "off", + "@typescript-eslint/no-magic-numbers": "off", "no-nested-ternary": "off", "func-style": "off", "arrow-parens": "off", "no-use-before-define": "off", + "@typescript-eslint/no-use-before-define": "off", "react/jsx-filename-extension": "off", "comma-dangle": "off", + "@typescript-eslint/comma-dangle": "off", "no-underscore-dangle": "off", + // Override airbnb config to allow leading underscore + // https://github.com/iamturns/eslint-config-airbnb-typescript/blob/master/lib/shared.js#L35 + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "class", + format: ["PascalCase"], + leadingUnderscore: "allow", + }, + { + selector: "function", + format: ["camelCase", "PascalCase"], + leadingUnderscore: "allowSingleOrDouble", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "variable", + format: ["camelCase", "PascalCase", "UPPER_CASE"], + leadingUnderscore: "allowSingleOrDouble", + trailingUnderscore: "allowDouble", + }, + ], "implicit-arrow-linebreak": "off", "no-console": "off", "spaced-comment": ["error", "always", { exceptions: ["*"] }], @@ -51,6 +79,7 @@ module.exports = { "object-curly-newline": ["error", { consistent: true }], "react/prop-types": [0], "space-before-function-paren": "off", + "@typescript-eslint/space-before-function-paren": "off", "function-paren-newline": "off", "prefer-destructuring": ["error", { object: true, array: false }], "import/prefer-default-export": "off", @@ -69,9 +98,9 @@ module.exports = { }, overrides: [ { - files: ["**/*.test.js"], + files: ["**/*.test.ts"], env: { - jest: true, // now **/*.test.js files' env has both es6 *and* jest + jest: true, // now **/*.test.ts files' env has both es6 *and* jest }, // Can't extend in overrides: https://github.com/eslint/eslint/issues/8813 // "extends": ["plugin:jest/recommended"] diff --git a/client/configuration/lint-staged/lint-staged.config.js b/client/configuration/lint-staged/lint-staged.config.js index e8a2415d..8a8a25c0 100644 --- a/client/configuration/lint-staged/lint-staged.config.js +++ b/client/configuration/lint-staged/lint-staged.config.js @@ -1,3 +1,3 @@ module.exports = { - "*.js": "eslint --fix", + "*.{js,ts,jsx,tsx}": "eslint --fix", }; diff --git a/client/configuration/webpack/webpack.config.dev.js b/client/configuration/webpack/webpack.config.dev.js index 408cb1e0..16d291b4 100644 --- a/client/configuration/webpack/webpack.config.dev.js +++ b/client/configuration/webpack/webpack.config.dev.js @@ -23,7 +23,7 @@ const devConfig = { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(ts|js)x?$/, loader: "babel-loader", options: babelOptions, }, diff --git a/client/configuration/webpack/webpack.config.prod.js b/client/configuration/webpack/webpack.config.prod.js index f9a63403..9a6b9c5f 100644 --- a/client/configuration/webpack/webpack.config.prod.js +++ b/client/configuration/webpack/webpack.config.prod.js @@ -38,7 +38,7 @@ const prodConfig = { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(ts|js)x?$/, loader: "babel-loader", options: babelOptions, }, diff --git a/client/configuration/webpack/webpack.config.shared.js b/client/configuration/webpack/webpack.config.shared.js index 0f98b59d..b54274ce 100644 --- a/client/configuration/webpack/webpack.config.shared.js +++ b/client/configuration/webpack/webpack.config.shared.js @@ -29,6 +29,9 @@ module.exports = { path: path.resolve("build"), publicPath, }, + resolve: { + extensions: [".ts", ".tsx", "..."], + }, module: { rules: [ { diff --git a/client/package-lock.json b/client/package-lock.json index c61504e8..015f4c4e 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -61,10 +61,38 @@ "@babel/plugin-transform-runtime": "^7.13.15", "@babel/preset-env": "^7.13.15", "@babel/preset-react": "^7.13.13", + "@babel/preset-typescript": "^7.14.5", "@babel/register": "^7.13.16", "@babel/runtime": "^7.13.16", "@blueprintjs/eslint-plugin": "^0.3.0", "@sentry/webpack-plugin": "^1.15.0", + "@types/d3": "^7.0.0", + "@types/d3-scale-chromatic": "^3.0.0", + "@types/expect-puppeteer": "^4.4.6", + "@types/flatbuffers": "^1.10.0", + "@types/is-number": "^7.0.1", + "@types/jest": "^26.0.24", + "@types/jest-environment-puppeteer": "^4.4.1", + "@types/lodash.clonedeep": "^4.5.6", + "@types/lodash.difference": "^4.5.6", + "@types/lodash.every": "^4.6.6", + "@types/lodash.filter": "^4.6.6", + "@types/lodash.foreach": "^4.5.6", + "@types/lodash.isnumber": "^3.0.6", + "@types/lodash.map": "^4.6.13", + "@types/lodash.pull": "^4.1.6", + "@types/lodash.sortby": "^4.7.6", + "@types/lodash.uniq": "^4.5.6", + "@types/lodash.zip": "^4.2.6", + "@types/pako": "^1.0.2", + "@types/puppeteer": "^5.4.4", + "@types/react": "^17.0.14", + "@types/react-dom": "^17.0.9", + "@types/react-helmet": "^6.1.2", + "@types/react-redux": "^7.1.18", + "@types/sha1": "^1.1.3", + "@typescript-eslint/eslint-plugin": "^4.28.4", + "@typescript-eslint/parser": "^4.28.4", "babel-eslint": "^10.1.0", "babel-jest": "^26.1.0", "babel-loader": "^8.1.0", @@ -77,7 +105,7 @@ "connect-history-api-fallback": "^1.6.0", "css-loader": "^5.2.4", "eslint": "^7.24.0", - "eslint-config-airbnb": "^18.2.0", + "eslint-config-airbnb-typescript": "^12.3.1", "eslint-config-prettier": "^8.2.0", "eslint-loader": "^4.0.2", "eslint-plugin-compat": "^3.8.0", @@ -120,6 +148,7 @@ "style-loader": "^2.0.0", "sw-precache-webpack-plugin": "^1.0.0", "terser-webpack-plugin": "^5.1.1", + "typescript": "^4.3.5", "url-loader": "^4.1.0", "webpack": "^5.34.0", "webpack-cli": "^4.6.0", @@ -1099,12 +1128,15 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { @@ -1139,17 +1171,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/core/node_modules/@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.13.16", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, "node_modules/@babel/core/node_modules/@babel/helper-compilation-targets": { "version": "7.13.16", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", @@ -1162,46 +1183,30 @@ "semver": "^6.3.0" } }, - "node_modules/@babel/core/node_modules/@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/types": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.16.tgz", - "integrity": "sha512-7enM8Wxhrl1hB1+k6+xO6RmxpNkaveRWkdpyii8DkrLWRgr0l3x29/SEuhTIkP+ynHsU/Hpjn8Evd/axv/ll6Q==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, "node_modules/@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", "dev": true, "dependencies": { - "@babel/types": "^7.13.0", + "@babel/types": "^7.14.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { @@ -1227,16 +1232,23 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", + "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", "dev": true, "dependencies": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { @@ -1275,42 +1287,53 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", - "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "dev": true, "dependencies": { - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", "dev": true, "dependencies": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { @@ -1339,19 +1362,25 @@ } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", - "dev": true + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.13.0", @@ -1365,15 +1394,18 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { @@ -1395,25 +1427,34 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", - "dev": true + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-wrap-function": { "version": "7.13.0", @@ -1438,25 +1479,18 @@ "@babel/types": "^7.13.16" } }, - "node_modules/@babel/helpers/node_modules/@babel/types": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.16.tgz", - "integrity": "sha512-7enM8Wxhrl1hB1+k6+xO6RmxpNkaveRWkdpyii8DkrLWRgr0l3x29/SEuhTIkP+ynHsU/Hpjn8Evd/axv/ll6Q==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - }, "node_modules/@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight/node_modules/chalk": { @@ -1474,9 +1508,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", - "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1808,6 +1842,21 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", @@ -2165,6 +2214,23 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz", + "integrity": "sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==", + "dev": true, + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.14.6", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", @@ -2288,6 +2354,23 @@ "@babel/plugin-transform-react-pure-annotations": "^7.12.1" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz", + "integrity": "sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/register": { "version": "7.13.16", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.16.tgz", @@ -2363,41 +2446,50 @@ } }, "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", - "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.15", - "@babel/types": "^7.13.14", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@bcoe/v8-coverage": { @@ -2801,6 +2893,7 @@ "jest-resolve": "^26.6.2", "jest-util": "^26.6.2", "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -3293,12 +3386,12 @@ } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -3306,21 +3399,21 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { @@ -3454,6 +3547,259 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/d3": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.0.0.tgz", + "integrity": "sha512-7rMMuS5unvbvFCJXAkQXIxWTo2OUlmVXN5q7sfQFesuVICY55PSP6hhbUhWjTTNpfTTB3iLALsIYDFe7KUNABw==", + "dev": true, + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.1.tgz", + "integrity": "sha512-D/G7oG0czeszALrkdUiV68CDiHDxXf+M2mLVqAyKktGd12VKQQljj1sHJGBKjcK4jRH1biBd6ZPQPHpJ0mNa0w==", + "dev": true + }, + "node_modules/@types/d3-axis": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.1.tgz", + "integrity": "sha512-zji/iIbdd49g9WN0aIsGcwcTBUkgLsCSwB+uH+LPVDAiKWENMtI3cJEWt+7/YYwelMoZmbBfzA3qCdrZ2XFNnw==", + "dev": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.1.tgz", + "integrity": "sha512-B532DozsiTuQMHu2YChdZU0qsFJSio3Q6jmBYGYNp3gMDzBmuFFgPt9qKA4VYuLZMp4qc6eX7IUFUEsvHiXZAw==", + "dev": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-eQfcxIHrg7V++W8Qxn6QkqBNBokyhdWSAS73AbkbMzvLQmVVBviknoz2SRS/ZJdIOmhcmmdCRE/NFOm28Z1AMw==", + "dev": true + }, + "node_modules/@types/d3-color": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.0.2.tgz", + "integrity": "sha512-WVx6zBiz4sWlboCy7TCgjeyHpNjMsoF36yaagny1uXfbadc9f+5BeBf7U+lRmQqY3EHbGQpP8UdW8AC+cywSwQ==", + "dev": true + }, + "node_modules/@types/d3-contour": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.1.tgz", + "integrity": "sha512-C3zfBrhHZvrpAAK3YXqLWVAGo87A4SvJ83Q/zVJ8rFWJdKejUnDYaWZPkA8K84kb2vDA/g90LTQAz7etXcgoQQ==", + "dev": true, + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.0.tgz", + "integrity": "sha512-iGm7ZaGLq11RK3e69VeMM6Oqj2SjKUB9Qhcyd1zIcqn2uE8w9GFB445yCY46NOQO3ByaNyktX1DK+Etz7ZaX+w==", + "dev": true + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-NhxMn3bAkqhjoxabVJWKryhnZXXYYVQxaBnbANu0O94+O/nX9qSjrA1P1jbAQJxJf+VC72TxDX/YJcKue5bRqw==", + "dev": true + }, + "node_modules/@types/d3-drag": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.1.tgz", + "integrity": "sha512-o1Va7bLwwk6h03+nSM8dpaGEYnoIG19P0lKqlic8Un36ymh9NSkNFX1yiXMKNMx8rJ0Kfnn2eovuFaL6Jvj0zA==", + "dev": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.0.tgz", + "integrity": "sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A==", + "dev": true + }, + "node_modules/@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==", + "dev": true + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-toZJNOwrOIqz7Oh6Q7l2zkaNfXkfR7mFSJvGvlD/Ciq/+SQ39d5gynHJZ/0fjt83ec3WL7+u3ssqIijQtBISsw==", + "dev": true, + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.3.tgz", + "integrity": "sha512-z8GteGVfkWJMKsx6hwC3SiTSLspL98VNpmvLpEFJQpZPq6xpA1I8HNBDNSpukfK0Vb0l64zGFhzunLgEAcBWSA==", + "dev": true + }, + "node_modules/@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "dev": true + }, + "node_modules/@types/d3-geo": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.2.tgz", + "integrity": "sha512-DbqK7MLYA8LpyHQfv6Klz0426bQEf7bRTvhMy44sNGVyZoWn//B0c+Qbeg8Osi2Obdc9BLLXYAKpyWege2/7LQ==", + "dev": true, + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.0.2.tgz", + "integrity": "sha512-+krnrWOZ+aQB6v+E+jEkmkAx9HvsNAD+1LCD0vlBY3t+HwjKnsBFbpVLx6WWzDzCIuiTWdAxXMEnGnVXpB09qQ==", + "dev": true + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "dev": true, + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==", + "dev": true + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz", + "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==", + "dev": true + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.2.tgz", + "integrity": "sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==", + "dev": true + }, + "node_modules/@types/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==", + "dev": true + }, + "node_modules/@types/d3-scale": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.1.tgz", + "integrity": "sha512-GDuXcRcR6mKcpUVMhPNttpOzHi2dP6YcDqLZYSZHgwTZ+sfCa8e9q0VEBwZomblAPNMYpVqxojnSyIEb4s/Pwg==", + "dev": true, + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==", + "dev": true + }, + "node_modules/@types/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-SZsDWFG1dLV9ivX2wGDPFWgLUf71tF4aupfEMTYMrbArHwEMLhmv3TS1CZECLQgoTttdpM1g5Z6JwRP7zoInWg==", + "dev": true + }, + "node_modules/@types/d3-shape": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.0.2.tgz", + "integrity": "sha512-5+ButCmIfNX8id5seZ7jKj3igdcxx+S9IDBiT35fQGTLZUfkFgTv+oBH34xgeoWDKpWcMITSzBILWQtBoN5Piw==", + "dev": true, + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "dev": true + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.0.tgz", + "integrity": "sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==", + "dev": true + }, + "node_modules/@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==", + "dev": true + }, + "node_modules/@types/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-Sv4qEI9uq3bnZwlOANvYK853zvpdKEm1yz9rcc8ZTsxvRklcs9Fx4YFuGA3gXoQN/c/1T6QkVNjhaRO/cWj94g==", + "dev": true, + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz", + "integrity": "sha512-7s5L9TjfqIYQmQQEUcpMAcBOahem7TRoSO/+Gkz02GbMVuULiZzjF2BOdw291dbO2aNon4m2OdFsRGaCq2caLQ==", + "dev": true, + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/dom4": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/dom4/-/dom4-2.0.1.tgz", @@ -3485,6 +3831,16 @@ "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", "dev": true }, + "node_modules/@types/expect-puppeteer": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/expect-puppeteer/-/expect-puppeteer-4.4.6.tgz", + "integrity": "sha512-RgQND/7RvcJm4NL2qoQbvVHTcfDh3h3yYe0Em0roczXY+MOIBkcgv5WRzVKeQJKO1nyhc4bEAbxpwykjDUMdqg==", + "dev": true, + "dependencies": { + "@types/jest": "*", + "@types/puppeteer": "*" + } + }, "node_modules/@types/favicons": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@types/favicons/-/favicons-5.5.0.tgz", @@ -3494,6 +3850,18 @@ "@types/node": "*" } }, + "node_modules/@types/flatbuffers": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==", + "dev": true + }, + "node_modules/@types/geojson": { + "version": "7946.0.8", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", + "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", + "dev": true + }, "node_modules/@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -3528,6 +3896,12 @@ "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", "dev": true }, + "node_modules/@types/is-number": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@types/is-number/-/is-number-7.0.1.tgz", + "integrity": "sha512-X8x3GugC4+84FEukgkKT75SkSVdzdeZJzy5k7n5CRB7/jk0PgeYwe2O5qRx7qOTnKkLNMVOP2d190R7VWzbzEw==", + "dev": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -3552,6 +3926,27 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jest": { + "version": "26.0.24", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", + "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", + "dev": true, + "dependencies": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "node_modules/@types/jest-environment-puppeteer": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/jest-environment-puppeteer/-/jest-environment-puppeteer-4.4.1.tgz", + "integrity": "sha512-LiZTD6i63le6QMnxi7pJB0SFv/fWtss6VVEEDm/UaeowBgjduf8txyE//j3WEeDPxngTvioUjbzA7Rc6Wc3cBA==", + "dev": true, + "dependencies": { + "@jest/types": ">=24 <=26", + "@types/puppeteer": "*", + "jest-environment-node": ">=24 <=26" + } + }, "node_modules/@types/json-schema": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", @@ -3564,6 +3959,111 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, + "node_modules/@types/lodash.clonedeep": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz", + "integrity": "sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.difference": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.difference/-/lodash.difference-4.5.6.tgz", + "integrity": "sha512-wXH53r+uoUCrKhmh7S5Gf6zo3vpsx/zH2R4pvkmDlmopmMTCROAUXDpPMXATGCWkCjE6ik3VZzZUxBgMjZho9Q==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.every": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.every/-/lodash.every-4.6.6.tgz", + "integrity": "sha512-eZC30bvV8GtmVUcMMhdAS+C2VgmkLMhnLyjTlf2lsPxhiquHfr/f0EnlX20l4xQWXG3B7H+OTSoWPqONyCeD2Q==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.filter": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.filter/-/lodash.filter-4.6.6.tgz", + "integrity": "sha512-K9oEglaInmu7pnQnZYdciNePpKe0W7O9yssnCza9mLjpq5N5Ju8RIMwTvp9tovb8V5yemxFTJqHzG+tIkAl1xw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.foreach": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.foreach/-/lodash.foreach-4.5.6.tgz", + "integrity": "sha512-A8+157A+27zwJSstmW/eWPc9lHLJNEer4jiMlsyxWieBxEx0arwB9vgQm+iai6DEDYYQuufHrzVhQOiapCalQQ==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.isnumber": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/lodash.isnumber/-/lodash.isnumber-3.0.6.tgz", + "integrity": "sha512-nnfRqgijLFBEVu8W6pkHGq4hefaQOMcVwqeY19qIpf4qhV04mczNZvyT4Hc8UjOcnCIXErQG0aqIJedqlbbvVw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.map": { + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/@types/lodash.map/-/lodash.map-4.6.13.tgz", + "integrity": "sha512-kppRBzlpuvQQsr7R2nv/DDDZds8fglRFNAK70WUOkOC18KOcuQ22oQF9Kgy5Z2v/eDNkBm0ltrT6FThSkuWwow==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.pull": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/lodash.pull/-/lodash.pull-4.1.6.tgz", + "integrity": "sha512-pK+efqDL+Of68Gqd81LfOdBAmB5X6+SHM6kkUTTFQWqOPAomn3BWJcASLrr998SRE7aYLnDVmM5wLLbS7T159A==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.sortby": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@types/lodash.sortby/-/lodash.sortby-4.7.6.tgz", + "integrity": "sha512-EnvAOmKvEg7gdYpYrS6+fVFPw5dL9rBnJi3vcKI7wqWQcLJVF/KRXK9dH29HjGNVvFUj0s9prRP3J8jEGnGKDw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.uniq": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.uniq/-/lodash.uniq-4.5.6.tgz", + "integrity": "sha512-XHNMXBtiwsWZstZMyxOYjr0e8YYWv0RgPlzIHblTuwBBiWo2MzWVaTBihtBpslb5BglgAWIeBv69qt1+RTRW1A==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/lodash.zip": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@types/lodash.zip/-/lodash.zip-4.2.6.tgz", + "integrity": "sha512-mKAcnkyFaihVR1oK83ZBQqSSQ1hpAY+uD5QaDkf//xtvr4NlNwqJEDg/oQoqLJg5YdSEwVWlQq0Aq4oLvD3zuw==", + "dev": true, + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -3582,6 +4082,12 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "node_modules/@types/pako": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz", + "integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==", + "dev": true + }, "node_modules/@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -3599,6 +4105,15 @@ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, + "node_modules/@types/puppeteer": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.4.tgz", + "integrity": "sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -3606,19 +4121,37 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz", - "integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==", + "version": "17.0.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.14.tgz", + "integrity": "sha512-0WwKHUbWuQWOce61UexYuWTGuGY/8JvtUe/dtQ6lR4sZ3UiylHotJeWpf3ArP9+DSGUoLY3wbU59VyMrJps5VQ==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, + "node_modules/@types/react-dom": { + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", + "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-helmet": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.2.tgz", + "integrity": "sha512-dcfAZNlWb5JYFbO9CGfrPWLJAyFcT6UeR3u35eBbv8liY2Rg4K7fM1G5+HnwVgot+C+kVwXAZ8pLEn2jsMfTDg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/react-redux": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", - "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.18.tgz", + "integrity": "sha512-9iwAsPyJ9DLTRH+OFeIrm9cAbIj1i2ANL3sKQFATqnPWRbg+jEFXyZOKHiQK/N86pNRXbb4HRxAxo0SIX1XwzQ==", "dependencies": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -3631,6 +4164,15 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" }, + "node_modules/@types/sha1": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/sha1/-/sha1-1.1.3.tgz", + "integrity": "sha512-bXfx/6xrPu1l6pLItGRMPX00lhnJavpj2qiQeLHflXvL2Ix97aC8FTF2/pQoqukRzcCwKyN3csZvOLzamIoaSA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", @@ -3662,61 +4204,176 @@ "@types/node": "*" } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.4.tgz", + "integrity": "sha512-s1oY4RmYDlWMlcV0kKPBaADn46JirZzvvH7c2CtAqxCY96S538JRBAzt83RrfkDheV/+G/vWNK0zek+8TB3Gmw==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "@typescript-eslint/experimental-utils": "4.28.4", + "@typescript-eslint/scope-manager": "4.28.4", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.4.tgz", + "integrity": "sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.4", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/typescript-estree": "4.28.4", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.4.tgz", + "integrity": "sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.28.4", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/typescript-estree": "4.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.4.tgz", + "integrity": "sha512-ZJBNs4usViOmlyFMt9X9l+X0WAFcDH7EdSArGqpldXu7aeZxDAuAzHiMAeI+JpSefY2INHrXeqnha39FVqXb8w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/visitor-keys": "4.28.4" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.4.tgz", + "integrity": "sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.4.tgz", + "integrity": "sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/visitor-keys": "4.28.4", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { @@ -3735,16 +4392,20 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.4.tgz", + "integrity": "sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/types": "4.28.4", "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@webassemblyjs/ast": { @@ -7672,7 +8333,8 @@ "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -7834,6 +8496,17 @@ "node": ">= 6" } }, + "node_modules/eslint-config-airbnb-typescript": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-12.3.1.tgz", + "integrity": "sha512-ql/Pe6/hppYuRp4m3iPaHJqkBB7dgeEmGPQ6X0UNmrQOfTF+dXw29/ZjU2kQ6RDoLxaxOA+Xqv07Vbef6oVTWw==", + "dev": true, + "dependencies": { + "@typescript-eslint/parser": "^4.4.1", + "eslint-config-airbnb": "^18.2.0", + "eslint-config-airbnb-base": "^14.2.0" + } + }, "node_modules/eslint-config-prettier": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", @@ -8970,6 +9643,7 @@ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "dependencies": { + "@types/yauzl": "^2.9.1", "debug": "^4.1.1", "get-stream": "^5.1.0", "yauzl": "^2.10.0" @@ -9018,17 +9692,16 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" }, "engines": { "node": ">=8" @@ -9061,9 +9734,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -9828,9 +10501,9 @@ } }, "node_modules/globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "dependencies": { "array-union": "^2.1.0", @@ -9842,6 +10515,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/got": { @@ -11512,6 +12188,7 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -16958,7 +17635,21 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, "node_modules/randombytes": { "version": "2.1.0", @@ -17995,6 +18686,20 @@ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { "queue-microtask": "^1.2.2" } @@ -20437,6 +21142,19 @@ "is-typedarray": "^1.0.0" } }, + "node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", @@ -22739,12 +23457,12 @@ } }, "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" } }, "@babel/compat-data": { @@ -22776,17 +23494,6 @@ "source-map": "^0.5.0" }, "dependencies": { - "@babel/generator": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", - "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", - "dev": true, - "requires": { - "@babel/types": "^7.13.16", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, "@babel/helper-compilation-targets": { "version": "7.13.16", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", @@ -22798,43 +23505,27 @@ "browserslist": "^4.14.5", "semver": "^6.3.0" } - }, - "@babel/parser": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", - "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==", - "dev": true - }, - "@babel/types": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.16.tgz", - "integrity": "sha512-7enM8Wxhrl1hB1+k6+xO6RmxpNkaveRWkdpyii8DkrLWRgr0l3x29/SEuhTIkP+ynHsU/Hpjn8Evd/axv/ll6Q==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } } } }, "@babel/generator": { - "version": "7.13.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.9.tgz", - "integrity": "sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", "dev": true, "requires": { - "@babel/types": "^7.13.0", + "@babel/types": "^7.14.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-annotate-as-pure": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", - "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz", + "integrity": "sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -22860,16 +23551,17 @@ } }, "@babel/helper-create-class-features-plugin": { - "version": "7.13.11", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.11.tgz", - "integrity": "sha512-ays0I7XYq9xbjCSvT+EvysLgfc3tOkwCULHjrnscGT3A9qD4sk3wXnJ3of0MAWsWGjdinFvajHU2smYuqXKMrw==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz", + "integrity": "sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-member-expression-to-functions": "^7.13.0", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/helper-replace-supers": "^7.13.0", - "@babel/helper-split-export-declaration": "^7.12.13" + "@babel/helper-annotate-as-pure": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5" } }, "@babel/helper-create-regexp-features-plugin": { @@ -22908,42 +23600,41 @@ } }, "@babel/helper-function-name": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", - "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" } }, "@babel/helper-hoist-variables": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz", - "integrity": "sha512-0kBzvXiIKfsCA0y6cFEIJf4OdzfpRuNk4+YTeHZpGGc666SATFKTz6sRncwFnQk7/ugJ4dSrCj6iJuvW4Qwr2g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "dev": true, "requires": { - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/types": "^7.14.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", - "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", "dev": true, "requires": { - "@babel/types": "^7.13.12" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-imports": { @@ -22972,18 +23663,18 @@ } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", - "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" } }, "@babel/helper-plugin-utils": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", - "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true }, "@babel/helper-remap-async-to-generator": { @@ -22998,15 +23689,15 @@ } }, "@babel/helper-replace-supers": { - "version": "7.13.12", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", - "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.13.12", - "@babel/helper-optimise-call-expression": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.12" + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-simple-access": { @@ -23028,24 +23719,24 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.12.17", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", - "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, "@babel/helper-wrap-function": { @@ -23069,27 +23760,15 @@ "@babel/template": "^7.12.13", "@babel/traverse": "^7.13.15", "@babel/types": "^7.13.16" - }, - "dependencies": { - "@babel/types": { - "version": "7.13.16", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.16.tgz", - "integrity": "sha512-7enM8Wxhrl1hB1+k6+xO6RmxpNkaveRWkdpyii8DkrLWRgr0l3x29/SEuhTIkP+ynHsU/Hpjn8Evd/axv/ll6Q==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/highlight": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", - "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -23108,9 +23787,9 @@ } }, "@babel/parser": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", - "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", "dev": true }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { @@ -23433,6 +24112,15 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, "@babel/plugin-transform-arrow-functions": { "version": "7.13.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz", @@ -23790,6 +24478,17 @@ "@babel/helper-plugin-utils": "^7.12.13" } }, + "@babel/plugin-transform-typescript": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz", + "integrity": "sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.14.6", + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/plugin-syntax-typescript": "^7.14.5" + } + }, "@babel/plugin-transform-unicode-escapes": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz", @@ -23913,6 +24612,17 @@ "@babel/plugin-transform-react-pure-annotations": "^7.12.1" } }, + "@babel/preset-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz", + "integrity": "sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "@babel/plugin-transform-typescript": "^7.14.5" + } + }, "@babel/register": { "version": "7.13.16", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.13.16.tgz", @@ -23985,40 +24695,40 @@ } }, "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/traverse": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", - "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-function-name": "^7.12.13", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.15", - "@babel/types": "^7.13.14", + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.13.14", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.14.tgz", - "integrity": "sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" } }, @@ -24843,28 +25553,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -24982,6 +25692,259 @@ "@babel/types": "^7.3.0" } }, + "@types/d3": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.0.0.tgz", + "integrity": "sha512-7rMMuS5unvbvFCJXAkQXIxWTo2OUlmVXN5q7sfQFesuVICY55PSP6hhbUhWjTTNpfTTB3iLALsIYDFe7KUNABw==", + "dev": true, + "requires": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "@types/d3-array": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.1.tgz", + "integrity": "sha512-D/G7oG0czeszALrkdUiV68CDiHDxXf+M2mLVqAyKktGd12VKQQljj1sHJGBKjcK4jRH1biBd6ZPQPHpJ0mNa0w==", + "dev": true + }, + "@types/d3-axis": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.1.tgz", + "integrity": "sha512-zji/iIbdd49g9WN0aIsGcwcTBUkgLsCSwB+uH+LPVDAiKWENMtI3cJEWt+7/YYwelMoZmbBfzA3qCdrZ2XFNnw==", + "dev": true, + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-brush": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.1.tgz", + "integrity": "sha512-B532DozsiTuQMHu2YChdZU0qsFJSio3Q6jmBYGYNp3gMDzBmuFFgPt9qKA4VYuLZMp4qc6eX7IUFUEsvHiXZAw==", + "dev": true, + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-eQfcxIHrg7V++W8Qxn6QkqBNBokyhdWSAS73AbkbMzvLQmVVBviknoz2SRS/ZJdIOmhcmmdCRE/NFOm28Z1AMw==", + "dev": true + }, + "@types/d3-color": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.0.2.tgz", + "integrity": "sha512-WVx6zBiz4sWlboCy7TCgjeyHpNjMsoF36yaagny1uXfbadc9f+5BeBf7U+lRmQqY3EHbGQpP8UdW8AC+cywSwQ==", + "dev": true + }, + "@types/d3-contour": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.1.tgz", + "integrity": "sha512-C3zfBrhHZvrpAAK3YXqLWVAGo87A4SvJ83Q/zVJ8rFWJdKejUnDYaWZPkA8K84kb2vDA/g90LTQAz7etXcgoQQ==", + "dev": true, + "requires": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "@types/d3-delaunay": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.0.tgz", + "integrity": "sha512-iGm7ZaGLq11RK3e69VeMM6Oqj2SjKUB9Qhcyd1zIcqn2uE8w9GFB445yCY46NOQO3ByaNyktX1DK+Etz7ZaX+w==", + "dev": true + }, + "@types/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-NhxMn3bAkqhjoxabVJWKryhnZXXYYVQxaBnbANu0O94+O/nX9qSjrA1P1jbAQJxJf+VC72TxDX/YJcKue5bRqw==", + "dev": true + }, + "@types/d3-drag": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.1.tgz", + "integrity": "sha512-o1Va7bLwwk6h03+nSM8dpaGEYnoIG19P0lKqlic8Un36ymh9NSkNFX1yiXMKNMx8rJ0Kfnn2eovuFaL6Jvj0zA==", + "dev": true, + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-dsv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.0.tgz", + "integrity": "sha512-o0/7RlMl9p5n6FQDptuJVMxDf/7EDEv2SYEO/CwdG2tr1hTfUVi0Iavkk2ax+VpaQ/1jVhpnj5rq1nj8vwhn2A==", + "dev": true + }, + "@types/d3-ease": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz", + "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA==", + "dev": true + }, + "@types/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-toZJNOwrOIqz7Oh6Q7l2zkaNfXkfR7mFSJvGvlD/Ciq/+SQ39d5gynHJZ/0fjt83ec3WL7+u3ssqIijQtBISsw==", + "dev": true, + "requires": { + "@types/d3-dsv": "*" + } + }, + "@types/d3-force": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.3.tgz", + "integrity": "sha512-z8GteGVfkWJMKsx6hwC3SiTSLspL98VNpmvLpEFJQpZPq6xpA1I8HNBDNSpukfK0Vb0l64zGFhzunLgEAcBWSA==", + "dev": true + }, + "@types/d3-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.1.tgz", + "integrity": "sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==", + "dev": true + }, + "@types/d3-geo": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.2.tgz", + "integrity": "sha512-DbqK7MLYA8LpyHQfv6Klz0426bQEf7bRTvhMy44sNGVyZoWn//B0c+Qbeg8Osi2Obdc9BLLXYAKpyWege2/7LQ==", + "dev": true, + "requires": { + "@types/geojson": "*" + } + }, + "@types/d3-hierarchy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.0.2.tgz", + "integrity": "sha512-+krnrWOZ+aQB6v+E+jEkmkAx9HvsNAD+1LCD0vlBY3t+HwjKnsBFbpVLx6WWzDzCIuiTWdAxXMEnGnVXpB09qQ==", + "dev": true + }, + "@types/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==", + "dev": true, + "requires": { + "@types/d3-color": "*" + } + }, + "@types/d3-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz", + "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg==", + "dev": true + }, + "@types/d3-polygon": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz", + "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw==", + "dev": true + }, + "@types/d3-quadtree": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.2.tgz", + "integrity": "sha512-QNcK8Jguvc8lU+4OfeNx+qnVy7c0VrDJ+CCVFS9srBo2GL9Y18CnIxBdTF3v38flrGy5s1YggcoAiu6s4fLQIw==", + "dev": true + }, + "@types/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ==", + "dev": true + }, + "@types/d3-scale": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.1.tgz", + "integrity": "sha512-GDuXcRcR6mKcpUVMhPNttpOzHi2dP6YcDqLZYSZHgwTZ+sfCa8e9q0VEBwZomblAPNMYpVqxojnSyIEb4s/Pwg==", + "dev": true, + "requires": { + "@types/d3-time": "*" + } + }, + "@types/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw==", + "dev": true + }, + "@types/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-SZsDWFG1dLV9ivX2wGDPFWgLUf71tF4aupfEMTYMrbArHwEMLhmv3TS1CZECLQgoTttdpM1g5Z6JwRP7zoInWg==", + "dev": true + }, + "@types/d3-shape": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.0.2.tgz", + "integrity": "sha512-5+ButCmIfNX8id5seZ7jKj3igdcxx+S9IDBiT35fQGTLZUfkFgTv+oBH34xgeoWDKpWcMITSzBILWQtBoN5Piw==", + "dev": true, + "requires": { + "@types/d3-path": "*" + } + }, + "@types/d3-time": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz", + "integrity": "sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==", + "dev": true + }, + "@types/d3-time-format": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.0.tgz", + "integrity": "sha512-yjfBUe6DJBsDin2BMIulhSHmr5qNR5Pxs17+oW4DoVPyVIXZ+m6bs7j1UVKP08Emv6jRmYrYqxYzO63mQxy1rw==", + "dev": true + }, + "@types/d3-timer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz", + "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g==", + "dev": true + }, + "@types/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-Sv4qEI9uq3bnZwlOANvYK853zvpdKEm1yz9rcc8ZTsxvRklcs9Fx4YFuGA3gXoQN/c/1T6QkVNjhaRO/cWj94g==", + "dev": true, + "requires": { + "@types/d3-selection": "*" + } + }, + "@types/d3-zoom": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.1.tgz", + "integrity": "sha512-7s5L9TjfqIYQmQQEUcpMAcBOahem7TRoSO/+Gkz02GbMVuULiZzjF2BOdw291dbO2aNon4m2OdFsRGaCq2caLQ==", + "dev": true, + "requires": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "@types/dom4": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/dom4/-/dom4-2.0.1.tgz", @@ -25013,6 +25976,16 @@ "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", "dev": true }, + "@types/expect-puppeteer": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/expect-puppeteer/-/expect-puppeteer-4.4.6.tgz", + "integrity": "sha512-RgQND/7RvcJm4NL2qoQbvVHTcfDh3h3yYe0Em0roczXY+MOIBkcgv5WRzVKeQJKO1nyhc4bEAbxpwykjDUMdqg==", + "dev": true, + "requires": { + "@types/jest": "*", + "@types/puppeteer": "*" + } + }, "@types/favicons": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@types/favicons/-/favicons-5.5.0.tgz", @@ -25022,6 +25995,18 @@ "@types/node": "*" } }, + "@types/flatbuffers": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@types/flatbuffers/-/flatbuffers-1.10.0.tgz", + "integrity": "sha512-7btbphLrKvo5yl/5CC2OCxUSMx1wV1wvGT1qDXkSt7yi00/YW7E8k6qzXqJHsp+WU0eoG7r6MTQQXI9lIvd0qA==", + "dev": true + }, + "@types/geojson": { + "version": "7946.0.8", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.8.tgz", + "integrity": "sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==", + "dev": true + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -25056,6 +26041,12 @@ "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", "dev": true }, + "@types/is-number": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@types/is-number/-/is-number-7.0.1.tgz", + "integrity": "sha512-X8x3GugC4+84FEukgkKT75SkSVdzdeZJzy5k7n5CRB7/jk0PgeYwe2O5qRx7qOTnKkLNMVOP2d190R7VWzbzEw==", + "dev": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -25080,6 +26071,27 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "26.0.24", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", + "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", + "dev": true, + "requires": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, + "@types/jest-environment-puppeteer": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/jest-environment-puppeteer/-/jest-environment-puppeteer-4.4.1.tgz", + "integrity": "sha512-LiZTD6i63le6QMnxi7pJB0SFv/fWtss6VVEEDm/UaeowBgjduf8txyE//j3WEeDPxngTvioUjbzA7Rc6Wc3cBA==", + "dev": true, + "requires": { + "@jest/types": ">=24 <=26", + "@types/puppeteer": "*", + "jest-environment-node": ">=24 <=26" + } + }, "@types/json-schema": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", @@ -25092,6 +26104,111 @@ "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, + "@types/lodash": { + "version": "4.14.171", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.171.tgz", + "integrity": "sha512-7eQ2xYLLI/LsicL2nejW9Wyko3lcpN6O/z0ZLHrEQsg280zIdCv1t/0m6UtBjUHokCGBQ3gYTbHzDkZ1xOBwwg==", + "dev": true + }, + "@types/lodash.clonedeep": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.6.tgz", + "integrity": "sha512-cE1jYr2dEg1wBImvXlNtp0xDoS79rfEdGozQVgliDZj1uERH4k+rmEMTudP9b4VQ8O6nRb5gPqft0QzEQGMQgA==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.difference": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.difference/-/lodash.difference-4.5.6.tgz", + "integrity": "sha512-wXH53r+uoUCrKhmh7S5Gf6zo3vpsx/zH2R4pvkmDlmopmMTCROAUXDpPMXATGCWkCjE6ik3VZzZUxBgMjZho9Q==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.every": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.every/-/lodash.every-4.6.6.tgz", + "integrity": "sha512-eZC30bvV8GtmVUcMMhdAS+C2VgmkLMhnLyjTlf2lsPxhiquHfr/f0EnlX20l4xQWXG3B7H+OTSoWPqONyCeD2Q==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.filter": { + "version": "4.6.6", + "resolved": "https://registry.npmjs.org/@types/lodash.filter/-/lodash.filter-4.6.6.tgz", + "integrity": "sha512-K9oEglaInmu7pnQnZYdciNePpKe0W7O9yssnCza9mLjpq5N5Ju8RIMwTvp9tovb8V5yemxFTJqHzG+tIkAl1xw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.foreach": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.foreach/-/lodash.foreach-4.5.6.tgz", + "integrity": "sha512-A8+157A+27zwJSstmW/eWPc9lHLJNEer4jiMlsyxWieBxEx0arwB9vgQm+iai6DEDYYQuufHrzVhQOiapCalQQ==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.isnumber": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/lodash.isnumber/-/lodash.isnumber-3.0.6.tgz", + "integrity": "sha512-nnfRqgijLFBEVu8W6pkHGq4hefaQOMcVwqeY19qIpf4qhV04mczNZvyT4Hc8UjOcnCIXErQG0aqIJedqlbbvVw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.map": { + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/@types/lodash.map/-/lodash.map-4.6.13.tgz", + "integrity": "sha512-kppRBzlpuvQQsr7R2nv/DDDZds8fglRFNAK70WUOkOC18KOcuQ22oQF9Kgy5Z2v/eDNkBm0ltrT6FThSkuWwow==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.pull": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/lodash.pull/-/lodash.pull-4.1.6.tgz", + "integrity": "sha512-pK+efqDL+Of68Gqd81LfOdBAmB5X6+SHM6kkUTTFQWqOPAomn3BWJcASLrr998SRE7aYLnDVmM5wLLbS7T159A==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.sortby": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@types/lodash.sortby/-/lodash.sortby-4.7.6.tgz", + "integrity": "sha512-EnvAOmKvEg7gdYpYrS6+fVFPw5dL9rBnJi3vcKI7wqWQcLJVF/KRXK9dH29HjGNVvFUj0s9prRP3J8jEGnGKDw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.uniq": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@types/lodash.uniq/-/lodash.uniq-4.5.6.tgz", + "integrity": "sha512-XHNMXBtiwsWZstZMyxOYjr0e8YYWv0RgPlzIHblTuwBBiWo2MzWVaTBihtBpslb5BglgAWIeBv69qt1+RTRW1A==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/lodash.zip": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@types/lodash.zip/-/lodash.zip-4.2.6.tgz", + "integrity": "sha512-mKAcnkyFaihVR1oK83ZBQqSSQ1hpAY+uD5QaDkf//xtvr4NlNwqJEDg/oQoqLJg5YdSEwVWlQq0Aq4oLvD3zuw==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -25110,6 +26227,12 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, + "@types/pako": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz", + "integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==", + "dev": true + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -25127,6 +26250,15 @@ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, + "@types/puppeteer": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.4.tgz", + "integrity": "sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/q": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", @@ -25134,19 +26266,37 @@ "dev": true }, "@types/react": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz", - "integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==", + "version": "17.0.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.14.tgz", + "integrity": "sha512-0WwKHUbWuQWOce61UexYuWTGuGY/8JvtUe/dtQ6lR4sZ3UiylHotJeWpf3ArP9+DSGUoLY3wbU59VyMrJps5VQ==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, + "@types/react-dom": { + "version": "17.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", + "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-helmet": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@types/react-helmet/-/react-helmet-6.1.2.tgz", + "integrity": "sha512-dcfAZNlWb5JYFbO9CGfrPWLJAyFcT6UeR3u35eBbv8liY2Rg4K7fM1G5+HnwVgot+C+kVwXAZ8pLEn2jsMfTDg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, "@types/react-redux": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.16.tgz", - "integrity": "sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw==", + "version": "7.1.18", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.18.tgz", + "integrity": "sha512-9iwAsPyJ9DLTRH+OFeIrm9cAbIj1i2ANL3sKQFATqnPWRbg+jEFXyZOKHiQK/N86pNRXbb4HRxAxo0SIX1XwzQ==", "requires": { "@types/hoist-non-react-statics": "^3.3.0", "@types/react": "*", @@ -25159,6 +26309,15 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" }, + "@types/sha1": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/sha1/-/sha1-1.1.3.tgz", + "integrity": "sha512-bXfx/6xrPu1l6pLItGRMPX00lhnJavpj2qiQeLHflXvL2Ix97aC8FTF2/pQoqukRzcCwKyN3csZvOLzamIoaSA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/stack-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", @@ -25190,49 +26349,98 @@ "@types/node": "*" } }, - "@typescript-eslint/experimental-utils": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.0.tgz", - "integrity": "sha512-xJXHHl6TuAxB5AWiVrGhvbGL8/hbiCQ8FiWwObO3r0fnvBdrbWEDy1hlvGQOAWc6qsCWuWMKdVWlLAEMpxnddg==", + "@typescript-eslint/eslint-plugin": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.4.tgz", + "integrity": "sha512-s1oY4RmYDlWMlcV0kKPBaADn46JirZzvvH7c2CtAqxCY96S538JRBAzt83RrfkDheV/+G/vWNK0zek+8TB3Gmw==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.22.0", - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/typescript-estree": "4.22.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "@typescript-eslint/experimental-utils": "4.28.4", + "@typescript-eslint/scope-manager": "4.28.4", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.4.tgz", + "integrity": "sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.4", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/typescript-estree": "4.28.4", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.4.tgz", + "integrity": "sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.28.4", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/typescript-estree": "4.28.4", + "debug": "^4.3.1" } }, "@typescript-eslint/scope-manager": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.22.0.tgz", - "integrity": "sha512-OcCO7LTdk6ukawUM40wo61WdeoA7NM/zaoq1/2cs13M7GyiF+T4rxuA4xM+6LeHWjWbss7hkGXjFDRcKD4O04Q==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.4.tgz", + "integrity": "sha512-ZJBNs4usViOmlyFMt9X9l+X0WAFcDH7EdSArGqpldXu7aeZxDAuAzHiMAeI+JpSefY2INHrXeqnha39FVqXb8w==", "dev": true, "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0" + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/visitor-keys": "4.28.4" } }, "@typescript-eslint/types": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.22.0.tgz", - "integrity": "sha512-sW/BiXmmyMqDPO2kpOhSy2Py5w6KvRRsKZnV0c4+0nr4GIcedJwXAq+RHNK4lLVEZAJYFltnnk1tJSlbeS9lYA==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.4.tgz", + "integrity": "sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.0.tgz", - "integrity": "sha512-TkIFeu5JEeSs5ze/4NID+PIcVjgoU3cUQUIZnH3Sb1cEn1lBo7StSV5bwPuJQuoxKXlzAObjYTilOEKRuhR5yg==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.4.tgz", + "integrity": "sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.22.0", - "@typescript-eslint/visitor-keys": "4.22.0", - "debug": "^4.1.1", - "globby": "^11.0.1", + "@typescript-eslint/types": "4.28.4", + "@typescript-eslint/visitor-keys": "4.28.4", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "dependencies": { "semver": { @@ -25247,12 +26455,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.0.tgz", - "integrity": "sha512-nnMu4F+s4o0sll6cBSsTeVsT4cwxB7zECK3dFxzEjPBii9xLpq4yqqsy/FU5zMfan6G60DKZSCXAa3sHJZrcYw==", + "version": "4.28.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.4.tgz", + "integrity": "sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.22.0", + "@typescript-eslint/types": "4.28.4", "eslint-visitor-keys": "^2.0.0" } }, @@ -28720,6 +29928,17 @@ "object.entries": "^1.1.2" } }, + "eslint-config-airbnb-typescript": { + "version": "12.3.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-12.3.1.tgz", + "integrity": "sha512-ql/Pe6/hppYuRp4m3iPaHJqkBB7dgeEmGPQ6X0UNmrQOfTF+dXw29/ZjU2kQ6RDoLxaxOA+Xqv07Vbef6oVTWw==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "^4.4.1", + "eslint-config-airbnb": "^18.2.0", + "eslint-config-airbnb-base": "^14.2.0" + } + }, "eslint-config-prettier": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.2.0.tgz", @@ -29646,17 +30865,16 @@ "dev": true }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -29683,9 +30901,9 @@ "dev": true }, "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -30311,9 +31529,9 @@ "dev": true }, "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -39105,6 +40323,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true + }, "uglify-es": { "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", diff --git a/client/package.json b/client/package.json index 11b7d5fe..d20ee17d 100644 --- a/client/package.json +++ b/client/package.json @@ -8,9 +8,9 @@ "build": "npm run clean && webpack --config", "clean": "rimraf build", "dev": "npm run build -- configuration/webpack/webpack.config.dev.js", - "e2e": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.js", - "e2e-annotations": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2eAnnotations.test.js", - "e2e-prod": "CXG_URL_BASE='https://cellxgene.cziscience.com/d/pbmc3k.cxg/' jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.js", + "e2e": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.ts", + "e2e-annotations": "jest --config __tests__/e2e/e2eJestConfig.json e2e/e2eAnnotations.test.ts", + "e2e-prod": "CXG_URL_BASE='https://cellxgene.cziscience.com/d/pbmc3k.cxg/' jest --config __tests__/e2e/e2eJestConfig.json e2e/e2e.test.ts", "fmt": "eslint --fix src __tests__", "lint": "eslint --fix src __tests__", "prod": "npm run build -- configuration/webpack/webpack.config.prod.js", @@ -90,10 +90,38 @@ "@babel/plugin-transform-runtime": "^7.13.15", "@babel/preset-env": "^7.13.15", "@babel/preset-react": "^7.13.13", + "@babel/preset-typescript": "^7.14.5", "@babel/register": "^7.13.16", "@babel/runtime": "^7.13.16", "@blueprintjs/eslint-plugin": "^0.3.0", "@sentry/webpack-plugin": "^1.15.0", + "@types/d3": "^7.0.0", + "@types/d3-scale-chromatic": "^3.0.0", + "@types/expect-puppeteer": "^4.4.6", + "@types/flatbuffers": "^1.10.0", + "@types/is-number": "^7.0.1", + "@types/jest": "^26.0.24", + "@types/jest-environment-puppeteer": "^4.4.1", + "@types/lodash.clonedeep": "^4.5.6", + "@types/lodash.difference": "^4.5.6", + "@types/lodash.every": "^4.6.6", + "@types/lodash.filter": "^4.6.6", + "@types/lodash.foreach": "^4.5.6", + "@types/lodash.isnumber": "^3.0.6", + "@types/lodash.map": "^4.6.13", + "@types/lodash.pull": "^4.1.6", + "@types/lodash.sortby": "^4.7.6", + "@types/lodash.uniq": "^4.5.6", + "@types/lodash.zip": "^4.2.6", + "@types/pako": "^1.0.2", + "@types/puppeteer": "^5.4.4", + "@types/react": "^17.0.14", + "@types/react-dom": "^17.0.9", + "@types/react-helmet": "^6.1.2", + "@types/react-redux": "^7.1.18", + "@types/sha1": "^1.1.3", + "@typescript-eslint/eslint-plugin": "^4.28.4", + "@typescript-eslint/parser": "^4.28.4", "babel-eslint": "^10.1.0", "babel-jest": "^26.1.0", "babel-loader": "^8.1.0", @@ -106,7 +134,7 @@ "connect-history-api-fallback": "^1.6.0", "css-loader": "^5.2.4", "eslint": "^7.24.0", - "eslint-config-airbnb": "^18.2.0", + "eslint-config-airbnb-typescript": "^12.3.1", "eslint-config-prettier": "^8.2.0", "eslint-loader": "^4.0.2", "eslint-plugin-compat": "^3.8.0", @@ -149,6 +177,7 @@ "style-loader": "^2.0.0", "sw-precache-webpack-plugin": "^1.0.0", "terser-webpack-plugin": "^5.1.1", + "typescript": "^4.3.5", "url-loader": "^4.1.0", "webpack": "^5.34.0", "webpack-cli": "^4.6.0", @@ -157,10 +186,10 @@ }, "jest": { "testMatch": [ - "**/__tests__/**/?(*.)(spec|test).js?(x)" + "**/__tests__/**/?(*.)(spec|test).ts?(x)" ], "setupFiles": [ - "./__tests__/setupMissingGlobals.js" + "./__tests__/setupMissingGlobals.ts" ], "coverageDirectory": "./coverage/", "collectCoverage": true @@ -170,7 +199,8 @@ "test": { "presets": [ "@babel/preset-env", - "@babel/preset-react" + "@babel/preset-react", + "@babel/preset-typescript" ], "plugins": [ "@babel/plugin-proposal-function-bind", diff --git a/client/src/actions/annotation.js b/client/src/actions/annotation.ts similarity index 91% rename from client/src/actions/annotation.js rename to client/src/actions/annotation.ts index 4b7ca9bf..85b3df83 100644 --- a/client/src/actions/annotation.js +++ b/client/src/actions/annotation.ts @@ -9,9 +9,9 @@ import { MatrixFBS, AnnotationsHelpers } from "../util/stateManager"; const { isUserAnnotation } = AnnotationsHelpers; export const annotationCreateCategoryAction = ( - newCategoryName, - categoryToDuplicate -) => async (dispatch, getState) => { + newCategoryName: any, + categoryToDuplicate: any +) => async (dispatch: any, getState: any) => { /* Add a new user-created category to the obs annotations. @@ -89,9 +89,9 @@ export const annotationCreateCategoryAction = ( }; export const annotationRenameCategoryAction = ( - oldCategoryName, - newCategoryName -) => (dispatch, getState) => { + oldCategoryName: any, + newCategoryName: any +) => (dispatch: any, getState: any) => { /* Rename a user-created annotation category */ @@ -124,9 +124,9 @@ export const annotationRenameCategoryAction = ( }); }; -export const annotationDeleteCategoryAction = (categoryName) => ( - dispatch, - getState +export const annotationDeleteCategoryAction = (categoryName: any) => ( + dispatch: any, + getState: any ) => { /* Delete a user-created category @@ -149,10 +149,10 @@ export const annotationDeleteCategoryAction = (categoryName) => ( }; export const annotationCreateLabelInCategory = ( - categoryName, - labelName, - assignSelected -) => async (dispatch, getState) => { + categoryName: any, + labelName: any, + assignSelected: any +) => async (dispatch: any, getState: any) => { /* Add a new label to a user-defined category. If assignSelected is true, assign the label to all currently selected cells. @@ -188,9 +188,9 @@ export const annotationCreateLabelInCategory = ( }; export const annotationDeleteLabelFromCategory = ( - categoryName, - labelName -) => async (dispatch, getState) => { + categoryName: any, + labelName: any +) => async (dispatch: any, getState: any) => { /* delete a label from a user-defined category */ @@ -218,10 +218,10 @@ export const annotationDeleteLabelFromCategory = ( }; export const annotationRenameLabelInCategory = ( - categoryName, - oldLabelName, - newLabelName -) => async (dispatch, getState) => { + categoryName: any, + oldLabelName: any, + newLabelName: any +) => async (dispatch: any, getState: any) => { /* label name change */ @@ -255,9 +255,9 @@ export const annotationRenameLabelInCategory = ( }; export const annotationLabelCurrentSelection = ( - categoryName, - labelName -) => async (dispatch, getState) => { + categoryName: any, + labelName: any +) => async (dispatch: any, getState: any) => { /* set the label on all currently selected */ @@ -284,13 +284,16 @@ export const annotationLabelCurrentSelection = ( }); }; -function writableAnnotations(annoMatrix) { +function writableAnnotations(annoMatrix: any) { return annoMatrix.schema.annotations.obs.columns - .filter((s) => s.writable) - .map((s) => s.name); + .filter((s: any) => s.writable) + .map((s: any) => s.name); } -export const needToSaveObsAnnotations = (annoMatrix, lastSavedAnnoMatrix) => { +export const needToSaveObsAnnotations = ( + annoMatrix: any, + lastSavedAnnoMatrix: any +) => { /* Return true if there are LIKELY user-defined annotation modifications between the two annoMatrices. Technically not an action creator, but intimately intertwined @@ -314,11 +317,14 @@ export const needToSaveObsAnnotations = (annoMatrix, lastSavedAnnoMatrix) => { // no schema changes; check for change in contents return currentWritable.some( - (col) => annoMatrix.col(col) !== lastSavedAnnoMatrix.col(col) + (col: any) => annoMatrix.col(col) !== lastSavedAnnoMatrix.col(col) ); }; -export const saveObsAnnotationsAction = () => async (dispatch, getState) => { +export const saveObsAnnotationsAction = () => async ( + dispatch: any, + getState: any +) => { /* Save the user-created obs annotations IF any have changed. */ @@ -388,7 +394,10 @@ export const saveObsAnnotationsAction = () => async (dispatch, getState) => { } }; -export const saveGenesetsAction = () => async (dispatch, getState) => { +export const saveGenesetsAction = () => async ( + dispatch: any, + getState: any +) => { const state = getState(); // bail if gene sets not available, or in readonly mode. @@ -465,7 +474,7 @@ export const saveGenesetsAction = () => async (dispatch, getState) => { res, }); } - return Promise.all([ + return await Promise.all([ dispatch({ type: "autosave: genesets complete", lastSavedGenesets: genesets, diff --git a/client/src/actions/embedding.js b/client/src/actions/embedding.ts similarity index 86% rename from client/src/actions/embedding.js rename to client/src/actions/embedding.ts index a4494dbd..7e95f70e 100644 --- a/client/src/actions/embedding.js +++ b/client/src/actions/embedding.ts @@ -6,9 +6,9 @@ import { AnnoMatrixObsCrossfilter } from "../annoMatrix"; import { _setEmbeddingSubset } from "../util/stateManager/viewStackHelpers"; export async function _switchEmbedding( - prevAnnoMatrix, - prevCrossfilter, - newEmbeddingName + prevAnnoMatrix: any, + prevCrossfilter: any, + newEmbeddingName: any ) { /* DRY helper used by embedding action creators @@ -25,9 +25,9 @@ export async function _switchEmbedding( return [annoMatrix, obsCrossfilter]; } -export const layoutChoiceAction = (newLayoutChoice) => async ( - dispatch, - getState +export const layoutChoiceAction = (newLayoutChoice: any) => async ( + dispatch: any, + getState: any ) => { /* On layout choice, make sure we have selected all on the previous layout, AND the new diff --git a/client/src/actions/geneset.js b/client/src/actions/geneset.ts similarity index 82% rename from client/src/actions/geneset.js rename to client/src/actions/geneset.ts index 49b2cf56..101978de 100644 --- a/client/src/actions/geneset.js +++ b/client/src/actions/geneset.ts @@ -21,7 +21,10 @@ The behavior manifest in these action creators: Note that crossfilter indices are lazy created, as needed. */ -export const genesetDelete = (genesetName) => (dispatch, getState) => { +export const genesetDelete = (genesetName: any) => ( + dispatch: any, + getState: any +) => { const state = getState(); const { genesets } = state; const gs = genesets?.genesets?.get(genesetName) ?? {}; @@ -40,9 +43,9 @@ export const genesetDelete = (genesetName) => (dispatch, getState) => { }); }; -export const genesetAddGenes = (genesetName, genes) => async ( - dispatch, - getState +export const genesetAddGenes = (genesetName: any, genes: any) => async ( + dispatch: any, + getState: any ) => { const state = getState(); const { obsCrossfilter: prevObsCrossfilter, annoMatrix } = state; @@ -50,7 +53,7 @@ export const genesetAddGenes = (genesetName, genes) => async ( const varIndex = schema.annotations.var.index; const df = await annoMatrix.fetch("var", varIndex); const geneNames = df.col(varIndex).asArray(); - genes = genes.reduce((acc, gene) => { + genes = genes.reduce((acc: any, gene: any) => { if (geneNames.indexOf(gene.geneSymbol) === -1) { postUserErrorToast( `${gene.geneSymbol} doesn't appear to be a valid gene name.` @@ -78,9 +81,9 @@ export const genesetAddGenes = (genesetName, genes) => async ( }); }; -export const genesetDeleteGenes = (genesetName, geneSymbols) => ( - dispatch, - getState +export const genesetDeleteGenes = (genesetName: any, geneSymbols: any) => ( + dispatch: any, + getState: any ) => { const state = getState(); const obsCrossfilter = dropGeneset(dispatch, state, genesetName, geneSymbols); @@ -97,7 +100,11 @@ export const genesetDeleteGenes = (genesetName, geneSymbols) => ( Private */ -function dropGenesetSummaryDimension(obsCrossfilter, state, genesetName) { +function dropGenesetSummaryDimension( + obsCrossfilter: any, + state: any, + genesetName: any +) { const { annoMatrix, genesets } = state; const varIndex = annoMatrix.schema.annotations?.var?.index; const gs = genesets?.genesets?.get(genesetName) ?? {}; @@ -113,7 +120,7 @@ function dropGenesetSummaryDimension(obsCrossfilter, state, genesetName) { return obsCrossfilter.dropDimension("X", query); } -function dropGeneDimension(obsCrossfilter, state, gene) { +function dropGeneDimension(obsCrossfilter: any, state: any, gene: any) { const { annoMatrix } = state; const varIndex = annoMatrix.schema.annotations?.var?.index; const query = { @@ -126,10 +133,16 @@ function dropGeneDimension(obsCrossfilter, state, gene) { return obsCrossfilter.dropDimension("X", query); } -function dropGeneset(dispatch, state, genesetName, geneSymbols) { +function dropGeneset( + dispatch: any, + state: any, + genesetName: any, + geneSymbols: any +) { const { obsCrossfilter: prevObsCrossfilter } = state; const obsCrossfilter = geneSymbols.reduce( - (crossfilter, gene) => dropGeneDimension(crossfilter, state, gene), + (crossfilter: any, gene: any) => + dropGeneDimension(crossfilter, state, gene), dropGenesetSummaryDimension(prevObsCrossfilter, state, genesetName) ); dispatch({ @@ -137,7 +150,7 @@ function dropGeneset(dispatch, state, genesetName, geneSymbols) { continuousNamespace: { isGeneSetSummary: true }, selection: genesetName, }); - geneSymbols.forEach((g) => + geneSymbols.forEach((g: any) => dispatch({ type: "continuous metadata histogram cancel", continuousNamespace: { isUserDefined: true }, diff --git a/client/src/actions/index.js b/client/src/actions/index.ts similarity index 87% rename from client/src/actions/index.js rename to client/src/actions/index.ts index 6626c6cd..1f129e87 100644 --- a/client/src/actions/index.js +++ b/client/src/actions/index.ts @@ -15,7 +15,7 @@ import * as genesetActions from "./geneset"; /* return promise fetching user-configured colors */ -async function userColorsFetchAndLoad(dispatch) { +async function userColorsFetchAndLoad(dispatch: any) { return fetchJson("colors").then((response) => dispatch({ type: "universe: user color load success", @@ -28,7 +28,7 @@ async function schemaFetch() { return fetchJson("schema"); } -async function configFetch(dispatch) { +async function configFetch(dispatch: any) { return fetchJson("config").then((response) => { const config = { ...globals.configDefaults, ...response.config }; dispatch({ @@ -39,7 +39,7 @@ async function configFetch(dispatch) { }); } -async function userInfoFetch(dispatch) { +async function userInfoFetch(dispatch: any) { return fetchJson("userinfo").then((response) => { const { userinfo: userInfo } = response || {}; dispatch({ @@ -50,7 +50,7 @@ async function userInfoFetch(dispatch) { }); } -async function genesetsFetch(dispatch, config) { +async function genesetsFetch(dispatch: any, config: any) { /* request genesets ONLY if the backend supports the feature */ const defaultResponse = { genesets: [], @@ -71,25 +71,26 @@ async function genesetsFetch(dispatch, config) { } } -function prefetchEmbeddings(annoMatrix) { +function prefetchEmbeddings(annoMatrix: any) { /* prefetch requests for all embeddings */ const { schema } = annoMatrix; - const available = schema.layout.obs.map((v) => v.name); - available.forEach((embName) => annoMatrix.prefetch("emb", embName)); + const available = schema.layout.obs.map((v: any) => v.name); + available.forEach((embName: any) => annoMatrix.prefetch("emb", embName)); } /* Application bootstrap */ const doInitialDataLoad = () => - catchErrorsWrap(async (dispatch) => { + catchErrorsWrap(async (dispatch: any) => { dispatch({ type: "initial data load start" }); try { const [config, schema] = await Promise.all([ configFetch(dispatch), + // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1. schemaFetch(dispatch), userColorsFetchAndLoad(dispatch), userInfoFetch(dispatch), @@ -113,7 +114,7 @@ const doInitialDataLoad = () => const layoutSchema = schema?.schema?.layout?.obs ?? []; if ( defaultEmbedding && - layoutSchema.some((s) => s.name === defaultEmbedding) + layoutSchema.some((s: any) => s.name === defaultEmbedding) ) { dispatch(embActions.layoutChoiceAction(defaultEmbedding)); } @@ -122,21 +123,22 @@ const doInitialDataLoad = () => } }, true); -function requestSingleGeneExpressionCountsForColoringPOST(gene) { +function requestSingleGeneExpressionCountsForColoringPOST(gene: any) { return { type: "color by expression", gene, }; } -const requestUserDefinedGene = (gene) => ({ +const requestUserDefinedGene = (gene: any) => ({ type: "request user defined gene success", + data: { genes: [gene], }, }); -const dispatchDiffExpErrors = (dispatch, response) => { +const dispatchDiffExpErrors = (dispatch: any, response: any) => { switch (response.status) { case 403: dispatchNetworkErrorMessageToUser( @@ -159,10 +161,11 @@ const dispatchDiffExpErrors = (dispatch, response) => { } }; -const requestDifferentialExpression = (set1, set2, num_genes = 50) => async ( - dispatch, - getState -) => { +const requestDifferentialExpression = ( + set1: any, + set2: any, + num_genes = 50 +) => async (dispatch: any, getState: any) => { dispatch({ type: "request differential expression started" }); try { /* @@ -210,7 +213,8 @@ const requestDifferentialExpression = (set1, set2, num_genes = 50) => async ( const varIndex = await annoMatrix.fetch("var", varIndexName); const diffexpLists = { negative: [], positive: [] }; for (const polarity of Object.keys(diffexpLists)) { - diffexpLists[polarity] = response[polarity].map((v) => [ + // @ts-expect-error ts-migrate(7053) FIXME: Element implicitly has an 'any' type because expre... Remove this comment to see the full error message + diffexpLists[polarity] = response[polarity].map((v: any) => [ varIndex.at(v[0], varIndexName), ...v.slice(1), ]); @@ -229,7 +233,7 @@ const requestDifferentialExpression = (set1, set2, num_genes = 50) => async ( } }; -function fetchJson(pathAndQuery) { +function fetchJson(pathAndQuery: any) { return doJsonRequest( `${globals.API.prefix}${globals.API.version}${pathAndQuery}` ); diff --git a/client/src/actions/selection.js b/client/src/actions/selection.ts similarity index 70% rename from client/src/actions/selection.js rename to client/src/actions/selection.ts index 4657bcdd..52504901 100644 --- a/client/src/actions/selection.js +++ b/client/src/actions/selection.ts @@ -2,11 +2,11 @@ Action creators for selection */ export const selectContinuousMetadataAction = ( - type, - query, - range, + type: any, + query: any, + range: any, oldProps = {} -) => async (dispatch, getState) => { +) => async (dispatch: any, getState: any) => { const { obsCrossfilter: prevObsCrossfilter } = getState(); const selection = range @@ -29,13 +29,13 @@ export const selectContinuousMetadataAction = ( }; export const selectCategoricalMetadataAction = ( - type, // action type - metadataField, // annotation category name - labels, - label, // the label being selected/deselected - isSelected, // bool + type: any, // action type + metadataField: any, // annotation category name + labels: any, + label: any, // the label being selected/deselected + isSelected: any, // bool oldProps = {} -) => async (dispatch, getState) => { +) => async (dispatch: any, getState: any) => { const { obsCrossfilter: prevObsCrossfilter, categoricalSelection, @@ -43,7 +43,7 @@ export const selectCategoricalMetadataAction = ( const labelSelectionState = new Map(categoricalSelection[metadataField]); labels.forEach( - (l) => labelSelectionState.has(l) || labelSelectionState.set(l, true) + (l: any) => labelSelectionState.has(l) || labelSelectionState.set(l, true) ); labelSelectionState.set(label, isSelected); @@ -70,19 +70,19 @@ export const selectCategoricalMetadataAction = ( }; export const selectCategoricalAllMetadataAction = ( - type, // action type - metadataField, // annotation category name - labels, - isSelected, // bool, select all or none + type: any, // action type + metadataField: any, // annotation category name + labels: any, + isSelected: any, // bool, select all or none oldProps = {} -) => async (dispatch, getState) => { +) => async (dispatch: any, getState: any) => { const { obsCrossfilter: prevObsCrossfilter, categoricalSelection, } = getState(); const labelSelectionState = new Map(categoricalSelection[metadataField]); - labels.forEach((label) => labelSelectionState.set(label, isSelected)); + labels.forEach((label: any) => labelSelectionState.set(label, isSelected)); const selection = { mode: isSelected ? "all" : "none" }; const obsCrossfilter = await prevObsCrossfilter.select( @@ -108,10 +108,11 @@ export const graphBrushStartAction = () => /* no change to crossfilter until a change fires */ ({ type: "graph brush start" }); -const _graphBrushWithinRectAction = (type, embName, brushCoords) => async ( - dispatch, - getState -) => { +const _graphBrushWithinRectAction = ( + type: any, + embName: any, + brushCoords: any +) => async (dispatch: any, getState: any) => { const { obsCrossfilter: prevObsCrossfilter } = getState(); const selection = { mode: "within-rect", ...brushCoords }; @@ -128,7 +129,10 @@ const _graphBrushWithinRectAction = (type, embName, brushCoords) => async ( }); }; -const _graphAllAction = (type, embName) => async (dispatch, getState) => { +const _graphAllAction = (type: any, embName: any) => async ( + dispatch: any, + getState: any +) => { const { obsCrossfilter: prevObsCrossfilter } = getState(); const obsCrossfilter = await prevObsCrossfilter.select("emb", embName, { @@ -141,30 +145,30 @@ const _graphAllAction = (type, embName) => async (dispatch, getState) => { }); }; -export const graphBrushChangeAction = (embName, brushCoords) => +export const graphBrushChangeAction = (embName: any, brushCoords: any) => _graphBrushWithinRectAction("graph brush change", embName, brushCoords); -export const graphBrushEndAction = (embName, brushCoords) => +export const graphBrushEndAction = (embName: any, brushCoords: any) => _graphBrushWithinRectAction("graph brush end", embName, brushCoords); -export const graphBrushCancelAction = (embName) => +export const graphBrushCancelAction = (embName: any) => _graphAllAction("graph brush cancel", embName); -export const graphBrushDeselectAction = (embName) => +export const graphBrushDeselectAction = (embName: any) => _graphAllAction("graph brush deselect", embName); export const graphLassoStartAction = () => /* no change to crossfilter until a change fires */ ({ type: "graph lasso start" }); -export const graphLassoCancelAction = (embName) => +export const graphLassoCancelAction = (embName: any) => _graphAllAction("graph lasso cancel", embName); -export const graphLassoDeselectAction = (embName) => +export const graphLassoDeselectAction = (embName: any) => _graphAllAction("graph lasso cancel", embName); -export const graphLassoEndAction = (embName, polygon) => async ( - dispatch, - getState +export const graphLassoEndAction = (embName: any, polygon: any) => async ( + dispatch: any, + getState: any ) => { const { obsCrossfilter: prevObsCrossfilter } = getState(); @@ -188,7 +192,10 @@ export const graphLassoEndAction = (embName, polygon) => async ( /* Differential expression set selection */ -export const setCellSetFromSelection = (cellSetId) => (dispatch, getState) => { +export const setCellSetFromSelection = (cellSetId: any) => ( + dispatch: any, + getState: any +) => { const { obsCrossfilter } = getState(); const selected = obsCrossfilter.allSelectedLabels(); diff --git a/client/src/actions/viewStack.js b/client/src/actions/viewStack.ts similarity index 89% rename from client/src/actions/viewStack.js rename to client/src/actions/viewStack.ts index 9d402cbd..450e3f32 100644 --- a/client/src/actions/viewStack.js +++ b/client/src/actions/viewStack.ts @@ -18,7 +18,10 @@ import { _userResetSubsetAnnoMatrix, } from "../util/stateManager/viewStackHelpers"; -export const clipAction = (min, max) => (dispatch, getState) => { +export const clipAction = (min: any, max: any) => ( + dispatch: any, + getState: any +) => { /* apply a clip to the current annoMatrix. By convention, the clip view is ALWAYS the top view. @@ -34,7 +37,7 @@ export const clipAction = (min, max) => (dispatch, getState) => { }); }; -export const subsetAction = () => (dispatch, getState) => { +export const subsetAction = () => (dispatch: any, getState: any) => { /* Subset the annoMatrix to the current crossfilter selection by pushing a subset view. @@ -58,7 +61,7 @@ export const subsetAction = () => (dispatch, getState) => { }); }; -export const resetSubsetAction = () => (dispatch, getState) => { +export const resetSubsetAction = () => (dispatch: any, getState: any) => { /* Reset the annoMatrix to all data. Because we may have multiple views stacked, we pop them all. By convention, any clip transformation will diff --git a/client/src/annoMatrix/annoMatrix.js b/client/src/annoMatrix/annoMatrix.ts similarity index 78% rename from client/src/annoMatrix/annoMatrix.js rename to client/src/annoMatrix/annoMatrix.ts index 1ed90995..595c2f33 100644 --- a/client/src/annoMatrix/annoMatrix.js +++ b/client/src/annoMatrix/annoMatrix.ts @@ -17,6 +17,28 @@ import { _queryValidate, _queryCacheKey } from "./query"; const _dataframeCache = dataframeMemo(128); export default class AnnoMatrix { + public isView: any; + + public nObs: any; + + public nVar: any; + + public rowIndex: any; + + public schema: any; + + public userFlags: any; + + public viewOf: any; + + protected _cache: any; + + private _pendingLoad: any; + + private _whereCache: any; + + private _gcInfo: any; + /* Abstract base class for all AnnoMatrix objects. This class provides a proxy to the annotated matrix data authoritatively served by the server/back-end. @@ -54,7 +76,7 @@ export default class AnnoMatrix { return ["obs", "var", "emb", "X"]; } - constructor(schema, nObs, nVar, rowIndex = null) { + constructor(schema: any, nObs: any, nVar: any, rowIndex = null) { /* Private constructor - this is an abstract base class. Do not use. */ @@ -83,13 +105,13 @@ export default class AnnoMatrix { this.userFlags = {}; /* - Private instance variables. + Private instance variables. - These are caches - lazily loaded. The only guarantee is that if they - are loaded, they will conform to the schema & dimensionality constraints. + These are caches - lazily loaded. The only guarantee is that if they + are loaded, they will conform to the schema & dimensionality constraints. - Do NOT use directly - instead, use the fetch() and preload() API. - */ + Do NOT use directly - instead, use the fetch() and preload() API. + */ this._cache = { obs: Dataframe.empty(this.rowIndex), var: Dataframe.empty(this.rowIndex), @@ -109,6 +131,7 @@ export default class AnnoMatrix { /** ** Schema helper/accessors **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. getMatrixColumns(field) { /* Return array of column names in the field. ONLY supported on the @@ -132,6 +155,7 @@ export default class AnnoMatrix { return AnnoMatrix.fields(); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. getColumnSchema(field, col) { /* Return the schema for the field & column ,eg, @@ -144,6 +168,7 @@ export default class AnnoMatrix { return _getColumnSchema(this.schema, field, col); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. getColumnDimensions(field, col) { /* Return the dimensions on this field / column. For most fields, which are 1D, @@ -174,6 +199,7 @@ export default class AnnoMatrix { /** ** Load / read interfaces **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. fetch(field, q) { /* Return the given query on a single matrix field as a single dataframe. @@ -231,6 +257,7 @@ export default class AnnoMatrix { return this._fetch(field, q); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. prefetch(field, q) { /* Start a data fetch & cache fill. Identical to fetch() except it does @@ -261,7 +288,8 @@ export default class AnnoMatrix { ** The actual implementation is in the sub-classes, which MUST override these. **/ - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read. + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements addObsAnnoCategory(col, category) { /* Add a new category value (aka "label") to a writable obs column, and return the new AnnoMatrix. @@ -278,7 +306,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read. + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements async removeObsAnnoCategory(col, category, unassignedCategory) { /* Remove a category value from an obs column, reassign any obs having that value @@ -299,7 +328,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read. + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements dropObsColumn(col) { /* Drop an entire writable column, eg a user-created obs annotation. Typical use @@ -315,7 +345,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'colSchema' is declared but its value is never rea... Remove this comment to see the full error message + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements addObsColumn(colSchema, Ctor, value) { /* Add a new writable OBS annotation column, with the caller-specified schema, initial value @@ -344,7 +375,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'oldCol' is declared but its value is never read. + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements renameObsColumn(oldCol, newCol) { /* Rename the obs column 'oldCol' to have name 'newCol' and returns new AnnoMatrix. @@ -359,7 +391,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read. + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements async setObsColumnValues(col, obsLabels, value) { /* Set all obs with label in array 'obsLabels' to have 'value'. Typical use would be @@ -377,7 +410,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'col' is declared but its value is never read. + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements async resetObsColumnValues(col, oldValue, newValue) { /* Set by value - all elements in the column with value 'oldValue' are set to 'newValue'. @@ -394,7 +428,8 @@ export default class AnnoMatrix { _subclassResponsibility(); } - // eslint-disable-next-line class-methods-use-this, no-unused-vars -- make sure subclass implements + // @ts-expect-error ts-migrate(6133) FIXME: 'colSchema' is declared but its value is never rea... Remove this comment to see the full error message + // eslint-disable-next-line class-methods-use-this, @typescript-eslint/no-unused-vars -- make sure subclass implements addEmbedding(colSchema) { /* Add a new obs embedding to the AnnoMatrix, with provided schema. @@ -407,28 +442,35 @@ export default class AnnoMatrix { _subclassResponsibility(); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. getCacheKeys(field, query) { /* - Return cache keys for columns associated with this query. May return - [unknown] if no keys are known (ie, nothing is or was cached). - */ +Return cache keys for columns associated with this query. May return +[unknown] if no keys are known (ie, nothing is or was cached). +*/ return _whereCacheGet(this._whereCache, this.schema, field, query); } /** ** Private interfaces below. **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. _resolveCachedQueries(field, queries) { - return queries - .map((query) => - _whereCacheGet(this._whereCache, this.schema, field, query).filter( - (cacheKey) => - cacheKey !== undefined && this._cache[field].hasCol(cacheKey) + return ( + queries + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'query' implicitly has an 'any' type. + .map((query) => + _whereCacheGet(this._whereCache, this.schema, field, query).filter( + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'cacheKey' implicitly has an 'any' type. + (cacheKey) => + cacheKey !== undefined && this._cache[field].hasCol(cacheKey) + ) ) - ) - .flat(); + .flat() + ); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. async _fetch(field, q) { if (!AnnoMatrix.fields().includes(field)) return undefined; const queries = Array.isArray(q) ? q : [q]; @@ -441,6 +483,7 @@ export default class AnnoMatrix { /* find any query not already cached */ const uncachedQueries = queries.filter((query) => _whereCacheGet(this._whereCache, this.schema, field, query).some( + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'cacheKey' implicitly has an 'any' type. (cacheKey) => cacheKey === undefined || !this._cache[field].hasCol(cacheKey) ) @@ -450,8 +493,10 @@ export default class AnnoMatrix { if (uncachedQueries.length > 0) { await Promise.all( uncachedQueries.map((query) => + // @ts-expect-error ts-migrate(7006) FIXME: Parameter '_field' implicitly has an 'any' type. this._getPendingLoad(field, query, async (_field, _query) => { /* fetch, then index. _doLoad is subclass interface */ + // @ts-expect-error ts-migrate(2488) FIXME: Type 'void' must have a '[Symbol.iterator]()' meth... Remove this comment to see the full error message const [whereCacheUpdate, df] = await this._doLoad(_field, _query); this._cache[_field] = this._cache[_field].withColsFrom(df); this._whereCache = _whereCacheMerge( @@ -472,6 +517,7 @@ export default class AnnoMatrix { return response; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. async _getPendingLoad(field, query, fetchFn) { /* Given a query on a field, ensure that we only have a single outstanding @@ -527,19 +573,21 @@ export default class AnnoMatrix { To be effective, the GC callback needs to be invoked from the undo/redo code, as much of the cache is pinned by that data structure. */ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. _gcField(field, isHot, pinnedColumns) { - const maxColumns = isHot ? 256 : 10; // maybe to aggressive? - + const maxColumns = isHot ? 256 : 10; const cache = this._cache[field]; if (cache.colIndex.size() < maxColumns) return; // trivial rejection const candidates = cache.colIndex .labels() + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. .filter((col) => !pinnedColumns.includes(col)); const excessCount = candidates.length + pinnedColumns.length - maxColumns; if (excessCount > 0) { const { _gcInfo } = this; + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'a' implicitly has an 'any' type. candidates.sort((a, b) => { let atime = _gcInfo.get(_columnCacheKey(field, a)); if (atime === undefined) atime = 0; @@ -558,13 +606,16 @@ export default class AnnoMatrix { // )}]` // ); this._cache[field] = toDrop.reduce( + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'df' implicitly has an 'any' type. (df, col) => df.dropCol(col), this._cache[field] ); + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. toDrop.forEach((col) => _gcInfo.delete(_columnCacheKey(field, col))); } } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. _gcFetchCleanup(field, pinnedColumns) { /* Called during data load/fetch. By definition, this is 'hot', so we @@ -579,6 +630,7 @@ export default class AnnoMatrix { } } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'hints' implicitly has an 'any' type. _gc(hints) { /* Called from middleware, or elsewhere. isHot is true if we are in the active store, @@ -591,6 +643,7 @@ export default class AnnoMatrix { ); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. _gcUpdateStats(field, dataframe) { /* called each time a query is performed, allowing the gc to update any bookkeeping @@ -600,6 +653,7 @@ export default class AnnoMatrix { const cols = dataframe.colIndex.labels(); const { _gcInfo } = this; const now = Date.now(); + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'c' implicitly has an 'any' type. cols.forEach((c) => { _gcInfo.set(_columnCacheKey(field, c), now); }); @@ -617,6 +671,7 @@ export default class AnnoMatrix { Do not override _clone(); **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'clone' implicitly has an 'any' type. _cloneDeeper(clone) { clone._cache = _shallowClone(this._cache); clone._gcInfo = new Map(); @@ -640,6 +695,7 @@ export default class AnnoMatrix { /* private utility functions below */ +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. function _columnCacheKey(field, column) { return `${field}/${column}`; } diff --git a/client/src/annoMatrix/clone.js b/client/src/annoMatrix/clone.ts similarity index 72% rename from client/src/annoMatrix/clone.js rename to client/src/annoMatrix/clone.ts index 97cad4b5..a6c9346a 100644 --- a/client/src/annoMatrix/clone.js +++ b/client/src/annoMatrix/clone.ts @@ -1,6 +1,6 @@ /* Shallow clone an object, correctly handling prototype */ -export default function _shallowClone(orig) { +export default function _shallowClone(orig: any) { return Object.assign(Object.create(Object.getPrototypeOf(orig)), orig); } diff --git a/client/src/annoMatrix/crossfilter.js b/client/src/annoMatrix/crossfilter.ts similarity index 56% rename from client/src/annoMatrix/crossfilter.js rename to client/src/annoMatrix/crossfilter.ts index e2310731..8d98797d 100644 --- a/client/src/annoMatrix/crossfilter.js +++ b/client/src/annoMatrix/crossfilter.ts @@ -10,26 +10,31 @@ AnnoMatrix stay in sync: import Crossfilter from "../util/typedCrossfilter"; import { _getColumnSchema } from "./schema"; +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. function _dimensionNameFromDf(field, df) { const colNames = df.colIndex.labels(); return _dimensionName(field, colNames); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. function _dimensionName(field, colNames) { if (!Array.isArray(colNames)) return `${field}/${colNames}`; return `${field}/${colNames.join(":")}`; } export default class AnnoMatrixObsCrossfilter { + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message constructor(annoMatrix, _obsCrossfilter = null) { - this.annoMatrix = annoMatrix; - this.obsCrossfilter = + (this as any).annoMatrix = annoMatrix; + (this as any).obsCrossfilter = _obsCrossfilter || new Crossfilter(annoMatrix._cache.obs); - this.obsCrossfilter = this.obsCrossfilter.setData(annoMatrix._cache.obs); + (this as any).obsCrossfilter = (this as any).obsCrossfilter.setData( + annoMatrix._cache.obs + ); } size() { - return this.obsCrossfilter.size(); + return (this as any).obsCrossfilter.size(); } /** @@ -39,14 +44,23 @@ export default class AnnoMatrixObsCrossfilter { See API documentation in annoMatrix.js. **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message addObsColumn(colSchema, Ctor, value) { - const annoMatrix = this.annoMatrix.addObsColumn(colSchema, Ctor, value); - const obsCrossfilter = this.obsCrossfilter.setData(annoMatrix._cache.obs); + const annoMatrix = (this as any).annoMatrix.addObsColumn( + colSchema, + Ctor, + value + ); + const obsCrossfilter = (this as any).obsCrossfilter.setData( + annoMatrix._cache.obs + ); return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. dropObsColumn(col) { - const annoMatrix = this.annoMatrix.dropObsColumn(col); + const annoMatrix = (this as any).annoMatrix.dropObsColumn(col); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; const dimName = _dimensionName("obs", col); if (obsCrossfilter.hasDimension(dimName)) { @@ -55,10 +69,12 @@ export default class AnnoMatrixObsCrossfilter { return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'oldCol' implicitly has an 'any' type. renameObsColumn(oldCol, newCol) { - const annoMatrix = this.annoMatrix.renameObsColumn(oldCol, newCol); + const annoMatrix = (this as any).annoMatrix.renameObsColumn(oldCol, newCol); const oldDimName = _dimensionName("obs", oldCol); const newDimName = _dimensionName("obs", newCol); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; if (obsCrossfilter.hasDimension(oldDimName)) { obsCrossfilter = obsCrossfilter.renameDimension(oldDimName, newDimName); @@ -66,9 +82,14 @@ export default class AnnoMatrixObsCrossfilter { return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. addObsAnnoCategory(col, category) { - const annoMatrix = this.annoMatrix.addObsAnnoCategory(col, category); + const annoMatrix = (this as any).annoMatrix.addObsAnnoCategory( + col, + category + ); const dimName = _dimensionName("obs", col); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; if (obsCrossfilter.hasDimension(dimName)) { obsCrossfilter = obsCrossfilter.delDimension(dimName); @@ -76,13 +97,15 @@ export default class AnnoMatrixObsCrossfilter { return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. async removeObsAnnoCategory(col, category, unassignedCategory) { - const annoMatrix = await this.annoMatrix.removeObsAnnoCategory( + const annoMatrix = await (this as any).annoMatrix.removeObsAnnoCategory( col, category, unassignedCategory ); const dimName = _dimensionName("obs", col); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; if (obsCrossfilter.hasDimension(dimName)) { obsCrossfilter = obsCrossfilter.delDimension(dimName); @@ -90,13 +113,15 @@ export default class AnnoMatrixObsCrossfilter { return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. async setObsColumnValues(col, rowLabels, value) { - const annoMatrix = await this.annoMatrix.setObsColumnValues( + const annoMatrix = await (this as any).annoMatrix.setObsColumnValues( col, rowLabels, value ); const dimName = _dimensionName("obs", col); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; if (obsCrossfilter.hasDimension(dimName)) { obsCrossfilter = obsCrossfilter.delDimension(dimName); @@ -104,13 +129,15 @@ export default class AnnoMatrixObsCrossfilter { return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. async resetObsColumnValues(col, oldValue, newValue) { - const annoMatrix = await this.annoMatrix.resetObsColumnValues( + const annoMatrix = await (this as any).annoMatrix.resetObsColumnValues( col, oldValue, newValue ); const dimName = _dimensionName("obs", col); + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; if (obsCrossfilter.hasDimension(dimName)) { obsCrossfilter = obsCrossfilter.delDimension(dimName); @@ -118,9 +145,13 @@ export default class AnnoMatrixObsCrossfilter { return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message addEmbedding(colSchema) { - const annoMatrix = this.annoMatrix.addEmbedding(colSchema); - return new AnnoMatrixObsCrossfilter(annoMatrix, this.obsCrossfilter); + const annoMatrix = (this as any).annoMatrix.addEmbedding(colSchema); + return new AnnoMatrixObsCrossfilter( + annoMatrix, + (this as any).obsCrossfilter + ); } /** @@ -128,11 +159,15 @@ export default class AnnoMatrixObsCrossfilter { * want to stop trackin the selection state, but aren't sure we want to blow the * annomatrix cache. */ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. dropDimension(field, query) { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message const { annoMatrix } = this; + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; const keys = annoMatrix .getCacheKeys(field, query) + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'k' implicitly has an 'any' type. .filter((k) => k !== undefined); const dimName = _dimensionName(field, keys); if (obsCrossfilter.hasDimension(dimName)) { @@ -146,8 +181,11 @@ export default class AnnoMatrixObsCrossfilter { are just wrappers to lazy create indices. **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. async select(field, query, spec) { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message const { annoMatrix } = this; + // @ts-expect-error ts-migrate(2339) FIXME: Property 'obsCrossfilter' does not exist on type '... Remove this comment to see the full error message let { obsCrossfilter } = this; if (!annoMatrix?._cache?.[field]) { @@ -180,55 +218,59 @@ export default class AnnoMatrixObsCrossfilter { /* Select all on any dimension in this field. */ + // @ts-expect-error ts-migrate(2339) FIXME: Property 'annoMatrix' does not exist on type 'Anno... Remove this comment to see the full error message const { annoMatrix } = this; - const currentDims = this.obsCrossfilter.dimensionNames(); + const currentDims = (this as any).obsCrossfilter.dimensionNames(); + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'xfltr' implicitly has an 'any' type. const obsCrossfilter = currentDims.reduce((xfltr, dim) => { return xfltr.select(dim, { mode: "all" }); - }, this.obsCrossfilter); + }, (this as any).obsCrossfilter); return new AnnoMatrixObsCrossfilter(annoMatrix, obsCrossfilter); } countSelected() { /* if no data yet indexed in the crossfilter, just say everything is selected */ - if (this.obsCrossfilter.size() === 0) return this.annoMatrix.nObs; - return this.obsCrossfilter.countSelected(); + if ((this as any).obsCrossfilter.size() === 0) + return (this as any).annoMatrix.nObs; + return (this as any).obsCrossfilter.countSelected(); } allSelectedMask() { /* if no data yet indexed in the crossfilter, just say everything is selected */ if ( - this.obsCrossfilter.size() === 0 || - this.obsCrossfilter.dimensionNames().length === 0 + (this as any).obsCrossfilter.size() === 0 || + (this as any).obsCrossfilter.dimensionNames().length === 0 ) { /* fake the mask */ - return new Uint8Array(this.annoMatrix.nObs).fill(1); + return new Uint8Array((this as any).annoMatrix.nObs).fill(1); } - return this.obsCrossfilter.allSelectedMask(); + return (this as any).obsCrossfilter.allSelectedMask(); } allSelectedLabels() { /* if no data yet indexed in the crossfilter, just say everything is selected */ if ( - this.obsCrossfilter.size() === 0 || - this.obsCrossfilter.dimensionNames().length === 0 + (this as any).obsCrossfilter.size() === 0 || + (this as any).obsCrossfilter.dimensionNames().length === 0 ) { - return this.annoMatrix.rowIndex.labels(); + return (this as any).annoMatrix.rowIndex.labels(); } - const mask = this.obsCrossfilter.allSelectedMask(); - const index = this.annoMatrix.rowIndex.isubsetMask(mask); + const mask = (this as any).obsCrossfilter.allSelectedMask(); + const index = (this as any).annoMatrix.rowIndex.isubsetMask(mask); return index.labels(); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'array' implicitly has an 'any' type. fillByIsSelected(array, selectedValue, deselectedValue) { /* if no data yet indexed in the crossfilter, just say everything is selected */ if ( - this.obsCrossfilter.size() === 0 || - this.obsCrossfilter.dimensionNames().length === 0 + (this as any).obsCrossfilter.size() === 0 || + (this as any).obsCrossfilter.dimensionNames().length === 0 ) { return array.fill(selectedValue); } - return this.obsCrossfilter.fillByIsSelected( + return (this as any).obsCrossfilter.fillByIsSelected( array, selectedValue, deselectedValue @@ -239,21 +281,29 @@ export default class AnnoMatrixObsCrossfilter { ** Private below **/ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message _addObsCrossfilterDimension(annoMatrix, obsCrossfilter, field, df) { if (field === "var") return obsCrossfilter; const dimName = _dimensionNameFromDf(field, df); const dimParams = this._getObsDimensionParams(field, df); obsCrossfilter = obsCrossfilter.setData(annoMatrix._cache.obs); + // @ts-expect-error ts-migrate(2488) FIXME: Type 'any[] | undefined' must have a '[Symbol.iter... Remove this comment to see the full error message obsCrossfilter = obsCrossfilter.addDimension(dimName, ...dimParams); return obsCrossfilter; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. _getColumnBaseType(field, col) { /* Look up the primitive type for this field/col */ - const colSchema = _getColumnSchema(this.annoMatrix.schema, field, col); + const colSchema = _getColumnSchema( + (this as any).annoMatrix.schema, + field, + col + ); return colSchema.type; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. _getObsDimensionParams(field, df) { /* return the crossfilter dimensiontype type and params for this field/dataframe */ diff --git a/client/src/annoMatrix/fetchHelpers.js b/client/src/annoMatrix/fetchHelpers.ts similarity index 78% rename from client/src/annoMatrix/fetchHelpers.js rename to client/src/annoMatrix/fetchHelpers.ts index 43f99705..c5db07ba 100644 --- a/client/src/annoMatrix/fetchHelpers.js +++ b/client/src/annoMatrix/fetchHelpers.ts @@ -1,19 +1,19 @@ export { doBinaryRequest, doFetch } from "../util/actionHelpers"; /* double URI encode - needed for query-param filters */ -export function _dubEncURIComp(s) { +export function _dubEncURIComp(s: any) { return encodeURIComponent(encodeURIComponent(s)); } /* currently unused, consider deleting */ -export function _fetchResult(promise) { +export function _fetchResult(promise: any) { let _status = "pending"; const res = promise.then( - (r) => { + (r: any) => { _status = "success"; return r; }, - (e) => { + (e: any) => { _status = "error"; throw e; } diff --git a/client/src/annoMatrix/index.js b/client/src/annoMatrix/index.ts similarity index 100% rename from client/src/annoMatrix/index.js rename to client/src/annoMatrix/index.ts diff --git a/client/src/annoMatrix/loader.js b/client/src/annoMatrix/loader.ts similarity index 80% rename from client/src/annoMatrix/loader.js rename to client/src/annoMatrix/loader.ts index c33e8be7..e2e3dd54 100644 --- a/client/src/annoMatrix/loader.js +++ b/client/src/annoMatrix/loader.ts @@ -23,6 +23,8 @@ import { const promiseThrottle = new PromiseLimit(5); export default class AnnoMatrixLoader extends AnnoMatrix { + baseURL: any; + /* AnnoMatrix implementation which proxies to HTTP server using the CXG REST API. Used as the base (non-view) instance. @@ -33,7 +35,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { new AnnoMatrixLoader(serverBaseURL, schema) -> instance */ - constructor(baseURL, schema) { + constructor(baseURL: any, schema: any) { const { nObs, nVar } = schema.dataframe; super(schema, nObs, nVar); @@ -48,7 +50,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { /** ** Public. API described in base class. **/ - addObsAnnoCategory(col, category) { + addObsAnnoCategory(col: any, category: any) { /* Add a new category (aka label) to the schema for an obs column. */ @@ -60,7 +62,11 @@ export default class AnnoMatrixLoader extends AnnoMatrix { return newAnnoMatrix; } - async removeObsAnnoCategory(col, category, unassignedCategory) { + async removeObsAnnoCategory( + col: any, + category: any, + unassignedCategory: any + ) { /* Remove a single "category" (aka "label") from the data & schema of an obs column. */ @@ -80,7 +86,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { return newAnnoMatrix; } - dropObsColumn(col) { + dropObsColumn(col: any) { /* drop column from field */ @@ -88,11 +94,12 @@ export default class AnnoMatrixLoader extends AnnoMatrix { _writableCheck(colSchema); // throws on error const newAnnoMatrix = this._clone(); - newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col); + newAnnoMatrix._cache.obs = (this as any)._cache.obs.dropCol(col); newAnnoMatrix.schema = removeObsAnnoColumn(this.schema, col); return newAnnoMatrix; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message addObsColumn(colSchema, Ctor, value) { /* add a column to field, initializing with value. Value may @@ -105,7 +112,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { const colName = colSchema.name; if ( _getColumnSchema(this.schema, "obs", colName) || - this._cache.obs.hasCol(colName) + (this as any)._cache.obs.hasCol(colName) ) { throw new Error("column already exists"); } @@ -121,7 +128,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { } else { data = new Ctor(this.nObs).fill(value); } - newAnnoMatrix._cache.obs = this._cache.obs.withCol(colName, data); + newAnnoMatrix._cache.obs = (this as any)._cache.obs.withCol(colName, data); _normalizeCategoricalSchema( colSchema, newAnnoMatrix._cache.obs.col(colName) @@ -130,15 +137,15 @@ export default class AnnoMatrixLoader extends AnnoMatrix { return newAnnoMatrix; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'oldCol' implicitly has an 'any' type. renameObsColumn(oldCol, newCol) { /* Rename the obs oldColName to newColName. oldCol must be writable. */ const oldColSchema = _getColumnSchema(this.schema, "obs", oldCol); - _writableCheck(oldColSchema); // throws on error - - const value = this._cache.obs.hasCol(oldCol) - ? this._cache.obs.col(oldCol).asArray() + _writableCheck(oldColSchema); + const value = (this as any)._cache.obs.hasCol(oldCol) + ? (this as any)._cache.obs.col(oldCol).asArray() : undefined; return this.dropObsColumn(oldCol).addObsColumn( { @@ -150,6 +157,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { ); } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. async setObsColumnValues(col, rowLabels, value) { /* Set all rows identified by rowLabels to value. @@ -159,11 +167,11 @@ export default class AnnoMatrixLoader extends AnnoMatrix { // ensure that we have the data in cache before we manipulate it await this.fetch("obs", col); - if (!this._cache.obs.hasCol(col)) + if (!(this as any)._cache.obs.hasCol(col)) throw new Error("Internal error - user annotation data missing"); const rowIndices = this.rowIndex.getOffsets(rowLabels); - const data = this._cache.obs.col(col).asArray().slice(); + const data = (this as any)._cache.obs.col(col).asArray().slice(); for (let i = 0, len = rowIndices.length; i < len; i += 1) { const idx = rowIndices[i]; if (idx === undefined) throw new Error("Unknown row label"); @@ -171,7 +179,10 @@ export default class AnnoMatrixLoader extends AnnoMatrix { } const newAnnoMatrix = this._clone(); - newAnnoMatrix._cache.obs = this._cache.obs.replaceColData(col, data); + newAnnoMatrix._cache.obs = (this as any)._cache.obs.replaceColData( + col, + data + ); const { categories } = colSchema; if (!categories?.includes(value)) { newAnnoMatrix.schema = addObsAnnoCategory(this.schema, col, value); @@ -179,6 +190,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { return newAnnoMatrix; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'col' implicitly has an 'any' type. async resetObsColumnValues(col, oldValue, newValue) { /* Set all rows with value 'oldValue' to 'newValue'. @@ -192,16 +204,19 @@ export default class AnnoMatrixLoader extends AnnoMatrix { // ensure that we have the data in cache before we manipulate it await this.fetch("obs", col); - if (!this._cache.obs.hasCol(col)) + if (!(this as any)._cache.obs.hasCol(col)) throw new Error("Internal error - user annotation data missing"); - const data = this._cache.obs.col(col).asArray().slice(); + const data = (this as any)._cache.obs.col(col).asArray().slice(); for (let i = 0, l = data.length; i < l; i += 1) { if (data[i] === oldValue) data[i] = newValue; } const newAnnoMatrix = this._clone(); - newAnnoMatrix._cache.obs = this._cache.obs.replaceColData(col, data); + newAnnoMatrix._cache.obs = (this as any)._cache.obs.replaceColData( + col, + data + ); const { categories } = colSchema; if (!categories?.includes(newValue)) { newAnnoMatrix.schema = addObsAnnoCategory(this.schema, col, newValue); @@ -209,6 +224,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { return newAnnoMatrix; } + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message addEmbedding(colSchema) { /* add new layout to the obs embeddings @@ -226,6 +242,7 @@ export default class AnnoMatrixLoader extends AnnoMatrix { /** ** Private below **/ + // @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixLoader' is n... Remove this comment to see the full error message async _doLoad(field, query) { /* _doLoad - evaluates the query against the field. Returns: @@ -280,12 +297,14 @@ export default class AnnoMatrixLoader extends AnnoMatrix { Utility functions below */ +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message function _writableCheck(colSchema) { if (!colSchema?.writable) { throw new Error("Unknown or readonly obs column"); } } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message function _writableCategoryTypeCheck(colSchema) { _writableCheck(colSchema); if (colSchema.type !== "categorical") { @@ -293,6 +312,7 @@ function _writableCategoryTypeCheck(colSchema) { } } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type. function _embLoader(baseURL, _field, query) { _expectSimpleQuery(query); @@ -302,6 +322,7 @@ function _embLoader(baseURL, _field, query) { return () => doBinaryRequest(url); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type. function _obsOrVarLoader(baseURL, field, query) { _expectSimpleQuery(query); @@ -311,6 +332,7 @@ function _obsOrVarLoader(baseURL, field, query) { return () => doBinaryRequest(url); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'baseURL' implicitly has an 'any' type. function _XLoader(baseURL, field, query) { _expectComplexQuery(query); diff --git a/client/src/annoMatrix/middleware.js b/client/src/annoMatrix/middleware.ts similarity index 81% rename from client/src/annoMatrix/middleware.js rename to client/src/annoMatrix/middleware.ts index d332b79a..9e26de32 100644 --- a/client/src/annoMatrix/middleware.js +++ b/client/src/annoMatrix/middleware.ts @@ -11,7 +11,7 @@ Undoable metareducer and the AnnoMatrix private API. It would be helpful to make the Undoable interface better factored. */ -const annoMatrixGC = (store) => (next) => (action) => { +const annoMatrixGC = (store: any) => (next: any) => (action: any) => { if (_itIsTimeForGC()) { _doGC(store); } @@ -34,7 +34,7 @@ function _itIsTimeForGC() { return false; } -function _doGC(store) { +function _doGC(store: any) { const state = store.getState(); // these should probably be a function imported from undoable.js, etc, as @@ -43,8 +43,8 @@ function _doGC(store) { const undoableFuture = state["@@undoable/future"]; const undoableStack = undoablePast .concat(undoableFuture) - .flatMap((snapshot) => - snapshot.filter((v) => v[0] === "annoMatrix").map((v) => v[1]) + .flatMap((snapshot: any) => + snapshot.filter((v: any) => v[0] === "annoMatrix").map((v: any) => v[1]) ); const currentAnnoMatrix = state.annoMatrix; @@ -53,14 +53,16 @@ function _doGC(store) { as our current gc algo is more aggressive with those not hot. */ const allAnnoMatrices = new Map( - undoableStack.map((m) => [m, { isHot: false }]) + undoableStack.map((m: any) => [m, { isHot: false }]) ); let am = currentAnnoMatrix; while (am) { allAnnoMatrices.set(am, { isHot: true }); am = am.viewOf; } - allAnnoMatrices.forEach((hints, annoMatrix) => annoMatrix._gc(hints)); + allAnnoMatrices.forEach((hints, annoMatrix) => + (annoMatrix as any)._gc(hints) + ); } export default annoMatrixGC; diff --git a/client/src/annoMatrix/query.js b/client/src/annoMatrix/query.ts similarity index 85% rename from client/src/annoMatrix/query.js rename to client/src/annoMatrix/query.ts index 55017858..f692b94e 100644 --- a/client/src/annoMatrix/query.js +++ b/client/src/annoMatrix/query.ts @@ -10,7 +10,7 @@ import { _dubEncURIComp } from "./fetchHelpers"; * @param {object | string} query - the query * @returns {object | string} - the normalized query */ -export function _queryValidate(query) { +export function _queryValidate(query: any) { if (typeof query !== "object") return query; if (query.where && query.summarize) @@ -40,11 +40,11 @@ export function _queryValidate(query) { throw new Error("query must specify one of where or summarize"); } -export function _expectSimpleQuery(query) { +export function _expectSimpleQuery(query: any) { if (typeof query === "object") throw new Error("expected simple query"); } -export function _expectComplexQuery(query) { +export function _expectComplexQuery(query: any) { if (typeof query !== "object") throw new Error("expected complex query"); } @@ -55,7 +55,7 @@ export function _expectComplexQuery(query) { * @param {string|object} query * @returns the key */ -export function _queryCacheKey(field, query) { +export function _queryCacheKey(field: any, query: any) { if (typeof query === "object") { // complex query if (query.where) { @@ -84,22 +84,22 @@ export function _queryCacheKey(field, query) { return `${field}/${query}`; } -function _urlEncodeWhereQuery(q) { +function _urlEncodeWhereQuery(q: any) { const { field: queryField, column: queryColumn, value: queryValue } = q; return `${_dubEncURIComp(queryField)}:${_dubEncURIComp( queryColumn )}=${_dubEncURIComp(queryValue)}`; } -function _urlEncodeSummarizeQuery(q) { +function _urlEncodeSummarizeQuery(q: any) { const { method, field, column, values } = q; const filter = values - .map((value) => _urlEncodeWhereQuery({ field, column, value })) + .map((value: any) => _urlEncodeWhereQuery({ field, column, value })) .join("&"); return `method=${method}&${filter}`; } -export function _urlEncodeComplexQuery(q) { +export function _urlEncodeComplexQuery(q: any) { if (typeof q === "object") { if (q.where) { return _urlEncodeWhereQuery(q.where); @@ -111,7 +111,7 @@ export function _urlEncodeComplexQuery(q) { throw new Error("Unrecognized complex query type"); } -export function _urlEncodeLabelQuery(colKey, q) { +export function _urlEncodeLabelQuery(colKey: any, q: any) { if (!colKey) throw new Error("Unsupported query by name"); if (typeof q !== "string") throw new Error("Query must be a simple label."); return `${colKey}=${encodeURIComponent(q)}`; @@ -120,7 +120,7 @@ export function _urlEncodeLabelQuery(colKey, q) { /** * Generate the column key the server will send us for this query. */ -export function _hashStringValues(arrayOfString) { +export function _hashStringValues(arrayOfString: any) { const hash = sha1(arrayOfString.join("")); return hash; } diff --git a/client/src/annoMatrix/schema.js b/client/src/annoMatrix/schema.ts similarity index 73% rename from client/src/annoMatrix/schema.js rename to client/src/annoMatrix/schema.ts index aade2c20..02fd636c 100644 --- a/client/src/annoMatrix/schema.js +++ b/client/src/annoMatrix/schema.ts @@ -4,7 +4,7 @@ Private helper functions related to schema import catLabelSort from "../util/catLabelSort"; import { unassignedCategoryLabel } from "../globals"; -export function _getColumnSchema(schema, field, col) { +export function _getColumnSchema(schema: any, field: any, col: any) { /* look up the column definition */ switch (field) { case "obs": @@ -26,7 +26,7 @@ export function _getColumnSchema(schema, field, col) { } } -export function _getColumnDimensionNames(schema, field, col) { +export function _getColumnDimensionNames(schema: any, field: any, col: any) { /* field/col may be an alias for multiple columns. Currently used to map ND values to 1D dataframe columns for embeddings/layout. Signified by the presence @@ -39,6 +39,7 @@ export function _getColumnDimensionNames(schema, field, col) { return colSchema.dims || [col]; } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type. export function _schemaColumns(schema, field) { switch (field) { case "obs": @@ -52,18 +53,25 @@ export function _schemaColumns(schema, field) { } } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type. export function _getWritableColumns(schema, field) { if (field !== "obs") return []; - return schema.annotations.obs.columns - .filter((v) => v.writable) - .map((v) => v.name); + return ( + schema.annotations.obs.columns + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'v' implicitly has an 'any' type. + .filter((v) => v.writable) + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'v' implicitly has an 'any' type. + .map((v) => v.name) + ); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'schema' implicitly has an 'any' type. export function _isContinuousType(schema) { const { type } = schema; return !(type === "string" || type === "boolean" || type === "categorical"); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colSchema' implicitly has an 'any' type... Remove this comment to see the full error message export function _normalizeCategoricalSchema(colSchema, col) { const { type, writable } = colSchema; if ( diff --git a/client/src/annoMatrix/viewCreators.js b/client/src/annoMatrix/viewCreators.ts similarity index 71% rename from client/src/annoMatrix/viewCreators.js rename to client/src/annoMatrix/viewCreators.ts index 28991b44..5e129dd3 100644 --- a/client/src/annoMatrix/viewCreators.js +++ b/client/src/annoMatrix/viewCreators.ts @@ -5,7 +5,7 @@ instances of AnnoMatrix, implementing common UI functions. import { AnnoMatrixRowSubsetView, AnnoMatrixClipView } from "./views"; -export function isubsetMask(annoMatrix, obsMask) { +export function isubsetMask(annoMatrix: any, obsMask: any) { /* Subset annomatrix to contain the rows which have truish value in the mask. Maks length must equal annoMatrix.nObs (row count). @@ -13,6 +13,7 @@ export function isubsetMask(annoMatrix, obsMask) { return isubset(annoMatrix, _maskToList(obsMask)); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message export function isubset(annoMatrix, obsOffsets) { /* Subset annomatrix to contain the positions contained in the obsOffsets array @@ -25,6 +26,7 @@ export function isubset(annoMatrix, obsOffsets) { return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message export function subset(annoMatrix, obsLabels) { /* subset based on labels @@ -33,6 +35,7 @@ export function subset(annoMatrix, obsLabels) { return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message export function subsetByIndex(annoMatrix, obsIndex) { /* subset based upon the new obs index. @@ -40,6 +43,7 @@ export function subsetByIndex(annoMatrix, obsIndex) { return new AnnoMatrixRowSubsetView(annoMatrix, obsIndex); } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'annoMatrix' implicitly has an 'any' typ... Remove this comment to see the full error message export function clip(annoMatrix, qmin, qmax) { /* Create a view that clips all continuous data to the [min, max] range. @@ -53,6 +57,7 @@ export function clip(annoMatrix, qmin, qmax) { Private utility functions below */ +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'mask' implicitly has an 'any' type. function _maskToList(mask) { /* convert masks to lists - method wastes space, but is fast */ if (!mask) { diff --git a/client/src/annoMatrix/views.js b/client/src/annoMatrix/views.ts similarity index 74% rename from client/src/annoMatrix/views.js rename to client/src/annoMatrix/views.ts index 5b9b9c26..2f395b39 100644 --- a/client/src/annoMatrix/views.js +++ b/client/src/annoMatrix/views.ts @@ -9,21 +9,26 @@ import { _whereCacheCreate } from "./whereCache"; import { _isContinuousType, _getColumnSchema } from "./schema"; class AnnoMatrixView extends AnnoMatrix { - constructor(viewOf, rowIndex = null) { + constructor(viewOf: any, rowIndex = null) { + // @ts-expect-error ts-migrate(2531) FIXME: Object is possibly 'null'. const nObs = rowIndex ? rowIndex.size() : viewOf.nObs; super(viewOf.schema, nObs, viewOf.nVar, rowIndex || viewOf.rowIndex); this.viewOf = viewOf; this.isView = true; } - addObsAnnoCategory(col, category) { + addObsAnnoCategory(col: any, category: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = this.viewOf.addObsAnnoCategory(col, category); newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema; return newAnnoMatrix; } - async removeObsAnnoCategory(col, category, unassignedCategory) { + async removeObsAnnoCategory( + col: any, + category: any, + unassignedCategory: any + ) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = await this.viewOf.removeObsAnnoCategory( col, @@ -34,7 +39,7 @@ class AnnoMatrixView extends AnnoMatrix { return newAnnoMatrix; } - dropObsColumn(col) { + dropObsColumn(col: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = this.viewOf.dropObsColumn(col); newAnnoMatrix._cache.obs = this._cache.obs.dropCol(col); @@ -42,21 +47,21 @@ class AnnoMatrixView extends AnnoMatrix { return newAnnoMatrix; } - addObsColumn(colSchema, Ctor, value) { + addObsColumn(colSchema: any, Ctor: any, value: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = this.viewOf.addObsColumn(colSchema, Ctor, value); newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema; return newAnnoMatrix; } - renameObsColumn(oldCol, newCol) { + renameObsColumn(oldCol: any, newCol: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = this.viewOf.renameObsColumn(oldCol, newCol); newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema; return newAnnoMatrix; } - async setObsColumnValues(col, rowLabels, value) { + async setObsColumnValues(col: any, rowLabels: any, value: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = await this.viewOf.setObsColumnValues( col, @@ -68,7 +73,7 @@ class AnnoMatrixView extends AnnoMatrix { return newAnnoMatrix; } - async resetObsColumnValues(col, oldValue, newValue) { + async resetObsColumnValues(col: any, oldValue: any, newValue: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = await this.viewOf.resetObsColumnValues( col, @@ -80,7 +85,7 @@ class AnnoMatrixView extends AnnoMatrix { return newAnnoMatrix; } - addEmbedding(colSchema) { + addEmbedding(colSchema: any) { const newAnnoMatrix = this._clone(); newAnnoMatrix.viewOf = this.viewOf.addEmbedding(colSchema); newAnnoMatrix.schema = newAnnoMatrix.viewOf.schema; @@ -92,17 +97,20 @@ class AnnoMatrixMapView extends AnnoMatrixView { /* A view which knows how to transform its data. */ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type. constructor(viewOf, mapFn) { super(viewOf); - this.mapFn = mapFn; + (this as any).mapFn = mapFn; } + // @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixMapView' is ... Remove this comment to see the full error message async _doLoad(field, query) { const df = await this.viewOf._fetch(field, query); + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'colData' implicitly has an 'any' type. const dfMapped = df.mapColumns((colData, colIdx) => { const colLabel = df.colIndex.getLabel(colIdx); const colSchema = _getColumnSchema(this.schema, field, colLabel); - return this.mapFn(field, colLabel, colSchema, colData, df); + return (this as any).mapFn(field, colLabel, colSchema, colData, df); }); const whereCacheUpdate = _whereCacheCreate( field, @@ -117,12 +125,14 @@ export class AnnoMatrixClipView extends AnnoMatrixMapView { /* A view which is a clipped transformation of its parent */ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type. constructor(viewOf, qmin, qmax) { + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. super(viewOf, (field, colLabel, colSchema, colData, df) => _clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax) ); - this.isClipped = true; - this.clipRange = [qmin, qmax]; + (this as any).isClipped = true; + (this as any).clipRange = [qmin, qmax]; Object.seal(this); } } @@ -131,11 +141,13 @@ export class AnnoMatrixRowSubsetView extends AnnoMatrixView { /* A view which is a subset of total rows. */ + // @ts-expect-error ts-migrate(7006) FIXME: Parameter 'viewOf' implicitly has an 'any' type. constructor(viewOf, rowIndex) { super(viewOf, rowIndex); Object.seal(this); } + // @ts-expect-error ts-migrate(2416) FIXME: Property '_doLoad' in type 'AnnoMatrixRowSubsetVie... Remove this comment to see the full error message async _doLoad(field, query) { const df = await this.viewOf._fetch(field, query); @@ -158,6 +170,7 @@ export class AnnoMatrixRowSubsetView extends AnnoMatrixView { Utility functions below */ +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. function _clipAnnoMatrix(field, colLabel, colSchema, colData, df, qmin, qmax) { /* only clip obs and var scalar columns */ if (field !== "obs" && field !== "X") return colData; diff --git a/client/src/annoMatrix/whereCache.js b/client/src/annoMatrix/whereCache.ts similarity index 87% rename from client/src/annoMatrix/whereCache.js rename to client/src/annoMatrix/whereCache.ts index e67c5d49..567967f4 100644 --- a/client/src/annoMatrix/whereCache.js +++ b/client/src/annoMatrix/whereCache.ts @@ -51,7 +51,12 @@ creates a cache entry of: import { _getColumnDimensionNames } from "./schema"; import { _hashStringValues } from "./query"; -export function _whereCacheGet(whereCache, schema, field, query) { +export function _whereCacheGet( + whereCache: any, + schema: any, + field: any, + query: any +) { /* query will either be an where query (object) or a column name (string). @@ -85,6 +90,7 @@ export function _whereCacheGet(whereCache, schema, field, query) { return _getColumnDimensionNames(schema, field, query) ?? [undefined]; } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'field' implicitly has an 'any' type. export function _whereCacheCreate(field, query, columnLabels) { /* Create a new whereCache @@ -131,10 +137,11 @@ export function _whereCacheCreate(field, query, columnLabels) { return {}; } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'dst' implicitly has an 'any' type. function __mergeQueries(dst, src) { for (const [queryField, columnMap] of Object.entries(src)) { dst[queryField] = dst[queryField] || new Map(); - for (const [queryColumn, valueMap] of columnMap) { + for (const [queryColumn, valueMap] of columnMap as any) { if (!dst[queryField].has(queryColumn)) dst[queryField].set(queryColumn, new Map()); for (const [queryValue, columnLabels] of valueMap) { @@ -144,6 +151,7 @@ function __mergeQueries(dst, src) { } } +// @ts-expect-error ts-migrate(7006) FIXME: Parameter 'dst' implicitly has an 'any' type. function __whereCacheMerge(dst, src) { /* merge src into dst (modifies dst) @@ -161,6 +169,7 @@ function __whereCacheMerge(dst, src) { dst.summarize = dst.summarize || {}; for (const [field, method] of Object.entries(src.summarize)) { dst.summarize[field] = dst.summarize[field] || {}; + // @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. for (const [methodName, query] of Object.entries(method)) { dst.summarize[field][methodName] = dst.summarize[field][methodName] || {}; @@ -171,6 +180,7 @@ function __whereCacheMerge(dst, src) { return dst; } +// @ts-expect-error ts-migrate(7019) FIXME: Rest parameter 'caches' implicitly has an 'any[]' ... Remove this comment to see the full error message export function _whereCacheMerge(...caches) { return caches.reduce(__whereCacheMerge, {}); } diff --git a/client/src/components/annoDialog.js b/client/src/components/annoDialog.tsx similarity index 50% rename from client/src/components/annoDialog.js rename to client/src/components/annoDialog.tsx index 8064b146..bcd4f969 100644 --- a/client/src/components/annoDialog.js +++ b/client/src/components/annoDialog.tsx @@ -1,30 +1,49 @@ import React from "react"; import { Button, Tooltip, Dialog, Classes, Colors } from "@blueprintjs/core"; -class AnnoDialog extends React.PureComponent { - constructor(props) { +type State = any; + +class AnnoDialog extends React.PureComponent<{}, State> { + constructor(props: {}) { super(props); this.state = {}; } render() { const { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'isActive' does not exist on type 'Readon... Remove this comment to see the full error message isActive, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'text' does not exist on type 'Readonly<{... Remove this comment to see the full error message text, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'title' does not exist on type 'Readonly<... Remove this comment to see the full error message title, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'instruction' does not exist on type 'Rea... Remove this comment to see the full error message instruction, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'cancelTooltipContent' does not exist on ... Remove this comment to see the full error message cancelTooltipContent, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'errorMessage' does not exist on type 'Re... Remove this comment to see the full error message errorMessage, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'validationError' does not exist on type ... Remove this comment to see the full error message validationError, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'annoSelect' does not exist on type 'Read... Remove this comment to see the full error message annoSelect, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'annoInput' does not exist on type 'Reado... Remove this comment to see the full error message annoInput, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'secondaryInstructions' does not exist on... Remove this comment to see the full error message secondaryInstructions, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'secondaryInput' does not exist on type '... Remove this comment to see the full error message secondaryInput, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'handleCancel' does not exist on type 'Re... Remove this comment to see the full error message handleCancel, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'handleSubmit' does not exist on type 'Re... Remove this comment to see the full error message handleSubmit, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'primaryButtonText' does not exist on typ... Remove this comment to see the full error message primaryButtonText, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'secondaryButtonText' does not exist on t... Remove this comment to see the full error message secondaryButtonText, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'handleSecondaryButtonSubmit' does not ex... Remove this comment to see the full error message handleSecondaryButtonSubmit, + // @ts-expect-error ts-migrate(2339) FIXME: Property 'primaryButtonProps' does not exist on ty... Remove this comment to see the full error message primaryButtonProps, } = this.props; diff --git a/client/src/components/app.js b/client/src/components/app.tsx similarity index 66% rename from client/src/components/app.js rename to client/src/components/app.tsx index eb46d3a6..624c1198 100644 --- a/client/src/components/app.js +++ b/client/src/components/app.tsx @@ -15,30 +15,32 @@ import TermsOfServicePrompt from "./termsPrompt"; import actions from "../actions"; +// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message @connect((state) => ({ - loading: state.controls.loading, - error: state.controls.error, - graphRenderCounter: state.controls.graphRenderCounter, + loading: (state as any).controls.loading, + error: (state as any).controls.error, + graphRenderCounter: (state as any).controls.graphRenderCounter, })) class App extends React.Component { componentDidMount() { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message const { dispatch } = this.props; - /* listen for url changes, fire one when we start the app up */ window.addEventListener("popstate", this._onURLChanged); this._onURLChanged(); - + // @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1. dispatch(actions.doInitialDataLoad(window.location.search)); this.forceUpdate(); } _onURLChanged() { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message const { dispatch } = this.props; - dispatch({ type: "url changed", url: document.location.href }); } render() { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'loading' does not exist on type 'Readonl... Remove this comment to see the full error message const { loading, error, graphRenderCounter } = this.props; return ( @@ -70,13 +72,15 @@ class App extends React.Component { {loading || error ? null : ( - {(viewportRef) => ( + {(viewportRef: any) => ( <> + {/* @ts-expect-error ts-migrate(2769) FIXME: No overload matches this call. */} + {/* @ts-expect-error ts-migrate(2322) FIXME: Type '{ key: any; viewportRef: any; }' is not assi... Remove this comment to see the full error message */} )} diff --git a/client/src/components/autosave/filenameDialog.js b/client/src/components/autosave/filenameDialog.tsx similarity index 62% rename from client/src/components/autosave/filenameDialog.js rename to client/src/components/autosave/filenameDialog.tsx index 83f91eb0..74432ac9 100644 --- a/client/src/components/autosave/filenameDialog.js +++ b/client/src/components/autosave/filenameDialog.tsx @@ -11,18 +11,23 @@ import { Tooltip, } from "@blueprintjs/core"; +type State = any; + +// @ts-expect-error ts-migrate(1238) FIXME: Unable to resolve signature of class decorator whe... Remove this comment to see the full error message @connect((state) => ({ - idhash: state.config?.parameters?.["annotations-user-data-idhash"] ?? null, - annotations: state.annotations, - auth: state.config?.authentication, - userInfo: state.userInfo, - writableCategoriesEnabled: state.config?.parameters?.annotations ?? false, + idhash: + (state as any).config?.parameters?.["annotations-user-data-idhash"] ?? null, + annotations: (state as any).annotations, + auth: (state as any).config?.authentication, + userInfo: (state as any).userInfo, + writableCategoriesEnabled: + (state as any).config?.parameters?.annotations ?? false, writableGenesetsEnabled: !( - state.config?.parameters?.annotations_genesets_readonly ?? true + (state as any).config?.parameters?.annotations_genesets_readonly ?? true ), })) -class FilenameDialog extends React.Component { - constructor(props) { +class FilenameDialog extends React.Component<{}, State> { + constructor(props: {}) { super(props); this.state = { filenameText: "", @@ -32,9 +37,9 @@ class FilenameDialog extends React.Component { dismissFilenameDialog = () => {}; handleCreateFilename = () => { + // @ts-expect-error ts-migrate(2339) FIXME: Property 'dispatch' does not exist on type 'Readon... Remove this comment to see the full error message const { dispatch } = this.props; const { filenameText } = this.state; - dispatch({ type: "set annotations collection name", data: filenameText, @@ -45,26 +50,26 @@ class FilenameDialog extends React.Component { const legalNames = /^\w+$/; const { filenameText } = this.state; let err = false; - if (filenameText === "") { + // @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'boolean'. err = "empty_string"; } else if (!legalNames.test(filenameText)) { /* - IMPORTANT: this test must ultimately match the test applied by the - backend, which is designed to ensure a safe file name can be created - from the data collection name. If you change this, you will also need - to change the validation code in the backend, or it will have no effect. - */ + IMPORTANT: this test must ultimately match the test applied by the + backend, which is designed to ensure a safe file name can be created + from the data collection name. If you change this, you will also need + to change the validation code in the backend, or it will have no effect. + */ + // @ts-expect-error ts-migrate(2322) FIXME: Type 'string' is not assignable to type 'boolean'. err = "characters"; } - return err; }; filenameErrorMessage = () => { const err = this.filenameError(); let markup = null; - + // @ts-expect-error ts-migrate(2367) FIXME: This condition will always return 'false' since th... Remove this comment to see the full error message if (err === "empty_string") { markup = ( ); + // @ts-expect-error ts-migrate(2367) FIXME: This condition will always return 'false' since th... Remove this comment to see the full error message } else if (err === "characters") { markup = ( this.setState({ filenameText: e.target.value }) @@ -138,12 +149,14 @@ class FilenameDialog extends React.Component {

+ {/* @ts-expect-error ts-migrate(2554) FIXME: Expected 0 arguments, but got 1. */} {this.filenameErrorMessage(filenameText)}

@@ -171,6 +184,7 @@ class FilenameDialog extends React.Component {