mirror of
https://github.com/Unleash/unleash.git
synced 2025-09-05 17:53:12 +02:00
refactor: convert auth tests from Cypress to Jest (#864)
* refactor: replace data-test with data-testid * refactor: add Jest tests for auth pages * refactor: remove Cypress tests for auth pages * refactor: remove questionable snapshots * refactor: share test server setup/teardown * refactor: restore auth page flex layout * refactor: use toBeInTheDocument * refactor: change recent data-test attrs to data-testid
This commit is contained in:
parent
1132a79f6d
commit
49b8e7329e
24
frontend/.github/workflows/e2e.auth.yml
vendored
24
frontend/.github/workflows/e2e.auth.yml
vendored
@ -1,24 +0,0 @@
|
||||
name: e2e:auth
|
||||
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows
|
||||
on: [deployment_status]
|
||||
jobs:
|
||||
e2e:
|
||||
# only runs this job on successful deploy
|
||||
if: github.event_name == 'deployment_status' && github.event.deployment_status.state == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Dump GitHub context
|
||||
env:
|
||||
GITHUB_CONTEXT: ${{ toJson(github) }}
|
||||
run: |
|
||||
echo "$GITHUB_CONTEXT"
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Cypress
|
||||
uses: cypress-io/github-action@v2
|
||||
with:
|
||||
config: baseUrl=${{ github.event.deployment_status.target_url }}
|
||||
record: true
|
||||
spec: cypress/integration/auth/auth.spec.ts
|
||||
env:
|
||||
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
|
@ -1,201 +0,0 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
export {};
|
||||
|
||||
describe('auth', () => {
|
||||
it('renders the password login', () => {
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
|
||||
cy.intercept('POST', '/auth/simple/login', req => {
|
||||
expect(req.body.username).to.equal('admin');
|
||||
expect(req.body.password).to.equal('unleash4all');
|
||||
}).as('passwordLogin');
|
||||
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').type('admin');
|
||||
cy.get('[data-test="LOGIN_PASSWORD_ID"]').type('unleash4all');
|
||||
cy.get("[data-test='LOGIN_BUTTON']").click();
|
||||
});
|
||||
|
||||
it('renders does not render password login if defaultHidden is true', () => {
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: true,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').should('not.exist');
|
||||
cy.get('[data-test="LOGIN_PASSWORD_ID"]').should('not.exist');
|
||||
});
|
||||
|
||||
it('renders google auth when options are specified', () => {
|
||||
const ssoPath = '/auth/google/login';
|
||||
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: true,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [
|
||||
{
|
||||
type: 'google',
|
||||
message: 'Sign in with Google',
|
||||
path: ssoPath,
|
||||
},
|
||||
],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').should('not.exist');
|
||||
cy.get('[data-test="LOGIN_PASSWORD_ID"]').should('not.exist');
|
||||
|
||||
cy.get('[data-test="SSO_LOGIN_BUTTON-google"]')
|
||||
.should('exist')
|
||||
.should('have.attr', 'href', ssoPath);
|
||||
});
|
||||
|
||||
it('renders oidc auth when options are specified', () => {
|
||||
const ssoPath = '/auth/oidc/login';
|
||||
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: true,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [
|
||||
{
|
||||
type: 'oidc',
|
||||
message: 'Sign in with OpenId Connect',
|
||||
path: ssoPath,
|
||||
},
|
||||
],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').should('not.exist');
|
||||
cy.get('[data-test="LOGIN_PASSWORD_ID"]').should('not.exist');
|
||||
|
||||
cy.get('[data-test="SSO_LOGIN_BUTTON-oidc"]')
|
||||
.should('exist')
|
||||
.should('have.attr', 'href', ssoPath);
|
||||
});
|
||||
|
||||
it('renders saml auth when options are specified', () => {
|
||||
const ssoPath = '/auth/saml/login';
|
||||
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: true,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [
|
||||
{
|
||||
type: 'saml',
|
||||
message: 'Sign in with SAML 2.0',
|
||||
path: ssoPath,
|
||||
},
|
||||
],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').should('not.exist');
|
||||
cy.get('[data-test="LOGIN_PASSWORD_ID"]').should('not.exist');
|
||||
|
||||
cy.get('[data-test="SSO_LOGIN_BUTTON-saml"]')
|
||||
.should('exist')
|
||||
.should('have.attr', 'href', ssoPath);
|
||||
});
|
||||
|
||||
it('can visit forgot password when password auth is enabled', () => {
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
},
|
||||
});
|
||||
|
||||
cy.visit('/forgotten-password');
|
||||
cy.get('[data-test="FORGOTTEN_PASSWORD_FIELD"').type('me@myemail.com');
|
||||
});
|
||||
|
||||
it('renders demo auth correctly', () => {
|
||||
const email = 'hello@hello.com';
|
||||
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [],
|
||||
path: '/auth/demo/login',
|
||||
type: 'demo',
|
||||
},
|
||||
});
|
||||
|
||||
cy.intercept('POST', '/auth/demo/login', req => {
|
||||
expect(req.body.email).to.equal(email);
|
||||
}).as('passwordLogin');
|
||||
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').type(email);
|
||||
cy.get("[data-test='LOGIN_BUTTON']").click();
|
||||
});
|
||||
|
||||
it('renders email auth correctly', () => {
|
||||
const email = 'hello@hello.com';
|
||||
|
||||
cy.intercept('GET', '/api/admin/**', {
|
||||
statusCode: 401,
|
||||
body: {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [],
|
||||
path: '/auth/unsecure/login',
|
||||
type: 'unsecure',
|
||||
},
|
||||
});
|
||||
|
||||
cy.intercept('POST', '/auth/unsecure/login', req => {
|
||||
expect(req.body.email).to.equal(email);
|
||||
}).as('passwordLogin');
|
||||
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').type(email);
|
||||
cy.get("[data-test='LOGIN_BUTTON']").click();
|
||||
});
|
||||
|
||||
it('renders invalid token page when token is invalid', () => {
|
||||
cy.visit('/new-user?token=hellotokenworld');
|
||||
cy.get('[data-test="INVALID_TOKEN_BUTTON"]').should('be.visible');
|
||||
});
|
||||
});
|
@ -42,61 +42,61 @@ describe('feature', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/');
|
||||
cy.get('[data-test="LOGIN_EMAIL_ID"]').type(AUTH_USER);
|
||||
cy.get('[data-testid="LOGIN_EMAIL_ID"]').type(AUTH_USER);
|
||||
|
||||
if (AUTH_PASSWORD) {
|
||||
cy.get('[data-test="LOGIN_PASSWORD_ID"]').type(AUTH_PASSWORD);
|
||||
cy.get('[data-testid="LOGIN_PASSWORD_ID"]').type(AUTH_PASSWORD);
|
||||
}
|
||||
|
||||
cy.get("[data-test='LOGIN_BUTTON']").click();
|
||||
cy.get("[data-testid='LOGIN_BUTTON']").click();
|
||||
// Wait for the login redirect to complete.
|
||||
cy.get('[data-test=HEADER_USER_AVATAR');
|
||||
cy.get('[data-testid=HEADER_USER_AVATAR');
|
||||
});
|
||||
|
||||
it('can create a feature toggle', () => {
|
||||
if (document.querySelector("[data-test='CLOSE_SPLASH']")) {
|
||||
cy.get("[data-test='CLOSE_SPLASH']").click();
|
||||
if (document.querySelector("[data-testid='CLOSE_SPLASH']")) {
|
||||
cy.get("[data-testid='CLOSE_SPLASH']").click();
|
||||
}
|
||||
|
||||
cy.get('[data-test=NAVIGATE_TO_CREATE_FEATURE').click();
|
||||
cy.get('[data-testid=NAVIGATE_TO_CREATE_FEATURE').click();
|
||||
|
||||
cy.intercept('POST', '/api/admin/projects/default/features').as(
|
||||
'createFeature'
|
||||
);
|
||||
|
||||
cy.get("[data-test='CF_NAME_ID'").type(featureToggleName);
|
||||
cy.get("[data-test='CF_DESC_ID'").type('hello-world');
|
||||
cy.get("[data-test='CF_CREATE_BTN_ID']").click();
|
||||
cy.get("[data-testid='CF_NAME_ID'").type(featureToggleName);
|
||||
cy.get("[data-testid='CF_DESC_ID'").type('hello-world');
|
||||
cy.get("[data-testid='CF_CREATE_BTN_ID']").click();
|
||||
cy.wait('@createFeature');
|
||||
cy.url().should('include', featureToggleName);
|
||||
});
|
||||
|
||||
it('gives an error if a toggle exists with the same name', () => {
|
||||
cy.get('[data-test=NAVIGATE_TO_CREATE_FEATURE').click();
|
||||
cy.get('[data-testid=NAVIGATE_TO_CREATE_FEATURE').click();
|
||||
|
||||
cy.intercept('POST', '/api/admin/projects/default/features').as(
|
||||
'createFeature'
|
||||
);
|
||||
|
||||
cy.get("[data-test='CF_NAME_ID'").type(featureToggleName);
|
||||
cy.get("[data-test='CF_DESC_ID'").type('hello-world');
|
||||
cy.get("[data-test='CF_CREATE_BTN_ID']").click();
|
||||
cy.get("[data-test='INPUT_ERROR_TEXT']").contains(
|
||||
cy.get("[data-testid='CF_NAME_ID'").type(featureToggleName);
|
||||
cy.get("[data-testid='CF_DESC_ID'").type('hello-world');
|
||||
cy.get("[data-testid='CF_CREATE_BTN_ID']").click();
|
||||
cy.get("[data-testid='INPUT_ERROR_TEXT']").contains(
|
||||
'A feature with this name already exists'
|
||||
);
|
||||
});
|
||||
|
||||
it('gives an error if a toggle name is url unsafe', () => {
|
||||
cy.get('[data-test=NAVIGATE_TO_CREATE_FEATURE').click();
|
||||
cy.get('[data-testid=NAVIGATE_TO_CREATE_FEATURE').click();
|
||||
|
||||
cy.intercept('POST', '/api/admin/projects/default/features').as(
|
||||
'createFeature'
|
||||
);
|
||||
|
||||
cy.get("[data-test='CF_NAME_ID'").type('featureToggleUnsafe####$#//');
|
||||
cy.get("[data-test='CF_DESC_ID'").type('hello-world');
|
||||
cy.get("[data-test='CF_CREATE_BTN_ID']").click();
|
||||
cy.get("[data-test='INPUT_ERROR_TEXT']").contains(
|
||||
cy.get("[data-testid='CF_NAME_ID'").type('featureToggleUnsafe####$#//');
|
||||
cy.get("[data-testid='CF_DESC_ID'").type('hello-world');
|
||||
cy.get("[data-testid='CF_CREATE_BTN_ID']").click();
|
||||
cy.get("[data-testid='INPUT_ERROR_TEXT']").contains(
|
||||
`"name" must be URL friendly`
|
||||
);
|
||||
});
|
||||
@ -107,16 +107,16 @@ describe('feature', () => {
|
||||
);
|
||||
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test=ROLLOUT_SLIDER_ID')
|
||||
cy.get('[data-testid=ROLLOUT_SLIDER_ID')
|
||||
.click()
|
||||
.type('{leftarrow}'.repeat(20));
|
||||
|
||||
if (ENTERPRISE) {
|
||||
cy.get('[data-test=ADD_CONSTRAINT_ID]').click();
|
||||
cy.get('[data-test=CONSTRAINT_AUTOCOMPLETE_ID]')
|
||||
cy.get('[data-testid=ADD_CONSTRAINT_ID]').click();
|
||||
cy.get('[data-testid=CONSTRAINT_AUTOCOMPLETE_ID]')
|
||||
.type('{downArrow}'.repeat(1))
|
||||
.type('{enter}');
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
}
|
||||
|
||||
cy.intercept(
|
||||
@ -140,7 +140,7 @@ describe('feature', () => {
|
||||
}
|
||||
).as('addStrategyToFeature');
|
||||
|
||||
cy.get(`[data-test=STRATEGY_FORM_SUBMIT_ID]`).first().click();
|
||||
cy.get(`[data-testid=STRATEGY_FORM_SUBMIT_ID]`).first().click();
|
||||
cy.wait('@addStrategyToFeature');
|
||||
});
|
||||
|
||||
@ -150,18 +150,18 @@ describe('feature', () => {
|
||||
);
|
||||
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test=ROLLOUT_SLIDER_ID')
|
||||
cy.get('[data-testid=ROLLOUT_SLIDER_ID')
|
||||
.click()
|
||||
.type('{rightArrow}'.repeat(10));
|
||||
|
||||
cy.get('[data-test=FLEXIBLE_STRATEGY_STICKINESS_ID]')
|
||||
cy.get('[data-testid=FLEXIBLE_STRATEGY_STICKINESS_ID]')
|
||||
.first()
|
||||
.click()
|
||||
.get('[data-test=SELECT_ITEM_ID-sessionId')
|
||||
.get('[data-testid=SELECT_ITEM_ID-sessionId')
|
||||
.first()
|
||||
.click();
|
||||
|
||||
cy.get('[data-test=FLEXIBLE_STRATEGY_GROUP_ID]')
|
||||
cy.get('[data-testid=FLEXIBLE_STRATEGY_GROUP_ID]')
|
||||
.first()
|
||||
.clear()
|
||||
.type('new-group-id');
|
||||
@ -186,7 +186,7 @@ describe('feature', () => {
|
||||
}
|
||||
).as('updateStrategy');
|
||||
|
||||
cy.get(`[data-test=STRATEGY_FORM_SUBMIT_ID]`).first().click();
|
||||
cy.get(`[data-testid=STRATEGY_FORM_SUBMIT_ID]`).first().click();
|
||||
cy.wait('@updateStrategy');
|
||||
});
|
||||
|
||||
@ -203,9 +203,11 @@ describe('feature', () => {
|
||||
}
|
||||
).as('deleteStrategy');
|
||||
|
||||
cy.get('[data-test=FEATURE_ENVIRONMENT_ACCORDION_development]').click();
|
||||
cy.get('[data-test=STRATEGY_FORM_REMOVE_ID]').click();
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get(
|
||||
'[data-testid=FEATURE_ENVIRONMENT_ACCORDION_development]'
|
||||
).click();
|
||||
cy.get('[data-testid=STRATEGY_FORM_REMOVE_ID]').click();
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.wait('@deleteStrategy');
|
||||
});
|
||||
|
||||
@ -215,19 +217,19 @@ describe('feature', () => {
|
||||
);
|
||||
|
||||
if (ENTERPRISE) {
|
||||
cy.get('[data-test=ADD_CONSTRAINT_ID]').click();
|
||||
cy.get('[data-test=CONSTRAINT_AUTOCOMPLETE_ID]')
|
||||
cy.get('[data-testid=ADD_CONSTRAINT_ID]').click();
|
||||
cy.get('[data-testid=CONSTRAINT_AUTOCOMPLETE_ID]')
|
||||
.type('{downArrow}'.repeat(1))
|
||||
.type('{enter}');
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
}
|
||||
|
||||
cy.get('[data-test=STRATEGY_INPUT_LIST]')
|
||||
cy.get('[data-testid=STRATEGY_INPUT_LIST]')
|
||||
.type('user1')
|
||||
.type('{enter}')
|
||||
.type('user2')
|
||||
.type('{enter}');
|
||||
cy.get('[data-test=ADD_TO_STRATEGY_INPUT_LIST]').click();
|
||||
cy.get('[data-testid=ADD_TO_STRATEGY_INPUT_LIST]').click();
|
||||
|
||||
cy.intercept(
|
||||
'POST',
|
||||
@ -249,7 +251,7 @@ describe('feature', () => {
|
||||
}
|
||||
).as('addStrategyToFeature');
|
||||
|
||||
cy.get(`[data-test=STRATEGY_FORM_SUBMIT_ID]`).first().click();
|
||||
cy.get(`[data-testid=STRATEGY_FORM_SUBMIT_ID]`).first().click();
|
||||
cy.wait('@addStrategyToFeature');
|
||||
});
|
||||
|
||||
@ -278,32 +280,32 @@ describe('feature', () => {
|
||||
}
|
||||
).as('variantCreation');
|
||||
|
||||
cy.get('[data-test=ADD_VARIANT_BUTTON]').click();
|
||||
cy.get('[data-testid=ADD_VARIANT_BUTTON]').click();
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test=VARIANT_NAME_INPUT]').type(variantName);
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get('[data-testid=VARIANT_NAME_INPUT]').type(variantName);
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.wait('@variantCreation');
|
||||
cy.get('[data-test=ADD_VARIANT_BUTTON]').click();
|
||||
cy.get('[data-testid=ADD_VARIANT_BUTTON]').click();
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test=VARIANT_NAME_INPUT]').type(secondVariantName);
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get('[data-testid=VARIANT_NAME_INPUT]').type(secondVariantName);
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.wait('@variantCreation');
|
||||
});
|
||||
|
||||
it('can set weight to fixed value for one of the variants', () => {
|
||||
cy.visit(`/projects/default/features/${featureToggleName}/variants`);
|
||||
|
||||
cy.get('[data-test=VARIANT_EDIT_BUTTON]').first().click();
|
||||
cy.get('[data-testid=VARIANT_EDIT_BUTTON]').first().click();
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test=VARIANT_NAME_INPUT]')
|
||||
cy.get('[data-testid=VARIANT_NAME_INPUT]')
|
||||
.children()
|
||||
.find('input')
|
||||
.should('have.attr', 'disabled');
|
||||
cy.get('[data-test=VARIANT_WEIGHT_TYPE]')
|
||||
cy.get('[data-testid=VARIANT_WEIGHT_TYPE]')
|
||||
.children()
|
||||
.find('input')
|
||||
.check();
|
||||
cy.get('[data-test=VARIANT_WEIGHT_INPUT]').clear().type('15');
|
||||
cy.get('[data-testid=VARIANT_WEIGHT_INPUT]').clear().type('15');
|
||||
|
||||
cy.intercept(
|
||||
'PATCH',
|
||||
@ -321,9 +323,9 @@ describe('feature', () => {
|
||||
}
|
||||
).as('variantUpdate');
|
||||
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.wait('@variantUpdate');
|
||||
cy.get('[data-test=VARIANT_WEIGHT]')
|
||||
cy.get('[data-testid=VARIANT_WEIGHT]')
|
||||
.first()
|
||||
.should('have.text', '15 %');
|
||||
});
|
||||
@ -332,10 +334,10 @@ describe('feature', () => {
|
||||
const variantName = 'to-be-deleted';
|
||||
|
||||
cy.visit(`/projects/default/features/${featureToggleName}/variants`);
|
||||
cy.get('[data-test=ADD_VARIANT_BUTTON]').click();
|
||||
cy.get('[data-testid=ADD_VARIANT_BUTTON]').click();
|
||||
cy.wait(1000);
|
||||
cy.get('[data-test=VARIANT_NAME_INPUT]').type(variantName);
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get('[data-testid=VARIANT_NAME_INPUT]').type(variantName);
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
|
||||
cy.intercept(
|
||||
'PATCH',
|
||||
@ -348,8 +350,8 @@ describe('feature', () => {
|
||||
}
|
||||
).as('delete');
|
||||
|
||||
cy.get(`[data-test=VARIANT_DELETE_BUTTON_${variantName}]`).click();
|
||||
cy.get('[data-test=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.get(`[data-testid=VARIANT_DELETE_BUTTON_${variantName}]`).click();
|
||||
cy.get('[data-testid=DIALOGUE_CONFIRM_ID]').click();
|
||||
cy.wait('@delete');
|
||||
});
|
||||
});
|
||||
|
@ -25,52 +25,52 @@ describe('segments', () => {
|
||||
cy.session(AUTH_USER, () => {
|
||||
cy.visit('/');
|
||||
cy.wait(1000);
|
||||
cy.get("[data-test='LOGIN_EMAIL_ID']").type(AUTH_USER);
|
||||
cy.get("[data-testid='LOGIN_EMAIL_ID']").type(AUTH_USER);
|
||||
|
||||
if (AUTH_PASSWORD) {
|
||||
cy.get("[data-test='LOGIN_PASSWORD_ID']").type(AUTH_PASSWORD);
|
||||
cy.get("[data-testid='LOGIN_PASSWORD_ID']").type(AUTH_PASSWORD);
|
||||
}
|
||||
|
||||
cy.get("[data-test='LOGIN_BUTTON']").click();
|
||||
cy.get("[data-testid='LOGIN_BUTTON']").click();
|
||||
// Wait for the login redirect to complete.
|
||||
cy.get("[data-test='HEADER_USER_AVATAR']");
|
||||
cy.get("[data-testid='HEADER_USER_AVATAR']");
|
||||
});
|
||||
|
||||
cy.visit('/segments');
|
||||
});
|
||||
|
||||
it('can create a segment', () => {
|
||||
if (document.querySelector("[data-test='CLOSE_SPLASH']")) {
|
||||
cy.get("[data-test='CLOSE_SPLASH']").click();
|
||||
if (document.querySelector("[data-testid='CLOSE_SPLASH']")) {
|
||||
cy.get("[data-testid='CLOSE_SPLASH']").click();
|
||||
}
|
||||
|
||||
cy.get("[data-test='NAVIGATE_TO_CREATE_SEGMENT']").click();
|
||||
cy.get("[data-testid='NAVIGATE_TO_CREATE_SEGMENT']").click();
|
||||
|
||||
cy.intercept('POST', '/api/admin/segments').as('createSegment');
|
||||
|
||||
cy.get("[data-test='SEGMENT_NAME_ID']").type(segmentName);
|
||||
cy.get("[data-test='SEGMENT_DESC_ID']").type('hello-world');
|
||||
cy.get("[data-test='SEGMENT_NEXT_BTN_ID']").click();
|
||||
cy.get("[data-test='SEGMENT_CREATE_BTN_ID']").click();
|
||||
cy.get("[data-testid='SEGMENT_NAME_ID']").type(segmentName);
|
||||
cy.get("[data-testid='SEGMENT_DESC_ID']").type('hello-world');
|
||||
cy.get("[data-testid='SEGMENT_NEXT_BTN_ID']").click();
|
||||
cy.get("[data-testid='SEGMENT_CREATE_BTN_ID']").click();
|
||||
cy.wait('@createSegment');
|
||||
cy.contains(segmentName);
|
||||
});
|
||||
|
||||
it('gives an error if a segment exists with the same name', () => {
|
||||
cy.get("[data-test='NAVIGATE_TO_CREATE_SEGMENT']").click();
|
||||
cy.get("[data-testid='NAVIGATE_TO_CREATE_SEGMENT']").click();
|
||||
|
||||
cy.get("[data-test='SEGMENT_NAME_ID']").type(segmentName);
|
||||
cy.get("[data-test='SEGMENT_NEXT_BTN_ID']").should('be.disabled');
|
||||
cy.get("[data-test='INPUT_ERROR_TEXT']").contains(
|
||||
cy.get("[data-testid='SEGMENT_NAME_ID']").type(segmentName);
|
||||
cy.get("[data-testid='SEGMENT_NEXT_BTN_ID']").should('be.disabled');
|
||||
cy.get("[data-testid='INPUT_ERROR_TEXT']").contains(
|
||||
'Segment name already exists'
|
||||
);
|
||||
});
|
||||
|
||||
it('can delete a segment', () => {
|
||||
cy.get(`[data-test='SEGMENT_DELETE_BTN_ID_${segmentName}']`).click();
|
||||
cy.get(`[data-testid='SEGMENT_DELETE_BTN_ID_${segmentName}']`).click();
|
||||
|
||||
cy.get("[data-test='SEGMENT_DIALOG_NAME_ID']").type(segmentName);
|
||||
cy.get("[data-test='DIALOGUE_CONFIRM_ID'").click();
|
||||
cy.get("[data-testid='SEGMENT_DIALOG_NAME_ID']").type(segmentName);
|
||||
cy.get("[data-testid='DIALOGUE_CONFIRM_ID'").click();
|
||||
|
||||
cy.contains(segmentName).should('not.exist');
|
||||
});
|
||||
|
@ -68,6 +68,7 @@
|
||||
"http-proxy-middleware": "2.0.4",
|
||||
"immer": "^9.0.12",
|
||||
"lodash.clonedeep": "4.5.0",
|
||||
"msw": "^0.39.2",
|
||||
"prettier": "2.6.1",
|
||||
"prop-types": "15.8.1",
|
||||
"react": "17.0.2",
|
||||
|
@ -247,7 +247,7 @@ export const ApiTokenList = () => {
|
||||
'/admin/api/create-token'
|
||||
)
|
||||
}
|
||||
data-test={CREATE_API_TOKEN_BUTTON}
|
||||
data-testid={CREATE_API_TOKEN_BUTTON}
|
||||
>
|
||||
New API token
|
||||
</Button>
|
||||
|
@ -81,7 +81,7 @@ const Dialogue: React.FC<IDialogue> = ({
|
||||
onClick={handleClick}
|
||||
autoFocus={!formId}
|
||||
disabled={disabledPrimaryButton}
|
||||
data-test={DIALOGUE_CONFIRM_ID}
|
||||
data-testid={DIALOGUE_CONFIRM_ID}
|
||||
type={formId ? 'submit' : 'button'}
|
||||
>
|
||||
{primaryButtonText || "Yes, I'm sure"}
|
||||
|
@ -52,7 +52,7 @@ const GeneralSelect: React.FC<ISelectMenuProps> = ({
|
||||
key={option.key}
|
||||
value={option.key}
|
||||
title={option.title || ''}
|
||||
data-test={`${SELECT_ITEM_ID}-${option.label}`}
|
||||
data-testid={`${SELECT_ITEM_ID}-${option.label}`}
|
||||
disabled={option.disabled}
|
||||
>
|
||||
{option.label}
|
||||
|
@ -48,7 +48,7 @@ const Input = ({
|
||||
onChange={onChange}
|
||||
FormHelperTextProps={{
|
||||
// @ts-expect-error
|
||||
['data-test']: INPUT_ERROR_TEXT,
|
||||
['data-testid']: INPUT_ERROR_TEXT,
|
||||
classes: {
|
||||
root: styles.helperText,
|
||||
},
|
||||
|
@ -29,7 +29,7 @@ export const SidebarModal = ({
|
||||
aria-label={label}
|
||||
BackdropComponent={Backdrop}
|
||||
BackdropProps={{ timeout: TRANSITION_DURATION }}
|
||||
data-test={SIDEBAR_MODAL_ID}
|
||||
data-testid={SIDEBAR_MODAL_ID}
|
||||
>
|
||||
<Fade timeout={TRANSITION_DURATION} in={open}>
|
||||
<div className={styles.modal}>{children}</div>
|
||||
|
@ -80,7 +80,7 @@ export const FormButtons = ({
|
||||
}) => (
|
||||
<div>
|
||||
<Button
|
||||
data-test={primaryButtonTestId}
|
||||
data-testid={primaryButtonTestId}
|
||||
type="submit"
|
||||
color="primary"
|
||||
variant="contained"
|
||||
|
@ -41,7 +41,7 @@ const SelectMenu: React.FC<ISelectMenuProps> = ({
|
||||
key={option.key}
|
||||
value={option.key}
|
||||
title={option.title || ''}
|
||||
data-test={`${SELECT_ITEM_ID}-${option.label}`}
|
||||
data-testid={`${SELECT_ITEM_ID}-${option.label}`}
|
||||
>
|
||||
{option.label}
|
||||
</MenuItem>
|
||||
|
@ -105,7 +105,7 @@ const CreateFeature = () => {
|
||||
name="Feature"
|
||||
permission={CREATE_FEATURE}
|
||||
projectId={project}
|
||||
data-test={CF_CREATE_BTN_ID}
|
||||
data-testid={CF_CREATE_BTN_ID}
|
||||
/>
|
||||
</FeatureForm>
|
||||
</FormTemplate>
|
||||
|
@ -32,7 +32,7 @@ export const CreateFeatureButton = ({
|
||||
<IconButton
|
||||
component={Link}
|
||||
to={createFeature.path}
|
||||
data-test={NAVIGATE_TO_CREATE_FEATURE}
|
||||
data-testid={NAVIGATE_TO_CREATE_FEATURE}
|
||||
disabled={!createFeature.access}
|
||||
>
|
||||
<Add titleAccess="New" />
|
||||
@ -45,7 +45,7 @@ export const CreateFeatureButton = ({
|
||||
color="primary"
|
||||
variant="contained"
|
||||
component={Link}
|
||||
data-test={NAVIGATE_TO_CREATE_FEATURE}
|
||||
data-testid={NAVIGATE_TO_CREATE_FEATURE}
|
||||
disabled={!createFeature.access}
|
||||
className={classnames({ skeleton: loading })}
|
||||
>
|
||||
|
@ -84,7 +84,7 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
||||
onFocus={() => clearErrors()}
|
||||
value={name}
|
||||
onChange={e => setName(trim(e.target.value))}
|
||||
data-test={CF_NAME_ID}
|
||||
data-testid={CF_NAME_ID}
|
||||
onBlur={validateToggleName}
|
||||
/>
|
||||
<p className={styles.inputDescription}>
|
||||
@ -97,7 +97,7 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
||||
label={'Toggle type'}
|
||||
id="feature-type-select"
|
||||
editable
|
||||
data-test={CF_TYPE_ID}
|
||||
data-testid={CF_TYPE_ID}
|
||||
IconComponent={KeyboardArrowDownOutlined}
|
||||
className={styles.selectInput}
|
||||
/>
|
||||
@ -137,7 +137,7 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
||||
label="Description"
|
||||
placeholder="A short description of the feature toggle"
|
||||
value={description}
|
||||
data-test={CF_DESC_ID}
|
||||
data-testid={CF_DESC_ID}
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
/>
|
||||
<FormControl className={styles.input}>
|
||||
|
@ -135,7 +135,7 @@ export const FeatureStrategyForm = ({
|
||||
color="primary"
|
||||
type="submit"
|
||||
disabled={loading || !hasValidConstraints}
|
||||
data-test={STRATEGY_FORM_SUBMIT_ID}
|
||||
data-testid={STRATEGY_FORM_SUBMIT_ID}
|
||||
>
|
||||
Save strategy
|
||||
</PermissionButton>
|
||||
|
@ -68,7 +68,7 @@ export const FeatureStrategyRemove = ({
|
||||
environmentId={environmentId}
|
||||
disabled={disabled}
|
||||
permission={DELETE_FEATURE_STRATEGY}
|
||||
data-test={STRATEGY_FORM_REMOVE_ID}
|
||||
data-testid={STRATEGY_FORM_REMOVE_ID}
|
||||
type="button"
|
||||
>
|
||||
<Delete titleAccess="Delete strategy" />
|
||||
@ -81,7 +81,7 @@ export const FeatureStrategyRemove = ({
|
||||
environmentId={environmentId}
|
||||
disabled={disabled}
|
||||
permission={DELETE_FEATURE_STRATEGY}
|
||||
data-test={STRATEGY_FORM_REMOVE_ID}
|
||||
data-testid={STRATEGY_FORM_REMOVE_ID}
|
||||
color="secondary"
|
||||
variant="text"
|
||||
type="button"
|
||||
|
@ -89,7 +89,7 @@ const FeatureOverviewEnvironment = ({
|
||||
<div className={styles.featureOverviewEnvironment}>
|
||||
<Accordion
|
||||
style={{ boxShadow: 'none' }}
|
||||
data-test={`${FEATURE_ENVIRONMENT_ACCORDION}_${env.name}`}
|
||||
data-testid={`${FEATURE_ENVIRONMENT_ACCORDION}_${env.name}`}
|
||||
>
|
||||
<AccordionSummary
|
||||
className={styles.accordionHeader}
|
||||
|
@ -277,7 +277,7 @@ export const AddVariant = ({
|
||||
type="name"
|
||||
disabled={editing}
|
||||
onChange={setVariantValue}
|
||||
data-test={'VARIANT_NAME_INPUT'}
|
||||
data-testid={'VARIANT_NAME_INPUT'}
|
||||
/>
|
||||
<br />
|
||||
<Grid container>
|
||||
@ -299,7 +299,7 @@ export const AddVariant = ({
|
||||
projectId={projectId}
|
||||
name="weightType"
|
||||
checked={isFixWeight}
|
||||
data-test={
|
||||
data-testid={
|
||||
'VARIANT_WEIGHT_TYPE'
|
||||
}
|
||||
onChange={setVariantWeightType}
|
||||
@ -320,7 +320,7 @@ export const AddVariant = ({
|
||||
id="weight"
|
||||
label="Weight"
|
||||
name="weight"
|
||||
data-test={'VARIANT_WEIGHT_INPUT'}
|
||||
data-testid={'VARIANT_WEIGHT_INPUT'}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position="start">
|
||||
@ -373,7 +373,7 @@ export const AddVariant = ({
|
||||
className={commonStyles.fullWidth}
|
||||
value={payload.value}
|
||||
onChange={onPayload}
|
||||
data-test={'VARIANT_PAYLOAD_VALUE'}
|
||||
data-testid={'VARIANT_PAYLOAD_VALUE'}
|
||||
placeholder={
|
||||
payload.type === 'json'
|
||||
? '{ "hello": "world" }'
|
||||
|
@ -292,7 +292,7 @@ const FeatureOverviewVariants = () => {
|
||||
setShowAddVariant(true);
|
||||
}}
|
||||
className={styles.addVariantButton}
|
||||
data-test={'ADD_VARIANT_BUTTON'}
|
||||
data-testid={'ADD_VARIANT_BUTTON'}
|
||||
permission={UPDATE_FEATURE_VARIANTS}
|
||||
projectId={projectId}
|
||||
>
|
||||
|
@ -23,7 +23,7 @@ const FeatureVariantListItem = ({
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
<TableCell data-test={'VARIANT_NAME'}>{variant.name}</TableCell>
|
||||
<TableCell data-testid={'VARIANT_NAME'}>{variant.name}</TableCell>
|
||||
<TableCell className={styles.chipContainer}>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(variant.payload)}
|
||||
@ -43,10 +43,10 @@ const FeatureVariantListItem = ({
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell data-test={'VARIANT_WEIGHT'}>
|
||||
<TableCell data-testid={'VARIANT_WEIGHT'}>
|
||||
{variant.weight / 10.0} %
|
||||
</TableCell>
|
||||
<TableCell data-test={'VARIANT_WEIGHT_TYPE'}>
|
||||
<TableCell data-testid={'VARIANT_WEIGHT_TYPE'}>
|
||||
{variant.weightType === FIX ? 'Fix' : 'Variable'}
|
||||
</TableCell>
|
||||
<ConditionallyRender
|
||||
@ -55,13 +55,13 @@ const FeatureVariantListItem = ({
|
||||
<TableCell className={styles.actions}>
|
||||
<div className={styles.actionsContainer}>
|
||||
<IconButton
|
||||
data-test={'VARIANT_EDIT_BUTTON'}
|
||||
data-testid={'VARIANT_EDIT_BUTTON'}
|
||||
onClick={() => editVariant(variant.name)}
|
||||
>
|
||||
<Edit />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
data-test={`VARIANT_DELETE_BUTTON_${variant.name}`}
|
||||
data-testid={`VARIANT_DELETE_BUTTON_${variant.name}`}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
setDelDialog({
|
||||
|
@ -117,7 +117,7 @@ const StrategyConstraintInputField = ({
|
||||
multiple
|
||||
size="small"
|
||||
options={options}
|
||||
data-test={CONSTRAINT_AUTOCOMPLETE_ID}
|
||||
data-testid={CONSTRAINT_AUTOCOMPLETE_ID}
|
||||
value={values || []}
|
||||
getOptionLabel={option => option.label}
|
||||
onBlur={onBlur}
|
||||
|
@ -104,7 +104,7 @@ const FlexibleStrategy = ({
|
||||
options={stickinessOptions}
|
||||
value={stickiness}
|
||||
disabled={!editable}
|
||||
data-test={FLEXIBLE_STRATEGY_STICKINESS_ID}
|
||||
data-testid={FLEXIBLE_STRATEGY_STICKINESS_ID}
|
||||
onChange={e =>
|
||||
onUpdate('stickiness')(e, e.target.value as number)
|
||||
}
|
||||
@ -136,7 +136,7 @@ const FlexibleStrategy = ({
|
||||
value={groupId || ''}
|
||||
disabled={!editable}
|
||||
onChange={e => onUpdate('groupId')(e, e.target.value)}
|
||||
data-test={FLEXIBLE_STRATEGY_GROUP_ID}
|
||||
data-testid={FLEXIBLE_STRATEGY_GROUP_ID}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -101,7 +101,7 @@ const RolloutSlider = ({
|
||||
getAriaValueText={valuetext}
|
||||
aria-labelledby="discrete-slider-always"
|
||||
step={1}
|
||||
data-test={ROLLOUT_SLIDER_ID}
|
||||
data-testid={ROLLOUT_SLIDER_ID}
|
||||
marks={marks}
|
||||
onChange={onChange}
|
||||
valueLabelDisplay="on"
|
||||
|
@ -100,12 +100,12 @@ const StrategyInputList = ({
|
||||
onChange={onChange}
|
||||
// @ts-expect-error
|
||||
onKeyDown={onKeyDown}
|
||||
data-test={STRATEGY_INPUT_LIST}
|
||||
data-testid={STRATEGY_INPUT_LIST}
|
||||
/>
|
||||
{/* @ts-expect-error */}
|
||||
<Button
|
||||
onClick={setValue}
|
||||
data-test={ADD_TO_STRATEGY_INPUT_LIST}
|
||||
data-testid={ADD_TO_STRATEGY_INPUT_LIST}
|
||||
color="secondary"
|
||||
startIcon={<Add />}
|
||||
>
|
||||
|
@ -97,7 +97,7 @@ export const CreateSegment = () => {
|
||||
name="segment"
|
||||
permission={CREATE_SEGMENT}
|
||||
disabled={!hasValidConstraints || atSegmentValuesLimit}
|
||||
data-test={SEGMENT_CREATE_BTN_ID}
|
||||
data-testid={SEGMENT_CREATE_BTN_ID}
|
||||
/>
|
||||
</SegmentForm>
|
||||
</FormTemplate>
|
||||
|
@ -99,7 +99,7 @@ export const EditSegment = () => {
|
||||
<UpdateButton
|
||||
permission={UPDATE_SEGMENT}
|
||||
disabled={!hasValidConstraints || atSegmentValuesLimit}
|
||||
data-test={SEGMENT_SAVE_BTN_ID}
|
||||
data-testid={SEGMENT_SAVE_BTN_ID}
|
||||
/>
|
||||
</SegmentForm>
|
||||
</FormTemplate>
|
||||
|
@ -55,7 +55,7 @@ export const SegmentDeleteConfirm = ({
|
||||
value={confirmName}
|
||||
label="Segment name"
|
||||
className={styles.deleteInput}
|
||||
data-test={SEGMENT_DIALOG_NAME_ID}
|
||||
data-testid={SEGMENT_DIALOG_NAME_ID}
|
||||
/>
|
||||
</form>
|
||||
</Dialogue>
|
||||
|
@ -48,7 +48,7 @@ export const SegmentFormStepOne: React.FC<ISegmentFormPartOneProps> = ({
|
||||
errorText={errors.name}
|
||||
autoFocus
|
||||
required
|
||||
data-test={SEGMENT_NAME_ID}
|
||||
data-testid={SEGMENT_NAME_ID}
|
||||
/>
|
||||
<p className={styles.inputDescription}>
|
||||
What is the segment description?
|
||||
@ -60,7 +60,7 @@ export const SegmentFormStepOne: React.FC<ISegmentFormPartOneProps> = ({
|
||||
onChange={e => setDescription(e.target.value)}
|
||||
error={Boolean(errors.description)}
|
||||
errorText={errors.description}
|
||||
data-test={SEGMENT_DESC_ID}
|
||||
data-testid={SEGMENT_DESC_ID}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.buttonContainer}>
|
||||
@ -70,7 +70,7 @@ export const SegmentFormStepOne: React.FC<ISegmentFormPartOneProps> = ({
|
||||
color="primary"
|
||||
onClick={() => setCurrentStep(2)}
|
||||
disabled={name.length === 0 || Boolean(errors.name)}
|
||||
data-test={SEGMENT_NEXT_BTN_ID}
|
||||
data-testid={SEGMENT_NEXT_BTN_ID}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
|
@ -102,7 +102,7 @@ export const SegmentsList = () => {
|
||||
<PermissionButton
|
||||
onClick={() => history.push('/segments/create')}
|
||||
permission={CREATE_SEGMENT}
|
||||
data-test={NAVIGATE_TO_CREATE_SEGMENT}
|
||||
data-testid={NAVIGATE_TO_CREATE_SEGMENT}
|
||||
>
|
||||
New Segment
|
||||
</PermissionButton>
|
||||
|
@ -83,7 +83,7 @@ export const SegmentListItem = ({
|
||||
setDelDialog(true);
|
||||
}}
|
||||
permission={ADMIN}
|
||||
data-test={`${SEGMENT_DELETE_BTN_ID}_${name}`}
|
||||
data-testid={`${SEGMENT_DELETE_BTN_ID}_${name}`}
|
||||
>
|
||||
<Delete />
|
||||
</PermissionIconButton>
|
||||
|
@ -73,7 +73,7 @@ export const SplashPageEnvironmentsContent: React.FC<
|
||||
<IconButton
|
||||
className={styles.closeButton}
|
||||
onClick={onClose}
|
||||
data-test={CLOSE_SPLASH}
|
||||
data-testid={CLOSE_SPLASH}
|
||||
>
|
||||
<CloseOutlined titleAccess="Close" />
|
||||
</IconButton>
|
||||
|
@ -69,7 +69,7 @@ export const StrategiesList = () => {
|
||||
condition={smallScreen}
|
||||
show={
|
||||
<PermissionIconButton
|
||||
data-test={ADD_NEW_STRATEGY_ID}
|
||||
data-testid={ADD_NEW_STRATEGY_ID}
|
||||
onClick={() => history.push('/strategies/create')}
|
||||
permission={CREATE_STRATEGY}
|
||||
>
|
||||
@ -81,7 +81,7 @@ export const StrategiesList = () => {
|
||||
onClick={() => history.push('/strategies/create')}
|
||||
color="primary"
|
||||
permission={CREATE_STRATEGY}
|
||||
data-test={ADD_NEW_STRATEGY_ID}
|
||||
data-testid={ADD_NEW_STRATEGY_ID}
|
||||
>
|
||||
New strategy
|
||||
</PermissionButton>
|
||||
|
@ -42,7 +42,7 @@ exports[`renders correctly with one strategy 1`] = `
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
|
||||
data-test="ADD_NEW_STRATEGY_ID"
|
||||
data-testid="ADD_NEW_STRATEGY_ID"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
@ -317,7 +317,7 @@ exports[`renders correctly with one strategy without permissions 1`] = `
|
||||
>
|
||||
<button
|
||||
className="MuiButtonBase-root MuiButton-root MuiButton-contained MuiButton-containedPrimary"
|
||||
data-test="ADD_NEW_STRATEGY_ID"
|
||||
data-testid="ADD_NEW_STRATEGY_ID"
|
||||
disabled={false}
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
|
@ -0,0 +1,135 @@
|
||||
import Authentication from 'component/user/Authentication/Authentication';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import {
|
||||
LOGIN_PASSWORD_ID,
|
||||
LOGIN_EMAIL_ID,
|
||||
LOGIN_BUTTON,
|
||||
AUTH_PAGE_ID,
|
||||
SSO_LOGIN_BUTTON,
|
||||
} from 'utils/testIds';
|
||||
import React from 'react';
|
||||
import { TestContext } from 'utils/testContext';
|
||||
import { testServerSetup, testServerRoute } from 'utils/testServer';
|
||||
|
||||
const server = testServerSetup();
|
||||
|
||||
test('should render password auth', async () => {
|
||||
testServerRoute(server, '*', {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
options: [],
|
||||
});
|
||||
|
||||
render(
|
||||
<TestContext>
|
||||
<Authentication redirect="/" />
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
await screen.findByTestId(AUTH_PAGE_ID);
|
||||
expect(screen.getByTestId(LOGIN_EMAIL_ID)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(LOGIN_PASSWORD_ID)).toBeInTheDocument();
|
||||
expect(screen.getByTestId(LOGIN_BUTTON)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should not render password auth if defaultHidden is true', async () => {
|
||||
testServerRoute(server, '*', {
|
||||
defaultHidden: true,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
options: [],
|
||||
});
|
||||
|
||||
render(
|
||||
<TestContext>
|
||||
<Authentication redirect="/" />
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
await screen.findByTestId(AUTH_PAGE_ID);
|
||||
expect(screen.queryByTestId(LOGIN_EMAIL_ID)).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId(LOGIN_PASSWORD_ID)).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId(LOGIN_BUTTON)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render demo auth', async () => {
|
||||
testServerRoute(server, '*', {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
path: '/auth/demo/login',
|
||||
type: 'demo',
|
||||
options: [],
|
||||
});
|
||||
|
||||
render(
|
||||
<TestContext>
|
||||
<Authentication redirect="/" />
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
await screen.findByTestId(AUTH_PAGE_ID);
|
||||
expect(screen.getByTestId(LOGIN_EMAIL_ID)).toBeInTheDocument();
|
||||
expect(screen.queryByTestId(LOGIN_PASSWORD_ID)).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId(LOGIN_BUTTON)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render email auth', async () => {
|
||||
testServerRoute(server, '*', {
|
||||
defaultHidden: false,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
path: '/auth/unsecure/login',
|
||||
type: 'unsecure',
|
||||
options: [],
|
||||
});
|
||||
|
||||
render(
|
||||
<TestContext>
|
||||
<Authentication redirect="/" />
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
await screen.findByTestId(AUTH_PAGE_ID);
|
||||
expect(screen.getByTestId(LOGIN_EMAIL_ID)).toBeInTheDocument();
|
||||
expect(screen.queryByTestId(LOGIN_PASSWORD_ID)).not.toBeInTheDocument();
|
||||
expect(screen.getByTestId(LOGIN_BUTTON)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render Google auth', async () => {
|
||||
await testSSOAuthOption('google');
|
||||
});
|
||||
|
||||
test('should render OIDC auth', async () => {
|
||||
await testSSOAuthOption('oidc');
|
||||
});
|
||||
|
||||
test('should render SAML auth', async () => {
|
||||
await testSSOAuthOption('saml');
|
||||
});
|
||||
|
||||
const testSSOAuthOption = async (authOption: string) => {
|
||||
const path = `/auth/${authOption}/login`;
|
||||
const testId = `${SSO_LOGIN_BUTTON}-${authOption}`;
|
||||
|
||||
testServerRoute(server, '*', {
|
||||
defaultHidden: true,
|
||||
message: 'You must sign in in order to use Unleash',
|
||||
options: [{ type: authOption, message: '...', path: path }],
|
||||
path: '/auth/simple/login',
|
||||
type: 'password',
|
||||
});
|
||||
|
||||
render(
|
||||
<TestContext>
|
||||
<Authentication redirect="/" />
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
const ssoLink = await screen.findByTestId(testId);
|
||||
expect(ssoLink.getAttribute('href')).toEqual(path);
|
||||
expect(screen.queryByTestId(LOGIN_EMAIL_ID)).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId(LOGIN_PASSWORD_ID)).not.toBeInTheDocument();
|
||||
expect(screen.queryByTestId(LOGIN_BUTTON)).not.toBeInTheDocument();
|
||||
};
|
@ -14,16 +14,20 @@ import useQueryParams from 'hooks/useQueryParams';
|
||||
import ConditionallyRender from 'component/common/ConditionallyRender';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
import { useAuthDetails } from 'hooks/api/getters/useAuth/useAuthDetails';
|
||||
import { AUTH_PAGE_ID } from 'utils/testIds';
|
||||
|
||||
interface IAuthenticationProps {
|
||||
redirect: string;
|
||||
}
|
||||
|
||||
const Authentication = ({ redirect }: IAuthenticationProps) => {
|
||||
const { authDetails } = useAuthDetails();
|
||||
const params = useQueryParams();
|
||||
|
||||
const error = params.get('errorMsg');
|
||||
if (!authDetails) return null;
|
||||
|
||||
if (!authDetails) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let content;
|
||||
if (authDetails.type === PASSWORD_TYPE) {
|
||||
@ -53,9 +57,10 @@ const Authentication = ({ redirect }: IAuthenticationProps) => {
|
||||
} else {
|
||||
content = <AuthenticationCustomComponent authDetails={authDetails} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ maxWidth: '350px' }}>
|
||||
<div style={{ maxWidth: '350px' }} data-testid={AUTH_PAGE_ID}>
|
||||
<ConditionallyRender
|
||||
condition={Boolean(error)}
|
||||
show={<Alert severity="error">{error}</Alert>}
|
||||
|
@ -45,12 +45,12 @@ const DemoAuth = ({ authDetails, redirect }) => {
|
||||
value={email}
|
||||
className={styles.emailField}
|
||||
onChange={handleChange}
|
||||
inputProps={{ 'data-test': 'email-input-field' }}
|
||||
inputProps={{ 'data-testid': 'email-input-field' }}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
label="Email"
|
||||
name="email"
|
||||
data-test={LOGIN_EMAIL_ID}
|
||||
data-testid={LOGIN_EMAIL_ID}
|
||||
required
|
||||
type="email"
|
||||
/>
|
||||
@ -60,7 +60,7 @@ const DemoAuth = ({ authDetails, redirect }) => {
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={styles.button}
|
||||
data-test={LOGIN_BUTTON}
|
||||
data-testid={LOGIN_BUTTON}
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
|
@ -0,0 +1,15 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { FORGOTTEN_PASSWORD_FIELD } from 'utils/testIds';
|
||||
import React from 'react';
|
||||
import { TestContext } from 'utils/testContext';
|
||||
import ForgottenPassword from 'component/user/ForgottenPassword/ForgottenPassword';
|
||||
|
||||
test('should render password auth', async () => {
|
||||
render(
|
||||
<TestContext>
|
||||
<ForgottenPassword />
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
await screen.findByTestId(FORGOTTEN_PASSWORD_FIELD);
|
||||
});
|
@ -96,7 +96,7 @@ const ForgottenPassword = () => {
|
||||
placeholder="email"
|
||||
type="email"
|
||||
data-loading
|
||||
data-test={FORGOTTEN_PASSWORD_FIELD}
|
||||
data-testid={FORGOTTEN_PASSWORD_FIELD}
|
||||
value={email}
|
||||
onChange={e => {
|
||||
setEmail(e.target.value);
|
||||
|
@ -109,7 +109,7 @@ const HostedAuth = ({ authDetails, redirect }) => {
|
||||
helperText={usernameError}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
data-test={LOGIN_EMAIL_ID}
|
||||
data-testid={LOGIN_EMAIL_ID}
|
||||
/>
|
||||
<PasswordField
|
||||
label="Password"
|
||||
@ -118,7 +118,7 @@ const HostedAuth = ({ authDetails, redirect }) => {
|
||||
value={password}
|
||||
error={!!passwordError}
|
||||
helperText={passwordError}
|
||||
data-test={LOGIN_PASSWORD_ID}
|
||||
data-testid={LOGIN_PASSWORD_ID}
|
||||
/>
|
||||
<Grid container>
|
||||
<Button
|
||||
@ -126,7 +126,7 @@ const HostedAuth = ({ authDetails, redirect }) => {
|
||||
color="primary"
|
||||
type="submit"
|
||||
className={styles.button}
|
||||
data-test={LOGIN_BUTTON}
|
||||
data-testid={LOGIN_BUTTON}
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
|
@ -108,7 +108,7 @@ const PasswordAuth = ({ authDetails, redirect }) => {
|
||||
error={!!usernameError}
|
||||
helperText={usernameError}
|
||||
autoComplete="true"
|
||||
data-test={LOGIN_EMAIL_ID}
|
||||
data-testid={LOGIN_EMAIL_ID}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
/>
|
||||
@ -120,14 +120,14 @@ const PasswordAuth = ({ authDetails, redirect }) => {
|
||||
error={!!passwordError}
|
||||
helperText={passwordError}
|
||||
autoComplete="true"
|
||||
data-test={LOGIN_PASSWORD_ID}
|
||||
data-testid={LOGIN_PASSWORD_ID}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
type="submit"
|
||||
style={{ width: '150px', margin: '1rem auto' }}
|
||||
data-test={LOGIN_BUTTON}
|
||||
data-testid={LOGIN_BUTTON}
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
|
@ -0,0 +1,26 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { INVALID_TOKEN_BUTTON } from 'utils/testIds';
|
||||
import React from 'react';
|
||||
import { TestContext } from 'utils/testContext';
|
||||
import ResetPassword from 'component/user/ResetPassword/ResetPassword';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { INVALID_TOKEN_ERROR } from 'hooks/api/getters/useResetPassword/useResetPassword';
|
||||
import { testServerSetup, testServerRoute } from 'utils/testServer';
|
||||
|
||||
const server = testServerSetup();
|
||||
|
||||
test('should render password auth', async () => {
|
||||
testServerRoute(server, '/auth/reset/validate', {
|
||||
name: INVALID_TOKEN_ERROR,
|
||||
});
|
||||
|
||||
render(
|
||||
<TestContext>
|
||||
<MemoryRouter initialEntries={['/new-user?token=invalid']}>
|
||||
<ResetPassword />
|
||||
</MemoryRouter>
|
||||
</TestContext>
|
||||
);
|
||||
|
||||
await screen.findByTestId(INVALID_TOKEN_BUTTON);
|
||||
});
|
@ -51,14 +51,14 @@ const SimpleAuth = ({ authDetails, redirect }) => {
|
||||
<TextField
|
||||
value={email}
|
||||
onChange={handleChange}
|
||||
inputProps={{ 'data-test': 'email-input-field' }}
|
||||
inputProps={{ 'data-testid': 'email-input-field' }}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
label="Email"
|
||||
name="email"
|
||||
required
|
||||
type="email"
|
||||
data-test={LOGIN_EMAIL_ID}
|
||||
data-testid={LOGIN_EMAIL_ID}
|
||||
/>
|
||||
<br />
|
||||
|
||||
@ -68,7 +68,7 @@ const SimpleAuth = ({ authDetails, redirect }) => {
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={styles.button}
|
||||
data-test={LOGIN_BUTTON}
|
||||
data-testid={LOGIN_BUTTON}
|
||||
>
|
||||
Sign in
|
||||
</Button>
|
||||
|
@ -71,7 +71,7 @@ const UserProfile = ({
|
||||
<Avatar
|
||||
alt="user image"
|
||||
src={imageUrl}
|
||||
data-test={HEADER_USER_AVATAR}
|
||||
data-testid={HEADER_USER_AVATAR}
|
||||
/>
|
||||
<KeyboardArrowDownIcon />
|
||||
</Button>
|
||||
|
@ -29,7 +29,7 @@ const AuthOptions = ({ options }: IAuthOptionProps) => {
|
||||
variant="outlined"
|
||||
href={o.path}
|
||||
size="small"
|
||||
data-test={`${SSO_LOGIN_BUTTON}-${o.type}`}
|
||||
data-testid={`${SSO_LOGIN_BUTTON}-${o.type}`}
|
||||
style={{ height: '40px', color: '#000' }}
|
||||
startIcon={
|
||||
<ConditionallyRender
|
||||
|
@ -27,7 +27,7 @@ const InvalidToken = () => {
|
||||
color="primary"
|
||||
component={Link}
|
||||
to="forgotten-password"
|
||||
data-test={INVALID_TOKEN_BUTTON}
|
||||
data-testid={INVALID_TOKEN_BUTTON}
|
||||
>
|
||||
Reset password
|
||||
</Button>
|
||||
|
@ -11,7 +11,7 @@ const getFetcher = (token: string) => () => {
|
||||
}).then(res => res.json());
|
||||
};
|
||||
|
||||
const INVALID_TOKEN_ERROR = 'InvalidTokenError';
|
||||
export const INVALID_TOKEN_ERROR = 'InvalidTokenError';
|
||||
const USED_TOKEN_ERROR = 'UsedTokenError';
|
||||
|
||||
const useResetPassword = (options: SWRConfiguration = {}) => {
|
||||
|
15
frontend/src/utils/testContext.tsx
Normal file
15
frontend/src/utils/testContext.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { SWRConfig } from 'swr';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { ThemeProvider } from '@material-ui/core/styles';
|
||||
import theme from 'themes/mainTheme';
|
||||
import React from 'react';
|
||||
|
||||
export const TestContext: React.FC = ({ children }) => {
|
||||
return (
|
||||
<SWRConfig value={{ provider: () => new Map() }}>
|
||||
<MemoryRouter>
|
||||
<ThemeProvider theme={theme}>{children}</ThemeProvider>
|
||||
</MemoryRouter>
|
||||
</SWRConfig>
|
||||
);
|
||||
};
|
@ -48,3 +48,4 @@ export const CLOSE_SPLASH = 'CLOSE_SPLASH';
|
||||
export const INPUT_ERROR_TEXT = 'INPUT_ERROR_TEXT';
|
||||
export const HEADER_USER_AVATAR = 'HEADER_USER_AVATAR';
|
||||
export const SIDEBAR_MODAL_ID = 'SIDEBAR_MODAL_ID';
|
||||
export const AUTH_PAGE_ID = 'AUTH_PAGE_ID';
|
||||
|
24
frontend/src/utils/testServer.ts
Normal file
24
frontend/src/utils/testServer.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { SetupServerApi, setupServer } from 'msw/node';
|
||||
import { rest } from 'msw';
|
||||
|
||||
export const testServerSetup = (): SetupServerApi => {
|
||||
const server = setupServer();
|
||||
|
||||
beforeAll(() => server.listen());
|
||||
afterAll(() => server.close());
|
||||
afterEach(() => server.resetHandlers());
|
||||
|
||||
return server;
|
||||
};
|
||||
|
||||
export const testServerRoute = (
|
||||
server: SetupServerApi,
|
||||
path: string,
|
||||
json: object
|
||||
) => {
|
||||
server.use(
|
||||
rest.get(path, (req, res, ctx) => {
|
||||
return res(ctx.json(json));
|
||||
})
|
||||
);
|
||||
};
|
@ -1482,6 +1482,26 @@
|
||||
prop-types "^15.7.2"
|
||||
react-is "^16.8.0 || ^17.0.0"
|
||||
|
||||
"@mswjs/cookies@^0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@mswjs/cookies/-/cookies-0.2.0.tgz#7ef2b5d7e444498bb27cf57720e61f76a4ce9f23"
|
||||
integrity sha512-GTKYnIfXVP8GL8HRWrse+ujqDXCLKvu7+JoL6pvZFzS/d2i9pziByoWD69cOe35JNoSrx2DPNqrhUF+vgV3qUA==
|
||||
dependencies:
|
||||
"@types/set-cookie-parser" "^2.4.0"
|
||||
set-cookie-parser "^2.4.6"
|
||||
|
||||
"@mswjs/interceptors@^0.15.1":
|
||||
version "0.15.1"
|
||||
resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.15.1.tgz#4a0009f56e51bc2cd3176f1507065c7d2f6c0d5e"
|
||||
integrity sha512-D5B+ZJNlfvBm6ZctAfRBdNJdCHYAe2Ix4My5qfbHV5WH+3lkt3mmsjiWJzEh5ZwGDauzY487TldI275If7DJVw==
|
||||
dependencies:
|
||||
"@open-draft/until" "^1.0.3"
|
||||
"@xmldom/xmldom" "^0.7.5"
|
||||
debug "^4.3.3"
|
||||
headers-polyfill "^3.0.4"
|
||||
outvariant "^1.2.1"
|
||||
strict-event-emitter "^0.2.0"
|
||||
|
||||
"@nodelib/fs.scandir@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
|
||||
@ -1503,6 +1523,11 @@
|
||||
"@nodelib/fs.scandir" "2.1.5"
|
||||
fastq "^1.6.0"
|
||||
|
||||
"@open-draft/until@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-1.0.3.tgz#db9cc719191a62e7d9200f6e7bab21c5b848adca"
|
||||
integrity sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==
|
||||
|
||||
"@pmmmwh/react-refresh-webpack-plugin@^0.5.3":
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz#e77aac783bd079f548daa0a7f080ab5b5a9741ca"
|
||||
@ -1848,6 +1873,11 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/cookie@^0.4.1":
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d"
|
||||
integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==
|
||||
|
||||
"@types/debounce@1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/debounce/-/debounce-1.2.1.tgz#79b65710bc8b6d44094d286aecf38e44f9627852"
|
||||
@ -1962,6 +1992,11 @@
|
||||
jest-matcher-utils "^27.0.0"
|
||||
pretty-format "^27.0.0"
|
||||
|
||||
"@types/js-levenshtein@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz#ba05426a43f9e4e30b631941e0aa17bf0c890ed5"
|
||||
integrity sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==
|
||||
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
|
||||
version "7.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
|
||||
@ -2141,6 +2176,13 @@
|
||||
"@types/mime" "^1"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/set-cookie-parser@^2.4.0":
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz#b6a955219b54151bfebd4521170723df5e13caad"
|
||||
integrity sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/sinonjs__fake-timers@8.1.1":
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3"
|
||||
@ -2409,6 +2451,11 @@
|
||||
"@webassemblyjs/ast" "1.11.1"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@xmldom/xmldom@^0.7.5":
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d"
|
||||
integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||
@ -2950,6 +2997,15 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
bl@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
||||
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
|
||||
dependencies:
|
||||
buffer "^5.5.0"
|
||||
inherits "^2.0.4"
|
||||
readable-stream "^3.4.0"
|
||||
|
||||
blob-util@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb"
|
||||
@ -3039,7 +3095,7 @@ buffer-from@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer@^5.6.0:
|
||||
buffer@^5.5.0, buffer@^5.6.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
|
||||
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
|
||||
@ -3128,6 +3184,14 @@ caseless@~0.12.0:
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
chalk@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
|
||||
integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.4.1:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
@ -3145,7 +3209,7 @@ chalk@^3.0.0:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
|
||||
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
@ -3168,6 +3232,11 @@ charcodes@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/charcodes/-/charcodes-0.2.0.tgz#5208d327e6cc05f99eb80ffc814707572d1f14e4"
|
||||
integrity sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ==
|
||||
|
||||
chardet@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||
|
||||
chart.js@3.7.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.7.1.tgz#0516f690c6a8680c6c707e31a4c1807a6f400ada"
|
||||
@ -3242,6 +3311,11 @@ cli-cursor@^3.1.0:
|
||||
dependencies:
|
||||
restore-cursor "^3.1.0"
|
||||
|
||||
cli-spinners@^2.5.0:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d"
|
||||
integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==
|
||||
|
||||
cli-table3@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.1.tgz#36ce9b7af4847f288d3cdd081fbd09bf7bd237b8"
|
||||
@ -3259,6 +3333,11 @@ cli-truncate@^2.1.0:
|
||||
slice-ansi "^3.0.0"
|
||||
string-width "^4.2.0"
|
||||
|
||||
cli-width@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
|
||||
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
@ -3268,6 +3347,11 @@ cliui@^7.0.2:
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
clone@^1.0.2:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
|
||||
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
|
||||
|
||||
clsx@^1.0.4:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||
@ -3432,7 +3516,7 @@ cookie-signature@1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
|
||||
integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw=
|
||||
|
||||
cookie@0.4.2:
|
||||
cookie@0.4.2, cookie@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
|
||||
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
|
||||
@ -3816,7 +3900,7 @@ debug@2.6.9, debug@^2.6.0, debug@^2.6.9:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2:
|
||||
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||
@ -3867,6 +3951,13 @@ default-gateway@^6.0.3:
|
||||
dependencies:
|
||||
execa "^5.0.0"
|
||||
|
||||
defaults@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
|
||||
integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=
|
||||
dependencies:
|
||||
clone "^1.0.2"
|
||||
|
||||
define-lazy-prop@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
|
||||
@ -4520,7 +4611,7 @@ eventemitter3@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
events@^3.2.0:
|
||||
events@^3.2.0, events@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
@ -4618,6 +4709,15 @@ extend@~3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
|
||||
external-editor@^3.0.3:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
|
||||
integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
|
||||
dependencies:
|
||||
chardet "^0.7.0"
|
||||
iconv-lite "^0.4.24"
|
||||
tmp "^0.0.33"
|
||||
|
||||
extract-zip@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
|
||||
@ -4698,7 +4798,7 @@ fd-slicer@~1.1.0:
|
||||
dependencies:
|
||||
pend "~1.2.0"
|
||||
|
||||
figures@^3.2.0:
|
||||
figures@^3.0.0, figures@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
|
||||
integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==
|
||||
@ -5056,6 +5156,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4,
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c"
|
||||
integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==
|
||||
|
||||
graphql@^16.3.0:
|
||||
version "16.3.0"
|
||||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.3.0.tgz#a91e24d10babf9e60c706919bb182b53ccdffc05"
|
||||
integrity sha512-xm+ANmA16BzCT5pLjuXySbQVFwH3oJctUVdy81w1sV0vBU0KgDdBGtxQOUd5zqOBk/JayAFeG8Dlmeq74rjm/A==
|
||||
|
||||
gzip-size@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462"
|
||||
@ -5112,6 +5217,11 @@ he@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
||||
headers-polyfill@^3.0.4:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-3.0.7.tgz#725c4f591e6748f46b036197eae102c92b959ff4"
|
||||
integrity sha512-JoLCAdCEab58+2/yEmSnOlficyHFpIl0XJqwu3l+Unkm1gXpFUYsThz6Yha3D6tNhocWkCPfyW0YVIGWFqTi7w==
|
||||
|
||||
history@^4.9.0:
|
||||
version "4.10.1"
|
||||
resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3"
|
||||
@ -5289,7 +5399,7 @@ hyphenate-style-name@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
||||
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
||||
|
||||
iconv-lite@0.4.24:
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
@ -5394,6 +5504,26 @@ ini@^1.3.5:
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||
|
||||
inquirer@^8.2.0:
|
||||
version "8.2.2"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.2.tgz#1310517a87a0814d25336c78a20b44c3d9b7629d"
|
||||
integrity sha512-pG7I/si6K/0X7p1qU+rfWnpTE1UIkTONN1wxtzh0d+dHXtT/JG6qBgLxoyHVsQa8cFABxAPh0pD6uUUHiAoaow==
|
||||
dependencies:
|
||||
ansi-escapes "^4.2.1"
|
||||
chalk "^4.1.1"
|
||||
cli-cursor "^3.1.0"
|
||||
cli-width "^3.0.0"
|
||||
external-editor "^3.0.3"
|
||||
figures "^3.0.0"
|
||||
lodash "^4.17.21"
|
||||
mute-stream "0.0.8"
|
||||
ora "^5.4.1"
|
||||
run-async "^2.4.0"
|
||||
rxjs "^7.5.5"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
internal-slot@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
|
||||
@ -5506,6 +5636,11 @@ is-installed-globally@~0.4.0:
|
||||
global-dirs "^3.0.0"
|
||||
is-path-inside "^3.0.2"
|
||||
|
||||
is-interactive@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
|
||||
integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
|
||||
|
||||
is-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||
@ -5516,6 +5651,11 @@ is-negative-zero@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
|
||||
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
|
||||
|
||||
is-node-process@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.0.1.tgz#4fc7ac3a91e8aac58175fe0578abbc56f2831b23"
|
||||
integrity sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==
|
||||
|
||||
is-number-object@^1.0.4:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc"
|
||||
@ -6115,6 +6255,11 @@ jest@^27.4.3:
|
||||
import-local "^3.0.2"
|
||||
jest-cli "^27.5.1"
|
||||
|
||||
js-levenshtein@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
|
||||
integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
@ -6498,7 +6643,7 @@ lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
log-symbols@^4.0.0:
|
||||
log-symbols@^4.0.0, log-symbols@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
|
||||
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
|
||||
@ -6535,11 +6680,6 @@ lru-cache@^7.4.0:
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.7.3.tgz#98cd19eef89ce6a4a3c4502c17c833888677c252"
|
||||
integrity sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==
|
||||
|
||||
lru-cache@^7.4.0:
|
||||
version "7.7.3"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.7.3.tgz#98cd19eef89ce6a4a3c4502c17c833888677c252"
|
||||
integrity sha512-WY9wjJNQt9+PZilnLbuFKM+SwDull9+6IAguOrarOMoOHTcJ9GnXSO11+Gw6c7xtDkBkthR57OZMtZKYr+1CEw==
|
||||
|
||||
lz-string@^1.4.4:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
|
||||
@ -6704,6 +6844,31 @@ ms@2.1.3, ms@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
msw@^0.39.2:
|
||||
version "0.39.2"
|
||||
resolved "https://registry.yarnpkg.com/msw/-/msw-0.39.2.tgz#832e9274db62c43cb79854d5a69dce031c700de8"
|
||||
integrity sha512-ju/HpqQpE4/qCxZ23t5Gaau0KREn4QuFzdG28nP1EpidMrymMJuIvNd32+2uGTGG031PMwrC41YW7vCxHOwyHA==
|
||||
dependencies:
|
||||
"@mswjs/cookies" "^0.2.0"
|
||||
"@mswjs/interceptors" "^0.15.1"
|
||||
"@open-draft/until" "^1.0.3"
|
||||
"@types/cookie" "^0.4.1"
|
||||
"@types/js-levenshtein" "^1.1.1"
|
||||
chalk "4.1.1"
|
||||
chokidar "^3.4.2"
|
||||
cookie "^0.4.2"
|
||||
graphql "^16.3.0"
|
||||
headers-polyfill "^3.0.4"
|
||||
inquirer "^8.2.0"
|
||||
is-node-process "^1.0.1"
|
||||
js-levenshtein "^1.1.6"
|
||||
node-fetch "^2.6.7"
|
||||
path-to-regexp "^6.2.0"
|
||||
statuses "^2.0.0"
|
||||
strict-event-emitter "^0.2.0"
|
||||
type-fest "^1.2.2"
|
||||
yargs "^17.3.1"
|
||||
|
||||
multicast-dns@^7.2.4:
|
||||
version "7.2.4"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.4.tgz#cf0b115c31e922aeb20b64e6556cbeb34cf0dd19"
|
||||
@ -6712,6 +6877,11 @@ multicast-dns@^7.2.4:
|
||||
dns-packet "^5.2.2"
|
||||
thunky "^1.0.2"
|
||||
|
||||
mute-stream@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
||||
|
||||
nanoid@^3.3.1:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557"
|
||||
@ -6740,6 +6910,13 @@ no-case@^3.0.4:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
node-fetch@^2.6.7:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-forge@^1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
|
||||
@ -6934,11 +7111,36 @@ optionator@^0.9.1:
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.3"
|
||||
|
||||
ora@^5.4.1:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18"
|
||||
integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==
|
||||
dependencies:
|
||||
bl "^4.1.0"
|
||||
chalk "^4.1.0"
|
||||
cli-cursor "^3.1.0"
|
||||
cli-spinners "^2.5.0"
|
||||
is-interactive "^1.0.0"
|
||||
is-unicode-supported "^0.1.0"
|
||||
log-symbols "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wcwidth "^1.0.1"
|
||||
|
||||
os-tmpdir@~1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
|
||||
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
|
||||
|
||||
ospath@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b"
|
||||
integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=
|
||||
|
||||
outvariant@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.3.0.tgz#c39723b1d2cba729c930b74bf962317a81b9b1c9"
|
||||
integrity sha512-yeWM9k6UPfG/nzxdaPlJkB2p08hCg4xP6Lx99F+vP8YF7xyZVfTmJjrrNalkmzudD4WFvNLVudQikqUmF8zhVQ==
|
||||
|
||||
p-limit@^1.1.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
|
||||
@ -7093,6 +7295,11 @@ path-to-regexp@^1.7.0:
|
||||
dependencies:
|
||||
isarray "0.0.1"
|
||||
|
||||
path-to-regexp@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38"
|
||||
integrity sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==
|
||||
|
||||
path-type@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
|
||||
@ -8097,7 +8304,7 @@ readable-stream@^2.0.1:
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.0.6:
|
||||
readable-stream@^3.0.6, readable-stream@^3.4.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
@ -8341,6 +8548,11 @@ rollup@^2.43.1:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
run-async@^2.4.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
|
||||
integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
|
||||
|
||||
run-parallel@^1.1.9:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
|
||||
@ -8348,7 +8560,7 @@ run-parallel@^1.1.9:
|
||||
dependencies:
|
||||
queue-microtask "^1.2.2"
|
||||
|
||||
rxjs@^7.5.1:
|
||||
rxjs@^7.5.1, rxjs@^7.5.5:
|
||||
version "7.5.5"
|
||||
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f"
|
||||
integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==
|
||||
@ -8466,7 +8678,7 @@ semver@7.0.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
|
||||
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
|
||||
|
||||
semver@7.3.6:
|
||||
semver@7.3.6, semver@^7.3.2, semver@^7.3.5:
|
||||
version "7.3.6"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b"
|
||||
integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==
|
||||
@ -8478,13 +8690,6 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.3.2, semver@^7.3.5:
|
||||
version "7.3.6"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b"
|
||||
integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w==
|
||||
dependencies:
|
||||
lru-cache "^7.4.0"
|
||||
|
||||
send@0.17.2:
|
||||
version "0.17.2"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820"
|
||||
@ -8541,6 +8746,11 @@ serve-static@1.14.2:
|
||||
parseurl "~1.3.3"
|
||||
send "0.17.2"
|
||||
|
||||
set-cookie-parser@^2.4.6:
|
||||
version "2.4.8"
|
||||
resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz#d0da0ed388bc8f24e706a391f9c9e252a13c58b2"
|
||||
integrity sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==
|
||||
|
||||
setprototypeof@1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
|
||||
@ -8751,6 +8961,18 @@ stackframe@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
|
||||
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
|
||||
|
||||
statuses@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
|
||||
|
||||
strict-event-emitter@^0.2.0:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.4.tgz#365714f0c95f059db31064ca745d5b33e5b30f6e"
|
||||
integrity sha512-xIqTLS5azUH1djSUsLH9DbP6UnM/nI18vu8d43JigCQEoVsnY+mrlE+qv6kYqs6/1OkMnMIiL6ffedQSZStuoQ==
|
||||
dependencies:
|
||||
events "^3.3.0"
|
||||
|
||||
string-length@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
|
||||
@ -8772,7 +8994,7 @@ string-natural-compare@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4"
|
||||
integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0:
|
||||
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@ -9079,7 +9301,7 @@ throttleit@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c"
|
||||
integrity sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=
|
||||
|
||||
through@^2.3.8:
|
||||
through@^2.3.6, through@^2.3.8:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
@ -9099,6 +9321,13 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
|
||||
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
|
||||
|
||||
tmp@^0.0.33:
|
||||
version "0.0.33"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
|
||||
integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
tmp@~0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
|
||||
@ -9164,6 +9393,11 @@ tr46@^2.1.0:
|
||||
dependencies:
|
||||
punycode "^2.1.1"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||
|
||||
tryer@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||
@ -9242,6 +9476,11 @@ type-fest@^0.21.3:
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
|
||||
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
|
||||
|
||||
type-fest@^1.2.2:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1"
|
||||
integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==
|
||||
|
||||
type-is@~1.6.18:
|
||||
version "1.6.18"
|
||||
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
|
||||
@ -9438,6 +9677,18 @@ wbuf@^1.1.0, wbuf@^1.7.3:
|
||||
dependencies:
|
||||
minimalistic-assert "^1.0.0"
|
||||
|
||||
wcwidth@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
|
||||
integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=
|
||||
dependencies:
|
||||
defaults "^1.0.3"
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||
|
||||
webidl-conversions@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
@ -9589,6 +9840,14 @@ whatwg-mimetype@^2.3.0:
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"
|
||||
@ -9879,6 +10138,11 @@ yargs-parser@^20.2.2:
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs-parser@^21.0.0:
|
||||
version "21.0.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35"
|
||||
integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==
|
||||
|
||||
yargs@^16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
@ -9892,6 +10156,19 @@ yargs@^16.2.0:
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yargs@^17.3.1:
|
||||
version "17.4.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.0.tgz#9fc9efc96bd3aa2c1240446af28499f0e7593d00"
|
||||
integrity sha512-WJudfrk81yWFSOkZYpAZx4Nt7V4xp7S/uJkX0CnxovMCt1wCE8LNftPpNuF9X/u9gN5nsD7ycYtRcDf2pL3UiA==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.3"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^21.0.0"
|
||||
|
||||
yauzl@^2.10.0:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
|
||||
|
Loading…
Reference in New Issue
Block a user