1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-04-07 21:38:58 +02:00

Optimised loading time by getting rid of launcher and caching module paths

This commit is contained in:
Laurent Cozic 2017-08-04 22:13:29 +02:00
parent 024be942a9
commit 3a5887ff14
27 changed files with 155 additions and 155 deletions

View File

@ -141,12 +141,6 @@ class Application {
continue;
}
if (arg == '--completion' || arg == '--compbash' || arg == '--compgen') {
// Handled by omelette
argv.splice(0, 1);
continue;
}
if (arg == '--autocompletion') {
this.autocompletion_.active = true;
argv.splice(0, 1);
@ -175,6 +169,9 @@ class Application {
if (arg == '--ac-line') {
if (!nextArg) throw new Error(_('Usage: %s', '--ac-line <line>'));
let line = nextArg.replace(/\|__QUOTE__\|/g, '"');
line = line.replace(/\|__SPACE__\|/g, ' ');
line = line.replace(/\|__OPEN_RB__\|/g, '(');
line = line.replace(/\|__OPEN_CB__\|/g, ')');
line = line.split('|__SEP__|');
this.autocompletion_.line = line;
argv.splice(0, 2);
@ -280,8 +277,9 @@ class Application {
async commandMetadata() {
if (this.commandMetadata_) return this.commandMetadata_;
const osTmpdir = require('os-tmpdir');
const storage = require('node-persist');
await storage.init({ dir: 'commandMetadata', ttl: 1000 * 60 * 60 * 24 });
await storage.init({ dir: osTmpdir() + '/commandMetadata', ttl: 1000 * 60 * 60 * 24 });
let output = await storage.getItem('metadata');
if (Setting.value('env') != 'dev' && output) {
@ -326,7 +324,7 @@ class Application {
}
async execCommand(argv) {
if (!argv.length) throw new Error('Empty command');
if (!argv.length) return this.execCommand(['help']);
const commandName = argv[0];
this.activeCommand_ = this.findCommandByName(commandName);
const cmdArgs = cliUtils.makeCommandArgs(this.activeCommand_, argv);
@ -416,6 +414,8 @@ class Application {
if (!items.length) return;
for (let i = 0; i < items.length; i++) {
items[i] = items[i].replace(/ /g, '\\ ');
items[i] = items[i].replace(/\(/g, '\\(');
items[i] = items[i].replace(/\)/g, '\\)');
}
console.info(items.join("\n"));
}

View File

@ -1,39 +0,0 @@
import { app } from './app.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
// For now, to go around this issue: https://github.com/dthree/vorpal/issues/114
function quotePromptArg(s) {
if (s.indexOf(' ') >= 0) {
return '"' + s + '"';
}
return s;
}
function autocompleteFolders() {
return Folder.all({ includeConflictFolder: true }).then((folders) => {
let output = [];
for (let i = 0; i < folders.length; i++) {
output.push(quotePromptArg(folders[i].title));
}
return output;
});
}
async function autocompleteItems() {
let items = [];
if (!app().currentFolder()) {
items = await Folder.all();
} else {
items = await Note.previews(app().currentFolder().id);
}
let output = [];
for (let i = 0; i < items.length; i++) {
output.push(quotePromptArg(items[i].title));
}
return output;
}
export { autocompleteFolders, autocompleteItems };

View File

@ -14,6 +14,9 @@ _|__APPNAME__|_completion() {
ESCAPED_LINE="$ESCAPED_LINE|__SEP__|"
fi
WORD="${WORD/\"/|__QUOTE__|}"
WORD="${WORD/\\(/|__OPEN_RB__|}"
WORD="${WORD/\\)/|__CLOSE_RB__|}"
WORD="${WORD/\\ /|__SPACE__|}"
ESCAPED_LINE="$ESCAPED_LINE$WORD"
done

View File

@ -16,10 +16,6 @@ class BaseCommand {
return [];
}
autocomplete() {
return null;
}
options() {
return [];
}

View File

@ -4,7 +4,6 @@ import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { autocompleteItems } from './autocomplete.js';
class Command extends BaseCommand {
@ -22,10 +21,6 @@ class Command extends BaseCommand {
];
}
autocomplete() {
return { data: autocompleteItems };
}
async action(args) {
let title = args['note'];

View File

@ -4,7 +4,6 @@ import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { autocompleteItems } from './autocomplete.js';
class Command extends BaseCommand {
@ -16,10 +15,6 @@ class Command extends BaseCommand {
return _('Duplicates the notes matching <note> to [notebook]. If no notebook is specified the note is duplicated in the current notebook.');
}
autocomplete() {
return { data: autocompleteItems };
}
async action(args) {
let folder = null;
if (args['notebook']) {

View File

@ -6,7 +6,6 @@ import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { Setting } from 'lib/models/setting.js';
import { BaseModel } from 'lib/base-model.js';
import { autocompleteItems } from './autocomplete.js';
import { cliUtils } from './cli-utils.js';
class Command extends BaseCommand {
@ -19,10 +18,6 @@ class Command extends BaseCommand {
return _('Edit note.');
}
autocomplete() {
return { data: autocompleteItems };
}
async action(args) {
let watcher = null;
let newNote = null;

View File

@ -4,7 +4,6 @@ import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { autocompleteItems } from './autocomplete.js';
class Command extends BaseCommand {
@ -16,10 +15,6 @@ class Command extends BaseCommand {
return _('Displays a geolocation URL for the note.');
}
autocomplete() {
return { data: autocompleteItems };
}
async action(args) {
let title = args['note'];

View File

@ -26,6 +26,8 @@ class Command extends BaseCommand {
output.push(renderCommandHelp(command));
}
output.sort();
this.log(output.join("\n\n"));
}

View File

@ -5,7 +5,6 @@ import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Setting } from 'lib/models/setting.js';
import { Note } from 'lib/models/note.js';
import { autocompleteFolders } from './autocomplete.js';
import { sprintf } from 'sprintf-js';
import { time } from 'lib/time-utils.js';
import { cliUtils } from './cli-utils.js';
@ -31,10 +30,6 @@ class Command extends BaseCommand {
];
}
autocomplete() {
return { data: autocompleteFolders };
}
async action(args) {
let pattern = args['note-pattern'];
let items = [];

View File

@ -4,7 +4,6 @@ import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { autocompleteItems } from './autocomplete.js';
class Command extends BaseCommand {
@ -16,10 +15,6 @@ class Command extends BaseCommand {
return _('Moves the notes matching <note-pattern> to [notebook].');
}
autocomplete() {
return { data: autocompleteItems };
}
async action(args) {
const pattern = args['note-pattern'];
const destination = args['notebook'];

View File

@ -5,7 +5,6 @@ import { BaseItem } from 'lib/models/base-item.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { BaseModel } from 'lib/base-model.js';
import { autocompleteItems } from './autocomplete.js';
import { cliUtils } from './cli-utils.js';
class Command extends BaseCommand {
@ -18,10 +17,6 @@ class Command extends BaseCommand {
return _('Deletes the notes matching <note-pattern>.');
}
autocomplete() {
return { data: autocompleteItems };
}
options() {
return [
['-f, --force', _('Deletes the items without asking for confirmation.')],

View File

@ -4,7 +4,6 @@ import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { autocompleteFolders } from './autocomplete.js';
import { sprintf } from 'sprintf-js';
import { time } from 'lib/time-utils.js';
@ -49,7 +48,7 @@ class Command extends BaseCommand {
if (idx >= 0) {
let fragment = note.body.substr(Math.max(0, idx - fragmentLength / 2), fragmentLength);
fragment = fragment.replace(/\n/g, ' ');
line = sprintf('%s: %s / %s: %s', BaseModel.shortId(note.id), note.title, parent.title, fragment);
line = sprintf('%s: %s / %s: %s', BaseModel.shortId(note.id), parent.title, note.title, fragment);
} else {
line = sprintf('%s: %s / %s', BaseModel.shortId(note.id), parent.title, note.title);
}

View File

@ -5,7 +5,6 @@ import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { BaseItem } from 'lib/models/base-item.js';
import { autocompleteItems } from './autocomplete.js';
class Command extends BaseCommand {
@ -17,10 +16,6 @@ class Command extends BaseCommand {
return _('Sets the property <name> of the given <note> to the given [value].');
}
autocomplete() {
return { data: autocompleteItems };
}
hidden() {
return true;
}

View File

@ -5,7 +5,6 @@ import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { Note } from 'lib/models/note.js';
import { time } from 'lib/time-utils.js';
import { autocompleteItems } from './autocomplete.js';
class Command extends BaseCommand {
@ -17,10 +16,6 @@ class Command extends BaseCommand {
return _('<todo-command> can either be "toggle" or "clear". Use "toggle" to toggle the given todo between completed and uncompleted state (If the target is a regular note it will be converted to a todo). Use "clear" to convert the todo back to a regular note.');
}
autocomplete() {
return { data: autocompleteItems };
}
async action(args) {
const action = args['todo-command'];
const pattern = args['note-pattern'];

View File

@ -3,7 +3,6 @@ import { app } from './app.js';
import { _ } from 'lib/locale.js';
import { BaseModel } from 'lib/base-model.js';
import { Folder } from 'lib/models/folder.js';
import { autocompleteFolders } from './autocomplete.js';
class Command extends BaseCommand {

View File

@ -58,6 +58,13 @@ process.on("SIGINT", async function() {
await application.cancelCurrentCommand();
});
process.stdout.on('error', function( err ) {
// https://stackoverflow.com/questions/12329816/error-write-epipe-when-piping-node-output-to-head#15884508
if (err.code == "EPIPE") {
process.exit(0);
}
});
application.start().catch((error) => {
console.error(_('Fatal error:'));
console.error(error);

View File

@ -1,43 +0,0 @@
#!/usr/bin/env node
// Because all the files in the "lib" directory are included as "lib/file.js" it
// means "lib" must be in NODE_PATH, however modifying the global NODE_PATH
// variable would be messy. So instead, the path is set temporarily just before running
// the app. To do this, this wrapper is needed.
// See https://gist.github.com/branneman/8048520
// Original wrapper code from https://gist.github.com/branneman/8775568
'use strict';
var spawn = require('child_process').spawn;
var args = ['main.js'];
if (process.argv[1].indexOf('joplindev') >= 0) {
args.push('--profile');
args.push('/mnt/d/Temp/TestNotes2');
args.push('--stack-trace-enabled');
args.push('--log-level');
args.push('debug');
args.push('--env');
args.push('dev');
}
var processArgs = process.argv.splice(2);
args = args.concat(processArgs);
var opt = {
cwd: __dirname,
env: (function() {
process.env.NODE_PATH = '.'; // Enables require() calls relative to the cwd :)
return process.env;
}()),
stdio: [process.stdin, process.stdout, process.stderr]
};
var app = spawn(process.execPath, args, opt);
// Pass on the exit code
app.on('close', (code) => {
process.exit(code);
});

View File

@ -1,15 +1,31 @@
#!/bin/bash
set -e
CLIENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
mkdir -p "$CLIENT_DIR/build"
rm -f "$CLIENT_DIR/app/lib"
ln -s "$CLIENT_DIR/../ReactNativeClient/lib" "$CLIENT_DIR/app"
cp "$CLIENT_DIR/package.json" "$CLIENT_DIR/build"
cp "$CLIENT_DIR/app/autocompletion_template.txt" "$CLIENT_DIR/build"
# require('cache-require-paths');
mkdir -p "$ROOT_DIR/build"
rm -f "$ROOT_DIR/app/lib"
ln -s "$ROOT_DIR/../ReactNativeClient/lib" "$ROOT_DIR/app"
npm run build
#yarn run build
#NODE_PATH="$CLIENT_DIR/build" node "$CLIENT_DIR/build/build-translation.js" --silent
cp "$ROOT_DIR/package.json" "$ROOT_DIR/build"
cp "$ROOT_DIR/app/autocompletion_template.txt" "$ROOT_DIR/build"
# Add modules on top of main.js:
# - cache-require-paths to cache require() calls
# - app-module-path so that lib/something paths can be resolved.
PACKAGE_MD5=$(cat "$ROOT_DIR/package.json.md5")
MAIN_PATH="$ROOT_DIR/build/main.js"
LINE_TO_ADD="var osTmpdir = require('os-tmpdir'); process.env.CACHE_REQUIRE_PATHS_FILE = osTmpdir() + '/joplin-module-path-cache-$PACKAGE_MD5'; require('cache-require-paths'); require('app-module-path').addPath(__dirname);"
RESULT="$(grep "$LINE_TO_ADD" "$MAIN_PATH")"
if [[ -z "$RESULT" ]]; then
echo "Adding extra modules..."
sed -i "2i $LINE_TO_ADD" "$MAIN_PATH"
else
echo "Extra modules already added."
fi
NODE_PATH="$ROOT_DIR/build" node "$ROOT_DIR/build/build-translation.js" --silent

View File

@ -123,6 +123,9 @@ msgstr ""
msgid "Displays a geolocation URL for the note."
msgstr ""
msgid "Displays usage information."
msgstr ""
msgid "Imports an Evernote notebook file (.enex file)."
msgstr ""
@ -240,6 +243,13 @@ msgstr ""
msgid "Synchronisation is already in progress."
msgstr ""
#, javascript-format
msgid ""
"Lock file is already being hold. If you know that no synchronisation is "
"taking place, you may delete the lock file at \"%s\" and resume the "
"operation."
msgstr ""
#, javascript-format
msgid "Synchronisation target: %s (%s)"
msgstr ""
@ -253,7 +263,7 @@ msgstr ""
msgid "Done."
msgstr ""
msgid "Cancelling..."
msgid "Cancelling... Please wait."
msgstr ""
msgid ""
@ -285,6 +295,10 @@ msgstr ""
msgid "%s %s (%s)"
msgstr ""
#, javascript-format
msgid "Received %s"
msgstr ""
msgid "Fatal error:"
msgstr ""
@ -340,6 +354,9 @@ msgstr ""
msgid "Last error: %s (stacktrace in log)."
msgstr ""
msgid "Cancelling..."
msgstr ""
#, javascript-format
msgid "Completed: %s"
msgstr ""

View File

@ -135,6 +135,10 @@ msgstr ""
msgid "Displays a geolocation URL for the note."
msgstr "Afficher l'URL de l'emplacement de la note."
#, fuzzy
msgid "Displays usage information."
msgstr "Affiche les informations de version"
msgid "Imports an Evernote notebook file (.enex file)."
msgstr "Importer un carnet Evernote (fichier .enex)."
@ -268,6 +272,13 @@ msgstr ""
msgid "Synchronisation is already in progress."
msgstr "La synchronisation est déjà en cours."
#, javascript-format
msgid ""
"Lock file is already being hold. If you know that no synchronisation is "
"taking place, you may delete the lock file at \"%s\" and resume the "
"operation."
msgstr ""
#, javascript-format
msgid "Synchronisation target: %s (%s)"
msgstr "Cible de la synchronisation : %s (%s)"
@ -281,7 +292,8 @@ msgstr "Commencement de la synchronisation..."
msgid "Done."
msgstr "Terminé."
msgid "Cancelling..."
#, fuzzy
msgid "Cancelling... Please wait."
msgstr "Annulation..."
#, fuzzy
@ -324,6 +336,10 @@ msgstr "Affiche les informations de version"
msgid "%s %s (%s)"
msgstr "%s %s (%s)"
#, javascript-format
msgid "Received %s"
msgstr ""
msgid "Fatal error:"
msgstr "Erreur fatale :"
@ -385,6 +401,9 @@ msgstr "Etat : %s."
msgid "Last error: %s (stacktrace in log)."
msgstr "Dernière erreur : %s (Plus d'information dans le journal d'erreurs)"
msgid "Cancelling..."
msgstr "Annulation..."
#, javascript-format
msgid "Completed: %s"
msgstr "Terminé : %s"

View File

@ -123,6 +123,9 @@ msgstr ""
msgid "Displays a geolocation URL for the note."
msgstr ""
msgid "Displays usage information."
msgstr ""
msgid "Imports an Evernote notebook file (.enex file)."
msgstr ""
@ -240,6 +243,13 @@ msgstr ""
msgid "Synchronisation is already in progress."
msgstr ""
#, javascript-format
msgid ""
"Lock file is already being hold. If you know that no synchronisation is "
"taking place, you may delete the lock file at \"%s\" and resume the "
"operation."
msgstr ""
#, javascript-format
msgid "Synchronisation target: %s (%s)"
msgstr ""
@ -253,7 +263,7 @@ msgstr ""
msgid "Done."
msgstr ""
msgid "Cancelling..."
msgid "Cancelling... Please wait."
msgstr ""
msgid ""
@ -285,6 +295,10 @@ msgstr ""
msgid "%s %s (%s)"
msgstr ""
#, javascript-format
msgid "Received %s"
msgstr ""
msgid "Fatal error:"
msgstr ""
@ -340,6 +354,9 @@ msgstr ""
msgid "Last error: %s (stacktrace in log)."
msgstr ""
msgid "Cancelling..."
msgstr ""
#, javascript-format
msgid "Completed: %s"
msgstr ""

View File

@ -14,6 +14,7 @@
"dependencies": {
"app-module-path": "^2.2.0",
"babel-plugin-transform-runtime": "^6.23.0",
"cache-require-paths": "^0.3.0",
"follow-redirects": "^1.2.4",
"form-data": "^2.1.4",
"fs-extra": "^3.0.1",
@ -23,6 +24,7 @@
"md5": "^2.2.1",
"moment": "^2.18.1",
"node-fetch": "^1.7.1",
"node-persist": "^2.1.0",
"os-tmpdir": "^1.0.2",
"promise": "^7.1.1",
"proper-lockfile": "^2.0.1",

View File

@ -0,0 +1 @@
e625fbfb1ba79ea6396d492047ab9f17

View File

@ -3,6 +3,7 @@ set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
npm version patch
$SCRIPT_DIR/update-package-md5.sh
bash $SCRIPT_DIR/build.sh
cp "$SCRIPT_DIR/package.json" build/
cp "$SCRIPT_DIR/../README.md" build/

View File

@ -0,0 +1,5 @@
#!/bin/bash
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
MD5="$(cat "$ROOT_DIR/package.json" | md5sum | cut -d' ' -f 1)"
echo -n $MD5 > "$ROOT_DIR/package.json.md5"

View File

@ -754,6 +754,10 @@ browserslist@^2.1.2:
caniuse-lite "^1.0.30000704"
electron-to-chromium "^1.3.16"
cache-require-paths@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/cache-require-paths/-/cache-require-paths-0.3.0.tgz#12a6075a3e4988da4c22f218e29485663e4c4a63"
camelcase@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
@ -1218,6 +1222,13 @@ invariant@^2.2.0, invariant@^2.2.2:
dependencies:
loose-envify "^1.0.0"
is-absolute@^0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb"
dependencies:
is-relative "^0.2.1"
is-windows "^0.2.0"
is-binary-path@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
@ -1300,6 +1311,12 @@ is-primitive@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
is-relative@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5"
dependencies:
is-unc-path "^0.1.1"
is-stream@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
@ -1308,6 +1325,16 @@ is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
is-unc-path@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9"
dependencies:
unc-path-regex "^0.1.0"
is-windows@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
is2@0.0.9:
version "0.0.9"
resolved "https://registry.yarnpkg.com/is2/-/is2-0.0.9.tgz#119556d1d1651a41ba105af803267c80b299f629"
@ -1489,7 +1516,7 @@ minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
"mkdirp@>=0.5 0", mkdirp@^0.5.1:
"mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
@ -1522,6 +1549,14 @@ node-fetch@^1.7.1:
encoding "^0.1.11"
is-stream "^1.0.1"
node-persist@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/node-persist/-/node-persist-2.1.0.tgz#e652bbf3885a04dad6a353d74176177c83914707"
dependencies:
is-absolute "^0.2.6"
mkdirp "~0.5.1"
q "~1.1.1"
node-pre-gyp@^0.6.36, node-pre-gyp@~0.6.31:
version "0.6.36"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786"
@ -1685,6 +1720,10 @@ q@0.9.7:
version "0.9.7"
resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75"
q@~1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/q/-/q-1.1.2.tgz#6357e291206701d99f197ab84e57e8ad196f2a89"
qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
@ -2006,6 +2045,10 @@ uid-number@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
unc-path-regex@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
universalify@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"