From 34e6adf0b0ddb32250f2dcb01a338adcf889a7c9 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 8 Jul 2022 14:02:12 +0200 Subject: [PATCH 001/111] First take on rendering app menus without the List component --- app/src/ui/app-menu/app-menu-bar-button.tsx | 1 + app/src/ui/app-menu/app-menu.tsx | 1 - app/src/ui/app-menu/menu-list-item.tsx | 45 +++++++- app/src/ui/app-menu/menu-pane.tsx | 119 ++++++-------------- app/styles/ui/_app-menu.scss | 29 +---- 5 files changed, 83 insertions(+), 112 deletions(-) diff --git a/app/src/ui/app-menu/app-menu-bar-button.tsx b/app/src/ui/app-menu/app-menu-bar-button.tsx index 65e89f1ab0..06a0642dff 100644 --- a/app/src/ui/app-menu/app-menu-bar-button.tsx +++ b/app/src/ui/app-menu/app-menu-bar-button.tsx @@ -209,6 +209,7 @@ export class AppMenuBarButton extends React.Component< highlightAccessKey={this.props.highlightMenuAccessKey} renderAcceleratorText={false} renderSubMenuArrow={false} + selected={false} /> ) diff --git a/app/src/ui/app-menu/app-menu.tsx b/app/src/ui/app-menu/app-menu.tsx index 36bf8c59cc..66ce645543 100644 --- a/app/src/ui/app-menu/app-menu.tsx +++ b/app/src/ui/app-menu/app-menu.tsx @@ -295,7 +295,6 @@ export class AppMenu extends React.Component { key={key} ref={this.onMenuPaneRef} className={className} - autoHeight={this.props.autoHeight} depth={depth} items={menu.items} selectedItem={menu.selectedItem} diff --git a/app/src/ui/app-menu/menu-list-item.tsx b/app/src/ui/app-menu/menu-list-item.tsx index aa7a7f3787..5244d30c88 100644 --- a/app/src/ui/app-menu/menu-list-item.tsx +++ b/app/src/ui/app-menu/menu-list-item.tsx @@ -34,6 +34,27 @@ interface IMenuListItemProps { * Defaults to true if not specified (i.e. undefined) */ readonly renderSubMenuArrow?: boolean + + readonly selected: boolean + + readonly onKeyDown?: ( + item: MenuItem, + event: React.KeyboardEvent + ) => void + + readonly onMouseEnter?: ( + item: MenuItem, + event: React.MouseEvent + ) => void + readonly onMouseLeave?: ( + item: MenuItem, + event: React.MouseEvent + ) => void + + readonly onClick?: ( + item: MenuItem, + event: React.MouseEvent + ) => void } /** @@ -59,6 +80,22 @@ export class MenuListItem extends React.Component { return null } + private onKeyDown = (event: React.KeyboardEvent) => { + this.props.onKeyDown?.(this.props.item, event) + } + + private onMouseEnter = (event: React.MouseEvent) => { + this.props.onMouseEnter?.(this.props.item, event) + } + + private onMouseLeave = (event: React.MouseEvent) => { + this.props.onMouseLeave?.(this.props.item, event) + } + + private onClick = (event: React.MouseEvent) => { + this.props.onClick?.(this.props.item, event) + } + public render() { const item = this.props.item @@ -95,7 +132,13 @@ export class MenuListItem extends React.Component { ) return ( -
+
{this.getIcon(item)}
@@ -108,18 +95,6 @@ function getSelectedIndex( return selectedItem ? items.findIndex(i => i.id === selectedItem.id) : -1 } -export function getListHeight(menuItems: ReadonlyArray) { - return menuItems.reduce((acc, item) => acc + getRowHeight(item), 0) -} - -export function getRowHeight(item: MenuItem) { - if (!item.visible) { - return 0 - } - - return item.type === 'separator' ? SeparatorRowHeight : RowHeight -} - /** * Creates a menu pane state given props. This is intentionally not * an instance member in order to avoid mistakenly using any other @@ -172,16 +147,19 @@ export class MenuPane extends React.Component { } } - private onRowClick = (row: number, source: ClickSource) => { - const item = this.state.items[row] - + private onRowClick = ( + item: MenuItem, + event: React.MouseEvent + ) => { if (item.type !== 'separator' && item.enabled) { - this.props.onItemClicked(this.props.depth, item, source) + this.props.onItemClicked(this.props.depth, item, { + kind: 'mouseclick', + event, + }) } } - private onSelectedRowChanged = (row: number, source: SelectionSource) => { - const item = this.state.items[row] + private onSelectedRowChanged = (item: MenuItem, source: SelectionSource) => { this.props.onSelectionChanged(this.props.depth, item, source) } @@ -217,51 +195,29 @@ export class MenuPane extends React.Component { } } - private onRowKeyDown = (row: number, event: React.KeyboardEvent) => { - if (this.props.onItemKeyDown) { - const item = this.state.items[row] - this.props.onItemKeyDown(this.props.depth, item, event) - } - } - - private canSelectRow = (row: number) => { - const item = this.state.items[row] - return itemIsSelectable(item) - } - - private onListRef = (list: List | null) => { - this.list = list + private onRowKeyDown = (item: MenuItem, event: React.KeyboardEvent) => { + this.props.onItemKeyDown?.(this.props.depth, item, event) } private onMouseEnter = (event: React.MouseEvent) => { - if (this.props.onMouseEnter) { - this.props.onMouseEnter(this.props.depth) + this.props.onMouseEnter?.(this.props.depth) + } + + private onRowMouseEnter = ( + item: MenuItem, + event: React.MouseEvent + ) => { + if (itemIsSelectable(item)) { + this.onSelectedRowChanged(item, { kind: 'hover', event }) } } - private renderMenuItem = (row: number) => { - const item = this.state.items[row] - - return ( - - ) - } - - private rowHeight = (info: { index: number }) => { - const item = this.state.items[info.index] - return item.type === 'separator' ? SeparatorRowHeight : RowHeight - } + private onRowMouseLeave = ( + item: MenuItem, + event: React.MouseEvent + ) => {} public render(): JSX.Element { - const style: React.CSSProperties = - this.props.autoHeight === true - ? { height: getListHeight(this.props.items) + 5, maxHeight: '100%' } - : {} - const className = classNames('menu-pane', this.props.className) return ( @@ -269,22 +225,19 @@ export class MenuPane extends React.Component { className={className} onMouseEnter={this.onMouseEnter} onKeyDown={this.onKeyDown} - style={style} > - + {this.state.items.map((item, ix) => ( + + ))}
) } diff --git a/app/styles/ui/_app-menu.scss b/app/styles/ui/_app-menu.scss index cb1c63565a..f2196405e5 100644 --- a/app/styles/ui/_app-menu.scss +++ b/app/styles/ui/_app-menu.scss @@ -1,34 +1,11 @@ @import '../mixins'; #app-menu-foldout { - height: 100%; display: flex; } .menu-pane { - height: 100%; - width: 240px; - - // Custom widths for some menus since we don't have - // auto-sizeable foldouts at the moment (or rather we - // do but our List implementation prevents them from - // working). See #3547 for an example. - &.menu-pane-branch { - width: 275px; - } - - &.menu-pane-edit { - width: 175px; - } - - &.menu-pane-help { - width: 220px; - } - - &.menu-pane-file { - width: 205px; - } - + padding-bottom: var(--spacing-half); // Open panes (except the first one) should have a border on their // right hand side to create a divider between them and their parent // menu. @@ -62,10 +39,8 @@ .menu-item { display: flex; align-items: center; - - height: 100%; - width: 100%; min-width: 0; + height: 30px; &.disabled { opacity: 0.3; From 1f8fc9a2dcb4ff89e0b854c7271192bc238779f2 Mon Sep 17 00:00:00 2001 From: Yohann Assouline Date: Fri, 8 Jul 2022 14:13:11 +0200 Subject: [PATCH 002/111] Add Neovide support --- app/src/lib/editors/darwin.ts | 4 ++++ docs/technical/editor-integration.md | 1 + 2 files changed, 5 insertions(+) diff --git a/app/src/lib/editors/darwin.ts b/app/src/lib/editors/darwin.ts index 15dc96f2d1..c141f88f15 100644 --- a/app/src/lib/editors/darwin.ts +++ b/app/src/lib/editors/darwin.ts @@ -31,6 +31,10 @@ const editors: IDarwinExternalEditor[] = [ name: 'MacVim', bundleIdentifiers: ['org.vim.MacVim'], }, + { + name: 'Neovide', + bundleIdentifiers: ['com.neovide.neovide'], + }, { name: 'Visual Studio Code', bundleIdentifiers: ['com.microsoft.VSCode'], diff --git a/docs/technical/editor-integration.md b/docs/technical/editor-integration.md index b6b3084ba5..8e280b07f0 100644 --- a/docs/technical/editor-integration.md +++ b/docs/technical/editor-integration.md @@ -212,6 +212,7 @@ These editors are currently supported: - [Atom](https://atom.io/) - [MacVim](https://macvim-dev.github.io/macvim/) + - [Neovide](https://github.com/neovide/neovide) - [Visual Studio Code](https://code.visualstudio.com/) - both stable and Insiders channel - [Visual Studio Codium](https://vscodium.com/) - [Sublime Text](https://www.sublimetext.com/) From 03fdc19ffecda03321d9190b95c256335e271362 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 8 Jul 2022 16:52:52 +0200 Subject: [PATCH 003/111] Wire up keyboard navigation again --- app/src/ui/app-menu/app-menu.tsx | 21 ++- app/src/ui/app-menu/menu-list-item.tsx | 47 +++-- app/src/ui/app-menu/menu-pane.tsx | 238 ++++++++++++------------ app/styles/ui/_app-menu.scss | 24 +-- app/styles/ui/window/_app-menu-bar.scss | 10 - 5 files changed, 168 insertions(+), 172 deletions(-) diff --git a/app/src/ui/app-menu/app-menu.tsx b/app/src/ui/app-menu/app-menu.tsx index 66ce645543..5e0c812f5c 100644 --- a/app/src/ui/app-menu/app-menu.tsx +++ b/app/src/ui/app-menu/app-menu.tsx @@ -166,11 +166,9 @@ export class AppMenu extends React.Component { } } - private onItemKeyDown = ( - depth: number, - item: MenuItem, - event: React.KeyboardEvent - ) => { + private onPaneKeyDown = (depth: number, event: React.KeyboardEvent) => { + const { selectedItem } = this.props.state[depth] + if (event.key === 'ArrowLeft' || event.key === 'Escape') { this.clearExpandCollapseTimer() @@ -191,9 +189,9 @@ export class AppMenu extends React.Component { this.clearExpandCollapseTimer() // Open the submenu and select the first item - if (item.type === 'submenuItem') { + if (selectedItem?.type === 'submenuItem') { this.props.dispatcher.setAppMenuState(menu => - menu.withOpenedMenu(item, true) + menu.withOpenedMenu(selectedItem, true) ) this.focusPane = depth + 1 event.preventDefault() @@ -222,6 +220,12 @@ export class AppMenu extends React.Component { }, expandCollapseTimeout) } + private onClearSelection = (depth: number) => { + this.props.dispatcher.setAppMenuState(appMenu => + appMenu.withDeselectedMenu(this.props.state[depth]) + ) + } + private onSelectionChanged = ( depth: number, item: MenuItem, @@ -300,9 +304,10 @@ export class AppMenu extends React.Component { selectedItem={menu.selectedItem} onItemClicked={this.onItemClicked} onMouseEnter={this.onPaneMouseEnter} - onItemKeyDown={this.onItemKeyDown} + onKeyDown={this.onPaneKeyDown} onSelectionChanged={this.onSelectionChanged} enableAccessKeyNavigation={this.props.enableAccessKeyNavigation} + onClearSelection={this.onClearSelection} /> ) } diff --git a/app/src/ui/app-menu/menu-list-item.tsx b/app/src/ui/app-menu/menu-list-item.tsx index 5244d30c88..8a81140757 100644 --- a/app/src/ui/app-menu/menu-list-item.tsx +++ b/app/src/ui/app-menu/menu-list-item.tsx @@ -37,11 +37,6 @@ interface IMenuListItemProps { readonly selected: boolean - readonly onKeyDown?: ( - item: MenuItem, - event: React.KeyboardEvent - ) => void - readonly onMouseEnter?: ( item: MenuItem, event: React.MouseEvent @@ -55,6 +50,8 @@ interface IMenuListItemProps { item: MenuItem, event: React.MouseEvent ) => void + + readonly focusOnSelection?: boolean } /** @@ -70,6 +67,8 @@ export function friendlyAcceleratorText(accelerator: string): string { } export class MenuListItem extends React.Component { + private wrapperRef = React.createRef() + private getIcon(item: MenuItem): JSX.Element | null { if (item.type === 'checkbox' && item.checked) { return @@ -80,10 +79,6 @@ export class MenuListItem extends React.Component { return null } - private onKeyDown = (event: React.KeyboardEvent) => { - this.props.onKeyDown?.(this.props.item, event) - } - private onMouseEnter = (event: React.MouseEvent) => { this.props.onMouseEnter?.(this.props.item, event) } @@ -96,6 +91,19 @@ export class MenuListItem extends React.Component { this.props.onClick?.(this.props.item, event) } + public componentDidMount() { + if (this.props.selected && this.props.focusOnSelection) { + this.wrapperRef.current?.focus() + } + } + + public componentDidUpdate(prevProps: IMenuListItemProps) { + const { focusOnSelection, selected } = this.props + if (focusOnSelection && selected && !prevProps.selected) { + this.wrapperRef.current?.focus() + } + } + public render() { const item = this.props.item @@ -120,24 +128,23 @@ export class MenuListItem extends React.Component {
) : null - const className = classNames( - 'menu-item', - { disabled: !item.enabled }, - { checkbox: item.type === 'checkbox' }, - { radio: item.type === 'radio' }, - { - checked: - (item.type === 'checkbox' || item.type === 'radio') && item.checked, - } - ) + const { type } = item + + const className = classNames('menu-item', { + disabled: !item.enabled, + checkbox: type === 'checkbox', + radio: type === 'radio', + checked: type === 'checkbox' || (type === 'radio' && item.checked), + selected: this.props.selected, + }) return (
{this.getIcon(item)}
diff --git a/app/src/ui/app-menu/menu-pane.tsx b/app/src/ui/app-menu/menu-pane.tsx index e4fec81f66..1cd9b515c8 100644 --- a/app/src/ui/app-menu/menu-pane.tsx +++ b/app/src/ui/app-menu/menu-pane.tsx @@ -1,13 +1,22 @@ import * as React from 'react' import classNames from 'classnames' -import { List, ClickSource, SelectionSource } from '../lib/list' +import { + ClickSource, + findLastSelectableRow, + findNextSelectableRow, + IHoverSource, + IKeyboardSource, + IMouseClickSource, + SelectionSource, +} from '../lib/list' import { MenuItem, itemIsSelectable, findItemByAccessKey, } from '../../models/app-menu' import { MenuListItem } from './menu-list-item' +import { assertNever } from '../../lib/fatal-error' interface IMenuPaneProps { /** @@ -51,11 +60,7 @@ interface IMenuPaneProps { * this only picks up on keyboard events received by a MenuItem and does * not cover keyboard events received on the MenuPane component itself. */ - readonly onItemKeyDown?: ( - depth: number, - item: MenuItem, - event: React.KeyboardEvent - ) => void + readonly onKeyDown?: (depth: number, event: React.KeyboardEvent) => void /** * A callback for when the MenuPane selection changes (i.e. a new menu item is selected). @@ -75,92 +80,54 @@ interface IMenuPaneProps { * keyboard navigation by pressing access keys. */ readonly enableAccessKeyNavigation: boolean + + readonly onClearSelection: (depth: number) => void } -interface IMenuPaneState { - /** - * A list of visible menu items that is to be rendered. This is a derivative - * of the props items with invisible items filtered out. - */ - readonly items: ReadonlyArray - - /** The selected row index or -1 if no selection exists. */ - readonly selectedIndex: number -} - -function getSelectedIndex( - selectedItem: MenuItem | undefined, - items: ReadonlyArray -) { - return selectedItem ? items.findIndex(i => i.id === selectedItem.id) : -1 -} - -/** - * Creates a menu pane state given props. This is intentionally not - * an instance member in order to avoid mistakenly using any other - * input data or state than the received props. - */ -function createState(props: IMenuPaneProps): IMenuPaneState { - const items = new Array() - const selectedItem = props.selectedItem - - let selectedIndex = -1 - - // Filter out all invisible items and maintain the correct - // selected index (if possible) - for (let i = 0; i < props.items.length; i++) { - const item = props.items[i] - - if (item.visible) { - items.push(item) - if (item === selectedItem) { - selectedIndex = items.length - 1 - } - } - } - - return { items, selectedIndex } -} - -export class MenuPane extends React.Component { - private list: List | null = null - - public constructor(props: IMenuPaneProps) { - super(props) - this.state = createState(props) - } - - public componentWillReceiveProps(nextProps: IMenuPaneProps) { - // No need to recreate the filtered list if it hasn't changed, - // we only have to update the selected item - if (this.props.items === nextProps.items) { - // Has the selection changed? - if (this.props.selectedItem !== nextProps.selectedItem) { - const selectedIndex = getSelectedIndex( - nextProps.selectedItem, - this.state.items - ) - this.setState({ selectedIndex }) - } - } else { - this.setState(createState(nextProps)) - } - } +export class MenuPane extends React.Component { + private paneRef = React.createRef() private onRowClick = ( item: MenuItem, event: React.MouseEvent ) => { if (item.type !== 'separator' && item.enabled) { - this.props.onItemClicked(this.props.depth, item, { - kind: 'mouseclick', - event, - }) + const source: IMouseClickSource = { kind: 'mouseclick', event } + this.props.onItemClicked(this.props.depth, item, source) } } - private onSelectedRowChanged = (item: MenuItem, source: SelectionSource) => { - this.props.onSelectionChanged(this.props.depth, item, source) + private trySelectItemAt(ix: number | null | undefined, source: ClickSource) { + const { items } = this.props + if (ix !== null && ix !== undefined && items[ix] !== undefined) { + this.props.onSelectionChanged(this.props.depth, items[ix], source) + return true + } + return false + } + + private tryMoveSelection( + direction: 'up' | 'down' | 'first' | 'last', + source: ClickSource + ) { + const { items, selectedItem } = this.props + const row = selectedItem ? items.indexOf(selectedItem) : -1 + const count = items.length + const selectable = (ix: number) => items[ix] && itemIsSelectable(items[ix]) + + let ix: number | null = null + + if (direction === 'up' || direction === 'down') { + ix = findNextSelectableRow(count, { direction, row }, selectable) + } else if (direction === 'first' || direction === 'last') { + ix = findLastSelectableRow( + direction === 'first' ? 'up' : 'down', + count, + selectable + ) + } + + return this.trySelectItemAt(ix, source) } private onKeyDown = (event: React.KeyboardEvent) => { @@ -173,30 +140,47 @@ export class MenuPane extends React.Component { return } + const source: IKeyboardSource = { kind: 'keyboard', event } + const { selectedItem } = this.props + const { key } = event + + if (isSupportedKey(key)) { + event.preventDefault() + + if (key === 'ArrowUp' || key === 'ArrowDown') { + this.tryMoveSelection(key === 'ArrowUp' ? 'up' : 'down', source) + } else if (key === 'Home' || key === 'End') { + const direction = key === 'Home' ? 'first' : 'last' + this.tryMoveSelection(direction, source) + } else if (key === 'Enter' || key === ' ') { + if (selectedItem !== undefined) { + this.props.onItemClicked(this.props.depth, selectedItem, source) + } + } else { + assertNever(key, 'Unsupported key') + } + } + // If we weren't opened with the Alt key we ignore key presses other than // arrow keys and Enter/Space etc. - if (!this.props.enableAccessKeyNavigation) { - return + if (this.props.enableAccessKeyNavigation) { + // At this point the list will already have intercepted any arrow keys + // and the list items themselves will have caught Enter/Space + const item = findItemByAccessKey(event.key, this.props.items) + if (item && itemIsSelectable(item)) { + event.preventDefault() + this.props.onSelectionChanged(this.props.depth, item, { + kind: 'keyboard', + event: event, + }) + this.props.onItemClicked(this.props.depth, item, { + kind: 'keyboard', + event: event, + }) + } } - // At this point the list will already have intercepted any arrow keys - // and the list items themselves will have caught Enter/Space - const item = findItemByAccessKey(event.key, this.state.items) - if (item && itemIsSelectable(item)) { - event.preventDefault() - this.props.onSelectionChanged(this.props.depth, item, { - kind: 'keyboard', - event: event, - }) - this.props.onItemClicked(this.props.depth, item, { - kind: 'keyboard', - event: event, - }) - } - } - - private onRowKeyDown = (item: MenuItem, event: React.KeyboardEvent) => { - this.props.onItemKeyDown?.(this.props.depth, item, event) + this.props.onKeyDown?.(this.props.depth, event) } private onMouseEnter = (event: React.MouseEvent) => { @@ -208,14 +192,19 @@ export class MenuPane extends React.Component { event: React.MouseEvent ) => { if (itemIsSelectable(item)) { - this.onSelectedRowChanged(item, { kind: 'hover', event }) + const source: IHoverSource = { kind: 'hover', event } + this.props.onSelectionChanged(this.props.depth, item, source) } } private onRowMouseLeave = ( item: MenuItem, event: React.MouseEvent - ) => {} + ) => { + if (this.props.selectedItem === item) { + this.props.onClearSelection(this.props.depth) + } + } public render(): JSX.Element { const className = classNames('menu-pane', this.props.className) @@ -225,26 +214,39 @@ export class MenuPane extends React.Component { className={className} onMouseEnter={this.onMouseEnter} onKeyDown={this.onKeyDown} + ref={this.paneRef} + tabIndex={-1} > - {this.state.items.map((item, ix) => ( - - ))} + {this.props.items + .filter(x => x.visible) + .map((item, ix) => ( + + ))}
) } public focus() { - if (this.list) { - this.list.focus() - } + this.paneRef.current?.focus() } } + +const supportedKeys = [ + 'ArrowUp', + 'ArrowDown', + 'Home', + 'End', + 'Enter', + ' ', +] as const +const isSupportedKey = (key: string): key is typeof supportedKeys[number] => + (supportedKeys as readonly string[]).includes(key) diff --git a/app/styles/ui/_app-menu.scss b/app/styles/ui/_app-menu.scss index f2196405e5..a950ee853b 100644 --- a/app/styles/ui/_app-menu.scss +++ b/app/styles/ui/_app-menu.scss @@ -13,22 +13,6 @@ border-left: var(--base-border); } - &:not(:last-child) { - // We want list items in previous menus to behave as if they have focus - // even though they don't, ie we want the selected+focus state - // to be in effect for all parent selected menu items as well as - // the current - .list-item { - &.selected { - --text-color: var(--box-selected-active-text-color); - --text-secondary-color: var(--box-selected-active-text-color); - - color: var(--text-color); - background-color: var(--box-selected-active-background-color); - } - } - } - // No focus outline for the list itself. When the app menu is opened without // an initial selection the list is given focus so that up/down arrow keys // will work. @@ -46,6 +30,14 @@ opacity: 0.3; } + &.selected { + --text-color: var(--box-selected-active-text-color); + --text-secondary-color: var(--box-selected-active-text-color); + + color: var(--text-color); + background-color: var(--box-selected-active-background-color); + } + .label { flex-grow: 1; margin-left: var(--spacing-double); diff --git a/app/styles/ui/window/_app-menu-bar.scss b/app/styles/ui/window/_app-menu-bar.scss index 419ec0bccd..d68cf5be29 100644 --- a/app/styles/ui/window/_app-menu-bar.scss +++ b/app/styles/ui/window/_app-menu-bar.scss @@ -56,15 +56,5 @@ pointer-events: all; } - - .menu-item:hover { - &:not(.disabled) { - --text-color: var(--box-selected-active-text-color); - --text-secondary-color: var(--box-selected-active-text-color); - - color: var(--text-color); - background-color: var(--box-selected-active-background-color); - } - } } } From e8140757fc32e984f3aa765c1848a7dee96946c0 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 8 Jul 2022 16:58:39 +0200 Subject: [PATCH 004/111] Get rid of focus outline --- app/styles/ui/_app-menu.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/styles/ui/_app-menu.scss b/app/styles/ui/_app-menu.scss index a950ee853b..f03c8afa5a 100644 --- a/app/styles/ui/_app-menu.scss +++ b/app/styles/ui/_app-menu.scss @@ -13,6 +13,10 @@ border-left: var(--base-border); } + &:focus { + outline: none; + } + // No focus outline for the list itself. When the app menu is opened without // an initial selection the list is given focus so that up/down arrow keys // will work. From caa996869c5cf5574602b2db2975a0ee83b4fed6 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 8 Jul 2022 16:58:47 +0200 Subject: [PATCH 005/111] We don't use List anymore --- app/src/ui/app-menu/app-menu.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/src/ui/app-menu/app-menu.tsx b/app/src/ui/app-menu/app-menu.tsx index 5e0c812f5c..acfcbdd60b 100644 --- a/app/src/ui/app-menu/app-menu.tsx +++ b/app/src/ui/app-menu/app-menu.tsx @@ -284,12 +284,6 @@ export class AppMenu extends React.Component { } private renderMenuPane(depth: number, menu: IMenu): JSX.Element { - // NB: We use the menu id instead of depth as the key here to force - // a new MenuPane instance and List. This is because we used dynamic - // row heights and the react-virtualized Grid component isn't able to - // recompute row heights accurately. Without this row indices which - // previously held a separator item will retain that height and vice- - // versa. // If the menu doesn't have an id it's the root menu const key = menu.id || '@' const className = menu.id ? menuPaneClassNameFromId(menu.id) : undefined From 1d25027dea02199b6fd29d590881242d35aaa7f7 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 8 Jul 2022 17:18:11 +0200 Subject: [PATCH 006/111] Restore aria attributes --- app/src/ui/app-menu/menu-list-item.tsx | 1 + app/src/ui/app-menu/menu-pane.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/app/src/ui/app-menu/menu-list-item.tsx b/app/src/ui/app-menu/menu-list-item.tsx index 8a81140757..5f04c5285d 100644 --- a/app/src/ui/app-menu/menu-list-item.tsx +++ b/app/src/ui/app-menu/menu-list-item.tsx @@ -145,6 +145,7 @@ export class MenuListItem extends React.Component { onMouseLeave={this.onMouseLeave} onClick={this.onClick} ref={this.wrapperRef} + role="menuitem" > {this.getIcon(item)}
diff --git a/app/src/ui/app-menu/menu-pane.tsx b/app/src/ui/app-menu/menu-pane.tsx index 1cd9b515c8..840b5b789f 100644 --- a/app/src/ui/app-menu/menu-pane.tsx +++ b/app/src/ui/app-menu/menu-pane.tsx @@ -216,6 +216,7 @@ export class MenuPane extends React.Component { onKeyDown={this.onKeyDown} ref={this.paneRef} tabIndex={-1} + role="menu" > {this.props.items .filter(x => x.visible) From 3fff7d17586290d5f370a1dbcf1cb6bc7fb80f27 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Fri, 8 Jul 2022 17:20:43 +0200 Subject: [PATCH 007/111] :art: cleanup --- app/src/ui/app-menu/menu-pane.tsx | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/app/src/ui/app-menu/menu-pane.tsx b/app/src/ui/app-menu/menu-pane.tsx index 840b5b789f..ab487d57e8 100644 --- a/app/src/ui/app-menu/menu-pane.tsx +++ b/app/src/ui/app-menu/menu-pane.tsx @@ -97,15 +97,6 @@ export class MenuPane extends React.Component { } } - private trySelectItemAt(ix: number | null | undefined, source: ClickSource) { - const { items } = this.props - if (ix !== null && ix !== undefined && items[ix] !== undefined) { - this.props.onSelectionChanged(this.props.depth, items[ix], source) - return true - } - return false - } - private tryMoveSelection( direction: 'up' | 'down' | 'first' | 'last', source: ClickSource @@ -120,14 +111,16 @@ export class MenuPane extends React.Component { if (direction === 'up' || direction === 'down') { ix = findNextSelectableRow(count, { direction, row }, selectable) } else if (direction === 'first' || direction === 'last') { - ix = findLastSelectableRow( - direction === 'first' ? 'up' : 'down', - count, - selectable - ) + const d = direction === 'first' ? 'up' : 'down' + ix = findLastSelectableRow(d, count, selectable) } - return this.trySelectItemAt(ix, source) + if (ix !== null && items[ix] !== undefined) { + this.props.onSelectionChanged(this.props.depth, items[ix], source) + return true + } + + return false } private onKeyDown = (event: React.KeyboardEvent) => { From d597a26343fa51f73c13bf1581363e32835134ce Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 10 Aug 2022 15:10:31 +0200 Subject: [PATCH 008/111] More specific types --- app/src/ui/app-menu/app-menu.tsx | 5 ++++- app/src/ui/app-menu/menu-pane.tsx | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/src/ui/app-menu/app-menu.tsx b/app/src/ui/app-menu/app-menu.tsx index acfcbdd60b..0e139e49d0 100644 --- a/app/src/ui/app-menu/app-menu.tsx +++ b/app/src/ui/app-menu/app-menu.tsx @@ -166,7 +166,10 @@ export class AppMenu extends React.Component { } } - private onPaneKeyDown = (depth: number, event: React.KeyboardEvent) => { + private onPaneKeyDown = ( + depth: number, + event: React.KeyboardEvent + ) => { const { selectedItem } = this.props.state[depth] if (event.key === 'ArrowLeft' || event.key === 'Escape') { diff --git a/app/src/ui/app-menu/menu-pane.tsx b/app/src/ui/app-menu/menu-pane.tsx index ab487d57e8..849147a723 100644 --- a/app/src/ui/app-menu/menu-pane.tsx +++ b/app/src/ui/app-menu/menu-pane.tsx @@ -60,7 +60,10 @@ interface IMenuPaneProps { * this only picks up on keyboard events received by a MenuItem and does * not cover keyboard events received on the MenuPane component itself. */ - readonly onKeyDown?: (depth: number, event: React.KeyboardEvent) => void + readonly onKeyDown?: ( + depth: number, + event: React.KeyboardEvent + ) => void /** * A callback for when the MenuPane selection changes (i.e. a new menu item is selected). @@ -123,7 +126,7 @@ export class MenuPane extends React.Component { return false } - private onKeyDown = (event: React.KeyboardEvent) => { + private onKeyDown = (event: React.KeyboardEvent) => { if (event.defaultPrevented) { return } From 5ac38c2fbc88d1dcbe7392dd515b4ed7b3cc3b3d Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 10 Aug 2022 15:12:34 +0200 Subject: [PATCH 009/111] Refactor fail --- app/src/ui/app-menu/menu-list-item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ui/app-menu/menu-list-item.tsx b/app/src/ui/app-menu/menu-list-item.tsx index 5f04c5285d..1cb5a3e78c 100644 --- a/app/src/ui/app-menu/menu-list-item.tsx +++ b/app/src/ui/app-menu/menu-list-item.tsx @@ -134,7 +134,7 @@ export class MenuListItem extends React.Component { disabled: !item.enabled, checkbox: type === 'checkbox', radio: type === 'radio', - checked: type === 'checkbox' || (type === 'radio' && item.checked), + checked: (type === 'checkbox' || type === 'radio') && item.checked, selected: this.props.selected, }) From 7788b80955297b09f235dfd02f39b579891e539a Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 10 Aug 2022 15:20:11 +0200 Subject: [PATCH 010/111] :book: --- app/src/ui/app-menu/menu-list-item.tsx | 11 +++++++++++ app/src/ui/app-menu/menu-pane.tsx | 10 +++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/ui/app-menu/menu-list-item.tsx b/app/src/ui/app-menu/menu-list-item.tsx index 1cb5a3e78c..db11e6457b 100644 --- a/app/src/ui/app-menu/menu-list-item.tsx +++ b/app/src/ui/app-menu/menu-list-item.tsx @@ -35,22 +35,33 @@ interface IMenuListItemProps { */ readonly renderSubMenuArrow?: boolean + /** + * Whether or not the menu item represented by this list item is the currently + * selected menu item. + */ readonly selected: boolean + /** Called when the user's pointer device enter the list item */ readonly onMouseEnter?: ( item: MenuItem, event: React.MouseEvent ) => void + /** Called when the user's pointer device leaves the list item */ readonly onMouseLeave?: ( item: MenuItem, event: React.MouseEvent ) => void + /** Called when the user's pointer device clicks on the list item */ readonly onClick?: ( item: MenuItem, event: React.MouseEvent ) => void + /** + * Whether the liste item should steal focus when selected. Defaults to + * false. + */ readonly focusOnSelection?: boolean } diff --git a/app/src/ui/app-menu/menu-pane.tsx b/app/src/ui/app-menu/menu-pane.tsx index 849147a723..890ab2f01b 100644 --- a/app/src/ui/app-menu/menu-pane.tsx +++ b/app/src/ui/app-menu/menu-pane.tsx @@ -56,9 +56,9 @@ interface IMenuPaneProps { ) => void /** - * A callback for when a keyboard key is pressed on a menu item. Note that - * this only picks up on keyboard events received by a MenuItem and does - * not cover keyboard events received on the MenuPane component itself. + * Called when the user presses down on a key while focused on, or within, the + * menu pane. Consumers should inspect isDefaultPrevented to determine whether + * the event was handled by the menu pane or not. */ readonly onKeyDown?: ( depth: number, @@ -84,6 +84,10 @@ interface IMenuPaneProps { */ readonly enableAccessKeyNavigation: boolean + /** + * Called to deselect the currently selected menu item (if any). This + * will be called when the user's pointer device leaves a menu item. + */ readonly onClearSelection: (depth: number) => void } From b91dcbb99b4b49627d6be414015a29544713cb34 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 18:03:42 +0200 Subject: [PATCH 011/111] Keep track of selected row range --- app/src/ui/diff/side-by-side-diff.tsx | 81 ++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 459cb66784..199ec71a2d 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -75,6 +75,21 @@ export interface ISelection { type ModifiedLine = { line: DiffLine; diffLineNumber: number } +const isElement = (n: Node): n is Element => n.nodeType === Node.ELEMENT_NODE +const closestElement = (n: Node): Element | null => + isElement(n) ? n : n.parentElement + +const closestRow = (n: Node) => { + const row = closestElement(n)?.closest('div[role=row]') + if (row && container.contains(row)) { + const rowIndex = + row.ariaRowIndex !== null ? parseInt(row.ariaRowIndex, 10) : NaN + return isNaN(rowIndex) ? undefined : rowIndex + } + + return undefined +} + interface ISideBySideDiffProps { readonly repository: Repository @@ -194,10 +209,14 @@ export class SideBySideDiff extends React.Component< ISideBySideDiffState > { private virtualListRef = React.createRef() + private diffContainerRef = React.createRef() /** Diff to restore when "Collapse all expanded lines" option is used */ private diffToRestore: ITextDiff | null = null + private textSelection: { startRow: number; endRow: number } | undefined = + undefined + public constructor(props: ISideBySideDiffProps) { super(props) @@ -216,12 +235,67 @@ export class SideBySideDiff extends React.Component< // Listen for the custom event find-text (see app.tsx) // and trigger the search plugin if we see it. document.addEventListener('find-text', this.showSearch) + + document.addEventListener('selectionchange', this.onDocumentSelectionChange) + } + + private onDocumentSelectionChange = (ev: Event) => { + const selection = document.getSelection() + + const currentTextSelection = this.textSelection + this.textSelection = undefined + + if (!selection || selection.isCollapsed) { + console.log('no selection or collapsed') + return + } + + const { anchorNode, focusNode } = selection + const container = this.diffContainerRef.current + + if (!anchorNode || !focusNode || !container) { + console.log('missing container, anchor of focus') + return + } + + if (!container.contains(anchorNode) || !container.contains(focusNode)) { + console.log('anchor of focus not inside container') + return + } + + const anchorRowIndex = closestRow(anchorNode) + const focusRowIndex = closestRow(focusNode) + + if (anchorRowIndex === undefined || focusRowIndex === undefined) { + console.log('failed to resolve row indices') + return + } + + const newTextSelection = { + startRow: Math.min(anchorRowIndex, focusRowIndex), + endRow: Math.max(anchorRowIndex, focusRowIndex), + } + + if ( + newTextSelection.startRow === currentTextSelection?.startRow && + newTextSelection.endRow === currentTextSelection?.endRow + ) { + this.textSelection = currentTextSelection + return + } else { + this.textSelection = newTextSelection + console.log(this.textSelection) + } } public componentWillUnmount() { window.removeEventListener('keydown', this.onWindowKeyDown) document.removeEventListener('mouseup', this.onEndSelection) document.removeEventListener('find-text', this.showSearch) + document.removeEventListener( + 'selectionchange', + this.onDocumentSelectionChange + ) } public componentDidUpdate( @@ -285,7 +359,10 @@ export class SideBySideDiff extends React.Component< onClose={this.onSearchCancel} /> )} -
+
{({ height, width }) => ( -
+
Date: Tue, 16 Aug 2022 18:21:32 +0200 Subject: [PATCH 012/111] Whoops --- app/src/ui/diff/side-by-side-diff.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 199ec71a2d..cd3084840c 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -79,7 +79,7 @@ const isElement = (n: Node): n is Element => n.nodeType === Node.ELEMENT_NODE const closestElement = (n: Node): Element | null => isElement(n) ? n : n.parentElement -const closestRow = (n: Node) => { +const closestRow = (n: Node, container: Element) => { const row = closestElement(n)?.closest('div[role=row]') if (row && container.contains(row)) { const rowIndex = @@ -263,8 +263,8 @@ export class SideBySideDiff extends React.Component< return } - const anchorRowIndex = closestRow(anchorNode) - const focusRowIndex = closestRow(focusNode) + const anchorRowIndex = closestRow(anchorNode, container) + const focusRowIndex = closestRow(focusNode, container) if (anchorRowIndex === undefined || focusRowIndex === undefined) { console.log('failed to resolve row indices') From 32b02cec9b80b3d100848d8d0a313d4f160b502f Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 18:22:08 +0200 Subject: [PATCH 013/111] First naive take on expanding overscan to encompass selection --- app/src/ui/diff/side-by-side-diff.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index cd3084840c..0c89287bed 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -26,6 +26,9 @@ import { CellMeasurerCache, CellMeasurer, ListRowProps, + OverscanIndicesGetterParams, + OverscanIndices, + defaultOverscanIndicesGetter, } from 'react-virtualized' import { SideBySideDiffRow } from './side-by-side-diff-row' import memoize from 'memoize-one' @@ -386,6 +389,7 @@ export class SideBySideDiff extends React.Component< hoveredHunk={this.state.hoveredHunk} isSelectable={canSelect(this.props.file)} fileSelection={this.getSelection()} + overscanIndicesGetter={this.overscanIndicesGetter} /> )} @@ -394,6 +398,16 @@ export class SideBySideDiff extends React.Component< ) } + private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { + return this.textSelection === undefined + ? defaultOverscanIndicesGetter(params) + : defaultOverscanIndicesGetter({ + ...params, + startIndex: Math.min(params.startIndex, this.textSelection.startRow), + stopIndex: Math.max(params.stopIndex, this.textSelection.endRow), + }) + } + private renderRow = ({ index, parent, style, key }: ListRowProps) => { const { diff } = this.state const rows = getDiffRows( From 1937470aff47b7dfb4aa83f232681a080e92120c Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 18:23:45 +0200 Subject: [PATCH 014/111] tidy up --- app/src/ui/diff/side-by-side-diff.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 0c89287bed..2115d6426f 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -27,7 +27,6 @@ import { CellMeasurer, ListRowProps, OverscanIndicesGetterParams, - OverscanIndices, defaultOverscanIndicesGetter, } from 'react-virtualized' import { SideBySideDiffRow } from './side-by-side-diff-row' From da60650ba7d525ebfc2ace25a922298e4ee57bf9 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 21:06:33 +0200 Subject: [PATCH 015/111] Selection in both directions --- app/src/ui/diff/side-by-side-diff.tsx | 65 ++++++++++++++------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 2115d6426f..ceadfaab48 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -216,8 +216,8 @@ export class SideBySideDiff extends React.Component< /** Diff to restore when "Collapse all expanded lines" option is used */ private diffToRestore: ITextDiff | null = null - private textSelection: { startRow: number; endRow: number } | undefined = - undefined + private textSelectionAnchorRow: number | undefined = undefined + private textSelectionFocusRow: number | undefined = undefined public constructor(props: ISideBySideDiffProps) { super(props) @@ -244,8 +244,8 @@ export class SideBySideDiff extends React.Component< private onDocumentSelectionChange = (ev: Event) => { const selection = document.getSelection() - const currentTextSelection = this.textSelection - this.textSelection = undefined + this.textSelectionAnchorRow = undefined + this.textSelectionFocusRow = undefined if (!selection || selection.isCollapsed) { console.log('no selection or collapsed') @@ -255,39 +255,27 @@ export class SideBySideDiff extends React.Component< const { anchorNode, focusNode } = selection const container = this.diffContainerRef.current - if (!anchorNode || !focusNode || !container) { - console.log('missing container, anchor of focus') + if (!anchorNode || !container) { + console.log('missing container or anchor') return } - if (!container.contains(anchorNode) || !container.contains(focusNode)) { + if (!container.contains(anchorNode)) { console.log('anchor of focus not inside container') return } - const anchorRowIndex = closestRow(anchorNode, container) - const focusRowIndex = closestRow(focusNode, container) + const newAnchorRow = closestRow(anchorNode, container) - if (anchorRowIndex === undefined || focusRowIndex === undefined) { + if (newAnchorRow === undefined) { console.log('failed to resolve row indices') return } - const newTextSelection = { - startRow: Math.min(anchorRowIndex, focusRowIndex), - endRow: Math.max(anchorRowIndex, focusRowIndex), - } - - if ( - newTextSelection.startRow === currentTextSelection?.startRow && - newTextSelection.endRow === currentTextSelection?.endRow - ) { - this.textSelection = currentTextSelection - return - } else { - this.textSelection = newTextSelection - console.log(this.textSelection) - } + this.textSelectionAnchorRow = newAnchorRow + this.textSelectionFocusRow = focusNode + ? closestRow(focusNode, container) + : undefined } public componentWillUnmount() { @@ -398,13 +386,26 @@ export class SideBySideDiff extends React.Component< } private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { - return this.textSelection === undefined - ? defaultOverscanIndicesGetter(params) - : defaultOverscanIndicesGetter({ - ...params, - startIndex: Math.min(params.startIndex, this.textSelection.startRow), - stopIndex: Math.max(params.stopIndex, this.textSelection.endRow), - }) + console.log(params.startIndex, params.stopIndex) + + if (this.textSelectionAnchorRow === undefined) { + return defaultOverscanIndicesGetter(params) + } + + const textSelectionStart = + this.textSelectionFocusRow === undefined + ? this.textSelectionAnchorRow + : Math.min(this.textSelectionAnchorRow, this.textSelectionFocusRow) + + const textSelectionEnd = + this.textSelectionFocusRow === undefined + ? undefined + : Math.max(this.textSelectionAnchorRow, this.textSelectionFocusRow) + + const startIndex = Math.min(textSelectionStart, params.startIndex) + const stopIndex = Math.max(params.stopIndex, textSelectionEnd ?? -Infinity) + + return defaultOverscanIndicesGetter({ ...params, startIndex, stopIndex }) } private renderRow = ({ index, parent, style, key }: ListRowProps) => { From 1525d9c74a876c113a4e9fe411010aacbd75ac2e Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 22:53:02 +0200 Subject: [PATCH 016/111] Another hot take on this Trying to sort out when either the anchor or the focus node (or both) are outside of the diff (i.e. the whole or at least parts of the diff are selected) --- app/src/ui/diff/side-by-side-diff.tsx | 66 +++++++++++++++++++++------ 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index ceadfaab48..b0b44362a2 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -252,30 +252,66 @@ export class SideBySideDiff extends React.Component< return } - const { anchorNode, focusNode } = selection const container = this.diffContainerRef.current - if (!anchorNode || !container) { - console.log('missing container or anchor') + if (!container) { return } - if (!container.contains(anchorNode)) { - console.log('anchor of focus not inside container') + if (!selection.containsNode(container, true)) { + console.log('no selection within container') return } - const newAnchorRow = closestRow(anchorNode, container) + const range = selection.getRangeAt(0) - if (newAnchorRow === undefined) { - console.log('failed to resolve row indices') - return + const { startContainer, endContainer } = range + + let startRow = closestRow(startContainer, container) + let endRow = closestRow(endContainer, container) + + if (startRow === undefined) { + const firstRow = container.querySelector('div[role=row]:first-child') + + if (firstRow && range.intersectsNode(firstRow)) { + startRow = closestRow(firstRow, container) + } } - this.textSelectionAnchorRow = newAnchorRow - this.textSelectionFocusRow = focusNode - ? closestRow(focusNode, container) - : undefined + if (endRow === undefined) { + const lastRow = container.querySelector('div[role=row]:last-child') + + if (lastRow && range.intersectsNode(lastRow)) { + endRow = closestRow(lastRow, container) + } + } + + this.textSelectionAnchorRow = startRow + this.textSelectionFocusRow = endRow + + console.log(startRow, endRow) + + // const { anchorNode, focusNode } = selection + + // let newAnchorRow = + // anchorNode !== null && container.contains(anchorNode) + // ? closestRow(anchorNode, container) + // : undefined + + // let newFocusRow = + // (focusNode !== null) & container.contains(focusNode) + // ? closestRow(focusNode, container) + // : undefined + + // if (newAnchorRow === undefined) { + // console.log('failed to resolve row indices') + // return + // } + + // this.textSelectionAnchorRow = newAnchorRow + // this.textSelectionFocusRow = focusNode + // ? closestRow(focusNode, container) + // : undefined } public componentWillUnmount() { @@ -386,12 +422,12 @@ export class SideBySideDiff extends React.Component< } private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { - console.log(params.startIndex, params.stopIndex) - if (this.textSelectionAnchorRow === undefined) { return defaultOverscanIndicesGetter(params) } + console.log(params) + const textSelectionStart = this.textSelectionFocusRow === undefined ? this.textSelectionAnchorRow From a46ce081ebb6dfd83603d629c06cec45902c7aab Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 22:54:47 +0200 Subject: [PATCH 017/111] Well at least this got a bit easier --- app/src/ui/diff/side-by-side-diff.tsx | 31 ++++++++------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index b0b44362a2..1961d810c0 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -216,8 +216,8 @@ export class SideBySideDiff extends React.Component< /** Diff to restore when "Collapse all expanded lines" option is used */ private diffToRestore: ITextDiff | null = null - private textSelectionAnchorRow: number | undefined = undefined - private textSelectionFocusRow: number | undefined = undefined + private textSelectionStartRow: number | undefined = undefined + private textSelectionEndRow: number | undefined = undefined public constructor(props: ISideBySideDiffProps) { super(props) @@ -244,8 +244,8 @@ export class SideBySideDiff extends React.Component< private onDocumentSelectionChange = (ev: Event) => { const selection = document.getSelection() - this.textSelectionAnchorRow = undefined - this.textSelectionFocusRow = undefined + this.textSelectionStartRow = undefined + this.textSelectionEndRow = undefined if (!selection || selection.isCollapsed) { console.log('no selection or collapsed') @@ -264,7 +264,6 @@ export class SideBySideDiff extends React.Component< } const range = selection.getRangeAt(0) - const { startContainer, endContainer } = range let startRow = closestRow(startContainer, container) @@ -286,8 +285,8 @@ export class SideBySideDiff extends React.Component< } } - this.textSelectionAnchorRow = startRow - this.textSelectionFocusRow = endRow + this.textSelectionStartRow = startRow + this.textSelectionEndRow = endRow console.log(startRow, endRow) @@ -422,24 +421,12 @@ export class SideBySideDiff extends React.Component< } private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { - if (this.textSelectionAnchorRow === undefined) { + if (this.textSelectionStartRow === undefined) { return defaultOverscanIndicesGetter(params) } - console.log(params) - - const textSelectionStart = - this.textSelectionFocusRow === undefined - ? this.textSelectionAnchorRow - : Math.min(this.textSelectionAnchorRow, this.textSelectionFocusRow) - - const textSelectionEnd = - this.textSelectionFocusRow === undefined - ? undefined - : Math.max(this.textSelectionAnchorRow, this.textSelectionFocusRow) - - const startIndex = Math.min(textSelectionStart, params.startIndex) - const stopIndex = Math.max(params.stopIndex, textSelectionEnd ?? -Infinity) + const startIndex = Math.min(this.textSelectionStartRow, params.startIndex) + const stopIndex = Math.max(params.stopIndex, this.textSelectionEndRow ?? 0) return defaultOverscanIndicesGetter({ ...params, startIndex, stopIndex }) } From abd6730649e66b2c5e824b5a5948755187101252 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 22:57:12 +0200 Subject: [PATCH 018/111] :art: cleanup --- app/src/ui/diff/side-by-side-diff.tsx | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 1961d810c0..240d4763f2 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -289,28 +289,6 @@ export class SideBySideDiff extends React.Component< this.textSelectionEndRow = endRow console.log(startRow, endRow) - - // const { anchorNode, focusNode } = selection - - // let newAnchorRow = - // anchorNode !== null && container.contains(anchorNode) - // ? closestRow(anchorNode, container) - // : undefined - - // let newFocusRow = - // (focusNode !== null) & container.contains(focusNode) - // ? closestRow(focusNode, container) - // : undefined - - // if (newAnchorRow === undefined) { - // console.log('failed to resolve row indices') - // return - // } - - // this.textSelectionAnchorRow = newAnchorRow - // this.textSelectionFocusRow = focusNode - // ? closestRow(focusNode, container) - // : undefined } public componentWillUnmount() { @@ -421,7 +399,10 @@ export class SideBySideDiff extends React.Component< } private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { - if (this.textSelectionStartRow === undefined) { + if ( + this.textSelectionStartRow === undefined || + this.textSelectionEndRow === undefined + ) { return defaultOverscanIndicesGetter(params) } From 539cbf14149cf53da4984ec9ee8e4861a797845a Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 22:59:47 +0200 Subject: [PATCH 019/111] :art: cleanup --- app/src/ui/diff/side-by-side-diff.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 240d4763f2..ec4e82e8f8 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -399,15 +399,10 @@ export class SideBySideDiff extends React.Component< } private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { - if ( - this.textSelectionStartRow === undefined || - this.textSelectionEndRow === undefined - ) { - return defaultOverscanIndicesGetter(params) - } + const [start, end] = [this.textSelectionStartRow, this.textSelectionEndRow] - const startIndex = Math.min(this.textSelectionStartRow, params.startIndex) - const stopIndex = Math.max(params.stopIndex, this.textSelectionEndRow ?? 0) + const startIndex = Math.min(start ?? params.startIndex, params.startIndex) + const stopIndex = Math.max(params.stopIndex, end ?? params.stopIndex) return defaultOverscanIndicesGetter({ ...params, startIndex, stopIndex }) } From 9225a396a37245c0c0b6f59b742d2b432d917e63 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 23:00:22 +0200 Subject: [PATCH 020/111] Eh, this is more readable --- app/src/ui/diff/side-by-side-diff.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index ec4e82e8f8..240dbd9b2c 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -401,8 +401,12 @@ export class SideBySideDiff extends React.Component< private overscanIndicesGetter = (params: OverscanIndicesGetterParams) => { const [start, end] = [this.textSelectionStartRow, this.textSelectionEndRow] - const startIndex = Math.min(start ?? params.startIndex, params.startIndex) - const stopIndex = Math.max(params.stopIndex, end ?? params.stopIndex) + if (start === undefined || end === undefined) { + return defaultOverscanIndicesGetter(params) + } + + const startIndex = Math.min(start, params.startIndex) + const stopIndex = Math.max(params.stopIndex, end) return defaultOverscanIndicesGetter({ ...params, startIndex, stopIndex }) } From 7ad2ba9d490222d75b3c7f3e70741a79ffca9442 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Tue, 16 Aug 2022 23:04:24 +0200 Subject: [PATCH 021/111] Clear selection when switching file --- app/src/ui/diff/side-by-side-diff.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 240dbd9b2c..c254685f33 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -325,6 +325,17 @@ export class SideBySideDiff extends React.Component< this.props.file.id !== prevProps.file.id ) { this.virtualListRef.current.scrollToPosition(0) + + // Reset selection + this.textSelectionStartRow = undefined + this.textSelectionEndRow = undefined + + if (this.diffContainerRef.current) { + const selection = document.getSelection() + if (selection?.containsNode(this.diffContainerRef.current, true)) { + selection.empty() + } + } } } From a7ea4015f0b71f092cec08aabe208505f5dd6ba5 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 17 Aug 2022 08:46:18 +0200 Subject: [PATCH 022/111] Above the invalidation props --- app/src/ui/diff/side-by-side-diff.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index c254685f33..49d9fd5744 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -387,6 +387,7 @@ export class SideBySideDiff extends React.Component< rowHeight={this.getRowHeight} rowRenderer={this.renderRow} ref={this.virtualListRef} + overscanIndicesGetter={this.overscanIndicesGetter} // The following properties are passed to the list // to make sure that it gets re-rendered when any of // them change. @@ -400,7 +401,6 @@ export class SideBySideDiff extends React.Component< hoveredHunk={this.state.hoveredHunk} isSelectable={canSelect(this.props.file)} fileSelection={this.getSelection()} - overscanIndicesGetter={this.overscanIndicesGetter} /> )} From 3c74394776ab5e066ebea3914a9b079d666dbb63 Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 17 Aug 2022 09:59:07 +0200 Subject: [PATCH 023/111] Initial take on select-all --- app/src/ui/diff/side-by-side-diff.tsx | 74 +++++++++++++++++++++------ 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 49d9fd5744..9ce0f86d79 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -211,7 +211,7 @@ export class SideBySideDiff extends React.Component< ISideBySideDiffState > { private virtualListRef = React.createRef() - private diffContainerRef = React.createRef() + private diffContainer: HTMLDivElement | null = null /** Diff to restore when "Collapse all expanded lines" option is used */ private diffToRestore: ITextDiff | null = null @@ -252,13 +252,11 @@ export class SideBySideDiff extends React.Component< return } - const container = this.diffContainerRef.current - - if (!container) { + if (!this.diffContainer) { return } - if (!selection.containsNode(container, true)) { + if (!selection.containsNode(this.diffContainer, true)) { console.log('no selection within container') return } @@ -266,22 +264,26 @@ export class SideBySideDiff extends React.Component< const range = selection.getRangeAt(0) const { startContainer, endContainer } = range - let startRow = closestRow(startContainer, container) - let endRow = closestRow(endContainer, container) + let startRow = closestRow(startContainer, this.diffContainer) + let endRow = closestRow(endContainer, this.diffContainer) if (startRow === undefined) { - const firstRow = container.querySelector('div[role=row]:first-child') + const firstRow = this.diffContainer.querySelector( + 'div[role=row]:first-child' + ) if (firstRow && range.intersectsNode(firstRow)) { - startRow = closestRow(firstRow, container) + startRow = closestRow(firstRow, this.diffContainer) } } if (endRow === undefined) { - const lastRow = container.querySelector('div[role=row]:last-child') + const lastRow = this.diffContainer.querySelector( + 'div[role=row]:last-child' + ) if (lastRow && range.intersectsNode(lastRow)) { - endRow = closestRow(lastRow, container) + endRow = closestRow(lastRow, this.diffContainer) } } @@ -330,9 +332,9 @@ export class SideBySideDiff extends React.Component< this.textSelectionStartRow = undefined this.textSelectionEndRow = undefined - if (this.diffContainerRef.current) { + if (this.diffContainer) { const selection = document.getSelection() - if (selection?.containsNode(this.diffContainerRef.current, true)) { + if (selection?.containsNode(this.diffContainer, true)) { selection.empty() } } @@ -348,6 +350,15 @@ export class SideBySideDiff extends React.Component< ) } + private onDiffContainerRef = (ref: HTMLDivElement | null) => { + if (ref === null) { + this.diffContainer?.removeEventListener('select-all', this.onSelectAll) + } else { + this.diffContainer = ref + this.diffContainer.addEventListener('select-all', this.onSelectAll) + } + } + public render() { const { diff } = this.state @@ -365,7 +376,11 @@ export class SideBySideDiff extends React.Component< }) return ( -
+
{diff.hasHiddenBidiChars && } {this.state.isSearching && ( {({ height, width }) => ( @@ -417,7 +432,10 @@ export class SideBySideDiff extends React.Component< } const startIndex = Math.min(start, params.startIndex) - const stopIndex = Math.max(params.stopIndex, end) + const stopIndex = Math.max( + params.stopIndex, + Math.min(params.cellCount - 1, end) + ) return defaultOverscanIndicesGetter({ ...params, startIndex, stopIndex }) } @@ -740,6 +758,30 @@ export class SideBySideDiff extends React.Component< } } + private onKeyDown = (event: React.KeyboardEvent) => { + const modifiers = event.altKey || event.metaKey || event.shiftKey + + if (!__DARWIN__ && event.key === 'a' && event.ctrlKey && !modifiers) { + this.onSelectAll(event) + } + } + + private onSelectAll = (ev: Event | React.SyntheticEvent) => { + ev.preventDefault() + + this.textSelectionStartRow = 0 + this.textSelectionEndRow = Infinity + + this.virtualListRef.current?.forceUpdate(() => { + console.log('selecting all') + const selection = document.getSelection() + if (selection && this.diffContainer) { + selection.empty() + selection.selectAllChildren(this.diffContainer) + } + }) + } + private onStartSelection = ( row: number, column: DiffColumn, From 516383ca7130ed1256e84d1e8cd7d907a38da18b Mon Sep 17 00:00:00 2001 From: Markus Olsson Date: Wed, 17 Aug 2022 10:19:35 +0200 Subject: [PATCH 024/111] :art: :book: cleanup --- app/src/ui/diff/side-by-side-diff.tsx | 39 ++++++++++++++++++++------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/app/src/ui/diff/side-by-side-diff.tsx b/app/src/ui/diff/side-by-side-diff.tsx index 9ce0f86d79..ffc63b056f 100644 --- a/app/src/ui/diff/side-by-side-diff.tsx +++ b/app/src/ui/diff/side-by-side-diff.tsx @@ -242,31 +242,43 @@ export class SideBySideDiff extends React.Component< } private onDocumentSelectionChange = (ev: Event) => { + if (!this.diffContainer) { + return + } + const selection = document.getSelection() this.textSelectionStartRow = undefined this.textSelectionEndRow = undefined if (!selection || selection.isCollapsed) { - console.log('no selection or collapsed') - return - } - - if (!this.diffContainer) { return } + // Check to see if there's at least a partial selection within the + // diff container. If there isn't then we want to get out of here as + // quickly as possible. if (!selection.containsNode(this.diffContainer, true)) { - console.log('no selection within container') return } + // Get the range to coerce uniform direction (i.e we don't want to have to + // care about whether the user is selecting right to left or left to right) const range = selection.getRangeAt(0) const { startContainer, endContainer } = range + // The (relative) happy path is when the user is currently selecting within + // the diff. That means that the start container will very likely be a text + // node somewhere within a row. let startRow = closestRow(startContainer, this.diffContainer) - let endRow = closestRow(endContainer, this.diffContainer) + // If we couldn't find the row by walking upwards it's likely that the user + // has moved their selection to the container itself or beyond (i.e dragged + // their selection all the way up to the point where they're now selecting + // inside the commit details). + // + // If so we attempt to check if the first row we're currently rendering is + // encompassed in the selection if (startRow === undefined) { const firstRow = this.diffContainer.querySelector( 'div[role=row]:first-child' @@ -277,6 +289,14 @@ export class SideBySideDiff extends React.Component< } } + // If we don't have starting row there's no point in us trying to find + // the end row. + if (startRow === undefined) { + return + } + + let endRow = closestRow(endContainer, this.diffContainer) + if (endRow === undefined) { const lastRow = this.diffContainer.querySelector( 'div[role=row]:last-child' @@ -289,8 +309,6 @@ export class SideBySideDiff extends React.Component< this.textSelectionStartRow = startRow this.textSelectionEndRow = endRow - - console.log(startRow, endRow) } public componentWillUnmount() { @@ -769,11 +787,12 @@ export class SideBySideDiff extends React.Component< private onSelectAll = (ev: Event | React.SyntheticEvent) => { ev.preventDefault() + // Expand the overscan to infinity (i.e. render it all) before selecting + // all of the diff contents. this.textSelectionStartRow = 0 this.textSelectionEndRow = Infinity this.virtualListRef.current?.forceUpdate(() => { - console.log('selecting all') const selection = document.getSelection() if (selection && this.diffContainer) { selection.empty() From 96855abde690bd9f791fd7b209a365bc3f507e6e Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 13 Jul 2022 16:19:57 +0200 Subject: [PATCH 025/111] WIP --- app/src/lib/git/status.ts | 34 ++++++++--- app/src/lib/status-parser.ts | 108 ++++++++++++++++++++++++++--------- app/src/models/status.ts | 28 ++++++++- 3 files changed, 135 insertions(+), 35 deletions(-) diff --git a/app/src/lib/git/status.ts b/app/src/lib/git/status.ts index b5008a8537..a2ca5164e3 100644 --- a/app/src/lib/git/status.ts +++ b/app/src/lib/git/status.ts @@ -140,18 +140,38 @@ function convertToAppStatus( if (entry.kind === 'ordinary') { switch (entry.type) { case 'added': - return { kind: AppFileStatusKind.New } + return { + kind: AppFileStatusKind.New, + submoduleStatus: entry.submoduleStatus ?? null, + } case 'modified': - return { kind: AppFileStatusKind.Modified } + return { + kind: AppFileStatusKind.Modified, + submoduleStatus: entry.submoduleStatus ?? null, + } case 'deleted': - return { kind: AppFileStatusKind.Deleted } + return { + kind: AppFileStatusKind.Deleted, + submoduleStatus: entry.submoduleStatus ?? null, + } } } else if (entry.kind === 'copied' && oldPath != null) { - return { kind: AppFileStatusKind.Copied, oldPath } + return { + kind: AppFileStatusKind.Copied, + oldPath, + submoduleStatus: entry.submoduleStatus ?? null, + } } else if (entry.kind === 'renamed' && oldPath != null) { - return { kind: AppFileStatusKind.Renamed, oldPath } + return { + kind: AppFileStatusKind.Renamed, + oldPath, + submoduleStatus: entry.submoduleStatus ?? null, + } } else if (entry.kind === 'untracked') { - return { kind: AppFileStatusKind.Untracked } + return { + kind: AppFileStatusKind.Untracked, + submoduleStatus: entry.submoduleStatus ?? null, + } } else if (entry.kind === 'conflicted') { return parseConflictedState(entry, path, conflictDetails) } @@ -270,7 +290,7 @@ function buildStatusMap( entry: IStatusEntry, conflictDetails: ConflictFilesDetails ): Map { - const status = mapStatus(entry.statusCode) + const status = mapStatus(entry.statusCode, entry.submoduleStatusCode) if (status.kind === 'ordinary') { // when a file is added in the index but then removed in the working diff --git a/app/src/lib/status-parser.ts b/app/src/lib/status-parser.ts index c642e97fec..5145921500 100644 --- a/app/src/lib/status-parser.ts +++ b/app/src/lib/status-parser.ts @@ -1,6 +1,7 @@ import { FileEntry, GitStatusEntry, + SubmoduleStatus, UnmergedEntrySummary, } from '../models/status' @@ -21,6 +22,9 @@ export interface IStatusEntry { /** The two character long status code */ readonly statusCode: string + /** The four character long submodule status code */ + readonly submoduleStatusCode: string + /** The original path in the case of a renamed file */ readonly oldPath?: string } @@ -102,7 +106,12 @@ function parseChangedEntry(field: string): IStatusEntry { throw new Error(`Failed to parse status line for changed entry`) } - return { kind: 'entry', statusCode: match[1], path: match[8] } + return { + kind: 'entry', + statusCode: match[1], + submoduleStatusCode: match[2], + path: match[8], + } } // 2 @@ -126,7 +135,13 @@ function parsedRenamedOrCopiedEntry( ) } - return { kind: 'entry', statusCode: match[1], oldPath, path: match[9] } + return { + kind: 'entry', + statusCode: match[1], + submoduleStatusCode: match[2], + oldPath, + path: match[9], + } } // u

@@ -144,6 +159,7 @@ function parseUnmergedEntry(field: string): IStatusEntry { return { kind: 'entry', statusCode: match[1], + submoduleStatusCode: match[2], path: match[10], } } @@ -155,97 +171,126 @@ function parseUntrackedEntry(field: string): IStatusEntry { // NOTE: We return ?? instead of ? here to play nice with mapStatus, // might want to consider changing this (and mapStatus) in the future. statusCode: '??', + submoduleStatusCode: '????', path, } } +function mapSubmoduleStatus( + submoduleStatusCode: string +): SubmoduleStatus | undefined { + if (!submoduleStatusCode.startsWith('S')) { + return undefined + } + + return { + commitChanged: submoduleStatusCode[1] === 'C', + modifiedChanges: submoduleStatusCode[2] === 'M', + untrackedChanges: submoduleStatusCode[3] === 'U', + } +} + /** * Map the raw status text from Git to a structure we can work with in the app. */ -export function mapStatus(status: string): FileEntry { - if (status === '??') { - return { kind: 'untracked' } +export function mapStatus( + statusCode: string, + submoduleStatusCode: string +): FileEntry { + const submoduleStatus = mapSubmoduleStatus(submoduleStatusCode) + + if (statusCode === '??') { + return { kind: 'untracked', submoduleStatus } } - if (status === '.M') { + if (statusCode === '.M') { return { kind: 'ordinary', type: 'modified', index: GitStatusEntry.Unchanged, workingTree: GitStatusEntry.Modified, + submoduleStatus, } } - if (status === 'M.') { + if (statusCode === 'M.') { return { kind: 'ordinary', type: 'modified', index: GitStatusEntry.Modified, workingTree: GitStatusEntry.Unchanged, + submoduleStatus, } } - if (status === '.A') { + if (statusCode === '.A') { return { kind: 'ordinary', type: 'added', index: GitStatusEntry.Unchanged, workingTree: GitStatusEntry.Added, + submoduleStatus, } } - if (status === 'A.') { + if (statusCode === 'A.') { return { kind: 'ordinary', type: 'added', index: GitStatusEntry.Added, workingTree: GitStatusEntry.Unchanged, + submoduleStatus, } } - if (status === '.D') { + if (statusCode === '.D') { return { kind: 'ordinary', type: 'deleted', index: GitStatusEntry.Unchanged, workingTree: GitStatusEntry.Deleted, + submoduleStatus, } } - if (status === 'D.') { + if (statusCode === 'D.') { return { kind: 'ordinary', type: 'deleted', index: GitStatusEntry.Deleted, workingTree: GitStatusEntry.Unchanged, + submoduleStatus, } } - if (status === 'R.') { + if (statusCode === 'R.') { return { kind: 'renamed', index: GitStatusEntry.Renamed, workingTree: GitStatusEntry.Unchanged, + submoduleStatus, } } - if (status === '.R') { + if (statusCode === '.R') { return { kind: 'renamed', index: GitStatusEntry.Unchanged, workingTree: GitStatusEntry.Renamed, + submoduleStatus, } } - if (status === 'C.') { + if (statusCode === 'C.') { return { kind: 'copied', index: GitStatusEntry.Copied, workingTree: GitStatusEntry.Unchanged, + submoduleStatus, } } - if (status === '.C') { + if (statusCode === '.C') { return { kind: 'copied', index: GitStatusEntry.Unchanged, @@ -253,100 +298,111 @@ export function mapStatus(status: string): FileEntry { } } - if (status === 'AD') { + if (statusCode === 'AD') { return { kind: 'ordinary', type: 'added', index: GitStatusEntry.Added, workingTree: GitStatusEntry.Deleted, + submoduleStatus, } } - if (status === 'AM') { + if (statusCode === 'AM') { return { kind: 'ordinary', type: 'added', index: GitStatusEntry.Added, workingTree: GitStatusEntry.Modified, + submoduleStatus, } } - if (status === 'RM') { + if (statusCode === 'RM') { return { kind: 'renamed', index: GitStatusEntry.Renamed, workingTree: GitStatusEntry.Modified, + submoduleStatus, } } - if (status === 'RD') { + if (statusCode === 'RD') { return { kind: 'renamed', index: GitStatusEntry.Renamed, workingTree: GitStatusEntry.Deleted, + submoduleStatus, } } - if (status === 'DD') { + if (statusCode === 'DD') { return { kind: 'conflicted', action: UnmergedEntrySummary.BothDeleted, us: GitStatusEntry.Deleted, them: GitStatusEntry.Deleted, + submoduleStatus, } } - if (status === 'AU') { + if (statusCode === 'AU') { return { kind: 'conflicted', action: UnmergedEntrySummary.AddedByUs, us: GitStatusEntry.Added, them: GitStatusEntry.UpdatedButUnmerged, + submoduleStatus, } } - if (status === 'UD') { + if (statusCode === 'UD') { return { kind: 'conflicted', action: UnmergedEntrySummary.DeletedByThem, us: GitStatusEntry.UpdatedButUnmerged, them: GitStatusEntry.Deleted, + submoduleStatus, } } - if (status === 'UA') { + if (statusCode === 'UA') { return { kind: 'conflicted', action: UnmergedEntrySummary.AddedByThem, us: GitStatusEntry.UpdatedButUnmerged, them: GitStatusEntry.Added, + submoduleStatus, } } - if (status === 'DU') { + if (statusCode === 'DU') { return { kind: 'conflicted', action: UnmergedEntrySummary.DeletedByUs, us: GitStatusEntry.Deleted, them: GitStatusEntry.UpdatedButUnmerged, + submoduleStatus, } } - if (status === 'AA') { + if (statusCode === 'AA') { return { kind: 'conflicted', action: UnmergedEntrySummary.BothAdded, us: GitStatusEntry.Added, them: GitStatusEntry.Added, + submoduleStatus, } } - if (status === 'UU') { + if (statusCode === 'UU') { return { kind: 'conflicted', action: UnmergedEntrySummary.BothModified, us: GitStatusEntry.UpdatedButUnmerged, them: GitStatusEntry.UpdatedButUnmerged, + submoduleStatus, } } diff --git a/app/src/models/status.ts b/app/src/models/status.ts index 4189fb6994..afd2561c19 100644 --- a/app/src/models/status.ts +++ b/app/src/models/status.ts @@ -34,6 +34,7 @@ export type PlainFileStatus = { | AppFileStatusKind.New | AppFileStatusKind.Modified | AppFileStatusKind.Deleted + submoduleStatus: SubmoduleStatus | null } /** @@ -46,6 +47,7 @@ export type PlainFileStatus = { export type CopiedOrRenamedFileStatus = { kind: AppFileStatusKind.Copied | AppFileStatusKind.Renamed oldPath: string + submoduleStatus: SubmoduleStatus | null } /** @@ -56,6 +58,7 @@ export type ConflictsWithMarkers = { kind: AppFileStatusKind.Conflicted entry: TextConflictEntry conflictMarkerCount: number + submoduleStatus: SubmoduleStatus | null } /** @@ -65,6 +68,7 @@ export type ConflictsWithMarkers = { export type ManualConflict = { kind: AppFileStatusKind.Conflicted entry: ManualConflictEntry + submoduleStatus: SubmoduleStatus | null } /** Union of potential conflict scenarios the application should handle */ @@ -92,14 +96,26 @@ export function isManualConflict( } /** Denotes an untracked file in the working directory) */ -export type UntrackedFileStatus = { kind: AppFileStatusKind.Untracked } +export type UntrackedFileStatus = { + kind: AppFileStatusKind.Untracked + submoduleStatus: SubmoduleStatus | null +} /** The union of potential states associated with a file change in Desktop */ -export type AppFileStatus = +export type AppFileStatus = { + submoduleStatus: SubmoduleStatus | null +} & ( | PlainFileStatus | CopiedOrRenamedFileStatus | ConflictedFileStatus | UntrackedFileStatus +) + +export type SubmoduleStatus = { + readonly commitChanged: boolean + readonly modifiedChanges: boolean + readonly untrackedChanges: boolean +} /** The porcelain status for an ordinary changed entry */ type OrdinaryEntry = { @@ -110,6 +126,8 @@ type OrdinaryEntry = { readonly index?: GitStatusEntry /** the status of the working tree for this entry (if known) */ readonly workingTree?: GitStatusEntry + /** the submodule status for this entry */ + readonly submoduleStatus?: SubmoduleStatus } /** The porcelain status for a renamed or copied entry */ @@ -119,6 +137,8 @@ type RenamedOrCopiedEntry = { readonly index?: GitStatusEntry /** the status of the working tree for this entry (if known) */ readonly workingTree?: GitStatusEntry + /** the submodule status for this entry */ + readonly submoduleStatus?: SubmoduleStatus } export enum UnmergedEntrySummary { @@ -194,6 +214,8 @@ type ManualConflictDetails = type ManualConflictEntry = { readonly kind: 'conflicted' + /** the submodule status for this entry */ + readonly submoduleStatus?: SubmoduleStatus } & ManualConflictDetails /** The porcelain status for an unmerged entry */ @@ -202,6 +224,8 @@ export type UnmergedEntry = TextConflictEntry | ManualConflictEntry /** The porcelain status for an unmerged entry */ type UntrackedEntry = { readonly kind: 'untracked' + /** the submodule status for this entry */ + readonly submoduleStatus?: SubmoduleStatus } /** The union of possible entries from the git status */ From f3fea329f7b8e514f068e832a8ac5d4e0beca3ee Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Mon, 25 Jul 2022 16:22:43 +0200 Subject: [PATCH 026/111] More WIP --- app/src/models/status.ts | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/src/models/status.ts b/app/src/models/status.ts index afd2561c19..4e07d16262 100644 --- a/app/src/models/status.ts +++ b/app/src/models/status.ts @@ -102,14 +102,11 @@ export type UntrackedFileStatus = { } /** The union of potential states associated with a file change in Desktop */ -export type AppFileStatus = { - submoduleStatus: SubmoduleStatus | null -} & ( +export type AppFileStatus = | PlainFileStatus | CopiedOrRenamedFileStatus | ConflictedFileStatus | UntrackedFileStatus -) export type SubmoduleStatus = { readonly commitChanged: boolean @@ -127,7 +124,7 @@ type OrdinaryEntry = { /** the status of the working tree for this entry (if known) */ readonly workingTree?: GitStatusEntry /** the submodule status for this entry */ - readonly submoduleStatus?: SubmoduleStatus + readonly submoduleStatus: SubmoduleStatus | null } /** The porcelain status for a renamed or copied entry */ @@ -138,7 +135,7 @@ type RenamedOrCopiedEntry = { /** the status of the working tree for this entry (if known) */ readonly workingTree?: GitStatusEntry /** the submodule status for this entry */ - readonly submoduleStatus?: SubmoduleStatus + readonly submoduleStatus: SubmoduleStatus | null } export enum UnmergedEntrySummary { @@ -215,7 +212,7 @@ type ManualConflictDetails = type ManualConflictEntry = { readonly kind: 'conflicted' /** the submodule status for this entry */ - readonly submoduleStatus?: SubmoduleStatus + readonly submoduleStatus: SubmoduleStatus | null } & ManualConflictDetails /** The porcelain status for an unmerged entry */ @@ -225,7 +222,7 @@ export type UnmergedEntry = TextConflictEntry | ManualConflictEntry type UntrackedEntry = { readonly kind: 'untracked' /** the submodule status for this entry */ - readonly submoduleStatus?: SubmoduleStatus + readonly submoduleStatus: SubmoduleStatus | null } /** The union of possible entries from the git status */ From 2c9a96f1f63d9fab482854bea168d9f49fdbf25f Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Tue, 26 Jul 2022 11:59:37 +0200 Subject: [PATCH 027/111] And more WIP --- app/src/lib/git/log.ts | 18 ++++++------- app/src/lib/git/status.ts | 10 +++++++- app/src/lib/status-parser.ts | 6 +++-- app/src/models/status.ts | 8 +++++- app/test/unit/git/apply-test.ts | 2 +- app/test/unit/git/commit-test.ts | 14 +++++------ app/test/unit/git/diff-test.ts | 18 ++++++------- app/test/unit/patch-formatter-test.ts | 25 ++++++++++--------- app/test/unit/repository-state-cache-test.ts | 2 +- .../updates/update-changed-files-test.ts | 6 ++--- 10 files changed, 63 insertions(+), 46 deletions(-) diff --git a/app/src/lib/git/log.ts b/app/src/lib/git/log.ts index 80579404ab..22e5aa373d 100644 --- a/app/src/lib/git/log.ts +++ b/app/src/lib/git/log.ts @@ -27,35 +27,35 @@ export function mapStatus( const status = rawStatus.trim() if (status === 'M') { - return { kind: AppFileStatusKind.Modified } + return { kind: AppFileStatusKind.Modified, submoduleStatus: null } } // modified if (status === 'A') { - return { kind: AppFileStatusKind.New } + return { kind: AppFileStatusKind.New, submoduleStatus: null } } // added if (status === '?') { - return { kind: AppFileStatusKind.Untracked } + return { kind: AppFileStatusKind.Untracked, submoduleStatus: null } } // untracked if (status === 'D') { - return { kind: AppFileStatusKind.Deleted } + return { kind: AppFileStatusKind.Deleted, submoduleStatus: null } } // deleted if (status === 'R' && oldPath != null) { - return { kind: AppFileStatusKind.Renamed, oldPath } + return { kind: AppFileStatusKind.Renamed, oldPath, submoduleStatus: null } } // renamed if (status === 'C' && oldPath != null) { - return { kind: AppFileStatusKind.Copied, oldPath } + return { kind: AppFileStatusKind.Copied, oldPath, submoduleStatus: null } } // copied // git log -M --name-status will return a RXXX - where XXX is a percentage if (status.match(/R[0-9]+/) && oldPath != null) { - return { kind: AppFileStatusKind.Renamed, oldPath } + return { kind: AppFileStatusKind.Renamed, oldPath, submoduleStatus: null } } // git log -C --name-status will return a CXXX - where XXX is a percentage if (status.match(/C[0-9]+/) && oldPath != null) { - return { kind: AppFileStatusKind.Copied, oldPath } + return { kind: AppFileStatusKind.Copied, oldPath, submoduleStatus: null } } - return { kind: AppFileStatusKind.Modified } + return { kind: AppFileStatusKind.Modified, submoduleStatus: null } } const isCopyOrRename = ( diff --git a/app/src/lib/git/status.ts b/app/src/lib/git/status.ts index a2ca5164e3..8b28ada797 100644 --- a/app/src/lib/git/status.ts +++ b/app/src/lib/git/status.ts @@ -102,9 +102,14 @@ function parseConflictedState( entry, conflictMarkerCount: conflictDetails.conflictCountsByPath.get(path) || 0, + submoduleStatus: null, } } else { - return { kind: AppFileStatusKind.Conflicted, entry } + return { + kind: AppFileStatusKind.Conflicted, + entry, + submoduleStatus: null, + } } } case UnmergedEntrySummary.BothModified: { @@ -115,11 +120,13 @@ function parseConflictedState( entry, conflictMarkerCount: conflictDetails.conflictCountsByPath.get(path) || 0, + submoduleStatus: null, } } else { return { kind: AppFileStatusKind.Conflicted, entry, + submoduleStatus: null, } } } @@ -127,6 +134,7 @@ function parseConflictedState( return { kind: AppFileStatusKind.Conflicted, entry, + submoduleStatus: null, } } } diff --git a/app/src/lib/status-parser.ts b/app/src/lib/status-parser.ts index 5145921500..2198ef15b5 100644 --- a/app/src/lib/status-parser.ts +++ b/app/src/lib/status-parser.ts @@ -178,9 +178,9 @@ function parseUntrackedEntry(field: string): IStatusEntry { function mapSubmoduleStatus( submoduleStatusCode: string -): SubmoduleStatus | undefined { +): SubmoduleStatus | null { if (!submoduleStatusCode.startsWith('S')) { - return undefined + return null } return { @@ -295,6 +295,7 @@ export function mapStatus( kind: 'copied', index: GitStatusEntry.Unchanged, workingTree: GitStatusEntry.Copied, + submoduleStatus, } } @@ -410,5 +411,6 @@ export function mapStatus( return { kind: 'ordinary', type: 'modified', + submoduleStatus, } } diff --git a/app/src/models/status.ts b/app/src/models/status.ts index 4e07d16262..edbf6f51ae 100644 --- a/app/src/models/status.ts +++ b/app/src/models/status.ts @@ -166,13 +166,18 @@ type TextConflictDetails = type TextConflictEntry = { readonly kind: 'conflicted' + /** the submodule status for this entry */ + readonly submoduleStatus: SubmoduleStatus | null } & TextConflictDetails /** * Valid Git index states where the user needs to choose one of `us` or `them` * in the app. */ -type ManualConflictDetails = +type ManualConflictDetails = { + /** the submodule status for this entry */ + readonly submoduleStatus: SubmoduleStatus | null +} & ( | { readonly action: UnmergedEntrySummary.BothAdded readonly us: GitStatusEntry.Added @@ -208,6 +213,7 @@ type ManualConflictDetails = readonly us: GitStatusEntry.Deleted readonly them: GitStatusEntry.Deleted } +) type ManualConflictEntry = { readonly kind: 'conflicted' diff --git a/app/test/unit/git/apply-test.ts b/app/test/unit/git/apply-test.ts index 34450ded8f..f5b654b12d 100644 --- a/app/test/unit/git/apply-test.ts +++ b/app/test/unit/git/apply-test.ts @@ -76,7 +76,7 @@ describe('git/apply', () => { async function getDiff(filePath: string) { const file = new WorkingDirectoryFileChange( filePath, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, DiffSelection.fromInitialSelection(DiffSelectionType.None) ) return (await getWorkingDirectoryDiff(repository, file)) as ITextDiff diff --git a/app/test/unit/git/commit-test.ts b/app/test/unit/git/commit-test.ts index 16b844a2c2..1890b4eab6 100644 --- a/app/test/unit/git/commit-test.ts +++ b/app/test/unit/git/commit-test.ts @@ -172,7 +172,7 @@ describe('git/commit', () => { const file = new WorkingDirectoryFileChange( newFileName, - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, selection ) @@ -213,7 +213,7 @@ describe('git/commit', () => { ) const file = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -265,7 +265,7 @@ describe('git/commit', () => { ) const modifiedFile = new WorkingDirectoryFileChange( fileName, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -279,7 +279,7 @@ describe('git/commit', () => { const file = new WorkingDirectoryFileChange( fileName, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) @@ -309,7 +309,7 @@ describe('git/commit', () => { ) const file = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -325,7 +325,7 @@ describe('git/commit', () => { const updatedFile = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) @@ -367,7 +367,7 @@ describe('git/commit', () => { const file = new WorkingDirectoryFileChange( deletedFile, - { kind: AppFileStatusKind.Deleted }, + { kind: AppFileStatusKind.Deleted, submoduleStatus: null }, selection ) diff --git a/app/test/unit/git/diff-test.ts b/app/test/unit/git/diff-test.ts index e168655734..0aa98c61bc 100644 --- a/app/test/unit/git/diff-test.ts +++ b/app/test/unit/git/diff-test.ts @@ -52,7 +52,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'new-image.png', - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, diffSelection ) const current = await getWorkingDirectoryImage(repository, file) @@ -67,7 +67,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'modified-image.jpg', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, diffSelection ) const current = await getWorkingDirectoryImage(repository, file) @@ -83,7 +83,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'modified-image.jpg', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, diffSelection ) const current = await getBlobImage(repository, file.path, 'HEAD') @@ -100,7 +100,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'new-animated-image.gif', - { kind: AppFileStatusKind.Deleted }, + { kind: AppFileStatusKind.Deleted, submoduleStatus: null }, diffSelection ) const previous = await getBlobImage(repository, file.path, 'HEAD') @@ -119,7 +119,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'modified-image.jpg', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, diffSelection ) const diff = await getWorkingDirectoryDiff(repository, file) @@ -140,7 +140,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'new-file.md', - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, diffSelection ) const diff = await getTextDiff(repository, file) @@ -161,7 +161,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'new-file.md', - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, diffSelection ) const diff = await getTextDiff(repository, file) @@ -186,7 +186,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'modified-file.md', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, diffSelection ) const diff = await getTextDiff(repository, file) @@ -214,7 +214,7 @@ describe('git/diff', () => { ) const file = new WorkingDirectoryFileChange( 'staged-file.md', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, diffSelection ) const diff = await getTextDiff(repository, file) diff --git a/app/test/unit/patch-formatter-test.ts b/app/test/unit/patch-formatter-test.ts index 14951ba43f..1c8e2dd3f2 100644 --- a/app/test/unit/patch-formatter-test.ts +++ b/app/test/unit/patch-formatter-test.ts @@ -24,6 +24,7 @@ async function parseDiff(diff: string): Promise { const repository = new Repository('', -1, null, false) const fileChange = new FileChange('file.txt', { kind: AppFileStatusKind.Modified, + submoduleStatus: null, }) const output = await convertDiff(repository, fileChange, rawDiff, 'HEAD') expect(output.kind === DiffType.Text) @@ -47,7 +48,7 @@ describe('patch formatting', () => { ) const file = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -68,7 +69,7 @@ describe('patch formatting', () => { const updatedFile = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) @@ -86,7 +87,7 @@ describe('patch formatting', () => { ) const file = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -107,7 +108,7 @@ describe('patch formatting', () => { const updatedFile = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) @@ -126,7 +127,7 @@ describe('patch formatting', () => { ) const file = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -146,7 +147,7 @@ describe('patch formatting', () => { ) const updatedFile = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) @@ -166,7 +167,7 @@ describe('patch formatting', () => { ) const file = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, unselectedFile ) @@ -189,7 +190,7 @@ describe('patch formatting', () => { const updatedFile = new WorkingDirectoryFileChange( modifiedFile, - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) @@ -255,7 +256,7 @@ describe('patch formatting', () => { const file = new WorkingDirectoryFileChange( 'file.md', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) const patch = formatPatch(file, diff) @@ -286,7 +287,7 @@ describe('patch formatting', () => { const file = new WorkingDirectoryFileChange( 'file.md', - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, selection ) const patch = formatPatch(file, diff) @@ -312,7 +313,7 @@ describe('patch formatting', () => { const file = new WorkingDirectoryFileChange( 'file.md', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) const patch = formatPatch(file, diff) @@ -345,7 +346,7 @@ describe('patch formatting', () => { const file = new WorkingDirectoryFileChange( 'file.md', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, selection ) diff --git a/app/test/unit/repository-state-cache-test.ts b/app/test/unit/repository-state-cache-test.ts index dc7a559f34..2980ef4c65 100644 --- a/app/test/unit/repository-state-cache-test.ts +++ b/app/test/unit/repository-state-cache-test.ts @@ -64,7 +64,7 @@ describe('RepositoryStateCache', () => { const files = [ new WorkingDirectoryFileChange( 'README.md', - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, DiffSelection.fromInitialSelection(DiffSelectionType.All) ), ] diff --git a/app/test/unit/stores/updates/update-changed-files-test.ts b/app/test/unit/stores/updates/update-changed-files-test.ts index 81ec03736e..2dee705443 100644 --- a/app/test/unit/stores/updates/update-changed-files-test.ts +++ b/app/test/unit/stores/updates/update-changed-files-test.ts @@ -25,12 +25,12 @@ const noneSelected = DiffSelection.fromInitialSelection(DiffSelectionType.None) const files = [ new WorkingDirectoryFileChange( 'README.md', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, allSelected ), new WorkingDirectoryFileChange( 'app/package.json', - { kind: AppFileStatusKind.Modified }, + { kind: AppFileStatusKind.Modified, submoduleStatus: null }, noneSelected ), ] @@ -49,7 +49,7 @@ describe('updateChangedFiles', () => { partiallySelectedFile = new WorkingDirectoryFileChange( 'app/index.ts', - { kind: AppFileStatusKind.New }, + { kind: AppFileStatusKind.New, submoduleStatus: null }, partialFileSelection ) From f1f52566798262804cb5d6ede070df2c41b1c0cd Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 27 Jul 2022 15:58:07 +0200 Subject: [PATCH 028/111] WIP submodule UI! --- app/src/lib/git/apply.ts | 1 + app/src/lib/git/diff.ts | 7 +++++++ app/src/models/diff/diff-data.ts | 5 +++++ app/src/ui/diff/index.tsx | 6 ++++++ app/src/ui/diff/submodule-diff.tsx | 20 ++++++++++++++++++++ 5 files changed, 39 insertions(+) create mode 100644 app/src/ui/diff/submodule-diff.tsx diff --git a/app/src/lib/git/apply.ts b/app/src/lib/git/apply.ts index 8546731282..bf3680cce1 100644 --- a/app/src/lib/git/apply.ts +++ b/app/src/lib/git/apply.ts @@ -64,6 +64,7 @@ export async function applyPatchToIndex( const { kind } = diff switch (diff.kind) { case DiffType.Binary: + case DiffType.Submodule: case DiffType.Image: throw new Error( `Can't create partial commit in binary file: ${file.path}` diff --git a/app/src/lib/git/diff.ts b/app/src/lib/git/diff.ts index fe08083722..3ec61d8c13 100644 --- a/app/src/lib/git/diff.ts +++ b/app/src/lib/git/diff.ts @@ -19,6 +19,7 @@ import { parseLineEndingText, ILargeTextDiff, IUnrenderableDiff, + ISubmoduleDiff, } from '../../models/diff' import { spawnAndComplete } from './spawn' @@ -487,6 +488,12 @@ function buildDiff( oldestCommitish: string, lineEndingsChange?: LineEndingsChange ): Promise { + if (file.status.submoduleStatus !== null) { + return Promise.resolve({ + kind: DiffType.Submodule, + }) + } + if (!isValidBuffer(buffer)) { // the buffer's diff is too large to be renderable in the UI return Promise.resolve({ kind: DiffType.Unrenderable }) diff --git a/app/src/models/diff/diff-data.ts b/app/src/models/diff/diff-data.ts index 99cea42042..25dd0226af 100644 --- a/app/src/models/diff/diff-data.ts +++ b/app/src/models/diff/diff-data.ts @@ -87,6 +87,10 @@ export interface IBinaryDiff { readonly kind: DiffType.Binary } +export interface ISubmoduleDiff { + readonly kind: DiffType.Submodule +} + export interface ILargeTextDiff extends ITextDiffData { readonly kind: DiffType.LargeText } @@ -100,5 +104,6 @@ export type IDiff = | ITextDiff | IImageDiff | IBinaryDiff + | ISubmoduleDiff | ILargeTextDiff | IUnrenderableDiff diff --git a/app/src/ui/diff/index.tsx b/app/src/ui/diff/index.tsx index 8130f17279..d973ba40e8 100644 --- a/app/src/ui/diff/index.tsx +++ b/app/src/ui/diff/index.tsx @@ -121,6 +121,8 @@ export class Diff extends React.Component { return this.renderText(diff) case DiffType.Binary: return this.renderBinaryFile() + case DiffType.Submodule: + return this.renderSubmoduleDiff() case DiffType.Image: return this.renderImage(diff) case DiffType.LargeText: { @@ -243,6 +245,10 @@ export class Diff extends React.Component { return this.renderTextDiff(diff) } + private renderSubmoduleDiff() { + return

Hello world

+ } + private renderBinaryFile() { return ( { + public constructor(props: ISubmoduleDiffProps) { + super(props) + } + + public render() { + return ( +
+

Submodule changes

+
+ ) + } +} From f55fdcdcf4359471155def84753aacbca52ed247 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Thu, 28 Jul 2022 13:19:24 +0200 Subject: [PATCH 029/111] WIP First working version of submodule interstitial --- app/src/lib/git/diff.ts | 20 +++-- app/src/models/diff/diff-data.ts | 3 + app/src/ui/changes/changes.tsx | 4 + app/src/ui/diff/index.tsx | 13 +++- app/src/ui/diff/seamless-diff-switcher.tsx | 5 ++ app/src/ui/diff/submodule-diff.tsx | 85 +++++++++++++++++++++- app/src/ui/dispatcher/dispatcher.ts | 17 +++++ app/src/ui/repository.tsx | 5 ++ 8 files changed, 140 insertions(+), 12 deletions(-) diff --git a/app/src/lib/git/diff.ts b/app/src/lib/git/diff.ts index 3ec61d8c13..34f6406d05 100644 --- a/app/src/lib/git/diff.ts +++ b/app/src/lib/git/diff.ts @@ -18,8 +18,6 @@ import { LineEndingsChange, parseLineEndingText, ILargeTextDiff, - IUnrenderableDiff, - ISubmoduleDiff, } from '../../models/diff' import { spawnAndComplete } from './spawn' @@ -33,6 +31,7 @@ import { git } from './core' import { NullTreeSHA } from './diff-index' import { GitError } from 'dugite' import { parseRawLogWithNumstat } from './log' +import { getConfigValue } from './config' /** * V8 has a limit on the size of string it can create (~256MB), and unless we want to @@ -481,7 +480,7 @@ function diffFromRawDiffOutput(output: Buffer): IRawDiff { return parser.parse(forceUnwrap(`Invalid diff output`, pieces.at(-1))) } -function buildDiff( +async function buildDiff( buffer: Buffer, repository: Repository, file: FileChange, @@ -489,14 +488,21 @@ function buildDiff( lineEndingsChange?: LineEndingsChange ): Promise { if (file.status.submoduleStatus !== null) { - return Promise.resolve({ + const path = file.path + const fullPath = Path.join(repository.path, path) + const url = + (await getConfigValue(repository, `submodule.${path}.url`, true)) ?? '' + return { kind: DiffType.Submodule, - }) + fullPath, + path, + url, + } } if (!isValidBuffer(buffer)) { // the buffer's diff is too large to be renderable in the UI - return Promise.resolve({ kind: DiffType.Unrenderable }) + return { kind: DiffType.Unrenderable } } const diff = diffFromRawDiffOutput(buffer) @@ -514,7 +520,7 @@ function buildDiff( hasHiddenBidiChars: diff.hasHiddenBidiChars, } - return Promise.resolve(largeTextDiff) + return largeTextDiff } return convertDiff(repository, file, diff, oldestCommitish, lineEndingsChange) diff --git a/app/src/models/diff/diff-data.ts b/app/src/models/diff/diff-data.ts index 25dd0226af..348de5e5d1 100644 --- a/app/src/models/diff/diff-data.ts +++ b/app/src/models/diff/diff-data.ts @@ -89,6 +89,9 @@ export interface IBinaryDiff { export interface ISubmoduleDiff { readonly kind: DiffType.Submodule + readonly fullPath: string + readonly path: string + readonly url: string } export interface ILargeTextDiff extends ITextDiffData { diff --git a/app/src/ui/changes/changes.tsx b/app/src/ui/changes/changes.tsx index efd0eb9acb..eaf9539c8c 100644 --- a/app/src/ui/changes/changes.tsx +++ b/app/src/ui/changes/changes.tsx @@ -29,6 +29,9 @@ interface IChangesProps { */ readonly onOpenBinaryFile: (fullPath: string) => void + /** Called when the user requests to open a submodule. */ + readonly onOpenSubmodule: (fullPath: string) => void + /** * Called when the user is viewing an image diff and requests * to change the diff presentation mode. @@ -121,6 +124,7 @@ export class Changes extends React.Component { this.props.askForConfirmationOnDiscardChanges } onOpenBinaryFile={this.props.onOpenBinaryFile} + onOpenSubmodule={this.props.onOpenSubmodule} onChangeImageDiffType={this.props.onChangeImageDiffType} onHideWhitespaceInDiffChanged={this.onHideWhitespaceInDiffChanged} /> diff --git a/app/src/ui/diff/index.tsx b/app/src/ui/diff/index.tsx index d973ba40e8..647be55755 100644 --- a/app/src/ui/diff/index.tsx +++ b/app/src/ui/diff/index.tsx @@ -19,6 +19,7 @@ import { ITextDiff, ILargeTextDiff, ImageDiffType, + ISubmoduleDiff, } from '../../models/diff' import { Button } from '../lib/button' import { @@ -31,6 +32,7 @@ import { TextDiff } from './text-diff' import { SideBySideDiff } from './side-by-side-diff' import { enableExperimentalDiffViewer } from '../../lib/feature-flag' import { IFileContents } from './syntax-highlighting' +import { SubmoduleDiff } from './submodule-diff' // image used when no diff is displayed const NoDiffImage = encodePathAsUrl(__dirname, 'static/ufo-alert.svg') @@ -80,6 +82,9 @@ interface IDiffProps { */ readonly onOpenBinaryFile: (fullPath: string) => void + /** Called when the user requests to open a submodule. */ + readonly onOpenSubmodule?: (fullPath: string) => void + /** * Called when the user is viewing an image diff and requests * to change the diff presentation mode. @@ -122,7 +127,7 @@ export class Diff extends React.Component { case DiffType.Binary: return this.renderBinaryFile() case DiffType.Submodule: - return this.renderSubmoduleDiff() + return this.renderSubmoduleDiff(diff) case DiffType.Image: return this.renderImage(diff) case DiffType.LargeText: { @@ -245,8 +250,10 @@ export class Diff extends React.Component { return this.renderTextDiff(diff) } - private renderSubmoduleDiff() { - return

Hello world

+ private renderSubmoduleDiff(diff: ISubmoduleDiff) { + return ( + + ) } private renderBinaryFile() { diff --git a/app/src/ui/diff/seamless-diff-switcher.tsx b/app/src/ui/diff/seamless-diff-switcher.tsx index b0b217e871..902caf3e93 100644 --- a/app/src/ui/diff/seamless-diff-switcher.tsx +++ b/app/src/ui/diff/seamless-diff-switcher.tsx @@ -65,6 +65,9 @@ interface ISeamlessDiffSwitcherProps { */ readonly onOpenBinaryFile: (fullPath: string) => void + /** Called when the user requests to open a submodule. */ + readonly onOpenSubmodule?: (fullPath: string) => void + /** * Called when the user is viewing an image diff and requests * to change the diff presentation mode. @@ -309,6 +312,7 @@ export class SeamlessDiffSwitcher extends React.Component< onDiscardChanges, file, onOpenBinaryFile, + onOpenSubmodule, onChangeImageDiffType, onHideWhitespaceInDiffChanged, } = this.state.propSnapshot @@ -343,6 +347,7 @@ export class SeamlessDiffSwitcher extends React.Component< onIncludeChanged={isLoadingDiff ? noop : onIncludeChanged} onDiscardChanges={isLoadingDiff ? noop : onDiscardChanges} onOpenBinaryFile={isLoadingDiff ? noop : onOpenBinaryFile} + onOpenSubmodule={isLoadingDiff ? noop : onOpenSubmodule} onChangeImageDiffType={isLoadingDiff ? noop : onChangeImageDiffType} onHideWhitespaceInDiffChanged={ isLoadingDiff ? noop : onHideWhitespaceInDiffChanged diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index 0888a08db5..544176be0c 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -1,7 +1,13 @@ import React from 'react' +import { parseRepositoryIdentifier } from '../../lib/remote-parsing' import { ISubmoduleDiff } from '../../models/diff' +import { LinkButton } from '../lib/link-button' +import { Octicon } from '../octicons' +import * as OcticonSymbol from '../octicons/octicons.generated' +import { SuggestedAction } from '../suggested-actions' interface ISubmoduleDiffProps { + readonly onOpenSubmodule?: (fullPath: string) => void readonly diff: ISubmoduleDiff } @@ -12,9 +18,84 @@ export class SubmoduleDiff extends React.Component { public render() { return ( -
-

Submodule changes

+
+
+
+
+

Submodule changes

+
+
+ {this.renderSubmoduleInfo()} + {this.renderCommitChangeInfo()} + {this.renderSubmodulesChangesInfo()} + {this.renderOpenSubmoduleAction()} +
) } + + private renderSubmoduleInfo() { + // TODO: only for GH submodules? + + const repoIdentifier = parseRepositoryIdentifier(this.props.diff.url) + if (repoIdentifier === null) { + return null + } + + const hostname = + repoIdentifier.hostname === 'github.com' + ? '' + : ` (${repoIdentifier.hostname})` + + return ( +

+ This is a submodule based on the + repository{' '} + + {repoIdentifier.owner}/{repoIdentifier.name} + {hostname} + + . +

+ ) + } + + private renderCommitChangeInfo() { + return ( +

+ This submodule has + changed its commit from fe158c2 to{' '} + 0ab36d9. This change can be committed to the + parent repository. +

+ ) + } + + private renderSubmodulesChangesInfo() { + return ( +

+ This submodule has modified + and untracked changes. Those changes must be committed inside of the + submodule before they can be part of the parent repository. +

+ ) + } + + private renderOpenSubmoduleAction() { + return ( + + ) + } + + private onOpenSubmoduleClick = () => { + this.props.onOpenSubmodule?.(this.props.diff.fullPath) + } } diff --git a/app/src/ui/dispatcher/dispatcher.ts b/app/src/ui/dispatcher/dispatcher.ts index 91ac5e55db..e2e1fcd7d1 100644 --- a/app/src/ui/dispatcher/dispatcher.ts +++ b/app/src/ui/dispatcher/dispatcher.ts @@ -1955,6 +1955,23 @@ export class Dispatcher { }) } + public async openOrAddRepository(path: string): Promise { + const state = this.appStore.getState() + const repositories = state.repositories + const existingRepository = repositories.find(r => r.path === path) + + if (existingRepository) { + return await this.selectRepository(existingRepository) + } + + return this.appStore._startOpenInDesktop(() => { + this.showPopup({ + type: PopupType.AddRepository, + path, + }) + }) + } + /** * Install the CLI tool. * diff --git a/app/src/ui/repository.tsx b/app/src/ui/repository.tsx index d1298bb445..af7707438e 100644 --- a/app/src/ui/repository.tsx +++ b/app/src/ui/repository.tsx @@ -489,6 +489,7 @@ export class RepositoryView extends React.Component< hideWhitespaceInDiff={this.props.hideWhitespaceInChangesDiff} showSideBySideDiff={this.props.showSideBySideDiff} onOpenBinaryFile={this.onOpenBinaryFile} + onOpenSubmodule={this.onOpenSubmodule} onChangeImageDiffType={this.onChangeImageDiffType} askForConfirmationOnDiscardChanges={ this.props.askForConfirmationOnDiscardChanges @@ -503,6 +504,10 @@ export class RepositoryView extends React.Component< openFile(fullPath, this.props.dispatcher) } + private onOpenSubmodule = (fullPath: string) => { + this.props.dispatcher.openOrAddRepository(fullPath) + } + private onChangeImageDiffType = (imageDiffType: ImageDiffType) => { this.props.dispatcher.changeImageDiffType(imageDiffType) } From 72fbbb3c18ae9043c0c793e8dc69b6c12822bdb9 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Thu, 28 Jul 2022 16:37:02 +0200 Subject: [PATCH 030/111] WIP More work showing submodule info in interstitial --- app/src/lib/git/diff.ts | 30 ++++++++++++++++++++++++++++++ app/src/models/diff/diff-data.ts | 4 ++++ app/src/ui/diff/submodule-diff.tsx | 12 +++++++++--- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/app/src/lib/git/diff.ts b/app/src/lib/git/diff.ts index 34f6406d05..6047e3f543 100644 --- a/app/src/lib/git/diff.ts +++ b/app/src/lib/git/diff.ts @@ -490,13 +490,43 @@ async function buildDiff( if (file.status.submoduleStatus !== null) { const path = file.path const fullPath = Path.join(repository.path, path) + const status = file.status.submoduleStatus const url = (await getConfigValue(repository, `submodule.${path}.url`, true)) ?? '' + + let oldSHA = null + let newSHA = null + + if (status.commitChanged) { + const diff = buffer.toString('utf-8') + const lines = diff.split('\n') + const baseRegex = 'Subproject commit ([^-]+)(-dirty)?$' + const oldSHARegex = new RegExp('-' + baseRegex) + const newSHARegex = new RegExp('\\+' + baseRegex) + oldSHA = + lines + .flatMap(line => { + const match = line.match(oldSHARegex) + return match ? match[1] : [] + }) + .at(0) ?? null + newSHA = + lines + .flatMap(line => { + const match = line.match(newSHARegex) + return match ? match[1] : [] + }) + .at(0) ?? null + } + return { kind: DiffType.Submodule, fullPath, path, url, + status, + oldSHA, + newSHA, } } diff --git a/app/src/models/diff/diff-data.ts b/app/src/models/diff/diff-data.ts index 348de5e5d1..06a54277a9 100644 --- a/app/src/models/diff/diff-data.ts +++ b/app/src/models/diff/diff-data.ts @@ -1,5 +1,6 @@ import { DiffHunk } from './raw-diff' import { Image } from './image' +import { SubmoduleStatus } from '../status' /** * V8 has a limit on the size of string it can create, and unless we want to * trigger an unhandled exception we need to do the encoding conversion by hand @@ -92,6 +93,9 @@ export interface ISubmoduleDiff { readonly fullPath: string readonly path: string readonly url: string + readonly status: SubmoduleStatus + readonly oldSHA: string | null + readonly newSHA: string | null } export interface ILargeTextDiff extends ITextDiffData { diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index 544176be0c..f787eee30e 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -63,12 +63,18 @@ export class SubmoduleDiff extends React.Component { } private renderCommitChangeInfo() { + const { diff } = this.props + + if (!diff.status.commitChanged) { + return null + } + return (

This submodule has - changed its commit from fe158c2 to{' '} - 0ab36d9. This change can be committed to the - parent repository. + changed its commit from {diff.oldSHA} to{' '} + {diff.newSHA}. This change can be committed to + the parent repository.

) } From 79b6df13a3eda83854db89c179daa8791706833d Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Thu, 28 Jul 2022 16:42:01 +0200 Subject: [PATCH 031/111] WIP Remove parts of the interstitial when not needed --- app/src/ui/diff/submodule-diff.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index f787eee30e..e955fa613c 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -36,6 +36,8 @@ export class SubmoduleDiff extends React.Component { private renderSubmoduleInfo() { // TODO: only for GH submodules? + // TODO: test with submodules without URL (is that possible? maybe a submodule + // from a local repo??) const repoIdentifier = parseRepositoryIdentifier(this.props.diff.url) if (repoIdentifier === null) { @@ -80,6 +82,12 @@ export class SubmoduleDiff extends React.Component { } private renderSubmodulesChangesInfo() { + const { diff } = this.props + + if (!diff.status.untrackedChanges) { + return null + } + return (

This submodule has modified From 9032cfe0132441742335e30436b3b4de5aa8fe02 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 17 Aug 2022 18:46:41 +0200 Subject: [PATCH 032/111] (WIP) Layout tweaks --- app/src/ui/changes/changes.tsx | 11 ++++++ app/src/ui/changes/no-changes.tsx | 2 +- app/src/ui/diff/submodule-diff.tsx | 37 +++++++++++-------- app/styles/ui/_changes.scss | 3 +- ...hanges.scss => _changes-interstitial.scss} | 2 +- app/styles/ui/changes/_submodule-diff.scss | 18 +++++++++ 6 files changed, 55 insertions(+), 18 deletions(-) rename app/styles/ui/changes/{_no-changes.scss => _changes-interstitial.scss} (97%) create mode 100644 app/styles/ui/changes/_submodule-diff.scss diff --git a/app/src/ui/changes/changes.tsx b/app/src/ui/changes/changes.tsx index eaf9539c8c..b422654d16 100644 --- a/app/src/ui/changes/changes.tsx +++ b/app/src/ui/changes/changes.tsx @@ -2,6 +2,7 @@ import * as React from 'react' import { ChangedFileDetails } from './changed-file-details' import { DiffSelection, + DiffType, IDiff, ImageDiffType, ITextDiff, @@ -11,6 +12,7 @@ import { Repository } from '../../models/repository' import { Dispatcher } from '../dispatcher' import { SeamlessDiffSwitcher } from '../diff/seamless-diff-switcher' import { PopupType } from '../../models/popup' +import { SubmoduleDiff } from '../diff/submodule-diff' interface IChangesProps { readonly repository: Repository @@ -97,6 +99,15 @@ export class Changes extends React.Component { } public render() { + if (this.props.diff?.kind === DiffType.Submodule) { + return ( + + ) + } + return (

+
diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index e955fa613c..5439d55275 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -18,7 +18,7 @@ export class SubmoduleDiff extends React.Component { public render() { return ( -
+
@@ -51,8 +51,8 @@ export class SubmoduleDiff extends React.Component { return (

- This is a submodule based on the - repository{' '} + This is a + submodule based on the repository{' '} @@ -73,8 +73,12 @@ export class SubmoduleDiff extends React.Component { return (

- This submodule has - changed its commit from {diff.oldSHA} to{' '} + {' '} + This submodule has changed its commit from{' '} + {diff.oldSHA} to{' '} {diff.newSHA}. This change can be committed to the parent repository.

@@ -90,22 +94,25 @@ export class SubmoduleDiff extends React.Component { return (

- This submodule has modified - and untracked changes. Those changes must be committed inside of the - submodule before they can be part of the parent repository. + {' '} + This submodule has modified and untracked changes. Those changes must be + committed inside of the submodule before they can be part of the parent + repository.

) } private renderOpenSubmoduleAction() { return ( - + + + ) } diff --git a/app/styles/ui/_changes.scss b/app/styles/ui/_changes.scss index 7fe0715ce4..656d5fe153 100644 --- a/app/styles/ui/_changes.scss +++ b/app/styles/ui/_changes.scss @@ -3,6 +3,7 @@ @import 'changes/changes-list'; @import 'changes/undo-commit'; @import 'changes/changes-view'; -@import 'changes/no-changes'; +@import 'changes/changes-interstitial'; @import 'changes/oversized-files-warning'; @import 'changes/commit-warning'; +@import 'changes/submodule-diff'; diff --git a/app/styles/ui/changes/_no-changes.scss b/app/styles/ui/changes/_changes-interstitial.scss similarity index 97% rename from app/styles/ui/changes/_no-changes.scss rename to app/styles/ui/changes/_changes-interstitial.scss index 8d4e1e8478..a11a865cea 100644 --- a/app/styles/ui/changes/_no-changes.scss +++ b/app/styles/ui/changes/_changes-interstitial.scss @@ -1,4 +1,4 @@ -#no-changes { +.changes-interstitial { padding: var(--spacing-quad); width: 100%; min-height: 100%; diff --git a/app/styles/ui/changes/_submodule-diff.scss b/app/styles/ui/changes/_submodule-diff.scss new file mode 100644 index 0000000000..41b09ffbac --- /dev/null +++ b/app/styles/ui/changes/_submodule-diff.scss @@ -0,0 +1,18 @@ +.submodule-diff { + + .info-icon { + color: var(--dialog-information-color); + } + + .modified-icon { + color: var(--color-modified); + } + + .untracked-icon { + color: var(--color-deleted); + } + + p { + font-size: var(--font-size-md); + } +} From 5d107379942b43222223fc8ec8f5db0fbe6c78fd Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Thu, 18 Aug 2022 18:43:23 +0200 Subject: [PATCH 033/111] (WIP) More layout improvements --- app/src/ui/diff/submodule-diff.tsx | 55 +++++++++++++++------- app/styles/ui/changes/_submodule-diff.scss | 36 +++++++++----- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index 5439d55275..425c20cc36 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -6,6 +6,20 @@ import { Octicon } from '../octicons' import * as OcticonSymbol from '../octicons/octicons.generated' import { SuggestedAction } from '../suggested-actions' +type SubmoduleItemIcon = + | { + readonly octicon: typeof OcticonSymbol.info + readonly className: 'info-icon' + } + | { + readonly octicon: typeof OcticonSymbol.diffModified + readonly className: 'modified-icon' + } + | { + readonly octicon: typeof OcticonSymbol.fileDiff + readonly className: 'untracked-icon' + } + interface ISubmoduleDiffProps { readonly onOpenSubmodule?: (fullPath: string) => void readonly diff: ISubmoduleDiff @@ -49,10 +63,10 @@ export class SubmoduleDiff extends React.Component { ? '' : ` (${repoIdentifier.hostname})` - return ( -

- This is a - submodule based on the repository{' '} + return this.renderSubmoduleDiffItem( + { octicon: OcticonSymbol.info, className: 'info-icon' }, + <> + This is a submodule based on the repository{' '} @@ -60,7 +74,7 @@ export class SubmoduleDiff extends React.Component { {hostname} . -

+ ) } @@ -71,17 +85,14 @@ export class SubmoduleDiff extends React.Component { return null } - return ( -

- {' '} + return this.renderSubmoduleDiffItem( + { octicon: OcticonSymbol.diffModified, className: 'modified-icon' }, + <> This submodule has changed its commit from{' '} {diff.oldSHA} to{' '} {diff.newSHA}. This change can be committed to the parent repository. -

+ ) } @@ -92,13 +103,25 @@ export class SubmoduleDiff extends React.Component { return null } - return ( -

- {' '} + return this.renderSubmoduleDiffItem( + { octicon: OcticonSymbol.fileDiff, className: 'untracked-icon' }, + <> This submodule has modified and untracked changes. Those changes must be committed inside of the submodule before they can be part of the parent repository. -

+ + ) + } + + private renderSubmoduleDiffItem( + icon: SubmoduleItemIcon, + content: React.ReactElement + ) { + return ( +
+ +
{content}
+
) } diff --git a/app/styles/ui/changes/_submodule-diff.scss b/app/styles/ui/changes/_submodule-diff.scss index 41b09ffbac..c825db85e5 100644 --- a/app/styles/ui/changes/_submodule-diff.scss +++ b/app/styles/ui/changes/_submodule-diff.scss @@ -1,18 +1,32 @@ .submodule-diff { - .info-icon { - color: var(--dialog-information-color); - } + .item { + display: flex; + flex-direction: row; + align-items: flex-start; + width: 100%; + gap: 3px; + margin-bottom: 1em; - .modified-icon { - color: var(--color-modified); - } + .content { + font-size: var(--font-size-md); + flex: 1; + } - .untracked-icon { - color: var(--color-deleted); - } + .octicon { + margin-top: 2px; - p { - font-size: var(--font-size-md); + &.info-icon { + color: var(--dialog-information-color); + } + + &.modified-icon { + color: var(--color-modified); + } + + &.untracked-icon { + color: var(--color-deleted); + } + } } } From b3f0dcf7653225d3da0f11d244242176fb048226 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Tue, 23 Aug 2022 13:32:39 +0200 Subject: [PATCH 034/111] Shorten commit SHAs of submodules --- app/src/lib/stores/notifications-store.ts | 4 ++-- app/src/models/commit.ts | 4 ++++ app/src/ui/diff/submodule-diff.tsx | 11 ++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/lib/stores/notifications-store.ts b/app/src/lib/stores/notifications-store.ts index 8d9303a0c3..e88b6922c4 100644 --- a/app/src/lib/stores/notifications-store.ts +++ b/app/src/lib/stores/notifications-store.ts @@ -16,7 +16,7 @@ import { AccountsStore } from './accounts-store' import { getCommit } from '../git' import { GitHubRepository } from '../../models/github-repository' import { PullRequestCoordinator } from './pull-request-coordinator' -import { Commit } from '../../models/commit' +import { Commit, shortenSHA } from '../../models/commit' import { AliveStore, DesktopAliveEvent, @@ -253,7 +253,7 @@ export class NotificationsStore { const pluralChecks = numberOfFailedChecks === 1 ? 'check was' : 'checks were' - const shortSHA = commitSHA.slice(0, 9) + const shortSHA = shortenSHA(commitSHA) const title = 'Pull Request checks failed' const body = `${pullRequest.title} #${pullRequest.pullRequestNumber} (${shortSHA})\n${numberOfFailedChecks} ${pluralChecks} not successful.` const onClick = () => { diff --git a/app/src/models/commit.ts b/app/src/models/commit.ts index 61e558a606..7318f8aa5e 100644 --- a/app/src/models/commit.ts +++ b/app/src/models/commit.ts @@ -2,6 +2,10 @@ import { CommitIdentity } from './commit-identity' import { ITrailer, isCoAuthoredByTrailer } from '../lib/git/interpret-trailers' import { GitAuthor } from './git-author' +export function shortenSHA(sha: string) { + return sha.slice(0, 9) +} + /** Grouping of information required to create a commit */ export interface ICommitContext { /** diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index 425c20cc36..a14921eb5b 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -1,5 +1,6 @@ import React from 'react' import { parseRepositoryIdentifier } from '../../lib/remote-parsing' +import { shortenSHA } from '../../models/commit' import { ISubmoduleDiff } from '../../models/diff' import { LinkButton } from '../lib/link-button' import { Octicon } from '../octicons' @@ -85,13 +86,17 @@ export class SubmoduleDiff extends React.Component { return null } + if (diff.oldSHA === null || diff.newSHA === null) { + return null + } + return this.renderSubmoduleDiffItem( { octicon: OcticonSymbol.diffModified, className: 'modified-icon' }, <> This submodule has changed its commit from{' '} - {diff.oldSHA} to{' '} - {diff.newSHA}. This change can be committed to - the parent repository. + {shortenSHA(diff.oldSHA)} to{' '} + {shortenSHA(diff.newSHA)}. This change can be + committed to the parent repository. ) } From efad351db16e847c0136dad4f467bde7c97cdbf5 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Tue, 23 Aug 2022 13:32:48 +0200 Subject: [PATCH 035/111] Cleanup CSS of submodule diffs --- app/styles/ui/changes/_submodule-diff.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/styles/ui/changes/_submodule-diff.scss b/app/styles/ui/changes/_submodule-diff.scss index c825db85e5..cb120ab95b 100644 --- a/app/styles/ui/changes/_submodule-diff.scss +++ b/app/styles/ui/changes/_submodule-diff.scss @@ -5,16 +5,16 @@ flex-direction: row; align-items: flex-start; width: 100%; - gap: 3px; + font-size: var(--font-size-md); + gap: 0.25em; margin-bottom: 1em; .content { - font-size: var(--font-size-md); flex: 1; } .octicon { - margin-top: 2px; + margin-top: 0.2em; &.info-icon { color: var(--dialog-information-color); From 2c06b283597ab44724b5da8238447c7e8d67267e Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Tue, 23 Aug 2022 13:33:09 +0200 Subject: [PATCH 036/111] Improve message for untracked/modified changes in submodule diff --- app/src/ui/diff/submodule-diff.tsx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index a14921eb5b..bb4747fa4d 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -51,8 +51,6 @@ export class SubmoduleDiff extends React.Component { private renderSubmoduleInfo() { // TODO: only for GH submodules? - // TODO: test with submodules without URL (is that possible? maybe a submodule - // from a local repo??) const repoIdentifier = parseRepositoryIdentifier(this.props.diff.url) if (repoIdentifier === null) { @@ -104,15 +102,22 @@ export class SubmoduleDiff extends React.Component { private renderSubmodulesChangesInfo() { const { diff } = this.props - if (!diff.status.untrackedChanges) { + if (!diff.status.untrackedChanges && !diff.status.modifiedChanges) { return null } + const changes = + diff.status.untrackedChanges && diff.status.modifiedChanges + ? 'modified and untracked' + : diff.status.untrackedChanges + ? 'untracked' + : 'modified' + return this.renderSubmoduleDiffItem( { octicon: OcticonSymbol.fileDiff, className: 'untracked-icon' }, <> - This submodule has modified and untracked changes. Those changes must be - committed inside of the submodule before they can be part of the parent + This submodule has {changes} changes. Those changes must be committed + inside of the submodule before they can be part of the parent repository. ) From 85e7084f9485a9f94be44643af67ec4b1ce70018 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Tue, 23 Aug 2022 13:33:26 +0200 Subject: [PATCH 037/111] Restore top bar in submodule diff --- app/src/ui/changes/changes.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/src/ui/changes/changes.tsx b/app/src/ui/changes/changes.tsx index b422654d16..eaf9539c8c 100644 --- a/app/src/ui/changes/changes.tsx +++ b/app/src/ui/changes/changes.tsx @@ -2,7 +2,6 @@ import * as React from 'react' import { ChangedFileDetails } from './changed-file-details' import { DiffSelection, - DiffType, IDiff, ImageDiffType, ITextDiff, @@ -12,7 +11,6 @@ import { Repository } from '../../models/repository' import { Dispatcher } from '../dispatcher' import { SeamlessDiffSwitcher } from '../diff/seamless-diff-switcher' import { PopupType } from '../../models/popup' -import { SubmoduleDiff } from '../diff/submodule-diff' interface IChangesProps { readonly repository: Repository @@ -99,15 +97,6 @@ export class Changes extends React.Component { } public render() { - if (this.props.diff?.kind === DiffType.Submodule) { - return ( - - ) - } - return (
Date: Tue, 23 Aug 2022 16:38:57 +0200 Subject: [PATCH 038/111] Remove diff options for submodule diffs --- app/src/ui/changes/changed-file-details.tsx | 30 ++++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/app/src/ui/changes/changed-file-details.tsx b/app/src/ui/changes/changed-file-details.tsx index a9f1ad17b1..b47b7d2918 100644 --- a/app/src/ui/changes/changed-file-details.tsx +++ b/app/src/ui/changes/changed-file-details.tsx @@ -43,16 +43,7 @@ export class ChangedFileDetails extends React.Component< {this.renderDecorator()} - + {this.renderDiffOptions()} + ) + } + private renderDecorator() { const diff = this.props.diff From 5789f564d087cff5965410dbc237f3fd09c27998 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 23 Aug 2022 14:46:15 -0400 Subject: [PATCH 039/111] Adding `esling-plugin-primer-react` linting --- .eslintrc.yml | 1 + package.json | 2 + yarn.lock | 712 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 707 insertions(+), 8 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 03051380c5..00d9e1b7fb 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -15,6 +15,7 @@ extends: - prettier/react - plugin:@typescript-eslint/recommended - prettier/@typescript-eslint + - plugin:primer-react/recommended rules: ########## diff --git a/package.json b/package.json index 920e8bbdb6..2de31457c0 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "xml2js": "^0.4.16" }, "devDependencies": { + "@primer/primitives": "^7.9.0", "@types/byline": "^4.2.31", "@types/classnames": "^2.2.2", "@types/codemirror": "5.60.4", @@ -157,6 +158,7 @@ "electron-builder": "^22.7.0", "electron-packager": "^15.1.0", "electron-winstaller": "^5.0.0", + "eslint-plugin-primer-react": "^1.0.1", "jest-esm-transformer": "^1.0.0", "reserved-words": "^0.1.2", "tsconfig-paths": "^3.9.0" diff --git a/yarn.lock b/yarn.lock index f4e1a41ff3..895c92dff8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -419,6 +419,21 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" +"@babel/runtime-corejs3@^7.10.2": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz#7bacecd1cb2dd694eacd32a91fcf7021c20770ae" + integrity sha512-qZEWeccZCrHA2Au4/X05QW5CMdm4VjUDCrGq5gf1ZDcM4hRqreKrtwAn7yci9zfgAS9apvnsFXiGBHBAxZdK9A== + dependencies: + core-js-pure "^3.20.2" + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.10.2", "@babel/runtime@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" @@ -852,6 +867,11 @@ dependencies: object-assign "^4.1.1" +"@primer/primitives@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@primer/primitives/-/primitives-7.9.0.tgz#c8a27287488c8308b1715a7d73214629c331544a" + integrity sha512-ZHHfwB0z0z6nDJp263gyGIClYDy+rl0nwqyi4qhcv3Cxhkmtf+If2KVjr6FQqBBFfi1wQwUzaax2FBvfEMFBnw== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -871,6 +891,103 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@styled-system/background@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/background/-/background-5.1.2.tgz#75c63d06b497ab372b70186c0bf608d62847a2ba" + integrity sha512-jtwH2C/U6ssuGSvwTN3ri/IyjdHb8W9X/g8Y0JLcrH02G+BW3OS8kZdHphF1/YyRklnrKrBT2ngwGUK6aqqV3A== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/border@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@styled-system/border/-/border-5.1.5.tgz#0493d4332d2b59b74bb0d57d08c73eb555761ba6" + integrity sha512-JvddhNrnhGigtzWRCVuAHepniyVi6hBlimxWDVAdcTuk7aRn9BYJUwfHslURtwYFsF5FoEs8Zmr1oZq2M1AP0A== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/color@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/color/-/color-5.1.2.tgz#b8d6b4af481faabe4abca1a60f8daa4ccc2d9f43" + integrity sha512-1kCkeKDZkt4GYkuFNKc7vJQMcOmTl3bJY3YBUs7fCNM6mMYJeT1pViQ2LwBSBJytj3AB0o4IdLBoepgSgGl5MA== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/core@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/core/-/core-5.1.2.tgz#b8b7b86455d5a0514f071c4fa8e434b987f6a772" + integrity sha512-XclBDdNIy7OPOsN4HBsawG2eiWfCcuFt6gxKn1x4QfMIgeO6TOlA2pZZ5GWZtIhCUqEPTgIBta6JXsGyCkLBYw== + dependencies: + object-assign "^4.1.1" + +"@styled-system/css@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@styled-system/css/-/css-5.1.5.tgz#0460d5f3ff962fa649ea128ef58d9584f403bbbc" + integrity sha512-XkORZdS5kypzcBotAMPBoeckDs9aSZVkvrAlq5K3xP8IMAUek+x2O4NtwoSgkYkWWzVBu6DGdFZLR790QWGG+A== + +"@styled-system/flexbox@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/flexbox/-/flexbox-5.1.2.tgz#077090f43f61c3852df63da24e4108087a8beecf" + integrity sha512-6hHV52+eUk654Y1J2v77B8iLeBNtc+SA3R4necsu2VVinSD7+XY5PCCEzBFaWs42dtOEDIa2lMrgL0YBC01mDQ== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/grid@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/grid/-/grid-5.1.2.tgz#7165049877732900b99cd00759679fbe45c6c573" + integrity sha512-K3YiV1KyHHzgdNuNlaw8oW2ktMuGga99o1e/NAfTEi5Zsa7JXxzwEnVSDSBdJC+z6R8WYTCYRQC6bkVFcvdTeg== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/layout@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/layout/-/layout-5.1.2.tgz#12d73e79887e10062f4dbbbc2067462eace42339" + integrity sha512-wUhkMBqSeacPFhoE9S6UF3fsMEKFv91gF4AdDWp0Aym1yeMPpqz9l9qS/6vjSsDPF7zOb5cOKC3tcKKOMuDCPw== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/position@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/position/-/position-5.1.2.tgz#56961266566836f57a24d8e8e33ce0c1adb59dd3" + integrity sha512-60IZfMXEOOZe3l1mCu6sj/2NAyUmES2kR9Kzp7s2D3P4qKsZWxD1Se1+wJvevb+1TP+ZMkGPEYYXRyU8M1aF5A== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/props@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@styled-system/props/-/props-5.1.5.tgz#f50bf40e8fc8393726f06cbcd096a39a7d779ce4" + integrity sha512-FXhbzq2KueZpGaHxaDm8dowIEWqIMcgsKs6tBl6Y6S0njG9vC8dBMI6WSLDnzMoSqIX3nSKHmOmpzpoihdDewg== + dependencies: + styled-system "^5.1.5" + +"@styled-system/shadow@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/shadow/-/shadow-5.1.2.tgz#beddab28d7de03cd0177a87ac4ed3b3b6d9831fd" + integrity sha512-wqniqYb7XuZM7K7C0d1Euxc4eGtqEe/lvM0WjuAFsQVImiq6KGT7s7is+0bNI8O4Dwg27jyu4Lfqo/oIQXNzAg== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/space@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/space/-/space-5.1.2.tgz#38925d2fa29a41c0eb20e65b7c3efb6e8efce953" + integrity sha512-+zzYpR8uvfhcAbaPXhH8QgDAV//flxqxSjHiS9cDFQQUSznXMQmxJegbhcdEF7/eNnJgHeIXv1jmny78kipgBA== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/typography@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@styled-system/typography/-/typography-5.1.2.tgz#65fb791c67d50cd2900d234583eaacdca8c134f7" + integrity sha512-BxbVUnN8N7hJ4aaPOd7wEsudeT7CxarR+2hns8XCX1zp0DFfbWw4xYa/olA0oQaqx7F1hzDg+eRaGzAJbF+jOg== + dependencies: + "@styled-system/core" "^5.1.2" + +"@styled-system/variant@^5.1.5": + version "5.1.5" + resolved "https://registry.yarnpkg.com/@styled-system/variant/-/variant-5.1.5.tgz#8446d8aad06af3a4c723d717841df2dbe4ddeafd" + integrity sha512-Yn8hXAFoWIro8+Q5J8YJd/mP85Teiut3fsGVR9CAxwgNfIAiqlYxsk5iHU7VHJks/0KjL4ATSjmbtCDC/4l1qw== + dependencies: + "@styled-system/core" "^5.1.2" + "@styled-system/css" "^5.1.5" + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -1486,6 +1603,21 @@ dependencies: "@types/node" "*" +"@typescript-eslint/eslint-plugin@^5.1.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.34.0.tgz#d690f60e335596f38b01792e8f4b361d9bd0cb35" + integrity sha512-eRfPPcasO39iwjlUAMtjeueRGuIrW3TQ9WseIDl7i5UWuFbf83yYaU7YPs4j8+4CxUMIsj1k+4kV+E+G+6ypDQ== + dependencies: + "@typescript-eslint/scope-manager" "5.34.0" + "@typescript-eslint/type-utils" "5.34.0" + "@typescript-eslint/utils" "5.34.0" + debug "^4.3.4" + functional-red-black-tree "^1.0.1" + ignore "^5.2.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/eslint-plugin@^5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz#f8c1d59fc37bd6d9d11c97267fdfe722c4777152" @@ -1508,6 +1640,16 @@ dependencies: "@typescript-eslint/utils" "5.10.2" +"@typescript-eslint/parser@^5.1.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.34.0.tgz#ca710858ea85dbfd30c9b416a335dc49e82dbc07" + integrity sha512-SZ3NEnK4usd2CXkoV3jPa/vo1mWX1fqRyIVUQZR4As1vyp4fneknBNJj+OFtV8WAVgGf+rOHMSqQbs2Qn3nFZQ== + dependencies: + "@typescript-eslint/scope-manager" "5.34.0" + "@typescript-eslint/types" "5.34.0" + "@typescript-eslint/typescript-estree" "5.34.0" + debug "^4.3.4" + "@typescript-eslint/parser@^5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.2.tgz#b6076d27cc5499ce3f2c625f5ccde946ecb7db9a" @@ -1526,6 +1668,14 @@ "@typescript-eslint/types" "5.10.2" "@typescript-eslint/visitor-keys" "5.10.2" +"@typescript-eslint/scope-manager@5.34.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.34.0.tgz#14efd13dc57602937e25f188fd911f118781e527" + integrity sha512-HNvASMQlah5RsBW6L6c7IJ0vsm+8Sope/wu5sEAf7joJYWNb1LDbJipzmdhdUOnfrDFE6LR1j57x1EYVxrY4ow== + dependencies: + "@typescript-eslint/types" "5.34.0" + "@typescript-eslint/visitor-keys" "5.34.0" + "@typescript-eslint/type-utils@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz#ad5acdf98a7d2ab030bea81f17da457519101ceb" @@ -1535,11 +1685,25 @@ debug "^4.3.2" tsutils "^3.21.0" +"@typescript-eslint/type-utils@5.34.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.34.0.tgz#7a324ab9ddd102cd5e1beefc94eea6f3eb32d32d" + integrity sha512-Pxlno9bjsQ7hs1pdWRUv9aJijGYPYsHpwMeCQ/Inavhym3/XaKt1ZKAA8FIw4odTBfowBdZJDMxf2aavyMDkLg== + dependencies: + "@typescript-eslint/utils" "5.34.0" + debug "^4.3.4" + tsutils "^3.21.0" + "@typescript-eslint/types@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.2.tgz#604d15d795c4601fffba6ecb4587ff9fdec68ce8" integrity sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w== +"@typescript-eslint/types@5.34.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.34.0.tgz#217bf08049e9e7b86694d982e88a2c1566330c78" + integrity sha512-49fm3xbbUPuzBIOcy2CDpYWqy/X7VBkxVN+DC21e0zIm3+61Z0NZi6J9mqPmSW1BDVk9FIOvuCFyUPjXz93sjA== + "@typescript-eslint/typescript-estree@5.10.2", "@typescript-eslint/typescript-estree@^5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz#810906056cd3ddcb35aa333fdbbef3713b0fe4a7" @@ -1553,6 +1717,19 @@ semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.34.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.34.0.tgz#ba7b83f4bf8ccbabf074bbf1baca7a58de3ccb9a" + integrity sha512-mXHAqapJJDVzxauEkfJI96j3D10sd567LlqroyCeJaHnu42sDbjxotGb3XFtGPYKPD9IyLjhsoULML1oI3M86A== + dependencies: + "@typescript-eslint/types" "5.34.0" + "@typescript-eslint/visitor-keys" "5.34.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/utils@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.2.tgz#1fcd37547c32c648ab11aea7173ec30060ee87a8" @@ -1565,6 +1742,18 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" +"@typescript-eslint/utils@5.34.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.34.0.tgz#0cae98f48d8f9e292e5caa9343611b6faf49e743" + integrity sha512-kWRYybU4Rn++7lm9yu8pbuydRyQsHRoBDIo11k7eqBWTldN4xUdVUMCsHBiE7aoEkFzrUEaZy3iH477vr4xHAQ== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.34.0" + "@typescript-eslint/types" "5.34.0" + "@typescript-eslint/typescript-estree" "5.34.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + "@typescript-eslint/visitor-keys@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz#fdbf272d8e61c045d865bd6c8b41bea73d222f3d" @@ -1573,6 +1762,14 @@ "@typescript-eslint/types" "5.10.2" eslint-visitor-keys "^3.0.0" +"@typescript-eslint/visitor-keys@5.34.0": + version "5.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.34.0.tgz#d0fb3e31033e82ddd5de048371ad39eb342b2d40" + integrity sha512-O1moYjOSrab0a2fUvFpsJe0QHtvTC+cR+ovYpgKrAVXzqQyc74mv76TgY6z+aEtjQE2vgZux3CQVtGryqdcOAw== + dependencies: + "@typescript-eslint/types" "5.34.0" + eslint-visitor-keys "^3.3.0" + "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" @@ -1994,6 +2191,14 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +aria-query@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" + integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== + dependencies: + "@babel/runtime" "^7.10.2" + "@babel/runtime-corejs3" "^7.10.2" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -2033,6 +2238,17 @@ array-includes@^3.1.3: get-intrinsic "^1.1.1" is-string "^1.0.7" +array-includes@^3.1.4, array-includes@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" + integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -2052,6 +2268,16 @@ array.prototype.flat@^1.2.1: es-abstract "^1.10.0" function-bind "^1.1.1" +array.prototype.flat@^1.2.5: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" + integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.2" + es-shim-unscopables "^1.0.0" + array.prototype.flatmap@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz#3103cd4826ef90019c9b0a4839b2535fa6faf4e9" @@ -2122,6 +2348,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -2174,6 +2405,16 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +axe-core@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" + integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== + +axobject-query@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" + integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== + azure-storage@^2.10.4: version "2.10.4" resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-2.10.4.tgz#c481d207eabc05f57f019b209f7faa8737435104" @@ -2425,6 +2666,16 @@ browserslist@^4.14.5, browserslist@^4.17.5: node-releases "^2.0.1" picocolors "^1.0.0" +browserslist@^4.21.0: + version "4.21.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== + dependencies: + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" + bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -2561,6 +2812,11 @@ caniuse-lite@^1.0.30001286: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz#0e690039f62e91c3ea581673d716890512e7ec52" integrity sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ== +caniuse-lite@^1.0.30001370: + version "1.0.30001382" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz#4d37f0d0b6fffb826c8e5e1c0f4bf8ce592db949" + integrity sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -2887,6 +3143,11 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +core-js-pure@^3.20.2: + version "3.24.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.24.1.tgz#8839dde5da545521bf282feb7dc6d0b425f39fd3" + integrity sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg== + core-js@^2.4.1, core-js@^2.5.3: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -3006,6 +3267,11 @@ cuint@^0.2.2: resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3029,7 +3295,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4: +debug@4, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -3043,6 +3309,13 @@ debug@^3.1.0: dependencies: ms "2.0.0" +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" @@ -3130,6 +3403,14 @@ define-properties@^1.1.2, define-properties@^1.1.3: dependencies: object-keys "^1.0.12" +define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -3431,6 +3712,11 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.40.tgz#f5dbced7bfbc7072e5e7ca5487f8f9a42c8bc768" integrity sha512-j+eVIyQGt2EU5xPWUblhpp5P5z5xyAdRgzogBgfe2F5JGV17gr9pfzWBua6DlPL00LavbOjxubWkWkbVQe9Wlw== +electron-to-chromium@^1.4.202: + version "1.4.227" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.227.tgz#28e46e2a701fed3188db3ca7bf0a3a475e484046" + integrity sha512-I9VVajA3oswIJOUFg2PSBqrHLF5Y+ahIfjOV9+v6uYyBqFZutmPxA6fxocDUUmgwYevRWFu1VjLyVG3w45qa/g== + electron-winstaller@*, electron-winstaller@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/electron-winstaller/-/electron-winstaller-5.0.0.tgz#0db968f34d498b16c69566a40848f562e70e7bcc" @@ -3471,6 +3757,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -3576,6 +3867,35 @@ es-abstract@^1.19.0, es-abstract@^1.19.1: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.1" +es-abstract@^1.19.2, es-abstract@^1.19.5: + version "1.20.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" + integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.4.3" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" @@ -3592,6 +3912,13 @@ es-module-lexer@^0.9.0: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + es-to-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" @@ -3667,6 +3994,11 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" +eslint-config-prettier@>=8.0.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + eslint-config-prettier@^6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1" @@ -3674,6 +4006,91 @@ eslint-config-prettier@^6.11.0: dependencies: get-stdin "^6.0.0" +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + dependencies: + debug "^3.2.7" + +eslint-plugin-escompat@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-escompat/-/eslint-plugin-escompat-3.2.0.tgz#7d40efe8721d8fccb5d300f4fbda44f350a27301" + integrity sha512-obXAKKiZE/wB2fgIw0ZxCmp+8vpDsUw2inkaok1i7OVxY4cEds4Y9YCoky0f5V+q8rqZpTUJDv1R9ykWbXLX8Q== + dependencies: + browserslist "^4.21.0" + +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + +eslint-plugin-filenames@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz#7094f00d7aefdd6999e3ac19f72cea058e590cf7" + integrity sha512-tqxJTiEM5a0JmRCUYQmxw23vtTxrb2+a3Q2mMOPhFxvt7ZQQJmdiuMby9B/vUAuVMghyP7oET+nIf6EO6CBd/w== + dependencies: + lodash.camelcase "4.3.0" + lodash.kebabcase "4.1.1" + lodash.snakecase "4.1.1" + lodash.upperfirst "4.3.1" + +eslint-plugin-github@^4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/eslint-plugin-github/-/eslint-plugin-github-4.3.7.tgz#596416a81240dcd1d3ba1cab6ddfed0a1827bf1a" + integrity sha512-tYZdXvAEz4JCMrC4NHIUoJTsLUvydCxff5OqB5hgU0vQbLmMkw6VOipN2KNe+T06pEhAWs1KBEwyq9cmMWRe7A== + dependencies: + "@typescript-eslint/eslint-plugin" "^5.1.0" + "@typescript-eslint/parser" "^5.1.0" + eslint-config-prettier ">=8.0.0" + eslint-plugin-escompat "^3.1.0" + eslint-plugin-eslint-comments "^3.2.0" + eslint-plugin-filenames "^1.3.2" + eslint-plugin-i18n-text "^1.0.1" + eslint-plugin-import "^2.25.2" + eslint-plugin-jsx-a11y "^6.6.0" + eslint-plugin-no-only-tests "^2.6.0" + eslint-plugin-prettier "^4.0.0" + eslint-rule-documentation ">=1.0.0" + jsx-ast-utils "^3.3.2" + prettier "^2.2.1" + svg-element-attributes "^1.3.1" + +eslint-plugin-i18n-text@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz#69ce14f9af7d135cbe8114b1b144a57bb83291dc" + integrity sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA== + +eslint-plugin-import@^2.25.2: + version "2.26.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" + integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.3" + has "^1.0.3" + is-core-module "^2.8.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.5" + resolve "^1.22.0" + tsconfig-paths "^3.14.1" + eslint-plugin-jsdoc@^37.7.0: version "37.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.7.0.tgz#975d9f18cb0520dde7a2b0db5f4421dfee3fdd17" @@ -3696,6 +4113,30 @@ eslint-plugin-json@^2.1.1: lodash "^4.17.19" vscode-json-languageservice "^3.7.0" +eslint-plugin-jsx-a11y@^6.6.0, eslint-plugin-jsx-a11y@^6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" + integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== + dependencies: + "@babel/runtime" "^7.18.9" + aria-query "^4.2.2" + array-includes "^3.1.5" + ast-types-flow "^0.0.7" + axe-core "^4.4.3" + axobject-query "^2.2.0" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + has "^1.0.3" + jsx-ast-utils "^3.3.2" + language-tags "^1.0.5" + minimatch "^3.1.2" + semver "^6.3.0" + +eslint-plugin-no-only-tests@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-2.6.0.tgz#19f6c9620bda02b9b9221b436c5f070e42628d76" + integrity sha512-T9SmE/g6UV1uZo1oHAqOvL86XWl7Pl2EpRpnLI8g/bkJu+h7XBCB+1LnubRZ2CUQXj805vh4/CYZdnqtVaEo2Q== + eslint-plugin-prettier@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2" @@ -3703,6 +4144,25 @@ eslint-plugin-prettier@^3.1.4: dependencies: prettier-linter-helpers "^1.0.0" +eslint-plugin-prettier@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-plugin-primer-react@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-primer-react/-/eslint-plugin-primer-react-1.0.1.tgz#4883b2555d874a5993fd8ddcf4beb3e78d428da5" + integrity sha512-c2qL7LwGl8ZR3Iw/fCt9sll3Cjvkju7dhJPBWdwl0YPe+h69zX1dtOFonMFCrLDBJVU9crYtNr9wQHeQUxY2oA== + dependencies: + "@styled-system/props" "^5.1.5" + eslint-plugin-github "^4.3.7" + eslint-plugin-jsx-a11y "^6.6.1" + eslint-traverse "^1.0.0" + lodash "^4.17.21" + styled-system "^5.1.5" + eslint-plugin-react@7.26.1: version "7.26.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e" @@ -3723,6 +4183,11 @@ eslint-plugin-react@7.26.1: semver "^6.3.0" string.prototype.matchall "^4.0.5" +eslint-rule-documentation@>=1.0.0: + version "1.0.23" + resolved "https://registry.yarnpkg.com/eslint-rule-documentation/-/eslint-rule-documentation-1.0.23.tgz#4e0886145597a78d24524ec7e0cf18c6fedc23a8" + integrity sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw== + eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -3739,6 +4204,11 @@ eslint-scope@^5.1.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-traverse/-/eslint-traverse-1.0.0.tgz#108d360a171a6e6334e1af0cee905a93bd0dcc53" + integrity sha512-bSp37rQs93LF8rZ409EI369DGCI4tELbFVmFNxI6QbuveS7VRxYVyUhwDafKN/enMyUh88HQQ7ZoGUHtPuGdcw== + eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" @@ -3773,6 +4243,11 @@ eslint-visitor-keys@^3.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + eslint@^7.3.1: version "7.6.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6" @@ -4351,11 +4826,26 @@ function.prototype.name@^1.1.0: function-bind "^1.1.1" is-callable "^1.1.3" +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + galactus@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/galactus/-/galactus-0.2.1.tgz#cbed2d20a40c1f5679a35908e2b9415733e78db9" @@ -4547,7 +5037,7 @@ globalthis@^1.0.1: dependencies: define-properties "^1.1.3" -globby@^11.0.4: +globby@^11.0.4, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -4633,6 +5123,11 @@ has-bigints@^1.0.1: resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -4648,6 +5143,13 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -4663,6 +5165,11 @@ has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -4867,7 +5374,7 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.8, ignore@^5.2.0: +ignore@^5.0.5, ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== @@ -5044,6 +5551,13 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-core-module@^2.8.1, is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -5142,7 +5656,7 @@ is-installed-globally@^0.3.1: global-dirs "^2.0.1" is-path-inside "^3.0.1" -is-negative-zero@^2.0.1: +is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== @@ -5225,6 +5739,13 @@ is-shared-array-buffer@^1.0.1: resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -5271,7 +5792,7 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-weakref@^1.0.1: +is-weakref@^1.0.1, is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== @@ -6068,6 +6589,14 @@ jsprim@^1.2.2: array-includes "^3.1.3" object.assign "^4.1.2" +jsx-ast-utils@^3.3.2: + version "3.3.3" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + dependencies: + array-includes "^3.1.5" + object.assign "^4.1.3" + jszip@^3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9" @@ -6131,6 +6660,18 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== +language-subtag-registry@~0.3.2: + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" + integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== + dependencies: + language-subtag-registry "~0.3.2" + latest-version@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" @@ -6249,6 +6790,11 @@ lodash.assign@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= +lodash.camelcase@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== + lodash.endswith@^4.0.1: version "4.2.1" resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" @@ -6264,11 +6810,21 @@ lodash.get@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= +lodash.kebabcase@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.snakecase@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -6289,6 +6845,11 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "~3.0.0" +lodash.upperfirst@4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" + integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== + lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -6538,7 +7099,7 @@ mini-css-extract-plugin@^2.5.3: dependencies: schema-utils "^4.0.0" -minimatch@^3.0.4: +minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -6567,6 +7128,11 @@ minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + mixin-deep@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.2.0.tgz#d02b8c6f8b6d4b8f5982d3fd009c4919851c3fe2" @@ -6706,6 +7272,11 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + normalize-package-data@^2.0.0, normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -6801,6 +7372,11 @@ object-inspect@^1.11.0, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== +object-inspect@^1.12.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -6833,6 +7409,16 @@ object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + object.entries@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" @@ -6904,7 +7490,7 @@ object.values@^1.0.4: function-bind "^1.1.0" has "^1.0.1" -object.values@^1.1.4: +object.values@^1.1.4, object.values@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== @@ -7134,7 +7720,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.5, path-parse@^1.0.6: +path-parse@^1.0.5, path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -7295,6 +7881,11 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" +prettier@^2.2.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + prettier@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" @@ -7658,6 +8249,11 @@ realistic-structured-clone@^2.0.1: typeson "^5.8.2" typeson-registry "^1.0.0-alpha.20" +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== + regex-not@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9" @@ -7688,6 +8284,15 @@ regexp.prototype.flags@^1.3.1: call-bind "^1.0.2" define-properties "^1.1.3" +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" @@ -7838,6 +8443,15 @@ resolve@^1.18.1: is-core-module "^2.1.0" path-parse "^1.0.6" +resolve@^1.20.0, resolve@^1.22.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^2.0.0-next.3: version "2.0.0-next.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" @@ -8061,6 +8675,13 @@ semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -8504,6 +9125,15 @@ string.prototype.trimend@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + string.prototype.trimstart@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" @@ -8512,6 +9142,15 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" +string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -8601,6 +9240,25 @@ style-loader@^3.3.1: resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== +styled-system@^5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/styled-system/-/styled-system-5.1.5.tgz#e362d73e1dbb5641a2fd749a6eba1263dc85075e" + integrity sha512-7VoD0o2R3RKzOzPK0jYrVnS8iJdfkKsQJNiLRDjikOpQVqQHns/DXWaPZOH4tIKkhAT7I6wIsy9FWTWh2X3q+A== + dependencies: + "@styled-system/background" "^5.1.2" + "@styled-system/border" "^5.1.5" + "@styled-system/color" "^5.1.2" + "@styled-system/core" "^5.1.2" + "@styled-system/flexbox" "^5.1.2" + "@styled-system/grid" "^5.1.2" + "@styled-system/layout" "^5.1.2" + "@styled-system/position" "^5.1.2" + "@styled-system/shadow" "^5.1.2" + "@styled-system/space" "^5.1.2" + "@styled-system/typography" "^5.1.2" + "@styled-system/variant" "^5.1.5" + object-assign "^4.1.1" + sumchecker@^3.0.0, sumchecker@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" @@ -8649,6 +9307,16 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +svg-element-attributes@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/svg-element-attributes/-/svg-element-attributes-1.3.1.tgz#0c55afac6284291ab563d0913c062cf78a8c0ddb" + integrity sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA== + symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -8930,6 +9598,16 @@ ts-node@^7.0.0: source-map-support "^0.5.6" yn "^2.0.0" +tsconfig-paths@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.6" + strip-bom "^3.0.0" + tsconfig-paths@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" @@ -9068,6 +9746,16 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + underscore@^1.12.1: version "1.13.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" @@ -9118,6 +9806,14 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + update-notifier@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3" From e849a0b9b5278e1e460748943353a0c4a3ce4c28 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 24 Aug 2022 11:31:17 +0200 Subject: [PATCH 040/111] Enable x64-to-arm64 immediate updates in prod builds --- app/src/lib/feature-flag.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/lib/feature-flag.ts b/app/src/lib/feature-flag.ts index cdbdec9cd2..7f5e765bd0 100644 --- a/app/src/lib/feature-flag.ts +++ b/app/src/lib/feature-flag.ts @@ -75,7 +75,7 @@ export function enableUpdateFromEmulatedX64ToARM64(): boolean { export function enableImmediateUpdateFromEmulatedX64ToARM64(): boolean { // Because of how Squirrel.Windows works, this is only available for macOS. // See: https://github.com/desktop/desktop/pull/14998 - return __DARWIN__ && enableBetaFeatures() + return __DARWIN__ } /** Should we allow resetting to a previous commit? */ From a1af96c131a5dd3532c13c2176141cd50ca5358d Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 24 Aug 2022 11:37:35 +0200 Subject: [PATCH 041/111] Turn feature flag into private function in the UpdateStore --- app/src/lib/feature-flag.ts | 10 ---------- app/src/ui/lib/update-store.ts | 20 ++++++++++++++------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/app/src/lib/feature-flag.ts b/app/src/lib/feature-flag.ts index 7f5e765bd0..28ddeba19e 100644 --- a/app/src/lib/feature-flag.ts +++ b/app/src/lib/feature-flag.ts @@ -68,16 +68,6 @@ export function enableUpdateFromEmulatedX64ToARM64(): boolean { return enableBetaFeatures() } -/** - * Should we allow x64 apps running under ARM translation to auto-update to - * ARM64 builds IMMEDIATELY instead of waiting for the next release? - */ -export function enableImmediateUpdateFromEmulatedX64ToARM64(): boolean { - // Because of how Squirrel.Windows works, this is only available for macOS. - // See: https://github.com/desktop/desktop/pull/14998 - return __DARWIN__ -} - /** Should we allow resetting to a previous commit? */ export function enableResetToCommit(): boolean { return enableDevelopmentFeatures() diff --git a/app/src/ui/lib/update-store.ts b/app/src/ui/lib/update-store.ts index 8d61eff517..a684cc5676 100644 --- a/app/src/ui/lib/update-store.ts +++ b/app/src/ui/lib/update-store.ts @@ -19,10 +19,7 @@ import { parseError } from '../../lib/squirrel-error-parser' import { ReleaseSummary } from '../../models/release-notes' import { generateReleaseSummary } from '../../lib/release-notes' import { setNumber, getNumber } from '../../lib/local-storage' -import { - enableImmediateUpdateFromEmulatedX64ToARM64, - enableUpdateFromEmulatedX64ToARM64, -} from '../../lib/feature-flag' +import { enableUpdateFromEmulatedX64ToARM64 } from '../../lib/feature-flag' import { offsetFromNow } from '../../lib/offset-from' import { gte, SemVer } from 'semver' import { getRendererGUID } from '../../lib/get-renderer-guid' @@ -124,7 +121,7 @@ class UpdateStore { // and it's the same version we have right now (which means we spoofed // Central with an old version of the app). this.isX64ToARM64ImmediateAutoUpdate = - enableImmediateUpdateFromEmulatedX64ToARM64() && + this.supportsImmediateUpdateFromEmulatedX64ToARM64() && this.newReleases !== null && this.newReleases.length === 1 && this.newReleases[0].latestVersion === getVersion() && @@ -133,6 +130,17 @@ class UpdateStore { this.emitDidChange() } + /** + * Whether or not the app supports auto-updating x64 apps running under ARM + * translation to ARM64 builds IMMEDIATELY instead of waiting for the next + * release. + */ + private supportsImmediateUpdateFromEmulatedX64ToARM64(): boolean { + // Because of how Squirrel.Windows works, this is only available for macOS. + // See: https://github.com/desktop/desktop/pull/14998 + return __DARWIN__ + } + /** Register a function to call when the auto updater state changes. */ public onDidChange(fn: (state: IUpdateState) => void): Disposable { return this.emitter.on('did-change', fn) @@ -229,7 +237,7 @@ class UpdateStore { // If we want the app to force an auto-update from x64 to arm64 right // after being installed, we need to spoof a really old version to trick // both Central and Squirrel into thinking we need the update. - if (enableImmediateUpdateFromEmulatedX64ToARM64()) { + if (this.supportsImmediateUpdateFromEmulatedX64ToARM64()) { url.searchParams.set('version', '0.0.64') } } From d9454b4e4d0561a1c1b9f94bd2ef888098400304 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 24 Aug 2022 17:25:51 +0200 Subject: [PATCH 042/111] Rename header class in interstitial to avoid conflicts with changed-file --- app/src/ui/changes/no-changes.tsx | 2 +- app/src/ui/diff/submodule-diff.tsx | 2 +- app/styles/ui/changes/_changes-interstitial.scss | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/ui/changes/no-changes.tsx b/app/src/ui/changes/no-changes.tsx index cda5013d39..259a393d35 100644 --- a/app/src/ui/changes/no-changes.tsx +++ b/app/src/ui/changes/no-changes.tsx @@ -706,7 +706,7 @@ export class NoChanges extends React.Component< return (
-
+

No local changes

diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index bb4747fa4d..3117b81d62 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -35,7 +35,7 @@ export class SubmoduleDiff extends React.Component { return (

-
+

Submodule changes

diff --git a/app/styles/ui/changes/_changes-interstitial.scss b/app/styles/ui/changes/_changes-interstitial.scss index a11a865cea..b147fc15fc 100644 --- a/app/styles/ui/changes/_changes-interstitial.scss +++ b/app/styles/ui/changes/_changes-interstitial.scss @@ -8,7 +8,7 @@ overflow-y: auto; overflow-x: hidden; - .header { + .interstitial-header { display: flex; flex-direction: row; From 179ee78c48adc9bd4d346bf60ff6051fbb1498f3 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Wed, 24 Aug 2022 17:54:47 +0200 Subject: [PATCH 043/111] Improve render of commit SHAs in submodule diffs --- app/src/ui/diff/submodule-diff.tsx | 15 ++++++- app/src/ui/history/commit-summary.tsx | 29 +++----------- app/src/ui/lib/tooltipped-commit-sha.tsx | 51 ++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 26 deletions(-) create mode 100644 app/src/ui/lib/tooltipped-commit-sha.tsx diff --git a/app/src/ui/diff/submodule-diff.tsx b/app/src/ui/diff/submodule-diff.tsx index 3117b81d62..aa2c2d62d9 100644 --- a/app/src/ui/diff/submodule-diff.tsx +++ b/app/src/ui/diff/submodule-diff.tsx @@ -3,6 +3,8 @@ import { parseRepositoryIdentifier } from '../../lib/remote-parsing' import { shortenSHA } from '../../models/commit' import { ISubmoduleDiff } from '../../models/diff' import { LinkButton } from '../lib/link-button' +import { Ref } from '../lib/ref' +import { TooltippedCommitSHA } from '../lib/tooltipped-commit-sha' import { Octicon } from '../octicons' import * as OcticonSymbol from '../octicons/octicons.generated' import { SuggestedAction } from '../suggested-actions' @@ -92,13 +94,22 @@ export class SubmoduleDiff extends React.Component { { octicon: OcticonSymbol.diffModified, className: 'modified-icon' }, <> This submodule has changed its commit from{' '} - {shortenSHA(diff.oldSHA)} to{' '} - {shortenSHA(diff.newSHA)}. This change can be + {this.renderTooltippedCommitSHA(diff.oldSHA)} to{' '} + {this.renderTooltippedCommitSHA(diff.newSHA)}. This change can be committed to the parent repository. ) } + private renderTooltippedCommitSHA(sha: string) { + return ( + {shortenSHA(sha)}} + longSHA={sha} + /> + ) + } + private renderSubmodulesChangesInfo() { const { diff } = this.props diff --git a/app/src/ui/history/commit-summary.tsx b/app/src/ui/history/commit-summary.tsx index c8853a9086..15cb6489a3 100644 --- a/app/src/ui/history/commit-summary.tsx +++ b/app/src/ui/history/commit-summary.tsx @@ -15,12 +15,11 @@ import { DiffOptions } from '../diff/diff-options' import { RepositorySectionTab } from '../../lib/app-state' import { IChangesetData } from '../../lib/git' import { TooltippedContent } from '../lib/tooltipped-content' -import { clipboard } from 'electron' -import { TooltipDirection } from '../lib/tooltip' import { AppFileStatusKind } from '../../models/status' import _ from 'lodash' import { LinkButton } from '../lib/link-button' import { UnreachableCommitsTab } from './unreachable-commits-dialog' +import { TooltippedCommitSHA } from '../lib/tooltipped-commit-sha' interface ICommitSummaryProps { readonly repository: Repository @@ -435,15 +434,11 @@ export class CommitSummary extends React.Component< aria-label="SHA" > - - {this.getShaRef(true)} - + shortSHA={this.getShaRef(true)} + longSHA={this.getShaRef()} + /> ) } @@ -538,20 +533,6 @@ export class CommitSummary extends React.Component< ) } - private renderShaTooltip() { - return ( - <> - {this.getShaRef()} - - - ) - } - - private onCopyShaButtonClick = (e: React.MouseEvent) => { - e.preventDefault() - clipboard.writeText(this.getShaRef()) - } - private renderChangedFilesDescription = () => { const fileCount = this.props.changesetData.files.length const filesPlural = fileCount === 1 ? 'file' : 'files' diff --git a/app/src/ui/lib/tooltipped-commit-sha.tsx b/app/src/ui/lib/tooltipped-commit-sha.tsx new file mode 100644 index 0000000000..034dbcf855 --- /dev/null +++ b/app/src/ui/lib/tooltipped-commit-sha.tsx @@ -0,0 +1,51 @@ +import { clipboard } from 'electron' +import React from 'react' +import { TooltipDirection } from './tooltip' +import { TooltippedContent } from './tooltipped-content' + +interface ITooltippedCommitSHAProps { + readonly className?: string + /** + * Short SHA to display in the tooltipped element, or the tooltipped element + * itself. + */ + readonly shortSHA: string | JSX.Element + + /** Long SHA to display within the tooltip. */ + readonly longSHA: string +} + +export class TooltippedCommitSHA extends React.Component< + ITooltippedCommitSHAProps, + {} +> { + public render() { + const { className, shortSHA } = this.props + + return ( + + {shortSHA} + + ) + } + + private renderShaTooltip() { + return ( + <> + {this.props.longSHA} + + + ) + } + + private onCopyShaButtonClick = (e: React.MouseEvent) => { + e.preventDefault() + clipboard.writeText(this.props.longSHA) + } +} From f577aa4388a9f7b0c6dcad96c8e5f64879549694 Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Thu, 25 Aug 2022 12:03:38 +0200 Subject: [PATCH 044/111] Adjust selection(ability) of submodules in change list --- app/src/ui/changes/changed-file.tsx | 32 ++++++++++++++++++---------- app/src/ui/changes/changes-list.tsx | 33 +++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/app/src/ui/changes/changed-file.tsx b/app/src/ui/changes/changed-file.tsx index 39372f84a8..40b04dc073 100644 --- a/app/src/ui/changes/changed-file.tsx +++ b/app/src/ui/changes/changed-file.tsx @@ -6,12 +6,14 @@ import { Checkbox, CheckboxValue } from '../lib/checkbox' import { mapStatus } from '../../lib/status' import { WorkingDirectoryFileChange } from '../../models/status' import { TooltipDirection } from '../lib/tooltip' +import { TooltippedContent } from '../lib/tooltipped-content' interface IChangedFileProps { readonly file: WorkingDirectoryFileChange readonly include: boolean | null readonly availableWidth: number readonly disableSelection: boolean + readonly checkboxTooltip?: string readonly onIncludeChanged: (path: string, include: boolean) => void /** Callback called when user right-clicks on an item */ @@ -39,7 +41,9 @@ export class ChangedFile extends React.Component { } public render() { - const { status, path } = this.props.file + const { file, availableWidth, disableSelection, checkboxTooltip } = + this.props + const { status, path } = file const fileStatus = mapStatus(status) const listItemPadding = 10 * 2 @@ -48,7 +52,7 @@ export class ChangedFile extends React.Component { const filePadding = 5 const availablePathWidth = - this.props.availableWidth - + availableWidth - listItemPadding - checkboxWidth - filePadding - @@ -56,15 +60,21 @@ export class ChangedFile extends React.Component { return (
- + + + ) } From d08de6e7d3cde7b7ed5f977a0742975aa13eed6c Mon Sep 17 00:00:00 2001 From: Sergio Padrino Date: Thu, 25 Aug 2022 12:38:47 +0200 Subject: [PATCH 045/111] Don't select initially submodules that can't be selected --- app/src/lib/git/status.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/lib/git/status.ts b/app/src/lib/git/status.ts index 8b28ada797..60efcf25a9 100644 --- a/app/src/lib/git/status.ts +++ b/app/src/lib/git/status.ts @@ -328,7 +328,14 @@ function buildStatusMap( entry.oldPath ) - const selection = DiffSelection.fromInitialSelection(DiffSelectionType.All) + const initialSelectionType = + appStatus.kind === AppFileStatusKind.Modified && + appStatus.submoduleStatus !== null && + !appStatus.submoduleStatus.commitChanged + ? DiffSelectionType.None + : DiffSelectionType.All + + const selection = DiffSelection.fromInitialSelection(initialSelectionType) files.set( entry.path, From 9fa0028c394aa93f4c07a07467db3eefa8c3c07e Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 08:29:16 -0400 Subject: [PATCH 046/111] Create unreachable-commits.md first draft --- docs/learn-more/unreachable-commits.md | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/learn-more/unreachable-commits.md diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md new file mode 100644 index 0000000000..1f0a812582 --- /dev/null +++ b/docs/learn-more/unreachable-commits.md @@ -0,0 +1,72 @@ +# Reachable and Unreachable Commits + +In Git, every commit will have at least one parent commit except the very first. Additionally, a repository may have any number of branches that begin at any particular commit. Because of this we can create a graph of the history of a commit by following the path from one commit's parent to the another. Given a branch `development`, whose initial commit is `A`, and I add commit `B` and `C`. A resulting graph would be as follows: + +``` +development +C +| +B +| +A +``` + +Since we can follow the graph from `C` to `A`, that means that `A` is `reachable` by or from `C`. This as known as following the ancestral path of `C`. + +Now, if we create a new branch called `feature-branch` from `C` and commit `D` and `E` and then return to `development` and commit `F`. We would have the resulting graph: +``` +development +F +| E +| | <-- feature-branch +| D +| / +C +| +B +| +A +``` + +Here A is reachable by F through F, C, B, A and A is reachable by E through E, D, C, B, A. However, E, and D are not reachable by F. Thus, they are unreachable through their ancestral path. + + +Now, lets say we merge the `feature-branch` into our `development` branch. Our graph becomes: + +G +| \ +F | +| E +| | +| D +| / +C +| +B +| +A + +Still E and D are unreachable by F. There are a few git commands that use the ancestral path to determine what to show. One of those is `git diff`. If you `git diff` two commits such as `git diff A..C`, you will receive the set of changes from commits if you traverse the graph from C to A. Thus, changes from A, B, C. + +If you `git diff A..F`, you will likewise get changes from A,B,C,F. + +In GitHub Desktop, this may feel confusing becuase Desktop displays the commits in chronological order. Thus, you will see a list that looks like a collapsed graph. + +G +| +F +| +E +| +D +| +C +| +B +| +A + +Thus, when you select F through A to see a diff of F to A, you may initially expect to see changes from E and D, but you won't because those changes are `unreachable` from F. + + + From 5b5d50b792c84bb849eba1db6e961ad9a87cbd85 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 08:35:24 -0400 Subject: [PATCH 047/111] Moving around some stuff --- docs/learn-more/unreachable-commits.md | 35 +++++++++++--------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 1f0a812582..284232f40d 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -11,7 +11,7 @@ B A ``` -Since we can follow the graph from `C` to `A`, that means that `A` is `reachable` by or from `C`. This as known as following the ancestral path of `C`. +Since we can follow the graph from `C` to `A`, that means that `A` is **reachable** by or from `C`. This as known as following the ancestral path of `C`. Now, if we create a new branch called `feature-branch` from `C` and commit `D` and `E` and then return to `development` and commit `F`. We would have the resulting graph: ``` @@ -28,11 +28,14 @@ B A ``` -Here A is reachable by F through F, C, B, A and A is reachable by E through E, D, C, B, A. However, E, and D are not reachable by F. Thus, they are unreachable through their ancestral path. +In the above example, `A` is reachable by `F` through the ancestral path of `F`-> `C` -> `B` -> `A` and `A` is reachable by `E` through `E` -> `D` -> `C` -> `B` -> `A`. However, there is no such path to get to `E` or `D` from `F`. Thus, `E` and `D` are **unreachable** from `F`. +There are a few git commands that use the ancestral path to determine what to show. One of those is `git diff`, which used to see the changes between two commits (non inclusive of the first commit). If we execute `git diff A..C`, we will receive the set of changes from commits if we wereto traverse the ancestral path from `C` to `A` or `C` -> `B` -> `A`. Thus, we would see changes from `B` and `C`. Likewise, if we executed `git diff A..F`, you will likewise get changes from reachable from `F`; thus, `F` -> `C` -> `B` -> `A`. But, not changes from `E` and `D` as they are unreachable. + +## Merge Commits Now, lets say we merge the `feature-branch` into our `development` branch. Our graph becomes: - +``` G | \ F | @@ -45,28 +48,18 @@ C B | A +``` -Still E and D are unreachable by F. There are a few git commands that use the ancestral path to determine what to show. One of those is `git diff`. If you `git diff` two commits such as `git diff A..C`, you will receive the set of changes from commits if you traverse the graph from C to A. Thus, changes from A, B, C. +Still `E` and `D` are unreachable by `F`. Thus, the previous statements are still true. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`. This is true if you include the commit that connects them. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits are ancestors of `G`. Thus, if we were to `git diff A..G`. We will see changes of all ancestral paths of `G` to `A`. Those paths are `G` -> `F` -> `C` -> `B` -> `A` and `G`-> `E` -> `D` -> `C` -> `B` -> `A`. Therefore we will see changes from `G`, `F`, `E`, `D`, `C`, and `B`. -If you `git diff A..F`, you will likewise get changes from A,B,C,F. +# GitHub Desktop +In GitHub Desktop, diffing across multiple commits on a branch with merges may sometimes result in diffs that have unreachable commits in the selection, because the commits are displayed chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: + +[Image from Desktop Here] + +Thus, when you select `F` through `A` to see a diff of `F` to `A` or `git diff A..F`, you may initially expect to see changes from `E` and `D`, but you won't because those changes are unreachable from `F`. -In GitHub Desktop, this may feel confusing becuase Desktop displays the commits in chronological order. Thus, you will see a list that looks like a collapsed graph. -G -| -F -| -E -| -D -| -C -| -B -| -A - -Thus, when you select F through A to see a diff of F to A, you may initially expect to see changes from E and D, but you won't because those changes are `unreachable` from F. From e904491fecb6361f694a8d18c0b7cf8742dfba58 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 08:54:51 -0400 Subject: [PATCH 048/111] Edits.. --- docs/learn-more/unreachable-commits.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 284232f40d..33d730a589 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -1,6 +1,6 @@ # Reachable and Unreachable Commits -In Git, every commit will have at least one parent commit except the very first. Additionally, a repository may have any number of branches that begin at any particular commit. Because of this we can create a graph of the history of a commit by following the path from one commit's parent to the another. Given a branch `development`, whose initial commit is `A`, and I add commit `B` and `C`. A resulting graph would be as follows: +In Git, every commit will have at least one parent commit except the very first. Additionally, a repository may have any number of branches that begin at any particular commit. Because of this we can create a graph of the history of a commit by following the path from one commit's parent to the another. Given a branch `development`, whose initial commit is `A`, and we add commit `B` and `C`. A resulting graph would be as follows: ``` development @@ -28,19 +28,20 @@ B A ``` -In the above example, `A` is reachable by `F` through the ancestral path of `F`-> `C` -> `B` -> `A` and `A` is reachable by `E` through `E` -> `D` -> `C` -> `B` -> `A`. However, there is no such path to get to `E` or `D` from `F`. Thus, `E` and `D` are **unreachable** from `F`. +In the above example, `B` is reachable by `F` through the ancestral path of `F`-> `C` -> `B` and `B` is reachable by `E` through `E` -> `D` -> `C` -> `B`. However, there is no such path to get to `E` or `D` from `F`. Thus, `E` and `D` are **unreachable** from `F`. -There are a few git commands that use the ancestral path to determine what to show. One of those is `git diff`, which used to see the changes between two commits (non inclusive of the first commit). If we execute `git diff A..C`, we will receive the set of changes from commits if we wereto traverse the ancestral path from `C` to `A` or `C` -> `B` -> `A`. Thus, we would see changes from `B` and `C`. Likewise, if we executed `git diff A..F`, you will likewise get changes from reachable from `F`; thus, `F` -> `C` -> `B` -> `A`. But, not changes from `E` and `D` as they are unreachable. +Some git commands use the ancestral path to determine what to show. One of those is `git diff`, which is used to see the changes between two commits non inclusive of the first commit. If we execute `git diff A..C`, we will receive the set of changes from the commits if we were to traverse the ancestral path from `C` to `A` or `C` -> `B` -> `A`. Thus, we would see changes from `B` and `C`. Likewise, if we executed `git diff B..F`, you will get changes from reachable from `F`; thus, `F` -> `C` -> `B`. But, not changes from `E` and `D` as they are unreachable. ## Merge Commits Now, lets say we merge the `feature-branch` into our `development` branch. Our graph becomes: ``` +development G | \ F | | E -| | +| | <-- feature-branch | D | / C @@ -50,10 +51,10 @@ B A ``` -Still `E` and `D` are unreachable by `F`. Thus, the previous statements are still true. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`. This is true if you include the commit that connects them. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits are ancestors of `G`. Thus, if we were to `git diff A..G`. We will see changes of all ancestral paths of `G` to `A`. Those paths are `G` -> `F` -> `C` -> `B` -> `A` and `G`-> `E` -> `D` -> `C` -> `B` -> `A`. Therefore we will see changes from `G`, `F`, `E`, `D`, `C`, and `B`. +Still `E` and `D` are unreachable by `F`. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`". This is true if you start at a commit that has them in it's ancestral path. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits in this graph are ancestors of `G`. Thus, if we were to execute `git diff B..G`. We will see changes of all ancestral paths of `G` to `A`. Those paths are `G` -> `F` -> `C` -> `B` and `G`-> `E` -> `D` -> `C` -> `B`. Therefore we will see changes from `G`, `F`, `E`, `D`, and `C`. # GitHub Desktop -In GitHub Desktop, diffing across multiple commits on a branch with merges may sometimes result in diffs that have unreachable commits in the selection, because the commits are displayed chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: +In GitHub Desktop diffing across multiple commits is accomplished through a range selection. This results in executing `git diff` from first to last commit in that selection. Therefore, generating diffs on a branches where multiple branches are merged may result in unreachable commits inside a diff selection. This is because the commits are displayed chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: [Image from Desktop Here] From cfb28d01c452a2aeeadc481cd75ef7d0411f8950 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:27:45 -0400 Subject: [PATCH 049/111] Adding images to #GitHub Desktop --- docs/learn-more/unreachable-commits.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 33d730a589..74add65875 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -54,11 +54,14 @@ A Still `E` and `D` are unreachable by `F`. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`". This is true if you start at a commit that has them in it's ancestral path. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits in this graph are ancestors of `G`. Thus, if we were to execute `git diff B..G`. We will see changes of all ancestral paths of `G` to `A`. Those paths are `G` -> `F` -> `C` -> `B` and `G`-> `E` -> `D` -> `C` -> `B`. Therefore we will see changes from `G`, `F`, `E`, `D`, and `C`. # GitHub Desktop -In GitHub Desktop diffing across multiple commits is accomplished through a range selection. This results in executing `git diff` from first to last commit in that selection. Therefore, generating diffs on a branches where multiple branches are merged may result in unreachable commits inside a diff selection. This is because the commits are displayed chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: +In GitHub Desktop, commits are displayed linearly and in chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: -[Image from Desktop Here] +![image](https://user-images.githubusercontent.com/75402236/186673232-8100fe29-4351-4a20-a96a-6043dd8d351d.png) + +In GitHub Desktop, diffing across multiple commits is accomplished through a range selection that results in executing `git diff` that shows the changes of comparing the first and last commit in the selection (inclusive). Therefore, generating diffs on a branches where merge commits exist may result in unreachable commits being inside a diff selection. The following shows the unreachable commit what the scenario described above in `Merge Commits`. + +https://user-images.githubusercontent.com/75402236/186671802-4ba49315-e25c-4a6c-93d1-70f2f24fbc19.mov -Thus, when you select `F` through `A` to see a diff of `F` to `A` or `git diff A..F`, you may initially expect to see changes from `E` and `D`, but you won't because those changes are unreachable from `F`. From 9334766cb3e46b56c4cfd905b4e5740fbe311b9f Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:30:03 -0400 Subject: [PATCH 050/111] Verbiage --- docs/learn-more/unreachable-commits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 74add65875..6a0b7fe2e0 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -31,7 +31,7 @@ A In the above example, `B` is reachable by `F` through the ancestral path of `F`-> `C` -> `B` and `B` is reachable by `E` through `E` -> `D` -> `C` -> `B`. However, there is no such path to get to `E` or `D` from `F`. Thus, `E` and `D` are **unreachable** from `F`. -Some git commands use the ancestral path to determine what to show. One of those is `git diff`, which is used to see the changes between two commits non inclusive of the first commit. If we execute `git diff A..C`, we will receive the set of changes from the commits if we were to traverse the ancestral path from `C` to `A` or `C` -> `B` -> `A`. Thus, we would see changes from `B` and `C`. Likewise, if we executed `git diff B..F`, you will get changes from reachable from `F`; thus, `F` -> `C` -> `B`. But, not changes from `E` and `D` as they are unreachable. +Some git commands use the ancestral path to determine what to show. One of those is `git diff`, which is used to see the changes between two commits non inclusive of the first commit. If we execute `git diff A..C`, we will receive the set of changes from the commits along the ancestral path from `C` to `A` or `C` -> `B` -> `A`. Thus, we would see changes from `B` and `C`. Likewise, if we executed `git diff B..F`, you will get changes from reachable from `F`; thus, `F` -> `C` -> `B`. But, not changes from `E` and `D` as they are unreachable. ## Merge Commits Now, lets say we merge the `feature-branch` into our `development` branch. Our graph becomes: From 66568b7e7c628083477d0ec38895acd36b9767ea Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:31:32 -0400 Subject: [PATCH 051/111] Add unreachable commits heading --- docs/learn-more/unreachable-commits.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 6a0b7fe2e0..cb62da6e74 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -13,6 +13,7 @@ A Since we can follow the graph from `C` to `A`, that means that `A` is **reachable** by or from `C`. This as known as following the ancestral path of `C`. +## Unreachable Commits Now, if we create a new branch called `feature-branch` from `C` and commit `D` and `E` and then return to `development` and commit `F`. We would have the resulting graph: ``` development From f858e568c93053c6b79f799ced441a3e32d139fc Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:35:20 -0400 Subject: [PATCH 052/111] Add Git command heading - correct typo --- docs/learn-more/unreachable-commits.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index cb62da6e74..051bd6e841 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -31,7 +31,7 @@ A In the above example, `B` is reachable by `F` through the ancestral path of `F`-> `C` -> `B` and `B` is reachable by `E` through `E` -> `D` -> `C` -> `B`. However, there is no such path to get to `E` or `D` from `F`. Thus, `E` and `D` are **unreachable** from `F`. - +## Git Commands Use the Ancestral Path Some git commands use the ancestral path to determine what to show. One of those is `git diff`, which is used to see the changes between two commits non inclusive of the first commit. If we execute `git diff A..C`, we will receive the set of changes from the commits along the ancestral path from `C` to `A` or `C` -> `B` -> `A`. Thus, we would see changes from `B` and `C`. Likewise, if we executed `git diff B..F`, you will get changes from reachable from `F`; thus, `F` -> `C` -> `B`. But, not changes from `E` and `D` as they are unreachable. ## Merge Commits @@ -52,7 +52,7 @@ B A ``` -Still `E` and `D` are unreachable by `F`. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`". This is true if you start at a commit that has them in it's ancestral path. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits in this graph are ancestors of `G`. Thus, if we were to execute `git diff B..G`. We will see changes of all ancestral paths of `G` to `A`. Those paths are `G` -> `F` -> `C` -> `B` and `G`-> `E` -> `D` -> `C` -> `B`. Therefore we will see changes from `G`, `F`, `E`, `D`, and `C`. +Still `E` and `D` are unreachable by `F`. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`". This is true if you start at a commit that has them in it's ancestral path. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits in this graph are ancestors of `G`. Thus, if we were to execute `git diff B..G`. We will see changes of all ancestral paths of `G` to `B`. Those paths are `G` -> `F` -> `C` -> `B` and `G`-> `E` -> `D` -> `C` -> `B`. Therefore we will see changes from `G`, `F`, `E`, `D`, and `C`. # GitHub Desktop In GitHub Desktop, commits are displayed linearly and in chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: From fe7a9aa763825d05a64ebc3c3a9abb3c00e7f37f Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:36:21 -0400 Subject: [PATCH 053/111] Remove redundancy --- docs/learn-more/unreachable-commits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 051bd6e841..b16ac02278 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -55,7 +55,7 @@ A Still `E` and `D` are unreachable by `F`. But, you may think "I merged the `feature-branch` into `development`, I should be able to see changes from `E` and `D`". This is true if you start at a commit that has them in it's ancestral path. That is `G` and it is known as a **merge commit** and it is special in that it has two parents. The first is `E` as the last commit of the branch being merged and `F` as the last commit of the branch being merged into. Now, all the commits in this graph are ancestors of `G`. Thus, if we were to execute `git diff B..G`. We will see changes of all ancestral paths of `G` to `B`. Those paths are `G` -> `F` -> `C` -> `B` and `G`-> `E` -> `D` -> `C` -> `B`. Therefore we will see changes from `G`, `F`, `E`, `D`, and `C`. # GitHub Desktop -In GitHub Desktop, commits are displayed linearly and in chronological order. Thus, the graph from the section `Merge Commits` from the previous section would look like: +In GitHub Desktop, commits are displayed linearly and in chronological order. Thus, the graph from the previous section `Merge Commits` would look like: ![image](https://user-images.githubusercontent.com/75402236/186673232-8100fe29-4351-4a20-a96a-6043dd8d351d.png) From cade255d576708851dc60549a8808ab01a2f0d60 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:37:40 -0400 Subject: [PATCH 054/111] Typo --- docs/learn-more/unreachable-commits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index b16ac02278..5be669cfb2 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -59,7 +59,7 @@ In GitHub Desktop, commits are displayed linearly and in chronological order. Th ![image](https://user-images.githubusercontent.com/75402236/186673232-8100fe29-4351-4a20-a96a-6043dd8d351d.png) -In GitHub Desktop, diffing across multiple commits is accomplished through a range selection that results in executing `git diff` that shows the changes of comparing the first and last commit in the selection (inclusive). Therefore, generating diffs on a branches where merge commits exist may result in unreachable commits being inside a diff selection. The following shows the unreachable commit what the scenario described above in `Merge Commits`. +In GitHub Desktop, diffing across multiple commits is accomplished through a range selection that results in executing `git diff` that shows the changes of comparing the first and last commit in the selection (inclusive). Therefore, generating a diff on a branch where merge commits exist may result in unreachable commits being inside a diff selection. The following shows the unreachable commit what the scenario described above in `Merge Commits`. https://user-images.githubusercontent.com/75402236/186671802-4ba49315-e25c-4a6c-93d1-70f2f24fbc19.mov From 0488f0ce47389e4325cf43aaa9d71270fa65b8f1 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 09:38:50 -0400 Subject: [PATCH 055/111] Grammars --- docs/learn-more/unreachable-commits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/learn-more/unreachable-commits.md b/docs/learn-more/unreachable-commits.md index 5be669cfb2..293c97fc17 100644 --- a/docs/learn-more/unreachable-commits.md +++ b/docs/learn-more/unreachable-commits.md @@ -59,7 +59,7 @@ In GitHub Desktop, commits are displayed linearly and in chronological order. Th ![image](https://user-images.githubusercontent.com/75402236/186673232-8100fe29-4351-4a20-a96a-6043dd8d351d.png) -In GitHub Desktop, diffing across multiple commits is accomplished through a range selection that results in executing `git diff` that shows the changes of comparing the first and last commit in the selection (inclusive). Therefore, generating a diff on a branch where merge commits exist may result in unreachable commits being inside a diff selection. The following shows the unreachable commit what the scenario described above in `Merge Commits`. +In GitHub Desktop, diffing across multiple commits is accomplished through a range selection that results in executing `git diff` that shows the changes of comparing the first and last commit in the selection (inclusive). Therefore, generating a diff on a branch where merge commits exist may result in unreachable commits being inside a diff selection. The following shows the unreachable commit scenario described above in `Merge Commits`. https://user-images.githubusercontent.com/75402236/186671802-4ba49315-e25c-4a6c-93d1-70f2f24fbc19.mov From f5ff47daed41f1f2fdd538a3833a2e4f588ae692 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 11:39:18 -0400 Subject: [PATCH 056/111] Warn for eslint-plugin-primer-react errors --- .eslintrc.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.eslintrc.yml b/.eslintrc.yml index 00d9e1b7fb..22f847c2d2 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -30,6 +30,40 @@ rules: ########### # PLUGINS # ########### + + # Accessibility + # From: primer-react/recommended + 'jsx-a11y/alt-text': + - warn + 'jsx-a11y/click-events-have-key-events': + - warn + 'jsx-a11y/no-noninteractive-element-interactions': + - warn + 'jsx-a11y/no-static-element-interactions': + - warn + 'jsx-a11y/no-autofocus': + - warn + 'jsx-a11y/no-noninteractive-element-to-interactive-role': + - warn + 'jsx-a11y/aria-role': + - warn + 'jsx-a11y/aria-activedescendant-has-tabindex': + - warn + 'jsx-a11y/mouse-events-have-key-events': + - warn + 'jsx-a11y/label-has-associated-control': + - warn + 'jsx-a11y/anchor-is-valid': + - warn + 'jsx-a11y/iframe-has-title': + - warn + 'jsx-a11y/no-noninteractive-tabindex': + - warn + 'jsx-a11y/role-supports-aria-props': + - warn + 'jsx-a11y/interactive-supports-focus': + - warn + # TYPESCRIPT '@typescript-eslint/naming-convention': - error From a0120c5890739f5cdb6561a99957429fbc6abfd9 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Tue, 23 Aug 2022 15:02:58 -0400 Subject: [PATCH 057/111] Adding `github/recommended` --- .eslintrc.yml | 1 + package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/.eslintrc.yml b/.eslintrc.yml index 22f847c2d2..f8bdc75cde 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -16,6 +16,7 @@ extends: - plugin:@typescript-eslint/recommended - prettier/@typescript-eslint - plugin:primer-react/recommended + - plugin:github/recommended rules: ########## diff --git a/package.json b/package.json index 2de31457c0..0462da6616 100644 --- a/package.json +++ b/package.json @@ -158,6 +158,7 @@ "electron-builder": "^22.7.0", "electron-packager": "^15.1.0", "electron-winstaller": "^5.0.0", + "eslint-plugin-github": "^4.3.7", "eslint-plugin-primer-react": "^1.0.1", "jest-esm-transformer": "^1.0.0", "reserved-words": "^0.1.2", From db807bbdf7f40c57cad58d59458aec5ec44f629d Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 14:27:21 -0400 Subject: [PATCH 058/111] Turn off errors from `github/recommended` --- .eslintrc.yml | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/.eslintrc.yml b/.eslintrc.yml index f8bdc75cde..5220cf5870 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -65,6 +65,82 @@ rules: 'jsx-a11y/interactive-supports-focus': - warn + # From github/recommended + 'github/array-foreach': + - off + 'github/no-then': + - off + 'import/no-namespace': + - off + 'import/first': + - off + 'import/no-duplicates': + - off + 'import/no-commonjs': + - off + 'import/no-unresolved': + - off + 'import/no-dynamic-require': + - off + 'import/named': + - off + 'import/extensions': + - off + 'eslint-comments/no-use': + - off + 'eslint-comments/no-unused-disable': + - off + 'eslint-comments/no-duplicate-disable': + - off + 'filenames/match-regex': + - off + 'i18n-text/no-en': + - off + 'no-only-tests/no-only-tests': + - off + 'no-console': + - off + 'no-undef': + - off + 'prefer-promise-reject-errors': + - off + 'no-shadow': + - off + 'no-case-declarations': + - off + 'no-unused-vars': + - off + 'no-invalid-this': + - off + 'camelcase': + - off + 'prefer-template': + - off + 'no-useless-escape': + - off + 'one-var': + - off + 'object-shorthand': + - off + 'func-style': + - off + 'no-useless-concat': + - off + 'no-extra-boolean-cast': + - off + 'no-control-regex': + - off + 'no-empty': + - off + 'no-ex-assign': + - off + 'no-fallthrough': + - off + 'no-irregular-whitespace': + - off + 'no-dupe-class-members': + - off + # TYPESCRIPT '@typescript-eslint/naming-convention': - error From 41c7883c38a316c724ed5f269c9ae5c23f66476c Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 15:13:43 -0400 Subject: [PATCH 059/111] Use github/react not github/recommended --- .eslintrc.yml | 78 +-------------------------------------------------- 1 file changed, 1 insertion(+), 77 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 5220cf5870..00ef270603 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -16,7 +16,7 @@ extends: - plugin:@typescript-eslint/recommended - prettier/@typescript-eslint - plugin:primer-react/recommended - - plugin:github/recommended + - plugin:github/react rules: ########## @@ -65,82 +65,6 @@ rules: 'jsx-a11y/interactive-supports-focus': - warn - # From github/recommended - 'github/array-foreach': - - off - 'github/no-then': - - off - 'import/no-namespace': - - off - 'import/first': - - off - 'import/no-duplicates': - - off - 'import/no-commonjs': - - off - 'import/no-unresolved': - - off - 'import/no-dynamic-require': - - off - 'import/named': - - off - 'import/extensions': - - off - 'eslint-comments/no-use': - - off - 'eslint-comments/no-unused-disable': - - off - 'eslint-comments/no-duplicate-disable': - - off - 'filenames/match-regex': - - off - 'i18n-text/no-en': - - off - 'no-only-tests/no-only-tests': - - off - 'no-console': - - off - 'no-undef': - - off - 'prefer-promise-reject-errors': - - off - 'no-shadow': - - off - 'no-case-declarations': - - off - 'no-unused-vars': - - off - 'no-invalid-this': - - off - 'camelcase': - - off - 'prefer-template': - - off - 'no-useless-escape': - - off - 'one-var': - - off - 'object-shorthand': - - off - 'func-style': - - off - 'no-useless-concat': - - off - 'no-extra-boolean-cast': - - off - 'no-control-regex': - - off - 'no-empty': - - off - 'no-ex-assign': - - off - 'no-fallthrough': - - off - 'no-irregular-whitespace': - - off - 'no-dupe-class-members': - - off - # TYPESCRIPT '@typescript-eslint/naming-convention': - error From ec2cf7657d7d97347cc2b9610aa021ae68f8658e Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 15:30:16 -0400 Subject: [PATCH 060/111] Revert eslint-plugin-primer-react --- .eslintrc.yml | 1 - package.json | 2 - yarn.lock | 712 +------------------------------------------------- 3 files changed, 8 insertions(+), 707 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index 00ef270603..cc9284d3fe 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -15,7 +15,6 @@ extends: - prettier/react - plugin:@typescript-eslint/recommended - prettier/@typescript-eslint - - plugin:primer-react/recommended - plugin:github/react rules: diff --git a/package.json b/package.json index 0462da6616..8d8798ab3e 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,6 @@ "xml2js": "^0.4.16" }, "devDependencies": { - "@primer/primitives": "^7.9.0", "@types/byline": "^4.2.31", "@types/classnames": "^2.2.2", "@types/codemirror": "5.60.4", @@ -159,7 +158,6 @@ "electron-packager": "^15.1.0", "electron-winstaller": "^5.0.0", "eslint-plugin-github": "^4.3.7", - "eslint-plugin-primer-react": "^1.0.1", "jest-esm-transformer": "^1.0.0", "reserved-words": "^0.1.2", "tsconfig-paths": "^3.9.0" diff --git a/yarn.lock b/yarn.lock index 895c92dff8..f4e1a41ff3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -419,21 +419,6 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/runtime-corejs3@^7.10.2": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz#7bacecd1cb2dd694eacd32a91fcf7021c20770ae" - integrity sha512-qZEWeccZCrHA2Au4/X05QW5CMdm4VjUDCrGq5gf1ZDcM4hRqreKrtwAn7yci9zfgAS9apvnsFXiGBHBAxZdK9A== - dependencies: - core-js-pure "^3.20.2" - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.2", "@babel/runtime@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" - integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/template@^7.10.4", "@babel/template@^7.12.7", "@babel/template@^7.3.3": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" @@ -867,11 +852,6 @@ dependencies: object-assign "^4.1.1" -"@primer/primitives@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@primer/primitives/-/primitives-7.9.0.tgz#c8a27287488c8308b1715a7d73214629c331544a" - integrity sha512-ZHHfwB0z0z6nDJp263gyGIClYDy+rl0nwqyi4qhcv3Cxhkmtf+If2KVjr6FQqBBFfi1wQwUzaax2FBvfEMFBnw== - "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -891,103 +871,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@styled-system/background@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/background/-/background-5.1.2.tgz#75c63d06b497ab372b70186c0bf608d62847a2ba" - integrity sha512-jtwH2C/U6ssuGSvwTN3ri/IyjdHb8W9X/g8Y0JLcrH02G+BW3OS8kZdHphF1/YyRklnrKrBT2ngwGUK6aqqV3A== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/border@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@styled-system/border/-/border-5.1.5.tgz#0493d4332d2b59b74bb0d57d08c73eb555761ba6" - integrity sha512-JvddhNrnhGigtzWRCVuAHepniyVi6hBlimxWDVAdcTuk7aRn9BYJUwfHslURtwYFsF5FoEs8Zmr1oZq2M1AP0A== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/color@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/color/-/color-5.1.2.tgz#b8d6b4af481faabe4abca1a60f8daa4ccc2d9f43" - integrity sha512-1kCkeKDZkt4GYkuFNKc7vJQMcOmTl3bJY3YBUs7fCNM6mMYJeT1pViQ2LwBSBJytj3AB0o4IdLBoepgSgGl5MA== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/core@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/core/-/core-5.1.2.tgz#b8b7b86455d5a0514f071c4fa8e434b987f6a772" - integrity sha512-XclBDdNIy7OPOsN4HBsawG2eiWfCcuFt6gxKn1x4QfMIgeO6TOlA2pZZ5GWZtIhCUqEPTgIBta6JXsGyCkLBYw== - dependencies: - object-assign "^4.1.1" - -"@styled-system/css@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@styled-system/css/-/css-5.1.5.tgz#0460d5f3ff962fa649ea128ef58d9584f403bbbc" - integrity sha512-XkORZdS5kypzcBotAMPBoeckDs9aSZVkvrAlq5K3xP8IMAUek+x2O4NtwoSgkYkWWzVBu6DGdFZLR790QWGG+A== - -"@styled-system/flexbox@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/flexbox/-/flexbox-5.1.2.tgz#077090f43f61c3852df63da24e4108087a8beecf" - integrity sha512-6hHV52+eUk654Y1J2v77B8iLeBNtc+SA3R4necsu2VVinSD7+XY5PCCEzBFaWs42dtOEDIa2lMrgL0YBC01mDQ== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/grid@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/grid/-/grid-5.1.2.tgz#7165049877732900b99cd00759679fbe45c6c573" - integrity sha512-K3YiV1KyHHzgdNuNlaw8oW2ktMuGga99o1e/NAfTEi5Zsa7JXxzwEnVSDSBdJC+z6R8WYTCYRQC6bkVFcvdTeg== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/layout@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/layout/-/layout-5.1.2.tgz#12d73e79887e10062f4dbbbc2067462eace42339" - integrity sha512-wUhkMBqSeacPFhoE9S6UF3fsMEKFv91gF4AdDWp0Aym1yeMPpqz9l9qS/6vjSsDPF7zOb5cOKC3tcKKOMuDCPw== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/position@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/position/-/position-5.1.2.tgz#56961266566836f57a24d8e8e33ce0c1adb59dd3" - integrity sha512-60IZfMXEOOZe3l1mCu6sj/2NAyUmES2kR9Kzp7s2D3P4qKsZWxD1Se1+wJvevb+1TP+ZMkGPEYYXRyU8M1aF5A== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/props@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@styled-system/props/-/props-5.1.5.tgz#f50bf40e8fc8393726f06cbcd096a39a7d779ce4" - integrity sha512-FXhbzq2KueZpGaHxaDm8dowIEWqIMcgsKs6tBl6Y6S0njG9vC8dBMI6WSLDnzMoSqIX3nSKHmOmpzpoihdDewg== - dependencies: - styled-system "^5.1.5" - -"@styled-system/shadow@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/shadow/-/shadow-5.1.2.tgz#beddab28d7de03cd0177a87ac4ed3b3b6d9831fd" - integrity sha512-wqniqYb7XuZM7K7C0d1Euxc4eGtqEe/lvM0WjuAFsQVImiq6KGT7s7is+0bNI8O4Dwg27jyu4Lfqo/oIQXNzAg== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/space@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/space/-/space-5.1.2.tgz#38925d2fa29a41c0eb20e65b7c3efb6e8efce953" - integrity sha512-+zzYpR8uvfhcAbaPXhH8QgDAV//flxqxSjHiS9cDFQQUSznXMQmxJegbhcdEF7/eNnJgHeIXv1jmny78kipgBA== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/typography@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@styled-system/typography/-/typography-5.1.2.tgz#65fb791c67d50cd2900d234583eaacdca8c134f7" - integrity sha512-BxbVUnN8N7hJ4aaPOd7wEsudeT7CxarR+2hns8XCX1zp0DFfbWw4xYa/olA0oQaqx7F1hzDg+eRaGzAJbF+jOg== - dependencies: - "@styled-system/core" "^5.1.2" - -"@styled-system/variant@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@styled-system/variant/-/variant-5.1.5.tgz#8446d8aad06af3a4c723d717841df2dbe4ddeafd" - integrity sha512-Yn8hXAFoWIro8+Q5J8YJd/mP85Teiut3fsGVR9CAxwgNfIAiqlYxsk5iHU7VHJks/0KjL4ATSjmbtCDC/4l1qw== - dependencies: - "@styled-system/core" "^5.1.2" - "@styled-system/css" "^5.1.5" - "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -1603,21 +1486,6 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@^5.1.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.34.0.tgz#d690f60e335596f38b01792e8f4b361d9bd0cb35" - integrity sha512-eRfPPcasO39iwjlUAMtjeueRGuIrW3TQ9WseIDl7i5UWuFbf83yYaU7YPs4j8+4CxUMIsj1k+4kV+E+G+6ypDQ== - dependencies: - "@typescript-eslint/scope-manager" "5.34.0" - "@typescript-eslint/type-utils" "5.34.0" - "@typescript-eslint/utils" "5.34.0" - debug "^4.3.4" - functional-red-black-tree "^1.0.1" - ignore "^5.2.0" - regexpp "^3.2.0" - semver "^7.3.7" - tsutils "^3.21.0" - "@typescript-eslint/eslint-plugin@^5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz#f8c1d59fc37bd6d9d11c97267fdfe722c4777152" @@ -1640,16 +1508,6 @@ dependencies: "@typescript-eslint/utils" "5.10.2" -"@typescript-eslint/parser@^5.1.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.34.0.tgz#ca710858ea85dbfd30c9b416a335dc49e82dbc07" - integrity sha512-SZ3NEnK4usd2CXkoV3jPa/vo1mWX1fqRyIVUQZR4As1vyp4fneknBNJj+OFtV8WAVgGf+rOHMSqQbs2Qn3nFZQ== - dependencies: - "@typescript-eslint/scope-manager" "5.34.0" - "@typescript-eslint/types" "5.34.0" - "@typescript-eslint/typescript-estree" "5.34.0" - debug "^4.3.4" - "@typescript-eslint/parser@^5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.2.tgz#b6076d27cc5499ce3f2c625f5ccde946ecb7db9a" @@ -1668,14 +1526,6 @@ "@typescript-eslint/types" "5.10.2" "@typescript-eslint/visitor-keys" "5.10.2" -"@typescript-eslint/scope-manager@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.34.0.tgz#14efd13dc57602937e25f188fd911f118781e527" - integrity sha512-HNvASMQlah5RsBW6L6c7IJ0vsm+8Sope/wu5sEAf7joJYWNb1LDbJipzmdhdUOnfrDFE6LR1j57x1EYVxrY4ow== - dependencies: - "@typescript-eslint/types" "5.34.0" - "@typescript-eslint/visitor-keys" "5.34.0" - "@typescript-eslint/type-utils@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz#ad5acdf98a7d2ab030bea81f17da457519101ceb" @@ -1685,25 +1535,11 @@ debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/type-utils@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.34.0.tgz#7a324ab9ddd102cd5e1beefc94eea6f3eb32d32d" - integrity sha512-Pxlno9bjsQ7hs1pdWRUv9aJijGYPYsHpwMeCQ/Inavhym3/XaKt1ZKAA8FIw4odTBfowBdZJDMxf2aavyMDkLg== - dependencies: - "@typescript-eslint/utils" "5.34.0" - debug "^4.3.4" - tsutils "^3.21.0" - "@typescript-eslint/types@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.2.tgz#604d15d795c4601fffba6ecb4587ff9fdec68ce8" integrity sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w== -"@typescript-eslint/types@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.34.0.tgz#217bf08049e9e7b86694d982e88a2c1566330c78" - integrity sha512-49fm3xbbUPuzBIOcy2CDpYWqy/X7VBkxVN+DC21e0zIm3+61Z0NZi6J9mqPmSW1BDVk9FIOvuCFyUPjXz93sjA== - "@typescript-eslint/typescript-estree@5.10.2", "@typescript-eslint/typescript-estree@^5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz#810906056cd3ddcb35aa333fdbbef3713b0fe4a7" @@ -1717,19 +1553,6 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.34.0.tgz#ba7b83f4bf8ccbabf074bbf1baca7a58de3ccb9a" - integrity sha512-mXHAqapJJDVzxauEkfJI96j3D10sd567LlqroyCeJaHnu42sDbjxotGb3XFtGPYKPD9IyLjhsoULML1oI3M86A== - dependencies: - "@typescript-eslint/types" "5.34.0" - "@typescript-eslint/visitor-keys" "5.34.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - "@typescript-eslint/utils@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.2.tgz#1fcd37547c32c648ab11aea7173ec30060ee87a8" @@ -1742,18 +1565,6 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/utils@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.34.0.tgz#0cae98f48d8f9e292e5caa9343611b6faf49e743" - integrity sha512-kWRYybU4Rn++7lm9yu8pbuydRyQsHRoBDIo11k7eqBWTldN4xUdVUMCsHBiE7aoEkFzrUEaZy3iH477vr4xHAQ== - dependencies: - "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.34.0" - "@typescript-eslint/types" "5.34.0" - "@typescript-eslint/typescript-estree" "5.34.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - "@typescript-eslint/visitor-keys@5.10.2": version "5.10.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz#fdbf272d8e61c045d865bd6c8b41bea73d222f3d" @@ -1762,14 +1573,6 @@ "@typescript-eslint/types" "5.10.2" eslint-visitor-keys "^3.0.0" -"@typescript-eslint/visitor-keys@5.34.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.34.0.tgz#d0fb3e31033e82ddd5de048371ad39eb342b2d40" - integrity sha512-O1moYjOSrab0a2fUvFpsJe0QHtvTC+cR+ovYpgKrAVXzqQyc74mv76TgY6z+aEtjQE2vgZux3CQVtGryqdcOAw== - dependencies: - "@typescript-eslint/types" "5.34.0" - eslint-visitor-keys "^3.3.0" - "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" @@ -2191,14 +1994,6 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -2238,17 +2033,6 @@ array-includes@^3.1.3: get-intrinsic "^1.1.1" is-string "^1.0.7" -array-includes@^3.1.4, array-includes@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" - integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -2268,16 +2052,6 @@ array.prototype.flat@^1.2.1: es-abstract "^1.10.0" function-bind "^1.1.1" -array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" - es-shim-unscopables "^1.0.0" - array.prototype.flatmap@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.1.tgz#3103cd4826ef90019c9b0a4839b2535fa6faf4e9" @@ -2348,11 +2122,6 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== - astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -2405,16 +2174,6 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -axe-core@^4.4.3: - version "4.4.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" - integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - azure-storage@^2.10.4: version "2.10.4" resolved "https://registry.yarnpkg.com/azure-storage/-/azure-storage-2.10.4.tgz#c481d207eabc05f57f019b209f7faa8737435104" @@ -2666,16 +2425,6 @@ browserslist@^4.14.5, browserslist@^4.17.5: node-releases "^2.0.1" picocolors "^1.0.0" -browserslist@^4.21.0: - version "4.21.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" - integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== - dependencies: - caniuse-lite "^1.0.30001370" - electron-to-chromium "^1.4.202" - node-releases "^2.0.6" - update-browserslist-db "^1.0.5" - bs-logger@0.x: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -2812,11 +2561,6 @@ caniuse-lite@^1.0.30001286: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz#0e690039f62e91c3ea581673d716890512e7ec52" integrity sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ== -caniuse-lite@^1.0.30001370: - version "1.0.30001382" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz#4d37f0d0b6fffb826c8e5e1c0f4bf8ce592db949" - integrity sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg== - capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -3143,11 +2887,6 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-pure@^3.20.2: - version "3.24.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.24.1.tgz#8839dde5da545521bf282feb7dc6d0b425f39fd3" - integrity sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg== - core-js@^2.4.1, core-js@^2.5.3: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -3267,11 +3006,6 @@ cuint@^0.2.2: resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b" integrity sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs= -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3295,7 +3029,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.3.4: +debug@4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -3309,13 +3043,6 @@ debug@^3.1.0: dependencies: ms "2.0.0" -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - debug@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" @@ -3403,14 +3130,6 @@ define-properties@^1.1.2, define-properties@^1.1.3: dependencies: object-keys "^1.0.12" -define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -3712,11 +3431,6 @@ electron-to-chromium@^1.4.17: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.40.tgz#f5dbced7bfbc7072e5e7ca5487f8f9a42c8bc768" integrity sha512-j+eVIyQGt2EU5xPWUblhpp5P5z5xyAdRgzogBgfe2F5JGV17gr9pfzWBua6DlPL00LavbOjxubWkWkbVQe9Wlw== -electron-to-chromium@^1.4.202: - version "1.4.227" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.227.tgz#28e46e2a701fed3188db3ca7bf0a3a475e484046" - integrity sha512-I9VVajA3oswIJOUFg2PSBqrHLF5Y+ahIfjOV9+v6uYyBqFZutmPxA6fxocDUUmgwYevRWFu1VjLyVG3w45qa/g== - electron-winstaller@*, electron-winstaller@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/electron-winstaller/-/electron-winstaller-5.0.0.tgz#0db968f34d498b16c69566a40848f562e70e7bcc" @@ -3757,11 +3471,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -3867,35 +3576,6 @@ es-abstract@^1.19.0, es-abstract@^1.19.1: string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.1" -es-abstract@^1.19.2, es-abstract@^1.19.5: - version "1.20.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" - integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - regexp.prototype.flags "^1.4.3" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" @@ -3912,13 +3592,6 @@ es-module-lexer@^0.9.0: resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - es-to-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" @@ -3994,11 +3667,6 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@>=8.0.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" - integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== - eslint-config-prettier@^6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz#f6d2238c1290d01c859a8b5c1f7d352a0b0da8b1" @@ -4006,91 +3674,6 @@ eslint-config-prettier@^6.11.0: dependencies: get-stdin "^6.0.0" -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== - dependencies: - debug "^3.2.7" - -eslint-plugin-escompat@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-escompat/-/eslint-plugin-escompat-3.2.0.tgz#7d40efe8721d8fccb5d300f4fbda44f350a27301" - integrity sha512-obXAKKiZE/wB2fgIw0ZxCmp+8vpDsUw2inkaok1i7OVxY4cEds4Y9YCoky0f5V+q8rqZpTUJDv1R9ykWbXLX8Q== - dependencies: - browserslist "^4.21.0" - -eslint-plugin-eslint-comments@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz#9e1cd7b4413526abb313933071d7aba05ca12ffa" - integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== - dependencies: - escape-string-regexp "^1.0.5" - ignore "^5.0.5" - -eslint-plugin-filenames@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz#7094f00d7aefdd6999e3ac19f72cea058e590cf7" - integrity sha512-tqxJTiEM5a0JmRCUYQmxw23vtTxrb2+a3Q2mMOPhFxvt7ZQQJmdiuMby9B/vUAuVMghyP7oET+nIf6EO6CBd/w== - dependencies: - lodash.camelcase "4.3.0" - lodash.kebabcase "4.1.1" - lodash.snakecase "4.1.1" - lodash.upperfirst "4.3.1" - -eslint-plugin-github@^4.3.7: - version "4.3.7" - resolved "https://registry.yarnpkg.com/eslint-plugin-github/-/eslint-plugin-github-4.3.7.tgz#596416a81240dcd1d3ba1cab6ddfed0a1827bf1a" - integrity sha512-tYZdXvAEz4JCMrC4NHIUoJTsLUvydCxff5OqB5hgU0vQbLmMkw6VOipN2KNe+T06pEhAWs1KBEwyq9cmMWRe7A== - dependencies: - "@typescript-eslint/eslint-plugin" "^5.1.0" - "@typescript-eslint/parser" "^5.1.0" - eslint-config-prettier ">=8.0.0" - eslint-plugin-escompat "^3.1.0" - eslint-plugin-eslint-comments "^3.2.0" - eslint-plugin-filenames "^1.3.2" - eslint-plugin-i18n-text "^1.0.1" - eslint-plugin-import "^2.25.2" - eslint-plugin-jsx-a11y "^6.6.0" - eslint-plugin-no-only-tests "^2.6.0" - eslint-plugin-prettier "^4.0.0" - eslint-rule-documentation ">=1.0.0" - jsx-ast-utils "^3.3.2" - prettier "^2.2.1" - svg-element-attributes "^1.3.1" - -eslint-plugin-i18n-text@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz#69ce14f9af7d135cbe8114b1b144a57bb83291dc" - integrity sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA== - -eslint-plugin-import@^2.25.2: - version "2.26.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" - has "^1.0.3" - is-core-module "^2.8.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - eslint-plugin-jsdoc@^37.7.0: version "37.7.0" resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-37.7.0.tgz#975d9f18cb0520dde7a2b0db5f4421dfee3fdd17" @@ -4113,30 +3696,6 @@ eslint-plugin-json@^2.1.1: lodash "^4.17.19" vscode-json-languageservice "^3.7.0" -eslint-plugin-jsx-a11y@^6.6.0, eslint-plugin-jsx-a11y@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" - integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== - dependencies: - "@babel/runtime" "^7.18.9" - aria-query "^4.2.2" - array-includes "^3.1.5" - ast-types-flow "^0.0.7" - axe-core "^4.4.3" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.2" - language-tags "^1.0.5" - minimatch "^3.1.2" - semver "^6.3.0" - -eslint-plugin-no-only-tests@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-2.6.0.tgz#19f6c9620bda02b9b9221b436c5f070e42628d76" - integrity sha512-T9SmE/g6UV1uZo1oHAqOvL86XWl7Pl2EpRpnLI8g/bkJu+h7XBCB+1LnubRZ2CUQXj805vh4/CYZdnqtVaEo2Q== - eslint-plugin-prettier@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz#168ab43154e2ea57db992a2cd097c828171f75c2" @@ -4144,25 +3703,6 @@ eslint-plugin-prettier@^3.1.4: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-prettier@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" - integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-plugin-primer-react@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-primer-react/-/eslint-plugin-primer-react-1.0.1.tgz#4883b2555d874a5993fd8ddcf4beb3e78d428da5" - integrity sha512-c2qL7LwGl8ZR3Iw/fCt9sll3Cjvkju7dhJPBWdwl0YPe+h69zX1dtOFonMFCrLDBJVU9crYtNr9wQHeQUxY2oA== - dependencies: - "@styled-system/props" "^5.1.5" - eslint-plugin-github "^4.3.7" - eslint-plugin-jsx-a11y "^6.6.1" - eslint-traverse "^1.0.0" - lodash "^4.17.21" - styled-system "^5.1.5" - eslint-plugin-react@7.26.1: version "7.26.1" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e" @@ -4183,11 +3723,6 @@ eslint-plugin-react@7.26.1: semver "^6.3.0" string.prototype.matchall "^4.0.5" -eslint-rule-documentation@>=1.0.0: - version "1.0.23" - resolved "https://registry.yarnpkg.com/eslint-rule-documentation/-/eslint-rule-documentation-1.0.23.tgz#4e0886145597a78d24524ec7e0cf18c6fedc23a8" - integrity sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw== - eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -4204,11 +3739,6 @@ eslint-scope@^5.1.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-traverse/-/eslint-traverse-1.0.0.tgz#108d360a171a6e6334e1af0cee905a93bd0dcc53" - integrity sha512-bSp37rQs93LF8rZ409EI369DGCI4tELbFVmFNxI6QbuveS7VRxYVyUhwDafKN/enMyUh88HQQ7ZoGUHtPuGdcw== - eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" @@ -4243,11 +3773,6 @@ eslint-visitor-keys@^3.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz#6fbb166a6798ee5991358bc2daa1ba76cc1254a1" integrity sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ== -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - eslint@^7.3.1: version "7.6.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.6.0.tgz#522d67cfaea09724d96949c70e7a0550614d64d6" @@ -4826,26 +4351,11 @@ function.prototype.name@^1.1.0: function-bind "^1.1.1" is-callable "^1.1.3" -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - galactus@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/galactus/-/galactus-0.2.1.tgz#cbed2d20a40c1f5679a35908e2b9415733e78db9" @@ -5037,7 +4547,7 @@ globalthis@^1.0.1: dependencies: define-properties "^1.1.3" -globby@^11.0.4, globby@^11.1.0: +globby@^11.0.4: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -5123,11 +4633,6 @@ has-bigints@^1.0.1: resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== -has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" @@ -5143,13 +4648,6 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - has-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" @@ -5165,11 +4663,6 @@ has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -5374,7 +4867,7 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.0.5, ignore@^5.1.8, ignore@^5.2.0: +ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== @@ -5551,13 +5044,6 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" - integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== - dependencies: - has "^1.0.3" - is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -5656,7 +5142,7 @@ is-installed-globally@^0.3.1: global-dirs "^2.0.1" is-path-inside "^3.0.1" -is-negative-zero@^2.0.1, is-negative-zero@^2.0.2: +is-negative-zero@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== @@ -5739,13 +5225,6 @@ is-shared-array-buffer@^1.0.1: resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -5792,7 +5271,7 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= -is-weakref@^1.0.1, is-weakref@^1.0.2: +is-weakref@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== @@ -6589,14 +6068,6 @@ jsprim@^1.2.2: array-includes "^3.1.3" object.assign "^4.1.2" -jsx-ast-utils@^3.3.2: - version "3.3.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== - dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" - jszip@^3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.7.1.tgz#bd63401221c15625a1228c556ca8a68da6fda3d9" @@ -6660,18 +6131,6 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== - dependencies: - language-subtag-registry "~0.3.2" - latest-version@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" @@ -6790,11 +6249,6 @@ lodash.assign@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= -lodash.camelcase@4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - lodash.endswith@^4.0.1: version "4.2.1" resolved "https://registry.yarnpkg.com/lodash.endswith/-/lodash.endswith-4.2.1.tgz#fed59ac1738ed3e236edd7064ec456448b37bc09" @@ -6810,21 +6264,11 @@ lodash.get@^4.0.0: resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= -lodash.kebabcase@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" - integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== - lodash.memoize@4.x: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= -lodash.snakecase@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -6845,11 +6289,6 @@ lodash.templatesettings@^4.0.0: dependencies: lodash._reinterpolate "~3.0.0" -lodash.upperfirst@4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" - integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== - lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -7099,7 +6538,7 @@ mini-css-extract-plugin@^2.5.3: dependencies: schema-utils "^4.0.0" -minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.4: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -7128,11 +6567,6 @@ minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minimist@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" - integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== - mixin-deep@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.2.0.tgz#d02b8c6f8b6d4b8f5982d3fd009c4919851c3fe2" @@ -7272,11 +6706,6 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== -node-releases@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" - integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== - normalize-package-data@^2.0.0, normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" @@ -7372,11 +6801,6 @@ object-inspect@^1.11.0, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-inspect@^1.12.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -7409,16 +6833,6 @@ object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.assign@^4.1.3: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - object.entries@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" @@ -7490,7 +6904,7 @@ object.values@^1.0.4: function-bind "^1.1.0" has "^1.0.1" -object.values@^1.1.4, object.values@^1.1.5: +object.values@^1.1.4: version "1.1.5" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== @@ -7720,7 +7134,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.5, path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.5, path-parse@^1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -7881,11 +7295,6 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.2.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== - prettier@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" @@ -8249,11 +7658,6 @@ realistic-structured-clone@^2.0.1: typeson "^5.8.2" typeson-registry "^1.0.0-alpha.20" -regenerator-runtime@^0.13.4: - version "0.13.9" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" - integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== - regex-not@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.0.tgz#42f83e39771622df826b02af176525d6a5f157f9" @@ -8284,15 +7688,6 @@ regexp.prototype.flags@^1.3.1: call-bind "^1.0.2" define-properties "^1.1.3" -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" @@ -8443,15 +7838,6 @@ resolve@^1.18.1: is-core-module "^2.1.0" path-parse "^1.0.6" -resolve@^1.20.0, resolve@^1.22.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - resolve@^2.0.0-next.3: version "2.0.0-next.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" @@ -8675,13 +8061,6 @@ semver@^7.3.4, semver@^7.3.5: dependencies: lru-cache "^6.0.0" -semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -9125,15 +8504,6 @@ string.prototype.trimend@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - string.prototype.trimstart@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" @@ -9142,15 +8512,6 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -9240,25 +8601,6 @@ style-loader@^3.3.1: resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== -styled-system@^5.1.5: - version "5.1.5" - resolved "https://registry.yarnpkg.com/styled-system/-/styled-system-5.1.5.tgz#e362d73e1dbb5641a2fd749a6eba1263dc85075e" - integrity sha512-7VoD0o2R3RKzOzPK0jYrVnS8iJdfkKsQJNiLRDjikOpQVqQHns/DXWaPZOH4tIKkhAT7I6wIsy9FWTWh2X3q+A== - dependencies: - "@styled-system/background" "^5.1.2" - "@styled-system/border" "^5.1.5" - "@styled-system/color" "^5.1.2" - "@styled-system/core" "^5.1.2" - "@styled-system/flexbox" "^5.1.2" - "@styled-system/grid" "^5.1.2" - "@styled-system/layout" "^5.1.2" - "@styled-system/position" "^5.1.2" - "@styled-system/shadow" "^5.1.2" - "@styled-system/space" "^5.1.2" - "@styled-system/typography" "^5.1.2" - "@styled-system/variant" "^5.1.5" - object-assign "^4.1.1" - sumchecker@^3.0.0, sumchecker@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-3.0.1.tgz#6377e996795abb0b6d348e9b3e1dfb24345a8e42" @@ -9307,16 +8649,6 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -svg-element-attributes@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/svg-element-attributes/-/svg-element-attributes-1.3.1.tgz#0c55afac6284291ab563d0913c062cf78a8c0ddb" - integrity sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA== - symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" @@ -9598,16 +8930,6 @@ ts-node@^7.0.0: source-map-support "^0.5.6" yn "^2.0.0" -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - tsconfig-paths@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" @@ -9746,16 +9068,6 @@ unbox-primitive@^1.0.1: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - underscore@^1.12.1: version "1.13.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1" @@ -9806,14 +9118,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -update-browserslist-db@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" - integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - update-notifier@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3" From 111083c7addf0cae86011c7675510629e2b6a591 Mon Sep 17 00:00:00 2001 From: tidy-dev <75402236+tidy-dev@users.noreply.github.com> Date: Thu, 25 Aug 2022 16:02:14 -0400 Subject: [PATCH 061/111] Disable errors via inline or file level disables --- .eslintrc.yml | 33 ------------------- app/src/crash/crash-app.tsx | 1 + app/src/ui/app-menu/app-menu.tsx | 1 + app/src/ui/app-menu/menu-pane.tsx | 1 + .../emoji-autocompletion-provider.tsx | 1 + app/src/ui/banners/banner.tsx | 3 ++ app/src/ui/branches/branch-list-item.tsx | 1 + app/src/ui/branches/branches-container.tsx | 1 + app/src/ui/branches/no-branches.tsx | 1 + app/src/ui/branches/no-pull-requests.tsx | 1 + app/src/ui/branches/pull-request-badge.tsx | 1 + .../ui/branches/pull-request-list-item.tsx | 1 + app/src/ui/changes/changes-list.tsx | 1 + app/src/ui/changes/commit-message-avatar.tsx | 2 ++ app/src/ui/changes/commit-message.tsx | 1 + app/src/ui/changes/multiple-selection.tsx | 1 + app/src/ui/changes/no-changes.tsx | 1 + .../ci-check-run-actions-job-step-item.tsx | 2 ++ .../ui/check-runs/ci-check-run-list-item.tsx | 3 ++ .../ui/check-runs/ci-check-run-popover.tsx | 2 ++ .../check-runs/ci-check-run-rerun-dialog.tsx | 1 + .../clone-generic-repository.tsx | 1 + app/src/ui/dialog/dialog.tsx | 1 + app/src/ui/dialog/header.tsx | 1 + app/src/ui/diff/diff-search-input.tsx | 1 + .../ui/diff/image-diffs/image-container.tsx | 1 + app/src/ui/diff/index.tsx | 1 + app/src/ui/diff/side-by-side-diff-row.tsx | 3 ++ app/src/ui/diff/side-by-side-diff.tsx | 1 + app/src/ui/dropdown-select-button.tsx | 1 + .../ui/generic-git-auth/generic-git-auth.tsx | 1 + app/src/ui/history/commit-list-item.tsx | 1 + app/src/ui/history/commit-summary.tsx | 2 ++ app/src/ui/history/selected-commits.tsx | 1 + app/src/ui/lib/authentication-form.tsx | 1 + app/src/ui/lib/draggable.tsx | 1 + app/src/ui/lib/enterprise-server-entry.tsx | 1 + app/src/ui/lib/fancy-text-box.tsx | 1 + app/src/ui/lib/filter-list.tsx | 1 + app/src/ui/lib/focus-container.tsx | 1 + app/src/ui/lib/link-button.tsx | 1 + .../lib/list/list-item-insertion-overlay.tsx | 1 + app/src/ui/lib/list/list-row.tsx | 1 + app/src/ui/lib/list/list.tsx | 2 ++ app/src/ui/lib/path-label.tsx | 2 ++ app/src/ui/lib/sandboxed-markdown.tsx | 1 + app/src/ui/lib/text-area.tsx | 1 + app/src/ui/lib/text-box.tsx | 1 + app/src/ui/lib/two-factor-authentication.tsx | 1 + .../segmented-item.tsx | 2 ++ .../vertical-segmented-control.tsx | 1 + .../no-repositories/no-repositories-view.tsx | 1 + .../pull-request-checks-failed.tsx | 1 + .../ui/preferences/custom-theme-selector.tsx | 2 ++ .../ui/release-notes/release-notes-dialog.tsx | 1 + .../repositories-list/repositories-list.tsx | 1 + app/src/ui/resizable/resizable.tsx | 1 + app/src/ui/sign-in/sign-in.tsx | 1 + app/src/ui/thank-you/thank-you.tsx | 3 ++ app/src/ui/toolbar/button.tsx | 1 + app/src/ui/toolbar/dropdown.tsx | 2 ++ app/src/ui/tutorial/done.tsx | 1 + app/src/ui/tutorial/tutorial-panel.tsx | 1 + .../ui/tutorial/tutorial-step-instruction.tsx | 2 ++ app/src/ui/tutorial/welcome.tsx | 1 + app/src/ui/welcome/welcome.tsx | 1 + 66 files changed, 83 insertions(+), 33 deletions(-) diff --git a/.eslintrc.yml b/.eslintrc.yml index cc9284d3fe..fe2ca1172b 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -31,39 +31,6 @@ rules: # PLUGINS # ########### - # Accessibility - # From: primer-react/recommended - 'jsx-a11y/alt-text': - - warn - 'jsx-a11y/click-events-have-key-events': - - warn - 'jsx-a11y/no-noninteractive-element-interactions': - - warn - 'jsx-a11y/no-static-element-interactions': - - warn - 'jsx-a11y/no-autofocus': - - warn - 'jsx-a11y/no-noninteractive-element-to-interactive-role': - - warn - 'jsx-a11y/aria-role': - - warn - 'jsx-a11y/aria-activedescendant-has-tabindex': - - warn - 'jsx-a11y/mouse-events-have-key-events': - - warn - 'jsx-a11y/label-has-associated-control': - - warn - 'jsx-a11y/anchor-is-valid': - - warn - 'jsx-a11y/iframe-has-title': - - warn - 'jsx-a11y/no-noninteractive-tabindex': - - warn - 'jsx-a11y/role-supports-aria-props': - - warn - 'jsx-a11y/interactive-supports-focus': - - warn - # TYPESCRIPT '@typescript-eslint/naming-convention': - error diff --git a/app/src/crash/crash-app.tsx b/app/src/crash/crash-app.tsx index a52636f228..9674b8cff6 100644 --- a/app/src/crash/crash-app.tsx +++ b/app/src/crash/crash-app.tsx @@ -201,6 +201,7 @@ export class CrashApp extends React.Component { } private renderBackgroundGraphics() { + // eslint-disable-next-line jsx-a11y/alt-text return } diff --git a/app/src/ui/app-menu/app-menu.tsx b/app/src/ui/app-menu/app-menu.tsx index 36bf8c59cc..3d40785d73 100644 --- a/app/src/ui/app-menu/app-menu.tsx +++ b/app/src/ui/app-menu/app-menu.tsx @@ -317,6 +317,7 @@ export class AppMenu extends React.Component { this.paneRefs = this.paneRefs.slice(0, panes.length) return ( + // eslint-disable-next-line jsx-a11y/no-static-element-interactions
{panes}
diff --git a/app/src/ui/app-menu/menu-pane.tsx b/app/src/ui/app-menu/menu-pane.tsx index 0d8a544f77..b187678432 100644 --- a/app/src/ui/app-menu/menu-pane.tsx +++ b/app/src/ui/app-menu/menu-pane.tsx @@ -265,6 +265,7 @@ export class MenuPane extends React.Component { const className = classNames('menu-pane', this.props.className) return ( + // eslint-disable-next-line jsx-a11y/no-static-element-interactions
#{this.props.number} {this.renderCheckStatusSymbol()} diff --git a/app/src/ui/check-runs/ci-check-run-popover.tsx b/app/src/ui/check-runs/ci-check-run-popover.tsx index 9a1a47dcdb..42b12ee8a3 100644 --- a/app/src/ui/check-runs/ci-check-run-popover.tsx +++ b/app/src/ui/check-runs/ci-check-run-popover.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/alt-text */ import * as React from 'react' import { GitHubRepository } from '../../models/github-repository' import { DisposableLike } from 'event-kit' @@ -340,6 +341,7 @@ export class CICheckRunPopover extends React.PureComponent< ) return ( + // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
{this.renderCompletenessIndicator( diff --git a/app/src/ui/check-runs/ci-check-run-rerun-dialog.tsx b/app/src/ui/check-runs/ci-check-run-rerun-dialog.tsx index 38e10ac8ed..3e2dda74ae 100644 --- a/app/src/ui/check-runs/ci-check-run-rerun-dialog.tsx +++ b/app/src/ui/check-runs/ci-check-run-rerun-dialog.tsx @@ -1,3 +1,4 @@ +/* eslint-disable jsx-a11y/alt-text */ import * as React from 'react' import { Dialog, DialogContent, DialogFooter } from '../dialog' import { OkCancelButtonGroup } from '../dialog/ok-cancel-button-group' diff --git a/app/src/ui/clone-repository/clone-generic-repository.tsx b/app/src/ui/clone-repository/clone-generic-repository.tsx index 678da4bbec..f25308e6e2 100644 --- a/app/src/ui/clone-repository/clone-generic-repository.tsx +++ b/app/src/ui/clone-repository/clone-generic-repository.tsx @@ -37,6 +37,7 @@ export class CloneGenericRepository extends React.Component< placeholder="URL or username/repository" value={this.props.url} onValueChanged={this.onUrlChanged} + // eslint-disable-next-line jsx-a11y/no-autofocus autoFocus={true} label={ diff --git a/app/src/ui/dialog/dialog.tsx b/app/src/ui/dialog/dialog.tsx index fc5b0313c7..9f9c27b1a1 100644 --- a/app/src/ui/dialog/dialog.tsx +++ b/app/src/ui/dialog/dialog.tsx @@ -590,6 +590,7 @@ export class Dialog extends React.Component { ) return ( + // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions { // I don't know and we may want to revisit it at some point but for // now an anchor will have to do. return ( + // eslint-disable-next-line jsx-a11y/anchor-is-valid, jsx-a11y/click-events-have-key-events, jsx-a11y/interactive-supports-focus {diff.hasHiddenBidiChars && } {this.state.isSearching && ( diff --git a/app/src/ui/dropdown-select-button.tsx b/app/src/ui/dropdown-select-button.tsx index f2a35912e8..f81aced6b0 100644 --- a/app/src/ui/dropdown-select-button.tsx +++ b/app/src/ui/dropdown-select-button.tsx @@ -158,6 +158,7 @@ export class DropdownSelectButton extends React.Component< >