From 3b227d1ba25b8864596cdf4fff87019055b348a8 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Sun, 27 Feb 2022 22:59:17 +0100 Subject: [PATCH 1/6] Migrate to ES6 modules --- api/v0/index.js | 22 ++++++++++++---------- index.js | 30 +++++++++++++++++++----------- package.json | 1 + routes/api.js | 9 ++++++--- routes/main.js | 16 ++++++++++------ routes/profile.js | 37 ++++++++++++++++++++----------------- routes/static.js | 7 ++++--- routes/util.js | 6 ++++-- server/demo.js | 2 +- server/index.js | 32 ++++++++++++++++---------------- server/keys.js | 34 +++++++++++++++++++--------------- server/utils.js | 6 +++--- static-src/index.js | 10 +++++----- static-src/kx-claim.js | 6 +++--- static-src/ui.js | 2 +- static-src/utils.js | 9 ++++++++- webpack.config.js | 18 +++++++++++++----- 17 files changed, 145 insertions(+), 102 deletions(-) diff --git a/api/v0/index.js b/api/v0/index.js index b7dd71d..54c3de5 100644 --- a/api/v0/index.js +++ b/api/v0/index.js @@ -27,12 +27,14 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const router = require('express').Router() -const { check, validationResult } = require('express-validator') -const Ajv = require("ajv") +import express from 'express' +import { check, validationResult } from 'express-validator' +import Ajv from 'ajv' +import { generateWKDProfile, generateHKPProfile } from '../../server/index.js' +import 'dotenv/config.js' + +const router = express.Router() const ajv = new Ajv({coerceTypes: true}) -const kx = require('../../server') -require('dotenv').config() const apiProfileSchema = { type: "object", @@ -251,16 +253,16 @@ router.get('/profile/fetch', let data switch (req.query.protocol) { case 'wkd': - data = await kx.generateWKDProfile(req.query.query) + data = await generateWKDProfile(req.query.query) break; case 'hkp': - data = await kx.generateHKPProfile(req.query.query) + data = await generateHKPProfile(req.query.query) break; default: if (req.query.query.includes('@')) { - data = await kx.generateWKDProfile(req.query.query) + data = await generateWKDProfile(req.query.query) } else { - data = await kx.generateHKPProfile(req.query.query) + data = await generateHKPProfile(req.query.query) } break; } @@ -329,4 +331,4 @@ router.get('/profile/verify', } ) -module.exports = router +export default router diff --git a/index.js b/index.js index 1e4df78..e515bfd 100644 --- a/index.js +++ b/index.js @@ -27,13 +27,19 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const express = require('express') -const fs = require('fs') -const app = express() -const { stringReplace } = require('string-replace-middleware') -require('dotenv').config() +import express from 'express' +import { readFileSync } from 'fs' +import { stringReplace } from 'string-replace-middleware' +import 'dotenv/config.js' -const packageData = JSON.parse(fs.readFileSync('package.json')) +import apiRoute from './routes/api.js' +import mainRoute from './routes/main.js' +import profileRoute from './routes/profile.js' +import staticRoute from './routes/static.js' +import utilRoute from './routes/util.js' + +const app = express() +const packageData = JSON.parse(readFileSync('package.json')) app.set('env', process.env.NODE_ENV || "production") app.set('view engine', 'pug') @@ -65,12 +71,14 @@ app.use(stringReplace({ app.use('/favicon.svg', express.static('favicon.svg')) app.use('/robots.txt', express.static('robots.txt')) -app.use('/', require('./routes/main')) -app.use('/api', require('./routes/api')) -app.use('/static', require('./routes/static')) -app.use('/util', require('./routes/util')) -app.use('/', require('./routes/profile')) +app.use('/', mainRoute) +app.use('/api', apiRoute) +app.use('/static', staticRoute) +app.use('/util', utilRoute) +app.use('/', profileRoute) app.listen(app.get('port'), () => { console.log(`Node server listening at http://localhost:${app.get('port')}`) }) + +export default app diff --git a/package.json b/package.json index 9d0ce1b..53fd2c7 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "3.2.0", "description": "A modern, secure and privacy-friendly platform to establish your decentralized online identity", "main": "index.js", + "type": "module", "dependencies": { "ajv": "^8.6.3", "bent": "^7.3.12", diff --git a/routes/api.js b/routes/api.js index 352da6e..1aa2e42 100644 --- a/routes/api.js +++ b/routes/api.js @@ -27,8 +27,11 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const router = require('express').Router() +import express from 'express' +import apiRouter0 from '../api/v0/index.js' -router.use('/0', require('../api/v0/index.js')) +const router = express.Router() -module.exports = router +router.use('/0', apiRouter0) + +export default router diff --git a/routes/main.js b/routes/main.js index 4da9d88..cacf057 100644 --- a/routes/main.js +++ b/routes/main.js @@ -27,9 +27,13 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const router = require('express').Router() -const md = require('markdown-it')({typographer: true}) -const fs = require('fs') +import express from 'express' +import markdownImport from 'markdown-it' +import { readFileSync } from 'fs' +import demoData from '../server/demo.js' + +const router = express.Router() +const md = markdownImport({typographer: true}) router.get('/', (req, res) => { let highlights = [] @@ -44,13 +48,13 @@ router.get('/', (req, res) => { } } - res.render('index', { highlights: highlights, demoData: require('../server/demo.js').data }) + res.render('index', { highlights: highlights, demoData: demoData }) }) router.get('/privacy', (req, res) => { - let rawContent = fs.readFileSync(`./content/privacy-policy.md`, "utf8") + let rawContent = readFileSync(`./content/privacy-policy.md`, "utf8") const content = md.render(rawContent) res.render(`article`, { title: `Privacy policy`, content: content }) }) -module.exports = router +export default router diff --git a/routes/profile.js b/routes/profile.js index a8e8e72..67cd5d3 100644 --- a/routes/profile.js +++ b/routes/profile.js @@ -27,53 +27,56 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const router = require('express').Router() -const bodyParser = require('body-parser').urlencoded({ extended: false }) -const kx = require('../server') +import express from 'express' +import bodyParserImport from 'body-parser' +import { generateSignatureProfile, utils, generateWKDProfile, generateHKPProfile, generateKeybaseProfile } from '../server/index.js' + +const router = express.Router() +const bodyParser = bodyParserImport.urlencoded({ extended: false }) router.get('/sig', (req, res) => { res.render('profile', { isSignature: true, signature: null }) }) router.post('/sig', bodyParser, async (req, res) => { - const data = await kx.generateSignatureProfile(req.body.signature) - const title = kx.utils.generatePageTitle('profile', data) + const data = await generateSignatureProfile(req.body.signature) + const title = utils.generatePageTitle('profile', data) res.render('profile', { title: title, data: data, isSignature: true, signature: req.body.signature }) }) router.get('/wkd/:id', async (req, res) => { - const data = await kx.generateWKDProfile(req.params.id) - const title = kx.utils.generatePageTitle('profile', data) + const data = await generateWKDProfile(req.params.id) + const title = utils.generatePageTitle('profile', data) res.render('profile', { title: title, data: data }) }) router.get('/hkp/:id', async (req, res) => { - const data = await kx.generateHKPProfile(req.params.id) - const title = kx.utils.generatePageTitle('profile', data) + const data = await generateHKPProfile(req.params.id) + const title = utils.generatePageTitle('profile', data) res.render('profile', { title: title, data: data }) }) router.get('/hkp/:server/:id', async (req, res) => { - const data = await kx.generateHKPProfile(req.params.id, req.params.server) - const title = kx.utils.generatePageTitle('profile', data) + const data = await generateHKPProfile(req.params.id, req.params.server) + const title = utils.generatePageTitle('profile', data) res.render('profile', { title: title, data: data }) }) router.get('/keybase/:username/:fingerprint', async (req, res) => { - const data = await kx.generateKeybaseProfile(req.params.username, req.params.fingerprint) - const title = kx.utils.generatePageTitle('profile', data) + const data = await generateKeybaseProfile(req.params.username, req.params.fingerprint) + const title = utils.generatePageTitle('profile', data) res.render('profile', { title: title, data: data }) }) router.get('/:id', async (req, res) => { let data if (req.params.id.includes('@')) { - data = await kx.generateWKDProfile(req.params.id) + data = await generateWKDProfile(req.params.id) } else { - data = await kx.generateHKPProfile(req.params.id) + data = await generateHKPProfile(req.params.id) } - const title = kx.utils.generatePageTitle('profile', data) + const title = utils.generatePageTitle('profile', data) res.render('profile', { title: title, data: data }) }) -module.exports = router +export default router diff --git a/routes/static.js b/routes/static.js index 2a7782f..ba3b800 100644 --- a/routes/static.js +++ b/routes/static.js @@ -27,9 +27,10 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const express = require('express') -const router = require('express').Router() +import express from 'express' + +const router = express.Router() router.use('/', express.static('static')) -module.exports = router +export default router diff --git a/routes/util.js b/routes/util.js index 24b2dd1..fb14437 100644 --- a/routes/util.js +++ b/routes/util.js @@ -27,7 +27,9 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const router = require('express').Router() +import express from 'express' + +const router = express.Router() router.get('/profile-url', function(req, res) { res.render('util/profile-url') @@ -57,4 +59,4 @@ router.get('/wkd/:input', function(req, res) { res.render('util/wkd', { input: req.params.input }) }) -module.exports = router +export default router diff --git a/server/demo.js b/server/demo.js index 5b64875..2be5113 100644 --- a/server/demo.js +++ b/server/demo.js @@ -27,7 +27,7 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -exports.data = { +export default { "claimVersion": 1, "uri": "https://fosstodon.org/@keyoxide", "fingerprint": "9f0048ac0b23301e1f77e994909f6bd6f80f485d", diff --git a/server/index.js b/server/index.js index 67c0a11..2a816b5 100644 --- a/server/index.js +++ b/server/index.js @@ -27,14 +27,14 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const doip = require('doipjs') -const keys = require('./keys') -const libravatar = require('libravatar') +import * as doipjs from 'doipjs' +import { fetchWKD, fetchHKP, fetchSignature, fetchKeybase } from './keys.js' +import libravatar from 'libravatar' const generateWKDProfile = async (id) => { - return keys.fetchWKD(id) + return fetchWKD(id) .then(async key => { - let keyData = await doip.keys.process(key.publicKey) + let keyData = await doipjs.keys.process(key.publicKey) keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` keyData.key.fetchMethod = 'wkd' keyData.key.uri = key.fetchURL @@ -59,9 +59,9 @@ const generateWKDProfile = async (id) => { } const generateHKPProfile = async (id, keyserverDomain) => { - return keys.fetchHKP(id, keyserverDomain) + return fetchHKP(id, keyserverDomain) .then(async key => { - let keyData = await doip.keys.process(key.publicKey) + let keyData = await doipjs.keys.process(key.publicKey) keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` keyData.key.fetchMethod = 'hkp' keyData.key.uri = key.fetchURL @@ -86,7 +86,7 @@ const generateHKPProfile = async (id, keyserverDomain) => { } const generateSignatureProfile = async (signature) => { - return keys.fetchSignature(signature) + return fetchSignature(signature) .then(async key => { let keyData = key.keyData keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` @@ -112,9 +112,9 @@ const generateSignatureProfile = async (signature) => { } const generateKeybaseProfile = async (username, fingerprint) => { - return keys.fetchKeybase(id, keyserverDomain) + return fetchKeybase(id, keyserverDomain) .then(async key => { - let keyData = await doip.keys.process(key.publicKey) + let keyData = await doipjs.keys.process(key.publicKey) keyData.openpgp4fpr = `openpgp4fpr:${keyData.fingerprint.toLowerCase()}` keyData.key.fetchMethod = 'hkp' keyData.key.uri = key.fetchURL @@ -142,7 +142,7 @@ const processKeyData = (keyData) => { keyData.users.forEach(user => { // Remove faulty claims user.claims = user.claims.filter(claim => { - return claim instanceof doip.Claim + return claim instanceof doipjs.Claim }) // Match claims @@ -178,9 +178,9 @@ const computeExtraData = async (key, keyData) => { } } -exports.generateWKDProfile = generateWKDProfile -exports.generateHKPProfile = generateHKPProfile -exports.generateKeybaseProfile = generateKeybaseProfile -exports.generateSignatureProfile = generateSignatureProfile +export { generateWKDProfile } +export { generateHKPProfile } +export { generateKeybaseProfile } +export { generateSignatureProfile } -exports.utils = require('./utils') +export * as utils from './utils.js' diff --git a/server/keys.js b/server/keys.js index d336179..aa24f67 100644 --- a/server/keys.js +++ b/server/keys.js @@ -27,10 +27,10 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const got = require('got') -const doip = require('doipjs') -const openpgp = require('openpgp') -const utils = require('./utils') +import got from 'got' +import * as doipjs from 'doipjs' +import { readKey, readCleartextMessage, verify } from 'openpgp' +import { computeWKDLocalPart } from './utils.js' const fetchWKD = (id) => { return new Promise(async (resolve, reject) => { @@ -47,7 +47,7 @@ const fetchWKD = (id) => { if (!localPart || !domain) { reject(new Error(`The WKD identifier "${id}" is invalid`)); } - const localEncoded = await utils.computeWKDLocalPart(localPart) + const localEncoded = await computeWKDLocalPart(localPart) const urlAdvanced = `https://openpgpkey.${domain}/.well-known/openpgpkey/${domain}/hu/${localEncoded}` const urlDirect = `https://${domain}/.well-known/openpgpkey/hu/${localEncoded}` let plaintext @@ -81,7 +81,7 @@ const fetchWKD = (id) => { } try { - output.publicKey = await openpgp.readKey({ + output.publicKey = await readKey({ binaryKey: plaintext }) } catch(error) { @@ -113,7 +113,7 @@ const fetchHKP = (id, keyserverDomain) => { } try { - output.publicKey = await doip.keys.fetchHKP(id, keyserverDomain) + output.publicKey = await doipjs.keys.fetchHKP(id, keyserverDomain) output.fetchURL = `https://${keyserverDomain}/pks/lookup?op=get&options=mr&search=${query}` } catch(error) { reject(new Error(`No public keys could be fetched using HKP`)) @@ -138,7 +138,7 @@ const fetchSignature = (signature) => { // Check validity of signature let signatureData try { - signatureData = await openpgp.readCleartextMessage({ + signatureData = await readCleartextMessage({ cleartextMessage: signature }) } catch (error) { @@ -147,7 +147,7 @@ const fetchSignature = (signature) => { // Process the signature try { - output.keyData = await doip.signatures.process(signature) + output.keyData = await doipjs.signatures.process(signature) output.publicKey = output.keyData.key.data // TODO Find the URL to the key output.fetchURL = null @@ -161,7 +161,7 @@ const fetchSignature = (signature) => { } // Check validity of signature - const verified = await openpgp.verify({ + const verified = await verify({ message: signatureData, verificationKeys: output.publicKey }) @@ -182,7 +182,7 @@ const fetchKeybase = (username, fingerprint) => { } try { - output.publicKey = await doip.keys.fetchKeybase(username, fingerprint) + output.publicKey = await doipjs.keys.fetchKeybase(username, fingerprint) output.fetchURL = `https://keybase.io/${username}/pgp_keys.asc?fingerprint=${fingerprint}` } catch(error) { reject(new Error(`No public keys could be fetched from Keybase`)) @@ -196,7 +196,11 @@ const fetchKeybase = (username, fingerprint) => { }) } -exports.fetchWKD = fetchWKD -exports.fetchHKP = fetchHKP -exports.fetchSignature = fetchSignature -exports.fetchKeybase = fetchKeybase +const _fetchWKD = fetchWKD +export { _fetchWKD as fetchWKD } +const _fetchHKP = fetchHKP +export { _fetchHKP as fetchHKP } +const _fetchSignature = fetchSignature +export { _fetchSignature as fetchSignature } +const _fetchKeybase = fetchKeybase +export { _fetchKeybase as fetchKeybase } diff --git a/server/utils.js b/server/utils.js index 8848e9c..306b282 100644 --- a/server/utils.js +++ b/server/utils.js @@ -27,15 +27,15 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -const crypto = require('crypto').webcrypto +import { webcrypto as crypto } from 'crypto' -exports.computeWKDLocalPart = async (localPart) => { +export async function computeWKDLocalPart(localPart) { const localPartEncoded = new TextEncoder().encode(localPart.toLowerCase()); const localPartHashed = new Uint8Array(await crypto.subtle.digest('SHA-1', localPartEncoded)); return encodeZBase32(localPartHashed); } -exports.generatePageTitle = (type, data) => { +export function generatePageTitle(type, data) { switch (type) { case 'profile': try { diff --git a/static-src/index.js b/static-src/index.js index 8e8ff4b..10d9bbe 100644 --- a/static-src/index.js +++ b/static-src/index.js @@ -28,11 +28,11 @@ if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ // Import JS libraries -import * as kx from'./keyoxide' -import * as kxKey from'./kx-key' -import * as kxClaim from'./kx-claim' -import * as ui from'./ui' -import * as utils from'./utils' +import * as kx from './keyoxide.js' +import * as kxKey from './kx-key.js' +import * as kxClaim from './kx-claim.js' +import * as ui from './ui.js' +import * as utils from './utils.js' // Import CSS files import './styles.css' diff --git a/static-src/kx-claim.js b/static-src/kx-claim.js index 6549e18..f8f6dc5 100644 --- a/static-src/kx-claim.js +++ b/static-src/kx-claim.js @@ -27,7 +27,7 @@ You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . */ -import * as doip from "doipjs" +import * as doipjs from 'doipjs'; export class Claim extends HTMLElement { // Specify the attributes to observe @@ -45,7 +45,7 @@ export class Claim extends HTMLElement { } async verify() { - const claim = new doip.Claim(JSON.parse(this.getAttribute('data-claim'))); + const claim = new doipjs.Claim(JSON.parse(this.getAttribute('data-claim'))); await claim.verify({ proxy: { policy: 'adaptive', @@ -57,7 +57,7 @@ export class Claim extends HTMLElement { updateContent(value) { const root = this; - const claim = new doip.Claim(JSON.parse(value)); + const claim = new doipjs.Claim(JSON.parse(value)); switch (claim.matches[0].serviceprovider.name) { case 'dns': diff --git a/static-src/ui.js b/static-src/ui.js index 712510d..1fb873c 100644 --- a/static-src/ui.js +++ b/static-src/ui.js @@ -30,7 +30,7 @@ more information on this, and how to apply and follow the GNU AGPL, see { + return crypto.webcrypto + }) + // import { webcrypto as crypto } from 'crypto' +} // Compute local part of Web Key Directory URL export async function computeWKDLocalPart(localPart) { const localPartEncoded = new TextEncoder().encode(localPart.toLowerCase()); - const localPartHashed = new Uint8Array(await crypto.subtle.digest('SHA-1', localPartEncoded)); + const localPartHashed = new Uint8Array(await _crypto.subtle.digest('SHA-1', localPartEncoded)); return encodeZBase32(localPartHashed); } diff --git a/webpack.config.js b/webpack.config.js index 2e92849..3cc166a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,8 +1,11 @@ -const path = require('path') -const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin -const MiniCssExtractPlugin = require("mini-css-extract-plugin") +import { dirname, resolve } from 'path' +import { fileURLToPath } from 'url' +import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer' +import MiniCssExtractPlugin from "mini-css-extract-plugin" -module.exports = (env) => { +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default (env) => { let config if (env.static) { config = { @@ -16,7 +19,7 @@ module.exports = (env) => { }, output: { filename: '[name].js', - path: path.resolve(__dirname, 'static'), + path: resolve(__dirname, 'static'), }, watch: env.mode == "development", module: { @@ -30,6 +33,11 @@ module.exports = (env) => { } ] }, + resolve: { + fallback: { + crypto: false, + } + }, plugins: [ new MiniCssExtractPlugin(), ], From e6f47963998927094eccd7ce36dacfa6e6ff5d7d Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Thu, 3 Mar 2022 15:48:32 +0100 Subject: [PATCH 2/6] Fix crypto fallback --- static-src/utils.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/static-src/utils.js b/static-src/utils.js index a6ffd4d..c7e34c4 100644 --- a/static-src/utils.js +++ b/static-src/utils.js @@ -30,15 +30,13 @@ more information on this, and how to apply and follow the GNU AGPL, see { - return crypto.webcrypto - }) - // import { webcrypto as crypto } from 'crypto' -} // Compute local part of Web Key Directory URL export async function computeWKDLocalPart(localPart) { + if (!_crypto) { + _crypto = (await import('crypto')).webcrypto + } + const localPartEncoded = new TextEncoder().encode(localPart.toLowerCase()); const localPartHashed = new Uint8Array(await _crypto.subtle.digest('SHA-1', localPartEncoded)); return encodeZBase32(localPartHashed); From 9d69a80cf4c358caafd6351f156c0694a05ef49b Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Thu, 3 Mar 2022 16:00:53 +0100 Subject: [PATCH 3/6] Make hostname configurable --- static-src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static-src/utils.js b/static-src/utils.js index c7e34c4..32bfdfe 100644 --- a/static-src/utils.js +++ b/static-src/utils.js @@ -44,7 +44,7 @@ export async function computeWKDLocalPart(localPart) { // Generate Keyoxide profile URL export async function generateProfileURL(data) { - let hostname = window.location.hostname; + let hostname = data.hostname || window.location.hostname; if (data.input == "") { return "Waiting for input..."; From 98ef14f1315f79bca0290399cf800e0e32e23c4c Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Thu, 3 Mar 2022 16:25:14 +0100 Subject: [PATCH 4/6] Export additional function --- server/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/utils.js b/server/utils.js index 306b282..7ec8dd7 100644 --- a/server/utils.js +++ b/server/utils.js @@ -52,7 +52,7 @@ export function generatePageTitle(type, data) { } // Copied from https://github.com/openpgpjs/wkd-client/blob/0d074519e011a5139a8953679cf5f807e4cd2378/src/wkd.js -function encodeZBase32(data) { +export function encodeZBase32(data) { if (data.length === 0) { return ""; } From 9d7336f7868fe7fc65d90e93a2234ebb54f07dd2 Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Thu, 3 Mar 2022 16:25:34 +0100 Subject: [PATCH 5/6] Fix exports --- server/keys.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/server/keys.js b/server/keys.js index aa24f67..9f09db5 100644 --- a/server/keys.js +++ b/server/keys.js @@ -196,11 +196,7 @@ const fetchKeybase = (username, fingerprint) => { }) } -const _fetchWKD = fetchWKD -export { _fetchWKD as fetchWKD } -const _fetchHKP = fetchHKP -export { _fetchHKP as fetchHKP } -const _fetchSignature = fetchSignature -export { _fetchSignature as fetchSignature } -const _fetchKeybase = fetchKeybase -export { _fetchKeybase as fetchKeybase } +export { fetchWKD } +export { fetchHKP } +export { fetchSignature } +export { fetchKeybase } From 69008af8a17ea2199097fe5b2721ff1def28862a Mon Sep 17 00:00:00 2001 From: Yarmo Mackenbach Date: Thu, 3 Mar 2022 16:25:49 +0100 Subject: [PATCH 6/6] Add initial tests --- package.json | 3 + test/browser.test.js | 63 ++++++++ test/server.test.js | 29 ++++ yarn.lock | 361 ++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 435 insertions(+), 21 deletions(-) create mode 100644 test/browser.test.js create mode 100644 test/server.test.js diff --git a/package.json b/package.json index 53fd2c7..faff89f 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,11 @@ }, "devDependencies": { "@vercel/ncc": "^0.33.3", + "chai": "^4.3.6", "css-loader": "^6.6.0", "license-check-and-add": "^4.0.3", "mini-css-extract-plugin": "^2.5.3", + "mocha": "^9.2.1", "nodemon": "^2.0.7", "style-loader": "^3.3.1", "webpack": "^5.69.1", @@ -36,6 +38,7 @@ "scripts": { "start": "node ./", "dev": "yarn run watch & yarn run build:static:dev", + "test": "mocha", "watch": "./node_modules/.bin/nodemon --config nodemon.json ./", "build": "ncc build index.js -o dist", "build:static": "webpack --config webpack.config.js --env static=true --env mode=production", diff --git a/test/browser.test.js b/test/browser.test.js new file mode 100644 index 0000000..b0bb3dc --- /dev/null +++ b/test/browser.test.js @@ -0,0 +1,63 @@ +import 'chai/register-should.js' +import * as utils from '../static-src/utils.js' + +describe('browser', function () { + describe('utils', function () { + describe('computeWKDLocalPart()', function () { + it('should handle "test"', async function () { + const local = await utils.computeWKDLocalPart('test') + local.should.equal('iffe93qcsgp4c8ncbb378rxjo6cn9q6u') + }) + it('should handle "zaphod"', async function () { + const local = await utils.computeWKDLocalPart('zaphod') + local.should.equal('xrea5za9y9auaxq463c9opxt338bnaxu') + }) + }) + describe('encodeZBase32()', function () { + it('should handle a Uint8Array', async function () { + const data = new Uint8Array([ + 169, 74, 143, 229, 204, 177, + 155, 166, 28, 76, 8, 115, + 211, 145, 233, 135, 152, 47, + 187, 211 + ]) + const local = utils.encodeZBase32(data) + local.should.equal('iffe93qcsgp4c8ncbb378rxjo6cn9q6u') + }) + }) + describe('generateProfileURL()', function () { + it('should handle a WKD URL', async function () { + const local = await utils.generateProfileURL({ + source: 'wkd', + input: 'test@doip.rocks', + hostname: 'keyoxide.instance' + }) + local.should.equal('https://keyoxide.instance/test@doip.rocks') + }) + it('should handle a HKP+email URL', async function () { + const local = await utils.generateProfileURL({ + source: 'hkp', + input: 'test@doip.rocks', + hostname: 'keyoxide.instance' + }) + local.should.equal('https://keyoxide.instance/hkp/test@doip.rocks') + }) + it('should handle a HKP+fingerprint URL', async function () { + const local = await utils.generateProfileURL({ + source: 'hkp', + input: '3637202523E7C1309AB79E99EF2DC5827B445F4B', + hostname: 'keyoxide.instance' + }) + local.should.equal('https://keyoxide.instance/3637202523E7C1309AB79E99EF2DC5827B445F4B') + }) + it('should handle a keybase URL', async function () { + const local = await utils.generateProfileURL({ + source: 'keybase', + input: 'https://keybase.io/doip/pgp_keys.asc?fingerprint=3637202523E7C1309AB79E99EF2DC5827B445F4B', + hostname: 'keyoxide.instance' + }) + local.should.equal('https://keyoxide.instance/keybase/doip/3637202523E7C1309AB79E99EF2DC5827B445F4B') + }) + }) + }) +}) \ No newline at end of file diff --git a/test/server.test.js b/test/server.test.js new file mode 100644 index 0000000..cc3d5db --- /dev/null +++ b/test/server.test.js @@ -0,0 +1,29 @@ +import 'chai/register-should.js' +import * as utils from '../server/utils.js' + +describe('server', function () { + describe('utils', function () { + describe('computeWKDLocalPart()', function () { + it('should handle "test"', async function () { + const local = await utils.computeWKDLocalPart('test') + local.should.equal('iffe93qcsgp4c8ncbb378rxjo6cn9q6u') + }) + it('should handle "zaphod"', async function () { + const local = await utils.computeWKDLocalPart('zaphod') + local.should.equal('xrea5za9y9auaxq463c9opxt338bnaxu') + }) + }) + describe('encodeZBase32()', function () { + it('should handle a Uint8Array', async function () { + const data = new Uint8Array([ + 169, 74, 143, 229, 204, 177, + 155, 166, 28, 76, 8, 115, + 211, 145, 233, 135, 152, 47, + 187, 211 + ]) + const local = utils.encodeZBase32(data) + local.should.equal('iffe93qcsgp4c8ncbb378rxjo6cn9q6u') + }) + }) + }) +}) \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e4cbb9b..4aaf2d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -455,6 +455,11 @@ dependencies: "@types/node" "*" +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + "@vercel/ncc@^0.33.3": version "0.33.3" resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.33.3.tgz#aacc6b3ea9f7b175e0c9a18c9b97e4005a2f4fcc" @@ -943,6 +948,11 @@ ansi-align@^3.0.0: dependencies: string-width "^3.0.0" +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz" @@ -953,6 +963,11 @@ ansi-regex@^5.0.0: resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" @@ -960,7 +975,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== @@ -975,7 +990,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@~3.1.1: +anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -990,6 +1005,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz" @@ -1059,6 +1079,11 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz" @@ -1250,6 +1275,11 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserslist@^4.14.5: version "4.16.6" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz" @@ -1361,6 +1391,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + caniuse-lite@^1.0.30001219: version "1.0.30001219" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001219.tgz" @@ -1371,6 +1406,19 @@ caseless@~0.12.0: resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +chai@^4.3.6: + version "4.3.6" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c" + integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + loupe "^2.3.1" + pathval "^1.1.1" + type-detect "^4.0.5" + chalk@^2.0.0: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -1408,6 +1456,26 @@ chardet@^1.2.1: resolved "https://registry.npmjs.org/chardet/-/chardet-1.3.0.tgz" integrity sha512-cyTQGGptIjIT+CMGT5J/0l9c6Fb+565GCFjjeUTKxUO7w3oR+FcNCMEKTn5xtVKaLFmladN7QF68IiQsv5Fbdw== +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chokidar@^3.2.2, chokidar@^3.4.0: version "3.5.1" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz" @@ -1465,6 +1533,15 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + clone-deep@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" @@ -1728,6 +1805,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3: dependencies: ms "2.0.0" +debug@4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== + dependencies: + ms "2.1.2" + debug@^3.2.6: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" @@ -1747,6 +1831,11 @@ decamelize@^1.2.0: resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz" @@ -1771,6 +1860,13 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" @@ -1840,6 +1936,11 @@ dialog-polyfill@^0.5.6: resolved "https://registry.npmjs.org/dialog-polyfill/-/dialog-polyfill-0.5.6.tgz" integrity sha512-ZbVDJI9uvxPAKze6z146rmfUZjBqNEwcnFTVamQzXH+svluiV7swmVIGr7miwADgfgt1G2JQIytypM9fbyhX4w== +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + dijkstrajs@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz" @@ -2018,16 +2119,16 @@ escape-html@~1.0.3: resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= +escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - escodegen@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz" @@ -2292,6 +2393,14 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz" @@ -2307,6 +2416,11 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + follow-redirects@^1.14.7: version "1.14.9" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" @@ -2372,7 +2486,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@~2.3.1: +fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -2387,11 +2501,16 @@ gensync@^1.0.0-beta.2: resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== -get-caller-file@^2.0.1: +get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz" @@ -2445,7 +2564,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.1.0, glob-parent@~5.1.0: +glob-parent@^5.1.0, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -2457,6 +2576,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + 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.0.0, glob@^7.1.3: version "7.1.6" resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" @@ -2539,6 +2670,11 @@ graceful-fs@^4.2.4, graceful-fs@^4.2.9: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + gzip-size@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" @@ -2631,6 +2767,11 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + hijackresponse@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/hijackresponse/-/hijackresponse-4.0.1.tgz" @@ -3058,6 +3199,11 @@ is-typedarray@^1.0.0, is-typedarray@~1.0.0: resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" @@ -3119,6 +3265,13 @@ js-tokens@^4.0.0: resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" @@ -3336,11 +3489,33 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +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== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +loupe@^2.3.1: + version "2.3.4" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.4.tgz#7e0b9bffc76f148f9be769cb1321d3dcf3cb25f3" + integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== + dependencies: + get-func-name "^2.0.0" + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" @@ -3532,7 +3707,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -3552,6 +3727,36 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mocha@^9.2.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.1.tgz#a1abb675aa9a8490798503af57e8782a78f1338e" + integrity sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.2.0" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + mrmime@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.0.tgz#14d387f0585a5233d291baba339b063752a2398b" @@ -3572,11 +3777,16 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.1.1: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +nanoid@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" + integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== + nanoid@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" @@ -3808,6 +4018,13 @@ p-limit@^2.0.0, p-limit@^2.2.0: dependencies: p-try "^2.0.0" +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz" @@ -3822,6 +4039,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" @@ -3902,6 +4126,11 @@ path-type@^4.0.0: resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathval@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" + integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" @@ -4291,6 +4520,13 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + rechoir@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" @@ -4591,7 +4827,7 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -serialize-javascript@^6.0.0: +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== @@ -4847,6 +5083,15 @@ string-width@^4.0.0, string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^4.2.0: + 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== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string.prototype.trimend@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz" @@ -4891,11 +5136,23 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" @@ -4906,6 +5163,13 @@ style-loader@^3.3.1: resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575" integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== +supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" @@ -4920,13 +5184,6 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" @@ -5080,6 +5337,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.8.1: version "0.8.1" resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" @@ -5412,7 +5674,7 @@ which-module@^2.0.0: resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^2.0.1: +which@2.0.2, which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -5446,6 +5708,11 @@ word-wrap@~1.2.3: resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz" @@ -5455,6 +5722,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" @@ -5500,11 +5776,21 @@ y18n@^4.0.0: resolved "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz" @@ -5513,6 +5799,34 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yargs@^13.2.4, yargs@^13.3.0: version "13.3.2" resolved "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz" @@ -5528,3 +5842,8 @@ yargs@^13.2.4, yargs@^13.3.0: which-module "^2.0.0" y18n "^4.0.0" yargs-parser "^13.1.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==