test: add object lifecycle tests (#463)

This commit is contained in:
Miralem Drek
2020-07-01 09:54:07 +02:00
committed by GitHub
parent 115c61f4fa
commit edbf8d8819
25 changed files with 747 additions and 59 deletions

View File

@@ -29,7 +29,9 @@ jobs:
docker:
- image: circleci/node:10.19.0
- image: qlikcore/engine:12.700.0
command: -S AcceptEULA=yes
command: |
-S AcceptEULA=yes
-S SSEPlugin=sse,localhost:50051
- image: browserless/chrome:1.34.0-puppeteer-1.20.0
working_directory: ~/project
@@ -37,6 +39,18 @@ jobs:
steps:
- checkout
# start the SSE plugin as early as possible so that the engine
# image has enough time to connect to it before tests are run
- run:
name: Initiate SSE plugin
command: |
cd test/fixtures/sse
echo "{}" > package.json
npm install qlik-sse@0.3.0 --no-package-lock
rm package.json
node start.js
background: true
- restore_cache: *restore_yarn_cache
- run:

2
.gitignore vendored
View File

@@ -16,3 +16,5 @@ test/**/__artifacts__/regression
test/**/__artifacts__/diff
apis/*/core/**/*.js
apis/locale/all.json
Search/

View File

@@ -2,9 +2,11 @@ version: '3.1'
services:
engine:
image: qlikcore/engine:${ENGINE_VERSION:-12.612.0}
image: qlikcore/engine:${ENGINE_VERSION:-12.700.0}
# restart: always
command: -S AcceptEULA=${ACCEPT_EULA:-no} -S DocumentDirectory=/apps
command: |
-S AcceptEULA=${ACCEPT_EULA:-no}
-S DocumentDirectory=/apps
ports:
- ${ENGINE_PORT:-9076}:9076
volumes:

View File

@@ -1,8 +1,6 @@
const path = require('path');
const { spawn } = require('child_process');
const cwd = path.resolve(__dirname, '../');
const execCmd = (cmd, cmdArgs = [], opts) => {
return new Promise((resolve, reject) => {
const child = spawn(cmd, cmdArgs, opts);
@@ -29,23 +27,24 @@ const execCmd = (cmd, cmdArgs = [], opts) => {
});
};
const useEngine = ({ ACCEPT_EULA = false }) => {
const useEngine = ({ ACCEPT_EULA = false, cwd = path.resolve(__dirname, '../'), files }) => {
if (ACCEPT_EULA !== true) {
throw new Error('Need to accept EULA in order to start engine container');
}
console.error('Starting engine container...');
console.error('Starting engine container...', cwd);
const f = (files || []).reduce((acc, curr) => [...acc, '-f', curr], []);
process.env.ACCEPT_EULA = 'yes';
const stopEngine = async () => {
console.error('Stopping engine container...');
try {
await execCmd('docker-compose', ['down', '--remove-orphans'], {
await execCmd('docker-compose', [...f, 'down', '--remove-orphans'], {
cwd,
});
} catch (err) {
console.error(err);
}
};
return execCmd('docker-compose', ['up', '-d', '--build'], { cwd }).then(() => stopEngine);
return execCmd('docker-compose', [...f, 'up', '-d', '--build'], { cwd }).then(() => stopEngine);
};
module.exports = useEngine;

View File

@@ -10,10 +10,11 @@
"locale:generate": "node apis/locale/scripts/generate-all.js",
"lint": "eslint packages apis commands --ext .js,.jsx",
"lint:check": "eslint --print-config ./aw.config.js | eslint-config-prettier-check",
"start": "MONO=true ./commands/cli/lib/index.js serve --entry ./test/viz/simple",
"start": "MONO=true ./commands/cli/lib/index.js serve --entry ./test/fixtures/viz/table",
"start:ui": "start-storybook",
"spec": "lerna run spec --stream --concurrency 99",
"test": "yarn run test:unit",
"mashup": "node scripts/start-mashup.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:component": "aw puppet -c aw.config.js --testExt '*.comp.js' --glob 'test/component/**/*.comp.js'",
@@ -75,6 +76,7 @@
"prettier": "2.0.5",
"pretty-quick": "2.0.1",
"qix-faker": "0.3.0",
"qlik-sse": "0.3.0",
"rollup": "2.18.0",
"rollup-plugin-babel": "4.4.0",
"rollup-plugin-dependency-flow": "0.3.0",

111
scripts/start-mashup.js Normal file
View File

@@ -0,0 +1,111 @@
#! /usr/bin/env node
const yargs = require('yargs');
const mashupServer = require('../test/mashup/server');
const sseServer = require('../test/fixtures/sse');
const useEngine = require('../commands/serve/lib/engine');
const args = yargs
.option('start', {
default: true,
type: 'boolean',
describe: 'Start the mashup server',
})
.option('sse', {
default: true,
type: 'boolean',
describe: 'Start the SSE plugin',
})
.option('engine', {
default: false,
type: 'boolean',
describe: 'Start the engine',
}).argv;
const { start, sse, engine } = args;
let hasCleanedUp = false;
const services = [];
if (start) {
let m;
services.push({
name: 'Mashup server',
start: async () => {
m = await mashupServer();
process.env.BASE_URL = m.url;
},
stop: async () => {
await m.close();
},
});
}
if (sse) {
const s = sseServer;
services.push({
name: 'SSE plugin server',
start: () => {
s.start();
},
stop: () => s.close(),
});
}
if (engine) {
let e;
services.push({
name: 'Qlik Engine',
start: async () => {
e = await useEngine({
ACCEPT_EULA: true,
files: ['./test/fixtures/docker/docker-compose.yml'],
cwd: process.cwd(),
});
},
stop: async () => {
await e();
},
});
}
function cleanup() {
if (hasCleanedUp) {
return;
}
hasCleanedUp = true;
console.log('Stopping services');
services.forEach(async (service) => {
console.log(`${service.name}`);
await service.stop();
});
}
async function run() {
console.log('Starting services');
try {
services.forEach(async (service) => {
console.log(`${service.name}`);
await service.start();
});
console.log('All up and running');
} catch (err) {
console.log(err);
cleanup();
throw err;
}
}
process.on('exit', cleanup);
process.on('SIGINT', process.exit);
process.on('SIGTERM', process.exit);
process.on('uncaughtException', (err) => {
if (!hasCleanedUp) {
console.log(err.stack);
process.exit(1);
}
});
run();

BIN
test/fixtures/data/apps/ctrl00.qvf vendored Normal file

Binary file not shown.

14
test/fixtures/docker/docker-compose.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
version: '3.1'
services:
engine:
image: qlikcore/engine:${ENGINE_VERSION:-12.700.0}
# restart: always
command: |
-S AcceptEULA=${ACCEPT_EULA:-no}
-S DocumentDirectory=/apps
-S SSEPlugin=sse,host.docker.internal:50051
ports:
- '9076:9076'
volumes:
- ${APPS_PATH:-../data/apps}:/apps

51
test/fixtures/sse/index.js vendored Normal file
View File

@@ -0,0 +1,51 @@
const q = require('qlik-sse');
const s = q.server({
identifier: 'heavy',
version: '0.1.0',
allowScript: true,
});
async function heavy(request) {
request.on('data', (bundle) => {
const rows = [];
let t = 100;
try {
t = bundle.rows[0].duals[0].numData;
} catch (e) {
/* */
}
setTimeout(() => {
bundle.rows.forEach((row) => {
row.duals.forEach((dual) => {
rows.push({
duals: [{ numData: dual.numData, strData: `$${dual.numData}` }],
});
});
});
request.write({ rows });
request.end();
}, t);
});
}
s.addFunction(heavy, {
functionType: q.sse.FunctionType.SCALAR,
returnType: q.sse.DataType.NUMERIC,
params: [
{
name: 'first',
dataType: q.sse.DataType.NUMERIC,
},
],
});
// start the server
/*
s.start({
port: 50051,
});
*/
module.exports = s;

3
test/fixtures/sse/start.js vendored Normal file
View File

@@ -0,0 +1,3 @@
require('./index').start({
port: 50051,
});

65
test/fixtures/viz/table/src/index.js vendored Normal file
View File

@@ -0,0 +1,65 @@
import { useElement, useLayout, useEffect } from '@nebula.js/stardust';
import data from './data.json';
import './style.css';
export default function v() {
return {
qae: {
properties: {
dimensionName: 'The first one',
layers: [
{
qHyperCubeDef: {
qInitialDataFetch: [{ qLeft: 0, qWidth: 4, qTop: 0, qHeight: 10 }],
},
},
],
},
data: {
targets: [
{
path: '/layers/0/qHyperCubeDef',
dimensions: {
min: 1,
max: 1,
description(props) {
return props.dimensionName;
},
},
measures: { max: () => 3 },
},
],
},
},
component() {
const element = useElement();
const layout = useLayout();
useEffect(() => {
const hc = layout.layers[0].qHyperCube;
// headers
const columns = [...hc.qDimensionInfo, ...hc.qMeasureInfo].map((f) => f.qFallbackTitle);
const header = `<thead><tr>${columns.map((c) => `<th>${c}</th>`).join('')}</tr></thead>`;
// rows
const rows = hc.qDataPages[0].qMatrix
.map((row) => `<tr>${row.map((cell) => `<td>${cell.qText}</td>`).join('')}</tr>`)
.join('');
// table
const table = `<table>${header}<tbody>${rows}</tbody></table>`;
// output
element.innerHTML = `
<div class="simple-table">
<div class="hello">A simple table</div>
<div class="json-value">${data.v}</div>
<div class="table">${table}</div>
</div>
`;
}, [element, layout]);
},
};
}

4
test/fixtures/viz/table/src/style.css vendored Normal file
View File

@@ -0,0 +1,4 @@
.simple-table .hello {
background-color: #90298c;
color: white;
}

View File

@@ -16,7 +16,7 @@ if (!process.env.BASE_URL) {
before(async () => {
s = await serve({
entry: path.resolve(__dirname, '../viz/simple'),
entry: path.resolve(__dirname, '../fixtures/viz/table'),
open: false,
});

View File

@@ -1,17 +1,17 @@
describe('Simple visualization', () => {
const content = '.simple-viz';
const content = '.simple-table';
describe('basic', () => {
before(async () => {
const app = encodeURIComponent(process.env.APP_ID || '/apps/ctrl00.qvf');
await page.goto(`${process.env.BASE_URL}/render/?app=${app}`);
await page.goto(`${process.env.BASE_URL}/render/?app=${app}&cols=Alpha`);
await page.waitForSelector(content, { visible: true });
});
it('should say hello', async () => {
it('should render a div', async () => {
const text = await page.$eval('.hello', (el) => el.textContent);
expect(text).to.equal('Hello engine!');
expect(text).to.equal('A simple table');
});
it('should be able to load json file', async () => {
@@ -24,9 +24,9 @@ describe('Simple visualization', () => {
expect(bg).to.equal('rgb(144, 41, 140)');
});
it('should have a dynamically calculated lavout value', async () => {
const text = await page.$eval('.layout-value', (el) => el.textContent);
expect(text).to.equal('3');
it('should have some data', async () => {
const text = await page.$eval('.table table tbody td', (el) => el.textContent);
expect(text).to.equal('A');
});
});
});

View File

@@ -21,6 +21,7 @@ module.exports = async () => {
app.use(express.static(path.resolve(__dirname)));
app.use('/apis', express.static(path.resolve(__dirname, '../../apis')));
app.use('/fixtures', express.static(path.resolve(__dirname, '../fixtures')));
app.use('/node_modules', express.static(path.resolve(__dirname, '../../node_modules')));
app.use(

View File

@@ -1,10 +1,11 @@
const server = require('./server');
page.on('pageerror', e => {
page.on('pageerror', (e) => {
console.error('Web: ', e.message);
process.exit(1);
});
page.on('console', msg => {
page.on('console', (msg) => {
for (let i = 0; i < msg.args().length; ++i) {
console.log(`console ${msg.text()}`);
}

View File

@@ -0,0 +1,25 @@
export default function connect() {
const loadSchema = () => fetch('/node_modules/enigma.js/schemas/3.2.json').then((response) => response.json());
const createConnection = () =>
loadSchema().then((schema) =>
window.enigma
.create({
schema,
url: `ws://${window.location.hostname || 'localhost'}:9076/app/${Date.now()}`,
})
.open()
.then((qix) => qix.createSessionApp())
);
return createConnection().then((app) =>
app
.setScript(
`
Characters:
Load Chr(RecNo()+Ord('A')-1) as Alpha, RecNo() as Num autogenerate 5;
`
)
.then(() => app.doReload().then(() => app))
);
}

View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="/node_modules/enigma.js/enigma.min.js"></script>
<script src="/apis/stardust/dist/stardust.dev.js"></script>
<style>
html,
body {
margin: 20px;
padding: 0;
background-color: #fafafa;
color: red;
}
.wrapper {
display: flex;
}
.viz {
flex: 0 0 600px;
position: relative;
width: 600px;
height: 400px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
}
.actions {
margin-left: 16px;
flex: 0 0 200px;
}
.actions > button {
display: block;
width: 100%;
margin-bottom: 8px;
padding: 8px 4px;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="viz"></div>
<div class="actions"></div>
</div>
<script type="module">
import connect from './connect.js';
import phases from './phases.js';
connect().then(async (app) => {
const actionsElement = document.querySelector('.actions');
const p = phases({ app }).phases;
p.forEach((phase) => {
const btn = document.createElement('button');
btn.textContent = phase.name;
btn.setAttribute('data-phase', phase.name.toLowerCase().replace(/\s+/g, '-'));
btn.addEventListener('click', phase.action);
actionsElement.appendChild(btn);
});
});
</script>
</body>
</html>

View File

@@ -0,0 +1,57 @@
describe('object lifecycle', () => {
const waitForTextStatus = async (selector, text, options = { timeout: 1000 }) => {
await page.waitForSelector(selector, { visible: true });
await page.waitForFunction(
(s, t) => document.querySelector(s) && document.querySelector(s).textContent === t,
options,
`${selector}`,
text
);
};
before(async () => {
await page.goto(`${process.env.BASE_URL}/visualize/life.html`);
await page.waitForSelector('button[data-phase="init-as-bad-type"]', { visible: true });
});
it('should fail to load unknown type', async () => {
await page.click('button[data-phase="init-as-bad-type"]');
await waitForTextStatus(
'[data-tid="error-title"]',
"Could not find a version of 'voooz' that supports current object version. Did you forget to register voooz?"
);
});
it('should show requirements for known type', async () => {
await page.click('button[data-phase="set-proper-type"]');
await waitForTextStatus('[data-tid="error-title"]', 'Incomplete visualization');
});
// need to fix calc condition view first
it('should show calculation unfulfilled', async () => {
await page.click('button[data-phase="set-calc-condition"]');
await waitForTextStatus('[data-tid="error-title"]', 'The calculation condition is not fulfilled');
});
it('should render when requirements are fulfilled', async () => {
await page.click('button[data-phase="fulfill-requirements"]');
await waitForTextStatus('.rendered', 'Success!');
});
it('should render long running query', async () => {
await page.click('button[data-phase="long-running-query"]');
// the cancel button should appear after 2000ms
// TODO - fix error thrown when long running query is cancelled
// await waitForTextStatus('.njs-cell button', 'Cancel', { timeout: 2500 });
// await page.click('.njs-cell button');
// await waitForTextStatus('.njs-cell button', 'Retry');
await waitForTextStatus('.pages', '4001', { timeout: 5000 });
});
it('should destroy', async () => {
await page.click('button[data-phase="destroy"]');
// wait for some time to ensure destroy has been run and no errors are thrown
await page.waitFor(100);
});
});

View File

@@ -0,0 +1,135 @@
const baseProps = {
qInfo: {
qType: 'doesnt matter',
},
visualization: 'my-chart',
qHyperCubeDef: {},
};
const badType = {
...baseProps,
visualization: 'voooz',
};
const calcCond = {
...baseProps,
qHyperCubeDef: {
qCalcCondition: {
qCond: { qv: '0' },
},
qDimensions: [{ qDef: { qFieldDefs: ['=a'] } }],
qMeasures: [{ qDef: { qDef: '=1' } }],
},
};
const fulfilled = {
...baseProps,
qHyperCubeDef: {
qDimensions: [{ qDef: { qFieldDefs: ['=a'] } }],
qMeasures: [{ qDef: { qDef: '=1' } }],
},
};
const longRunning = {
...baseProps,
qHyperCubeDef: {
qInitialDataFetch: [
{
qTop: 0,
qLeft: 0,
qWidth: 2,
qHeight: 10,
},
],
qDimensions: [{ qDef: { qFieldDefs: ['=a'] } }],
qMeasures: [{ qDef: { qDef: 'sse.heavy(4001)' } }],
},
};
const { useElement, useLayout } = window.stardust;
const chart = {
qae: {
data: {
targets: [
{
path: '/qHyperCubeDef',
dimensions: { min: 1, description: () => 'Some dimension' },
measures: { min: 1 },
},
],
},
},
component() {
const element = useElement();
const layout = useLayout();
element.innerHTML = `
<div>
<div class="rendered">Success!</div>
<div class="pages">${layout.qHyperCube.qDataPages[0] && layout.qHyperCube.qDataPages[0].qMatrix[0][1].qText}</div>
</div>
`;
},
};
// eslint-disable-next-line
const configured = stardust.embed.createConfiguration({
types: [
{
name: 'my-chart',
load: () => Promise.resolve(chart),
},
],
});
export default function phases({ app }) {
let viz;
let obj;
return {
phases: [
{
name: 'Init as bad type',
action: async () => {
if (obj) {
throw new Error('Already initiated');
}
obj = await app.createSessionObject(badType);
viz = await configured(app).render({
element: document.querySelector('.viz'),
id: obj.id,
});
},
},
{
name: 'Set proper type',
action: () => {
obj.setProperties(baseProps);
},
},
{
name: 'Set calc condition',
action: () => {
obj.setProperties(calcCond);
},
},
{
name: 'Fulfill requirements',
action: () => {
obj.setProperties(fulfilled);
},
},
{
name: 'Long running query',
action: () => {
obj.setProperties(longRunning);
},
},
{
name: 'Destroy',
action: () => {
viz.destroy();
},
},
],
};
}

View File

@@ -1,29 +0,0 @@
import { useElement, useLayout } from '@nebula.js/stardust';
import data from './data.json';
import './style.css';
export default function v() {
return {
qae: {
properties: {
v: {
qValueExpression: {
qExpr: '1+2',
},
},
},
},
component() {
const element = useElement();
const layout = useLayout();
element.innerHTML = `
<div class="simple-viz">
<div class="hello">Hello engine!</div>
<div class="json-value">${data.v}</div>
<div class="layout-value">${layout.v}</div>
</div>
`;
},
};
}

View File

@@ -1,8 +0,0 @@
.simple-viz {
font: 24px bold Georgia;
}
.simple-viz .hello {
background-color: #90298c;
color: white;
}

178
yarn.lock
View File

@@ -5977,6 +5977,14 @@
dependencies:
"@types/babel-types" "*"
"@types/bytebuffer@^5.0.40":
version "5.0.41"
resolved "https://registry.yarnpkg.com/@types/bytebuffer/-/bytebuffer-5.0.41.tgz#6850dba4d4cd2846596b4842874d5bfc01cd3db1"
integrity sha512-Mdrv4YcaHvpkx25ksqqFaezktx3yZRcd51GZY0rY/9avyaqZdiT/GiWRhfrJhMpgzXqTOSHgGvsumGxJFNiZZA==
dependencies:
"@types/long" "*"
"@types/node" "*"
"@types/color-name@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
@@ -6048,6 +6056,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
"@types/long@*":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
"@types/mime-types@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73"
@@ -7012,6 +7025,14 @@ asap@^2.0.0, asap@~2.0.3:
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
ascli@~1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/ascli/-/ascli-1.0.1.tgz#bcfa5974a62f18e81cabaeb49732ab4a88f906bc"
integrity sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=
dependencies:
colour "~0.7.1"
optjs "~3.2.2"
asn1.js@^4.0.0:
version "4.10.1"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0"
@@ -7877,6 +7898,13 @@ byte-size@^5.0.1:
resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-5.0.1.tgz#4b651039a5ecd96767e71a3d7ed380e48bed4191"
integrity sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==
bytebuffer@~5:
version "5.0.1"
resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd"
integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=
dependencies:
long "~3"
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -8019,7 +8047,7 @@ camelcase@^1.0.2:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=
camelcase@^2.0.0:
camelcase@^2.0.0, camelcase@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
@@ -8431,6 +8459,15 @@ cliui@^2.1.0:
right-align "^0.1.1"
wordwrap "0.0.2"
cliui@^3.0.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=
dependencies:
string-width "^1.0.1"
strip-ansi "^3.0.1"
wrap-ansi "^2.0.0"
cliui@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
@@ -8555,6 +8592,11 @@ colors@^1.1.2:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
colour@~0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/colour/-/colour-0.7.1.tgz#9cb169917ec5d12c0736d3e8685746df1cadf778"
integrity sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=
columnify@^1.5.4:
version "1.5.4"
resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
@@ -11530,6 +11572,18 @@ glob@7.1.3, glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.0.5:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.1.2:
version "7.1.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0"
@@ -11723,6 +11777,18 @@ growl@1.10.5:
version "1.10.5"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
grpc@^1.14.1:
version "1.24.3"
resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.24.3.tgz#92efe28dfc1250dca179b8133e40b4f2341473d9"
integrity sha512-EDemzuZTfhM0hgrXqC4PtR76O3t+hTIYJYR5vgiW0yt2WJqo4mhxUqZUirzUQz34Psz7dbLp38C6Cl7Ij2vXRQ==
dependencies:
"@types/bytebuffer" "^5.0.40"
lodash.camelcase "^4.3.0"
lodash.clone "^4.5.0"
nan "^2.13.2"
node-pre-gyp "^0.15.0"
protobufjs "^5.0.3"
gud@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
@@ -13924,6 +13990,11 @@ lodash.camelcase@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
lodash.clone@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
lodash.clonedeep@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
@@ -14036,6 +14107,11 @@ lolex@^4.1.0, lolex@^4.2.0:
resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.2.0.tgz#ddbd7f6213ca1ea5826901ab1222b65d714b3cd7"
integrity sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==
long@~3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b"
integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
@@ -14634,6 +14710,14 @@ minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minipass@^2.8.6:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
dependencies:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minipass@^3.0.0, minipass@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5"
@@ -14837,6 +14921,11 @@ mz@^2.5.0:
object-assign "^4.0.1"
thenify-all "^1.0.0"
nan@^2.13.2:
version "2.14.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
nan@^2.9.2:
version "2.12.1"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
@@ -14869,6 +14958,15 @@ needle@^2.2.1:
iconv-lite "^0.4.4"
sax "^1.2.4"
needle@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0"
integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==
dependencies:
debug "^3.2.6"
iconv-lite "^0.4.4"
sax "^1.2.4"
negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@@ -15045,6 +15143,22 @@ node-pre-gyp@^0.10.0:
semver "^5.3.0"
tar "^4"
node-pre-gyp@^0.15.0:
version "0.15.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz#c2fc383276b74c7ffa842925241553e8b40f1087"
integrity sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.3"
needle "^2.5.0"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4.4.2"
node-releases@^1.1.19:
version "1.1.20"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.20.tgz#f77f9f9a4fcb22e74ba88fe15732a3a8b037146d"
@@ -15506,6 +15620,11 @@ optionator@^0.9.1:
type-check "^0.4.0"
word-wrap "^1.2.3"
optjs@~3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee"
integrity sha1-aabOicRCpEQDFBrS+bNwvVu29O4=
original@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
@@ -15520,6 +15639,13 @@ os-homedir@^1.0.0, os-homedir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
os-locale@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=
dependencies:
lcid "^1.0.0"
os-locale@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2"
@@ -16684,6 +16810,16 @@ proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
protobufjs@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-5.0.3.tgz#e4dfe9fb67c90b2630d15868249bcc4961467a17"
integrity sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==
dependencies:
ascli "~1"
bytebuffer "~5"
glob "^7.0.5"
yargs "^3.10.0"
protocols@^1.1.0, protocols@^1.4.0:
version "1.4.7"
resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.7.tgz#95f788a4f0e979b291ffefcf5636ad113d037d32"
@@ -16908,6 +17044,13 @@ qix-faker@0.3.0:
dependencies:
faker "^4.1.0"
qlik-sse@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/qlik-sse/-/qlik-sse-0.3.0.tgz#d251bf1ffd0059d1721e893a58db5fd62560d0fd"
integrity sha512-vbhoF7R3qWg4kKTDjN/mnPdbRFmn4gPQIrEp2Q8t1QLChtEAjZJU54OSJd2qzn7F1zHv5I2Zg7CNs2QEw+hP/w==
dependencies:
grpc "^1.14.1"
qs@6.7.0:
version "6.7.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
@@ -19326,6 +19469,19 @@ tar@^4.4.10:
safe-buffer "^5.1.2"
yallist "^3.0.3"
tar@^4.4.2:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
dependencies:
chownr "^1.1.1"
fs-minipass "^1.2.5"
minipass "^2.8.6"
minizlib "^1.2.1"
mkdirp "^0.5.0"
safe-buffer "^5.1.2"
yallist "^3.0.3"
telejson@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/telejson/-/telejson-3.3.0.tgz#6d814f3c0d254d5c4770085aad063e266b56ad03"
@@ -20593,6 +20749,11 @@ window-size@0.1.0:
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=
window-size@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=
windows-release@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f"
@@ -20792,7 +20953,7 @@ xtend@^4.0.1:
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^3.2.1:
y18n@^3.2.0, y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
integrity sha1-bRX7qITAhnnA136I53WegR4H+kE=
@@ -20966,6 +21127,19 @@ yargs@^13.3.0, yargs@^13.3.2:
y18n "^4.0.0"
yargs-parser "^13.1.2"
yargs@^3.10.0:
version "3.32.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"
integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=
dependencies:
camelcase "^2.0.1"
cliui "^3.0.3"
decamelize "^1.1.1"
os-locale "^1.4.0"
string-width "^1.0.1"
window-size "^0.1.4"
y18n "^3.2.0"
yargs@~3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"