diff --git a/.eslintrc.js b/.eslintrc.js index 09b84c5b2..24cb7406f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,7 +5,9 @@ module.exports = { 'prettier', 'plugin:import/recommended', 'plugin:import/typescript', - 'plugin:@typescript-eslint/recommended' + 'plugin:@typescript-eslint/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended' ], rules: { // We use winston's logging instead @@ -19,5 +21,10 @@ module.exports = { '@typescript-eslint/no-var-requires': 'off' } } - ] + ], + settings: { + react: { + version: 'detect' + } + } } diff --git a/core/cli/src/config.ts b/core/cli/src/config.ts index 327d414ef..55ebdf529 100644 --- a/core/cli/src/config.ts +++ b/core/cli/src/config.ts @@ -200,6 +200,7 @@ export async function loadConfig(logger: Logger, { validate = true } = {}): Prom if (validate) { validateConfig(validPluginConfig) + return validPluginConfig } return config diff --git a/core/tool-box/bin/run b/core/tool-box/bin/run new file mode 100755 index 000000000..671b7e56b --- /dev/null +++ b/core/tool-box/bin/run @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +const { main } = require('../lib/index.js') + +main() diff --git a/core/tool-box/package.json b/core/tool-box/package.json new file mode 100644 index 000000000..126852291 --- /dev/null +++ b/core/tool-box/package.json @@ -0,0 +1,40 @@ +{ + "name": "@dotcom-tool-kit/tool-box", + "version": "0.0.0-development", + "description": "", + "main": "lib", + "bin": { + "dotcom-tool-kit": "./bin/run" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "FT.com Platforms Team ", + "license": "ISC", + "dependencies": { + "@dotcom-tool-kit/logger": "^2.1.2", + "dotcom-tool-kit": "^2.4.0", + "ink": "^3.2.0", + "react": "^17.0.2", + "winston": "^3.6.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/financial-times/dotcom-tool-kit.git", + "directory": "core/box" + }, + "bugs": "https://github.com/financial-times/dotcom-tool-kit/issues", + "homepage": "https://github.com/financial-times/dotcom-tool-kit/tree/main/core/box", + "files": [ + "/lib", + ".toolkitrc.yml" + ], + "volta": { + "extends": "../../package.json" + }, + "devDependencies": { + "@dotcom-tool-kit/types": "^2.7.0", + "@types/react": "^17.0.52" + } +} diff --git a/core/tool-box/src/components/DetailsBox.tsx b/core/tool-box/src/components/DetailsBox.tsx new file mode 100644 index 000000000..6e679bd5d --- /dev/null +++ b/core/tool-box/src/components/DetailsBox.tsx @@ -0,0 +1,8 @@ +import React from 'react' +import { SelectableBox, SelectableBoxProps } from './SelectableBox' + +export const DetailsBox = (props: React.PropsWithChildren): JSX.Element => ( + + {props.children} + +) diff --git a/core/tool-box/src/components/List.tsx b/core/tool-box/src/components/List.tsx new file mode 100644 index 000000000..ae35aa95f --- /dev/null +++ b/core/tool-box/src/components/List.tsx @@ -0,0 +1,19 @@ +import { Box, Text } from 'ink' +import React from 'react' +import { SelectableBox } from './SelectableBox' + +export interface ListProps { + items: string[] + selected: boolean + cursor: number +} + +export const List = (props: ListProps): JSX.Element => ( + + {props.items.map((item, index) => ( + + {item} + + ))} + +) diff --git a/core/tool-box/src/components/SelectableBox.tsx b/core/tool-box/src/components/SelectableBox.tsx new file mode 100644 index 000000000..d76146cb0 --- /dev/null +++ b/core/tool-box/src/components/SelectableBox.tsx @@ -0,0 +1,15 @@ +import { Box, BoxProps } from 'ink' +import React from 'react' + +export interface SelectableBoxProps extends BoxProps { + selected: boolean +} + +export const SelectableBox = (props: React.PropsWithChildren): JSX.Element => { + const { selected, children, ...rest } = props + return ( + + {children} + + ) +} diff --git a/core/tool-box/src/components/TabbedView.tsx b/core/tool-box/src/components/TabbedView.tsx new file mode 100644 index 000000000..a79ba22ac --- /dev/null +++ b/core/tool-box/src/components/TabbedView.tsx @@ -0,0 +1,111 @@ +import type { ValidConfig } from 'dotcom-tool-kit/lib/config' +import { Box, Text, useInput } from 'ink' +import React, { useState } from 'react' +import { HooksPage } from './pages/Hooks' +import { PluginsPage } from './pages/Plugins' +import { TabName, TabPages } from './pages/shared' +import { TasksPage } from './pages/Tasks' + +// Our styling uses ansi-colors, whereas ink uses chalk, and there's no nice +// way to convert between the two, so lets just copy the appropriate colours +// as strings. +const tabColours = { plugins: 'cyan', hooks: 'magenta', tasks: 'blueBright' } + +interface TabbedViewProps { + config: ValidConfig +} + +export const TabbedView = (props: TabbedViewProps): JSX.Element => { + const [activeTab, setActiveTab] = useState(0) + const [pluginsStart, setPluginsStart] = useState() + const [hooksStart, setHooksStart] = useState() + const [tasksStart, setTasksStart] = useState() + const pluginsWithHook: Record = {} + const pluginsWithTask: Record = {} + for (const [pluginId, plugin] of Object.entries(props.config.plugins)) { + for (const hookId of Object.keys(plugin.module?.hooks ?? {})) { + pluginsWithHook[hookId] ??= [] + pluginsWithHook[hookId].push(pluginId) + } + for (const taskId of Object.keys(plugin.module?.tasks ?? {})) { + pluginsWithTask[taskId] ??= [] + pluginsWithTask[taskId].push(pluginId) + } + } + const tasksWithHook = Object.entries(props.config.hookTasks).map( + ([hookId, hookTask]) => [hookId, hookTask.tasks] as const + ) + const hooksWithTask: Record = {} + for (const [hookId, tasks] of tasksWithHook) { + for (const task of tasks) { + hooksWithTask[task] ??= [] + hooksWithTask[task].push(hookId) + } + } + + const handleTabChange = (newTab: TabName, itemId?: string) => { + setActiveTab(TabPages.indexOf(newTab)) + if (itemId) { + switch (newTab) { + case 'plugins': + setPluginsStart(itemId) + break + case 'hooks': + setHooksStart(itemId) + break + case 'tasks': + setTasksStart(itemId) + break + } + } + } + useInput((_, key) => { + if (key.tab) { + if (key.shift) { + const prevTab = activeTab - 1 + setActiveTab(prevTab < 0 ? TabPages.length - 1 : prevTab) + } else { + setActiveTab((activeTab + 1) % TabPages.length) + } + } + }) + return ( + <> + + {TabPages.map((page, index) => ( + + {index !== 0 && | } + {page} + + ))} + + + {TabPages[activeTab] === 'plugins' && ( + + )} + {TabPages[activeTab] === 'hooks' && ( + + )} + {TabPages[activeTab] === 'tasks' && ( + + )} + + + ) +} diff --git a/core/tool-box/src/components/pages/Hooks.tsx b/core/tool-box/src/components/pages/Hooks.tsx new file mode 100644 index 000000000..ba5c2d9ab --- /dev/null +++ b/core/tool-box/src/components/pages/Hooks.tsx @@ -0,0 +1,109 @@ +import { styles } from '@dotcom-tool-kit/logger' +import type { Hook, HookClass } from '@dotcom-tool-kit/types' +import { Box, Text } from 'ink' +import React, { useCallback } from 'react' +import { DetailsBox } from '../DetailsBox' +import { List } from '../List' +import { TabPageProps, ToolEssentials, useNavigation } from './shared' + +interface HookDetailsProps extends ToolEssentials { + hook: Hook + taskIds: string[] + pluginIds: string[] +} + +const HookDetails = (props: HookDetailsProps) => { + return ( + + {(props.hook.constructor as HookClass).description} + {props.hook.plugin && ( + + Defined in the{' '} + {styles.plugin(props.hook.plugin.id)}{' '} + plugin + + )} + {props.taskIds.length > 0 && ( + <> + Calls the following tasks: + {props.taskIds.map((taskId, index) => ( + + - {styles.plugin(taskId)} + + ))} + + )} + {props.pluginIds.length > 0 && ( + <> + Appears in the following plugins: + {props.pluginIds.map((pluginId, index) => ( + + -{' '} + + {styles.plugin(pluginId)} + + + ))} + + )} + + ) +} + +export interface HooksPageProps extends TabPageProps { + hooks: [string, Hook][] + taskMap: Record + pluginMap: Record +} + +export const HooksPage = (props: HooksPageProps): JSX.Element => { + const { listCursor, detailsCursor, detailsSelected } = useNavigation({ + listLength: props.hooks.length, + getDetailsLength(cursor) { + const [hookId, hook] = props.hooks[cursor] + return ( + (hook.plugin ? 1 : 0) + (props.taskMap[hookId]?.length ?? 0) + (props.pluginMap[hookId]?.length ?? 0) + ) + }, + getSelectedItem(listCursor, detailsCursor) { + const [hookId, hook] = props.hooks[listCursor] + if (detailsCursor === 0 && hook.plugin) { + return ['plugins', hook.plugin.id] + } else if (detailsCursor <= props.taskMap[hookId]?.length ?? 0) { + return ['tasks', props.taskMap[hookId][detailsCursor - (hook.plugin ? 1 : 0)]] + } else { + return [ + 'plugins', + props.pluginMap[hookId][ + detailsCursor - (props.taskMap[hookId]?.length ?? 0) - (hook.plugin ? 1 : 0) + ] + ] + } + }, + findItem: useCallback( + (itemId) => { + return props.hooks.findIndex(([hookId]) => hookId === itemId) + }, + [props.hooks] + ), + startingItem: props.startingItem, + changeTab: props.onTabChange + }) + const [hookId, selectedHook] = props.hooks[listCursor] + return ( + + styles.hook(id))} + selected={!detailsSelected} + cursor={listCursor} + /> + + + ) +} diff --git a/core/tool-box/src/components/pages/Plugins.tsx b/core/tool-box/src/components/pages/Plugins.tsx new file mode 100644 index 000000000..8afc78310 --- /dev/null +++ b/core/tool-box/src/components/pages/Plugins.tsx @@ -0,0 +1,99 @@ +import { styles } from '@dotcom-tool-kit/logger' +import type { Plugin } from '@dotcom-tool-kit/types' +import { Box, Text } from 'ink' +import React, { useCallback } from 'react' +import { DetailsBox } from '../DetailsBox' +import { List } from '../List' +import { TabPageProps, ToolEssentials, useNavigation } from './shared' + +interface PluginDetailsProps extends ToolEssentials { + parent?: Plugin + hookIds: string[] + taskIds: string[] +} + +const PluginDetails = (props: PluginDetailsProps) => ( + + + Included by{' '} + + {styles.plugin(props.parent?.id ?? 'no parent')} + + + {props.hookIds.length > 0 && ( + <> + Defines the following hooks: + {props.hookIds.map((hookId, index) => ( + + - {styles.hook(hookId)} + + ))} + + )} + {props.taskIds.length > 0 && ( + <> + Defines the following tasks: + {props.taskIds.map((taskId, index) => ( + + -{' '} + + {styles.task(taskId)} + + + ))} + + )} + +) + +interface PluginsPageProps extends TabPageProps { + plugins: [string, Plugin][] +} + +export const PluginsPage = (props: PluginsPageProps): JSX.Element => { + const { listCursor, detailsCursor, detailsSelected } = useNavigation({ + listLength: props.plugins.length, + getDetailsLength(cursor) { + const [, plugin] = props.plugins[cursor] + return 1 + Object.keys(plugin.module?.hooks ?? {}).length + (plugin.module?.tasks?.length ?? 0) + }, + getSelectedItem(listCursor, detailsCursor) { + const [, plugin] = props.plugins[listCursor] + const hookLength = Object.keys(plugin.module?.hooks ?? {}).length + if (detailsCursor === 0) { + return ['plugins', plugin.parent?.id ?? plugin.id] + } else if (detailsCursor <= hookLength) { + return ['hooks', Object.keys(plugin.module?.hooks ?? {})[detailsCursor - 1]] + } else { + return ['tasks', (plugin.module?.tasks ?? [])[detailsCursor - 1 - hookLength].id] + } + }, + findItem: useCallback( + (itemId) => { + return props.plugins.findIndex(([pluginId]) => pluginId === itemId) + }, + [props.plugins] + ), + startingItem: props.startingItem, + changeTab: props.onTabChange + }) + const [, selectedPlugin] = props.plugins[listCursor] + return ( + + styles.plugin(id))} + selected={!detailsSelected} + cursor={listCursor} + /> + task.id).filter((id): id is string => !!id) ?? [] + } + selected={detailsSelected} + cursor={detailsCursor} + /> + + ) +} diff --git a/core/tool-box/src/components/pages/Tasks.tsx b/core/tool-box/src/components/pages/Tasks.tsx new file mode 100644 index 000000000..616e1782e --- /dev/null +++ b/core/tool-box/src/components/pages/Tasks.tsx @@ -0,0 +1,106 @@ +import { styles } from '@dotcom-tool-kit/logger' +import type { TaskClass } from '@dotcom-tool-kit/types' +import { Box, Text } from 'ink' +import React, { useCallback } from 'react' +import { DetailsBox } from '../DetailsBox' +import { List } from '../List' +import { TabPageProps, ToolEssentials, useNavigation } from './shared' + +interface TaskDetailsProps extends ToolEssentials { + task: TaskClass + pluginIds: string[] + hookIds: string[] +} + +const TaskDetails = (props: TaskDetailsProps) => { + return ( + + {props.task.description} + {props.task.plugin && ( + + Defined in the{' '} + {styles.plugin(props.task.plugin.id)}{' '} + plugin + + )} + {props.pluginIds.length > 0 && ( + <> + Appears in the following plugins: + {props.pluginIds.map((pluginId, index) => ( + + - {styles.plugin(pluginId)} + + ))} + + )} + {props.hookIds.length > 0 && ( + <> + Is called by the following hooks: + {props.hookIds.map((hookId, index) => ( + + - {styles.hook(hookId)} + + ))} + + )} + + ) +} + +export interface TasksPageProps extends TabPageProps { + tasks: [string, TaskClass][] + pluginMap: Record + hookMap: Record +} + +export const TasksPage = (props: TasksPageProps): JSX.Element => { + const { listCursor, detailsCursor, detailsSelected } = useNavigation({ + listLength: props.tasks.length, + getDetailsLength(cursor) { + const [taskId, task] = props.tasks[cursor] + return ( + (task.plugin ? 1 : 0) + (props.pluginMap[taskId]?.length ?? 0) + (props.hookMap[taskId]?.length ?? 0) + ) + }, + getSelectedItem(listCursor, detailsCursor) { + const [taskId, task] = props.tasks[listCursor] + if (detailsCursor === 0 && task.plugin) { + return ['plugins', task.plugin.id] + } else if (detailsCursor <= props.hookMap[taskId]?.length ?? 0) { + return ['hooks', props.hookMap[taskId][detailsCursor - (task.plugin ? 1 : 0)]] + } else { + return [ + 'plugins', + props.pluginMap[taskId][ + detailsCursor - (props.hookMap[taskId]?.length ?? 0) - (task.plugin ? 1 : 0) + ] + ] + } + }, + findItem: useCallback( + (itemId) => { + return props.tasks.findIndex(([taskId]) => taskId === itemId) + }, + [props.tasks] + ), + startingItem: props.startingItem, + changeTab: props.onTabChange + }) + const [taskId, selectedTask] = props.tasks[listCursor] + return ( + + styles.task(id))} + selected={!detailsSelected} + cursor={listCursor} + /> + + + ) +} diff --git a/core/tool-box/src/components/pages/shared.tsx b/core/tool-box/src/components/pages/shared.tsx new file mode 100644 index 000000000..17ed42485 --- /dev/null +++ b/core/tool-box/src/components/pages/shared.tsx @@ -0,0 +1,88 @@ +import { useApp, useInput } from 'ink' +import { useEffect, useState } from 'react' + +export interface ToolEssentials { + selected: boolean + cursor: number +} + +export const TabPages = ['plugins', 'hooks', 'tasks'] as const +export type TabName = typeof TabPages[number] + +export interface TabPageProps { + startingItem?: string + onTabChange: (newTab: TabName, itemId: string | undefined) => void +} + +interface NavigationArgs { + listLength: number + getDetailsLength: (listCursor: number) => number + getSelectedItem: (listCursor: number, detailsCursor: number) => [TabName, string | undefined] + findItem: (itemId: string) => number + startingItem?: string + changeTab: (newTab: TabName, itemId: string | undefined) => void +} + +interface NavigationState { + listCursor: number + detailsCursor: number + detailsSelected: boolean +} + +export const useNavigation = ({ + listLength, + getDetailsLength, + getSelectedItem, + findItem, + startingItem, + changeTab +}: NavigationArgs): NavigationState => { + const { exit } = useApp() + const [listCursor, setListCursor] = useState(0) + const [detailsCursor, setDetailsCursor] = useState(0) + const [detailsSelected, setDetailsSelected] = useState(false) + + const maxListCursor = listLength - 1 + const maxDetailsCursor = getDetailsLength(listCursor) - 1 + + useEffect(() => { + if (startingItem) { + setListCursor(findItem(startingItem)) + } + }, [startingItem, findItem]) + + useInput((input, key) => { + if (key.downArrow || input === 'j') { + if (detailsSelected) { + setDetailsCursor(detailsCursor !== maxDetailsCursor ? detailsCursor + 1 : 0) + } else { + setListCursor(listCursor !== maxListCursor ? listCursor + 1 : 0) + setDetailsCursor(0) + } + } + if (key.upArrow || input === 'k') { + if (detailsSelected) { + setDetailsCursor(detailsCursor !== 0 ? detailsCursor - 1 : maxDetailsCursor) + } else { + setListCursor(listCursor !== 0 ? listCursor - 1 : maxListCursor) + setDetailsCursor(0) + } + } + if (key.return || key.rightArrow || input === 'l') { + if (detailsSelected) { + const [newTab, itemId] = getSelectedItem(listCursor, detailsCursor) + changeTab(newTab, itemId) + } else { + setDetailsSelected(true) + } + } + if (detailsSelected && (key.escape || key.leftArrow || input === 'h')) { + setDetailsSelected(false) + } + if (input === 'q') { + exit() + } + }) + + return { listCursor, detailsCursor, detailsSelected } +} diff --git a/core/tool-box/src/index.tsx b/core/tool-box/src/index.tsx new file mode 100644 index 000000000..4e4aa760b --- /dev/null +++ b/core/tool-box/src/index.tsx @@ -0,0 +1,16 @@ +import { loadConfig } from 'dotcom-tool-kit/lib/config' +import { render } from 'ink' +import React from 'react' +import winston from 'winston' +import { TabbedView } from './components/TabbedView' + +export async function main(): Promise { + const logger = winston.createLogger({ silent: true }) + const config = await loadConfig(logger) + + render( + + + + ) +} diff --git a/core/tool-box/tsconfig.json b/core/tool-box/tsconfig.json new file mode 100644 index 000000000..748508250 --- /dev/null +++ b/core/tool-box/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.settings.json", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src", + "jsx": "react" + }, + "references": [{ "path": "../cli" }, { "path": "../../lib/logger" }, { "path": "../../lib/types" }] +} diff --git a/package-lock.json b/package-lock.json index da4aac3ac..43e26605e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,8 @@ "eslint": "^7.20.0", "eslint-config-prettier": "^8.0.0", "eslint-plugin-import": "^2.22.1", + "eslint-plugin-react": "^7.30.1", + "eslint-plugin-react-hooks": "^4.6.0", "husky": "^4.3.8", "jest": "^27.4.7", "lint-staged": "^10.5.4", @@ -43,15 +45,35 @@ "npm": "7.x || 8.x" } }, + "core/box": { + "name": "@dotcom-tool-kit/box", + "version": "0.0.0-development", + "extraneous": true, + "license": "ISC", + "dependencies": { + "@dotcom-tool-kit/logger": "^2.1.2", + "dotcom-tool-kit": "^2.4.0", + "ink": "^3.2.0", + "react": "^17.0.2", + "winston": "^3.6.0" + }, + "bin": { + "dotcom-tool-kit": "bin/run" + }, + "devDependencies": { + "@dotcom-tool-kit/types": "^2.7.0", + "@types/react": "^17.0.52" + } + }, "core/cli": { "name": "dotcom-tool-kit", - "version": "2.3.6", + "version": "2.4.0", "license": "MIT", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/options": "^2.0.9", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/options": "^2.0.10", + "@dotcom-tool-kit/types": "^2.7.0", "@dotcom-tool-kit/wait-for-ok": "^2.0.1", "cosmiconfig": "^7.0.0", "lodash.groupby": "^4.6.0", @@ -65,17 +87,17 @@ "dotcom-tool-kit": "bin/run" }, "devDependencies": { - "@dotcom-tool-kit/babel": "^2.0.9", - "@dotcom-tool-kit/backend-app": "^2.0.12", - "@dotcom-tool-kit/circleci": "^2.1.7", - "@dotcom-tool-kit/circleci-heroku": "^2.0.12", - "@dotcom-tool-kit/eslint": "^2.2.2", - "@dotcom-tool-kit/frontend-app": "^2.1.10", - "@dotcom-tool-kit/heroku": "^2.1.0", - "@dotcom-tool-kit/mocha": "^2.1.6", - "@dotcom-tool-kit/n-test": "^2.1.4", - "@dotcom-tool-kit/npm": "^2.0.10", - "@dotcom-tool-kit/webpack": "^2.1.8", + "@dotcom-tool-kit/babel": "^2.0.10", + "@dotcom-tool-kit/backend-app": "^2.0.13", + "@dotcom-tool-kit/circleci": "^3.0.0", + "@dotcom-tool-kit/circleci-heroku": "^2.1.0", + "@dotcom-tool-kit/eslint": "^2.2.3", + "@dotcom-tool-kit/frontend-app": "^2.1.11", + "@dotcom-tool-kit/heroku": "^2.1.1", + "@dotcom-tool-kit/mocha": "^2.1.7", + "@dotcom-tool-kit/n-test": "^2.1.5", + "@dotcom-tool-kit/npm": "^2.0.11", + "@dotcom-tool-kit/webpack": "^2.1.9", "@jest/globals": "^27.4.6", "@types/lodash.groupby": "^4.6.7", "@types/lodash.merge": "^4.6.6", @@ -114,12 +136,12 @@ }, "core/create": { "name": "@dotcom-tool-kit/create", - "version": "2.3.1", + "version": "2.3.2", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@financial-times/package-json": "^3.0.0", "@quarterto/parse-makefile-rules": "^1.1.0", "import-cwd": "^3.0.0", @@ -142,7 +164,7 @@ "@types/pacote": "^11.1.3", "@types/prompts": "^2.0.14", "cosmiconfig": "^7.0.1", - "dotcom-tool-kit": "^2.3.6" + "dotcom-tool-kit": "^2.4.0" } }, "core/create/node_modules/tslib": { @@ -155,11 +177,11 @@ "license": "ISC", "devDependencies": { "@dotcom-tool-kit/circleci-heroku": "^2.0.0", - "@dotcom-tool-kit/circleci-npm": "^2.0.0", + "@dotcom-tool-kit/circleci-npm": "^3.0.0", "@dotcom-tool-kit/eslint": "^2.0.0", "@dotcom-tool-kit/frontend-app": "^2.0.0", "@dotcom-tool-kit/jest": "^2.0.0", - "@dotcom-tool-kit/lint-staged": "^2.0.0", + "@dotcom-tool-kit/lint-staged": "^3.0.0", "@dotcom-tool-kit/lint-staged-npm": "^2.0.0", "@dotcom-tool-kit/mocha": "^2.0.0", "@dotcom-tool-kit/n-test": "^2.0.0", @@ -174,6 +196,24 @@ "nodemon": "^2.0.15" } }, + "core/tool-box": { + "version": "0.0.0-development", + "license": "ISC", + "dependencies": { + "@dotcom-tool-kit/logger": "^2.1.2", + "dotcom-tool-kit": "^2.4.0", + "ink": "^3.2.0", + "react": "^17.0.2", + "winston": "^3.6.0" + }, + "bin": { + "dotcom-tool-kit": "bin/run" + }, + "devDependencies": { + "@dotcom-tool-kit/types": "^2.7.0", + "@types/react": "^17.0.52" + } + }, "lib/error": { "name": "@dotcom-tool-kit/error", "version": "2.0.1", @@ -211,10 +251,10 @@ }, "lib/options": { "name": "@dotcom-tool-kit/options", - "version": "2.0.9", + "version": "2.0.10", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" } }, @@ -225,7 +265,7 @@ }, "lib/package-json-hook": { "name": "@dotcom-tool-kit/package-json-hook", - "version": "2.1.1", + "version": "3.0.0", "license": "ISC", "dependencies": { "@financial-times/package-json": "^3.0.0", @@ -258,7 +298,7 @@ }, "lib/types": { "name": "@dotcom-tool-kit/types", - "version": "2.6.2", + "version": "2.7.0", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.0", @@ -280,12 +320,12 @@ }, "lib/vault": { "name": "@dotcom-tool-kit/vault", - "version": "2.0.9", + "version": "2.0.10", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", - "@dotcom-tool-kit/options": "^2.0.9", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/options": "^2.0.10", + "@dotcom-tool-kit/types": "^2.7.0", "@financial-times/n-fetch": "^1.0.0-beta.7", "fs": "0.0.1-security", "os": "^0.1.2", @@ -2340,6 +2380,10 @@ "resolved": "lib/state", "link": true }, + "node_modules/@dotcom-tool-kit/tool-box": { + "resolved": "core/tool-box", + "link": true + }, "node_modules/@dotcom-tool-kit/types": { "resolved": "lib/types", "link": true @@ -4194,6 +4238,12 @@ "@types/node": "*" } }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "devOptional": true + }, "node_modules/@types/puppeteer": { "version": "3.0.8", "dev": true, @@ -4202,6 +4252,17 @@ "@types/node": "*" } }, + "node_modules/@types/react": { + "version": "17.0.52", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", + "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, "node_modules/@types/request": { "version": "2.48.8", "license": "MIT", @@ -4228,6 +4289,12 @@ "version": "0.12.0", "license": "MIT" }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "devOptional": true + }, "node_modules/@types/semver": { "version": "7.3.9", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", @@ -4297,6 +4364,11 @@ "@types/node": "*" } }, + "node_modules/@types/yoga-layout": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", + "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "4.33.0", "dev": true, @@ -5040,6 +5112,24 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.map": { "version": "1.0.4", "license": "MIT", @@ -5180,6 +5270,17 @@ "node": ">= 4.5.0" } }, + "node_modules/auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/aws-sdk": { "version": "2.1128.0", "license": "Apache-2.0", @@ -6367,6 +6468,17 @@ "node": ">= 0.12.0" } }, + "node_modules/code-excerpt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "dependencies": { + "convert-to-spaces": "^1.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/code-point-at": { "version": "1.1.0", "dev": true, @@ -6747,6 +6859,14 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha512-cj09EBuObp9gZNQCzc7hByQyrs6jVGE+o9kSJmeUoj+GiPiJvi5LYqEH/Hmme4+MTLHM+Ejtq+FChpjjEnsPdQ==", + "engines": { + "node": ">= 4" + } + }, "node_modules/cookie": { "version": "0.3.1", "license": "MIT", @@ -7098,6 +7218,12 @@ "version": "0.3.8", "license": "MIT" }, + "node_modules/csstype": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", + "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", + "devOptional": true + }, "node_modules/cwise-compiler": { "version": "1.1.3", "license": "MIT", @@ -8138,6 +8264,93 @@ "node": ">=4.0.0" } }, + "node_modules/eslint-plugin-react": { + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.30.1.tgz", + "integrity": "sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.5", + "object.fromentries": "^2.0.5", + "object.hasown": "^1.1.1", + "object.values": "^1.1.5", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "dev": true, @@ -9185,7 +9398,6 @@ "node_modules/functions-have-names": { "version": "1.2.3", "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10207,6 +10419,72 @@ "version": "1.3.8", "license": "ISC" }, + "node_modules/ink": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-3.2.0.tgz", + "integrity": "sha512-firNp1q3xxTzoItj/eOOSZQnYSlyrWks5llCTVX37nJ59K3eXbQ8PtzCguqo8YI19EELo5QxaKnJd4VxzhU8tg==", + "dependencies": { + "ansi-escapes": "^4.2.1", + "auto-bind": "4.0.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "indent-string": "^4.0.0", + "is-ci": "^2.0.0", + "lodash": "^4.17.20", + "patch-console": "^1.0.0", + "react-devtools-core": "^4.19.1", + "react-reconciler": "^0.26.2", + "scheduler": "^0.20.2", + "signal-exit": "^3.0.2", + "slice-ansi": "^3.0.0", + "stack-utils": "^2.0.2", + "string-width": "^4.2.2", + "type-fest": "^0.12.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0", + "ws": "^7.5.5", + "yoga-layout-prebuilt": "^1.9.6" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": ">=16.8.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/ink/node_modules/type-fest": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", + "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ink/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/inquirer": { "version": "7.3.3", "license": "MIT", @@ -11732,6 +12010,19 @@ "node": ">=0.6.0" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.2.tgz", + "integrity": "sha512-4ZCADZHRkno244xlNnn4AOG6sRQ7iBZ5BbgZ4vW4y5IZw7cVUD1PPeblm1xx/nfmMxPdt/LHsXZW8z/j58+l9Q==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.2" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/keyv": { "version": "3.1.0", "license": "MIT", @@ -12353,6 +12644,17 @@ "version": "0.8.4", "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/loupe": { "version": "2.3.4", "dev": true, @@ -14133,6 +14435,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/object.pick": { "version": "1.3.0", "license": "MIT", @@ -15207,6 +15553,14 @@ "node": ">=0.10.0" } }, + "node_modules/patch-console": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-1.0.0.tgz", + "integrity": "sha512-nxl9nrnLQmh64iTzMfyylSlRozL7kAXIaxw1fVcLYdyhNkJCRUzirRZTikXGJsg+hc4fqpneTK6iU2H1Q8THSA==", + "engines": { + "node": ">=10" + } + }, "node_modules/path": { "version": "0.12.7", "license": "MIT", @@ -15489,6 +15843,23 @@ "node": ">= 6" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/protocolify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/protocolify/-/protocolify-3.0.0.tgz", @@ -15764,10 +16135,47 @@ "node": ">=0.10.0" } }, + "node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-devtools-core": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.25.0.tgz", + "integrity": "sha512-iewRrnu0ZnmfL+jJayKphXj04CFh6i3ezVnpCtcnZbTPSQgN09XqHAzXbKbqNDl7aTg9QLNkQRP6M3DvdrinWA==", + "dependencies": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, "node_modules/react-is": { "version": "17.0.2", "license": "MIT" }, + "node_modules/react-reconciler": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz", + "integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^17.0.2" + } + }, "node_modules/read-package-json": { "version": "5.0.1", "license": "ISC", @@ -16090,6 +16498,23 @@ "node": ">=0.10.0" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpp": { "version": "3.2.0", "dev": true, @@ -16566,6 +16991,15 @@ "node": ">= 0.10.0" } }, + "node_modules/scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "node_modules/schema-utils": { "version": "1.0.0", "license": "MIT", @@ -16740,6 +17174,11 @@ "node": ">=0.10.0" } }, + "node_modules/shell-quote": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" + }, "node_modules/side-channel": { "version": "1.0.4", "license": "MIT", @@ -17340,6 +17779,25 @@ "node": ">=8" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { "version": "1.0.5", "license": "MIT", @@ -19926,6 +20384,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoga-layout-prebuilt": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", + "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", + "dependencies": { + "@types/yoga-layout": "1.9.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/zip-stream": { "version": "2.1.3", "license": "MIT", @@ -19940,12 +20409,12 @@ }, "plugins/babel": { "name": "@dotcom-tool-kit/babel", - "version": "2.0.9", + "version": "2.0.10", "license": "MIT", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "fast-glob": "^3.2.11", "tslib": "^2.3.1" }, @@ -19966,12 +20435,12 @@ }, "plugins/backend-app": { "name": "@dotcom-tool-kit/backend-app", - "version": "2.0.12", + "version": "2.0.13", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/circleci-heroku": "^2.0.12", - "@dotcom-tool-kit/node": "^2.2.2", - "@dotcom-tool-kit/npm": "^2.0.10" + "@dotcom-tool-kit/circleci-heroku": "^2.1.0", + "@dotcom-tool-kit/node": "^2.2.3", + "@dotcom-tool-kit/npm": "^2.0.11" }, "peerDependencies": { "dotcom-tool-kit": "2.x" @@ -19979,13 +20448,13 @@ }, "plugins/circleci": { "name": "@dotcom-tool-kit/circleci", - "version": "2.1.7", + "version": "3.0.0", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.0", "@dotcom-tool-kit/logger": "^2.1.1", "@dotcom-tool-kit/state": "^2.0.0", - "@dotcom-tool-kit/types": "^2.6.1", + "@dotcom-tool-kit/types": "^2.7.0", "lodash": "^4.17.21", "tslib": "^2.3.1", "yaml": "^2.1.1" @@ -20003,11 +20472,11 @@ }, "plugins/circleci-heroku": { "name": "@dotcom-tool-kit/circleci-heroku", - "version": "2.0.12", + "version": "2.1.0", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/circleci": "^2.1.7", - "@dotcom-tool-kit/heroku": "^2.1.0", + "@dotcom-tool-kit/circleci": "^3.0.0", + "@dotcom-tool-kit/heroku": "^2.1.1", "tslib": "^2.3.1" }, "peerDependencies": { @@ -20021,12 +20490,12 @@ }, "plugins/circleci-npm": { "name": "@dotcom-tool-kit/circleci-npm", - "version": "2.0.10", + "version": "3.0.0", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/circleci": "^2.1.7", - "@dotcom-tool-kit/npm": "^2.0.10", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/circleci": "^3.0.0", + "@dotcom-tool-kit/npm": "^2.0.11", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "peerDependencies": { @@ -20053,18 +20522,19 @@ }, "plugins/component": { "name": "@dotcom-tool-kit/component", - "version": "2.0.0", + "version": "2.0.1", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/circleci-npm": "^2.0.9", - "@dotcom-tool-kit/npm": "^2.0.9" + "@dotcom-tool-kit/circleci-npm": "^3.0.0", + "@dotcom-tool-kit/npm": "^2.0.11" }, "peerDependencies": { "dotcom-tool-kit": "2.x" } }, "plugins/cypress": { - "version": "0.1.0", + "name": "@dotcom-tool-kit/cypress", + "version": "2.0.0", "license": "ISC", "peerDependencies": { "dotcom-tool-kit": "2.x" @@ -20072,12 +20542,12 @@ }, "plugins/eslint": { "name": "@dotcom-tool-kit/eslint", - "version": "2.2.2", + "version": "2.2.3", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "devDependencies": { @@ -20290,11 +20760,11 @@ }, "plugins/frontend-app": { "name": "@dotcom-tool-kit/frontend-app", - "version": "2.1.10", + "version": "2.1.11", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/backend-app": "^2.0.12", - "@dotcom-tool-kit/webpack": "^2.1.8" + "@dotcom-tool-kit/backend-app": "^2.0.13", + "@dotcom-tool-kit/webpack": "^2.1.9" }, "peerDependencies": { "dotcom-tool-kit": "2.x" @@ -20302,16 +20772,16 @@ }, "plugins/heroku": { "name": "@dotcom-tool-kit/heroku", - "version": "2.1.0", + "version": "2.1.1", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/npm": "^2.0.10", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", + "@dotcom-tool-kit/npm": "^2.0.11", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "@dotcom-tool-kit/wait-for-ok": "^2.0.1", "@octokit/request": "^5.6.0", "@octokit/request-error": "^2.1.0", @@ -20337,10 +20807,10 @@ }, "plugins/husky-npm": { "name": "@dotcom-tool-kit/husky-npm", - "version": "2.2.1", + "version": "3.0.0", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/package-json-hook": "^2.1.1", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", "tslib": "^2.3.1" }, "peerDependencies": { @@ -20355,11 +20825,11 @@ }, "plugins/jest": { "name": "@dotcom-tool-kit/jest", - "version": "2.0.9", + "version": "2.0.10", "license": "ISC", "dependencies": { "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "devDependencies": { @@ -20378,12 +20848,12 @@ }, "plugins/lint-staged": { "name": "@dotcom-tool-kit/lint-staged", - "version": "2.1.9", + "version": "3.0.0", "license": "ISC", "dependencies": { "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", + "@dotcom-tool-kit/types": "^2.7.0", "lint-staged": "^11.2.3", "tslib": "^2.3.1" }, @@ -20393,12 +20863,12 @@ }, "plugins/lint-staged-npm": { "name": "@dotcom-tool-kit/lint-staged-npm", - "version": "2.0.10", + "version": "2.0.11", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/husky-npm": "^2.2.1", - "@dotcom-tool-kit/lint-staged": "^2.1.9", - "@dotcom-tool-kit/options": "^2.0.9", + "@dotcom-tool-kit/husky-npm": "^3.0.0", + "@dotcom-tool-kit/lint-staged": "^3.0.0", + "@dotcom-tool-kit/options": "^2.0.10", "tslib": "^2.3.1" }, "peerDependencies": { @@ -20467,12 +20937,12 @@ }, "plugins/mocha": { "name": "@dotcom-tool-kit/mocha", - "version": "2.1.6", + "version": "2.1.7", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "fs": "0.0.1-security", "glob": "^7.1.7", "mocha": "^8.3.2", @@ -20495,12 +20965,12 @@ }, "plugins/n-test": { "name": "@dotcom-tool-kit/n-test", - "version": "2.1.4", + "version": "2.1.5", "license": "ISC", "dependencies": { "@dotcom-tool-kit/logger": "^2.1.2", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@financial-times/n-test": "^4.0.1", "tslib": "^2.3.1" }, @@ -20520,14 +20990,14 @@ }, "plugins/next-router": { "name": "@dotcom-tool-kit/next-router", - "version": "2.0.9", + "version": "2.0.10", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "ft-next-router": "^1.0.0", "tslib": "^2.3.1" }, @@ -20542,13 +21012,13 @@ }, "plugins/node": { "name": "@dotcom-tool-kit/node", - "version": "2.2.2", + "version": "2.2.3", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "get-port": "^5.1.1", "tslib": "^2.3.1", "wait-port": "^0.2.9" @@ -20564,13 +21034,13 @@ }, "plugins/nodemon": { "name": "@dotcom-tool-kit/nodemon", - "version": "2.1.2", + "version": "2.1.3", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "get-port": "^5.1.1", "tslib": "^2.3.1" }, @@ -20589,14 +21059,14 @@ }, "plugins/npm": { "name": "@dotcom-tool-kit/npm", - "version": "2.0.10", + "version": "2.0.11", "license": "ISC", "dependencies": { "@actions/exec": "^1.1.0", "@dotcom-tool-kit/error": "^2.0.1", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "libnpmpack": "^3.1.0", "libnpmpublish": "^5.0.1", "pacote": "^12.0.3", @@ -20753,10 +21223,10 @@ }, "plugins/pa11y": { "name": "@dotcom-tool-kit/pa11y", - "version": "0.3.6", + "version": "0.3.7", "license": "ISC", "dependencies": { - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "pa11y-ci": "^3.0.1", "tslib": "^2.3.1" }, @@ -20774,13 +21244,13 @@ }, "plugins/prettier": { "name": "@dotcom-tool-kit/prettier", - "version": "2.1.0", + "version": "2.1.1", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", + "@dotcom-tool-kit/types": "^2.7.0", "fast-glob": "^3.2.7", "hook-std": "^2.0.0", "prettier": "^2.2.1", @@ -20803,11 +21273,11 @@ }, "plugins/secret-squirrel": { "name": "@dotcom-tool-kit/secret-squirrel", - "version": "1.0.8", + "version": "1.0.9", "license": "ISC", "dependencies": { "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "peerDependencies": { @@ -20822,12 +21292,12 @@ }, "plugins/upload-assets-to-s3": { "name": "@dotcom-tool-kit/upload-assets-to-s3", - "version": "2.0.10", + "version": "2.0.11", "license": "ISC", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "aws-sdk": "^2.901.0", "glob": "^7.1.6", "mime": "^2.5.2", @@ -20852,12 +21322,12 @@ }, "plugins/webpack": { "name": "@dotcom-tool-kit/webpack", - "version": "2.1.8", + "version": "2.1.9", "license": "MIT", "dependencies": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1", "webpack-cli": "^4.6.0" }, @@ -22114,7 +22584,7 @@ "@babel/preset-env": "^7.16.11", "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "fast-glob": "^3.2.11", "tslib": "^2.3.1", @@ -22131,9 +22601,9 @@ "@dotcom-tool-kit/backend-app": { "version": "file:plugins/backend-app", "requires": { - "@dotcom-tool-kit/circleci-heroku": "^2.0.12", - "@dotcom-tool-kit/node": "^2.2.2", - "@dotcom-tool-kit/npm": "^2.0.10" + "@dotcom-tool-kit/circleci-heroku": "^2.1.0", + "@dotcom-tool-kit/node": "^2.2.3", + "@dotcom-tool-kit/npm": "^2.0.11" } }, "@dotcom-tool-kit/circleci": { @@ -22142,7 +22612,7 @@ "@dotcom-tool-kit/error": "^2.0.0", "@dotcom-tool-kit/logger": "^2.1.1", "@dotcom-tool-kit/state": "^2.0.0", - "@dotcom-tool-kit/types": "^2.6.1", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "@types/jest": "^27.4.0", "@types/js-yaml": "^4.0.3", @@ -22168,8 +22638,8 @@ "@dotcom-tool-kit/circleci-heroku": { "version": "file:plugins/circleci-heroku", "requires": { - "@dotcom-tool-kit/circleci": "^2.1.7", - "@dotcom-tool-kit/heroku": "^2.1.0", + "@dotcom-tool-kit/circleci": "^3.0.0", + "@dotcom-tool-kit/heroku": "^2.1.1", "tslib": "^2.3.1" }, "dependencies": { @@ -22183,9 +22653,9 @@ "@dotcom-tool-kit/circleci-npm": { "version": "file:plugins/circleci-npm", "requires": { - "@dotcom-tool-kit/circleci": "^2.1.7", - "@dotcom-tool-kit/npm": "^2.0.10", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/circleci": "^3.0.0", + "@dotcom-tool-kit/npm": "^2.0.11", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "dependencies": { @@ -22199,8 +22669,8 @@ "@dotcom-tool-kit/component": { "version": "file:plugins/component", "requires": { - "@dotcom-tool-kit/circleci-npm": "^2.0.9", - "@dotcom-tool-kit/npm": "^2.0.9" + "@dotcom-tool-kit/circleci-npm": "^3.0.0", + "@dotcom-tool-kit/npm": "^2.0.11" } }, "@dotcom-tool-kit/create": { @@ -22208,7 +22678,7 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@financial-times/package-json": "^3.0.0", "@quarterto/parse-makefile-rules": "^1.1.0", "@types/financial-times__package-json": "^1.9.0", @@ -22218,7 +22688,7 @@ "@types/pacote": "^11.1.3", "@types/prompts": "^2.0.14", "cosmiconfig": "^7.0.1", - "dotcom-tool-kit": "^2.3.6", + "dotcom-tool-kit": "^2.4.0", "import-cwd": "^3.0.0", "js-yaml": "^4.1.0", "komatsu": "^1.3.0", @@ -22256,7 +22726,7 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "@types/eslint": "^7.2.13", "eslint": "^8.15.0", @@ -22402,8 +22872,8 @@ "@dotcom-tool-kit/frontend-app": { "version": "file:plugins/frontend-app", "requires": { - "@dotcom-tool-kit/backend-app": "^2.0.12", - "@dotcom-tool-kit/webpack": "^2.1.8" + "@dotcom-tool-kit/backend-app": "^2.0.13", + "@dotcom-tool-kit/webpack": "^2.1.9" } }, "@dotcom-tool-kit/heroku": { @@ -22411,11 +22881,11 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/npm": "^2.0.10", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", + "@dotcom-tool-kit/npm": "^2.0.11", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "@dotcom-tool-kit/wait-for-ok": "^2.0.1", "@octokit/request": "^5.6.0", "@octokit/request-error": "^2.1.0", @@ -22439,7 +22909,7 @@ "@dotcom-tool-kit/husky-npm": { "version": "file:plugins/husky-npm", "requires": { - "@dotcom-tool-kit/package-json-hook": "^2.1.1", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", "tslib": "^2.3.1" }, "dependencies": { @@ -22454,7 +22924,7 @@ "version": "file:plugins/jest", "requires": { "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "tslib": "^2.3.1", "winston": "^3.5.1" @@ -22471,8 +22941,8 @@ "version": "file:plugins/lint-staged", "requires": { "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", + "@dotcom-tool-kit/types": "^2.7.0", "lint-staged": "^11.2.3", "tslib": "^2.3.1" }, @@ -22518,9 +22988,9 @@ "@dotcom-tool-kit/lint-staged-npm": { "version": "file:plugins/lint-staged-npm", "requires": { - "@dotcom-tool-kit/husky-npm": "^2.2.1", - "@dotcom-tool-kit/lint-staged": "^2.1.9", - "@dotcom-tool-kit/options": "^2.0.9", + "@dotcom-tool-kit/husky-npm": "^3.0.0", + "@dotcom-tool-kit/lint-staged": "^3.0.0", + "@dotcom-tool-kit/options": "^2.0.10", "tslib": "^2.3.1" }, "dependencies": { @@ -22556,7 +23026,7 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "@types/glob": "^7.1.3", "@types/mocha": "^8.2.2", @@ -22579,7 +23049,7 @@ "requires": { "@dotcom-tool-kit/logger": "^2.1.2", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@financial-times/n-test": "^4.0.1", "@jest/globals": "^27.4.6", "@types/jest": "^27.4.0", @@ -22600,8 +23070,8 @@ "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "ft-next-router": "^1.0.0", "tslib": "^2.3.1" }, @@ -22618,8 +23088,8 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "get-port": "^5.1.1", "tslib": "^2.3.1", "wait-port": "^0.2.9" @@ -22637,8 +23107,8 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", - "@dotcom-tool-kit/vault": "^2.0.9", + "@dotcom-tool-kit/types": "^2.7.0", + "@dotcom-tool-kit/vault": "^2.0.10", "@types/nodemon": "^1.19.1", "get-port": "^5.1.1", "tslib": "^2.3.1" @@ -22656,9 +23126,9 @@ "requires": { "@actions/exec": "^1.1.0", "@dotcom-tool-kit/error": "^2.0.1", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", "@dotcom-tool-kit/state": "^2.0.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@types/libnpmpublish": "^4.0.1", "@types/pacote": "^11.1.3", "@types/tar": "^6.1.1", @@ -22775,7 +23245,7 @@ "@dotcom-tool-kit/options": { "version": "file:lib/options", "requires": { - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "dependencies": { @@ -22789,7 +23259,7 @@ "@dotcom-tool-kit/pa11y": { "version": "file:plugins/pa11y", "requires": { - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@types/pa11y": "^5.3.4", "pa11y-ci": "^3.0.1", "tslib": "^2.3.1" @@ -22825,8 +23295,8 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/package-json-hook": "^2.1.1", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/package-json-hook": "^3.0.0", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "fast-glob": "^3.2.7", "hook-std": "^2.0.0", @@ -22848,11 +23318,11 @@ "version": "file:core/sandbox", "requires": { "@dotcom-tool-kit/circleci-heroku": "^2.0.0", - "@dotcom-tool-kit/circleci-npm": "^2.0.0", + "@dotcom-tool-kit/circleci-npm": "^3.0.0", "@dotcom-tool-kit/eslint": "^2.0.0", "@dotcom-tool-kit/frontend-app": "^2.0.0", "@dotcom-tool-kit/jest": "^2.0.0", - "@dotcom-tool-kit/lint-staged": "^2.0.0", + "@dotcom-tool-kit/lint-staged": "^3.0.0", "@dotcom-tool-kit/lint-staged-npm": "^2.0.0", "@dotcom-tool-kit/mocha": "^2.0.0", "@dotcom-tool-kit/n-test": "^2.0.0", @@ -22871,7 +23341,7 @@ "version": "file:plugins/secret-squirrel", "requires": { "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "tslib": "^2.3.1" }, "dependencies": { @@ -22895,6 +23365,18 @@ } } }, + "@dotcom-tool-kit/tool-box": { + "version": "file:core/tool-box", + "requires": { + "@dotcom-tool-kit/logger": "^2.1.2", + "@dotcom-tool-kit/types": "^2.7.0", + "@types/react": "^17.0.52", + "dotcom-tool-kit": "^2.4.0", + "ink": "^3.2.0", + "react": "^17.0.2", + "winston": "^3.6.0" + } + }, "@dotcom-tool-kit/types": { "version": "file:lib/types", "requires": { @@ -22921,7 +23403,7 @@ "@aws-sdk/types": "^3.13.1", "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "@types/glob": "^7.1.3", "@types/jest": "^27.4.0", @@ -22944,8 +23426,8 @@ "version": "file:lib/vault", "requires": { "@dotcom-tool-kit/error": "^2.0.1", - "@dotcom-tool-kit/options": "^2.0.9", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/options": "^2.0.10", + "@dotcom-tool-kit/types": "^2.7.0", "@financial-times/n-fetch": "^1.0.0-beta.7", "@types/jest": "^27.0.2", "fs": "0.0.1-security", @@ -22998,7 +23480,7 @@ "requires": { "@dotcom-tool-kit/error": "^2.0.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/types": "^2.7.0", "@jest/globals": "^27.4.6", "ts-node": "^10.0.0", "tslib": "^2.3.1", @@ -24426,6 +24908,12 @@ "@types/node": "*" } }, + "@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", + "devOptional": true + }, "@types/puppeteer": { "version": "3.0.8", "dev": true, @@ -24433,6 +24921,17 @@ "@types/node": "*" } }, + "@types/react": { + "version": "17.0.52", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.52.tgz", + "integrity": "sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A==", + "devOptional": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, "@types/request": { "version": "2.48.8", "requires": { @@ -24455,6 +24954,12 @@ "@types/retry": { "version": "0.12.0" }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "devOptional": true + }, "@types/semver": { "version": "7.3.9", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz", @@ -24515,6 +25020,11 @@ "@types/node": "*" } }, + "@types/yoga-layout": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", + "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" + }, "@typescript-eslint/eslint-plugin": { "version": "4.33.0", "dev": true, @@ -24990,6 +25500,18 @@ "es-shim-unscopables": "^1.0.0" } }, + "array.prototype.flatmap": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", + "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, "array.prototype.map": { "version": "1.0.4", "peer": true, @@ -25089,6 +25611,11 @@ "atob": { "version": "2.1.2" }, + "auto-bind": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", + "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==" + }, "aws-sdk": { "version": "2.1128.0", "requires": { @@ -25867,6 +26394,14 @@ "co": { "version": "4.6.0" }, + "code-excerpt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-3.0.0.tgz", + "integrity": "sha512-VHNTVhd7KsLGOqfX3SyeO8RyYPMp1GJOg194VITk04WMYCv4plV68YWe6TJZxd9MhobjtpMRnVky01gqZsalaw==", + "requires": { + "convert-to-spaces": "^1.0.1" + } + }, "code-point-at": { "version": "1.1.0", "dev": true @@ -26154,6 +26689,11 @@ "safe-buffer": "~5.1.1" } }, + "convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha512-cj09EBuObp9gZNQCzc7hByQyrs6jVGE+o9kSJmeUoj+GiPiJvi5LYqEH/Hmme4+MTLHM+Ejtq+FChpjjEnsPdQ==" + }, "cookie": { "version": "0.3.1" }, @@ -26382,6 +26922,12 @@ } } }, + "csstype": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz", + "integrity": "sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==", + "devOptional": true + }, "cwise-compiler": { "version": "1.1.3", "requires": { @@ -26614,22 +27160,22 @@ "dotcom-tool-kit": { "version": "file:core/cli", "requires": { - "@dotcom-tool-kit/babel": "^2.0.9", - "@dotcom-tool-kit/backend-app": "^2.0.12", - "@dotcom-tool-kit/circleci": "^2.1.7", - "@dotcom-tool-kit/circleci-heroku": "^2.0.12", + "@dotcom-tool-kit/babel": "^2.0.10", + "@dotcom-tool-kit/backend-app": "^2.0.13", + "@dotcom-tool-kit/circleci": "^3.0.0", + "@dotcom-tool-kit/circleci-heroku": "^2.1.0", "@dotcom-tool-kit/error": "^2.0.1", - "@dotcom-tool-kit/eslint": "^2.2.2", - "@dotcom-tool-kit/frontend-app": "^2.1.10", - "@dotcom-tool-kit/heroku": "^2.1.0", + "@dotcom-tool-kit/eslint": "^2.2.3", + "@dotcom-tool-kit/frontend-app": "^2.1.11", + "@dotcom-tool-kit/heroku": "^2.1.1", "@dotcom-tool-kit/logger": "^2.1.2", - "@dotcom-tool-kit/mocha": "^2.1.6", - "@dotcom-tool-kit/n-test": "^2.1.4", - "@dotcom-tool-kit/npm": "^2.0.10", - "@dotcom-tool-kit/options": "^2.0.9", - "@dotcom-tool-kit/types": "^2.6.2", + "@dotcom-tool-kit/mocha": "^2.1.7", + "@dotcom-tool-kit/n-test": "^2.1.5", + "@dotcom-tool-kit/npm": "^2.0.11", + "@dotcom-tool-kit/options": "^2.0.10", + "@dotcom-tool-kit/types": "^2.7.0", "@dotcom-tool-kit/wait-for-ok": "^2.0.1", - "@dotcom-tool-kit/webpack": "^2.1.8", + "@dotcom-tool-kit/webpack": "^2.1.9", "@jest/globals": "^27.4.6", "@types/lodash.groupby": "^4.6.7", "@types/lodash.merge": "^4.6.6", @@ -27198,6 +27744,69 @@ "version": "2.6.0", "dev": true }, + "eslint-plugin-react": { + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.30.1.tgz", + "integrity": "sha512-NbEvI9jtqO46yJA3wcRF9Mo0lF9T/jhdHqhCHXiXtD+Zcb98812wvokjWpU7Q4QH5edo6dmqrukxVvWWXHlsUg==", + "dev": true, + "requires": { + "array-includes": "^3.1.5", + "array.prototype.flatmap": "^1.3.0", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.5", + "object.fromentries": "^2.0.5", + "object.hasown": "^1.1.1", + "object.values": "^1.1.5", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.7" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "requires": {} + }, "eslint-scope": { "version": "5.1.1", "dev": true, @@ -27836,8 +28445,7 @@ "dev": true }, "functions-have-names": { - "version": "1.2.3", - "peer": true + "version": "1.2.3" }, "gauge": { "version": "4.0.4", @@ -28458,6 +29066,53 @@ "ini": { "version": "1.3.8" }, + "ink": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ink/-/ink-3.2.0.tgz", + "integrity": "sha512-firNp1q3xxTzoItj/eOOSZQnYSlyrWks5llCTVX37nJ59K3eXbQ8PtzCguqo8YI19EELo5QxaKnJd4VxzhU8tg==", + "requires": { + "ansi-escapes": "^4.2.1", + "auto-bind": "4.0.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "code-excerpt": "^3.0.0", + "indent-string": "^4.0.0", + "is-ci": "^2.0.0", + "lodash": "^4.17.20", + "patch-console": "^1.0.0", + "react-devtools-core": "^4.19.1", + "react-reconciler": "^0.26.2", + "scheduler": "^0.20.2", + "signal-exit": "^3.0.2", + "slice-ansi": "^3.0.0", + "stack-utils": "^2.0.2", + "string-width": "^4.2.2", + "type-fest": "^0.12.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0", + "ws": "^7.5.5", + "yoga-layout-prebuilt": "^1.9.6" + }, + "dependencies": { + "type-fest": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", + "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==" + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, "inquirer": { "version": "7.3.3", "requires": { @@ -29418,6 +30073,16 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.2.tgz", + "integrity": "sha512-4ZCADZHRkno244xlNnn4AOG6sRQ7iBZ5BbgZ4vW4y5IZw7cVUD1PPeblm1xx/nfmMxPdt/LHsXZW8z/j58+l9Q==", + "dev": true, + "requires": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.2" + } + }, "keyv": { "version": "3.1.0", "requires": { @@ -29839,6 +30504,14 @@ "loglevel-plugin-prefix": { "version": "0.8.4" }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "loupe": { "version": "2.3.4", "dev": true, @@ -31057,6 +31730,38 @@ "object-keys": "^1.1.1" } }, + "object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + } + }, + "object.hasown": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz", + "integrity": "sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==", + "dev": true, + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, "object.pick": { "version": "1.3.0", "requires": { @@ -31790,6 +32495,11 @@ "pascalcase": { "version": "0.1.1" }, + "patch-console": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/patch-console/-/patch-console-1.0.0.tgz", + "integrity": "sha512-nxl9nrnLQmh64iTzMfyylSlRozL7kAXIaxw1fVcLYdyhNkJCRUzirRZTikXGJsg+hc4fqpneTK6iU2H1Q8THSA==" + }, "path": { "version": "0.12.7", "requires": { @@ -31950,6 +32660,25 @@ "sisteransi": "^1.0.5" } }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + } + } + }, "protocolify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/protocolify/-/protocolify-3.0.0.tgz", @@ -32141,9 +32870,37 @@ } } }, + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-devtools-core": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.25.0.tgz", + "integrity": "sha512-iewRrnu0ZnmfL+jJayKphXj04CFh6i3ezVnpCtcnZbTPSQgN09XqHAzXbKbqNDl7aTg9QLNkQRP6M3DvdrinWA==", + "requires": { + "shell-quote": "^1.6.1", + "ws": "^7" + } + }, "react-is": { "version": "17.0.2" }, + "react-reconciler": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz", + "integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "scheduler": "^0.20.2" + } + }, "read-package-json": { "version": "5.0.1", "requires": { @@ -32359,6 +33116,17 @@ } } }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "regexpp": { "version": "3.2.0", "dev": true @@ -32671,6 +33439,15 @@ "scarlet": { "version": "2.0.20" }, + "scheduler": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "1.0.0", "requires": { @@ -32785,6 +33562,11 @@ "version": "1.0.0", "dev": true }, + "shell-quote": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz", + "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==" + }, "side-channel": { "version": "1.0.4", "requires": { @@ -33204,6 +33986,22 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.matchall": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", + "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.1", + "side-channel": "^1.0.4" + } + }, "string.prototype.trimend": { "version": "1.0.5", "requires": { @@ -34908,6 +35706,14 @@ "yocto-queue": { "version": "0.1.0" }, + "yoga-layout-prebuilt": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.10.0.tgz", + "integrity": "sha512-YnOmtSbv4MTf7RGJMK0FvZ+KD8OEe/J5BNnR0GHhD8J/XcG/Qvxgszm0Un6FTHWW4uHlTgP0IztiXQnGyIR45g==", + "requires": { + "@types/yoga-layout": "1.9.2" + } + }, "zip-stream": { "version": "2.1.3", "requires": { diff --git a/package.json b/package.json index 744f7a1af..770a22f49 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,8 @@ "eslint": "^7.20.0", "eslint-config-prettier": "^8.0.0", "eslint-plugin-import": "^2.22.1", + "eslint-plugin-react": "^7.30.1", + "eslint-plugin-react-hooks": "^4.6.0", "husky": "^4.3.8", "jest": "^27.4.7", "lint-staged": "^10.5.4", diff --git a/release-please-config.json b/release-please-config.json index a315d36f1..5d9c51db6 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -8,6 +8,7 @@ "packages": { "core/cli": {}, "core/create": {}, + "core/tool-box": {}, "lib/error": {}, "lib/logger": {}, "lib/options": {}, diff --git a/tsconfig.json b/tsconfig.json index f75e39f9c..3f77658d5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -105,6 +105,9 @@ }, { "path": "plugins/cypress" + }, + { + "path": "core/tool-box" } ] }