diff --git a/app/ephemeral_config.js b/app/ephemeral_config.js deleted file mode 100644 index 84b498743..000000000 --- a/app/ephemeral_config.js +++ /dev/null @@ -1,14 +0,0 @@ -const path = require('path'); - -const { app } = require('electron'); - -const { start } = require('./base_config'); - -const userDataPath = app.getPath('userData'); -const targetPath = path.join(userDataPath, 'ephemeral.json'); - -const ephemeralConfig = start('ephemeral', targetPath, { - allowMalformedOnStartup: true, -}); - -module.exports = ephemeralConfig; diff --git a/app/user_config.d.ts b/app/user_config.d.ts deleted file mode 100644 index 4b0a2282c..000000000 --- a/app/user_config.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { BaseConfig } from './base_config'; - -type UserConfig = BaseConfig; diff --git a/app/window_state.d.ts b/app/window_state.d.ts deleted file mode 100644 index 90714af01..000000000 --- a/app/window_state.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export function markShouldQuit(): void; -export function shouldQuit(): void; diff --git a/app/window_state.js b/app/window_state.js deleted file mode 100644 index 0cd7dd024..000000000 --- a/app/window_state.js +++ /dev/null @@ -1,14 +0,0 @@ -let shouldQuitFlag = false; - -function markShouldQuit() { - shouldQuitFlag = true; -} - -function shouldQuit() { - return shouldQuitFlag; -} - -module.exports = { - shouldQuit, - markShouldQuit, -}; diff --git a/package.json b/package.json index db8b6bb56..6fafa872e 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "nan": "2.14.2", "node-fetch": "2.3.0", "node-sass": "6.0.1", - "os-locale": "2.1.0", + "os-locale": "6.0.2", "p-retry": "^4.2.0", "pify": "3.0.0", "protobufjs": "^6.11.2", diff --git a/app/attachment_channel.js b/ts/node/attachment_channel.ts similarity index 57% rename from app/attachment_channel.js rename to ts/node/attachment_channel.ts index 520162b0f..940545ff9 100644 --- a/app/attachment_channel.js +++ b/ts/node/attachment_channel.ts @@ -1,30 +1,35 @@ -const electron = require('electron'); -const Attachments = require('../ts/attachments/attachments'); -const rimraf = require('rimraf'); +import { ipcMain } from 'electron'; +import rimraf from 'rimraf'; -const { ipcMain } = electron; - -module.exports = { - initialize, -}; +import * as Attachments from '../attachments/attachments'; +// tslint:disable: no-console let initialized = false; const ERASE_ATTACHMENTS_KEY = 'erase-attachments'; const CLEANUP_ORPHANED_ATTACHMENTS_KEY = 'cleanup-orphaned-attachments'; -async function initialize({ configDir, cleanupOrphanedAttachments }) { +export async function cleanupOrphanedAttachments(userDataPath: string) { + const allAttachments = await Attachments.getAllAttachments(userDataPath); + const orphanedAttachments = await sql.removeKnownAttachments(allAttachments); //sql.js + await Attachments.deleteAll({ + userDataPath, + attachments: orphanedAttachments, + }); +} + +export async function initialize({ userDataPath }: { userDataPath: string }) { if (initialized) { throw new Error('initialze: Already initialized!'); } initialized = true; console.log('Ensure attachments directory exists'); - await Attachments.ensureDirectory(configDir); + await Attachments.ensureDirectory(userDataPath); - const attachmentsDir = Attachments.getPath(configDir); + const attachmentsDir = Attachments.getPath(userDataPath); - ipcMain.on(ERASE_ATTACHMENTS_KEY, async event => { + ipcMain.on(ERASE_ATTACHMENTS_KEY, event => { try { rimraf.sync(attachmentsDir); event.sender.send(`${ERASE_ATTACHMENTS_KEY}-done`); @@ -37,7 +42,7 @@ async function initialize({ configDir, cleanupOrphanedAttachments }) { ipcMain.on(CLEANUP_ORPHANED_ATTACHMENTS_KEY, async event => { try { - await cleanupOrphanedAttachments(); + await cleanupOrphanedAttachments(userDataPath); event.sender.send(`${CLEANUP_ORPHANED_ATTACHMENTS_KEY}-done`); } catch (error) { const errorForDisplay = error && error.stack ? error.stack : error; diff --git a/app/base_config.js b/ts/node/config/base_config.ts similarity index 62% rename from app/base_config.js rename to ts/node/config/base_config.ts index b67cd20be..60728d931 100644 --- a/app/base_config.js +++ b/ts/node/config/base_config.ts @@ -1,19 +1,19 @@ -const fs = require('fs'); - -const _ = require('lodash'); +import { readFileSync, unlinkSync, writeFileSync } from 'fs'; const ENCODING = 'utf8'; -module.exports = { - start, -}; - -function start(name, targetPath, options = {}) { +export function start( + name: string, + targetPath: string, + options: { + allowMalformedOnStartup?: boolean; + } = {} +) { const { allowMalformedOnStartup } = options; - let cachedValue = null; + let cachedValue: Record = {}; try { - const text = fs.readFileSync(targetPath, ENCODING); + const text = readFileSync(targetPath, ENCODING); cachedValue = JSON.parse(text); console.log(`config/get: Successfully read ${name} config file`); @@ -30,20 +30,20 @@ function start(name, targetPath, options = {}) { cachedValue = Object.create(null); } - function get(keyPath) { - return _.get(cachedValue, keyPath); + function get(keyPath: string) { + return cachedValue[keyPath]; } - function set(keyPath, value) { - _.set(cachedValue, keyPath, value); + function set(keyPath: string, value: number | string | boolean) { + cachedValue[keyPath] = value; console.log(`config/set: Saving ${name} config to disk`); const text = JSON.stringify(cachedValue, null, ' '); - fs.writeFileSync(targetPath, text, ENCODING); + writeFileSync(targetPath, text, ENCODING); } function remove() { console.log(`config/remove: Deleting ${name} config from disk`); - fs.unlinkSync(targetPath); + unlinkSync(targetPath); cachedValue = Object.create(null); } diff --git a/ts/node/config/ephemeral_config.ts b/ts/node/config/ephemeral_config.ts new file mode 100644 index 000000000..819e1eadc --- /dev/null +++ b/ts/node/config/ephemeral_config.ts @@ -0,0 +1,12 @@ +import path from 'path'; + +import { app } from 'electron'; + +import { start } from './base_config'; + +const userDataPath = app.getPath('userData'); +const targetPath = path.join(userDataPath, 'ephemeral.json'); + +export const ephemeralConfig = start('ephemeral', targetPath, { + allowMalformedOnStartup: true, +}); diff --git a/ts/node/config/user_config.ts b/ts/node/config/user_config.ts new file mode 100644 index 000000000..393d42fa8 --- /dev/null +++ b/ts/node/config/user_config.ts @@ -0,0 +1,39 @@ +import path from 'path'; +import process from 'process'; + +import { app } from 'electron'; + +import { start } from './base_config'; +// tslint:disable: no-console + +let storageProfile; + +// Node makes sure all environment variables are strings +const { NODE_ENV: environment, NODE_APP_INSTANCE: instance } = process.env; + +// We need to make sure instance is not empty +const isValidInstance = typeof instance === 'string' && instance.length > 0; +const isProduction = environment === 'production' && !isValidInstance; + +// Use seperate data directories for each different environment and app instances +if (!isProduction) { + storageProfile = environment; + if (isValidInstance) { + storageProfile = (storageProfile || '').concat(`-${instance}`); + } +} + +if (storageProfile) { + const userData = path.join(app.getPath('appData'), `Session-${storageProfile}`); + + app.setPath('userData', userData); +} + +console.log(`userData: ${app.getPath('userData')}`); + +const userDataPath = app.getPath('userData'); +const targetPath = path.join(userDataPath, 'config.json'); + +const userConfig = start('user', targetPath); + +export type UserConfig = typeof userConfig; diff --git a/app/locale.js b/ts/node/locale.ts similarity index 70% rename from app/locale.js rename to ts/node/locale.ts index 35a908ec5..73ba234d5 100644 --- a/app/locale.js +++ b/ts/node/locale.ts @@ -1,8 +1,8 @@ -const path = require('path'); -const fs = require('fs'); -const _ = require('lodash'); +import path from 'path'; +import fs from 'fs'; +import _ from 'lodash'; -function normalizeLocaleName(locale) { +function normalizeLocaleName(locale: string) { if (/^en-/.test(locale)) { return 'en'; } @@ -10,15 +10,21 @@ function normalizeLocaleName(locale) { return locale; } -function getLocaleMessages(locale) { +function getLocaleMessages(locale: string): LocaleMessagesType { const onDiskLocale = locale.replace('-', '_'); const targetFile = path.join(__dirname, '..', '_locales', onDiskLocale, 'messages.json'); + // tslint:disable-next-line: non-literal-fs-path return JSON.parse(fs.readFileSync(targetFile, 'utf-8')); } +export type LocaleMessagesType = Record; +export type LocaleMessagesWithNameType = { messages: LocaleMessagesType; name: string }; -function load({ appLocale, logger } = {}) { +export function load({ + appLocale, + logger, +}: { appLocale?: string; logger?: any } = {}): LocaleMessagesWithNameType { if (!appLocale) { throw new TypeError('`appLocale` is required'); } @@ -55,7 +61,3 @@ function load({ appLocale, logger } = {}) { messages, }; } - -module.exports = { - load, -}; diff --git a/app/menu.js b/ts/node/menu.ts similarity index 83% rename from app/menu.js rename to ts/node/menu.ts index 29006234d..8a761dfec 100644 --- a/app/menu.js +++ b/ts/node/menu.ts @@ -1,17 +1,30 @@ -const { isString } = require('lodash'); - -exports.createTemplate = (options, messages) => { +import { LocaleMessagesType } from './locale'; + +import { isString } from 'lodash'; + +// tslint:disable-next-line: max-func-body-length +export const createTemplate = ( + options: { + openReleaseNotes: () => void; + openSupportPage: () => void; + platform: () => void; + showAbout: () => void; + showDebugLog: () => void; + showWindow: () => void; + }, + messages: LocaleMessagesType +) => { if (!isString(options.platform)) { throw new TypeError('`options.platform` must be a string'); } const { - includeSetup, openReleaseNotes, openSupportPage, platform, showAbout, showDebugLog, + showWindow, } = options; const template = [ @@ -138,25 +151,22 @@ exports.createTemplate = (options, messages) => { }, ]; - if (includeSetup) { - const fileMenu = template[0]; - - // These are in reverse order, since we're prepending them one at a time - - fileMenu.submenu.unshift({ - type: 'separator', - }); - } - if (platform === 'darwin') { - return updateForMac(template, messages, options); + return updateForMac(template, messages, { + showAbout: showAbout, + showWindow: showWindow, + }); } return template; }; -function updateForMac(template, messages, options) { - const { includeSetup, showAbout, showWindow } = options; +function updateForMac( + template: any, + messages: LocaleMessagesType, + options: { showAbout: () => void; showWindow: () => void } +) { + const { showAbout, showWindow } = options; // Remove About item and separator from Help menu, since it's on the first menu template[4].submenu.pop(); @@ -165,16 +175,6 @@ function updateForMac(template, messages, options) { // Remove File menu template.shift(); - if (includeSetup) { - // Add a File menu just for these setup options. Because we're using unshift(), we add - // the file menu first, though it ends up to the right of the Signal Desktop menu. - const fileMenu = { - label: messages.mainMenuFile, - }; - - template.unshift(fileMenu); - } - // Add the OSX-specific Signal Desktop menu at the far left template.unshift({ label: messages.sessionMessenger, @@ -212,7 +212,7 @@ function updateForMac(template, messages, options) { }); // Replace Window menu - const windowMenuTemplateIndex = includeSetup ? 4 : 3; + const windowMenuTemplateIndex = 3; // eslint-disable-next-line no-param-reassign template[windowMenuTemplateIndex].submenu = [ { diff --git a/app/spell_check.js b/ts/node/spell_check.ts similarity index 82% rename from app/spell_check.js rename to ts/node/spell_check.ts index a6c7f52be..6fa6d37fe 100644 --- a/app/spell_check.js +++ b/ts/node/spell_check.ts @@ -1,12 +1,12 @@ -/* global exports, require */ -/* eslint-disable strict */ +// tslint:disable: no-console -const { Menu } = require('electron'); -const osLocale = require('os-locale'); +import { Menu } from 'electron'; +import { BrowserWindow } from 'electron/main'; +import { osLocaleSync } from 'os-locale'; -exports.setup = (browserWindow, messages) => { +export const setup = (browserWindow: BrowserWindow, messages: any) => { const { session } = browserWindow.webContents; - const userLocale = osLocale.sync().replace(/_/g, '-'); + const userLocale = osLocaleSync().replace(/_/g, '-'); const userLocales = [userLocale, userLocale.split('-')[0]]; const available = session.availableSpellCheckerLanguages; @@ -16,7 +16,7 @@ exports.setup = (browserWindow, messages) => { console.log('spellcheck: setting languages to: ', languages); session.setSpellCheckerLanguages(languages); - browserWindow.webContents.on('context-menu', (_event, params) => { + browserWindow.webContents.on('context-menu', (_event: any, params: any) => { const { editFlags } = params; const isMisspelled = Boolean(params.misspelledWord); const showMenu = params.isEditable || editFlags.canCopy; @@ -28,7 +28,7 @@ exports.setup = (browserWindow, messages) => { if (isMisspelled) { if (params.dictionarySuggestions.length > 0) { template.push( - ...params.dictionarySuggestions.map(label => ({ + ...params.dictionarySuggestions.map((label: any) => ({ label, click: () => { browserWindow.webContents.replaceMisspelling(label); @@ -75,7 +75,7 @@ exports.setup = (browserWindow, messages) => { } const menu = Menu.buildFromTemplate(template); - menu.popup(browserWindow); + menu.popup({ window: browserWindow }); } }); }; diff --git a/app/tray_icon.js b/ts/node/tray_icon.ts similarity index 68% rename from app/tray_icon.js rename to ts/node/tray_icon.ts index 862099759..ee8990109 100644 --- a/app/tray_icon.js +++ b/ts/node/tray_icon.ts @@ -1,17 +1,20 @@ -const path = require('path'); +import path from 'path'; -const { app, Menu, Tray } = require('electron'); +import { app, Menu, Tray } from 'electron'; +import { BrowserWindow } from 'electron/main'; +import { LocaleMessagesType } from './locale'; let trayContextMenu = null; -let tray = null; +let tray: Tray | null = null; +let trayAny: any; -function createTrayIcon(getMainWindow, messages) { +function createTrayIcon(getMainWindow: () => BrowserWindow, messages: LocaleMessagesType) { // keep the duplicated part to allow for search and find const iconFile = process.platform === 'darwin' ? 'session_icon_16.png' : 'session_icon_32.png'; const iconNoNewMessages = path.join(__dirname, '..', 'images', 'session', iconFile); tray = new Tray(iconNoNewMessages); - - tray.forceOnTop = mainWindow => { + trayAny = tray; + trayAny.forceOnTop = (mainWindow: BrowserWindow) => { if (mainWindow) { // On some versions of GNOME the window may not be on top when restored. // This trick should fix it. @@ -22,7 +25,7 @@ function createTrayIcon(getMainWindow, messages) { } }; - tray.toggleWindowVisibility = () => { + trayAny.toggleWindowVisibility = () => { const mainWindow = getMainWindow(); if (mainWindow) { if (mainWindow.isVisible()) { @@ -30,25 +33,25 @@ function createTrayIcon(getMainWindow, messages) { } else { mainWindow.show(); - tray.forceOnTop(mainWindow); + trayAny.forceOnTop(mainWindow); } } - tray.updateContextMenu(); + trayAny.updateContextMenu(); }; - tray.showWindow = () => { + trayAny.showWindow = () => { const mainWindow = getMainWindow(); if (mainWindow) { if (!mainWindow.isVisible()) { mainWindow.show(); } - tray.forceOnTop(mainWindow); + trayAny.forceOnTop(mainWindow); } - tray.updateContextMenu(); + trayAny.updateContextMenu(); }; - tray.updateContextMenu = () => { + trayAny.updateContextMenu = () => { const mainWindow = getMainWindow(); // NOTE: we want to have the show/hide entry available in the tray icon @@ -59,7 +62,7 @@ function createTrayIcon(getMainWindow, messages) { { id: 'toggleWindowVisibility', label: messages[mainWindow.isVisible() ? 'appMenuHide' : 'show'], - click: tray.toggleWindowVisibility, + click: trayAny.toggleWindowVisibility, }, { id: 'quit', @@ -68,13 +71,13 @@ function createTrayIcon(getMainWindow, messages) { }, ]); - tray.setContextMenu(trayContextMenu); + trayAny.setContextMenu(trayContextMenu); }; - tray.on('click', tray.showWindow); + tray.on('click', trayAny.showWindow); tray.setToolTip(messages.sessionMessenger); - tray.updateContextMenu(); + trayAny.updateContextMenu(); return tray; } diff --git a/ts/node/window_state.ts b/ts/node/window_state.ts new file mode 100644 index 000000000..d293f7d0d --- /dev/null +++ b/ts/node/window_state.ts @@ -0,0 +1,9 @@ +let shouldQuitFlag = false; + +export function markShouldQuit() { + shouldQuitFlag = true; +} + +export function shouldQuit() { + return shouldQuitFlag; +} diff --git a/ts/updater/index.ts b/ts/updater/index.ts index 1bc27bc14..2dde2e7d8 100644 --- a/ts/updater/index.ts +++ b/ts/updater/index.ts @@ -1,7 +1,7 @@ import { BrowserWindow } from 'electron'; import { start as startUpdater, stop as stopUpdater } from './updater'; import { LoggerType, MessagesType } from './common'; -import { UserConfig } from '../../app/user_config'; +import { UserConfig } from '../node/config/user_config'; let initialized = false; let localUserConfig: UserConfig; diff --git a/ts/updater/updater.ts b/ts/updater/updater.ts index 2867fcae0..593be047d 100644 --- a/ts/updater/updater.ts +++ b/ts/updater/updater.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import * as fs from 'fs-extra'; import { autoUpdater, UpdateInfo } from 'electron-updater'; import { app, BrowserWindow } from 'electron'; -import { markShouldQuit } from '../../app/window_state'; +import { markShouldQuit } from '../node/window_state'; import { getPrintableError, diff --git a/yarn.lock b/yarn.lock index 177e3091f..65d14603d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2542,7 +2542,7 @@ cross-env@^6.0.3: dependencies: cross-spawn "^7.0.0" -cross-spawn@^5.0.1, cross-spawn@^5.1.0: +cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= @@ -3375,19 +3375,6 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -3795,11 +3782,6 @@ get-stdin@^5.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -4412,10 +4394,10 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= +invert-kv@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-3.0.1.tgz#a93c7a3d4386a1dc8325b97da9bb1620c0282523" + integrity sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw== ip2country@1.0.1: version "1.0.1" @@ -4537,11 +4519,6 @@ is-resolvable@^1.0.0: resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -4888,12 +4865,12 @@ lazy-val@^1.0.4: resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.4.tgz#882636a7245c2cfe6e0a4e3ba6c5d68a137e5c65" integrity sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q== -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= +lcid@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-3.1.1.tgz#9030ec479a058fc36b5e8243ebaac8b6ac582fd0" + integrity sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg== dependencies: - invert-kv "^1.0.0" + invert-kv "^3.0.0" levn@^0.3.0, levn@~0.3.0: version "0.3.0" @@ -5127,13 +5104,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -5586,13 +5556,6 @@ npm-conf@^1.1.3: config-chain "^1.1.11" pify "^3.0.0" -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -5701,14 +5664,12 @@ os-homedir@1.0.2, os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== +os-locale@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-6.0.2.tgz#2e5122600f48cd9b846524c07f898db1c596bf20" + integrity sha512-qIb8bzRqaN/vVqEYZ7lTAg6PonskO7xOmM7OClD28F6eFa4s5XGe4bGpHUHMoCHbNNuR0pDYFeSLiW5bnjWXIA== dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" + lcid "^3.1.1" os-tmpdir@^1.0.0, os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" @@ -5728,11 +5689,6 @@ p-cancelable@^1.0.0: resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -5873,11 +5829,6 @@ path-is-inside@^1.0.2: resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -7385,11 +7336,6 @@ strip-bom@^3.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - 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"