Compare commits

...

4 Commits

Author SHA1 Message Date
ade5b933d8 better timestamps, adapt default config
All checks were successful
continuous-integration/drone/push Build is passing
2020-08-23 14:31:15 +02:00
714110edb0 fix 2020-08-23 14:18:14 +02:00
b6ecd65748 prevent huge data amounts, separate sources 2020-08-23 14:17:10 +02:00
39f9f17b95 linting, cleanup 2020-08-23 13:08:04 +02:00
16 changed files with 253 additions and 247 deletions

View File

@ -9,46 +9,21 @@
'use strict'; 'use strict';
const express = require ('express'); const express = require ('express');
const auth = require ('@sapphirecode/auth-server-helper');
const body_parser = require ('body-parser'); const body_parser = require ('body-parser');
const cookie_parser = require ('cookie-parser');
const db = require ('./lib/db'); const db = require ('./lib/db');
const crypto = require ('@sapphirecode/crypto-helper');
const password_helper = require ('@sapphirecode/password-helper');
const api = require ('./lib/api'); const api = require ('./lib/api');
const http_proxy = require ('express-http-proxy'); const http_proxy = require ('express-http-proxy');
const history_fallback = require ('connect-history-api-fallback'); const history_fallback = require ('connect-history-api-fallback');
const fs = require ('fs');
const { argv } = require ('yargs'); const { argv } = require ('yargs');
const salt = crypto.create_salt ();
const hash = crypto.hash_sha512 ('asd', salt);
const user = {
id: 0,
salt,
password: password_helper.hash (hash)
};
const is_dev = argv.dev; const is_dev = argv.dev;
(async () => { (async () => {
if (fs.existsSync ('db.sqlite'))
fs.unlinkSync ('db.sqlite');
await db.init (is_dev); await db.init (is_dev);
const app = express (); const app = express ();
app.use (cookie_parser ());
app.use (body_parser.json ()); app.use (body_parser.json ());
/*
* app.use (auth ((name) => {
*if (name === 'timo')
* return user;
*return null;
*}));
*/
app.use (api); app.use (api);
app.use (history_fallback ()); app.use (history_fallback ());
if (is_dev) if (is_dev)
@ -57,6 +32,7 @@ const is_dev = argv.dev;
app.use (express.static ('dist')); app.use (express.static ('dist'));
app.listen (3000, () => { app.listen (3000, () => {
// eslint-disable-next-line no-console
console.log ('listening on 3000'); console.log ('listening on 3000');
}); });
}) (); }) ();

View File

@ -1,7 +1,10 @@
module.exports = (req,res,next) => { /* eslint-disable no-console */
console.log(req.method, req.originalUrl); 'use strict';
console.log(JSON.stringify(req.headers));
console.log(''); module.exports = (req, res, next) => {
console.log(JSON.stringify(req.body, null, 2)); console.log (req.method, req.originalUrl);
next(); console.log (JSON.stringify (req.headers));
}; console.log ('');
console.log (JSON.stringify (req.body, null, 2));
next ();
};

View File

@ -11,15 +11,20 @@ const db = require ('../db');
const { http } = require ('@sapphirecode/consts'); const { http } = require ('@sapphirecode/consts');
module.exports = async (req, res) => { module.exports = async (req, res) => {
if ( const limit = parseInt (req.headers.limit);
typeof req.headers.app_id === 'undefined' const offset = parseInt (req.headers.offset);
|| isNaN (parseInt (req.headers.app_id)) const app_id = parseInt (req.headers.app_id);
) {
if (isNaN (app_id)) {
res.status (http.status_bad_request) res.status (http.status_bad_request)
.end (); .end ('app id not specified');
} return;
else {
res.status (http.status_ok)
.json (await db.log.get_all (parseInt (req.headers.app_id)));
} }
res.status (http.status_ok)
.json (await db.log.get_all (
parseInt (req.headers.app_id),
isNaN (limit) ? 100 : limit,
isNaN (offset) ? 0 : offset
));
}; };

View File

@ -10,7 +10,7 @@
const router = require ('express') const router = require ('express')
.Router (); .Router ();
router.use(require('./dump')); router.use (require ('./dump'));
router.get ('/log', require ('./get-log')); router.get ('/log', require ('./get-log'));
router.get ('/app', require ('./get-app')); router.get ('/app', require ('./get-app'));

View File

@ -16,17 +16,15 @@ module.exports = async (req, res) => {
app_id === 'undefined' app_id === 'undefined'
|| isNaN (parseInt (app_id)) || isNaN (parseInt (app_id))
) { ) {
console.log('bad request, did not receive app id');
res.status (http.status_bad_request) res.status (http.status_bad_request)
.end (); .end ('app id not specified');
return; return;
} }
const log = req.body; const log = req.body;
if (typeof log !== 'object') { if (typeof log !== 'object') {
console.log('bad request, did not receive data in json format');
res.status (http.status_bad_request) res.status (http.status_bad_request)
.end (); .end ('invalid data format');
return; return;
} }

View File

@ -5,16 +5,25 @@
* Created by Timo Hocker <timo@scode.ovh>, August 2020 * Created by Timo Hocker <timo@scode.ovh>, August 2020
*/ */
/* eslint-disable no-sync */
'use strict'; 'use strict';
const knex = require ('knex'); const knex = require ('knex');
const fs = require ('fs');
let db = null; let db = null;
async function init (use_fake_seed) { async function init (use_fake_seed) {
if (!fs.existsSync ('data'))
fs.mkdirSync ('data');
if (use_fake_seed && fs.existsSync ('data/db.sqlite'))
fs.unlinkSync ('data/db.sqlite');
db = knex ({ db = knex ({
client: 'sqlite', client: 'sqlite',
connection: { filename: 'db.sqlite' }, connection: { filename: 'data/db.sqlite' },
migrations: { directory: 'migrations' }, migrations: { directory: 'migrations' },
seeds: { directory: 'seeds' }, seeds: { directory: 'seeds' },
useNullAsDefault: true useNullAsDefault: true

View File

@ -8,7 +8,7 @@
'use strict'; 'use strict';
module.exports = (get_db) => ({ module.exports = (get_db) => ({
get_all (app_id) { get_all (app_id, limit = 100, offset = 0) {
const knex = get_db (); const knex = get_db ();
return knex.select ( return knex.select (
'id', 'id',
@ -17,7 +17,10 @@ module.exports = (get_db) => ({
'timestamp' 'timestamp'
) )
.from ('log') .from ('log')
.where ({ app_id }); .where ({ app_id })
.orderBy ('timestamp')
.limit (Math.min (limit, 10000))
.offset (offset);
}, },
insert (app_id, message, data = '{}', timestamp = (new Date)) { insert (app_id, message, data = '{}', timestamp = (new Date)) {
const knex = get_db (); const knex = get_db ();

View File

@ -9,22 +9,16 @@
"serve": "vue-cli-service serve" "serve": "vue-cli-service serve"
}, },
"dependencies": { "dependencies": {
"@sapphirecode/auth-client-helper": "^1.1.1",
"@sapphirecode/auth-server-helper": "^1.1.2",
"@sapphirecode/consts": "^1.1.28", "@sapphirecode/consts": "^1.1.28",
"@sapphirecode/crypto-helper": "^1.1.57", "@sapphirecode/crypto-helper": "^1.1.57",
"@sapphirecode/password-helper": "^1.0.47",
"@sapphirecode/ui-modules": "^0.1.1",
"@sapphirecode/utilities": "^1.8.5", "@sapphirecode/utilities": "^1.8.5",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"chart.js": "^2.9.3", "chart.js": "^2.9.3",
"connect-history-api-fallback": "^1.6.0", "connect-history-api-fallback": "^1.6.0",
"cookie-parser": "^1.4.5",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"express": "^4.17.1", "express": "^4.17.1",
"express-http-proxy": "^1.6.2", "express-http-proxy": "^1.6.2",
"faker": "^4.1.0", "faker": "^4.1.0",
"hjson": "^3.2.1",
"knex": "^0.21.2", "knex": "^0.21.2",
"simplex-noise": "^2.4.0", "simplex-noise": "^2.4.0",
"sqlite3": "^5.0.0", "sqlite3": "^5.0.0",
@ -53,4 +47,4 @@
"name": "Timo Hocker", "name": "Timo Hocker",
"email": "timo@scode.ovh" "email": "timo@scode.ovh"
} }
} }

View File

@ -22,9 +22,9 @@ async function create_app (knex) {
function create_log (index, simplex) { function create_log (index, simplex) {
const data = { const data = {
num1: faker.random.number (), light: faker.random.number (),
num2: simplex.noise2D (index * 0.1, 0), temperature: simplex.noise2D (index * 0.1, 0),
num3: simplex.noise2D (index * 0.1, 1000) humidity: simplex.noise2D (index * 0.1, 1000)
}; };
return { return {
app_id: faker.random.arrayElement (apps), app_id: faker.random.arrayElement (apps),

View File

@ -10,10 +10,16 @@
async function seed (knex) { async function seed (knex) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log ('creating prod seeds'); console.log ('creating prod seeds');
await knex ('app')
.insert ( const apps = await knex ('app')
{ name: 'test app' } .select ();
);
if (apps.length < 1) {
await knex ('app')
.insert (
{ name: 'test app' }
);
}
} }
module.exports = { seed }; module.exports = { seed };

View File

@ -7,6 +7,14 @@
class="label" class="label"
v-text="template.name" v-text="template.name"
/> />
<button
v-if="removable"
class="array_remove"
type="button"
@click="$emit('remove')"
>
X
</button>
<!-- editor --> <!-- editor -->
<div <div
v-if="template.type === 'object'" v-if="template.type === 'object'"
@ -26,10 +34,11 @@
> >
<ConfigEditor <ConfigEditor
v-for="(child,key) of config" v-for="(child,key) of config"
:key="key" :key="salt (key)"
v-model="config[key]" v-model="config[key]"
:template="template.child" :template="template.child"
:enabled="is_enabled(template.child.if)" :removable="true"
@remove="config.splice(key, 1)"
/> />
<button <button
type="button" type="button"
@ -83,8 +92,10 @@
</template> </template>
<script> <script>
import { create_salt } from '@sapphirecode/crypto-helper';
import { resolve_data } from '../helper'; import { resolve_data } from '../helper';
export default { export default {
name: 'ConfigEditor', name: 'ConfigEditor',
props: { props: {
@ -98,6 +109,10 @@ export default {
enabled: { enabled: {
type: Boolean, type: Boolean,
default: true default: true
},
removable: {
type: Boolean,
default: false
} }
}, },
data () { data () {
@ -155,6 +170,9 @@ export default {
return res; return res;
} }
return null; return null;
},
salt () {
return create_salt ();
} }
} }
}; };
@ -177,4 +195,11 @@ export default {
display: inline-block; display: inline-block;
grid-column: label; grid-column: label;
} }
.array_remove {
display: inline-block;
width: 20px;
height: 20px;
padding: 0;
}
</style> </style>

View File

@ -5,38 +5,52 @@
* Created by Timo Hocker <timo@scode.ovh>, August 2020 * Created by Timo Hocker <timo@scode.ovh>, August 2020
*/ */
export default [ export default {
{ sources: [
type: 'chart', {
x: 'timestamp', name: 'default',
y: [ limit: 140,
{ offset: 0
label: 'temperature', },
field: 'data/temperature', {
color: '#ff0000', name: 'secondary',
fill: '#0000' limit: 10,
}, offset: 0
{ }
label: 'humidity', ],
field: 'data/humidity', displays: [
color: '#0000ff', {
fill: '#0000' source: 'default',
}, type: 'chart',
{ x: 'timestamp',
label: 'light', y: [
field: 'data/light', {
color: '#ffff00', label: 'temperature',
fill: '#0000' field: 'data/temperature',
} color: '#ff0000',
] fill: '#0000'
}, },
{ {
type: 'table', label: 'humidity',
columns: [ field: 'data/humidity',
'id', color: '#0000ff',
'message', fill: '#0000'
'data', },
'timestamp' {
] label: 'light',
} field: 'data/light',
]; color: '#ffff00',
fill: '#0000'
}
]
},
{
source: 'secondary',
type: 'table',
columns: [
'timestamp',
'data'
]
}
]
};

View File

@ -11,17 +11,49 @@ import Vuex from 'vuex';
Vue.use (Vuex); Vue.use (Vuex);
export default new Vuex.Store ({ export default new Vuex.Store ({
state: { log: [] }, state: { log: {} },
mutations: { mutations: {
set_log (state, log) { set_log (state, log) {
state.log = log; state.log = log;
} }
}, },
getters: {
log (state) {
return (source) => {
if (typeof state.log[source] === 'undefined')
return [];
return state.log[source];
};
}
},
actions: { actions: {
async get_log ({ commit }, { app_id }) { async get_log ({ commit }, { app_id, sources }) {
const log = await fetch ('/log', { headers: { app_id } }) const logs = {};
.then ((res) => res.json ()); for (const source of sources) {
commit ('set_log', log); // eslint-disable-next-line no-await-in-loop
const log = await fetch ('/log', {
headers: {
app_id,
offset: source.offset,
limit: source.limit
}
})
.then ((res) => res.json ())
.then ((json) => json.map ((entry) => {
entry.data = JSON.parse (entry.data);
const time
= (/(?<y>[0-9]+-[0-9]+-[0-9]+)T(?<t>[0-9]+:[0-9]+:[0-9]+)/u)
.exec (
new Date (entry.timestamp)
.toISOString ()
);
entry.timestamp = `${time.groups.y} ${time.groups.t}`;
return entry;
}));
logs[source.name] = log;
}
commit ('set_log', logs);
} }
}, },
modules: {} modules: {}

View File

@ -6,43 +6,74 @@
*/ */
export default { export default {
type: 'array', type: 'object',
child: { properties: [
type: 'object', {
properties: [ type: 'array',
{ name: 'sources',
type: 'string', child: {
name: 'type', type: 'object',
choices: [ properties: [
'table', {
'chart' type: 'string',
name: 'name'
},
{
type: 'number',
name: 'limit'
},
{
type: 'number',
name: 'offset'
}
] ]
},
{
name: 'columns',
type: 'array',
child: { type: 'string' },
if: { prop: 'type', op: '=', val: 'table' }
},
{
name: 'x',
type: 'string',
if: { prop: 'type', op: '=', val: 'chart' }
},
{
name: 'y',
type: 'array',
if: { prop: 'type', op: '=', val: 'chart' },
child: {
type: 'object',
properties: [
{ type: 'string', name: 'label' },
{ type: 'string', name: 'field' },
{ type: 'string', name: 'color' },
{ type: 'string', name: 'fill' }
]
}
} }
] },
} {
type: 'array',
name: 'displays',
child: {
type: 'object',
properties: [
{
type: 'string',
name: 'source'
},
{
type: 'string',
name: 'type',
choices: [
'table',
'chart'
]
},
{
name: 'columns',
type: 'array',
child: { type: 'string' },
if: { prop: 'type', op: '=', val: 'table' }
},
{
name: 'x',
type: 'string',
if: { prop: 'type', op: '=', val: 'chart' }
},
{
name: 'y',
type: 'array',
if: { prop: 'type', op: '=', val: 'chart' },
child: {
type: 'object',
properties: [
{ type: 'string', name: 'label' },
{ type: 'string', name: 'field' },
{ type: 'string', name: 'color' },
{ type: 'string', name: 'fill' }
]
}
}
]
}
}
]
}; };

View File

@ -7,10 +7,10 @@
:template="template" :template="template"
/> />
<ViewComponent <ViewComponent
v-for="(item,key) of saved_config" v-for="(item,key) of saved_config.displays"
:key="key" :key="key"
:config="item" :config="item"
:data="parsed_log" :data="log(item.source)"
/> />
</div> </div>
</template> </template>
@ -32,17 +32,9 @@ export default {
template: default_template template: default_template
}; };
}, },
computed: { computed: { ...Vuex.mapGetters ({ log: 'log' }) },
parsed_log () {
return this.log.map ((l) => {
l.data = JSON.parse (l.data);
return l;
});
},
...Vuex.mapState ({ log: (state) => state.log })
},
mounted () { mounted () {
this.get_log ({ app_id: this.$route.params.id }); this.fetch_log ();
document.body.addEventListener ('keydown', (ev) => { document.body.addEventListener ('keydown', (ev) => {
if (ev.key === 's' && ev.ctrlKey) { if (ev.key === 's' && ev.ctrlKey) {
this.save_config (); this.save_config ();
@ -59,6 +51,13 @@ export default {
body: JSON.stringify (this.config) body: JSON.stringify (this.config)
}); });
this.saved_config = copy_object (this.config); this.saved_config = copy_object (this.config);
this.fetch_log ();
},
fetch_log () {
this.get_log ({
app_id: this.$route.params.id,
sources: this.saved_config.sources
});
}, },
...Vuex.mapActions ({ get_log: 'get_log' }) ...Vuex.mapActions ({ get_log: 'get_log' })
} }

View File

@ -936,35 +936,12 @@
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b"
integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==
"@phc/format@^1.0.0": "@sapphirecode/consts@^1.1.28":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@phc/format/-/format-1.0.0.tgz#b5627003b3216dc4362125b13f48a4daa76680e4"
integrity sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==
"@sapphirecode/auth-client-helper@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@sapphirecode/auth-client-helper/-/auth-client-helper-1.1.1.tgz#27c268007a2c392ae921fa2b5981d3257c593f85"
integrity sha512-D7tJV5knGIb3DdfKQI/cn3PT45tD4kzNArXyL1vLQNpkGORMj3Fs7285I/hi1Qrd7pRNFm0PcaokIV84n9lt8A==
dependencies:
"@sapphirecode/consts" "^1.1.18"
"@sapphirecode/crypto-helper" "^1.1.44"
node-fetch "^2.6.0"
"@sapphirecode/auth-server-helper@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@sapphirecode/auth-server-helper/-/auth-server-helper-1.1.2.tgz#9c3dd34cd55e6b771e878d0001e4b066fb9f8f6a"
integrity sha512-twzMZrbHut8OVVjDs9vbQEcTIl6yPAuIOsjV+eeNbX8PgBGUqmEPNcRAEYEgVthmdgtB9OH/6e+xCbn0noqBxw==
dependencies:
"@sapphirecode/consts" "^1.1.18"
"@sapphirecode/crypto-helper" "^1.1.44"
"@sapphirecode/password-helper" "^1.0.35"
"@sapphirecode/consts@^1.1.18", "@sapphirecode/consts@^1.1.28":
version "1.1.28" version "1.1.28"
resolved "https://registry.yarnpkg.com/@sapphirecode/consts/-/consts-1.1.28.tgz#4f9400a80666c3e41b55acada999c877d32eb55c" resolved "https://registry.yarnpkg.com/@sapphirecode/consts/-/consts-1.1.28.tgz#4f9400a80666c3e41b55acada999c877d32eb55c"
integrity sha512-OVZpkhOJtdzf379GNVPBb3D1iqTTSger8/LF/hmq9dqvrcfHm+rara2jChg9qOqk840EEzZCLEFLjyEMz+aDeA== integrity sha512-OVZpkhOJtdzf379GNVPBb3D1iqTTSger8/LF/hmq9dqvrcfHm+rara2jChg9qOqk840EEzZCLEFLjyEMz+aDeA==
"@sapphirecode/crypto-helper@^1.1.44", "@sapphirecode/crypto-helper@^1.1.57": "@sapphirecode/crypto-helper@^1.1.57":
version "1.1.57" version "1.1.57"
resolved "https://registry.yarnpkg.com/@sapphirecode/crypto-helper/-/crypto-helper-1.1.57.tgz#cfa7d7fefd417e875c2b080816b63edf699d79bf" resolved "https://registry.yarnpkg.com/@sapphirecode/crypto-helper/-/crypto-helper-1.1.57.tgz#cfa7d7fefd417e875c2b080816b63edf699d79bf"
integrity sha512-ReKGCFOMq+S8y/XEY2bjG5BQFoYzoebiJi/1BYuu6WXLLTIzGO2JkZ7rsFZV2FEW1dQGVdbjpGmovMwtZjJhtw== integrity sha512-ReKGCFOMq+S8y/XEY2bjG5BQFoYzoebiJi/1BYuu6WXLLTIzGO2JkZ7rsFZV2FEW1dQGVdbjpGmovMwtZjJhtw==
@ -1000,18 +977,6 @@
eslint-plugin-node "^11.1.0" eslint-plugin-node "^11.1.0"
eslint-plugin-sort-requires-by-path "^1.0.2" eslint-plugin-sort-requires-by-path "^1.0.2"
"@sapphirecode/password-helper@^1.0.35", "@sapphirecode/password-helper@^1.0.47":
version "1.0.48"
resolved "https://registry.yarnpkg.com/@sapphirecode/password-helper/-/password-helper-1.0.48.tgz#188c374ca4c8e72826129a949aeec852fb1f4ac9"
integrity sha512-gHbbg+6BUivYOzDnG+21s/6TcTxN4MYVOno0De57EAu4JnuJZkYZumrz0y2U9NLDywufGKJXphvNHK/AhdcHhQ==
dependencies:
argon2 "^0.27.0"
"@sapphirecode/ui-modules@^0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@sapphirecode/ui-modules/-/ui-modules-0.1.1.tgz#97bce95999f4fa42f12a7b8af9bcd9bd940d47ee"
integrity sha512-yPho+ekXGjHGG9yvEcpfsZYT8jq9WwvxDHNnl962YoF8lmdVPV7NjWzYJ1cQpJWgT6GjikM4JimLp9OotrYO/w==
"@sapphirecode/utilities@^1.8.5": "@sapphirecode/utilities@^1.8.5":
version "1.8.5" version "1.8.5"
resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.8.5.tgz#86bee5bd5aae2b7577ea33c39f459e9e9b35aaae" resolved "https://registry.yarnpkg.com/@sapphirecode/utilities/-/utilities-1.8.5.tgz#86bee5bd5aae2b7577ea33c39f459e9e9b35aaae"
@ -1783,16 +1748,6 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0" delegates "^1.0.0"
readable-stream "^2.0.6" readable-stream "^2.0.6"
argon2@^0.27.0:
version "0.27.0"
resolved "https://registry.yarnpkg.com/argon2/-/argon2-0.27.0.tgz#0e92acfab23041544208d184acf8c3ca61a67e3f"
integrity sha512-IkhJhz/4qaZ6RpYyRZvAMOu+EysF40z3J8jksvv0V9LvQFo13d2WBQr5lPuMzZid2k5XpdbQd2oVsgXR4Oi8TQ==
dependencies:
"@phc/format" "^1.0.0"
node-addon-api "^3.0.0"
node-pre-gyp "^0.15.0"
opencollective-postinstall "^2.0.3"
argparse@^1.0.7: argparse@^1.0.7:
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -2819,14 +2774,6 @@ convert-source-map@^1.7.0:
dependencies: dependencies:
safe-buffer "~5.1.1" safe-buffer "~5.1.1"
cookie-parser@^1.4.5:
version "1.4.5"
resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.5.tgz#3e572d4b7c0c80f9c61daf604e4336831b5d1d49"
integrity sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==
dependencies:
cookie "0.4.0"
cookie-signature "1.0.6"
cookie-signature@1.0.6: cookie-signature@1.0.6:
version "1.0.6" version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@ -4670,11 +4617,6 @@ highlight.js@^9.6.0:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.3.tgz#a1a0a2028d5e3149e2380f8a865ee8516703d634" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.3.tgz#a1a0a2028d5e3149e2380f8a865ee8516703d634"
integrity sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ== integrity sha512-zBZAmhSupHIl5sITeMqIJnYCDfAEc3Gdkqj65wC1lpI468MMQeeQkhcIAvk+RylAkxrCcI9xy9piHiXeQ1BdzQ==
hjson@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/hjson/-/hjson-3.2.1.tgz#20de41dc87fc9a10d1557d0230b0e02afb1b09ac"
integrity sha512-OhhrFMeC7dVuA1xvxuXGTv/yTdhTvbe8hz+3LgVNsfi9+vgz0sF/RrkuX8eegpKaMc9cwYwydImBH6iePoJtdQ==
hmac-drbg@^1.0.0: hmac-drbg@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@ -6101,7 +6043,7 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
needle@^2.2.1, needle@^2.5.0: needle@^2.2.1:
version "2.5.0" version "2.5.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0" resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0"
integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA== integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==
@ -6137,16 +6079,6 @@ node-addon-api@2.0.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b"
integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA== integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==
node-addon-api@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.0.0.tgz#812446a1001a54f71663bed188314bba07e09247"
integrity sha512-sSHCgWfJ+Lui/u+0msF3oyCgvdkhxDbkCS6Q8uiJquzOimkJBvX6hl5aSSA7DR1XbMpdM8r7phjcF63sF4rkKg==
node-fetch@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-forge@0.9.0: node-forge@0.9.0:
version "0.9.0" version "0.9.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
@ -6224,22 +6156,6 @@ node-pre-gyp@^0.11.0:
semver "^5.3.0" semver "^5.3.0"
tar "^4" 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.60: node-releases@^1.1.60:
version "1.1.60" version "1.1.60"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.60.tgz#6948bdfce8286f0b5d0e5a88e8384e954dfe7084"
@ -6516,11 +6432,6 @@ open@^6.3.0:
dependencies: dependencies:
is-wsl "^1.1.0" is-wsl "^1.1.0"
opencollective-postinstall@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==
opener@^1.5.1: opener@^1.5.1:
version "1.5.1" version "1.5.1"
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
@ -8522,7 +8433,7 @@ tar@^2.0.0:
fstream "^1.0.12" fstream "^1.0.12"
inherits "2" inherits "2"
tar@^4, tar@^4.4.2: tar@^4:
version "4.4.13" version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==