mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 17:58:43 -05:00
test: Migration to jest (#935)
* jest initialised * refactor: `connect()` and `openApp()` * test: integrate to jest * chore: renaming jests test commands * chore: adding override rule for non `commands/serve` directories to skip jest rules
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"root": true,
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true
|
"browser": true,
|
||||||
|
"jest/globals": true
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"extends": ["airbnb", "prettier"],
|
"extends": ["airbnb", "prettier"],
|
||||||
"plugins": ["prettier"],
|
"plugins": ["prettier", "jest"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"max-len": 0,
|
"max-len": 0,
|
||||||
"no-plusplus": 0,
|
"no-plusplus": 0,
|
||||||
@@ -18,12 +19,24 @@
|
|||||||
"react/prop-types": 0,
|
"react/prop-types": 0,
|
||||||
"react/no-deprecated": 0,
|
"react/no-deprecated": 0,
|
||||||
"import/no-extraneous-dependencies": [2, { "devDependencies": true }],
|
"import/no-extraneous-dependencies": [2, { "devDependencies": true }],
|
||||||
"import/no-dynamic-require": 0
|
"import/no-dynamic-require": 0,
|
||||||
|
"jest/no-disabled-tests": "warn",
|
||||||
|
"jest/no-focused-tests": "error",
|
||||||
|
"jest/no-identical-title": "error",
|
||||||
|
"jest/prefer-to-have-length": "warn",
|
||||||
|
"jest/valid-expect": "error"
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"__NEBULA_DEV__": false
|
"__NEBULA_DEV__": false
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["apis/**/*", "packages/**/*", "commands/create/**/*", "commands/sense/src/**/*"],
|
||||||
|
"rules": {
|
||||||
|
"jest/valid-expect": 0,
|
||||||
|
"jest/no-identical-title": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"files": ["scripts/**/*", "**/apis/*/scripts/**/*"],
|
"files": ["scripts/**/*", "**/apis/*/scripts/**/*"],
|
||||||
"rules": {
|
"rules": {
|
||||||
|
|||||||
@@ -2,15 +2,7 @@ module.exports = {
|
|||||||
env: {
|
env: {
|
||||||
test: {
|
test: {
|
||||||
presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
|
presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
|
||||||
plugins: [
|
plugins: ['@babel/plugin-transform-react-jsx'],
|
||||||
['@babel/plugin-transform-react-jsx'],
|
|
||||||
[
|
|
||||||
'istanbul',
|
|
||||||
{
|
|
||||||
exclude: ['**/test/**', '**/__test__/**', '**/dist/**'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import Step from '@mui/material/Step';
|
|||||||
import StepLabel from '@mui/material/StepLabel';
|
import StepLabel from '@mui/material/StepLabel';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
|
|
||||||
import { info as connectionInfo, connect } from '../connect';
|
import { getConnectionInfo, connect } from '../connect';
|
||||||
import storageFn from '../storage';
|
import storageFn from '../storage';
|
||||||
|
|
||||||
const storage = storageFn({});
|
const storage = storageFn({});
|
||||||
@@ -268,7 +268,7 @@ export default function Hub() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
connectionInfo.then((i) => {
|
getConnectionInfo().then((i) => {
|
||||||
if (i.enigma.appId) {
|
if (i.enigma.appId) {
|
||||||
window.location.href = `/dev/${window.location.search}`;
|
window.location.href = `/dev/${window.location.search}`;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -61,51 +61,37 @@ const parseEngineURL = (url) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const connectionInfo = fetch('/info')
|
const getConnectionInfo = () =>
|
||||||
.then((response) => response.json())
|
fetch('/info')
|
||||||
.then(async (n) => {
|
.then((response) => response.json())
|
||||||
let info = n;
|
.then(async (n) => {
|
||||||
if (params.engine_url) {
|
let info = n;
|
||||||
info = {
|
if (params.engine_url) {
|
||||||
|
info = {
|
||||||
|
...info,
|
||||||
|
...parseEngineURL(params.engine_url),
|
||||||
|
};
|
||||||
|
} else if (params.app) {
|
||||||
|
info = {
|
||||||
|
...info,
|
||||||
|
enigma: {
|
||||||
|
...info.enigma,
|
||||||
|
appId: params.app,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (params['qlik-web-integration-id']) {
|
||||||
|
info.webIntegrationId = params['qlik-web-integration-id'];
|
||||||
|
}
|
||||||
|
if (info.invalid) {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
const rootPath = `${info.enigma.secure ? 'https' : 'http'}://${info.enigma.host}`;
|
||||||
|
return {
|
||||||
...info,
|
...info,
|
||||||
...parseEngineURL(params.engine_url),
|
rootPath,
|
||||||
};
|
};
|
||||||
} else if (params.app) {
|
});
|
||||||
info = {
|
|
||||||
...info,
|
|
||||||
enigma: {
|
|
||||||
...info.enigma,
|
|
||||||
appId: params.app,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (params['qlik-web-integration-id']) {
|
|
||||||
info.webIntegrationId = params['qlik-web-integration-id'];
|
|
||||||
}
|
|
||||||
if (info.invalid) {
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
const rootPath = `${info.enigma.secure ? 'https' : 'http'}://${info.enigma.host}`;
|
|
||||||
return {
|
|
||||||
...info,
|
|
||||||
rootPath,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
let headers;
|
|
||||||
|
|
||||||
const getHeaders = (authInstance) => {
|
|
||||||
if (!authInstance) return 401;
|
|
||||||
headers = {
|
|
||||||
'qlik-web-integration-id': authInstance.config.webIntegrationId,
|
|
||||||
'qlik-csrf-token': authInstance.config.csrfToken,
|
|
||||||
};
|
|
||||||
return headers;
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultConfig = {
|
|
||||||
secure: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
const getAuthInstance = ({ webIntegrationId, host }) => {
|
const getAuthInstance = ({ webIntegrationId, host }) => {
|
||||||
const authInstance = new Auth({
|
const authInstance = new Auth({
|
||||||
@@ -118,69 +104,73 @@ const getAuthInstance = ({ webIntegrationId, host }) => {
|
|||||||
return authInstance;
|
return authInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
let connection;
|
const connect = async () => {
|
||||||
const connect = () => {
|
try {
|
||||||
if (!connection) {
|
const {
|
||||||
connection = connectionInfo.then(({ webIntegrationId, enigma: enigmaInfo, enigma: { host } }) => {
|
webIntegrationId,
|
||||||
if (webIntegrationId) {
|
enigma: enigmaInfo,
|
||||||
const authInstance = getAuthInstance({ webIntegrationId, host });
|
enigma: { host },
|
||||||
if (!headers) headers = getHeaders(authInstance);
|
} = await getConnectionInfo();
|
||||||
if (headers === 401) return { status: 401 };
|
|
||||||
|
|
||||||
return {
|
|
||||||
getDocList: async () => {
|
|
||||||
const url = `/items?resourceType=app&limit=30&sort=-updatedAt`;
|
|
||||||
const { data = [] } = await (await authInstance.rest(url)).json();
|
|
||||||
return data.map((d) => ({
|
|
||||||
qDocId: d.resourceId,
|
|
||||||
qTitle: d.name,
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
getConfiguration: async () => ({}),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = SenseUtilities.buildUrl({
|
|
||||||
...defaultConfig,
|
|
||||||
...enigmaInfo,
|
|
||||||
});
|
|
||||||
|
|
||||||
return enigma
|
|
||||||
.create({
|
|
||||||
schema: qixSchema,
|
|
||||||
url,
|
|
||||||
})
|
|
||||||
.open();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return connection;
|
|
||||||
};
|
|
||||||
|
|
||||||
const openApp = (id) =>
|
|
||||||
connectionInfo.then(async ({ webIntegrationId, enigma: enigmaInfo, enigma: { host } }) => {
|
|
||||||
let urlParams = {};
|
|
||||||
if (webIntegrationId) {
|
if (webIntegrationId) {
|
||||||
const authInstance = getAuthInstance({ webIntegrationId, host });
|
const authInstance = getAuthInstance({ webIntegrationId, host });
|
||||||
|
|
||||||
if (!headers) headers = getHeaders(authInstance);
|
return {
|
||||||
urlParams = { ...headers };
|
getDocList: async () => {
|
||||||
|
const url = `/items?resourceType=app&limit=30&sort=-updatedAt`;
|
||||||
|
const { data = [] } = await (await authInstance.rest(url)).json();
|
||||||
|
return data.map((d) => ({
|
||||||
|
qDocId: d.resourceId,
|
||||||
|
qTitle: d.name,
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
getConfiguration: async () => ({}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const url = SenseUtilities.buildUrl({
|
||||||
|
secure: false,
|
||||||
|
...enigmaInfo,
|
||||||
|
});
|
||||||
|
|
||||||
|
return enigma
|
||||||
|
.create({
|
||||||
|
schema: qixSchema,
|
||||||
|
url,
|
||||||
|
})
|
||||||
|
.open();
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error('Failed to return enigma instance');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const openApp = async (id) => {
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
webIntegrationId,
|
||||||
|
enigma: enigmaInfo,
|
||||||
|
enigma: { host },
|
||||||
|
} = await getConnectionInfo();
|
||||||
|
|
||||||
|
if (webIntegrationId) {
|
||||||
|
const authInstance = getAuthInstance({ webIntegrationId, host });
|
||||||
const url = await authInstance.generateWebsocketUrl(id);
|
const url = await authInstance.generateWebsocketUrl(id);
|
||||||
const enigmaGlobal = await enigma.create({ schema: qixSchema, url }).open();
|
const enigmaGlobal = await enigma.create({ schema: qixSchema, url }).open();
|
||||||
return enigmaGlobal.openDoc(id);
|
return enigmaGlobal.openDoc(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const url = SenseUtilities.buildUrl({
|
const url = SenseUtilities.buildUrl({
|
||||||
...defaultConfig,
|
secure: false,
|
||||||
...enigmaInfo,
|
...enigmaInfo,
|
||||||
urlParams,
|
urlParams: {},
|
||||||
appId: id,
|
appId: id,
|
||||||
});
|
});
|
||||||
return enigma
|
return enigma
|
||||||
.create({ schema: qixSchema, url })
|
.create({ schema: qixSchema, url })
|
||||||
.open()
|
.open()
|
||||||
.then((global) => global.openDoc(id));
|
.then((global) => global.openDoc(id));
|
||||||
});
|
} catch (error) {
|
||||||
|
throw new Error('Failed to open app!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export { connect, openApp, params, connectionInfo as info };
|
export { connect, openApp, params, getConnectionInfo, getAuthInstance };
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import ReactDOM from 'react-dom';
|
|||||||
|
|
||||||
import App from './components/App';
|
import App from './components/App';
|
||||||
|
|
||||||
import { openApp, info } from './connect';
|
import { openApp, getConnectionInfo } from './connect';
|
||||||
import initiateWatch from './hot';
|
import initiateWatch from './hot';
|
||||||
|
|
||||||
info.then(($) => {
|
getConnectionInfo().then(($) => {
|
||||||
if (!$.enigma.appId) {
|
if (!$.enigma.appId) {
|
||||||
window.location.href = `/${window.location.search}`;
|
window.location.href = `/${window.location.search}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { embed } from '@nebula.js/stardust';
|
import { embed } from '@nebula.js/stardust';
|
||||||
import snapshooter from '@nebula.js/snapshooter/client';
|
import snapshooter from '@nebula.js/snapshooter/client';
|
||||||
|
|
||||||
import { openApp, params, info as serverInfo } from './connect';
|
import { openApp, params, getConnectionInfo } from './connect';
|
||||||
import initiateWatch from './hot';
|
import initiateWatch from './hot';
|
||||||
import renderFixture from './render-fixture';
|
import renderFixture from './render-fixture';
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ const nuke = async ({ app, supernova: { name }, themes, theme, language }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function renderWithEngine() {
|
async function renderWithEngine() {
|
||||||
const info = await serverInfo;
|
const info = await getConnectionInfo();
|
||||||
initiateWatch(info);
|
initiateWatch(info);
|
||||||
if (!info.enigma.appId) {
|
if (!info.enigma.appId) {
|
||||||
location.href = location.origin; //eslint-disable-line
|
location.href = location.origin; //eslint-disable-line
|
||||||
@@ -79,7 +79,7 @@ async function renderWithEngine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function renderSnapshot() {
|
async function renderSnapshot() {
|
||||||
const info = await serverInfo;
|
const info = await getConnectionInfo();
|
||||||
const { themes, supernova } = info;
|
const { themes, supernova } = info;
|
||||||
initiateWatch(info);
|
initiateWatch(info);
|
||||||
const element = document.querySelector('#chart-container');
|
const element = document.querySelector('#chart-container');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { embed } from '@nebula.js/stardust';
|
import { embed } from '@nebula.js/stardust';
|
||||||
import EnigmaMocker from '@nebula.js/enigma-mocker';
|
import EnigmaMocker from '@nebula.js/enigma-mocker';
|
||||||
import extend from 'extend';
|
import extend from 'extend';
|
||||||
import { info as getServerInfo } from './connect';
|
import { getConnectionInfo } from './connect';
|
||||||
import { getModule } from './hot';
|
import { getModule } from './hot';
|
||||||
|
|
||||||
const getDefaultGenericObject = ({ type }) => ({
|
const getDefaultGenericObject = ({ type }) => ({
|
||||||
@@ -101,7 +101,7 @@ function getQId(genericObjects = []) {
|
|||||||
|
|
||||||
const renderFixture = async (params) => {
|
const renderFixture = async (params) => {
|
||||||
const element = document.querySelector('#chart-container');
|
const element = document.querySelector('#chart-container');
|
||||||
const serverInfo = await getServerInfo;
|
const serverInfo = await getConnectionInfo();
|
||||||
const fixture = await getFixture(params.fixture);
|
const fixture = await getFixture(params.fixture);
|
||||||
const { type, load, genericObjects, instanceConfig, snConfig } = await getOptions({ fixture, params, serverInfo });
|
const { type, load, genericObjects, instanceConfig, snConfig } = await getOptions({ fixture, params, serverInfo });
|
||||||
const mockedApp = await EnigmaMocker.fromGenericObjects(genericObjects);
|
const mockedApp = await EnigmaMocker.fromGenericObjects(genericObjects);
|
||||||
|
|||||||
16
jest.config.js
Normal file
16
jest.config.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
module.exports = {
|
||||||
|
clearMocks: true,
|
||||||
|
testEnvironment: 'jest-environment-jsdom',
|
||||||
|
testRegex: ['commands/serve/web/.+\\.(test|spec)\\.[jt]sx?$'],
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
|
||||||
|
collectCoverageFrom: [
|
||||||
|
'commands/serve/web/**/*.{js,jsx}',
|
||||||
|
'!commands/serve/web/**/*.spec.{js,jsx}',
|
||||||
|
'!commands/serve/web/**/*.test.{js,jsx}',
|
||||||
|
'!commands/serve/web/**/__tests__/**/*',
|
||||||
|
|
||||||
|
'!**/dist/**',
|
||||||
|
'!**/node_modules/**',
|
||||||
|
],
|
||||||
|
coverageReporters: ['json', 'lcov', 'text-summary', 'clover'],
|
||||||
|
};
|
||||||
2
jest.setup.js
Normal file
2
jest.setup.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import '@testing-library/jest-dom';
|
||||||
|
import 'whatwg-fetch';
|
||||||
14
package.json
14
package.json
@@ -15,6 +15,9 @@
|
|||||||
"build-storybook": "build-storybook",
|
"build-storybook": "build-storybook",
|
||||||
"spec": "lerna run spec --stream --concurrency 99 && lerna run ts --stream --concurrency 99 ",
|
"spec": "lerna run spec --stream --concurrency 99 && lerna run ts --stream --concurrency 99 ",
|
||||||
"test": "yarn run test:unit",
|
"test": "yarn run test:unit",
|
||||||
|
"test:jest": "jest",
|
||||||
|
"test:jest:watch": "jest --watch",
|
||||||
|
"test:jest:coverage": "jest --coverage",
|
||||||
"mashup": "node scripts/start-mashup.js",
|
"mashup": "node scripts/start-mashup.js",
|
||||||
"test:mashup": "aw puppet -c aw.config.js --testExt '*.int.js' --glob 'test/mashup/**/*.int.js'",
|
"test:mashup": "aw puppet -c aw.config.js --testExt '*.int.js' --glob 'test/mashup/**/*.int.js'",
|
||||||
"test:integration": "aw puppet -c aw.config.js --testExt '*.int.js' --glob 'test/integration/**/*.int.js'",
|
"test:integration": "aw puppet -c aw.config.js --testExt '*.int.js' --glob 'test/integration/**/*.int.js'",
|
||||||
@@ -36,8 +39,8 @@
|
|||||||
"@babel/cli": "7.18.10",
|
"@babel/cli": "7.18.10",
|
||||||
"@babel/core": "7.18.13",
|
"@babel/core": "7.18.13",
|
||||||
"@babel/helper-plugin-utils": "7.18.9",
|
"@babel/helper-plugin-utils": "7.18.9",
|
||||||
"@babel/plugin-transform-react-jsx": "7.18.10",
|
|
||||||
"@babel/plugin-proposal-object-rest-spread": "7.18.9",
|
"@babel/plugin-proposal-object-rest-spread": "7.18.9",
|
||||||
|
"@babel/plugin-transform-react-jsx": "7.18.10",
|
||||||
"@babel/preset-env": "7.18.10",
|
"@babel/preset-env": "7.18.10",
|
||||||
"@babel/preset-react": "7.18.6",
|
"@babel/preset-react": "7.18.6",
|
||||||
"@commitlint/cli": "17.1.2",
|
"@commitlint/cli": "17.1.2",
|
||||||
@@ -46,9 +49,9 @@
|
|||||||
"@rollup/plugin-json": "4.1.0",
|
"@rollup/plugin-json": "4.1.0",
|
||||||
"@rollup/plugin-node-resolve": "13.3.0",
|
"@rollup/plugin-node-resolve": "13.3.0",
|
||||||
"@rollup/plugin-replace": "4.0.0",
|
"@rollup/plugin-replace": "4.0.0",
|
||||||
"@storybook/addon-docs": "6.5.10",
|
|
||||||
"@storybook/addon-controls": "6.5.10",
|
|
||||||
"@storybook/addon-actions": "6.5.10",
|
"@storybook/addon-actions": "6.5.10",
|
||||||
|
"@storybook/addon-controls": "6.5.10",
|
||||||
|
"@storybook/addon-docs": "6.5.10",
|
||||||
"@storybook/addon-essentials": "6.5.10",
|
"@storybook/addon-essentials": "6.5.10",
|
||||||
"@storybook/addon-interactions": "6.5.10",
|
"@storybook/addon-interactions": "6.5.10",
|
||||||
"@storybook/addon-links": "6.5.10",
|
"@storybook/addon-links": "6.5.10",
|
||||||
@@ -56,6 +59,7 @@
|
|||||||
"@storybook/manager-webpack5": "6.5.10",
|
"@storybook/manager-webpack5": "6.5.10",
|
||||||
"@storybook/react": "6.5.10",
|
"@storybook/react": "6.5.10",
|
||||||
"@storybook/testing-library": "0.0.13",
|
"@storybook/testing-library": "0.0.13",
|
||||||
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
"babel-loader": "8.2.5",
|
"babel-loader": "8.2.5",
|
||||||
"babel-plugin-istanbul": "6.1.1",
|
"babel-plugin-istanbul": "6.1.1",
|
||||||
"body-parser": "1.20.0",
|
"body-parser": "1.20.0",
|
||||||
@@ -65,6 +69,7 @@
|
|||||||
"eslint-config-airbnb": "19.0.4",
|
"eslint-config-airbnb": "19.0.4",
|
||||||
"eslint-config-prettier": "8.5.0",
|
"eslint-config-prettier": "8.5.0",
|
||||||
"eslint-plugin-import": "2.26.0",
|
"eslint-plugin-import": "2.26.0",
|
||||||
|
"eslint-plugin-jest": "^27.0.4",
|
||||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||||
"eslint-plugin-mocha": "10.1.0",
|
"eslint-plugin-mocha": "10.1.0",
|
||||||
"eslint-plugin-prettier": "4.2.1",
|
"eslint-plugin-prettier": "4.2.1",
|
||||||
@@ -72,6 +77,8 @@
|
|||||||
"eslint-plugin-storybook": "0.6.4",
|
"eslint-plugin-storybook": "0.6.4",
|
||||||
"express": "4.18.1",
|
"express": "4.18.1",
|
||||||
"husky": "8.0.1",
|
"husky": "8.0.1",
|
||||||
|
"jest": "^29.0.3",
|
||||||
|
"jest-environment-jsdom": "^29.0.3",
|
||||||
"jimp": "0.16.1",
|
"jimp": "0.16.1",
|
||||||
"lerna": "5.5.0",
|
"lerna": "5.5.0",
|
||||||
"lint-staged": "13.0.3",
|
"lint-staged": "13.0.3",
|
||||||
@@ -86,6 +93,7 @@
|
|||||||
"rollup-plugin-dependency-flow": "0.3.0",
|
"rollup-plugin-dependency-flow": "0.3.0",
|
||||||
"rollup-plugin-sass": "1.2.13",
|
"rollup-plugin-sass": "1.2.13",
|
||||||
"rollup-plugin-terser": "7.0.2",
|
"rollup-plugin-terser": "7.0.2",
|
||||||
|
"whatwg-fetch": "^3.6.2",
|
||||||
"yargs": "17.5.1"
|
"yargs": "17.5.1"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|||||||
Reference in New Issue
Block a user