diff --git a/.gitignore b/.gitignore
index 4cb12784f5..1eb148df02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,3 +24,4 @@ test/test.js
# React / TypeScript
ts/**/*.js
+ts/protobuf/*.d.ts
diff --git a/.prettierignore b/.prettierignore
index ed8fd952d7..c7b5de7190 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -2,14 +2,19 @@
# supports `.gitignore`: https://github.com/prettier/prettier/issues/2294
# Generated files
+config/local-*.json
+config/local.json
dist/**
js/components.js
js/libsignal-protocol-worker.js
js/libtextsecure.js
libtextsecure/components.js
libtextsecure/test/test.js
+stylesheets/*.css
test/test.js
ts/**/*.js
+ts/protobuf/*.d.ts
+ts/protobuf/*.js
# Third-party files
components/**
diff --git a/.travis.yml b/.travis.yml
index 96730e76c2..b56c17dd63 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,11 +7,10 @@ dist: trusty
install:
- yarn install --frozen-lockfile
script:
- - yarn transpile
+ - yarn generate
- yarn lint
- yarn test-node
- yarn nsp check
- - yarn generate
- yarn prepare-beta-build
- $(yarn bin)/build --config.extraMetadata.environment=$SIGNAL_ENV --config.mac.bundleVersion='$TRAVIS_BUILD_NUMBER' --publish=never
- ./travis.sh
diff --git a/Gruntfile.js b/Gruntfile.js
index 72d0aa4e85..4b23b8bdad 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -186,17 +186,21 @@ module.exports = function(grunt) {
},
},
watch: {
- sass: {
- files: ['./stylesheets/*.scss'],
- tasks: ['sass'],
+ dist: {
+ files: ['<%= dist.src %>', '<%= dist.res %>'],
+ tasks: ['copy_dist'],
},
libtextsecure: {
files: ['./libtextsecure/*.js', './libtextsecure/storage/*.js'],
tasks: ['concat:libtextsecure'],
},
- dist: {
- files: ['<%= dist.src %>', '<%= dist.res %>'],
- tasks: ['copy_dist'],
+ protobuf: {
+ files: ['./protos/SignalService.proto'],
+ tasks: ['exec:build-protobuf'],
+ },
+ sass: {
+ files: ['./stylesheets/*.scss'],
+ tasks: ['sass'],
},
scripts: {
files: ['<%= jshint.files %>'],
@@ -216,7 +220,10 @@ module.exports = function(grunt) {
cmd: 'tx pull',
},
transpile: {
- cmd: 'npm run transpile',
+ cmd: 'yarn transpile',
+ },
+ 'build-protobuf': {
+ cmd: 'yarn build-protobuf',
},
},
'test-release': {
@@ -499,10 +506,11 @@ module.exports = function(grunt) {
grunt.registerTask('copy_dist', ['gitinfo', 'copy:res', 'copy:src']);
grunt.registerTask('date', ['gitinfo', 'getExpireTime']);
grunt.registerTask('default', [
+ 'exec:build-protobuf',
+ 'exec:transpile',
'concat',
'copy:deps',
'sass',
'date',
- 'exec:transpile',
]);
};
diff --git a/appveyor.yml b/appveyor.yml
index 52dac757c0..1ba2bac72a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,11 +12,10 @@ install:
- yarn install --frozen-lockfile
build_script:
- - yarn transpile
+ - yarn generate
- yarn lint-windows
- yarn test-node
- yarn nsp check
- - yarn generate
- node build\grunt.js
- type package.json | findstr /v certificateSubjectName > temp.json
- move temp.json package.json
diff --git a/js/models/messages.js b/js/models/messages.js
index 67431eea68..032428d215 100644
--- a/js/models/messages.js
+++ b/js/models/messages.js
@@ -1,10 +1,12 @@
/* global _: false */
/* global Backbone: false */
-/* global Whisper: false */
-/* global textsecure: false */
+
/* global ConversationController: false */
-/* global i18n: false */
/* global getAccountManager: false */
+/* global i18n: false */
+/* global Signal: false */
+/* global textsecure: false */
+/* global Whisper: false */
/* eslint-disable more/no-then */
@@ -14,8 +16,8 @@
window.Whisper = window.Whisper || {};
- const { Message: TypedMessage } = window.Signal.Types;
- const { deleteAttachmentData } = window.Signal.Migrations;
+ const { Message: TypedMessage } = Signal.Types;
+ const { deleteAttachmentData } = Signal.Migrations;
window.Whisper.Message = Backbone.Model.extend({
database: Whisper.Database,
@@ -31,9 +33,6 @@
this.on('change:expireTimer', this.setToExpire);
this.on('unload', this.unload);
this.setToExpire();
-
- this.VOICE_FLAG =
- textsecure.protobuf.AttachmentPointer.Flags.VOICE_MESSAGE;
},
idForLogging() {
return `${this.get('source')}.${this.get('sourceDevice')} ${this.get(
@@ -246,8 +245,7 @@
});
return Object.assign({}, attachment, {
- // eslint-disable-next-line no-bitwise
- isVoiceMessage: Boolean(attachment.flags & this.VOICE_FLAG),
+ isVoiceMessage: Signal.Types.Attachment.isVoiceMessage(attachment),
thumbnail: thumbnailWithObjectUrl,
});
},
diff --git a/js/modules/types/attachment.js b/js/modules/types/attachment.js
index 5010f87fc4..1420152654 100644
--- a/js/modules/types/attachment.js
+++ b/js/modules/types/attachment.js
@@ -179,4 +179,5 @@ exports.deleteData = deleteAttachmentData => {
};
};
+exports.isVoiceMessage = AttachmentTS.isVoiceMessage;
exports.save = AttachmentTS.save;
diff --git a/js/views/attachment_view.js b/js/views/attachment_view.js
index 798039e7c4..15654e82bd 100644
--- a/js/views/attachment_view.js
+++ b/js/views/attachment_view.js
@@ -5,7 +5,6 @@
/* global i18n: false */
/* global Signal: false */
-/* global textsecure: false */
/* global Whisper: false */
// eslint-disable-next-line func-names
@@ -119,20 +118,7 @@
Signal.Backbone.Views.Lightbox.show(this.lightboxView.el);
},
isVoiceMessage() {
- if (
- // eslint-disable-next-line no-bitwise
- this.model.flags &
- textsecure.protobuf.AttachmentPointer.Flags.VOICE_MESSAGE
- ) {
- return true;
- }
-
- // Support for android legacy voice messages
- if (this.isAudio() && this.model.fileName === null) {
- return true;
- }
-
- return false;
+ return Signal.Types.Attachment.isVoiceMessage(this.model);
},
isAudio() {
const { contentType } = this.model;
diff --git a/libtextsecure/test/index.html b/libtextsecure/test/index.html
index ca81c39ad7..acb9304363 100644
--- a/libtextsecure/test/index.html
+++ b/libtextsecure/test/index.html
@@ -2,7 +2,7 @@
- libTextSecure test runner
+ libtextsecure test runner
diff --git a/package.json b/package.json
index 583113b7cf..3213678bac 100644
--- a/package.json
+++ b/package.json
@@ -15,9 +15,13 @@
"start": "electron .",
"grunt": "grunt",
"icon-gen": "electron-icon-maker --input=images/icon_1024.png --output=./build",
- "generate": "npm run icon-gen && grunt",
+ "generate": "yarn icon-gen && yarn grunt",
"build": "build --config.extraMetadata.environment=$SIGNAL_ENV",
"build-release": "SIGNAL_ENV=production npm run build -- --config.directories.output=release",
+ "build-module-protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
+ "clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
+ "build-protobuf": "yarn build-module-protobuf",
+ "clean-protobuf": "yarn clean-module-protobuf",
"prepare-beta-build": "node prepare_beta_build.js",
"prepare-import-build": "node prepare_import_build.js",
"publish-to-apt": "NAME=$npm_package_name VERSION=$npm_package_version ./aptly.sh",
@@ -69,6 +73,7 @@
"node-fetch": "https://github.com/scottnonnenberg/node-fetch.git#3e5f51e08c647ee5f20c43b15cf2d352d61c36b4",
"os-locale": "^2.1.0",
"pify": "^3.0.0",
+ "protobufjs": "^6.8.6",
"proxy-agent": "^2.1.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
diff --git a/protos/WhisperTextProtocol.proto b/protos/WhisperTextProtocol.proto
deleted file mode 100644
index 852d5640b5..0000000000
--- a/protos/WhisperTextProtocol.proto
+++ /dev/null
@@ -1,28 +0,0 @@
-package signalservice;
-
-option java_package = "org.whispersystems.libsignal.protocol";
-option java_outer_classname = "WhisperProtos";
-
-message WhisperMessage {
- optional bytes ephemeralKey = 1;
- optional uint32 counter = 2;
- optional uint32 previousCounter = 3;
- optional bytes ciphertext = 4; // PushMessageContent
-}
-
-message PreKeyWhisperMessage {
- optional uint32 registrationId = 5;
- optional uint32 preKeyId = 1;
- optional uint32 signedPreKeyId = 6;
- optional bytes baseKey = 2;
- optional bytes identityKey = 3;
- optional bytes message = 4; // WhisperMessage
-}
-
-message KeyExchangeMessage {
- optional uint32 id = 1;
- optional bytes baseKey = 2;
- optional bytes ephemeralKey = 3;
- optional bytes identityKey = 4;
- optional bytes baseKeySignature = 5;
-}
diff --git a/ts/components/conversation/Message.md b/ts/components/conversation/Message.md
index afefcd5078..1b01c3cba1 100644
--- a/ts/components/conversation/Message.md
+++ b/ts/components/conversation/Message.md
@@ -597,7 +597,7 @@ const outgoing = new Whisper.Message({
sent_at: Date.now() - 15000,
attachments: [
{
- flags: textsecure.protobuf.AttachmentPointer.Flags.VOICE_MESSAGE,
+ flags: SignalService.AttachmentPointer.Flags.VOICE_MESSAGE,
data: util.mp3,
fileName: 'agnus_dei.mp3',
contentType: 'audio/mp3',
diff --git a/ts/components/conversation/Quote.md b/ts/components/conversation/Quote.md
index 7cdf0b514a..5ab2f58966 100644
--- a/ts/components/conversation/Quote.md
+++ b/ts/components/conversation/Quote.md
@@ -572,7 +572,7 @@ const outgoing = new Whisper.Message({
attachments: [
{
// proposed as of afternoon of 4/6 in Quoted Replies group
- flags: textsecure.protobuf.AttachmentPointer.Flags.VOICE_MESSAGE,
+ flags: SignalService.AttachmentPointer.Flags.VOICE_MESSAGE,
contentType: 'audio/mp3',
fileName: 'agnus_dei.mp4',
},
diff --git a/ts/components/conversation/media-gallery/DocumentListItem.tsx b/ts/components/conversation/media-gallery/DocumentListItem.tsx
index b5d6394038..b8e83bcec9 100644
--- a/ts/components/conversation/media-gallery/DocumentListItem.tsx
+++ b/ts/components/conversation/media-gallery/DocumentListItem.tsx
@@ -4,7 +4,7 @@ import moment from 'moment';
import formatFileSize from 'filesize';
interface Props {
- fileName?: string;
+ fileName?: string | null;
fileSize?: number;
i18n: (key: string, values?: Array) => string;
onClick?: () => void;
diff --git a/ts/protobuf/README.md b/ts/protobuf/README.md
new file mode 100644
index 0000000000..57cdbc733d
--- /dev/null
+++ b/ts/protobuf/README.md
@@ -0,0 +1,3 @@
+# Protocol Buffers
+
+Placeholder directory for Protocol Buffers compiled to JavaScript / TypeScript.
diff --git a/ts/protobuf/index.ts b/ts/protobuf/index.ts
new file mode 100644
index 0000000000..c760e2caec
--- /dev/null
+++ b/ts/protobuf/index.ts
@@ -0,0 +1,3 @@
+import { signalservice as SignalService } from './compiled';
+
+export { SignalService };
diff --git a/ts/styleguide/StyleGuideUtil.ts b/ts/styleguide/StyleGuideUtil.ts
index ecba629d8f..1b8167c699 100644
--- a/ts/styleguide/StyleGuideUtil.ts
+++ b/ts/styleguide/StyleGuideUtil.ts
@@ -19,7 +19,9 @@ export { BackboneWrapper } from '../components/utility/BackboneWrapper';
import { Quote } from '../components/conversation/Quote';
import * as HTML from '../html';
+import * as Attachment from '../../ts/types/Attachment';
import * as MIME from '../../ts/types/MIME';
+import { SignalService } from '../../ts/protobuf';
// TypeScript wants two things when you import:
// 1) a normal typescript file
@@ -125,10 +127,12 @@ parent.ReactDOM = ReactDOM;
parent.Signal.HTML = HTML;
parent.Signal.Types.MIME = MIME;
+parent.Signal.Types.Attachment = Attachment;
parent.Signal.Components = {
Quote,
};
parent.Signal.Util = Util;
+parent.SignalService = SignalService;
parent.filesize = filesize;
parent.ConversationController._initialFetchComplete = true;
diff --git a/ts/test/types/Attachment_test.ts b/ts/test/types/Attachment_test.ts
index 343373d4ba..14b0cdcee7 100644
--- a/ts/test/types/Attachment_test.ts
+++ b/ts/test/types/Attachment_test.ts
@@ -5,7 +5,8 @@ import 'mocha';
import { assert } from 'chai';
import * as Attachment from '../../types/Attachment';
-import { MIMEType } from '../../types/MIME';
+import * as MIME from '../../types/MIME';
+import { SignalService } from '../../protobuf';
// @ts-ignore
import { stringToArrayBuffer } from '../../../js/modules/string_to_array_buffer';
@@ -14,7 +15,7 @@ describe('Attachment', () => {
it('should return file extension from content type', () => {
const input: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
- contentType: 'image/gif' as MIMEType,
+ contentType: MIME.IMAGE_GIF,
};
assert.strictEqual(Attachment.getFileExtension(input), 'gif');
});
@@ -22,7 +23,7 @@ describe('Attachment', () => {
it('should return file extension for QuickTime videos', () => {
const input: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
- contentType: 'video/quicktime' as MIMEType,
+ contentType: MIME.VIDEO_QUICKTIME,
};
assert.strictEqual(Attachment.getFileExtension(input), 'mov');
});
@@ -34,7 +35,7 @@ describe('Attachment', () => {
const attachment: Attachment.Attachment = {
fileName: 'funny-cat.mov',
data: stringToArrayBuffer('foo'),
- contentType: 'video/quicktime' as MIMEType,
+ contentType: MIME.VIDEO_QUICKTIME,
};
const actual = Attachment.getSuggestedFilename({ attachment });
const expected = 'funny-cat.mov';
@@ -45,7 +46,7 @@ describe('Attachment', () => {
it('should generate a filename based on timestamp', () => {
const attachment: Attachment.Attachment = {
data: stringToArrayBuffer('foo'),
- contentType: 'video/quicktime' as MIMEType,
+ contentType: MIME.VIDEO_QUICKTIME,
};
const timestamp = new Date(new Date(0).getTimezoneOffset() * 60 * 1000);
const actual = Attachment.getSuggestedFilename({
@@ -57,4 +58,34 @@ describe('Attachment', () => {
});
});
});
+
+ describe('isVoiceMessage', () => {
+ it('should return true for voice message attachment', () => {
+ const attachment: Attachment.Attachment = {
+ fileName: 'Voice Message.aac',
+ flags: SignalService.AttachmentPointer.Flags.VOICE_MESSAGE,
+ data: stringToArrayBuffer('voice message'),
+ contentType: MIME.AUDIO_AAC,
+ };
+ assert.isTrue(Attachment.isVoiceMessage(attachment));
+ });
+
+ it('should return true for legacy Android voice message attachment', () => {
+ const attachment: Attachment.Attachment = {
+ fileName: null,
+ data: stringToArrayBuffer('voice message'),
+ contentType: MIME.AUDIO_MP3,
+ };
+ assert.isTrue(Attachment.isVoiceMessage(attachment));
+ });
+
+ it('should return false for other attachments', () => {
+ const attachment: Attachment.Attachment = {
+ fileName: 'foo.gif',
+ data: stringToArrayBuffer('foo'),
+ contentType: MIME.IMAGE_GIF,
+ };
+ assert.isFalse(Attachment.isVoiceMessage(attachment));
+ });
+ });
});
diff --git a/ts/test/types/message/initializeAttachmentMetadata_test.ts b/ts/test/types/message/initializeAttachmentMetadata_test.ts
index d76618f280..9c87215f3b 100644
--- a/ts/test/types/message/initializeAttachmentMetadata_test.ts
+++ b/ts/test/types/message/initializeAttachmentMetadata_test.ts
@@ -3,7 +3,7 @@ import { assert } from 'chai';
import * as Message from '../../../../ts/types/message/initializeAttachmentMetadata';
import { IncomingMessage } from '../../../../ts/types/Message';
-import { MIMEType } from '../../../../ts/types/MIME';
+import * as MIME from '../../../../ts/types/MIME';
// @ts-ignore
import { stringToArrayBuffer } from '../../../../js/modules/string_to_array_buffer';
@@ -19,7 +19,7 @@ describe('Message', () => {
sent_at: 1523317140800,
attachments: [
{
- contentType: 'image/jpeg' as MIMEType,
+ contentType: MIME.IMAGE_JPEG,
data: stringToArrayBuffer('foo'),
fileName: 'foo.jpg',
size: 1111,
@@ -35,7 +35,7 @@ describe('Message', () => {
sent_at: 1523317140800,
attachments: [
{
- contentType: 'image/jpeg' as MIMEType,
+ contentType: MIME.IMAGE_JPEG,
data: stringToArrayBuffer('foo'),
fileName: 'foo.jpg',
size: 1111,
diff --git a/ts/types/Attachment.ts b/ts/types/Attachment.ts
index d37b2f3e34..e4e58ffe84 100644
--- a/ts/types/Attachment.ts
+++ b/ts/types/Attachment.ts
@@ -2,13 +2,15 @@ import is from '@sindresorhus/is';
import moment from 'moment';
import * as GoogleChrome from '../util/GoogleChrome';
-import { saveURLAsFile } from '../util/saveURLAsFile';
+import * as MIME from './MIME';
import { arrayBufferToObjectURL } from '../util/arrayBufferToObjectURL';
-import { MIMEType } from './MIME';
+import { saveURLAsFile } from '../util/saveURLAsFile';
+import { SignalService } from '../protobuf';
export type Attachment = {
- fileName?: string;
- contentType?: MIMEType;
+ fileName?: string | null;
+ flags?: SignalService.AttachmentPointer.Flags;
+ contentType?: MIME.MIMEType;
size?: number;
data: ArrayBuffer;
@@ -20,15 +22,12 @@ export type Attachment = {
// thumbnail?: ArrayBuffer;
// key?: ArrayBuffer;
// digest?: ArrayBuffer;
- // flags?: number;
} & Partial;
interface AttachmentSchemaVersion3 {
path: string;
}
-const SAVE_CONTENT_TYPE = 'application/octet-stream' as MIMEType;
-
export const isVisualMedia = (attachment: Attachment): boolean => {
const { contentType } = attachment;
@@ -41,6 +40,26 @@ export const isVisualMedia = (attachment: Attachment): boolean => {
return isSupportedImageType || isSupportedVideoType;
};
+export const isVoiceMessage = (attachment: Attachment): boolean => {
+ const flag = SignalService.AttachmentPointer.Flags.VOICE_MESSAGE;
+ const hasFlag =
+ // tslint:disable-next-line no-bitwise
+ !is.undefined(attachment.flags) && (attachment.flags & flag) === flag;
+ if (hasFlag) {
+ return true;
+ }
+
+ const isLegacyAndroidVoiceMessage =
+ !is.undefined(attachment.contentType) &&
+ MIME.isAudio(attachment.contentType) &&
+ attachment.fileName === null;
+ if (isLegacyAndroidVoiceMessage) {
+ return true;
+ }
+
+ return false;
+};
+
export const save = ({
attachment,
document,
@@ -57,7 +76,7 @@ export const save = ({
? getAbsolutePath(attachment.path)
: arrayBufferToObjectURL({
data: attachment.data,
- type: SAVE_CONTENT_TYPE,
+ type: MIME.APPLICATION_OCTET_STREAM,
});
const filename = getSuggestedFilename({ attachment, timestamp });
saveURLAsFile({ url, filename, document });
diff --git a/ts/types/MIME.ts b/ts/types/MIME.ts
index 620df41c96..c2cc66ac58 100644
--- a/ts/types/MIME.ts
+++ b/ts/types/MIME.ts
@@ -1,5 +1,12 @@
export type MIMEType = string & { _mimeTypeBrand: any };
+export const APPLICATION_OCTET_STREAM = 'application/octet-stream' as MIMEType;
+export const AUDIO_AAC = 'audio/aac' as MIMEType;
+export const AUDIO_MP3 = 'audio/mp3' as MIMEType;
+export const IMAGE_GIF = 'image/gif' as MIMEType;
+export const IMAGE_JPEG = 'image/jpeg' as MIMEType;
+export const VIDEO_QUICKTIME = 'video/quicktime' as MIMEType;
+
export const isJPEG = (value: MIMEType): boolean => value === 'image/jpeg';
export const isImage = (value: MIMEType): boolean => value.startsWith('image/');
export const isVideo = (value: MIMEType): boolean => value.startsWith('video/');
diff --git a/yarn.lock b/yarn.lock
index 47540d5bbb..86b435defe 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -22,6 +22,49 @@
"7zip-bin-mac" "~1.0.1"
"7zip-bin-win" "~2.2.0"
+"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
+
+"@protobufjs/base64@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735"
+
+"@protobufjs/codegen@^2.0.4":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb"
+
+"@protobufjs/eventemitter@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70"
+
+"@protobufjs/fetch@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45"
+ dependencies:
+ "@protobufjs/aspromise" "^1.1.1"
+ "@protobufjs/inquire" "^1.1.0"
+
+"@protobufjs/float@^1.0.2":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1"
+
+"@protobufjs/inquire@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089"
+
+"@protobufjs/path@^1.1.2":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d"
+
+"@protobufjs/pool@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54"
+
+"@protobufjs/utf8@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570"
+
"@sindresorhus/is@^0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd"
@@ -56,6 +99,10 @@
version "4.14.106"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.106.tgz#6093e9a02aa567ddecfe9afadca89e53e5dce4dd"
+"@types/long@^3.0.32":
+ version "3.0.32"
+ resolved "https://registry.yarnpkg.com/@types/long/-/long-3.0.32.tgz#f4e5af31e9e9b196d8e5fca8a5e2e20aa3d60b69"
+
"@types/mocha@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.0.0.tgz#a3014921991066193f6c8e47290d4d598dfd19e6"
@@ -68,6 +115,10 @@
version "8.9.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.9.4.tgz#dfd327582a06c114eb6e0441fa3d6fab35edad48"
+"@types/node@^8.9.4":
+ version "8.10.12"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.12.tgz#dcb66f6de39074a296534bd1a256a3c6a1c8f5b5"
+
"@types/qs@^6.5.1":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.5.1.tgz#a38f69c62528d56ba7bd1f91335a8004988d72f7"
@@ -5326,6 +5377,10 @@ lolex@^2.2.0, lolex@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807"
+long@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
+
longest-streak@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.2.tgz#2421b6ba939a443bb9ffebf596585a50b4c38e2e"
@@ -6947,6 +7002,24 @@ prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1:
loose-envify "^1.3.1"
object-assign "^4.1.1"
+protobufjs@^6.8.6:
+ version "6.8.6"
+ resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.6.tgz#ce3cf4fff9625b62966c455fc4c15e4331a11ca2"
+ dependencies:
+ "@protobufjs/aspromise" "^1.1.2"
+ "@protobufjs/base64" "^1.1.2"
+ "@protobufjs/codegen" "^2.0.4"
+ "@protobufjs/eventemitter" "^1.1.0"
+ "@protobufjs/fetch" "^1.1.0"
+ "@protobufjs/float" "^1.0.2"
+ "@protobufjs/inquire" "^1.1.0"
+ "@protobufjs/path" "^1.1.2"
+ "@protobufjs/pool" "^1.1.0"
+ "@protobufjs/utf8" "^1.1.0"
+ "@types/long" "^3.0.32"
+ "@types/node" "^8.9.4"
+ long "^4.0.0"
+
proxy-addr@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"