From c5dbd3b0c30121bf7ee2ad8e34993f25badae41e Mon Sep 17 00:00:00 2001 From: Mathieu Marques Date: Thu, 12 Jan 2023 19:24:55 +0100 Subject: [PATCH] perf(remark): remove partials from page props (#195) * perf(remark): remove partials from page props * chore(lint): add ts-prune --- .eslintrc.json | 1 - .gitignore | 2 +- .ts-prunerc.json | 3 + package.json | 8 +- src/components/Remark/Remark.tsx | 11 +-- .../Remark/renderers/RemarkAccordion.tsx | 86 ++++++++----------- src/pages/[category]/[chapter].tsx | 29 ++----- .../[year]/[month]/[day]/[article].tsx | 31 ++----- src/pages/index.tsx | 28 ++---- src/pages/license.tsx | 20 ++--- src/tools/markdown/getMarkdown.ts | 65 +++++++++----- src/tools/markdown/getPartials.ts | 34 -------- src/tools/markdown/types.ts | 1 + src/tools/remark/remarkAccordion.ts | 2 - src/tools/remark/remarkPartials.ts | 41 +++++++++ .../{remarkScryfall.ts => remarkScries.ts} | 2 +- src/tools/scryfall/types.ts | 14 --- yarn.lock | 61 ++++++++++++- 18 files changed, 220 insertions(+), 219 deletions(-) create mode 100644 .ts-prunerc.json delete mode 100644 src/tools/markdown/getPartials.ts create mode 100644 src/tools/remark/remarkPartials.ts rename src/tools/remark/{remarkScryfall.ts => remarkScries.ts} (98%) diff --git a/.eslintrc.json b/.eslintrc.json index ae5f1414..467a9298 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -65,7 +65,6 @@ "warn", { "ignoreRestSiblings": true } ], - "@typescript-eslint/no-use-before-define": "error", "camelcase": ["warn", { "ignoreDestructuring": true }], "import/extensions": [ "error", diff --git a/.gitignore b/.gitignore index 55646d07..67dc3a38 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ .vercel/ coverage/ node_modules/ -.env.local +.env*.local tsconfig.tsbuildinfo diff --git a/.ts-prunerc.json b/.ts-prunerc.json new file mode 100644 index 00000000..c497cd82 --- /dev/null +++ b/.ts-prunerc.json @@ -0,0 +1,3 @@ +{ + "ignore": "src/pages/" +} diff --git a/package.json b/package.json index 87439ca2..32bc3a63 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,11 @@ "node": "18" }, "scripts": { - "build": "concurrently -c auto -n 'next,scryfall' 'NEXT_PUBLIC_HASH=$(git rev-parse --short HEAD) next build' 'yarn scryfall' --kill-others --success first", - "dev": "concurrently -c auto -n 'next,scryfall' 'NEXT_PUBLIC_HASH=$(git rev-parse --short HEAD) next dev' 'yarn scryfall'", - "lint": "yarn lint:code && yarn lint:typings", + "build": "concurrently 'NEXT_PUBLIC_HASH=$(git rev-parse --short HEAD) next build' 'yarn scryfall' --names 'next,scryfall' --prefix-colors auto --kill-others --success first", + "dev": "concurrently 'NEXT_PUBLIC_HASH=$(git rev-parse --short HEAD) next dev' 'yarn scryfall' --names 'next,scryfall' --prefix-colors auto", + "lint": "concurrently 'yarn:lint:*(!wiki)' --names --prefix-colors auto --success all", "lint:code": "eslint .", + "lint:prune": "ts-prune --error", "lint:typings": "tsc", "lint:wiki": "markdownlint markdown/", "prepare": "husky install", @@ -73,6 +74,7 @@ "markdownlint-cli": "0.33.0", "msw": "0.49.2", "prettier": "2.8.2", + "ts-prune": "0.10.3", "typescript": "4.9.4" } } diff --git a/src/components/Remark/Remark.tsx b/src/components/Remark/Remark.tsx index 4fcb93ab..25ca5ba5 100644 --- a/src/components/Remark/Remark.tsx +++ b/src/components/Remark/Remark.tsx @@ -9,7 +9,7 @@ import { Box } from '@mui/material'; // eslint-disable-next-line import/no-cycle import { COMPONENTS, COMPONENTS_EXTRA } from '@/components/Remark/constants'; import type { Decklists } from '@/tools/decklists/types'; -import type { Markdown, Partials } from '@/tools/markdown/types'; +import type { Markdown } from '@/tools/markdown/types'; import { remarkAccordion } from '@/tools/remark/remarkAccordion'; import { remarkBase } from '@/tools/remark/remarkBase'; import { remarkCard } from '@/tools/remark/remarkCard'; @@ -20,15 +20,10 @@ import { remarkRow } from '@/tools/remark/remarkRow'; interface Props { decklists: Decklists; markdown: Markdown; - partials: Partials; } -export const Remark: FunctionComponent = ({ - decklists, - markdown, - partials, -}) => { - const { scries, text } = markdown; +export const Remark: FunctionComponent = ({ decklists, markdown }) => { + const { partials, scries, text } = markdown; /** Vendor plugins to run against the node tree. */ const basePlugins: PluggableList = [ diff --git a/src/components/Remark/renderers/RemarkAccordion.tsx b/src/components/Remark/renderers/RemarkAccordion.tsx index 5250301c..2d144d1c 100644 --- a/src/components/Remark/renderers/RemarkAccordion.tsx +++ b/src/components/Remark/renderers/RemarkAccordion.tsx @@ -13,7 +13,7 @@ import { alpha } from '@mui/material/styles'; // eslint-disable-next-line import/no-cycle import { Remark } from '@/components/Remark/Remark'; import type { Decklists } from '@/tools/decklists/types'; -import type { Markdown, Partials } from '@/tools/markdown/types'; +import type { Markdown } from '@/tools/markdown/types'; // NOTE Because this feature allows Markdown content within itself, it // introduces a circular reference but is controlled as long as it doesn't @@ -24,57 +24,43 @@ import type { Markdown, Partials } from '@/tools/markdown/types'; export interface Props extends ReactMarkdownProps { decklists: Decklists; markdown?: Markdown; - partials: Partials; } export const RemarkAccordion: FunctionComponent = ({ - children, + children: [title = 'Expand', ...content] = [], decklists, markdown, - partials, -}) => { - const [title, ...content] = children; - - if (!title) return null; - - return ( - ({ - ...theme.mixins.barf, - border: 1, - borderColor: 'divider', - borderLeft: 0, - borderRight: 0, - '& + &': { borderTop: 0, mt: '0!important' }, - })} - > - - } - sx={(theme) => theme.mixins.gutters} - > - {title} - - ({ - ...theme.mixins.gutters, - bgcolor: alpha(theme.palette.primary.light, 0.1), - borderTop: 1, - borderTopColor: 'divider', - py: 2, - '& h6:first-of-type': { mt: 0 }, - })} - > - {content} - {markdown && ( - - )} - - - - ); -}; +}) => ( + ({ + ...theme.mixins.barf, + border: 1, + borderColor: 'divider', + borderLeft: 0, + borderRight: 0, + '& + &': { borderTop: 0, mt: '0!important' }, + })} + > + + } + sx={(theme) => theme.mixins.gutters} + > + {title} + + ({ + ...theme.mixins.gutters, + bgcolor: alpha(theme.palette.primary.light, 0.1), + borderTop: 1, + borderTopColor: 'divider', + py: 2, + '& h6:first-of-type': { mt: 0 }, + })} + > + {content} + {markdown && } + + + +); diff --git a/src/pages/[category]/[chapter].tsx b/src/pages/[category]/[chapter].tsx index a557e29b..4894e7fe 100644 --- a/src/pages/[category]/[chapter].tsx +++ b/src/pages/[category]/[chapter].tsx @@ -10,27 +10,15 @@ import type { Decklists } from '@/tools/decklists/types'; import { getChapters } from '@/tools/markdown/getChapters'; import { getMarkdown } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; -import { getPartials } from '@/tools/markdown/getPartials'; -import type { - Document, - Markdown, - Menu, - Partials, -} from '@/tools/markdown/types'; +import type { Document, Markdown, Menu } from '@/tools/markdown/types'; interface Props { decklists: Decklists; markdown: Markdown; menu: Menu; - partials: Partials; } -const ChapterPage: NextPage = ({ - decklists, - markdown, - menu, - partials, -}) => { +const ChapterPage: NextPage = ({ decklists, markdown, menu }) => { const { title } = markdown.matter; if (!title) return null; @@ -42,11 +30,7 @@ const ChapterPage: NextPage = ({ {title} - + @@ -72,12 +56,11 @@ export const getStaticProps: GetStaticProps = async ({ }) => ({ props: { decklists: getDecklists(), - markdown: await getMarkdown( + markdown: await getMarkdown({ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - join('chapters', params!.category, params!.chapter) - ), + path: join('chapters', params!.category, params!.chapter), + }), menu: getMenu(), - partials: await getPartials(), }, }); diff --git a/src/pages/articles/[year]/[month]/[day]/[article].tsx b/src/pages/articles/[year]/[month]/[day]/[article].tsx index c5b396ce..170e14f9 100644 --- a/src/pages/articles/[year]/[month]/[day]/[article].tsx +++ b/src/pages/articles/[year]/[month]/[day]/[article].tsx @@ -9,22 +9,15 @@ import { Remark } from '@/components/Remark/Remark'; import { getDecklists } from '@/tools/decklists/getDecklists'; import type { Decklists } from '@/tools/decklists/types'; import { getArticles } from '@/tools/markdown/getArticles'; -import { getMarkdown } from '@/tools/markdown/getMarkdown'; +import { getMarkdown, getMarkdownPartial } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; -import { getPartials } from '@/tools/markdown/getPartials'; -import type { - Document, - Markdown, - Menu, - Partials, -} from '@/tools/markdown/types'; +import type { Document, Markdown, Menu } from '@/tools/markdown/types'; interface Props { decklists: Decklists; footer: Markdown; markdown: Markdown; menu: Menu; - partials: Partials; } const ArticlePage: NextPage = ({ @@ -32,7 +25,6 @@ const ArticlePage: NextPage = ({ footer, markdown, menu, - partials, }) => { const { matter } = markdown; const { authors, bannerData, title } = matter; @@ -44,15 +36,11 @@ const ArticlePage: NextPage = ({ - + - + @@ -80,9 +68,9 @@ export const getStaticProps: GetStaticProps = async ({ }) => ({ props: { decklists: getDecklists(), - footer: await getMarkdown('partials/article-footer'), - markdown: await getMarkdown( - join( + footer: await getMarkdownPartial('article-footer'), + markdown: await getMarkdown({ + path: join( 'articles', /* eslint-disable @typescript-eslint/no-non-null-assertion */ params!.year, @@ -90,10 +78,9 @@ export const getStaticProps: GetStaticProps = async ({ params!.day, params!.article /* eslint-enable @typescript-eslint/no-non-null-assertion */ - ) - ), + ), + }), menu: getMenu(), - partials: await getPartials(), }, }); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9323e79c..4e6d99bc 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -7,15 +7,9 @@ import { Remark } from '@/components/Remark/Remark'; import { getDecklists } from '@/tools/decklists/getDecklists'; import type { Decklists } from '@/tools/decklists/types'; import { getArticles } from '@/tools/markdown/getArticles'; -import { getMarkdown } from '@/tools/markdown/getMarkdown'; +import { getMarkdownPartial } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; -import { getPartials } from '@/tools/markdown/getPartials'; -import type { - Document, - Markdown, - Menu, - Partials, -} from '@/tools/markdown/types'; +import type { Document, Markdown, Menu } from '@/tools/markdown/types'; const ARTICLES_INITIAL_SIZE = 5; @@ -23,17 +17,10 @@ interface Props { articles: Document[]; decklists: Decklists; menu: Menu; - partials: Partials; welcome: Markdown; } -const HomePage: NextPage = ({ - articles, - decklists, - menu, - partials, - welcome, -}) => { +const HomePage: NextPage = ({ articles, decklists, menu, welcome }) => { const articleRoot = useRef(null); const [size, setSize] = useState(ARTICLES_INITIAL_SIZE); @@ -54,11 +41,7 @@ const HomePage: NextPage = ({ - + @@ -93,8 +76,7 @@ export const getStaticProps: GetStaticProps = async () => ({ articles: await getArticles(), decklists: getDecklists(), menu: getMenu(), - partials: await getPartials(), - welcome: await getMarkdown('partials/welcome'), + welcome: await getMarkdownPartial('welcome'), }, }); diff --git a/src/pages/license.tsx b/src/pages/license.tsx index fafa75a1..e004b6e7 100644 --- a/src/pages/license.tsx +++ b/src/pages/license.tsx @@ -7,42 +7,34 @@ import { Layout } from '@/components/Layout/Layout'; import { Remark } from '@/components/Remark/Remark'; import { getDecklists } from '@/tools/decklists/getDecklists'; import type { Decklists } from '@/tools/decklists/types'; -import { getMarkdown } from '@/tools/markdown/getMarkdown'; +import { getMarkdownPartial } from '@/tools/markdown/getMarkdown'; import { getMenu } from '@/tools/markdown/getMenu'; -import { getPartials } from '@/tools/markdown/getPartials'; -import type { Markdown, Menu, Partials } from '@/tools/markdown/types'; +import type { Markdown, Menu } from '@/tools/markdown/types'; interface Props { decklists: Decklists; markdown: Markdown; menu: Menu; - partials: Partials; } -const LicensePage: NextPage = ({ - decklists, - markdown, - menu, - partials, -}) => ( +const LicensePage: NextPage = ({ decklists, markdown, menu }) => ( License - + ); -export const getStaticProps: GetStaticProps = async () => ({ +export const getStaticProps: GetStaticProps = async () => ({ props: { decklists: getDecklists(), - markdown: await getMarkdown('partials/license'), + markdown: await getMarkdownPartial('license'), menu: getMenu(), - partials: await getPartials(), }, }); diff --git a/src/tools/markdown/getMarkdown.ts b/src/tools/markdown/getMarkdown.ts index f6b52fc1..ea913ff3 100644 --- a/src/tools/markdown/getMarkdown.ts +++ b/src/tools/markdown/getMarkdown.ts @@ -1,3 +1,4 @@ +import type { GrayMatterFile } from 'gray-matter'; import type { Root } from 'mdast'; import { join } from 'path'; import remarkDirective from 'remark-directive'; @@ -5,44 +6,68 @@ import remarkParse from 'remark-parse'; import { unified } from 'unified'; import { readMarkdown } from '@/tools/io/readMarkdown'; import { toDirective } from '@/tools/mana/toDirective'; -import { Markdown } from '@/tools/markdown/types'; import { BASE_MARKDOWN_URL, + BASE_PARTIALS_URL, MARKDOWN_EXTENSION, } from '@/tools/markdown/constants/Files'; import { getBanner } from '@/tools/markdown/getBanner'; -import { remarkScryfall } from '@/tools/remark/remarkScryfall'; +import type { Markdown, Partials } from '@/tools/markdown/types'; +import { remarkPartials } from '@/tools/remark/remarkPartials'; +import { remarkScries } from '@/tools/remark/remarkScries'; import type { Scries } from '@/tools/scryfall/types'; -type GetScries = (buffer: string) => Promise; +/** Parse buffer as Markdown text and return all partials necessary for it. */ +const makePartials = async (tree: Root): Promise => { + const partials = await unified() + // NOTE Provide the getter as a callback to avoid circular imports + .use(remarkPartials, getMarkdownPartial) + .run(tree); + return partials as unknown as Partials; +}; /** Parse buffer as Markdown text and return Scry data from directives. */ -const getScries: GetScries = async (buffer) => { - const tree: Root = unified() - .use(remarkParse) - .use(remarkDirective) - .parse(buffer); - const scries = await unified().use(remarkScryfall).run(tree); +const makeScries = async (tree: Root): Promise => { + const scries = await unified().use(remarkScries).run(tree); return scries as unknown as Scries; }; -type GetMarkdown = (path: string, root?: string) => Promise; +/** Forge a `unified` tree ready to be parsed by remarkers. */ +const makeTree = (buffer: string): Root => + unified().use(remarkParse).use(remarkDirective).parse(buffer); + +type GetMarkdown = (options: { + path: string; + root?: string; +}) => Promise; /** * Read file system and return Markdown matter from the specified path. * Provided path should be relative to `BASE_MARKDOWN_URL` but can be specified. * Augment the result with Scryfall data found in the Markdown content. */ -export const getMarkdown: GetMarkdown = async ( - path, - root = BASE_MARKDOWN_URL -) => { +export const getMarkdown: GetMarkdown = async (options) => { + const { path, root = BASE_MARKDOWN_URL } = options; const absolutePath = join(root, path) + MARKDOWN_EXTENSION; - const { content, data } = readMarkdown(absolutePath); - const scries: Scries = await getScries(content); - const matter = data; - if (matter.banner) { - matter.bannerData = await getBanner(matter.banner); + const markdown: GrayMatterFile = readMarkdown(absolutePath); + const { content, data: matter } = markdown; + const tree: Root = makeTree(content); + try { + const scries: Scries = await makeScries(tree); + const partials: Partials = await makePartials(tree); + if (matter.banner) { + matter.bannerData = await getBanner(matter.banner); + } + return { matter, partials, scries, text: toDirective(content) }; + } catch (error) { + let message = `${error}`; + if (error instanceof Error) message = error.message; + throw new Error(`Failed retrieving markdown "${path}". ${message}`); } - return { matter, scries, text: toDirective(content) }; }; + +type GetMarkdownPartial = (path: string) => Promise; + +/** Read Mardown content under the provided `path`. */ +export const getMarkdownPartial: GetMarkdownPartial = async (path) => + getMarkdown({ path, root: BASE_PARTIALS_URL }); diff --git a/src/tools/markdown/getPartials.ts b/src/tools/markdown/getPartials.ts deleted file mode 100644 index e7c0544d..00000000 --- a/src/tools/markdown/getPartials.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { join } from 'path'; -import { walk } from '@/tools/io/walk'; -import { Markdown, Partials } from '@/tools/markdown/types'; -import { - BASE_PARTIALS_URL, - MARKDOWN_EXTENSION, -} from '@/tools/markdown/constants/Files'; -import { getMarkdown } from '@/tools/markdown/getMarkdown'; - -type GetPartials = () => Promise; - -/** - * Read file system and return all Markdown partials. - * Parse each resource using `getMarkdown`. - */ -export const getPartials: GetPartials = async () => { - const files = Array.from( - walk(BASE_PARTIALS_URL, { extension: MARKDOWN_EXTENSION }) - ); - // NOTE Collect all partial promises - const promises: Record> = files.reduce< - Record> - >((accumulator, crumbs) => { - const path = join(...crumbs); - return { ...accumulator, [path]: getMarkdown(path, BASE_PARTIALS_URL) }; - }, {}); - // NOTE Await promise successes and build the record of partials - await Promise.all(Object.values(promises)); - const partials: Partials = {}; - Object.entries(promises).forEach(async ([key, promise]) => { - partials[key] = await Promise.resolve(promise); - }); - return partials; -}; diff --git a/src/tools/markdown/types.ts b/src/tools/markdown/types.ts index c66c1809..5b8c7499 100644 --- a/src/tools/markdown/types.ts +++ b/src/tools/markdown/types.ts @@ -21,6 +21,7 @@ export interface Document { export interface Markdown { matter: Partial; + partials: Partials; scries: Scries; text: string; } diff --git a/src/tools/remark/remarkAccordion.ts b/src/tools/remark/remarkAccordion.ts index 9d96ea23..e4d00974 100644 --- a/src/tools/remark/remarkAccordion.ts +++ b/src/tools/remark/remarkAccordion.ts @@ -26,8 +26,6 @@ const remarkWithPartial = ( console.error(`[remark] Missing path for accordion at ${l}:${c}`); } else if (!partials[path]) { console.error(`[remark] Missing source file for "${path}" partial`); - } else if (!directive.children.length) { - console.error(`[remark] Missing title for accordion with "${path}"`); } else { // eslint-disable-next-line no-param-reassign directive.data = { diff --git a/src/tools/remark/remarkPartials.ts b/src/tools/remark/remarkPartials.ts new file mode 100644 index 00000000..5d45a933 --- /dev/null +++ b/src/tools/remark/remarkPartials.ts @@ -0,0 +1,41 @@ +import type { Root } from 'mdast'; +import type { LeafDirective } from 'mdast-util-directive'; +import type { Plugin } from 'unified'; +import { Node, Test, visit } from 'unist-util-visit'; +import type { Markdown, Partials } from '@/tools/markdown/types'; + +/** + * Augment targets with content from partials for further reference while + * rendering components. + * The `props` argument is only used to pass down context for nested accordions. + */ +export const remarkPartials: Plugin< + [(path: string) => Promise], + Root, + Partials +> = (getMarkdownPartial) => async (tree: Root) => { + const tests: Test = [{ name: 'accordion', type: 'leafDirective' }]; + const promises: Promise[] = []; + const partials: Partials = {}; + visit(tree, tests, (node) => { + const directive = node as LeafDirective; + const path: string | undefined = directive.attributes?.path; + const { column: c, line: l } = directive.position?.start ?? {}; + if (!path) { + throw new Error(`Missing path for accordion at ${l}:${c}`); + } else { + const promise: Promise = getMarkdownPartial(path).then( + (response) => { + partials[path] = response; + return response; + }, + (error) => { + throw error; + } + ); + promises.push(promise); + } + }); + await Promise.all(promises); + return partials; +}; diff --git a/src/tools/remark/remarkScryfall.ts b/src/tools/remark/remarkScries.ts similarity index 98% rename from src/tools/remark/remarkScryfall.ts rename to src/tools/remark/remarkScries.ts index c5f0f746..34ab03ec 100644 --- a/src/tools/remark/remarkScryfall.ts +++ b/src/tools/remark/remarkScries.ts @@ -11,7 +11,7 @@ import type { Scries, ScryCard, ScryData } from '@/tools/scryfall/types'; * the queries within. * This Unified pluggable returns a record of queries and responses pairs. */ -export const remarkScryfall = +export const remarkScries = () => async (tree: Node): Promise => { /** Unist tests to only visit nodes that contain Scryfall queries. */ diff --git a/src/tools/scryfall/types.ts b/src/tools/scryfall/types.ts index 475b9c35..7d7984d3 100644 --- a/src/tools/scryfall/types.ts +++ b/src/tools/scryfall/types.ts @@ -1,7 +1,6 @@ export enum ScryObject { CARD = 'card', CARD_FACE = 'card_face', - ERROR = 'error', LIST = 'list', } @@ -48,19 +47,6 @@ export interface ScryDataList { warnings: string[] | null; } -/** - * Scryfall API response in case of error. - * See https://scryfall.com/docs/api/errors - */ -export interface ScryError { - code: string; - details: string; - object: ScryObject.ERROR; - status: number; - type: string | null; - warnings: string[] | null; -} - /** Sanitized Scryfall data for a single card. */ export interface ScryCard { artist: string; diff --git a/yarn.lock b/yarn.lock index de8d9782..b479cb9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1015,6 +1015,16 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== +"@ts-morph/common@~0.12.3": + version "0.12.3" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.12.3.tgz#a96e250217cd30e480ab22ec6a0ebbe65fd784ff" + integrity sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w== + dependencies: + fast-glob "^3.2.7" + minimatch "^3.0.4" + mkdirp "^1.0.4" + path-browserify "^1.0.1" + "@types/aria-query@^5.0.1": version "5.0.1" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.1.tgz#3286741fb8f1e1580ac28784add4c7a1d49bdfbc" @@ -1917,6 +1927,11 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== +code-block-writer@^11.0.0: + version "11.0.3" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-11.0.3.tgz#9eec2993edfb79bfae845fbc093758c0a0b73b76" + integrity sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw== + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" @@ -1968,6 +1983,11 @@ comma-separated-tokens@^2.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + commander@^9.4.1: version "9.5.0" resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" @@ -2023,7 +2043,7 @@ core-js-pure@^3.25.1: resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.27.1.tgz#ede4a6b8440585c7190062757069c01d37a19dca" integrity sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw== -cosmiconfig@^7.0.0: +cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== @@ -2734,7 +2754,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.11, fast-glob@^3.2.9: +fast-glob@^3.2.11, fast-glob@^3.2.7, fast-glob@^3.2.9: version "3.2.12" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -4099,7 +4119,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.2.2: +json5@^2.1.3, json5@^2.2.2: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -4879,6 +4899,11 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mri@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" @@ -5255,6 +5280,11 @@ parse5@^7.0.0, parse5@^7.1.1: dependencies: entities "^4.4.0" +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -6183,6 +6213,31 @@ trough@^2.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== +"true-myth@^4.1.0": + version "4.1.1" + resolved "https://registry.yarnpkg.com/true-myth/-/true-myth-4.1.1.tgz#ff4ac9d5130276e34aa338757e2416ec19248ba2" + integrity sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg== + +ts-morph@^13.0.1: + version "13.0.3" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-13.0.3.tgz#c0c51d1273ae2edb46d76f65161eb9d763444c1d" + integrity sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw== + dependencies: + "@ts-morph/common" "~0.12.3" + code-block-writer "^11.0.0" + +ts-prune@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/ts-prune/-/ts-prune-0.10.3.tgz#b6c71a525543b38dcf947a7d3adfb7f9e8b91f38" + integrity sha512-iS47YTbdIcvN8Nh/1BFyziyUqmjXz7GVzWu02RaZXqb+e/3Qe1B7IQ4860krOeCGUeJmterAlaM2FRH0Ue0hjw== + dependencies: + commander "^6.2.1" + cosmiconfig "^7.0.1" + json5 "^2.1.3" + lodash "^4.17.21" + "true-myth" "^4.1.0" + ts-morph "^13.0.1" + tsconfig-paths@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a"