chore(package): use complex-matcher package (#2536)
This commit is contained in:
parent
ef17cb1c6c
commit
9aed4f6fba
@ -57,6 +57,7 @@
|
||||
"chartist-plugin-legend": "^0.6.1",
|
||||
"chartist-plugin-tooltip": "0.0.11",
|
||||
"classnames": "^2.2.3",
|
||||
"complex-matcher": "^0.1.0",
|
||||
"cookies-js": "^1.2.2",
|
||||
"d3": "^4.12.0",
|
||||
"dependency-check": "^2.9.2",
|
||||
|
@ -1,12 +0,0 @@
|
||||
import { parse, toString } from './'
|
||||
import { ast, pattern } from './index.fixtures'
|
||||
|
||||
export default ({ benchmark }) => {
|
||||
benchmark('parse', () => {
|
||||
parse(pattern)
|
||||
})
|
||||
|
||||
benchmark('toString', () => {
|
||||
;ast::toString()
|
||||
})
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import {
|
||||
createAnd,
|
||||
createOr,
|
||||
createNot,
|
||||
createProperty,
|
||||
createString,
|
||||
createTruthyProperty,
|
||||
} from './'
|
||||
|
||||
export const pattern = 'foo !"\\\\ \\"" name:|(wonderwoman batman) hasCape?'
|
||||
|
||||
export const ast = createAnd([
|
||||
createString('foo'),
|
||||
createNot(createString('\\ "')),
|
||||
createProperty(
|
||||
'name',
|
||||
createOr([createString('wonderwoman'), createString('batman')])
|
||||
),
|
||||
createTruthyProperty('hasCape'),
|
||||
])
|
@ -1,400 +0,0 @@
|
||||
import every from 'lodash/every'
|
||||
import filter from 'lodash/filter'
|
||||
import forEach from 'lodash/forEach'
|
||||
import isArray from 'lodash/isArray'
|
||||
import isPlainObject from 'lodash/isPlainObject'
|
||||
import isString from 'lodash/isString'
|
||||
import map from 'lodash/map'
|
||||
import some from 'lodash/some'
|
||||
|
||||
import filterReduce from '../filter-reduce'
|
||||
import invoke from '../invoke'
|
||||
|
||||
// ===================================================================
|
||||
|
||||
const RAW_STRING_CHARS = invoke(() => {
|
||||
const chars = { __proto__: null }
|
||||
const add = (a, b = a) => {
|
||||
let i = a.charCodeAt(0)
|
||||
const j = b.charCodeAt(0)
|
||||
while (i <= j) {
|
||||
chars[String.fromCharCode(i++)] = true
|
||||
}
|
||||
}
|
||||
add('$')
|
||||
add('-')
|
||||
add('.')
|
||||
add('0', '9')
|
||||
add('_')
|
||||
add('A', 'Z')
|
||||
add('a', 'z')
|
||||
return chars
|
||||
})
|
||||
const isRawString = string => {
|
||||
const { length } = string
|
||||
for (let i = 0; i < length; ++i) {
|
||||
if (!RAW_STRING_CHARS[string[i]]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const createAnd = children =>
|
||||
children.length === 1 ? children[0] : { type: 'and', children }
|
||||
|
||||
export const createOr = children =>
|
||||
children.length === 1 ? children[0] : { type: 'or', children }
|
||||
|
||||
export const createNot = child => ({ type: 'not', child })
|
||||
|
||||
export const createProperty = (name, child) => ({
|
||||
type: 'property',
|
||||
name,
|
||||
child,
|
||||
})
|
||||
|
||||
export const createString = value => ({ type: 'string', value })
|
||||
|
||||
export const createTruthyProperty = name => ({ type: 'truthyProperty', name })
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// *and = terms
|
||||
// terms = term+
|
||||
// term = ws (groupedAnd | or | not | property | truthyProperty | string) ws
|
||||
// ws = ' '*
|
||||
// groupedAnd = "(" and ")"
|
||||
// *or = "|" ws "(" terms ")"
|
||||
// *not = "!" term
|
||||
// *property = string ws ":" term
|
||||
// *truthyProperty = string ws "?"
|
||||
// *string = quotedString | rawString
|
||||
// quotedString = "\"" ( /[^"\]/ | "\\\\" | "\\\"" )+
|
||||
// rawString = /[a-z0-9-_.]+/i
|
||||
export const parse = invoke(() => {
|
||||
let i
|
||||
let n
|
||||
let input
|
||||
|
||||
// -----
|
||||
|
||||
const backtrace = parser => () => {
|
||||
const pos = i
|
||||
const node = parser()
|
||||
if (node != null) {
|
||||
return node
|
||||
}
|
||||
i = pos
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
const parseAnd = () => parseTerms(createAnd)
|
||||
const parseTerms = fn => {
|
||||
let term = parseTerm()
|
||||
if (!term) {
|
||||
return
|
||||
}
|
||||
|
||||
const terms = [term]
|
||||
while ((term = parseTerm())) {
|
||||
terms.push(term)
|
||||
}
|
||||
return fn(terms)
|
||||
}
|
||||
const parseTerm = () => {
|
||||
parseWs()
|
||||
|
||||
const child =
|
||||
parseGroupedAnd() ||
|
||||
parseOr() ||
|
||||
parseNot() ||
|
||||
parseProperty() ||
|
||||
parseTruthyProperty() ||
|
||||
parseString()
|
||||
if (child) {
|
||||
parseWs()
|
||||
return child
|
||||
}
|
||||
}
|
||||
const parseWs = () => {
|
||||
while (input[i] === ' ') {
|
||||
++i
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
const parseGroupedAnd = backtrace(() => {
|
||||
let and
|
||||
if (input[i++] === '(' && (and = parseAnd()) && input[i++] === ')') {
|
||||
return and
|
||||
}
|
||||
})
|
||||
const parseOr = backtrace(() => {
|
||||
let or
|
||||
if (
|
||||
input[i++] === '|' &&
|
||||
parseWs() &&
|
||||
input[i++] === '(' &&
|
||||
(or = parseTerms(createOr)) &&
|
||||
input[i++] === ')'
|
||||
) {
|
||||
return or
|
||||
}
|
||||
})
|
||||
const parseNot = backtrace(() => {
|
||||
let child
|
||||
if (input[i++] === '!' && (child = parseTerm())) {
|
||||
return createNot(child)
|
||||
}
|
||||
})
|
||||
const parseProperty = backtrace(() => {
|
||||
let name, child
|
||||
if (
|
||||
(name = parseString()) &&
|
||||
parseWs() &&
|
||||
input[i++] === ':' &&
|
||||
(child = parseTerm())
|
||||
) {
|
||||
return createProperty(name.value, child)
|
||||
}
|
||||
})
|
||||
const parseString = () => {
|
||||
let value
|
||||
if (
|
||||
(value = parseQuotedString()) != null ||
|
||||
(value = parseRawString()) != null
|
||||
) {
|
||||
return createString(value)
|
||||
}
|
||||
}
|
||||
const parseQuotedString = backtrace(() => {
|
||||
if (input[i++] !== '"') {
|
||||
return
|
||||
}
|
||||
|
||||
const value = []
|
||||
let char
|
||||
while (i < n && (char = input[i++]) !== '"') {
|
||||
if (char === '\\') {
|
||||
char = input[i++]
|
||||
}
|
||||
value.push(char)
|
||||
}
|
||||
|
||||
return value.join('')
|
||||
})
|
||||
const parseRawString = () => {
|
||||
let value = ''
|
||||
let c
|
||||
while ((c = input[i]) && RAW_STRING_CHARS[c]) {
|
||||
++i
|
||||
value += c
|
||||
}
|
||||
if (value.length) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
const parseTruthyProperty = backtrace(() => {
|
||||
let name
|
||||
if ((name = parseString()) && parseWs() && input[i++] === '?') {
|
||||
return createTruthyProperty(name.value)
|
||||
}
|
||||
})
|
||||
|
||||
return input_ => {
|
||||
if (!input_) {
|
||||
return
|
||||
}
|
||||
|
||||
i = 0
|
||||
input = input_.split('')
|
||||
n = input.length
|
||||
|
||||
try {
|
||||
return parseAnd()
|
||||
} finally {
|
||||
input = null
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
const _getPropertyClauseStrings = ({ child }) => {
|
||||
const { type } = child
|
||||
|
||||
if (type === 'or') {
|
||||
const strings = []
|
||||
forEach(child.children, child => {
|
||||
if (child.type === 'string') {
|
||||
strings.push(child.value)
|
||||
}
|
||||
})
|
||||
return strings
|
||||
}
|
||||
|
||||
if (type === 'string') {
|
||||
return [child.value]
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
// Find possible values for property clauses in a and clause.
|
||||
export const getPropertyClausesStrings = function () {
|
||||
if (!this) {
|
||||
return {}
|
||||
}
|
||||
|
||||
const { type } = this
|
||||
|
||||
if (type === 'property') {
|
||||
return {
|
||||
[this.name]: _getPropertyClauseStrings(this),
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'and') {
|
||||
const strings = {}
|
||||
forEach(this.children, node => {
|
||||
if (node.type === 'property') {
|
||||
const { name } = node
|
||||
const values = strings[name]
|
||||
if (values) {
|
||||
values.push.apply(values, _getPropertyClauseStrings(node))
|
||||
} else {
|
||||
strings[name] = _getPropertyClauseStrings(node)
|
||||
}
|
||||
}
|
||||
})
|
||||
return strings
|
||||
}
|
||||
|
||||
return {}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const removePropertyClause = function (name) {
|
||||
let type
|
||||
if (!this || ((type = this.type) === 'property' && this.name === name)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (type === 'and') {
|
||||
return createAnd(
|
||||
filter(
|
||||
this.children,
|
||||
node => node.type !== 'property' || node.name !== name
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
const _addAndClause = (node, child, predicate, reducer) =>
|
||||
createAnd(
|
||||
filterReduce(
|
||||
node.type === 'and' ? node.children : [node],
|
||||
predicate,
|
||||
reducer,
|
||||
child
|
||||
)
|
||||
)
|
||||
|
||||
export const setPropertyClause = function (name, child) {
|
||||
const property = createProperty(
|
||||
name,
|
||||
isString(child) ? createString(child) : child
|
||||
)
|
||||
|
||||
if (!this) {
|
||||
return property
|
||||
}
|
||||
|
||||
return _addAndClause(
|
||||
this,
|
||||
property,
|
||||
node => node.type === 'property' && node.name === name
|
||||
)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const execute = invoke(() => {
|
||||
const visitors = {
|
||||
and: ({ children }, value) =>
|
||||
every(children, child => child::execute(value)),
|
||||
not: ({ child }, value) => !child::execute(value),
|
||||
or: ({ children }, value) => some(children, child => child::execute(value)),
|
||||
property: ({ name, child }, value) =>
|
||||
value != null && child::execute(value[name]),
|
||||
truthyProperty: ({ name }, value) => !!value[name],
|
||||
string: invoke(() => {
|
||||
const match = (pattern, value) => {
|
||||
if (isString(value)) {
|
||||
return value.toLowerCase().indexOf(pattern) !== -1
|
||||
}
|
||||
|
||||
if (isArray(value) || isPlainObject(value)) {
|
||||
return some(value, value => match(pattern, value))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return ({ value: pattern }, value) => match(pattern.toLowerCase(), value)
|
||||
}),
|
||||
}
|
||||
|
||||
return function (value) {
|
||||
return visitors[this.type](this, value)
|
||||
}
|
||||
})
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const toString = invoke(() => {
|
||||
const toStringTerms = terms => map(terms, toString).join(' ')
|
||||
const toStringGroup = terms => `(${toStringTerms(terms)})`
|
||||
|
||||
const visitors = {
|
||||
and: ({ children }) => toStringGroup(children),
|
||||
not: ({ child }) => `!${toString(child)}`,
|
||||
or: ({ children }) => `|${toStringGroup(children)}`,
|
||||
property: ({ name, child }) =>
|
||||
`${toString(createString(name))}:${toString(child)}`,
|
||||
string: ({ value }) =>
|
||||
isRawString(value)
|
||||
? value
|
||||
: `"${value.replace(/\\|"/g, match => `\\${match}`)}"`,
|
||||
truthyProperty: ({ name }) => `${toString(createString(name))}?`,
|
||||
}
|
||||
|
||||
const toString = node => visitors[node.type](node)
|
||||
|
||||
// Special case for a root “and”: do not add braces.
|
||||
return function () {
|
||||
return !this
|
||||
? ''
|
||||
: this.type === 'and' ? toStringTerms(this.children) : toString(this)
|
||||
}
|
||||
})
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
export const create = pattern => {
|
||||
pattern = parse(pattern)
|
||||
if (!pattern) {
|
||||
return
|
||||
}
|
||||
|
||||
return value => pattern::execute(value)
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/* eslint-env jest */
|
||||
|
||||
import {
|
||||
getPropertyClausesStrings,
|
||||
parse,
|
||||
setPropertyClause,
|
||||
toString,
|
||||
} from './'
|
||||
import { ast, pattern } from './index.fixtures'
|
||||
|
||||
it('getPropertyClausesStrings', () => {
|
||||
const tmp = parse('foo bar:baz baz:|(foo bar)')::getPropertyClausesStrings()
|
||||
expect(tmp).toEqual({
|
||||
bar: ['baz'],
|
||||
baz: ['foo', 'bar'],
|
||||
})
|
||||
})
|
||||
|
||||
it('parse', () => {
|
||||
expect(parse(pattern)).toEqual(ast)
|
||||
})
|
||||
|
||||
it('setPropertyClause', () => {
|
||||
expect(null::setPropertyClause('foo', 'bar')::toString()).toBe('foo:bar')
|
||||
|
||||
expect(
|
||||
parse('baz')
|
||||
::setPropertyClause('foo', 'bar')
|
||||
::toString()
|
||||
).toBe('baz foo:bar')
|
||||
|
||||
expect(
|
||||
parse('plip foo:baz plop')
|
||||
::setPropertyClause('foo', 'bar')
|
||||
::toString()
|
||||
).toBe('plip plop foo:bar')
|
||||
|
||||
expect(
|
||||
parse('foo:|(baz plop)')
|
||||
::setPropertyClause('foo', 'bar')
|
||||
::toString()
|
||||
).toBe('foo:bar')
|
||||
})
|
||||
|
||||
it('toString', () => {
|
||||
expect(pattern).toBe(ast::toString())
|
||||
})
|
@ -1,9 +1,9 @@
|
||||
import * as CM from 'complex-matcher'
|
||||
import React from 'react'
|
||||
|
||||
import Component from './base-component'
|
||||
import propTypes from './prop-types-decorator'
|
||||
import Tags from './tags'
|
||||
import { createString, createProperty, toString } from './complex-matcher'
|
||||
|
||||
@propTypes({
|
||||
labels: propTypes.arrayOf(React.PropTypes.string).isRequired,
|
||||
@ -19,7 +19,7 @@ export default class HomeTags extends Component {
|
||||
|
||||
_onClick = label => {
|
||||
const s = encodeURIComponent(
|
||||
createProperty('tags', createString(label))::toString()
|
||||
new CM.Property('tags', new CM.String(label)).toString()
|
||||
)
|
||||
const t = encodeURIComponent(this.props.type)
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as CM from 'complex-matcher'
|
||||
import _ from 'intl'
|
||||
import classNames from 'classnames'
|
||||
import DropdownMenu from 'react-bootstrap-4/lib/DropdownMenu' // https://phabricator.babeljs.io/T6662 so Dropdown.Menu won't work like https://react-bootstrap.github.io/components.html#btn-dropdowns-custom
|
||||
@ -29,7 +30,6 @@ import SingleLineRow from '../single-line-row'
|
||||
import Tooltip from '../tooltip'
|
||||
import { BlockLink } from '../link'
|
||||
import { Container, Col } from '../grid'
|
||||
import { create as createMatcher } from '../complex-matcher'
|
||||
import { Input as DebouncedInput } from '../debounce-component-decorator'
|
||||
import {
|
||||
createCounter,
|
||||
@ -326,6 +326,7 @@ export default class SortedTable extends Component {
|
||||
|
||||
this._getTotalNumberOfItems = createCounter(() => this.props.collection)
|
||||
|
||||
const createMatcher = str => CM.parse(str).createPredicate()
|
||||
this._getItems = createSort(
|
||||
createFilter(
|
||||
() => this.props.collection,
|
||||
|
@ -506,7 +506,7 @@ export default class Home extends Component {
|
||||
}
|
||||
|
||||
const parsed = ComplexMatcher.parse(filter)
|
||||
const properties = parsed::ComplexMatcher.getPropertyClausesStrings()
|
||||
const properties = ComplexMatcher.getPropertyClausesStrings(parsed)
|
||||
|
||||
const sort = this._getDefaultSort(props)
|
||||
|
||||
@ -537,14 +537,14 @@ export default class Home extends Component {
|
||||
|
||||
_getFilterFunction = createSelector(
|
||||
this._getParsedFilter,
|
||||
filter => filter && (value => filter::ComplexMatcher.execute(value))
|
||||
filter => filter !== undefined && filter.createPredicate()
|
||||
)
|
||||
|
||||
// Optionally can take the props to be able to use it in
|
||||
// componentWillReceiveProps().
|
||||
_setFilter (filter, props = this.props, replace) {
|
||||
if (!isString(filter)) {
|
||||
filter = filter::ComplexMatcher.toString()
|
||||
filter = filter.toString()
|
||||
}
|
||||
|
||||
const { pathname, query } = props.location
|
||||
@ -600,13 +600,14 @@ export default class Home extends Component {
|
||||
|
||||
this._setFilter(
|
||||
pools.length
|
||||
? filter::ComplexMatcher.setPropertyClause(
|
||||
? ComplexMatcher.setPropertyClause(
|
||||
filter,
|
||||
'$pool',
|
||||
ComplexMatcher.createOr(
|
||||
map(pools, pool => ComplexMatcher.createString(pool.id))
|
||||
new ComplexMatcher.Or(
|
||||
map(pools, pool => new ComplexMatcher.String(pool.id))
|
||||
)
|
||||
)
|
||||
: filter::ComplexMatcher.removePropertyClause('$pool')
|
||||
: ComplexMatcher.setPropertyClause(filter, '$pool', undefined)
|
||||
)
|
||||
}
|
||||
_updateSelectedHosts = hosts => {
|
||||
@ -614,13 +615,14 @@ export default class Home extends Component {
|
||||
|
||||
this._setFilter(
|
||||
hosts.length
|
||||
? filter::ComplexMatcher.setPropertyClause(
|
||||
? ComplexMatcher.setPropertyClause(
|
||||
filter,
|
||||
'$container',
|
||||
ComplexMatcher.createOr(
|
||||
map(hosts, host => ComplexMatcher.createString(host.id))
|
||||
new ComplexMatcher.Or(
|
||||
map(hosts, host => new ComplexMatcher.String(host.id))
|
||||
)
|
||||
)
|
||||
: filter::ComplexMatcher.removePropertyClause('$container')
|
||||
: ComplexMatcher.setPropertyClause(filter, '$container', undefined)
|
||||
)
|
||||
}
|
||||
_updateSelectedTags = tags => {
|
||||
@ -628,13 +630,14 @@ export default class Home extends Component {
|
||||
|
||||
this._setFilter(
|
||||
tags.length
|
||||
? filter::ComplexMatcher.setPropertyClause(
|
||||
? ComplexMatcher.setPropertyClause(
|
||||
filter,
|
||||
'tags',
|
||||
ComplexMatcher.createOr(
|
||||
map(tags, tag => ComplexMatcher.createString(tag.id))
|
||||
new ComplexMatcher.Or(
|
||||
map(tags, tag => new ComplexMatcher.String(tag.id))
|
||||
)
|
||||
)
|
||||
: filter::ComplexMatcher.removePropertyClause('tags')
|
||||
: ComplexMatcher.setPropertyClause(filter, 'tags', undefined)
|
||||
)
|
||||
}
|
||||
_updateSelectedResourceSets = resourceSets => {
|
||||
@ -642,13 +645,14 @@ export default class Home extends Component {
|
||||
|
||||
this._setFilter(
|
||||
resourceSets.length
|
||||
? filter::ComplexMatcher.setPropertyClause(
|
||||
? ComplexMatcher.setPropertyClause(
|
||||
filter,
|
||||
'resourceSet',
|
||||
ComplexMatcher.createOr(
|
||||
map(resourceSets, set => ComplexMatcher.createString(set.id))
|
||||
new ComplexMatcher.Or(
|
||||
map(resourceSets, set => new ComplexMatcher.String(set.id))
|
||||
)
|
||||
)
|
||||
: filter::ComplexMatcher.removePropertyClause('resourceSet')
|
||||
: ComplexMatcher.setPropertyClause(filter, 'resourceSet', undefined)
|
||||
)
|
||||
}
|
||||
_addCustomFilter = () => {
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as CM from 'complex-matcher'
|
||||
import _ from 'intl'
|
||||
import Copiable from 'copiable'
|
||||
import Icon from 'icon'
|
||||
@ -12,7 +13,6 @@ import { FormattedRelative } from 'react-intl'
|
||||
import { formatSize } from 'utils'
|
||||
import Usage, { UsageElement } from 'usage'
|
||||
import { getObject } from 'selectors'
|
||||
import { createString, createProperty, toString } from 'complex-matcher'
|
||||
import {
|
||||
CpuSparkLines,
|
||||
MemorySparkLines,
|
||||
@ -30,7 +30,7 @@ export default ({
|
||||
}) => {
|
||||
const pool = getObject(store.getState(), host.$pool)
|
||||
const vmsFilter = encodeURIComponent(
|
||||
createProperty('$container', createString(host.id))::toString()
|
||||
new CM.Property('$container', new CM.String(host.id)).toString()
|
||||
)
|
||||
|
||||
return (
|
||||
|
16
yarn.lock
16
yarn.lock
@ -33,6 +33,13 @@
|
||||
dependencies:
|
||||
"@babel/types" "7.0.0-beta.31"
|
||||
|
||||
"@babel/polyfill@^7.0.0-beta.35":
|
||||
version "7.0.0-beta.35"
|
||||
resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.0.0-beta.35.tgz#49d033c4fdfa54a3a11e8f87239530141650d47a"
|
||||
dependencies:
|
||||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.11.1"
|
||||
|
||||
"@babel/template@7.0.0-beta.31":
|
||||
version "7.0.0-beta.31"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.31.tgz#577bb29389f6c497c3e7d014617e7d6713f68bda"
|
||||
@ -1954,6 +1961,13 @@ commander@2.8.x:
|
||||
dependencies:
|
||||
graceful-readlink ">= 1.0.0"
|
||||
|
||||
complex-matcher@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/complex-matcher/-/complex-matcher-0.1.0.tgz#a26ff7c362e9f67b781374e99ea3a502cbd28191"
|
||||
dependencies:
|
||||
"@babel/polyfill" "^7.0.0-beta.35"
|
||||
lodash "^4.17.4"
|
||||
|
||||
component-emitter@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6"
|
||||
@ -7334,7 +7348,7 @@ regenerate@^1.2.1:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f"
|
||||
|
||||
regenerator-runtime@^0.11.0:
|
||||
regenerator-runtime@^0.11.0, regenerator-runtime@^0.11.1:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user