The tests do not depend on separate files for loading templates. This is for the layouts to be defined alongside the tests for easier updates. The methods have been refactored and documented for ease of use of the consumers.master
@@ -1,4 +1,6 @@ | |||
# formxtr | |||
# formxtra | |||
_(read "form extra")_ | |||
Extract form values through the DOM. | |||
@@ -20,7 +22,7 @@ Upon retrieving the field values somehow, some libraries attempt to duplicate th | |||
for instance by attaching event listeners and storing the new values into some internal object or map, which can be | |||
retrieved by some other exposed function. | |||
With `formxtr`, there is no need to traverse the DOM for individual fields to get their values. Provided the fields are | |||
With `formxtra`, there is no need to traverse the DOM for individual fields to get their values. Provided the fields are | |||
associated to the form (either as a descendant of the `<form>` element or [associated through the `form=""` | |||
attribute](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form)) and has a valid | |||
`name`, the values of these fields can be easily extracted, using the `form.elements` attribute built-in to the DOM and | |||
@@ -32,8 +34,8 @@ of the field elements are already stored in the DOM, waiting to be accessed. | |||
The package can be found on: | |||
- [Modal Pack](https://js.pack.modal.sh) | |||
- [npm](https://npmjs.com/package/formxtr) | |||
- [GitHub Package Registry](https://github.com/TheoryOfNekomata/formxtr/packages/784699) | |||
- [npm](https://npmjs.com/package/formxtra) | |||
- [GitHub Package Registry](https://github.com/TheoryOfNekomata/formxtra/packages/784699) | |||
## Usage | |||
@@ -60,7 +62,7 @@ For an example form: | |||
Use the library as follows (code is in TypeScript, but can work with JavaScript as well): | |||
```typescript | |||
import getFormValues from '@theoryofnekomata/formxtr'; | |||
import getFormValues from '@theoryofnekomata/formxtra'; | |||
const form: HTMLFormElement = document.getElementById('form'); | |||
@@ -1,12 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,98 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<article> | |||
<h2></h2> | |||
<form> | |||
<div> | |||
<input type="text" placeholder="First Name" name="first_name" /> | |||
</div> | |||
<div> | |||
<input type="text" placeholder="Middle Name" name="middle_name" /> | |||
</div> | |||
<div> | |||
<input type="text" placeholder="Last Name" name="last_name" /> | |||
</div> | |||
<fieldset> | |||
<legend>Gender</legend> | |||
<div> | |||
<label> | |||
<input type="radio" name="gender" value="m" /> | |||
Male | |||
</label> | |||
<label> | |||
<input type="radio" name="gender" value="f" /> | |||
Female | |||
</label> | |||
</div> | |||
</fieldset> | |||
<div> | |||
<select name="civil_status"> | |||
<option value="">Select Civil Status</option> | |||
<option value="single">Single</option> | |||
<option value="married">Married</option> | |||
<option value="divorced">Divorced</option> | |||
<option value="separated">Separated</option> | |||
</select> | |||
</div> | |||
<div> | |||
<label> | |||
<input type="checkbox" name="new_registration" /> | |||
New Registration | |||
</label> | |||
</div> | |||
<div> | |||
<label> | |||
<input type="checkbox" value="filipino" name="nationality" /> | |||
Filipino | |||
</label> | |||
</div> | |||
<fieldset> | |||
<legend> | |||
Default Dependents | |||
</legend> | |||
<div> | |||
<label> | |||
<input type="radio" value="James" name="dependent" /> | |||
James | |||
</label> | |||
<label> | |||
<input type="radio" value="Jun" name="dependent" /> | |||
Jun | |||
</label> | |||
</div> | |||
</fieldset> | |||
<div> | |||
<button type="button" class="dependents"> | |||
Add Dependents | |||
</button> | |||
</div> | |||
<div> | |||
<textarea name="notes" placeholder="Notes"></textarea> | |||
</div> | |||
<div> | |||
<button name="submit" value="Hello" type="submit">Hello</button> | |||
<button name="submit" value="Hi" type="submit">Hi</button> | |||
</div> | |||
</form> | |||
</article> | |||
<script> | |||
Array.from(document.getElementsByClassName('dependents')).forEach(d => { | |||
d.addEventListener('click', e => { | |||
const container = document.createElement('div') | |||
const input = document.createElement('input') | |||
input.name = 'dependent' | |||
input.type = 'text' | |||
input.placeholder = 'Dependent' | |||
container.classList.add('additional-dependent') | |||
container.appendChild(input) | |||
e.target.parentElement.parentElement.insertBefore(container, e.target.parentElement) | |||
}) | |||
}) | |||
</script> | |||
</body> | |||
</html> |
@@ -1,19 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input | |||
type="text" name="hello" value="Hi" | |||
disabled | |||
/> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,16 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="file" name="hello" /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,17 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" /> | |||
</label> | |||
<button name="action" value="Foo" type="submit">Foo</button> | |||
<button name="action" value="Bar" type="submit">Bar</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,17 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" /> | |||
</label> | |||
<input name="action" value="Foo" type="submit" /> | |||
<input name="action" value="Bar" type="submit" /> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,16 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,16 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="file" name="hello" multiple /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,21 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<select name="hello" multiple> | |||
<option>Foo</option> | |||
<option selected>Bar</option> | |||
<option>Baz</option> | |||
<option selected>Quux</option> | |||
</select> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,15 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form id="form"></form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" form="form" /> | |||
</label> | |||
<button type="submit" form="form">Submit</button> | |||
</body> | |||
</html> |
@@ -1,18 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form | |||
id="form" | |||
> | |||
<button type="submit">Submit</button> | |||
</form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" form="form" /> | |||
</label> | |||
</body> | |||
</html> |
@@ -1,19 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input | |||
type="text" name="hello" value="Hi" | |||
readonly | |||
/> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -1,20 +0,0 @@ | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Title</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<select name="hello"> | |||
<option>Foo</option> | |||
<option>Bar</option> | |||
<option selected>Baz</option> | |||
</select> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> |
@@ -0,0 +1,3 @@ | |||
{ | |||
"hello": "hi" | |||
} |
@@ -1,18 +0,0 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../../test/utils' | |||
describe('blank template', () => { | |||
beforeEach(utils.setup('blank')) | |||
it('should have blank form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}); | |||
}) |
@@ -0,0 +1,82 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../utils' | |||
describe('checkbox', () => { | |||
describe('basic', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Checkbox/Basic</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="checkbox" name="enabled" /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have no form values', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const values = getFormValues(form, {submitter}) | |||
const before = utils.makeSearchParams(values).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(values['enabled']).toBeUndefined(); | |||
expect(before).toEqual(after); | |||
}, | |||
'' | |||
); | |||
}); | |||
it('should have false checked value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const values = getFormValues(form, {submitter, booleanValuelessCheckbox: true }) | |||
expect(values['enabled']).toBe(false); | |||
} | |||
); | |||
}); | |||
}) | |||
describe('checked', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Checkbox/Checked</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="checkbox" name="enabled" checked /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have single form value on a single field', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
'enabled=on' | |||
); | |||
}); | |||
}) | |||
}) |
@@ -1,38 +0,0 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../../test/utils'; | |||
describe('everything template', () => { | |||
beforeEach(utils.setup('everything')) | |||
it('should have correct form values', () => { | |||
utils.test( | |||
(cy) => { | |||
cy.get('[name="first_name"]').type('John') | |||
cy.get('[name="middle_name"]').type('Marcelo') | |||
cy.get('[name="last_name"]').type('Dela Cruz') | |||
cy.get('[name="gender"][value="m"]').check() | |||
cy.get('[name="civil_status"]').select('Married') | |||
cy.get('[name="new_registration"]').check() | |||
cy.get('[name="nationality"][value="filipino"]').check() | |||
cy.get('[name="dependent"][value="Jun"]').check() | |||
// Note: JSDOM is static for now | |||
cy.get('button.dependents').click() | |||
cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Juana') | |||
cy.get('button.dependents').click() | |||
cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Jane') | |||
cy.get('button.dependents').click() | |||
cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Josh') | |||
cy.get('[name="notes"]').type('Test content\n\nNew line\n\nAnother line') | |||
return cy.get('[name="submit"][value="Hi"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
'first_name=John&middle_name=Marcelo&last_name=Dela+Cruz&gender=m&civil_status=married&new_registration=on&nationality=filipino&dependent=Jun¬es=Test+content%0D%0A%0D%0ANew+line%0D%0A%0D%0AAnother+line&submit=Hi', | |||
); | |||
}); | |||
}) |
@@ -0,0 +1,142 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../utils' | |||
describe('file', () => { | |||
describe('single', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>File/Single</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="file" name="hello" /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have no form values when no file is selected', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}) | |||
it('should have single form value when a file is selected', () => { | |||
utils.test( | |||
(cy: any) => { | |||
cy | |||
.get('[name="hello"]') | |||
.attachFile('uploads/data.json') | |||
return cy.get('[type="submit"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'data.json', | |||
} | |||
); | |||
}) | |||
it('should retrieve the file list upon setting appropriate option', () => { | |||
utils.test( | |||
(cy: any) => { | |||
cy | |||
.get('[name="hello"]') | |||
.attachFile('uploads/data.json') | |||
return cy.get('[type="submit"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any) => { | |||
const formValues = getFormValues(form, {submitter, getFileObjects: true}) | |||
expect(formValues.hello[0].name).toBe('data.json') | |||
//expect(before).toEqual(after); | |||
}, | |||
); | |||
}) | |||
}) | |||
describe('multiple', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>File/Multiple</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="file" name="hello" multiple /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have no form values when no file is selected', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}) | |||
it('should have single form value when a file is selected', () => { | |||
utils.test( | |||
(cy: any) => { | |||
cy | |||
.get('[name="hello"]') | |||
.attachFile(['uploads/data.json', 'uploads/data2.json']) | |||
return cy.get('[type="submit"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
'hello=data.json&hello=data2.json', | |||
); | |||
}) | |||
it('should retrieve the file list upon setting appropriate option', () => { | |||
utils.test( | |||
(cy: any) => { | |||
cy | |||
.get('[name="hello"]') | |||
.attachFile(['uploads/data.json', 'uploads/data2.json']) | |||
return cy.get('[type="submit"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any) => { | |||
const formValues = getFormValues(form, {submitter, getFileObjects: true}) | |||
expect(formValues.hello[0].name).toBe('data.json') | |||
expect(formValues.hello[1].name).toBe('data2.json') | |||
}, | |||
); | |||
}) | |||
}) | |||
}) |
@@ -0,0 +1,168 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../utils' | |||
describe('misc', () => { | |||
describe('blank', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Misc/Blank</title> | |||
</head> | |||
<body> | |||
<form> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have blank form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}); | |||
}) | |||
describe('everything', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Misc/Everything</title> | |||
</head> | |||
<body> | |||
<article> | |||
<h2></h2> | |||
<form> | |||
<div> | |||
<input type="text" placeholder="First Name" name="first_name" /> | |||
</div> | |||
<div> | |||
<input type="text" placeholder="Middle Name" name="middle_name" /> | |||
</div> | |||
<div> | |||
<input type="text" placeholder="Last Name" name="last_name" /> | |||
</div> | |||
<fieldset> | |||
<legend>Gender</legend> | |||
<div> | |||
<label> | |||
<input type="radio" name="gender" value="m" /> | |||
Male | |||
</label> | |||
<label> | |||
<input type="radio" name="gender" value="f" /> | |||
Female | |||
</label> | |||
</div> | |||
</fieldset> | |||
<div> | |||
<select name="civil_status"> | |||
<option value="">Select Civil Status</option> | |||
<option value="single">Single</option> | |||
<option value="married">Married</option> | |||
<option value="divorced">Divorced</option> | |||
<option value="separated">Separated</option> | |||
</select> | |||
</div> | |||
<div> | |||
<label> | |||
<input type="checkbox" name="new_registration" /> | |||
New Registration | |||
</label> | |||
</div> | |||
<div> | |||
<label> | |||
<input type="checkbox" value="filipino" name="nationality" /> | |||
Filipino | |||
</label> | |||
</div> | |||
<fieldset> | |||
<legend> | |||
Default Dependents | |||
</legend> | |||
<div> | |||
<label> | |||
<input type="radio" value="James" name="dependent" /> | |||
James | |||
</label> | |||
<label> | |||
<input type="radio" value="Jun" name="dependent" /> | |||
Jun | |||
</label> | |||
</div> | |||
</fieldset> | |||
<div> | |||
<button type="button" class="dependents"> | |||
Add Dependents | |||
</button> | |||
</div> | |||
<div> | |||
<textarea name="notes" placeholder="Notes"></textarea> | |||
</div> | |||
<div> | |||
<button name="submit" value="Hello" type="submit">Hello</button> | |||
<button name="submit" value="Hi" type="submit">Hi</button> | |||
</div> | |||
</form> | |||
</article> | |||
<script> | |||
Array.from(document.getElementsByClassName('dependents')).forEach(d => { | |||
d.addEventListener('click', e => { | |||
const container = document.createElement('div') | |||
const input = document.createElement('input') | |||
input.name = 'dependent' | |||
input.type = 'text' | |||
input.placeholder = 'Dependent' | |||
container.classList.add('additional-dependent') | |||
container.appendChild(input) | |||
e.target.parentElement.parentElement.insertBefore(container, e.target.parentElement) | |||
}) | |||
}) | |||
</script> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have correct form values', () => { | |||
utils.test( | |||
(cy) => { | |||
cy.get('[name="first_name"]').type('John') | |||
cy.get('[name="middle_name"]').type('Marcelo') | |||
cy.get('[name="last_name"]').type('Dela Cruz') | |||
cy.get('[name="gender"][value="m"]').check() | |||
cy.get('[name="civil_status"]').select('Married') | |||
cy.get('[name="new_registration"]').check() | |||
cy.get('[name="nationality"][value="filipino"]').check() | |||
cy.get('[name="dependent"][value="Jun"]').check() | |||
// Note: JSDOM is static for now | |||
cy.get('button.dependents').click() | |||
cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Juana') | |||
cy.get('button.dependents').click() | |||
cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Jane') | |||
cy.get('button.dependents').click() | |||
cy.get('.additional-dependent [name="dependent"][type="text"]').last().type('Josh') | |||
cy.get('[name="notes"]').type('Test content\n\nNew line\n\nAnother line') | |||
return cy.get('[name="submit"][value="Hi"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
'first_name=John&middle_name=Marcelo&last_name=Dela+Cruz&gender=m&civil_status=married&new_registration=on&nationality=filipino&dependent=Jun¬es=Test+content%0D%0A%0D%0ANew+line%0D%0A%0D%0AAnother+line&submit=Hi', | |||
); | |||
}); | |||
}) | |||
}) |
@@ -0,0 +1,81 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../utils' | |||
describe('select', () => { | |||
describe('multiple', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Select/Multiple</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<select name="hello" multiple> | |||
<option>Foo</option> | |||
<option selected>Bar</option> | |||
<option>Baz</option> | |||
<option selected>Quux</option> | |||
</select> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have multiple form values on a single field', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
'hello=Bar&hello=Quux' | |||
); | |||
}); | |||
}) | |||
describe('single', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Select/Single</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<select name="hello"> | |||
<option>Foo</option> | |||
<option>Bar</option> | |||
<option selected>Baz</option> | |||
</select> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have single form value on a single field', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Baz', | |||
} | |||
); | |||
}); | |||
}) | |||
}) |
@@ -1,200 +0,0 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../../test/utils'; | |||
describe('single input template', () => { | |||
beforeEach(utils.setup('single-input')) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single outside input template', () => { | |||
beforeEach(utils.setup('single-outside-input')) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single outside input and submitter template', () => { | |||
beforeEach(utils.setup('single-outside-input-and-submitter')) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single readonly template', () => { | |||
beforeEach(utils.setup('single-readonly-input')) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single disabled template', () => { | |||
beforeEach(utils.setup('single-disabled-input')) | |||
it('should have blank form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}); | |||
}) | |||
describe('single input with double button submitters template', () => { | |||
beforeEach(utils.setup('single-input-with-double-button-submitters')) | |||
it('should have double form values', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[name="action"][value="Foo"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
action: 'Foo', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single input with double input submitters template', () => { | |||
beforeEach(utils.setup('single-input-with-double-input-submitters')) | |||
it('should have double form values', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[name="action"][value="Bar"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
action: 'Bar', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single select template', () => { | |||
beforeEach(utils.setup('single-select')) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Baz', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single multiple select template', () => { | |||
beforeEach(utils.setup('single-multiple-select')) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Bar,Quux', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('single file input template', () => { | |||
beforeEach(utils.setup('single-file-input')) | |||
it('should have no form values when no file is selected', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}) | |||
it('should have single form value when a file is selected', () => { | |||
utils.test( | |||
(cy: any) => { | |||
cy | |||
.get('[name="hello"]') | |||
.attachFile('uploads/data.json') | |||
return cy.get('[type="submit"]') | |||
}, | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'data.json', | |||
} | |||
); | |||
}) | |||
}) |
@@ -0,0 +1,112 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../utils' | |||
describe('submitter', () => { | |||
describe('button', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Submitter/Button</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" /> | |||
</label> | |||
<button name="action" value="Foo" type="submit">Foo</button> | |||
<button name="action" value="Bar" type="submit">Bar</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have double form values', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[name="action"][value="Foo"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
action: 'Foo', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('input', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Submitter/Input</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" /> | |||
</label> | |||
<input name="action" value="Foo" type="submit" /> | |||
<input name="action" value="Bar" type="submit" /> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have double form values', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[name="action"][value="Bar"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
action: 'Bar', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('outside', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Submitter/Outside</title> | |||
</head> | |||
<body> | |||
<form id="form"></form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" form="form" /> | |||
</label> | |||
<button type="submit" form="form">Submit</button> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
}) |
@@ -0,0 +1,148 @@ | |||
import getFormValues from '../../src' | |||
import * as utils from '../utils' | |||
describe('text', () => { | |||
describe('basic', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Text/Basic</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" /> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('disabled', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Text/Disabled</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input | |||
type="text" name="hello" value="Hi" | |||
disabled | |||
/> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have blank form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{} | |||
); | |||
}); | |||
}) | |||
describe('outside', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Text/Outside</title> | |||
</head> | |||
<body> | |||
<form id="form"> | |||
<button type="submit">Submit</button> | |||
</form> | |||
<label> | |||
<span>Hello</span> | |||
<input type="text" name="hello" value="Hi" form="form" /> | |||
</label> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
describe('readonly', () => { | |||
beforeEach(utils.setup(` | |||
<!DOCTYPE html> | |||
<html lang="en-PH"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>Text/Readonly</title> | |||
</head> | |||
<body> | |||
<form> | |||
<label> | |||
<span>Hello</span> | |||
<input | |||
type="text" name="hello" value="Hi" | |||
readonly | |||
/> | |||
</label> | |||
<button type="submit">Submit</button> | |||
</form> | |||
</body> | |||
</html> | |||
`)) | |||
it('should have single form value', () => { | |||
utils.test( | |||
(cy: any) => cy.get('[type="submit"]'), | |||
(form: HTMLFormElement, submitter: any, search: any) => { | |||
const before = utils.makeSearchParams(getFormValues(form, {submitter})).toString(); | |||
const after = utils.makeSearchParams(search).toString(); | |||
expect(before).toEqual(after); | |||
}, | |||
{ | |||
hello: 'Hi', | |||
} | |||
); | |||
}); | |||
}) | |||
}) |
@@ -0,0 +1,95 @@ | |||
/// <reference types="cypress" /> | |||
import JSDOMDummyCypress from './jsdom-compat' | |||
type ExpectedSearchValue = Record<string, string> | string | |||
type RetrieveSubmitterFn = (wrapper: any) => any | |||
type HTMLSubmitterElement = HTMLButtonElement | HTMLInputElement | |||
type TestFn = (form: HTMLFormElement, submitter: HTMLSubmitterElement, after: ExpectedSearchValue) => unknown | |||
export const setup = (template: string) => { | |||
if (typeof cy !== 'undefined') { | |||
return () => { | |||
cy.intercept({ url: '/' }, { body: template }); | |||
cy.intercept({ url: '/?*' }, { body: template }).as('submitted'); | |||
} | |||
} | |||
return () => { | |||
window.document.open(undefined, undefined, undefined, true) | |||
window.document.write(template) | |||
window.document.close() | |||
} | |||
} | |||
export const test = (retrieveSubmitterFn: RetrieveSubmitterFn, testFn: TestFn, expectedValue?: ExpectedSearchValue) => { | |||
let form: HTMLFormElement | |||
let submitter: HTMLButtonElement | HTMLInputElement | |||
let r: any | |||
if (typeof cy !== 'undefined') { | |||
cy | |||
.visit('/') | |||
.get('form') | |||
.then((formResult: any) => { | |||
[form] = Array.from(formResult); | |||
}) | |||
r = retrieveSubmitterFn(cy) | |||
.then((submitterQueryEl: any) => { | |||
[submitter] = Array.from(submitterQueryEl as any[]) | |||
}) | |||
if (typeof expectedValue !== 'undefined') { | |||
r.click() | |||
cy | |||
.wait('@submitted') | |||
.location('search') | |||
.then((search: any) => { | |||
testFn(form, submitter, search) | |||
}) | |||
} else { | |||
cy | |||
.location('search') | |||
.then((search: any) => { | |||
testFn(form, submitter, search) | |||
}) | |||
} | |||
} else { | |||
r = retrieveSubmitterFn(new JSDOMDummyCypress()) | |||
.then((submitterQueryEl: any) => { | |||
[submitter] = Array.from(submitterQueryEl as any[]); | |||
[form] = Array.from(window.document.getElementsByTagName('form')) | |||
testFn(form, submitter, expectedValue) | |||
}) | |||
if (typeof expectedValue !== 'undefined') { | |||
r.click() | |||
} | |||
} | |||
} | |||
export const makeSearchParams = (beforeValues: Record<string, unknown> | string) => { | |||
switch (typeof (beforeValues as unknown)) { | |||
case 'string': | |||
return new URLSearchParams(beforeValues as string) | |||
case 'object': | |||
return Object | |||
.entries(beforeValues) | |||
.filter(([k]) => k.trim().length > 0) | |||
.reduce( | |||
(beforeSearchParams, [key, value]) => { | |||
const theValue = !Array.isArray(value) ? [value] : value | |||
theValue.forEach(v => { | |||
beforeSearchParams.append(key, v) | |||
}) | |||
return beforeSearchParams | |||
}, | |||
new URLSearchParams() | |||
) | |||
default: | |||
break | |||
} | |||
throw new TypeError('Invalid parameter.') | |||
} |
@@ -0,0 +1,74 @@ | |||
/// <reference types="node" /> | |||
import { readFileSync } from 'fs' | |||
import { join } from 'path' | |||
class JSDOMJQuery { | |||
private selectedElements: Node[] | |||
constructor(elements: NodeList) { | |||
this.selectedElements = Array.from(elements) | |||
} | |||
type(s: string) { | |||
this.selectedElements.forEach((el: any) => { | |||
if (el.tagName === 'TEXTAREA') { | |||
el.innerText = s | |||
el.value = s | |||
return | |||
} | |||
el.setAttribute('value', s) | |||
el.value = s | |||
}) | |||
return this | |||
} | |||
check() { | |||
this.selectedElements.forEach((el: any) => { | |||
el.setAttribute('checked', '') | |||
el.checked = true | |||
}) | |||
return this | |||
} | |||
select(v: string) { | |||
this.selectedElements.forEach((el: any) => { | |||
const option: any = Array.from(el.querySelectorAll('option')).find((o: any) => o.textContent === v) | |||
option.setAttribute('selected', '') | |||
el.value = option.value | |||
}) | |||
return this | |||
} | |||
last() { | |||
this.selectedElements = this.selectedElements.slice(-1) | |||
return this | |||
} | |||
then(fn: (...args: unknown[]) => unknown) { | |||
fn(this.selectedElements) | |||
return this | |||
} | |||
click() { | |||
return this | |||
} | |||
submit() { | |||
return this | |||
} | |||
attachFile(filename: string) { | |||
const contents = readFileSync(join('cypress', 'fixtures', filename)) | |||
// TODO | |||
contents.toString('binary') | |||
return this | |||
} | |||
} | |||
export default class JSDOMDummyCypress { | |||
private currentElement = window.document; | |||
get(q: string) { | |||
return new JSDOMJQuery(this.currentElement.querySelectorAll(q)); | |||
} | |||
} |
@@ -9,13 +9,13 @@ | |||
], | |||
"publishing": { | |||
"github": { | |||
"repository": "https://github.com/TheoryOfNekomata/formxtr.git", | |||
"repository": "https://github.com/TheoryOfNekomata/formxtra.git", | |||
"publishConfig": { | |||
"registry": "https://npm.pkg.github.com" | |||
} | |||
}, | |||
"master": { | |||
"repository": "https://code.modal.sh/TheoryOfNekomata/formxtr.git", | |||
"repository": "https://code.modal.sh/TheoryOfNekomata/formxtra.git", | |||
"publishConfig": { | |||
"registry": "https://js.pack.modal.sh" | |||
} | |||
@@ -51,7 +51,7 @@ | |||
"singleQuote": true, | |||
"trailingComma": "es5" | |||
}, | |||
"name": "@theoryofnekomata/formxtr", | |||
"name": "@theoryofnekomata/formxtra", | |||
"author": "TheoryOfNekomata", | |||
"module": "dist/get-form-values.esm.js", | |||
"size-limit": [ | |||
@@ -1,137 +1,285 @@ | |||
/** | |||
* Type for valid field elements. | |||
* | |||
* | |||
*/ | |||
type HTMLFieldElement | |||
export type HTMLFieldElement | |||
= HTMLInputElement | |||
| HTMLButtonElement | |||
| HTMLSelectElement | |||
| HTMLTextAreaElement | |||
/** | |||
* Line ending. | |||
*/ | |||
export enum LineEnding { | |||
/** | |||
* Carriage return. | |||
*/ | |||
CR = '\r', | |||
/** | |||
* Line feed. | |||
*/ | |||
LF = '\n', | |||
/** | |||
* Carriage return/line feed combination. | |||
*/ | |||
CRLF = '\r\n', | |||
} | |||
/** | |||
* Type for valid submitter elements. | |||
* | |||
* Only the <button> and <input> elements can be submitter elements. | |||
* Only the `<button>` and `<input>` elements can be submitter elements. | |||
*/ | |||
type HTMLSubmitterElement | |||
export type HTMLSubmitterElement | |||
= HTMLButtonElement | |||
| HTMLInputElement | |||
const isFormFieldElement = (el: HTMLFieldElement) => { | |||
const htmlEl = el as HTMLElement | |||
const tagName = htmlEl.tagName | |||
/** | |||
* Options for getting a `<textarea>` element field value. | |||
*/ | |||
type GetTextAreaValueOptions = { | |||
/** | |||
* Line ending used for the element's value. | |||
*/ | |||
lineEndings?: LineEnding, | |||
} | |||
/** | |||
* Options for getting a `<select>` element field value. | |||
*/ | |||
type GetSelectValueOptions = {} | |||
/** | |||
* Options for getting an `<input type="checkbox">` element field value. | |||
*/ | |||
type GetInputCheckboxFieldValueOptions = { | |||
/** | |||
* Should we consider the `checked` attribute of checkboxes with no `value` attributes instead of the default value | |||
* "on" when checked? | |||
* | |||
* This forces the field to get the `false` value when unchecked. | |||
*/ | |||
booleanValuelessCheckbox?: true, | |||
} | |||
/** | |||
* Options for getting an `<input type="radio">` element field value. | |||
*/ | |||
type GetInputRadioFieldValueOptions = {} | |||
/** | |||
* Options for getting an `<input type="file">` element field value. | |||
*/ | |||
type GetInputFileFieldValueOptions = { | |||
/** | |||
* Should we retrieve the `files` attribute of file inputs instead of the currently selected file names? | |||
*/ | |||
getFileObjects?: true, | |||
} | |||
/** | |||
* Options for getting an `<input>` element field value. | |||
*/ | |||
type GetInputFieldValueOptions | |||
= GetInputCheckboxFieldValueOptions | |||
& GetInputFileFieldValueOptions | |||
& GetInputRadioFieldValueOptions | |||
/** | |||
* Options for getting a field value. | |||
*/ | |||
type GetFieldValueOptions | |||
= GetTextAreaValueOptions | |||
& GetSelectValueOptions | |||
& GetInputFieldValueOptions | |||
/** | |||
* Options for getting form values. | |||
*/ | |||
type GetFormValuesOptions = GetFieldValueOptions & { | |||
/** | |||
* The element that triggered the submission of the form. | |||
*/ | |||
submitter?: HTMLSubmitterElement, | |||
} | |||
/** | |||
* Checks if an element can hold a field value. | |||
* @param el - The element. | |||
*/ | |||
export const isFormFieldElement = (el: HTMLElement) => { | |||
const { tagName } = el | |||
if (['SELECT', 'TEXTAREA'].includes(tagName)) { | |||
return true | |||
} | |||
if (tagName !== 'INPUT') { | |||
return false | |||
} | |||
const inputEl = htmlEl as HTMLInputElement | |||
const type = inputEl.type | |||
const checkedValue = inputEl.getAttribute('value') | |||
if (type === 'checkbox' && checkedValue !== null) { | |||
return inputEl.checked | |||
} | |||
const inputEl = el as HTMLInputElement | |||
const { type } = inputEl | |||
if (type === 'submit' || type === 'reset') { | |||
return false | |||
} | |||
return Boolean(inputEl.name) | |||
} | |||
const getTextAreaFieldValue = (textareaEl: HTMLTextAreaElement, options = {} as GetTextAreaValueOptions) => { | |||
const { lineEndings = LineEnding.CRLF, } = options | |||
return textareaEl.value.replace(/\n/g, lineEndings) | |||
} | |||
/** | |||
* Gets the value of a field element. | |||
* @param el - The field element node. | |||
* Gets the value of a `<select>` element. | |||
* @param selectEl - The element. | |||
* @param options - The options. | |||
* @returns Value of the select element. | |||
*/ | |||
const getFieldValue = (el: HTMLFieldElement) => { | |||
const fieldEl = el as HTMLFieldElement | |||
const tagName = fieldEl.tagName | |||
const type = fieldEl.type | |||
if (tagName === 'TEXTAREA') { | |||
return fieldEl.value.replace(/\n/g, '\r\n') | |||
const getSelectFieldValue = (selectEl: HTMLSelectElement, options = {} as GetSelectValueOptions) => { | |||
if (selectEl.multiple) { | |||
return Array.from(selectEl.options).filter(o => o.selected).map(o => o.value) | |||
} | |||
if (typeof options !== 'object' || options === null) { | |||
throw new Error('Invalid options.') | |||
} | |||
return selectEl.value | |||
} | |||
if (tagName === 'SELECT') { | |||
if (fieldEl.value === '') { | |||
return null | |||
} | |||
const selectEl = fieldEl as HTMLSelectElement | |||
if (selectEl.multiple) { | |||
return Array.from(selectEl.options).filter(o => o.selected).map(o => o.value) | |||
/** | |||
* Type for an `<input type="checkbox">` element. | |||
*/ | |||
export type HTMLInputCheckboxElement = HTMLInputElement & { type: 'checkbox' } | |||
/** | |||
* Type for an `<input type="radio">` element. | |||
*/ | |||
export type HTMLInputRadioElement = HTMLInputElement & { type: 'radio' } | |||
/** | |||
* Type for an `<input type="file">` element. | |||
*/ | |||
export type HTMLInputFileElement = HTMLInputElement & { type: 'file' } | |||
/** | |||
* Gets the value of an `<input type="radio">` element. | |||
* @param inputEl - The element. | |||
* @param options - The options. | |||
* @returns Value of the input element. | |||
*/ | |||
const getInputRadioFieldValue = (inputEl: HTMLInputRadioElement, options = {} as GetInputRadioFieldValueOptions) => { | |||
if (inputEl.checked) { | |||
return inputEl.value | |||
} | |||
if (typeof options !== 'object' || options === null) { | |||
throw new Error('Invalid options.') | |||
} | |||
return null | |||
} | |||
/** | |||
* Gets the value of an `<input type="checkbox">` element. | |||
* @param inputEl - The element. | |||
* @param options - The options. | |||
* @returns Value of the input element. | |||
*/ | |||
const getInputCheckboxFieldValue = (inputEl: HTMLInputCheckboxElement, options = {} as GetInputCheckboxFieldValueOptions) => { | |||
const checkedValue = inputEl.getAttribute('value') | |||
if (checkedValue !== null) { | |||
if (inputEl.checked) { | |||
return inputEl.value | |||
} | |||
return selectEl.value | |||
return null | |||
} | |||
if (options.booleanValuelessCheckbox) { | |||
return inputEl.checked | |||
} | |||
if (inputEl.checked) { | |||
return 'on' | |||
} | |||
return null | |||
} | |||
if (tagName === 'INPUT') { | |||
switch (type) { | |||
case 'checkbox': | |||
const checkboxEl = fieldEl as HTMLInputElement | |||
const checkedValue = checkboxEl.getAttribute('value') | |||
if (checkedValue !== null) { | |||
if (checkboxEl.checked) { | |||
return checkboxEl.value | |||
} | |||
return null | |||
} | |||
return 'on' // default value | |||
case 'radio': | |||
const radioEl = fieldEl as HTMLInputElement | |||
if (radioEl.checked) { | |||
return radioEl.value | |||
} | |||
return null | |||
case 'file': | |||
const fileUploadEl = fieldEl as HTMLInputElement | |||
const { files } = fileUploadEl | |||
if ((files as unknown) !== null) { | |||
const [file = null] = Array.from(files as FileList) | |||
if (file !== null) { | |||
return file.name | |||
} | |||
return '' | |||
} | |||
return null | |||
default: | |||
break | |||
} | |||
/** | |||
* Gets the value of an `<input type="file">` element. | |||
* @param inputEl - The element. | |||
* @param options - The options. | |||
* @returns Value of the input element. | |||
*/ | |||
const getInputFileFieldValue = (inputEl: HTMLInputFileElement, options = {} as GetInputFileFieldValueOptions) => { | |||
const { files } = inputEl | |||
if ((files as unknown) === null) { | |||
return null | |||
} | |||
if (options.getFileObjects) { | |||
return files | |||
} | |||
const filesArray = Array.from(files as FileList) | |||
if (filesArray.length > 1) { | |||
return filesArray.map(f => f.name) | |||
} | |||
if (filesArray.length === 1) { | |||
return filesArray[0].name | |||
} | |||
return '' | |||
} | |||
/** | |||
* Gets the value of an `<input>` element. | |||
* @param inputEl - The element. | |||
* @param options - The options. | |||
* @returns Value of the input element. | |||
*/ | |||
const getInputFieldValue = (inputEl: HTMLInputElement, options = {} as GetInputFieldValueOptions) => { | |||
switch (inputEl.type) { | |||
case 'checkbox': | |||
return getInputCheckboxFieldValue(inputEl as HTMLInputCheckboxElement, options) | |||
case 'radio': | |||
return getInputRadioFieldValue(inputEl as HTMLInputRadioElement, options) | |||
case 'file': | |||
return getInputFileFieldValue(inputEl as HTMLInputFileElement, options) | |||
default: | |||
break | |||
} | |||
return inputEl.value | |||
} | |||
return fieldEl.value | |||
/** | |||
* Gets the value of a field element. | |||
* @param el - The field element. | |||
* @param options - The options. | |||
* @returns Value of the field element. | |||
*/ | |||
export const getFieldValue = (el: HTMLElement, options = {} as GetFieldValueOptions) => { | |||
switch (el.tagName) { | |||
case 'TEXTAREA': | |||
return getTextAreaFieldValue(el as HTMLTextAreaElement, options) | |||
case 'SELECT': | |||
return getSelectFieldValue(el as HTMLSelectElement, options) | |||
case 'INPUT': | |||
return getInputFieldValue(el as HTMLInputElement, options) | |||
default: | |||
break | |||
} | |||
const fieldEl = el as HTMLFieldElement | |||
return fieldEl.value || null | |||
} | |||
/** | |||
* Returns only named form field elements. | |||
* Determines if an element is a named and enabled form field. | |||
* @param el - The element. | |||
* @returns Value determining if the element is a named and enabled form field. | |||
*/ | |||
const isValidFormField = (el: HTMLFieldElement) => { | |||
export const isNamedEnabledFormFieldElement = (el: HTMLElement) => { | |||
if (typeof el['name'] !== 'string') { | |||
return false | |||
} | |||
const namedEl = el as HTMLElement & { name: string, disabled: unknown } | |||
return ( | |||
'name' in el | |||
&& typeof el['name'] === 'string' | |||
&& el['name'].length > 0 | |||
&& !('disabled' in el && Boolean(el['disabled'])) | |||
&& isFormFieldElement(el) | |||
namedEl.name.length > 0 | |||
&& !('disabled' in namedEl && Boolean(namedEl.disabled)) | |||
&& isFormFieldElement(namedEl) | |||
) | |||
} | |||
type GetFormValuesOptions = { | |||
/** | |||
* The element that triggered the submission of the form. | |||
*/ | |||
submitter?: HTMLSubmitterElement, | |||
/** | |||
* Should we consider the `checked` attribute of checkboxes with no `value` attributes instead of the default value | |||
* "on" when checked? | |||
*/ | |||
booleanValuelessCheckbox?: true, | |||
/** | |||
* Should we retrieve the `files` attribute of file inputs instead of the currently selected file names? | |||
*/ | |||
hasFiles?: true, | |||
} | |||
/** | |||
* Gets the values of all the fields within the form through accessing the DOM nodes. | |||
* @param form - The form. | |||
@@ -144,16 +292,13 @@ const getFormValues = (form: HTMLFormElement, options = {} as GetFormValuesOptio | |||
} | |||
const formElements = form.elements as unknown as Record<string | number, HTMLFieldElement> | |||
const allFormFieldElements = Object.entries<HTMLFieldElement>(formElements) | |||
const formFieldElements = allFormFieldElements.filter(([k, el]) => { | |||
return ( | |||
// get only indexed forms | |||
!isNaN(Number(k)) | |||
&& isValidFormField(el) | |||
) | |||
}) | |||
const fieldValues = formFieldElements.reduce( | |||
const indexedNamedEnabledFormFieldElements = allFormFieldElements.filter(([k, el]) => ( | |||
!isNaN(Number(k)) | |||
&& isNamedEnabledFormFieldElement(el) | |||
)) | |||
const fieldValues = indexedNamedEnabledFormFieldElements.reduce( | |||
(theFormValues, [,el]) => { | |||
const fieldValue = getFieldValue(el) | |||
const fieldValue = getFieldValue(el, options) | |||
if (fieldValue === null) { | |||
return theFormValues | |||
} | |||
@@ -183,9 +328,12 @@ const getFormValues = (form: HTMLFormElement, options = {} as GetFormValuesOptio | |||
{} as any | |||
) | |||
if (Boolean(options.submitter as unknown)) { | |||
return { | |||
...fieldValues, | |||
[(options.submitter as HTMLSubmitterElement).name]: (options.submitter as HTMLSubmitterElement).value, | |||
const submitter = options.submitter as HTMLSubmitterElement | |||
if (submitter.name.length > 0) { | |||
return { | |||
...fieldValues, | |||
[submitter.name]: submitter.value, | |||
} | |||
} | |||
} | |||
return fieldValues | |||
@@ -1,145 +0,0 @@ | |||
/// <reference types="cypress" /> | |||
/// <reference types="cypress-jest-adapter" /> | |||
/// <reference types="node" /> | |||
import * as fs from 'fs' | |||
import * as path from 'path' | |||
type TestFn = (form: HTMLFormElement, submitter: HTMLButtonElement | HTMLInputElement, after: Record<string, string> | string) => unknown | |||
class JSDOMJQuery { | |||
private selectedElements: Node[] | |||
constructor(elements: NodeList) { | |||
this.selectedElements = Array.from(elements) | |||
} | |||
type(s: string) { | |||
this.selectedElements.forEach((el: any) => { | |||
if (el.tagName === 'TEXTAREA') { | |||
el.innerText = s | |||
el.value = s | |||
return | |||
} | |||
el.setAttribute('value', s) | |||
el.value = s | |||
}) | |||
return this | |||
} | |||
check() { | |||
this.selectedElements.forEach((el: any) => { | |||
el.setAttribute('checked', '') | |||
el.checked = true | |||
}) | |||
return this | |||
} | |||
select(v: string) { | |||
this.selectedElements.forEach((el: any) => { | |||
const option: any = Array.from(el.querySelectorAll('option')).find((o: any) => o.textContent === v) | |||
option.setAttribute('selected', '') | |||
el.value = option.value | |||
}) | |||
return this | |||
} | |||
last() { | |||
this.selectedElements = this.selectedElements.slice(-1) | |||
return this | |||
} | |||
then(fn: (...args: unknown[]) => unknown) { | |||
fn(this.selectedElements) | |||
return this | |||
} | |||
click() { | |||
return this | |||
} | |||
submit() { | |||
return this | |||
} | |||
} | |||
class JSDOMDummyCypress { | |||
private currentElement = window.document; | |||
get(q: string) { | |||
return new JSDOMJQuery(this.currentElement.querySelectorAll(q)); | |||
} | |||
} | |||
export const setup = (template: string) => { | |||
if (typeof cy !== 'undefined') { | |||
return () => { | |||
cy.intercept({ url: '/' }, { fixture: `templates/${template}.html` }); | |||
cy.intercept({ url: '/?*' }, { fixture: `templates/${template}.html` }).as('submitted'); | |||
} | |||
} | |||
return async () => { | |||
const templatePath = path.join('test', 'fixtures', 'templates', `${template}.html`) | |||
const templateRaw = await fs.promises.readFile(templatePath) | |||
window.document.open(undefined, undefined, undefined, true) | |||
window.document.write(templateRaw.toString('utf-8')) | |||
window.document.close() | |||
} | |||
} | |||
export const test = (retrieveSubmitterFn: (wrapper: any) => any, testFn: TestFn, expectedValue: Record<string, string> | string) => { | |||
let form: HTMLFormElement | |||
let submitter: HTMLButtonElement | HTMLInputElement | |||
if (typeof cy !== 'undefined') { | |||
cy | |||
.visit('/') | |||
.get('form') | |||
.then((formResult: any) => { | |||
[form] = Array.from(formResult); | |||
}) | |||
retrieveSubmitterFn(cy) | |||
.then((submitterQueryEl: any) => { | |||
[submitter] = Array.from(submitterQueryEl as any[]) | |||
}) | |||
.click() | |||
cy | |||
.wait('@submitted') | |||
.location('search') | |||
.then(search => { | |||
testFn(form, submitter, search) | |||
}) | |||
} else { | |||
retrieveSubmitterFn(new JSDOMDummyCypress()) | |||
.then((submitterQueryEl: any) => { | |||
[submitter] = Array.from(submitterQueryEl as any[]); | |||
[form] = Array.from(window.document.getElementsByTagName('form')) | |||
testFn(form, submitter, expectedValue) | |||
}) | |||
.click(); | |||
} | |||
} | |||
export const makeSearchParams = (beforeValues: Record<string, unknown> | string) => { | |||
switch (typeof (beforeValues as unknown)) { | |||
case 'string': | |||
return new URLSearchParams(beforeValues as string) | |||
case 'object': | |||
return Object | |||
.entries(beforeValues) | |||
.filter(([k]) => k.trim().length > 0) | |||
.reduce( | |||
(beforeSearchParams, [key, value]) => { | |||
const theValue = !Array.isArray(value) ? [value] : value | |||
theValue.forEach(v => { | |||
beforeSearchParams.append(key, v) | |||
}) | |||
return beforeSearchParams | |||
}, | |||
new URLSearchParams() | |||
) | |||
default: | |||
break | |||
} | |||
throw new TypeError('Invalid parameter.') | |||
} |
@@ -6,7 +6,7 @@ | |||
"importHelpers": true, | |||
"declaration": true, | |||
"sourceMap": true, | |||
"strict": true, | |||
"strict": false, | |||
"noImplicitReturns": true, | |||
"noFallthroughCasesInSwitch": true, | |||
"noUnusedLocals": true, | |||
@@ -9,25 +9,25 @@ | |||
dependencies: | |||
"@babel/highlight" "^7.12.13" | |||
"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.14.0": | |||
"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.15", "@babel/compat-data@^7.14.0": | |||
version "7.14.0" | |||
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.0.tgz#a901128bce2ad02565df95e6ecbf195cf9465919" | |||
integrity sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q== | |||
"@babel/core@^7.1.0", "@babel/core@^7.4.4", "@babel/core@^7.7.5": | |||
version "7.14.0" | |||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.0.tgz#47299ff3ec8d111b493f1a9d04bf88c04e728d88" | |||
integrity sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw== | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.2.tgz#54e45334ffc0172048e5c93ded36461d3ad4c417" | |||
integrity sha512-OgC1mON+l4U4B4wiohJlQNUU3H73mpTyYY3j/c8U9dr9UagGGSm+WFpzjy/YLdoyjiG++c1kIDgxCo/mLwQJeQ== | |||
dependencies: | |||
"@babel/code-frame" "^7.12.13" | |||
"@babel/generator" "^7.14.0" | |||
"@babel/generator" "^7.14.2" | |||
"@babel/helper-compilation-targets" "^7.13.16" | |||
"@babel/helper-module-transforms" "^7.14.0" | |||
"@babel/helper-module-transforms" "^7.14.2" | |||
"@babel/helpers" "^7.14.0" | |||
"@babel/parser" "^7.14.0" | |||
"@babel/parser" "^7.14.2" | |||
"@babel/template" "^7.12.13" | |||
"@babel/traverse" "^7.14.0" | |||
"@babel/types" "^7.14.0" | |||
"@babel/traverse" "^7.14.2" | |||
"@babel/types" "^7.14.2" | |||
convert-source-map "^1.7.0" | |||
debug "^4.1.0" | |||
gensync "^1.0.0-beta.2" | |||
@@ -35,12 +35,12 @@ | |||
semver "^6.3.0" | |||
source-map "^0.5.0" | |||
"@babel/generator@^7.14.0": | |||
version "7.14.1" | |||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" | |||
integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== | |||
"@babel/generator@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.2.tgz#d5773e8b557d421fd6ce0d5efa5fd7fc22567c30" | |||
integrity sha512-OnADYbKrffDVai5qcpkMxQ7caomHOoEwjkouqnN2QhydAjowFAZcsdecFIRUBdb+ZcruwYE4ythYmF1UBZU5xQ== | |||
dependencies: | |||
"@babel/types" "^7.14.1" | |||
"@babel/types" "^7.14.2" | |||
jsesc "^2.5.1" | |||
source-map "^0.5.0" | |||
@@ -59,7 +59,7 @@ | |||
"@babel/helper-explode-assignable-expression" "^7.12.13" | |||
"@babel/types" "^7.12.13" | |||
"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.13.8": | |||
"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16": | |||
version "7.13.16" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz#6e91dccf15e3f43e5556dffe32d860109887563c" | |||
integrity sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA== | |||
@@ -70,12 +70,12 @@ | |||
semver "^6.3.0" | |||
"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0": | |||
version "7.14.1" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz#1fe11b376f3c41650ad9fedc665b0068722ea76c" | |||
integrity sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg== | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.2.tgz#4e455b0329af29c2d3ad254b5dd5aed34595385d" | |||
integrity sha512-6YctwVsmlkchxfGUogvVrrhzyD3grFJyluj5JgDlQrwfMLJSt5tdAzFZfPf4H2Xoi5YLcQ6BxfJlaOBHuctyIw== | |||
dependencies: | |||
"@babel/helper-annotate-as-pure" "^7.12.13" | |||
"@babel/helper-function-name" "^7.12.13" | |||
"@babel/helper-function-name" "^7.14.2" | |||
"@babel/helper-member-expression-to-functions" "^7.13.12" | |||
"@babel/helper-optimise-call-expression" "^7.12.13" | |||
"@babel/helper-replace-supers" "^7.13.12" | |||
@@ -124,14 +124,14 @@ | |||
dependencies: | |||
"@babel/types" "^7.13.0" | |||
"@babel/helper-function-name@^7.12.13": | |||
version "7.12.13" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a" | |||
integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA== | |||
"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2" | |||
integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ== | |||
dependencies: | |||
"@babel/helper-get-function-arity" "^7.12.13" | |||
"@babel/template" "^7.12.13" | |||
"@babel/types" "^7.12.13" | |||
"@babel/types" "^7.14.2" | |||
"@babel/helper-get-function-arity@^7.12.13": | |||
version "7.12.13" | |||
@@ -162,10 +162,10 @@ | |||
dependencies: | |||
"@babel/types" "^7.13.12" | |||
"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0": | |||
version "7.14.0" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz#8fcf78be220156f22633ee204ea81f73f826a8ad" | |||
integrity sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw== | |||
"@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0", "@babel/helper-module-transforms@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5" | |||
integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA== | |||
dependencies: | |||
"@babel/helper-module-imports" "^7.13.12" | |||
"@babel/helper-replace-supers" "^7.13.12" | |||
@@ -173,8 +173,8 @@ | |||
"@babel/helper-split-export-declaration" "^7.12.13" | |||
"@babel/helper-validator-identifier" "^7.14.0" | |||
"@babel/template" "^7.12.13" | |||
"@babel/traverse" "^7.14.0" | |||
"@babel/types" "^7.14.0" | |||
"@babel/traverse" "^7.14.2" | |||
"@babel/types" "^7.14.2" | |||
"@babel/helper-optimise-call-expression@^7.12.13": | |||
version "7.12.13" | |||
@@ -197,7 +197,7 @@ | |||
"@babel/helper-wrap-function" "^7.13.0" | |||
"@babel/types" "^7.13.0" | |||
"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.13.12": | |||
"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.12": | |||
version "7.13.12" | |||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz#6442f4c1ad912502481a564a7386de0c77ff3804" | |||
integrity sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw== | |||
@@ -266,10 +266,10 @@ | |||
chalk "^2.0.0" | |||
js-tokens "^4.0.0" | |||
"@babel/parser@^7.1.0", "@babel/parser@^7.11.5", "@babel/parser@^7.12.13", "@babel/parser@^7.14.0", "@babel/parser@^7.7.0": | |||
version "7.14.1" | |||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" | |||
integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== | |||
"@babel/parser@^7.1.0", "@babel/parser@^7.11.5", "@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.7.0": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.2.tgz#0c1680aa44ad4605b16cbdcc5c341a61bde9c746" | |||
integrity sha512-IoVDIHpsgE/fu7eXBeRWt8zLbDrSvD7H1gpomOkPpBoEN8KCruCqSDdqo8dddwQQrui30KSvQBaMUOJiuFu6QQ== | |||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": | |||
version "7.13.12" | |||
@@ -280,10 +280,10 @@ | |||
"@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" | |||
"@babel/plugin-proposal-optional-chaining" "^7.13.12" | |||
"@babel/plugin-proposal-async-generator-functions@^7.13.15": | |||
version "7.13.15" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.15.tgz#80e549df273a3b3050431b148c892491df1bcc5b" | |||
integrity sha512-VapibkWzFeoa6ubXy/NgV5U2U4MVnUlvnx6wo1XhlsaTrLYWE0UFpDQsVrmn22q5CzeloqJ8gEMHSKxuee6ZdA== | |||
"@babel/plugin-proposal-async-generator-functions@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz#3a2085abbf5d5f962d480dbc81347385ed62eb1e" | |||
integrity sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/helper-remap-async-to-generator" "^7.13.0" | |||
@@ -305,77 +305,77 @@ | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-class-static-block" "^7.12.13" | |||
"@babel/plugin-proposal-dynamic-import@^7.13.8": | |||
version "7.13.8" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d" | |||
integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ== | |||
"@babel/plugin-proposal-dynamic-import@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz#01ebabd7c381cff231fa43e302939a9de5be9d9f" | |||
integrity sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-dynamic-import" "^7.8.3" | |||
"@babel/plugin-proposal-export-namespace-from@^7.12.13": | |||
version "7.12.13" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz#393be47a4acd03fa2af6e3cde9b06e33de1b446d" | |||
integrity sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw== | |||
"@babel/plugin-proposal-export-namespace-from@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz#62542f94aa9ce8f6dba79eec698af22112253791" | |||
integrity sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.12.13" | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-export-namespace-from" "^7.8.3" | |||
"@babel/plugin-proposal-json-strings@^7.13.8": | |||
version "7.13.8" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b" | |||
integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q== | |||
"@babel/plugin-proposal-json-strings@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz#830b4e2426a782e8b2878fbfe2cba85b70cbf98c" | |||
integrity sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-json-strings" "^7.8.3" | |||
"@babel/plugin-proposal-logical-assignment-operators@^7.13.8": | |||
version "7.13.8" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a" | |||
integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A== | |||
"@babel/plugin-proposal-logical-assignment-operators@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz#222348c080a1678e0e74ea63fe76f275882d1fd7" | |||
integrity sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" | |||
"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": | |||
version "7.13.8" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3" | |||
integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A== | |||
"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz#425b11dc62fc26939a2ab42cbba680bdf5734546" | |||
integrity sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" | |||
"@babel/plugin-proposal-numeric-separator@^7.12.13": | |||
version "7.12.13" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz#bd9da3188e787b5120b4f9d465a8261ce67ed1db" | |||
integrity sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w== | |||
"@babel/plugin-proposal-numeric-separator@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz#82b4cc06571143faf50626104b335dd71baa4f9e" | |||
integrity sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.12.13" | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-numeric-separator" "^7.10.4" | |||
"@babel/plugin-proposal-object-rest-spread@^7.13.8": | |||
version "7.13.8" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" | |||
integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== | |||
"@babel/plugin-proposal-object-rest-spread@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.2.tgz#e17d418f81cc103fedd4ce037e181c8056225abc" | |||
integrity sha512-hBIQFxwZi8GIp934+nj5uV31mqclC1aYDhctDu5khTi9PCCUOczyy0b34W0oE9U/eJXiqQaKyVsmjeagOaSlbw== | |||
dependencies: | |||
"@babel/compat-data" "^7.13.8" | |||
"@babel/helper-compilation-targets" "^7.13.8" | |||
"@babel/compat-data" "^7.14.0" | |||
"@babel/helper-compilation-targets" "^7.13.16" | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-object-rest-spread" "^7.8.3" | |||
"@babel/plugin-transform-parameters" "^7.13.0" | |||
"@babel/plugin-transform-parameters" "^7.14.2" | |||
"@babel/plugin-proposal-optional-catch-binding@^7.13.8": | |||
version "7.13.8" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107" | |||
integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA== | |||
"@babel/plugin-proposal-optional-catch-binding@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz#150d4e58e525b16a9a1431bd5326c4eed870d717" | |||
integrity sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3" | |||
"@babel/plugin-proposal-optional-chaining@^7.13.12": | |||
version "7.13.12" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz#ba9feb601d422e0adea6760c2bd6bbb7bfec4866" | |||
integrity sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ== | |||
"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz#df8171a8b9c43ebf4c1dabe6311b432d83e1b34e" | |||
integrity sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" | |||
@@ -542,23 +542,23 @@ | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.12.13" | |||
"@babel/plugin-transform-block-scoping@^7.14.1": | |||
version "7.14.1" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.1.tgz#ac1b3a8e3d8cbb31efc6b9be2f74eb9823b74ab2" | |||
integrity sha512-2mQXd0zBrwfp0O1moWIhPpEeTKDvxyHcnma3JATVP1l+CctWBuot6OJG8LQ4DnBj4ZZPSmlb/fm4mu47EOAnVA== | |||
"@babel/plugin-transform-block-scoping@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.2.tgz#761cb12ab5a88d640ad4af4aa81f820e6b5fdf5c" | |||
integrity sha512-neZZcP19NugZZqNwMTH+KoBjx5WyvESPSIOQb4JHpfd+zPfqcH65RMu5xJju5+6q/Y2VzYrleQTr+b6METyyxg== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/plugin-transform-classes@^7.13.0": | |||
version "7.13.0" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b" | |||
integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g== | |||
"@babel/plugin-transform-classes@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.2.tgz#3f1196c5709f064c252ad056207d87b7aeb2d03d" | |||
integrity sha512-7oafAVcucHquA/VZCsXv/gmuiHeYd64UJyyTYU+MPfNu0KeNlxw06IeENBO8bJjXVbolu+j1MM5aKQtH1OMCNg== | |||
dependencies: | |||
"@babel/helper-annotate-as-pure" "^7.12.13" | |||
"@babel/helper-function-name" "^7.12.13" | |||
"@babel/helper-function-name" "^7.14.2" | |||
"@babel/helper-optimise-call-expression" "^7.12.13" | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/helper-replace-supers" "^7.13.0" | |||
"@babel/helper-replace-supers" "^7.13.12" | |||
"@babel/helper-split-export-declaration" "^7.12.13" | |||
globals "^11.1.0" | |||
@@ -628,12 +628,12 @@ | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.12.13" | |||
"@babel/plugin-transform-modules-amd@^7.14.0": | |||
version "7.14.0" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.0.tgz#589494b5b290ff76cf7f59c798011f6d77026553" | |||
integrity sha512-CF4c5LX4LQ03LebQxJ5JZes2OYjzBuk1TdiF7cG7d5dK4lAdw9NZmaxq5K/mouUdNeqwz3TNjnW6v01UqUNgpQ== | |||
"@babel/plugin-transform-modules-amd@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz#6622806fe1a7c07a1388444222ef9535f2ca17b0" | |||
integrity sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw== | |||
dependencies: | |||
"@babel/helper-module-transforms" "^7.14.0" | |||
"@babel/helper-module-transforms" "^7.14.2" | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
babel-plugin-dynamic-import-node "^2.3.3" | |||
@@ -688,10 +688,10 @@ | |||
"@babel/helper-plugin-utils" "^7.12.13" | |||
"@babel/helper-replace-supers" "^7.12.13" | |||
"@babel/plugin-transform-parameters@^7.13.0": | |||
version "7.13.0" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.13.0.tgz#8fa7603e3097f9c0b7ca1a4821bc2fb52e9e5007" | |||
integrity sha512-Jt8k/h/mIwE2JFEOb3lURoY5C85ETcYPnbuAJ96zRBzh1XHtQZfs62ChZ6EP22QlC8c7Xqr9q+e1SU5qttwwjw== | |||
"@babel/plugin-transform-parameters@^7.14.2": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz#e4290f72e0e9e831000d066427c4667098decc31" | |||
integrity sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A== | |||
dependencies: | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
@@ -768,27 +768,27 @@ | |||
"@babel/helper-plugin-utils" "^7.12.13" | |||
"@babel/preset-env@^7.11.0": | |||
version "7.14.1" | |||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.1.tgz#b55914e2e68885ea03f69600b2d3537e54574a93" | |||
integrity sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ== | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.2.tgz#e80612965da73579c84ad2f963c2359c71524ed5" | |||
integrity sha512-7dD7lVT8GMrE73v4lvDEb85cgcQhdES91BSD7jS/xjC6QY8PnRhux35ac+GCpbiRhp8crexBvZZqnaL6VrY8TQ== | |||
dependencies: | |||
"@babel/compat-data" "^7.14.0" | |||
"@babel/helper-compilation-targets" "^7.13.16" | |||
"@babel/helper-plugin-utils" "^7.13.0" | |||
"@babel/helper-validator-option" "^7.12.17" | |||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12" | |||
"@babel/plugin-proposal-async-generator-functions" "^7.13.15" | |||
"@babel/plugin-proposal-async-generator-functions" "^7.14.2" | |||
"@babel/plugin-proposal-class-properties" "^7.13.0" | |||
"@babel/plugin-proposal-class-static-block" "^7.13.11" | |||
"@babel/plugin-proposal-dynamic-import" "^7.13.8" | |||
"@babel/plugin-proposal-export-namespace-from" "^7.12.13" | |||
"@babel/plugin-proposal-json-strings" "^7.13.8" | |||
"@babel/plugin-proposal-logical-assignment-operators" "^7.13.8" | |||
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.13.8" | |||
"@babel/plugin-proposal-numeric-separator" "^7.12.13" | |||
"@babel/plugin-proposal-object-rest-spread" "^7.13.8" | |||
"@babel/plugin-proposal-optional-catch-binding" "^7.13.8" | |||
"@babel/plugin-proposal-optional-chaining" "^7.13.12" | |||
"@babel/plugin-proposal-dynamic-import" "^7.14.2" | |||
"@babel/plugin-proposal-export-namespace-from" "^7.14.2" | |||
"@babel/plugin-proposal-json-strings" "^7.14.2" | |||
"@babel/plugin-proposal-logical-assignment-operators" "^7.14.2" | |||
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.2" | |||
"@babel/plugin-proposal-numeric-separator" "^7.14.2" | |||
"@babel/plugin-proposal-object-rest-spread" "^7.14.2" | |||
"@babel/plugin-proposal-optional-catch-binding" "^7.14.2" | |||
"@babel/plugin-proposal-optional-chaining" "^7.14.2" | |||
"@babel/plugin-proposal-private-methods" "^7.13.0" | |||
"@babel/plugin-proposal-private-property-in-object" "^7.14.0" | |||
"@babel/plugin-proposal-unicode-property-regex" "^7.12.13" | |||
@@ -809,8 +809,8 @@ | |||
"@babel/plugin-transform-arrow-functions" "^7.13.0" | |||
"@babel/plugin-transform-async-to-generator" "^7.13.0" | |||
"@babel/plugin-transform-block-scoped-functions" "^7.12.13" | |||
"@babel/plugin-transform-block-scoping" "^7.14.1" | |||
"@babel/plugin-transform-classes" "^7.13.0" | |||
"@babel/plugin-transform-block-scoping" "^7.14.2" | |||
"@babel/plugin-transform-classes" "^7.14.2" | |||
"@babel/plugin-transform-computed-properties" "^7.13.0" | |||
"@babel/plugin-transform-destructuring" "^7.13.17" | |||
"@babel/plugin-transform-dotall-regex" "^7.12.13" | |||
@@ -820,14 +820,14 @@ | |||
"@babel/plugin-transform-function-name" "^7.12.13" | |||
"@babel/plugin-transform-literals" "^7.12.13" | |||
"@babel/plugin-transform-member-expression-literals" "^7.12.13" | |||
"@babel/plugin-transform-modules-amd" "^7.14.0" | |||
"@babel/plugin-transform-modules-amd" "^7.14.2" | |||
"@babel/plugin-transform-modules-commonjs" "^7.14.0" | |||
"@babel/plugin-transform-modules-systemjs" "^7.13.8" | |||
"@babel/plugin-transform-modules-umd" "^7.14.0" | |||
"@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13" | |||
"@babel/plugin-transform-new-target" "^7.12.13" | |||
"@babel/plugin-transform-object-super" "^7.12.13" | |||
"@babel/plugin-transform-parameters" "^7.13.0" | |||
"@babel/plugin-transform-parameters" "^7.14.2" | |||
"@babel/plugin-transform-property-literals" "^7.12.13" | |||
"@babel/plugin-transform-regenerator" "^7.13.15" | |||
"@babel/plugin-transform-reserved-words" "^7.12.13" | |||
@@ -839,7 +839,7 @@ | |||
"@babel/plugin-transform-unicode-escapes" "^7.12.13" | |||
"@babel/plugin-transform-unicode-regex" "^7.12.13" | |||
"@babel/preset-modules" "^0.1.4" | |||
"@babel/types" "^7.14.1" | |||
"@babel/types" "^7.14.2" | |||
babel-plugin-polyfill-corejs2 "^0.2.0" | |||
babel-plugin-polyfill-corejs3 "^0.2.0" | |||
babel-plugin-polyfill-regenerator "^0.2.0" | |||
@@ -881,24 +881,24 @@ | |||
"@babel/parser" "^7.12.13" | |||
"@babel/types" "^7.12.13" | |||
"@babel/traverse@^7.1.0", "@babel/traverse@^7.11.5", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.7.0": | |||
version "7.14.0" | |||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.0.tgz#cea0dc8ae7e2b1dec65f512f39f3483e8cc95aef" | |||
integrity sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA== | |||
"@babel/traverse@^7.1.0", "@babel/traverse@^7.11.5", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2", "@babel/traverse@^7.7.0": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b" | |||
integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA== | |||
dependencies: | |||
"@babel/code-frame" "^7.12.13" | |||
"@babel/generator" "^7.14.0" | |||
"@babel/helper-function-name" "^7.12.13" | |||
"@babel/generator" "^7.14.2" | |||
"@babel/helper-function-name" "^7.14.2" | |||
"@babel/helper-split-export-declaration" "^7.12.13" | |||
"@babel/parser" "^7.14.0" | |||
"@babel/types" "^7.14.0" | |||
"@babel/parser" "^7.14.2" | |||
"@babel/types" "^7.14.2" | |||
debug "^4.1.0" | |||
globals "^11.1.0" | |||
"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": | |||
version "7.14.1" | |||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" | |||
integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== | |||
"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": | |||
version "7.14.2" | |||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.2.tgz#4208ae003107ef8a057ea8333e56eb64d2f6a2c3" | |||
integrity sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw== | |||
dependencies: | |||
"@babel/helper-validator-identifier" "^7.14.0" | |||
to-fast-properties "^2.0.0" | |||
@@ -1412,14 +1412,14 @@ | |||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= | |||
"@types/node@*": | |||
version "15.0.2" | |||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.0.2.tgz#51e9c0920d1b45936ea04341aa3e2e58d339fb67" | |||
integrity sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA== | |||
version "15.3.0" | |||
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.3.0.tgz#d6fed7d6bc6854306da3dea1af9f874b00783e26" | |||
integrity sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ== | |||
"@types/node@^14.14.31": | |||
version "14.14.44" | |||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.44.tgz#df7503e6002847b834371c004b372529f3f85215" | |||
integrity sha512-+gaugz6Oce6ZInfI/tK4Pq5wIIkJMEJUu92RB3Eu93mtj4wjjjz9EB5mLp5s1pSsLXdC/CPut/xF20ZzAQJbTA== | |||
version "14.14.45" | |||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.45.tgz#ec2dfb5566ff814d061aef7e141575aedba245cf" | |||
integrity sha512-DssMqTV9UnnoxDWu959sDLZzfvqCF0qDNRjaWeYSui9xkFe61kKo4l1TWNTQONpuXEm+gLMRvdlzvNHBamzmEw== | |||
"@types/normalize-package-data@^2.4.0": | |||
version "2.4.0" | |||
@@ -1914,7 +1914,7 @@ array-unique@^0.3.2: | |||
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" | |||
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= | |||
array.prototype.flat@^1.2.3: | |||
array.prototype.flat@^1.2.4: | |||
version "1.2.4" | |||
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" | |||
integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== | |||
@@ -2878,10 +2878,13 @@ constants-browserify@^1.0.0: | |||
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" | |||
integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= | |||
contains-path@^0.1.0: | |||
version "0.1.0" | |||
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" | |||
integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= | |||
contains-path@^1.0.0: | |||
version "1.0.0" | |||
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-1.0.0.tgz#3458b332185603e8eed18f518d4a10888a3abc91" | |||
integrity sha1-NFizMhhWA+ju0Y9RjUoQiIo6vJE= | |||
dependencies: | |||
normalize-path "^2.1.1" | |||
path-starts-with "^1.0.0" | |||
convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: | |||
version "1.7.0" | |||
@@ -3296,7 +3299,7 @@ debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: | |||
dependencies: | |||
ms "2.0.0" | |||
debug@^3.1.0: | |||
debug@^3.1.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== | |||
@@ -3415,14 +3418,6 @@ dir-glob@^3.0.1: | |||
dependencies: | |||
path-type "^4.0.0" | |||
doctrine@1.5.0: | |||
version "1.5.0" | |||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" | |||
integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= | |||
dependencies: | |||
esutils "^2.0.2" | |||
isarray "^1.0.0" | |||
doctrine@^2.1.0: | |||
version "2.1.0" | |||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" | |||
@@ -3513,9 +3508,9 @@ ecc-jsbn@~0.1.1: | |||
safer-buffer "^2.1.0" | |||
electron-to-chromium@^1.3.723: | |||
version "1.3.727" | |||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz#857e310ca00f0b75da4e1db6ff0e073cc4a91ddf" | |||
integrity sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg== | |||
version "1.3.728" | |||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.728.tgz#dbedd6373f595ae10a13d146b66bece4c1afa5bd" | |||
integrity sha512-SHv4ziXruBpb1Nz4aTuqEHBYi/9GNCJMYIJgDEXrp/2V01nFXMNFUTli5Z85f5ivSkioLilQatqBYFB44wNJrA== | |||
elegant-spinner@^1.0.1: | |||
version "1.0.1" | |||
@@ -3590,7 +3585,7 @@ errno@^0.1.3, errno@~0.1.7: | |||
dependencies: | |||
prr "~1.0.1" | |||
error-ex@^1.2.0, error-ex@^1.3.1: | |||
error-ex@^1.3.1: | |||
version "1.3.2" | |||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" | |||
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== | |||
@@ -3694,12 +3689,12 @@ eslint-import-resolver-node@^0.3.4: | |||
debug "^2.6.9" | |||
resolve "^1.13.1" | |||
eslint-module-utils@^2.6.0: | |||
version "2.6.0" | |||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz#579ebd094f56af7797d19c9866c9c9486629bfa6" | |||
integrity sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA== | |||
eslint-module-utils@^2.6.1: | |||
version "2.6.1" | |||
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz#b51be1e473dd0de1c5ea638e22429c2490ea8233" | |||
integrity sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A== | |||
dependencies: | |||
debug "^2.6.9" | |||
debug "^3.2.7" | |||
pkg-dir "^2.0.0" | |||
eslint-plugin-flowtype@^3.13.0: | |||
@@ -3710,22 +3705,25 @@ eslint-plugin-flowtype@^3.13.0: | |||
lodash "^4.17.15" | |||
eslint-plugin-import@^2.18.2: | |||
version "2.22.1" | |||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz#0896c7e6a0cf44109a2d97b95903c2bb689d7702" | |||
integrity sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw== | |||
version "2.23.2" | |||
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.23.2.tgz#ee15dd68fc7a1a1ba4c653c734e0d01c100d3484" | |||
integrity sha512-LmNoRptHBxOP+nb0PIKz1y6OSzCJlB+0g0IGS3XV4KaKk2q4szqQ6s6F1utVf5ZRkxk/QOTjdxe7v4VjS99Bsg== | |||
dependencies: | |||
array-includes "^3.1.1" | |||
array.prototype.flat "^1.2.3" | |||
contains-path "^0.1.0" | |||
array-includes "^3.1.3" | |||
array.prototype.flat "^1.2.4" | |||
contains-path "^1.0.0" | |||
debug "^2.6.9" | |||
doctrine "1.5.0" | |||
doctrine "^2.1.0" | |||
eslint-import-resolver-node "^0.3.4" | |||
eslint-module-utils "^2.6.0" | |||
eslint-module-utils "^2.6.1" | |||
find-up "^2.0.0" | |||
has "^1.0.3" | |||
is-core-module "^2.4.0" | |||
minimatch "^3.0.4" | |||
object.values "^1.1.1" | |||
read-pkg-up "^2.0.0" | |||
resolve "^1.17.0" | |||
object.values "^1.1.3" | |||
pkg-up "^2.0.0" | |||
read-pkg-up "^3.0.0" | |||
resolve "^1.20.0" | |||
tsconfig-paths "^3.9.0" | |||
eslint-plugin-jsx-a11y@^6.2.3: | |||
@@ -4912,7 +4910,7 @@ is-color-stop@^1.0.0: | |||
rgb-regex "^1.0.1" | |||
rgba-regex "^1.0.0" | |||
is-core-module@^2.2.0: | |||
is-core-module@^2.2.0, is-core-module@^2.4.0: | |||
version "2.4.0" | |||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" | |||
integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A== | |||
@@ -5965,14 +5963,14 @@ listr@^0.14.3: | |||
p-map "^2.0.0" | |||
rxjs "^6.3.3" | |||
load-json-file@^2.0.0: | |||
version "2.0.0" | |||
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" | |||
integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= | |||
load-json-file@^4.0.0: | |||
version "4.0.0" | |||
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" | |||
integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= | |||
dependencies: | |||
graceful-fs "^4.1.2" | |||
parse-json "^2.2.0" | |||
pify "^2.0.0" | |||
parse-json "^4.0.0" | |||
pify "^3.0.0" | |||
strip-bom "^3.0.0" | |||
loader-runner@^2.4.0: | |||
@@ -6471,9 +6469,9 @@ node-notifier@^6.0.0: | |||
which "^1.3.1" | |||
node-releases@^1.1.71: | |||
version "1.1.71" | |||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" | |||
integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== | |||
version "1.1.72" | |||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe" | |||
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw== | |||
normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: | |||
version "2.5.0" | |||
@@ -6615,7 +6613,7 @@ object.pick@^1.3.0: | |||
dependencies: | |||
isobject "^3.0.1" | |||
object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3: | |||
object.values@^1.1.0, object.values@^1.1.3: | |||
version "1.1.3" | |||
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" | |||
integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== | |||
@@ -6817,13 +6815,6 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: | |||
pbkdf2 "^3.0.3" | |||
safe-buffer "^5.1.1" | |||
parse-json@^2.2.0: | |||
version "2.2.0" | |||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" | |||
integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= | |||
dependencies: | |||
error-ex "^1.2.0" | |||
parse-json@^4.0.0: | |||
version "4.0.0" | |||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" | |||
@@ -6905,12 +6896,19 @@ path-parse@^1.0.6: | |||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" | |||
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== | |||
path-type@^2.0.0: | |||
version "2.0.0" | |||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" | |||
integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= | |||
path-starts-with@^1.0.0: | |||
version "1.0.0" | |||
resolved "https://registry.yarnpkg.com/path-starts-with/-/path-starts-with-1.0.0.tgz#b28243015e8b138de572682ac52da42e646ad84e" | |||
integrity sha1-soJDAV6LE43lcmgqxS2kLmRq2E4= | |||
dependencies: | |||
normalize-path "^2.1.1" | |||
path-type@^3.0.0: | |||
version "3.0.0" | |||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" | |||
integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== | |||
dependencies: | |||
pify "^2.0.0" | |||
pify "^3.0.0" | |||
path-type@^4.0.0: | |||
version "4.0.0" | |||
@@ -6943,11 +6941,16 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3: | |||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" | |||
integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== | |||
pify@^2.0.0, pify@^2.2.0: | |||
pify@^2.2.0: | |||
version "2.3.0" | |||
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" | |||
integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= | |||
pify@^3.0.0: | |||
version "3.0.0" | |||
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" | |||
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= | |||
pify@^4.0.1: | |||
version "4.0.1" | |||
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" | |||
@@ -6981,6 +6984,13 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: | |||
dependencies: | |||
find-up "^4.0.0" | |||
pkg-up@^2.0.0: | |||
version "2.0.0" | |||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" | |||
integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= | |||
dependencies: | |||
find-up "^2.1.0" | |||
pn@^1.1.0: | |||
version "1.1.0" | |||
resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" | |||
@@ -7264,9 +7274,9 @@ postcss-selector-parser@^3.0.0: | |||
uniq "^1.0.1" | |||
postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: | |||
version "6.0.5" | |||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz#042d74e137db83e6f294712096cb413f5aa612c4" | |||
integrity sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg== | |||
version "6.0.6" | |||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" | |||
integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== | |||
dependencies: | |||
cssesc "^3.0.0" | |||
util-deprecate "^1.0.2" | |||
@@ -7518,13 +7528,13 @@ react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4: | |||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" | |||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== | |||
read-pkg-up@^2.0.0: | |||
version "2.0.0" | |||
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" | |||
integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= | |||
read-pkg-up@^3.0.0: | |||
version "3.0.0" | |||
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" | |||
integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= | |||
dependencies: | |||
find-up "^2.0.0" | |||
read-pkg "^2.0.0" | |||
read-pkg "^3.0.0" | |||
read-pkg-up@^7.0.1: | |||
version "7.0.1" | |||
@@ -7535,14 +7545,14 @@ read-pkg-up@^7.0.1: | |||
read-pkg "^5.2.0" | |||
type-fest "^0.8.1" | |||
read-pkg@^2.0.0: | |||
version "2.0.0" | |||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" | |||
integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= | |||
read-pkg@^3.0.0: | |||
version "3.0.0" | |||
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" | |||
integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= | |||
dependencies: | |||
load-json-file "^2.0.0" | |||
load-json-file "^4.0.0" | |||
normalize-package-data "^2.3.2" | |||
path-type "^2.0.0" | |||
path-type "^3.0.0" | |||
read-pkg@^5.2.0: | |||
version "5.2.0" | |||
@@ -7791,7 +7801,7 @@ resolve@1.17.0: | |||
dependencies: | |||
path-parse "^1.0.6" | |||
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0: | |||
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.20.0: | |||
version "1.20.0" | |||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" | |||
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== | |||
@@ -8733,9 +8743,9 @@ timsort@^0.3.0: | |||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= | |||
tiny-glob@^0.2.6: | |||
version "0.2.8" | |||
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.8.tgz#b2792c396cc62db891ffa161fe8b33e76123e531" | |||
integrity sha512-vkQP7qOslq63XRX9kMswlby99kyO5OvKptw7AMwBVMjXEI7Tb61eoI5DydyEMOseyGS5anDN1VPoVxEvH01q8w== | |||
version "0.2.9" | |||
resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" | |||
integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== | |||
dependencies: | |||
globalyzer "0.1.0" | |||
globrex "^0.1.2" | |||