From c68b34e4b8776203d1f9608f88f676f60ff9be3a Mon Sep 17 00:00:00 2001 From: Nathan Bierema Date: Sun, 16 Aug 2020 09:00:54 -0400 Subject: [PATCH] refactor(react-base16-styling)!: convert react-base16-styling to TypeScript (#592) BREAKING CHANGES: Switch from pure-color to color which could change behavior of string parsing or results. No API changes. --- .eslintignore | 3 + .eslintrc | 1 + eslintrc.ts.base.json | 12 + eslintrc.ts.jest.base.json | 13 + jest.config.js | 2 +- package.json | 24 +- packages/react-base16-styling/.babelrc | 2 +- packages/react-base16-styling/.eslintignore | 1 + packages/react-base16-styling/.eslintrc.js | 21 ++ packages/react-base16-styling/jest.config.js | 3 + packages/react-base16-styling/package.json | 56 +-- .../src/colorConverters.js | 30 -- .../src/colorConverters.ts | 30 ++ packages/react-base16-styling/src/index.js | 232 ------------ packages/react-base16-styling/src/index.ts | 290 +++++++++++++++ packages/react-base16-styling/src/types.ts | 32 ++ .../test/{index.test.js => index.test.ts} | 75 ++-- .../react-base16-styling/test/tsconfig.json | 4 + packages/react-base16-styling/tsconfig.json | 7 + tsconfig.base.json | 11 + yarn.lock | 335 +++++++++++++++--- 21 files changed, 810 insertions(+), 374 deletions(-) create mode 100644 eslintrc.ts.base.json create mode 100644 eslintrc.ts.jest.base.json create mode 100644 packages/react-base16-styling/.eslintignore create mode 100644 packages/react-base16-styling/.eslintrc.js create mode 100644 packages/react-base16-styling/jest.config.js delete mode 100644 packages/react-base16-styling/src/colorConverters.js create mode 100644 packages/react-base16-styling/src/colorConverters.ts delete mode 100644 packages/react-base16-styling/src/index.js create mode 100644 packages/react-base16-styling/src/index.ts create mode 100644 packages/react-base16-styling/src/types.ts rename packages/react-base16-styling/test/{index.test.js => index.test.ts} (76%) create mode 100644 packages/react-base16-styling/test/tsconfig.json create mode 100644 packages/react-base16-styling/tsconfig.json create mode 100644 tsconfig.base.json diff --git a/.eslintignore b/.eslintignore index b8937bc4..65bea899 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,3 +7,6 @@ build coverage node_modules __snapshots__ + +# Ignore until TS linting is configured in redux-devtools package +packages/redux-devtools/index.d.ts diff --git a/.eslintrc b/.eslintrc index fbc807e5..a7235ea2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,4 +1,5 @@ { + "root": true, "parser": "babel-eslint", "extends": [ "eslint:recommended", diff --git a/eslintrc.ts.base.json b/eslintrc.ts.base.json new file mode 100644 index 00000000..ba7fe944 --- /dev/null +++ b/eslintrc.ts.base.json @@ -0,0 +1,12 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:prettier/recommended", + "prettier/@typescript-eslint" + ] +} diff --git a/eslintrc.ts.jest.base.json b/eslintrc.ts.jest.base.json new file mode 100644 index 00000000..09258ad7 --- /dev/null +++ b/eslintrc.ts.jest.base.json @@ -0,0 +1,13 @@ +{ + "plugins": ["jest"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", + "plugin:jest/recommended", + "plugin:jest/style", + "plugin:prettier/recommended", + "prettier/@typescript-eslint" + ] +} diff --git a/jest.config.js b/jest.config.js index 7e1daca2..18639473 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,3 @@ module.exports = { - setupFiles: ['devui/tests/setup.js'], + projects: ['/packages/*'], }; diff --git a/package.json b/package.json index 122b5ad5..ed590b14 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,29 @@ { "private": true, "devDependencies": { + "@babel/cli": "^7.10.5", + "@babel/core": "^7.11.1", + "@babel/plugin-proposal-class-properties": "^7.10.4", + "@babel/preset-env": "^7.11.0", + "@babel/preset-typescript": "^7.10.4", + "@types/jest": "^26.0.9", + "@typescript-eslint/eslint-plugin": "^3.9.0", + "@typescript-eslint/parser": "^3.9.0", "babel-eslint": "^10.1.0", "eslint": "^7.6.0", "eslint-config-prettier": "^6.11.0", "eslint-plugin-babel": "^5.3.1", + "eslint-plugin-jest": "^23.20.0", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-react": "^7.20.5", "husky": "^4.2.5", "jest": "^26.2.2", "lerna": "^3.22.1", "lint-staged": "^10.2.11", - "prettier": "^2.0.5" + "prettier": "^2.0.5", + "rimraf": "^3.0.2", + "ts-jest": "^26.2.0", + "typescript": "^3.9.7" }, "scripts": { "lerna": "lerna", @@ -20,10 +32,10 @@ "publish": "lerna publish", "canary": "lerna publish --canary preminor --npm-tag alpha", "next": "lerna publish --bump prerelease --npm-tag next", - "lint": "eslint \"**/*.{js,jsx}\" --cache", - "lint:fix": "eslint \"**/*.{js,jsx}\" --fix --cache", - "lint:all": "eslint \"**/*.{js,jsx}\"", - "prettify": "prettier \"**/*.{js,jsx,json,css,html,md}\" --write", + "lint": "eslint \"**/*.{js,jsx,ts,tsx}\" --cache", + "lint:fix": "eslint \"**/*.{js,jsx,ts,tsx}\" --fix --cache", + "lint:all": "eslint \"**/*.{js,jsx,ts,tsx}\"", + "prettify": "prettier \"**/*.{js,jsx,ts,tsx,json,css,html,md}\" --write", "test": "jest --onlyChanged", "test:all": "jest" }, @@ -44,7 +56,7 @@ } }, "lint-staged": { - "*.{js,jsx}": [ + "*.{js,jsx,ts,tsx}": [ "prettier --write", "yarn lint:fix" ], diff --git a/packages/react-base16-styling/.babelrc b/packages/react-base16-styling/.babelrc index 644dde97..5259cd24 100644 --- a/packages/react-base16-styling/.babelrc +++ b/packages/react-base16-styling/.babelrc @@ -1,4 +1,4 @@ { - "presets": ["@babel/preset-env"], + "presets": ["@babel/preset-env", "@babel/preset-typescript"], "plugins": ["@babel/plugin-proposal-class-properties"] } diff --git a/packages/react-base16-styling/.eslintignore b/packages/react-base16-styling/.eslintignore new file mode 100644 index 00000000..a65b4177 --- /dev/null +++ b/packages/react-base16-styling/.eslintignore @@ -0,0 +1 @@ +lib diff --git a/packages/react-base16-styling/.eslintrc.js b/packages/react-base16-styling/.eslintrc.js new file mode 100644 index 00000000..486b7fd4 --- /dev/null +++ b/packages/react-base16-styling/.eslintrc.js @@ -0,0 +1,21 @@ +module.exports = { + extends: '../../.eslintrc', + overrides: [ + { + files: ['*.ts', '*.tsx'], + extends: '../../eslintrc.ts.base.json', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig.json'], + }, + }, + { + files: ['test/*.ts', 'test/*.tsx'], + extends: '../../eslintrc.ts.jest.base.json', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./test/tsconfig.json'], + }, + }, + ], +}; diff --git a/packages/react-base16-styling/jest.config.js b/packages/react-base16-styling/jest.config.js new file mode 100644 index 00000000..8824c114 --- /dev/null +++ b/packages/react-base16-styling/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + preset: 'ts-jest', +}; diff --git a/packages/react-base16-styling/package.json b/packages/react-base16-styling/package.json index 69caea8e..2dd5e90f 100644 --- a/packages/react-base16-styling/package.json +++ b/packages/react-base16-styling/package.json @@ -2,42 +2,48 @@ "name": "react-base16-styling", "version": "0.7.0", "description": "React styling with base16 color scheme support", - "main": "lib/index.js", - "scripts": { - "clean": "rimraf lib", - "build": "babel src --out-dir lib", - "test": "jest", - "prepare": "npm run build", - "prepublishOnly": "npm run test && npm run clean && npm run build" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/reduxjs/redux-devtools.git" - }, "keywords": [ "react", "theme", "base16", "styling" ], - "author": "Alexander (http://kuzya.org/)", - "license": "MIT", + "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/react-base16-styling", "bugs": { "url": "https://github.com/reduxjs/redux-devtools/issues" }, - "homepage": "https://github.com/reduxjs/redux-devtools", - "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.11.1", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-transform-runtime": "^7.11.0", - "@babel/preset-env": "^7.11.0", - "rimraf": "^3.0.2" + "license": "MIT", + "author": "Alexander (http://kuzya.org/)", + "files": [ + "lib", + "src" + ], + "main": "lib/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/reduxjs/redux-devtools.git" + }, + "scripts": { + "build": "npm run build:types && npm run build:js", + "build:types": "tsc --emitDeclarationOnly", + "build:js": "babel src --out-dir lib --extensions \".ts\" --source-maps inline", + "clean": "rimraf lib", + "test": "jest", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint . --ext .ts --fix", + "type-check": "tsc --noEmit", + "type-check:watch": "npm run type-check -- --watch", + "prepublishOnly": "npm run type-check && npm run lint && npm run test && npm run clean && npm run build" }, "dependencies": { + "@types/base16": "^1.0.2", + "@types/lodash.curry": "^4.1.6", "base16": "^1.0.0", - "lodash.curry": "^4.1.1", - "lodash.flow": "^3.5.0", - "pure-color": "^1.3.0" + "color": "^3.1.2", + "csstype": "^3.0.2", + "lodash.curry": "^4.1.1" + }, + "devDependencies": { + "@types/color": "^3.0.1" } } diff --git a/packages/react-base16-styling/src/colorConverters.js b/packages/react-base16-styling/src/colorConverters.js deleted file mode 100644 index e2960018..00000000 --- a/packages/react-base16-styling/src/colorConverters.js +++ /dev/null @@ -1,30 +0,0 @@ -export function yuv2rgb(yuv) { - var y = yuv[0], - u = yuv[1], - v = yuv[2], - r, - g, - b; - - r = y * 1 + u * 0 + v * 1.13983; - g = y * 1 + u * -0.39465 + v * -0.5806; - b = y * 1 + u * 2.02311 + v * 0; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -} - -export function rgb2yuv(rgb) { - var r = rgb[0] / 255, - g = rgb[1] / 255, - b = rgb[2] / 255; - - var y = r * 0.299 + g * 0.587 + b * 0.114; - var u = r * -0.14713 + g * -0.28886 + b * 0.436; - var v = r * 0.615 + g * -0.51499 + b * -0.10001; - - return [y, u, v]; -} diff --git a/packages/react-base16-styling/src/colorConverters.ts b/packages/react-base16-styling/src/colorConverters.ts new file mode 100644 index 00000000..4251b7e1 --- /dev/null +++ b/packages/react-base16-styling/src/colorConverters.ts @@ -0,0 +1,30 @@ +export type Color = [number, number, number]; + +export function yuv2rgb(yuv: Color): Color { + const y = yuv[0], + u = yuv[1], + v = yuv[2]; + let r, g, b; + + r = y * 1 + u * 0 + v * 1.13983; + g = y * 1 + u * -0.39465 + v * -0.5806; + b = y * 1 + u * 2.02311 + v * 0; + + r = Math.min(Math.max(0, r), 1); + g = Math.min(Math.max(0, g), 1); + b = Math.min(Math.max(0, b), 1); + + return [r * 255, g * 255, b * 255]; +} + +export function rgb2yuv(rgb: Color): Color { + const r = rgb[0] / 255, + g = rgb[1] / 255, + b = rgb[2] / 255; + + const y = r * 0.299 + g * 0.587 + b * 0.114; + const u = r * -0.14713 + g * -0.28886 + b * 0.436; + const v = r * 0.615 + g * -0.51499 + b * -0.10001; + + return [y, u, v]; +} diff --git a/packages/react-base16-styling/src/index.js b/packages/react-base16-styling/src/index.js deleted file mode 100644 index 25b148b2..00000000 --- a/packages/react-base16-styling/src/index.js +++ /dev/null @@ -1,232 +0,0 @@ -import curry from 'lodash.curry'; -import * as base16 from 'base16'; -import rgb2hex from 'pure-color/convert/rgb2hex'; -import parse from 'pure-color/parse'; -import flow from 'lodash.flow'; -import { yuv2rgb, rgb2yuv } from './colorConverters'; - -const DEFAULT_BASE16 = base16.default; - -const BASE16_KEYS = Object.keys(DEFAULT_BASE16); - -// we need a correcting factor, so that a dark, but not black background color -// converts to bright enough inversed color -const flip = (x) => (x < 0.25 ? 1 : x < 0.5 ? 0.9 - x : 1.1 - x); - -const invertColor = flow( - parse, - rgb2yuv, - ([y, u, v]) => [flip(y), u, v], - yuv2rgb, - rgb2hex -); - -const merger = function merger(styling) { - return (prevStyling) => ({ - className: [prevStyling.className, styling.className] - .filter(Boolean) - .join(' '), - style: { ...(prevStyling.style || {}), ...(styling.style || {}) }, - }); -}; - -const mergeStyling = function mergeStyling(customStyling, defaultStyling) { - if (customStyling === undefined) { - return defaultStyling; - } - if (defaultStyling === undefined) { - return customStyling; - } - - const customType = typeof customStyling; - const defaultType = typeof defaultStyling; - - switch (customType) { - case 'string': - switch (defaultType) { - case 'string': - return [defaultStyling, customStyling].filter(Boolean).join(' '); - case 'object': - return merger({ className: customStyling, style: defaultStyling }); - case 'function': - return (styling, ...args) => - merger({ - className: customStyling, - })(defaultStyling(styling, ...args)); - } - break; - case 'object': - switch (defaultType) { - case 'string': - return merger({ className: defaultStyling, style: customStyling }); - case 'object': - return { ...defaultStyling, ...customStyling }; - case 'function': - return (styling, ...args) => - merger({ - style: customStyling, - })(defaultStyling(styling, ...args)); - } - break; - case 'function': - switch (defaultType) { - case 'string': - return (styling, ...args) => - customStyling( - merger(styling)({ - className: defaultStyling, - }), - ...args - ); - case 'object': - return (styling, ...args) => - customStyling( - merger(styling)({ - style: defaultStyling, - }), - ...args - ); - case 'function': - return (styling, ...args) => - customStyling(defaultStyling(styling, ...args), ...args); - } - } -}; - -const mergeStylings = function mergeStylings(customStylings, defaultStylings) { - const keys = Object.keys(defaultStylings); - for (const key in customStylings) { - if (keys.indexOf(key) === -1) keys.push(key); - } - - return keys.reduce( - (mergedStyling, key) => ( - (mergedStyling[key] = mergeStyling( - customStylings[key], - defaultStylings[key] - )), - mergedStyling - ), - {} - ); -}; - -const getStylingByKeys = (mergedStyling, keys, ...args) => { - if (keys === null) { - return mergedStyling; - } - - if (!Array.isArray(keys)) { - keys = [keys]; - } - - const styles = keys.map((key) => mergedStyling[key]).filter(Boolean); - - const props = styles.reduce( - (obj, s) => { - if (typeof s === 'string') { - obj.className = [obj.className, s].filter(Boolean).join(' '); - } else if (typeof s === 'object') { - obj.style = { ...obj.style, ...s }; - } else if (typeof s === 'function') { - obj = { ...obj, ...s(obj, ...args) }; - } - - return obj; - }, - { className: '', style: {} } - ); - - if (!props.className) { - delete props.className; - } - - if (Object.keys(props.style).length === 0) { - delete props.style; - } - - return props; -}; - -export const invertBase16Theme = (base16Theme) => - Object.keys(base16Theme).reduce( - (t, key) => ( - (t[key] = /^base/.test(key) - ? invertColor(base16Theme[key]) - : key === 'scheme' - ? base16Theme[key] + ':inverted' - : base16Theme[key]), - t - ), - {} - ); - -export const createStyling = curry( - (getStylingFromBase16, options = {}, themeOrStyling = {}, ...args) => { - const { defaultBase16 = DEFAULT_BASE16, base16Themes = null } = options; - - const base16Theme = getBase16Theme(themeOrStyling, base16Themes); - if (base16Theme) { - themeOrStyling = { - ...base16Theme, - ...themeOrStyling, - }; - } - - const theme = BASE16_KEYS.reduce( - (t, key) => ((t[key] = themeOrStyling[key] || defaultBase16[key]), t), - {} - ); - - const customStyling = Object.keys(themeOrStyling).reduce( - (s, key) => - BASE16_KEYS.indexOf(key) === -1 - ? ((s[key] = themeOrStyling[key]), s) - : s, - {} - ); - - const defaultStyling = getStylingFromBase16(theme); - - const mergedStyling = mergeStylings(customStyling, defaultStyling); - - return curry(getStylingByKeys, 2)(mergedStyling, ...args); - }, - 3 -); - -export const getBase16Theme = (theme, base16Themes) => { - if (theme && theme.extend) { - theme = theme.extend; - } - - if (typeof theme === 'string') { - const [themeName, modifier] = theme.split(':'); - theme = (base16Themes || {})[themeName] || base16[themeName]; - if (modifier === 'inverted') { - theme = invertBase16Theme(theme); - } - } - - return theme && Object.prototype.hasOwnProperty.call(theme, 'base00') - ? theme - : undefined; -}; - -export const invertTheme = (theme) => { - if (typeof theme === 'string') { - return `${theme}:inverted`; - } - - if (theme && theme.extend) { - if (typeof theme.extend === 'string') { - return { ...theme, extend: `${theme.extend}:inverted` }; - } - - return { ...theme, extend: invertBase16Theme(theme.extend) }; - } - - if (theme) { - return invertBase16Theme(theme); - } -}; diff --git a/packages/react-base16-styling/src/index.ts b/packages/react-base16-styling/src/index.ts new file mode 100644 index 00000000..382fcec3 --- /dev/null +++ b/packages/react-base16-styling/src/index.ts @@ -0,0 +1,290 @@ +import * as base16 from 'base16'; +import { Base16Theme } from 'base16'; +import Color from 'color'; +import * as CSS from 'csstype'; +import curry from 'lodash.curry'; +import { Color as ColorTuple, yuv2rgb, rgb2yuv } from './colorConverters'; +import { + Styling, + StylingConfig, + StylingFunction, + StylingValue, + StylingValueFunction, + Theme, +} from './types'; + +const DEFAULT_BASE16 = base16.default; + +const BASE16_KEYS = Object.keys(DEFAULT_BASE16); + +// we need a correcting factor, so that a dark, but not black background color +// converts to bright enough inversed color +const flip = (x: number) => (x < 0.25 ? 1 : x < 0.5 ? 0.9 - x : 1.1 - x); + +const invertColor = (hexString: string) => { + const color = Color(hexString); + const [y, u, v] = rgb2yuv(color.array() as ColorTuple); + const flippedYuv: ColorTuple = [flip(y), u, v]; + const rgb = yuv2rgb(flippedYuv); + return Color.rgb(rgb).hex(); +}; + +const merger = (styling: Styling) => { + return (prevStyling: Styling) => ({ + className: [prevStyling.className, styling.className] + .filter(Boolean) + .join(' '), + style: { ...(prevStyling.style || {}), ...(styling.style || {}) }, + }); +}; + +const mergeStyling = ( + customStyling: StylingValue, + defaultStyling: StylingValue +): StylingValue | undefined => { + if (customStyling === undefined) { + return defaultStyling; + } + if (defaultStyling === undefined) { + return customStyling; + } + + const customType = typeof customStyling; + const defaultType = typeof defaultStyling; + + switch (customType) { + case 'string': + switch (defaultType) { + case 'string': + return [defaultStyling, customStyling].filter(Boolean).join(' '); + case 'object': + return merger({ + className: customStyling as string, + style: defaultStyling as CSS.Properties, + }); + case 'function': + return (styling: Styling, ...args: any[]) => + merger({ + className: customStyling as string, + })((defaultStyling as StylingValueFunction)(styling, ...args)); + } + break; + case 'object': + switch (defaultType) { + case 'string': + return merger({ + className: defaultStyling as string, + style: customStyling as CSS.Properties, + }); + case 'object': + return { + ...(defaultStyling as CSS.Properties), + ...(customStyling as CSS.Properties), + }; + case 'function': + return (styling: Styling, ...args: any[]) => + merger({ + style: customStyling as CSS.Properties, + })((defaultStyling as StylingValueFunction)(styling, ...args)); + } + break; + case 'function': + switch (defaultType) { + case 'string': + return (styling, ...args) => + (customStyling as StylingValueFunction)( + merger(styling)({ + className: defaultStyling as string, + }), + ...args + ); + case 'object': + return (styling, ...args) => + (customStyling as StylingValueFunction)( + merger(styling)({ + style: defaultStyling as CSS.Properties, + }), + ...args + ); + case 'function': + return (styling, ...args) => + (customStyling as StylingValueFunction)( + (defaultStyling as StylingValueFunction)(styling, ...args), + ...args + ); + } + } +}; + +const mergeStylings = ( + customStylings: StylingConfig, + defaultStylings: StylingConfig +): StylingConfig => { + const keys = Object.keys(defaultStylings); + for (const key in customStylings) { + if (keys.indexOf(key) === -1) keys.push(key); + } + + return keys.reduce( + (mergedStyling, key) => ( + (mergedStyling[key as keyof StylingConfig] = mergeStyling( + customStylings[key] as StylingValue, + defaultStylings[key] as StylingValue + ) as StylingValue), + mergedStyling + ), + {} as StylingConfig + ); +}; + +const getStylingByKeys = ( + mergedStyling: StylingConfig, + keys: string | string[], + ...args: any[] +): Styling => { + if (keys === null) { + return mergedStyling as Styling; + } + + if (!Array.isArray(keys)) { + keys = [keys]; + } + + const styles = keys.map((key) => mergedStyling[key]).filter(Boolean); + + const props = styles.reduce( + (obj, s) => { + if (typeof s === 'string') { + obj.className = [obj.className, s].filter(Boolean).join(' '); + } else if (typeof s === 'object') { + obj.style = { ...obj.style, ...s }; + } else if (typeof s === 'function') { + obj = { ...obj, ...s(obj, ...args) }; + } + + return obj; + }, + { className: '', style: {} } + ); + + if (!props.className) { + delete props.className; + } + + if (Object.keys(props.style).length === 0) { + delete props.style; + } + + return props; +}; + +export const invertBase16Theme = (base16Theme: Base16Theme): Base16Theme => + Object.keys(base16Theme).reduce( + (t, key) => ( + (t[key as keyof Base16Theme] = /^base/.test(key) + ? invertColor(base16Theme[key as keyof Base16Theme]) + : key === 'scheme' + ? base16Theme[key] + ':inverted' + : base16Theme[key as keyof Base16Theme]), + t + ), + {} as Base16Theme + ); + +export const createStyling = curry( + ( + getStylingFromBase16: (base16Theme: Base16Theme) => StylingConfig, + options: { + defaultBase16?: Base16Theme; + base16Themes?: { [themeName: string]: Base16Theme }; + } = {}, + themeOrStyling: Theme = {}, + ...args + ): StylingFunction => { + const { defaultBase16 = DEFAULT_BASE16, base16Themes = null } = options; + + const base16Theme = getBase16Theme(themeOrStyling, base16Themes); + if (base16Theme) { + themeOrStyling = { + ...base16Theme, + ...(themeOrStyling as Base16Theme | StylingConfig), + }; + } + + const theme = BASE16_KEYS.reduce( + (t, key) => ( + (t[key as keyof Base16Theme] = + (themeOrStyling as Base16Theme)[key as keyof Base16Theme] || + defaultBase16[key as keyof Base16Theme]), + t + ), + {} as Base16Theme + ); + + const customStyling = Object.keys(themeOrStyling).reduce( + (s, key) => + BASE16_KEYS.indexOf(key) === -1 + ? ((s[key] = (themeOrStyling as StylingConfig)[key]), s) + : s, + {} as StylingConfig + ); + + const defaultStyling = getStylingFromBase16(theme); + + const mergedStyling = mergeStylings(customStyling, defaultStyling); + + return curry(getStylingByKeys, 2)(mergedStyling, ...args); + }, + 3 +); + +const isStylingConfig = (theme: Theme): theme is StylingConfig => + !!(theme as StylingConfig).extend; + +export const getBase16Theme = ( + theme: Theme, + base16Themes?: { [themeName: string]: Base16Theme } | null +): Base16Theme | undefined => { + if (theme && isStylingConfig(theme) && theme.extend) { + theme = theme.extend as string | Base16Theme; + } + + if (typeof theme === 'string') { + const [themeName, modifier] = theme.split(':'); + if (base16Themes) { + theme = base16Themes[themeName]; + } else { + theme = base16[themeName as keyof typeof base16]; + } + if (modifier === 'inverted') { + theme = invertBase16Theme(theme); + } + } + + return theme && Object.prototype.hasOwnProperty.call(theme, 'base00') + ? (theme as Base16Theme) + : undefined; +}; + +export const invertTheme = (theme: Theme): Theme => { + if (typeof theme === 'string') { + return `${theme}:inverted`; + } + + if (theme && isStylingConfig(theme) && theme.extend) { + if (typeof theme.extend === 'string') { + return { ...theme, extend: `${theme.extend}:inverted` }; + } + + return { + ...theme, + extend: invertBase16Theme(theme.extend as Base16Theme), + }; + } + + if (theme) { + return invertBase16Theme(theme as Base16Theme); + } + + return theme; +}; diff --git a/packages/react-base16-styling/src/types.ts b/packages/react-base16-styling/src/types.ts new file mode 100644 index 00000000..f5e93f0e --- /dev/null +++ b/packages/react-base16-styling/src/types.ts @@ -0,0 +1,32 @@ +import { Base16Theme } from 'base16'; +import * as CSS from 'csstype'; + +export interface Styling { + className?: string; + style?: CSS.Properties; +} + +export type StylingValueFunction = ( + styling: Styling, + ...rest: any[] +) => Styling; + +export type StylingValue = + | string + | CSS.Properties + | StylingValueFunction; + +export type StylingConfig = { + // Should actually only be string | Base16Theme + extend?: string | Base16Theme | StylingValue; +} & { + // Should actually only be StylingValue + [name: string]: StylingValue | string | Base16Theme; +}; + +export type Theme = string | Base16Theme | StylingConfig; + +export type StylingFunction = ( + keys: string | string[], + ...rest: any[] +) => Styling; diff --git a/packages/react-base16-styling/test/index.test.js b/packages/react-base16-styling/test/index.test.ts similarity index 76% rename from packages/react-base16-styling/test/index.test.js rename to packages/react-base16-styling/test/index.test.ts index d1de7720..1ee0e6ae 100644 --- a/packages/react-base16-styling/test/index.test.js +++ b/packages/react-base16-styling/test/index.test.ts @@ -1,5 +1,6 @@ import { createStyling, invertBase16Theme, getBase16Theme } from '../src'; -import apathy from 'base16/lib/apathy'; +import { apathy, Base16Theme } from 'base16'; +import { Styling, StylingConfig } from '../src/types'; const base16Theme = { scheme: 'myscheme', @@ -25,52 +26,52 @@ const base16Theme = { const invertedBase16Theme = { scheme: 'myscheme:inverted', author: 'me', - base00: '#ffffff', - base01: '#ffffff', - base02: '#a2a1a2', - base03: '#807f80', - base04: '#807f80', - base05: '#5e5d5e', - base06: '#3c3b3c', - base07: '#1a191a', - base08: '#ff4d4d', - base09: '#cb6500', + base00: '#FFFFFF', + base01: '#FFFFFF', + base02: '#A2A1A2', + base03: '#807F80', + base04: '#807F80', + base05: '#5E5D5E', + base06: '#3C3B3C', + base07: '#1A191A', + base08: '#FF4D4D', + base09: '#CB6500', base0A: '#545400', - base0B: '#a2a20a', - base0C: '#0fa8a8', - base0D: '#32cb32', - base0E: '#6868ce', - base0F: '#ff2ac3', + base0B: '#A2A20A', + base0C: '#0FA8A8', + base0D: '#32CB32', + base0E: '#6868CE', + base0F: '#FF2AC3', }; const apathyInverted = { author: 'jannik siebert (https://github.com/janniks)', - base00: '#efffff', - base01: '#e3ffff', - base02: '#daffff', - base03: '#67a49a', - base04: '#66a399', - base05: '#51857c', - base06: '#3c635d', - base07: '#2a3f3c', - base08: '#2f8779', - base09: '#4e89a6', - base0A: '#8391db', - base0B: '#b167bf', - base0C: '#c8707e', - base0D: '#a7994f', + base00: '#EFFFFF', + base01: '#E3FFFF', + base02: '#DAFFFF', + base03: '#67A49A', + base04: '#66A399', + base05: '#51857C', + base06: '#3C635D', + base07: '#2A3F3C', + base08: '#2F8779', + base09: '#4E89A6', + base0A: '#8391DB', + base0B: '#B167BF', + base0C: '#C8707E', + base0D: '#A7994F', base0E: '#469038', - base0F: '#3a9257', + base0F: '#3A9257', scheme: 'apathy:inverted', }; -const getStylingFromBase16 = (base16) => ({ +const getStylingFromBase16 = (base16: Base16Theme): StylingConfig => ({ testClass: 'testClass', testStyle: { color: base16.base00, }, - testFunc: ({ style }, arg) => ({ - className: 'testClass--' + arg, + testFunc: ({ style }, arg: string) => ({ + className: `testClass--${arg}`, style: { ...style, width: 0, @@ -93,7 +94,7 @@ test('getBase16Theme', () => { expect(getBase16Theme('apathy')).toEqual(apathy); expect(getBase16Theme({ extend: 'apathy' })).toEqual(apathy); expect(getBase16Theme('apathy:inverted')).toEqual(apathyInverted); - expect(getBase16Theme({})).toBe(undefined); + expect(getBase16Theme({})).toBeUndefined(); }); test('createStyling (default)', () => { @@ -122,8 +123,8 @@ test('createStyling (custom)', () => { let customStyling = styling({ testClass: 'customClass', testStyle: { height: 0 }, - testFunc: (styling, arg) => ({ - className: styling.className + ' customClass--' + arg, + testFunc: (styling: Styling, arg: string) => ({ + className: `${styling.className!} customClass--${arg}`, style: { ...styling.style, border: 0, diff --git a/packages/react-base16-styling/test/tsconfig.json b/packages/react-base16-styling/test/tsconfig.json new file mode 100644 index 00000000..b55532d2 --- /dev/null +++ b/packages/react-base16-styling/test/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["../src", "."] +} diff --git a/packages/react-base16-styling/tsconfig.json b/packages/react-base16-styling/tsconfig.json new file mode 100644 index 00000000..84575cb5 --- /dev/null +++ b/packages/react-base16-styling/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["src"] +} diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 00000000..545b15ac --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2019", + "module": "commonjs", + "declaration": true, + "strict": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + } +} diff --git a/yarn.lock b/yarn.lock index b9506b28..a0cb21be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1012,7 +1012,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-typescript@^7.1.0": +"@babel/plugin-transform-typescript@^7.1.0", "@babel/plugin-transform-typescript@^7.10.4": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.11.0.tgz#2b4879676af37342ebb278216dd090ac67f13abb" integrity sha512-edJsNzTtvb3MaXQwj8403B7mZoGu9ElDJQZOKjGUnvilquxBA3IQoEIOvkX/1O8xfAsnHS/oQhe2w/IXrr+w0w== @@ -1216,6 +1216,14 @@ "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-transform-typescript" "^7.1.0" +"@babel/preset-typescript@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.10.4.tgz#7d5d052e52a682480d6e2cc5aa31be61c8c25e36" + integrity sha512-SdYnvGPv+bLlwkF2VkJnaX/ni1sMNetcGI1+nThF1gyv6Ph8Qucc4ZZAjM5yZcE/AKRXIOTZz7eSRDWOEjPyRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-typescript" "^7.10.4" + "@babel/runtime-corejs2@^7.4.5": version "7.11.2" resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.11.2.tgz#700a03945ebad0d31ba6690fc8a6bcc9040faa47" @@ -1681,6 +1689,16 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/types@^25.5.0": + version "25.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" + integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^1.1.1" + "@types/yargs" "^15.0.0" + chalk "^3.0.0" + "@jest/types@^26.2.0": version "26.2.0" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.2.0.tgz#b28ca1fb517a4eb48c0addea7fcd9edc4ab45721" @@ -1692,6 +1710,17 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jest/types@^26.3.0": + version "26.3.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.3.0.tgz#97627bf4bdb72c55346eef98e3b3f7ddc4941f71" + integrity sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + "@lerna/add@3.21.0": version "3.21.0" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.21.0.tgz#27007bde71cc7b0a2969ab3c2f0ae41578b4577b" @@ -3016,16 +3045,40 @@ dependencies: "@babel/types" "^7.3.0" +"@types/base16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/base16/-/base16-1.0.2.tgz#eb3a07db52309bfefb9ba010dfdb3c0784971f65" + integrity sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg== + "@types/classnames@^2.2.10": version "2.2.10" resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.2.10.tgz#cc658ca319b6355399efc1f5b9e818f1a24bf999" integrity sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ== -"@types/color-name@^1.1.1": +"@types/color-convert@*": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-1.9.0.tgz#bfa8203e41e7c65471e9841d7e306a7cd8b5172d" + integrity sha512-OKGEfULrvSL2VRbkl/gnjjgbbF7ycIlpSsX7Nkab4MOWi5XxmgBYvuiQ7lcCFY5cPDz7MUNaKgxte2VRmtr4Fg== + dependencies: + "@types/color-name" "*" + +"@types/color-name@*", "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/color@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/color/-/color-3.0.1.tgz#2900490ed04da8116c5058cd5dba3572d5a25071" + integrity sha512-oeUWVaAwI+xINDUx+3F2vJkl/vVB03VChFF/Gl3iQCdbcakjuoJyMOba+3BXRtnBhxZ7uBYqQBi9EpLnvSoztA== + dependencies: + "@types/color-convert" "*" + +"@types/eslint-visitor-keys@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" + integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== + "@types/glob@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" @@ -3071,11 +3124,38 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" -"@types/json-schema@^7.0.4": +"@types/istanbul-reports@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" + integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@26.x", "@types/jest@^26.0.9": + version "26.0.9" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.9.tgz#0543b57da5f0cd949c5f423a00c56c492289c989" + integrity sha512-k4qFfJ5AUKrWok5KYXp2EPm89b0P/KZpl7Vg4XuOTVVQEhLDBDBU3iBFrjjdgd8fLw96aAtmnwhXHl63bWeBQQ== + dependencies: + jest-diff "^25.2.1" + pretty-format "^25.2.1" + +"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4": version "7.0.5" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== +"@types/lodash.curry@^4.1.6": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/lodash.curry/-/lodash.curry-4.1.6.tgz#f26c490c80c92d7cbaa2300d542e89781d44b1ff" + integrity sha512-x3ctCcmOYqRrihNNnQJW6fe/yZFCgnrIa6p80AiPQRO8Jis29bBdy1dEw1FwngoF/mCZa3Bx+33fUZvOEE635Q== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.159" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.159.tgz#61089719dc6fdd9c5cb46efc827f2571d1517065" + integrity sha512-gF7A72f7WQN33DpqOWw9geApQPh4M3PxluMtaHxWHXEGSN12/WbcEk/eNSqWNQcQhF66VSZ06vCF94CrHwXJDg== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -3201,6 +3281,89 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/eslint-plugin@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.0.tgz#0fe529b33d63c9a94f7503ca2bb12c84b9477ff3" + integrity sha512-UD6b4p0/hSe1xdTvRCENSx7iQ+KR6ourlZFfYuPC7FlXEzdHuLPrEmuxZ23b2zW96KJX9Z3w05GE/wNOiEzrVg== + dependencies: + "@typescript-eslint/experimental-utils" "3.9.0" + debug "^4.1.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.0.0" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/experimental-utils@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.0.tgz#3171d8ddba0bf02a8c2034188593630914fcf5ee" + integrity sha512-/vSHUDYizSOhrOJdjYxPNGfb4a3ibO8zd4nUKo/QBFOmxosT3cVUV7KIg8Dwi6TXlr667G7YPqFK9+VSZOorNA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/types" "3.9.0" + "@typescript-eslint/typescript-estree" "3.9.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/experimental-utils@^2.5.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" + integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/typescript-estree" "2.34.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/parser@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.9.0.tgz#344978a265d9a5c7c8f13e62c78172a4374dabea" + integrity sha512-rDHOKb6uW2jZkHQniUQVZkixQrfsZGUCNWWbKWep4A5hGhN5dLHMUCNAWnC4tXRlHedXkTDptIpxs6e4Pz8UfA== + dependencies: + "@types/eslint-visitor-keys" "^1.0.0" + "@typescript-eslint/experimental-utils" "3.9.0" + "@typescript-eslint/types" "3.9.0" + "@typescript-eslint/typescript-estree" "3.9.0" + eslint-visitor-keys "^1.1.0" + +"@typescript-eslint/types@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.9.0.tgz#be9d0aa451e1bf3ce99f2e6920659e5b2e6bfe18" + integrity sha512-rb6LDr+dk9RVVXO/NJE8dT1pGlso3voNdEIN8ugm4CWM5w5GimbThCMiMl4da1t5u3YwPWEwOnKAULCZgBtBHg== + +"@typescript-eslint/typescript-estree@2.34.0": + version "2.34.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" + integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== + dependencies: + debug "^4.1.1" + eslint-visitor-keys "^1.1.0" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/typescript-estree@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.0.tgz#c6abbb50fa0d715cab46fef67ca6378bf2eaca13" + integrity sha512-N+158NKgN4rOmWVfvKOMoMFV5n8XxAliaKkArm/sOypzQ0bUL8MSnOEBW3VFIeffb/K5ce/cAV0yYhR7U4ALAA== + dependencies: + "@typescript-eslint/types" "3.9.0" + "@typescript-eslint/visitor-keys" "3.9.0" + debug "^4.1.1" + glob "^7.1.6" + is-glob "^4.0.1" + lodash "^4.17.15" + semver "^7.3.2" + tsutils "^3.17.1" + +"@typescript-eslint/visitor-keys@3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.0.tgz#44de8e1b1df67adaf3b94d6b60b80f8faebc8dd3" + integrity sha512-O1qeoGqDbu0EZUC/MZ6F1WHTIzcBVhGqDj3LhTnj65WUA548RXVxUHbYhAW9bZWfb2rnX9QsbbP5nmeJ5Z4+ng== + dependencies: + eslint-visitor-keys "^1.1.0" + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -4680,6 +4843,13 @@ browserslist@^4.1.0, browserslist@^4.12.0, browserslist@^4.8.5: escalade "^3.0.2" node-releases "^1.1.60" +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -4702,7 +4872,7 @@ buffer-equal-constant-time@1.0.1: resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= -buffer-from@^1.0.0: +buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== @@ -4957,6 +5127,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4 escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -6244,6 +6422,11 @@ diff-match-patch@^1.0.0: resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37" integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw== +diff-sequences@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" + integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== + diff-sequences@^26.0.0: version "26.0.0" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.0.0.tgz#0760059a5c287637b842bd7085311db7060e88a6" @@ -6848,6 +7031,13 @@ eslint-plugin-babel@^5.3.1: dependencies: eslint-rule-composer "^0.3.0" +eslint-plugin-jest@^23.20.0: + version "23.20.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz#e1d69c75f639e99d836642453c4e75ed22da4099" + integrity sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw== + dependencies: + "@typescript-eslint/experimental-utils" "^2.5.0" + 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" @@ -6885,7 +7075,7 @@ eslint-scope@^4.0.3: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-scope@^5.1.0: +eslint-scope@^5.0.0, eslint-scope@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5" integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w== @@ -6893,7 +7083,7 @@ eslint-scope@^5.1.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^2.1.0: +eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -7279,7 +7469,7 @@ fast-glob@^3.1.1: micromatch "^4.0.2" picomatch "^2.2.1" -fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -7933,7 +8123,7 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= -glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -9475,6 +9665,16 @@ jest-config@^26.2.2: micromatch "^4.0.2" pretty-format "^26.2.0" +jest-diff@^25.2.1: + version "25.5.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" + integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== + dependencies: + chalk "^3.0.0" + diff-sequences "^25.2.6" + jest-get-type "^25.2.6" + pretty-format "^25.5.0" + jest-diff@^26.2.0: version "26.2.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.2.0.tgz#dee62c771adbb23ae585f3f1bd289a6e8ef4f298" @@ -9528,6 +9728,11 @@ jest-environment-node@^26.2.0: jest-mock "^26.2.0" jest-util "^26.2.0" +jest-get-type@^25.2.6: + version "25.2.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" + integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== + jest-get-type@^26.0.0: version "26.0.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.0.0.tgz#381e986a718998dbfafcd5ec05934be538db4039" @@ -9738,6 +9943,18 @@ jest-snapshot@^26.2.2: pretty-format "^26.2.0" semver "^7.3.2" +jest-util@26.x: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.3.0.tgz#a8974b191df30e2bf523ebbfdbaeb8efca535b3e" + integrity sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw== + dependencies: + "@jest/types" "^26.3.0" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + jest-util@^26.2.0: version "26.2.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.2.0.tgz#0597d2a27c559340957609f106c408c17c1d88ac" @@ -9903,6 +10120,13 @@ json3@^3.3.2: resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== +json5@2.x, json5@^2.1.0, json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== + dependencies: + minimist "^1.2.5" + json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -9915,13 +10139,6 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0, json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== - dependencies: - minimist "^1.2.5" - jsondiffpatch@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/jsondiffpatch/-/jsondiffpatch-0.4.1.tgz#9fb085036767f03534ebd46dcd841df6070c5773" @@ -10502,11 +10719,6 @@ lodash.flattendeep@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= -lodash.flow@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" - integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o= - lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -10557,6 +10769,11 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= +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.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" @@ -10710,7 +10927,7 @@ make-dir@^3.0.0: dependencies: semver "^6.0.0" -make-error@^1.3.5: +make-error@1.x, make-error@^1.3.5: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -11141,7 +11358,7 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" -mkdirp@*: +mkdirp@*, mkdirp@1.x: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -12602,6 +12819,16 @@ pretty-error@^2.1.1: renderkid "^2.0.1" utila "~0.4" +pretty-format@^25.2.1, pretty-format@^25.5.0: + version "25.5.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" + integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== + dependencies: + "@jest/types" "^25.5.0" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^16.12.0" + pretty-format@^26.2.0: version "26.2.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.2.0.tgz#83ecc8d7de676ff224225055e72bd64821cec4f1" @@ -12815,11 +13042,6 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pure-color@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" - integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4= - q@^1.1.2, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -13584,7 +13806,7 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.0: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -regexpp@^3.1.0: +regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== @@ -14140,16 +14362,16 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.x, semver@^7.2.1, semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.2.1, semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -15634,11 +15856,35 @@ ts-invariant@^0.4.0: dependencies: tslib "^1.9.3" -tslib@^1.10.0, tslib@^1.9.0, tslib@^1.9.3: +ts-jest@^26.2.0: + version "26.2.0" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.2.0.tgz#7ec22faceb05ee1467fdb5265d1b33c27441f163" + integrity sha512-9+y2qwzXdAImgLSYLXAb/Rhq9+K4rbt0417b8ai987V60g2uoNWBBmMkYgutI7D8Zhu+IbCSHbBtrHxB9d7xyA== + dependencies: + "@types/jest" "26.x" + bs-logger "0.x" + buffer-from "1.x" + fast-json-stable-stringify "2.x" + jest-util "26.x" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + mkdirp "1.x" + semver "7.x" + yargs-parser "18.x" + +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== +tsutils@^3.17.1: + version "3.17.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" + integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== + dependencies: + tslib "^1.8.1" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -15725,6 +15971,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^3.9.7: + version "3.9.7" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" + integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== + ua-parser-js@^0.7.18: version "0.7.21" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" @@ -16601,6 +16852,14 @@ yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== +yargs-parser@18.x, yargs-parser@^18.1.2, yargs-parser@^18.1.3: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -16617,14 +16876,6 @@ yargs-parser@^15.0.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^18.1.2, yargs-parser@^18.1.3: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs@^13.3.2: version "13.3.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"