diff --git a/package.json b/package.json index 8e68c4e96b..6d48bc6812 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ }, "dependencies": { "bootstrap": "3.3.1", - "dbus-native": "github:sidorares/node-dbus#9b464a1c99ce149dd660e1e88382318d248dff60", "ember-localstorage-adapter": "1.0.0", "flag-icon-css": "2.8.0", "font-awesome": "4.7.0", diff --git a/src/app/initializers/localstorage.js b/src/app/initializers/localstorage.js index 3df5eb149b..c4a1f48b8b 100644 --- a/src/app/initializers/localstorage.js +++ b/src/app/initializers/localstorage.js @@ -113,8 +113,8 @@ function upgradeSettings() { }); // update notification provider - if ( settings.notify_provider === "libnotify" ) { - settings.notify_provider = "freedesktop"; + if ( [ "libnotify", "freedesktop" ].includes( settings.notify_provider ) ) { + settings.notify_provider = "native"; } // map quality number IDs to strings diff --git a/src/app/models/localstorage/Settings.js b/src/app/models/localstorage/Settings.js index d517cda8d5..3497ca2905 100644 --- a/src/app/models/localstorage/Settings.js +++ b/src/app/models/localstorage/Settings.js @@ -241,14 +241,6 @@ export default Model.extend({ notes: "\"Banner notifications\" need to be enabled in the system preferences" } }, - { - value: "freedesktop", - label: { - name: "Freedesktop notifications", - description: "Native notifications on Linux", - notes: "Implementation of the Desktop Notifications Specification" - } - }, { value: "growl", label: { diff --git a/src/app/services/NotificationService/providers/freedesktop.js b/src/app/services/NotificationService/providers/freedesktop.js deleted file mode 100644 index aac6cd2725..0000000000 --- a/src/app/services/NotificationService/providers/freedesktop.js +++ /dev/null @@ -1,186 +0,0 @@ -import { - main as mainConfig, - notification as notificationConfig -} from "config"; -import { - window as Window -} from "nwjs/Window"; -import { ATTR_NOTIFY_CLICK_NOOP } from "models/localstorage/Settings"; -import { isLinux } from "utils/node/platform"; -import { sessionBus } from "dbus-native"; - - -const { "display-name": displayName } = mainConfig; -const { - provider: { - freedesktop: { - expire: EXPIRE_SECS - } - } -} = notificationConfig; - -const { setTimeout, clearTimeout } = Window; - -// don't use NotificationClosed return codes -//const CODE_NOTIF_DISMISSED = 2; -//const CODE_NOTIF_CLOSED = 3; - -const ACTION_OPEN_ID = "open"; -const ACTION_OPEN_TEXT = "Open"; -const ACTION_DISMISS_ID = "dismiss"; -const ACTION_DISMISS_TEXT = "Dismiss"; - -const ACTIONS = [ ACTION_OPEN_ID, ACTION_OPEN_TEXT, ACTION_DISMISS_ID, ACTION_DISMISS_TEXT ]; - -const EXPIRE_MSECS = EXPIRE_SECS * 1000; - - -/** - * @class NotificationProviderFreedesktopCallback - * @property {Function} callback - * @property {number} expire - */ -class NotificationProviderFreedesktopCallback { - /** - * @param {Function} callback - * @param {number} expire - */ - constructor( callback, expire ) { - this.callback = callback; - this.expire = expire; - } -} - - -/** - * Freedesktop notifications - * https://developer.gnome.org/notification-spec/ - * - * Use the "dbus-native" module for all DBus communication. - * This only requires native node modules in special cases, which have been disabled by webpack. - * - * @class NotificationProviderFreedesktop - * @implements NotificationProvider - */ -export default class NotificationProviderFreedesktop { - static isSupported() { - return isLinux; - } - - /** - * Calls a method on the given dbus interface and returns a Promise - * @param {Object} iface - * @param {string} method - * @param {...(*)} args - * @returns {Promise} - */ - static async callMethod( iface, method, ...args ) { - return await new Promise( ( resolve, reject ) => { - iface[ method ]( ...args, ( err, result ) => { - if ( err ) { - reject( err ); - } else { - resolve( result ); - } - }); - }); - } - - async setup() { - // get the session bus - const bus = sessionBus(); - if ( !bus ) { - throw new Error( "Could not connect to the DBus session bus" ); - } - - const { callMethod } = NotificationProviderFreedesktop; - - // get the session bus freedesktop notification interface - const iNotification = await callMethod( - bus.getService( "org.freedesktop.Notifications" ), - "getInterface", - "/org/freedesktop/Notifications", - "org.freedesktop.Notifications" - ); - this.iNotification = iNotification; - - // check notification server - await callMethod( iNotification, "GetServerInformation" ); - - // get server capabilities - const capabilities = await callMethod( iNotification, "GetCapabilities" ); - this.supportsActions = capabilities.includes( "actions" ); - - /** @type {Map} */ - this.callbacks = new Map(); - - iNotification.on( "NotificationClosed", ( id/*, code*/ ) => { - if ( !this.callbacks.has( id ) ) { return; } - this.unregisterCallback( id ); - }); - - iNotification.on( "ActionInvoked", ( id, action ) => { - if ( !this.callbacks.has( id ) ) { return; } - if ( this.supportsActions && action === ACTION_OPEN_ID ) { - this.callbacks.get( id ).callback(); - } - this.unregisterCallback( id ); - }); - } - - /** - * @param {NotificationData} data - * @returns {Promise} - */ - async notify( data ) { - const actions = this.getActions( data ); - - const id = await NotificationProviderFreedesktop.callMethod( - this.iNotification, - "Notify", - displayName, - 0, - data.icon, - data.title, - data.getMessageAsString(), - actions, - {}, - EXPIRE_SECS - ); - - if ( actions.length ) { - this.registerCallback( id, data.click ); - } - } - - /** - * @param {NotificationData} data - * @returns {string[]} - */ - getActions( data ) { - const actions = this.supportsActions - && data.click - && data.settings !== ATTR_NOTIFY_CLICK_NOOP; - - return actions - ? ACTIONS - : []; - } - - /** - * @param {number} id - * @param {Function} callback - */ - registerCallback( id, callback ) { - const expire = setTimeout( () => this.callbacks.delete( id ), EXPIRE_MSECS ); - this.callbacks.set( id, new NotificationProviderFreedesktopCallback( callback, expire ) ); - } - - /** - * @param {number} id - */ - unregisterCallback( id ) { - clearTimeout( this.callbacks.get( id ).expire ); - this.callbacks.delete( id ); - } -} diff --git a/src/app/services/NotificationService/providers/index.js b/src/app/services/NotificationService/providers/index.js index 8230c1d590..24dbae3758 100644 --- a/src/app/services/NotificationService/providers/index.js +++ b/src/app/services/NotificationService/providers/index.js @@ -1,7 +1,6 @@ import NotificationProviderAuto from "./auto"; import NotificationProviderSnoreToast from "./snoretoast"; import NotificationProviderNative from "./native"; -import NotificationProviderFreedesktop from "./freedesktop"; import NotificationProviderGrowl from "./growl"; import NotificationProviderRich from "./rich"; @@ -35,7 +34,6 @@ export default { "native": NotificationProviderNative, // helper providers for native notifications "snoretoast": NotificationProviderSnoreToast, - "freedesktop": NotificationProviderFreedesktop, // non-native providers "growl": NotificationProviderGrowl, "rich": NotificationProviderRich diff --git a/src/app/services/NotificationService/providers/native.js b/src/app/services/NotificationService/providers/native.js index e92fa3a6bd..77efe8dadf 100644 --- a/src/app/services/NotificationService/providers/native.js +++ b/src/app/services/NotificationService/providers/native.js @@ -1,7 +1,10 @@ import { window as Window } from "nwjs/Window"; -import { isDarwin } from "utils/node/platform"; +import { + isDarwin, + isLinux +} from "utils/node/platform"; const { Notification } = Window; @@ -27,19 +30,12 @@ const { Notification } = Window; * since Chromium 61 (NWjs 0.25) behind a feature flag * https://crbug.com/676220 * - * Issues: - * - "settings" action button can't be disabled - * Clicking the settings action will open a new NWjs window that tries to load Chromium's - * settings page, which doesn't exist in NWjs and is therefore empty. - * This is "acceptable" on macOS (native notifications would require 3rd party applications), - * but on Linux, we have the freedesktop provider that can set the correct actions. - * * @class NotificationProviderNative * @implements NotificationProvider */ export default class NotificationProviderNative { static isSupported() { - return isDarwin; + return isDarwin || isLinux; } async setup() {} @@ -56,7 +52,10 @@ export default class NotificationProviderNative { actions: [] }); - notification.addEventListener( "click", () => data.click() ); + notification.addEventListener( "click", () => data.click instanceof Function + ? data.click() + : null + ); notification.addEventListener( "show", () => resolve() ); notification.addEventListener( "error", () => reject( new Error( "Could not show notification" ) ) diff --git a/src/config/main.json b/src/config/main.json index 296bccb413..5e6048dd72 100644 --- a/src/config/main.json +++ b/src/config/main.json @@ -1,7 +1,7 @@ { "display-name": "Streamlink Twitch GUI", "app-identifier": "streamlink-twitch-gui", - "nwjs-version": "0.25.3", + "nwjs-version": "0.26.1", "urls": { "homepage": "https://github.com/streamlink/streamlink-twitch-gui", "release": "https://github.com/streamlink/streamlink-twitch-gui/releases/tag/v{version}", diff --git a/src/test/tests/services/NotificationService/providers/freedesktop.js b/src/test/tests/services/NotificationService/providers/freedesktop.js deleted file mode 100644 index c6a4daffc5..0000000000 --- a/src/test/tests/services/NotificationService/providers/freedesktop.js +++ /dev/null @@ -1,469 +0,0 @@ -import { - module, - test -} from "qunit"; -import notificationProviderFreedesktopInjector - from "inject-loader!services/NotificationService/providers/freedesktop"; -import NotificationData from "services/NotificationService/data"; -import { EventEmitter } from "events"; - - -const config = { - main: { - "display-name": "application name" - }, - notification: { - provider: { - freedesktop: { - expire: 2 - } - } - } -}; -const ATTR_NOTIFY_CLICK_NOOP = 0; -const ATTR_NOTIFY_CLICK_FOLLOWED = 1; - - -module( "services/NotificationService/providers/freedesktop" ); - - -test( "isSupported", assert => { - - const common = { - config, - "nwjs/Window": { - window: {} - }, - "models/localstorage/Settings": {}, - "dbus-native": {} - }; - - let NotificationProviderFreedesktop; - - NotificationProviderFreedesktop = notificationProviderFreedesktopInjector( Object.assign( {}, { - "utils/node/platform": { - isLinux: false - } - }, common ) )[ "default" ]; - - assert.notOk( NotificationProviderFreedesktop.isSupported(), "Is not supported" ); - - NotificationProviderFreedesktop = notificationProviderFreedesktopInjector( Object.assign( {}, { - "utils/node/platform": { - isLinux: true - } - }, common ) )[ "default" ]; - - assert.ok( NotificationProviderFreedesktop.isSupported(), "Is supported" ); - -}); - - -test( "callMethod", async assert => { - - assert.expect( 5 ); - - const { default: NotificationProviderFreedesktop } = notificationProviderFreedesktopInjector({ - config, - "nwjs/Window": { window: {} }, - "models/localstorage/Settings": {}, - "utils/node/platform": {}, - "dbus-native": {} - }); - - const result = await NotificationProviderFreedesktop.callMethod( - { - foo( ...args ) { - const callback = args.pop(); - assert.propEqual( args, [ 123, 456 ], "Calls method with correct args" ); - assert.ok( callback instanceof Function, "Last param is a callback" ); - callback( null, 789 ); - } - }, - "foo", - 123, - 456 - ); - assert.strictEqual( result, 789, "Resolves with correct return value" ); - - try { - await NotificationProviderFreedesktop.callMethod( - { - foo( ...args ) { - args.pop()( new Error( "fail" ), 789 ); - } - }, - "foo", - 123, - 456 - ); - } catch ( e ) { - assert.strictEqual( e.message, "fail", "Rejects on error" ); - } - - try { - await NotificationProviderFreedesktop.callMethod( {}, "foo" ); - } catch ( e ) { - assert.ok( e instanceof TypeError, "Invalid methods reject with a TypeError" ); - } - -}); - - -test( "setup", async assert => { - - assert.expect( 40 ); - - let failSessionBus = true; - let failGetService = true; - let failGetInterface = true; - let failGetServerInformation = true; - let failGetCapabilities = true; - - const capabilities = []; - - const iface = new EventEmitter(); - iface.GetServerInformation = callback => { - if ( failGetServerInformation ) { - callback( new Error( "fail server information" ) ); - } else { - callback( null, null ); - } - }; - iface.GetCapabilities = callback => { - if ( failGetCapabilities ) { - callback( new Error( "fail capabilities" ) ); - } else { - callback( null, capabilities ); - } - }; - - const service = { - getInterface( path, ifaceName, callback ) { - assert.strictEqual( - path, - "/org/freedesktop/Notifications", - "Requests the correct freedesktop notification path" - ); - assert.strictEqual( - ifaceName, - "org.freedesktop.Notifications", - "Requests the correct freedesktop notification interface" - ); - if ( failGetInterface ) { - callback( new Error( "fail interface" ) ); - } else { - callback( null, iface ); - } - } - }; - - const sessionBus = { - getService( name ) { - assert.strictEqual( - name, - "org.freedesktop.Notifications", - "Requests the correct service name" - ); - if ( failGetService ) { - throw new Error( "fail service" ); - } else { - return service; - } - } - }; - - const { default: NotificationProviderFreedesktop } = notificationProviderFreedesktopInjector({ - config, - "nwjs/Window": { window: {} }, - "models/localstorage/Settings": {}, - "utils/node/platform": {}, - "dbus-native": { - sessionBus() { - return failSessionBus - ? false - : sessionBus; - } - } - }); - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - } catch ( e ) { - assert.strictEqual( - e.message, - "Could not connect to the DBus session bus", - "sessionBus fail" - ); - } - - failSessionBus = false; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - } catch ( e ) { - assert.strictEqual( e.message, "fail service", "getService fail" ); - } - - failGetService = false; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - } catch ( e ) { - assert.strictEqual( e.message, "fail interface", "getInterface fail" ); - } - - failGetInterface = false; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - } catch ( e ) { - assert.strictEqual( e.message, "fail server information", "GetServerInformation fail" ); - } - - failGetServerInformation = false; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - } catch ( e ) { - assert.strictEqual( e.message, "fail capabilities", "GetCapabilities fail" ); - } - - failGetCapabilities = false; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - assert.strictEqual( inst.iNotification, iface, "Has the dbus interface property" ); - assert.strictEqual( inst.supportsActions, false, "Doesn't support actions" ); - assert.ok( inst.callbacks instanceof Map, "Has a callbacks map registered" ); - assert.propEqual( - iface.eventNames(), - [ "NotificationClosed", "ActionInvoked" ], - "Interface has listeners set up" - ); - } catch ( e ) { - throw e; - } - - iface.removeAllListeners(); - capabilities.push( "actions" ); - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.setup(); - assert.strictEqual( inst.supportsActions, true, "Supports actions" ); - - inst.unregisterCallback = id => { - assert.strictEqual( id, 1, "Calls unregisterCallback" ); - assert.step( "unregister" ); - }; - /** @type {NotificationProviderFreedesktopCallback} */ - const callback = { - callback() { - assert.step( "callback" ); - } - }; - - iface.emit( "NotificationClosed", 1 ); - iface.emit( "ActionInvoked", 1 ); - assert.checkSteps( [], "Doesn't call unregisterCallback on unknown notifications" ); - - inst.callbacks.set( 1, callback ); - iface.emit( "NotificationClosed", 1 ); - assert.checkSteps( [ "unregister" ], "Unregisters known notification callback" ); - - iface.emit( "ActionInvoked", 1 ); - assert.checkSteps( [ "unregister" ], "Unregisters known notification callback" ); - iface.emit( "ActionInvoked", 1, "open" ); - assert.checkSteps( [ "callback", "unregister" ], "Executes callback" ); - - inst.supportsActions = false; - iface.emit( "ActionInvoked", 1, "open" ); - assert.checkSteps( [ "unregister" ], "Doesn't execute callback" ); - } catch ( e ) { - throw e; - } - -}); - - -test( "getActions", assert => { - - const { default: NotificationProviderFreedesktop } = notificationProviderFreedesktopInjector({ - config, - "nwjs/Window": { window: {} }, - "models/localstorage/Settings": { - ATTR_NOTIFY_CLICK_NOOP - }, - "utils/node/platform": {}, - "dbus-native": {} - }); - - const dataWithoutClick = new NotificationData({}); - const dataWithoutAction = new NotificationData({ - click() {}, - settings: ATTR_NOTIFY_CLICK_NOOP - }); - const dataWithAction = new NotificationData({ - click() {}, - settings: ATTR_NOTIFY_CLICK_FOLLOWED - }); - - const inst = new NotificationProviderFreedesktop(); - - inst.supportsActions = false; - assert.propEqual( inst.getActions( dataWithoutClick ), [], "No actions, if unsupported" ); - assert.propEqual( inst.getActions( dataWithoutAction ), [], "No actions, if unsupported" ); - assert.propEqual( inst.getActions( dataWithAction ), [], "No actions, if unsupported" ); - - inst.supportsActions = true; - assert.propEqual( inst.getActions( dataWithoutClick ), [], "No actions, if no callback" ); - assert.propEqual( inst.getActions( dataWithoutAction ), [], "No actions, if no user actions" ); - assert.propEqual( - inst.getActions( dataWithAction ), - [ "open", "Open", "dismiss", "Dismiss" ], - "Returns open and dismiss actions" - ); - -}); - - -test( "notify", async assert => { - - assert.expect( 20 ); - - let failNotify = true; - let data; - - let expectedMessage; - let expectedActions = []; - const click = () => {}; - - const { default: NotificationProviderFreedesktop } = notificationProviderFreedesktopInjector({ - config, - "nwjs/Window": { window: {} }, - "models/localstorage/Settings": {}, - "utils/node/platform": {}, - "dbus-native": {} - }); - - NotificationProviderFreedesktop.prototype.iNotification = { - Notify( name, id, icon, title, message, actions, hints, expire, callback ) { - if ( failNotify ) { - return callback( new Error( "fail notify" ) ); - } - - assert.strictEqual( name, "application name", "Has correct app name" ); - assert.strictEqual( id, 0, "Don't replace any notifications" ); - assert.strictEqual( icon, "icon-path", "Has the correct icon path" ); - assert.strictEqual( title, "title", "Has the correct title" ); - assert.strictEqual( message, expectedMessage, "Has the correct message" ); - assert.strictEqual( actions, expectedActions, "Uses the returned actions array" ); - assert.propEqual( hints, {}, "Doesn't use any notification hints" ); - assert.strictEqual( expire, 2, "Sets the correct expiration time in seconds" ); - - callback( null, 1 ); - } - }; - - NotificationProviderFreedesktop.prototype.getActions = obj => { - assert.strictEqual( obj, data, "Calls getActions" ); - return expectedActions; - }; - - NotificationProviderFreedesktop.prototype.registerCallback = ( id, callback ) => { - assert.strictEqual( id, 1, "Registers notification id" ); - assert.strictEqual( callback, click, "Registers notification callback" ); - }; - - - try { - const inst = new NotificationProviderFreedesktop(); - data = new NotificationData({}); - await inst.notify( data ); - } catch ( e ) { - assert.strictEqual( e.message, "fail notify", "Notify fail" ); - } - - failNotify = false; - data = new NotificationData({ - title: "title", - message: "message", - icon: "icon-path", - click - }); - expectedMessage = "message"; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.notify( data ); - } catch ( e ) { - throw e; - } - - data.message = [ - { title: "foo" }, - { title: "bar" } - ]; - expectedMessage = "foo, bar"; - - try { - const inst = new NotificationProviderFreedesktop(); - await inst.notify( data ); - } catch ( e ) { - throw e; - } - -}); - - -test( "Callbacks", assert => { - - assert.expect( 10 ); - - let deleteCallback; - - const { default: NotificationProviderFreedesktop } = notificationProviderFreedesktopInjector({ - config, - "nwjs/Window": { - window: { - setTimeout( callback, time ) { - assert.ok( callback instanceof Function, "Has a delete callback" ); - assert.strictEqual( time, 2000, "Sets the expiration time in msecs" ); - deleteCallback = callback; - return 1234; - }, - clearTimeout( timeout ) { - assert.strictEqual( timeout, 1234, "Clears timeout" ); - } - } - }, - "models/localstorage/Settings": {}, - "utils/node/platform": {}, - "dbus-native": {} - }); - - const inst = new NotificationProviderFreedesktop(); - inst.callbacks = new Map(); - - let callback = () => {}; - - inst.registerCallback( 1, callback ); - assert.strictEqual( inst.callbacks.get( 1 ).callback, callback, "Callback is registered" ); - assert.strictEqual( inst.callbacks.get( 1 ).expire, 1234, "Has an expiration timeout" ); - - deleteCallback(); - assert.notOk( inst.callbacks.has( 1 ), "Removes callback once it expires" ); - - inst.registerCallback( 2, callback ); - assert.strictEqual( inst.callbacks.size, 1, "Callbacks has a size of one" ); - inst.unregisterCallback( 2 ); - assert.strictEqual( inst.callbacks.size, 0, "Callbacks are empty" ); - -}); diff --git a/src/test/tests/services/NotificationService/providers/native.js b/src/test/tests/services/NotificationService/providers/native.js index 90e1706203..799354016d 100644 --- a/src/test/tests/services/NotificationService/providers/native.js +++ b/src/test/tests/services/NotificationService/providers/native.js @@ -20,7 +20,8 @@ test( "isSupported", assert => { window: {} }, "utils/node/platform": { - isDarwin: true + isDarwin: true, + isLinux: false } })[ "default" ]; @@ -31,7 +32,20 @@ test( "isSupported", assert => { window: {} }, "utils/node/platform": { - isDarwin: false + isDarwin: false, + isLinux: true + } + })[ "default" ]; + + assert.ok( NotificationProviderNative.isSupported(), "Supported on Linux" ); + + NotificationProviderNative = notificationProviderNativeInjector({ + "nwjs/Window": { + window: {} + }, + "utils/node/platform": { + isDarwin: false, + isLinux: false } })[ "default" ]; @@ -57,7 +71,7 @@ test( "setup", async assert => { test( "notify", async assert => { - assert.expect( 6 ); + assert.expect( 8 ); let notification; let expectedMessage; @@ -119,4 +133,15 @@ test( "notify", async assert => { throw e; } + data.click = null; + + try { + const promise = inst.notify( data ); + notification.dispatchEvent( new Event( "show" ) ); + await promise; + notification.dispatchEvent( new Event( "click" ) ); + } catch ( e ) { + throw e; + } + }); diff --git a/src/test/tests/tests.js b/src/test/tests/tests.js index f1216f4e5e..38db753e73 100644 --- a/src/test/tests/tests.js +++ b/src/test/tests/tests.js @@ -84,7 +84,6 @@ import "tests/services/StreamingService/player/resolve"; import "tests/services/StreamingService/launch/parse-error"; import "tests/services/StreamingService/launch/index"; import "tests/services/NotificationService/providers/auto"; -import "tests/services/NotificationService/providers/freedesktop"; import "tests/services/NotificationService/providers/growl"; import "tests/services/NotificationService/providers/native"; import "tests/services/NotificationService/providers/rich"; diff --git a/yarn.lock b/yarn.lock index 321bc754c8..d2241c1a3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,13 +6,6 @@ abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" -abstract-socket@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/abstract-socket/-/abstract-socket-2.0.0.tgz#d83c93e7df30d27e23f3e82a763e7f5e78d916f9" - dependencies: - bindings "^1.2.1" - nan "^2.0.9" - acorn-dynamic-import@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" @@ -776,10 +769,6 @@ binary-extensions@^1.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.0.0.tgz#e597d1a7a6a3558a2d1c7241a16c99965e6aa40f" -bindings@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" - bl@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.1.tgz#cac328f7bee45730d404b692203fcb590e172d5e" @@ -1608,19 +1597,6 @@ dateformat@~1.0.12: get-stdin "^4.0.1" meow "^3.3.0" -"dbus-native@github:sidorares/node-dbus#9b464a1c99ce149dd660e1e88382318d248dff60": - version "0.2.3" - resolved "https://codeload.github.com/sidorares/node-dbus/tar.gz/9b464a1c99ce149dd660e1e88382318d248dff60" - dependencies: - event-stream "^3.1.7" - hexy "^0.2.10" - long "^3.0.1" - optimist "^0.6.1" - put "0.0.6" - xml2js "0.1.14" - optionalDependencies: - abstract-socket "^2.0.0" - debug@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" @@ -1803,10 +1779,6 @@ duplexer2@^0.1.4: dependencies: readable-stream "^2.0.2" -duplexer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - eachr@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/eachr/-/eachr-3.2.0.tgz#2c35e43ea086516f7997cf80b7aa64d55a4a4484" @@ -2080,18 +2052,6 @@ event-emitter@~0.3.5: d "1" es5-ext "~0.10.14" -event-stream@^3.1.7: - version "3.3.4" - resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" - dependencies: - duplexer "~0.1.1" - from "~0" - map-stream "~0.1.0" - pause-stream "0.0.11" - split "0.3" - stream-combiner "~0.0.4" - through "~2.3.1" - eventemitter2@~0.4.13: version "0.4.14" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" @@ -2364,10 +2324,6 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" -from@~0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" - fs-exists-sync@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" @@ -2803,10 +2759,6 @@ heimdalljs@^0.2.0, heimdalljs@^0.2.1, heimdalljs@^0.2.3: dependencies: rsvp "~3.2.1" -hexy@^0.2.10: - version "0.2.10" - resolved "https://registry.yarnpkg.com/hexy/-/hexy-0.2.10.tgz#eb9504947ad293ede2f554ddb14d0891a07a16b5" - hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3529,10 +3481,6 @@ lodash@~4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.3.0.tgz#efd9c4a6ec53f3b05412429915c3e4824e4d25a4" -long@^3.0.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" - longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -3583,10 +3531,6 @@ map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" -map-stream@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" - masonry-layout@4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/masonry-layout/-/masonry-layout-4.2.0.tgz#43835c6b6e0d72eff2c31a118c8000cccc4ab965" @@ -3770,10 +3714,6 @@ mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" -nan@^2.0.9: - version "2.7.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" - nan@^2.3.0, nan@^2.6.1: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" @@ -4153,12 +4093,6 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -pause-stream@0.0.11: - version "0.0.11" - resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" - dependencies: - through "~2.3" - pbkdf2@^3.0.3: version "3.0.12" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.12.tgz#be36785c5067ea48d806ff923288c5f750b6b8a2" @@ -4569,10 +4503,6 @@ punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -put@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/put/-/put-0.0.6.tgz#30f5f60bd6e4389bd329e16a25386cbb2e4a00a3" - q@^1.1.2: version "1.5.0" resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" @@ -4999,10 +4929,6 @@ safefs@^4.0.0: editions "^1.1.1" graceful-fs "^4.1.4" -sax@>=0.1.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - sax@~1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" @@ -5151,12 +5077,6 @@ spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" -split@0.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" - dependencies: - through "2" - sprintf-js@^1.0.3, sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -5190,12 +5110,6 @@ stream-buffers@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" -stream-combiner@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" - dependencies: - duplexer "~0.1.1" - stream-http@^2.3.1: version "2.7.2" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" @@ -5385,7 +5299,7 @@ thenify@^3.3.0: dependencies: any-promise "^1.0.0" -through@2, through@^2.3.6, through@~2.3, through@~2.3.1, through@~2.3.8: +through@^2.3.6, through@~2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -5789,12 +5703,6 @@ xml-char-classes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/xml-char-classes/-/xml-char-classes-1.0.0.tgz#64657848a20ffc5df583a42ad8a277b4512bbc4d" -xml2js@0.1.14: - version "0.1.14" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.1.14.tgz#5274e67f5a64c5f92974cd85139e0332adc6b90c" - dependencies: - sax ">=0.1.1" - xmlbuilder@8.2.2: version "8.2.2" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773"