diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000000..63fab7657b2c --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +**/build/* diff --git a/.flowconfig b/.flowconfig index d9a7bc921cd5..83b5e3c51b37 100644 --- a/.flowconfig +++ b/.flowconfig @@ -2,6 +2,7 @@ .*/build/.* [include] +./node_modules/@polkadot/dev/flow-typed [libs] @@ -9,3 +10,7 @@ esproposal.decorators=ignore module.ignore_non_literal_requires=true unsafe.enable_getters_and_setters=true +module.name_mapper='^@polkadot/api-format\(.*\)$' -> '/packages/api-format/src\1' +module.name_mapper='^@polkadot/api-jsonrpc\(.*\)$' -> '/packages/api-jsonrpc/src\1' +module.name_mapper='^@polkadot/api-provider\(.*\)$' -> '/packages/api-provider/src\1' +module.name_mapper='^@polkadot/jsonrpc\(.*\)$' -> '/packages/api-jsonrpc/src\1' diff --git a/.gitignore b/.gitignore index 88030e50b5f7..c598dbe4b7ed 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ tmp/ .env.development.local .env.test.local .env.production.local +lerna-debug.log* npm-debug.log* yarn-debug.log* yarn-error.log* diff --git a/.npmignore b/.npmignore index 99ec041f746f..8b137891791f 100644 --- a/.npmignore +++ b/.npmignore @@ -1,21 +1 @@ -coverage -scripts -src -test -tmp -.babelrc -.coveralls.yml -.editorconfig -.eslintrc.json -.flowconfig -.gitignore -.istanbul.yml -.travis.yml -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local -npm-debug.log* -yarn-debug.log* -yarn-error.log* + diff --git a/.travis.yml b/.travis.yml index b25770718023..36a9fea8638b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,10 @@ cache: directories: - node_modules before_install: - - npm install -g yarn --cache-min 999999999 + - npm install --global yarn --cache-min 999999999 + - npm install --global lerna install: - - yarn + - yarn install + - lerna bootstrap script: - - yarn run polkadot-dev-build-travis + - yarn polkadot-dev-build-travis diff --git a/README.md b/README.md index 6f0f5823e094..976719c7aba9 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,22 @@ +![ISC](https://img.shields.io/badge/license-ISC-lightgrey.svg) +[![npm (scoped)](https://img.shields.io/npm/v/@polkadot/api.svg)](https://www.npmjs.com/package/@polkadot/api) [![Build Status](https://travis-ci.org/polkadot-js/api.svg?branch=master)](https://travis-ci.org/polkadot-js/api) [![Coverage Status](https://coveralls.io/repos/github/polkadot-js/api/badge.svg?branch=master)](https://coveralls.io/github/polkadot-js/api?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/polkadot-js/api.svg)](https://greenkeeper.io/) -[![Dependency Status](https://david-dm.org/polkadot-js/api.svg)](https://david-dm.org/polkadot-js/api) -[![devDependency Status](https://david-dm.org/polkadot-js/api/dev-status.svg)](https://david-dm.org/polkadot-js/api#info=devDependencies) -# @polkadot/api +# @polkadot/client -Warning - currently this does not actually do all that much, it is an attempt to put into code some thoughts about how to maintain the endpoints. This library provides a clean wrapper around all the methods exposed by a Polkadot network client. Methods are auto-generated for the [JsonRPC interface definitions](https://github.com/polkadot-js/jsonrpc). +This library provides a clean wrapper around all the methods exposed by a Polkadot network client. -## Usage +It is split up into a number of internal packages - -Installation - +- [@polkadot/api](packages/api/) The API library +- [@polkadot/api-format](packages/api-format/) Input and output formatters +- [@polkadot/api-jsonrpc](packages/api-jsonrpc/) Interface definitions for RPC +- [@polkadot/api-provider](packages/api-provider/) Transport providers -``` -npm install --save @polkadot/api -``` +## Contributing -Initialisation - - -```js -import Api from '@polkadot/api'; -import HttpProvider from '@polkadot/api-provider/http'; - -const provider = new HttpProvider('http://127.0.0.1:9933'); -const api = new Api(provider); -``` - -Making calls - - -```js -api.chain - .getHeader('0x1234567890') - .then((header) => console.log(header)) - .catch((error) => console.error(error)); -``` - -## Available methods - -For a list of currently exposed methods, see the [@polkadot/jsonrpc](https://github.com/polkadot-js/jsonrpc#readme) repository. +- Make sure you have [Lerna](https://lernajs.io/) installed, `yarn install -g lerna` +- Bootstrap the dependencies, `lerna bootstrap` +- Make any changes in the relevant package, on master merges new versions will be published automatically diff --git a/jest.config.js b/jest.config.js index d7782a7531bd..d8b18290a2b6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1 +1,9 @@ -module.exports = require('@polkadot/dev/jest.config'); +const config = require('@polkadot/dev/jest.config'); + +module.exports = Object.assign({}, config, { + moduleNameMapper: { + '@polkadot/api-format(.*)$': '/packages/api-format/src/$1', + '@polkadot/api-jsonrpc(.*)$': '/packages/api-jsonrpc/src/$1', + '@polkadot/api-provider(.*)$': '/packages/api-provider/src/$1' + } +}); diff --git a/lerna.json b/lerna.json new file mode 100644 index 000000000000..ec3ab373f53d --- /dev/null +++ b/lerna.json @@ -0,0 +1,14 @@ +{ + "lerna": "2.5.1", + "npmClient": "yarn", + "useWorkspaces": true, + "command": { + "publish": { + "allowBranch": "master" + } + }, + "packages": [ + "packages/*" + ], + "version": "0.5.0" +} diff --git a/package.json b/package.json index 41bcdc97cad9..c2324ebc2a42 100644 --- a/package.json +++ b/package.json @@ -1,20 +1,13 @@ { - "name": "@polkadot/api", - "version": "0.4.14", - "description": "A JavaScript wrapper for the Polkadot JsonRPC interface", - "main": "index.js", - "keywords": [ - "Polkadot", - "JsonRPC" - ], + "name": "@polkadot/api-wrapper", + "version": "0.5.0", + "description": "Non-published, see packages/", + "keywords": [], "author": "Jaco Greeff ", "license": "ISC", + "private": true, "engines": { - "node": ">=6.4" - }, - "publishConfig": { - "access": "public", - "registry": "https://registry.npmjs.org" + "node": ">=8.0" }, "repository": { "type": "git", @@ -25,18 +18,16 @@ }, "homepage": "https://github.com/polkadot-js/api#readme", "scripts": { - "build": "polkadot-dev-build-babel", - "check": "eslint src && flow check", - "test": "jest --coverage src" + "build": "yarn polkadot-dev-build-babel", + "check": "yarn eslint packages && yarn flow check", + "test": "yarn jest --coverage packages" }, "devDependencies": { - "@polkadot/dev": "^0.8.1" + "@polkadot/dev": "^0.9.1", + "lerna": "^2.5.1" }, - "dependencies": { - "@polkadot/api-format": "^0.3.7", - "@polkadot/api-provider": "^0.1.6", - "@polkadot/jsonrpc": "^0.3.9", - "@polkadot/util": "^0.5.10", - "babel-runtime": "^6.26.0" - } + "dependencies": {}, + "workspaces": [ + "packages/*" + ] } diff --git a/packages/api-format/LICENSE b/packages/api-format/LICENSE new file mode 100644 index 000000000000..e4ee6869c311 --- /dev/null +++ b/packages/api-format/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017 Jaco Greeff + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/api-format/README.md b/packages/api-format/README.md new file mode 100644 index 000000000000..525bf991a980 --- /dev/null +++ b/packages/api-format/README.md @@ -0,0 +1,14 @@ +[![Dependency Status](https://david-dm.org/polkadot-js/api.svg?path=packages/api-format)](https://david-dm.org/polkadot-js/api?path=packages/api-format) +[![devDependency Status](https://david-dm.org/polkadot-js/api/dev-status.svg?path=packages/api-format)](https://david-dm.org/polkadot-js/api?path=packages/api-format#info=devDependencies) + +# @polkadot/api-format + +Formatters that are used by the application API interface, taking care of transparently formatting parameters (inputs) and the results (output) for requests made over the client RPC interfaces. + +## Usage + +Installation - + +``` +npm install --save @polkadot/api-format +``` diff --git a/packages/api-format/package.json b/packages/api-format/package.json new file mode 100644 index 000000000000..1b6790639ac8 --- /dev/null +++ b/packages/api-format/package.json @@ -0,0 +1,40 @@ +{ + "name": "@polkadot/api-format", + "version": "0.5.0", + "description": "Input/Output formatters for JsonRPC exchange", + "main": "index.js", + "keywords": [ + "Polkadot", + "JsonRPC" + ], + "author": "Jaco Greeff ", + "license": "ISC", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/api.git" + }, + "bugs": { + "url": "https://github.com/polkadot-js/api/issues" + }, + "homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-format#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "devDependencies": { + "@polkadot/api-jsonrpc": "^0.5.0", + "@polkadot/dev": "^0.9.1" + }, + "dependencies": { + "@polkadot/util": "^0.5.15", + "babel-runtime": "^6.26.0" + } +} diff --git a/packages/api-format/src/index.js b/packages/api-format/src/index.js new file mode 100644 index 000000000000..18a3031f6954 --- /dev/null +++ b/packages/api-format/src/index.js @@ -0,0 +1,10 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +const formatInputs = require('./input'); +const formatOutput = require('./output'); + +module.exports = { + formatInputs, + formatOutput +}; diff --git a/packages/api-format/src/input/address.js b/packages/api-format/src/input/address.js new file mode 100644 index 000000000000..9809ffc21266 --- /dev/null +++ b/packages/api-format/src/input/address.js @@ -0,0 +1,10 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +const { formatH160 } = require('./hex'); + +// TODO: Currently the format assumes 160-bit values (like Ethereum) +// this will probably change along the way as things get firmed up +module.exports = function format (value: ?string): string { + return formatH160(value); +}; diff --git a/packages/api-format/src/input/address.spec.js b/packages/api-format/src/input/address.spec.js new file mode 100644 index 000000000000..700459777b6f --- /dev/null +++ b/packages/api-format/src/input/address.spec.js @@ -0,0 +1,13 @@ +// ISC, Copyright 2017 Jaco Greeff + +const format = require('./address'); + +describe('input/address', () => { + describe('format', () => { + it('pads to H160 value', () => { + expect( + format('0x1234567890') + ).toEqual('0x0000000000000000000000000000001234567890'); + }); + }); +}); diff --git a/packages/api-format/src/input/hex.js b/packages/api-format/src/input/hex.js new file mode 100644 index 000000000000..4d72e946b8a1 --- /dev/null +++ b/packages/api-format/src/input/hex.js @@ -0,0 +1,33 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +const { hexAddPrefix, hexHasPrefix, hexStripPrefix } = require('@polkadot/util/hex'); + +const H64_ZERO: string = '00000000000000000000000000000000'; +const H128_ZERO: string = `${H64_ZERO}${H64_ZERO}`; +const H256_ZERO: string = `${H128_ZERO}${H128_ZERO}`; +// const H512_ZERO: string = `${H256_ZERO}${H256_ZERO}`; + +function leftHexPad (value: ?string, bitLength: number): string { + const length = 2 * bitLength / 8; + + if (hexHasPrefix(value)) { + value = hexStripPrefix(value); + } + + return hexAddPrefix(`${H256_ZERO}${value || ''}`.slice(-length)); +} + +function formatH160 (value: ?string): string { + return leftHexPad(value, 160); +} + +function formatH256 (value: ?string): string { + return leftHexPad(value, 256); +} + +module.exports = { + leftHexPad, + formatH160, + formatH256 +}; diff --git a/packages/api-format/src/input/hex.spec.js b/packages/api-format/src/input/hex.spec.js new file mode 100644 index 000000000000..cae7cc973580 --- /dev/null +++ b/packages/api-format/src/input/hex.spec.js @@ -0,0 +1,53 @@ +// ISC, Copyright 2017 Jaco Greeff + +const { leftHexPad, formatH160, formatH256 } = require('./hex'); + +describe('input/hex', () => { + describe('leftHexPad', () => { + it('padds to the required length', () => { + expect( + leftHexPad('0x123', 16) + ).toEqual('0x0123'); + }); + + it('padds to the required length (no prefix)', () => { + expect( + leftHexPad('123', 16) + ).toEqual('0x0123'); + }); + + it('pads null values correctly', () => { + expect( + leftHexPad(null, 16) + ).toEqual('0x0000'); + }); + }); + + describe('formatH160', () => { + it('pads to 40 bytes', () => { + expect( + formatH160('0x1234567890') + ).toEqual('0x0000000000000000000000000000001234567890'); + }); + + it('pads null values correctly', () => { + expect( + formatH160(null) + ).toMatch(/^0x(00){20,}$/); + }); + }); + + describe('formatH256', () => { + it('pads to 64 bytes', () => { + expect( + formatH256('0x1234567890') + ).toEqual('0x0000000000000000000000000000000000000000000000000000001234567890'); + }); + + it('pads null values correctly', () => { + expect( + formatH256(null) + ).toMatch(/^0x(00){32,}$/); + }); + }); +}); diff --git a/packages/api-format/src/input/index.js b/packages/api-format/src/input/index.js new file mode 100644 index 000000000000..8fcb6f52c11d --- /dev/null +++ b/packages/api-format/src/input/index.js @@ -0,0 +1,24 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { FormatInputType, InterfaceInputType } from '@polkadot/api-jsonrpc/types'; +import type { FormatterFunction } from '../types'; + +const formatAddress = require('./address'); +const { formatH256 } = require('./hex'); +const formatNoop = require('../noop'); +const util = require('../util'); + +const formatters: { [FormatInputType]: FormatterFunction } = { + 'Address': formatAddress, + 'CallData': formatNoop, + 'H256': formatH256, + 'HeaderHash': formatH256, + 'String': formatNoop +}; + +module.exports = function format (inputs: Array, values: Array): Array { + const types = inputs.map(({ type }) => type); + + return util.formatArray(formatters, types, values); +}; diff --git a/packages/api-format/src/input/index.spec.js b/packages/api-format/src/input/index.spec.js new file mode 100644 index 000000000000..e7af4f1d4709 --- /dev/null +++ b/packages/api-format/src/input/index.spec.js @@ -0,0 +1,22 @@ +// ISC, Copyright 2017 Jaco Greeff + +const format = require('./index'); + +describe('input', () => { + describe('format', () => { + it('formats each value in an array', () => { + expect( + format( + [ + { name: 'foo', type: 'Address' }, + { name: 'bar', type: 'H256' } + ], + ['0x1234', '0xabcd'] + ) + ).toEqual([ + '0x0000000000000000000000000000000000001234', + '0x000000000000000000000000000000000000000000000000000000000000abcd' + ]); + }); + }); +}); diff --git a/packages/api-format/src/noop.js b/packages/api-format/src/noop.js new file mode 100644 index 000000000000..6fc35ab9e808 --- /dev/null +++ b/packages/api-format/src/noop.js @@ -0,0 +1,6 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +module.exports = function format (value: any): any { + return value; +}; diff --git a/packages/api-format/src/noop.spec.js b/packages/api-format/src/noop.spec.js new file mode 100644 index 000000000000..46bdca6bcd37 --- /dev/null +++ b/packages/api-format/src/noop.spec.js @@ -0,0 +1,13 @@ +// ISC, Copyright 2017 Jaco Greeff + +const format = require('./noop'); + +describe('noop', () => { + it('returns input value as output value', () => { + const input = { 'some': 'object' }; + + expect( + format(input) + ).toEqual(input); + }); +}); diff --git a/packages/api-format/src/output/index.js b/packages/api-format/src/output/index.js new file mode 100644 index 000000000000..a0322c7a6e1d --- /dev/null +++ b/packages/api-format/src/output/index.js @@ -0,0 +1,18 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { FormatOutputType, InterfaceOutputType } from '@polkadot/api-jsonrpc/types'; +import type { FormatterFunction } from '../types'; + +const formatNoop = require('../noop'); +const util = require('../util'); + +const formatters: { [FormatOutputType]: FormatterFunction } = { + 'Header': formatNoop, + 'OutData': formatNoop, + 'StorageData': formatNoop +}; + +module.exports = function format (output: InterfaceOutputType, value: any): any { + return util.format(formatters, output.type, value); +}; diff --git a/packages/api-format/src/output/index.spec.js b/packages/api-format/src/output/index.spec.js new file mode 100644 index 000000000000..e73c1fa7e925 --- /dev/null +++ b/packages/api-format/src/output/index.spec.js @@ -0,0 +1,13 @@ +// ISC, Copyright 2017 Jaco Greeff + +const format = require('./index'); + +describe('output', () => { + describe('format', () => { + it('formats the value', () => { + expect( + format('Header', 'test') + ).toEqual('test'); + }); + }); +}); diff --git a/packages/api-format/src/types.js b/packages/api-format/src/types.js new file mode 100644 index 000000000000..7099809f172a --- /dev/null +++ b/packages/api-format/src/types.js @@ -0,0 +1,4 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +export type FormatterFunction = (value: any) => any; diff --git a/packages/api-format/src/util.js b/packages/api-format/src/util.js new file mode 100644 index 000000000000..91d7fe46748c --- /dev/null +++ b/packages/api-format/src/util.js @@ -0,0 +1,49 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { FormatterFunction } from './types'; + +const { isUndefined } = require('@polkadot/util/is'); +const formatNoop = require('./noop'); + +const arrayTypeRegex = /\[\]$/; + +function format (formatters: { [any]: FormatterFunction }, type: string, value: any): any { + const isArrayType: boolean = arrayTypeRegex.test(type); + const formatter: FormatterFunction = isArrayType + ? formatters[type.replace(arrayTypeRegex, '')] + : formatters[type]; + + if (isUndefined(formatter)) { + console.warn(`Unable to find default formatter for '${type}', falling back to noop`); + + return formatNoop(value); + } + + if (isArrayType && !Array.isArray(value)) { + throw new Error(`Unable to format non-array '${value}' as '${type}'`); + } + + try { + if (isArrayType) { + return (value: Array).map((value) => formatter(value)); + } else { + return formatter(value); + } + } catch (error) { + throw new Error(`Error formatting '${value}' as '${type}'': ${error.message}`); + } +} + +function formatArray (formatters: { [any]: FormatterFunction }, types: Array, values: Array): Array { + return types.map((type, index) => { + const value = values[index]; + + return format(formatters, type, value); + }); +} + +module.exports = { + format, + formatArray +}; diff --git a/packages/api-format/src/util.spec.js b/packages/api-format/src/util.spec.js new file mode 100644 index 000000000000..bad2b80fefe0 --- /dev/null +++ b/packages/api-format/src/util.spec.js @@ -0,0 +1,86 @@ +// ISC, Copyright 2017 Jaco Greeff + +/* global jest */ + +const { format, formatArray } = require('./util'); +const formatNoop = require('./noop'); + +describe('util', () => { + let formatters; + let noopSpy; + let warnSpy; + + beforeEach(() => { + noopSpy = jest.fn(formatNoop); + warnSpy = jest.spyOn(console, 'warn'); + + formatters = { + 'Address': noopSpy, + 'Address[]': noopSpy, + 'Exception': () => { + throw new Error('something went wrong'); + } + }; + }); + + afterEach(() => { + noopSpy.mockRestore(); + warnSpy.mockRestore(); + }); + + describe('format', () => { + it('formats unknown types with a fallback', () => { + expect( + format(formatters, 'Unknown', 'test') + ).toEqual('test'); + }); + + it('logs a warning with unknown types', () => { + format(formatters, 'Unknown', 'test'); + expect(warnSpy).toHaveBeenCalledWith("Unable to find default formatter for 'Unknown', falling back to noop"); + }); + + it('wraps exceptions with the type', () => { + expect( + () => format(formatters, 'Exception', 'test') + ).toThrow(/Error formatting 'test' as 'Exception'/); + }); + + describe('primitives', () => { + it('formats known types using the supplied formatter', () => { + format(formatters, 'Address', '0xaddress'); + + expect(noopSpy).toHaveBeenCalledWith('0xaddress'); + }); + }); + + describe('primitive[]', () => { + it('throws exception with array type, but non-array value', () => { + expect( + () => format(formatters, 'Address[]', 'not-an-array') + ).toThrow(/Unable to format non-array/); + }); + + it('formats using the primitive type', () => { + format(formatters, 'Address[]', ['0x123', '0x234']); + + expect(noopSpy).toHaveBeenCalledWith('0x123'); + expect(noopSpy).toHaveBeenCalledWith('0x234'); + }); + + it('returns formatted values as arrays', () => { + expect( + format(formatters, 'Address[]', ['0x123', '0x234']) + ).toEqual(['0x123', '0x234']); + }); + }); + }); + + describe('formatArray', () => { + it('formats each value in an array', () => { + expect( + formatArray(formatters, ['Unknown', 'Unknown'], ['test', 'blah']) + ).toEqual(['test', 'blah']); + }); + }); +}); diff --git a/packages/api-jsonrpc/LICENSE b/packages/api-jsonrpc/LICENSE new file mode 100644 index 000000000000..e4ee6869c311 --- /dev/null +++ b/packages/api-jsonrpc/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017 Jaco Greeff + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/api-jsonrpc/README.md b/packages/api-jsonrpc/README.md new file mode 100644 index 000000000000..28acb78bd1ad --- /dev/null +++ b/packages/api-jsonrpc/README.md @@ -0,0 +1,23 @@ +[![Dependency Status](https://david-dm.org/polkadot-js/api.svg?path=packages/api-jsonrpc)](https://david-dm.org/polkadot-js/api?path=packages/api-jsonrpc) +[![devDependency Status](https://david-dm.org/polkadot-js/api/dev-status.svg?path=packages/api-jsonrpc)](https://david-dm.org/polkadot-js/api?path=packages/api-jsonrpc#info=devDependencies) + +# @polkadot/api-jsonrpc + +A defintion of all the methods exposed in a general Polkadot client application. These are used not only to provide a comprehensive code-generated document of the available methods, but are also used in the API to auto-generate endpoints with the required type-checking. + +## Usage + +Installation - + +``` +npm install --save @polkadot/api-jsonrpc +``` + +For a list of currently exposed methods, see the [method documentation](docs/README.md). + +## Adding methods + +As methods are added, simply adding the name, inputs & output will prepare it for use. + +- Add the method to the correct file in [src/rpc/](src/rpc/) (Input/Output types as cross-referenced from the canonical implementation and match one-to-one) +- Should a new type be required, add it to the type list, [src/types.js](src/types.js) (Required for flow type checking) diff --git a/packages/api-jsonrpc/docs/README.md b/packages/api-jsonrpc/docs/README.md new file mode 100644 index 000000000000..45addbd1b25d --- /dev/null +++ b/packages/api-jsonrpc/docs/README.md @@ -0,0 +1,7 @@ +# Available interfaces + +Exposes the definition for the RPC endpoints for a Polkadot client node + +- [chain](chain.md) Methods to retrieve chain data. +- [state](state.md) Query the state and state storage. + diff --git a/packages/api-jsonrpc/docs/chain.md b/packages/api-jsonrpc/docs/chain.md new file mode 100644 index 000000000000..170da8138999 --- /dev/null +++ b/packages/api-jsonrpc/docs/chain.md @@ -0,0 +1,17 @@ +# chain + +Methods to retrieve chain data. + +- [getHeader](#getheader) Retrieves the header for a specific block. + +## getHeader + +Retrieves the header for a specific block. + +```js +chain_getHeader (hash: HeaderHash): Header +``` + + +Given a block header specified by `hash`, return the full block `Header` information. + diff --git a/packages/api-jsonrpc/docs/state.md b/packages/api-jsonrpc/docs/state.md new file mode 100644 index 000000000000..ec3f41f28897 --- /dev/null +++ b/packages/api-jsonrpc/docs/state.md @@ -0,0 +1,31 @@ +# state + +Query the state and state storage. + +- [call](#call) Perform a call to a builtin on the chain. +- [getStorage](#getstorage) Retrieves the storage for an address. + +## call + +Perform a call to a builtin on the chain. + +```js +chain_call (address: Address, method: String, data: CallData, block: HeaderHash): OutData +``` + + +Calls a `method` at a specific `address`, passing the encoded `data`. The query is executed at the block specified by `block`. + + + +## getStorage + +Retrieves the storage for an address. + +```js +chain_getStorage (address: Address, key: H256, block: HeaderHash): StorageData +``` + + +Retrieves the storage `key` at a specific `address`, executing the query at a specific `block`. + diff --git a/packages/api-jsonrpc/package.json b/packages/api-jsonrpc/package.json new file mode 100644 index 000000000000..509da01db3cd --- /dev/null +++ b/packages/api-jsonrpc/package.json @@ -0,0 +1,38 @@ +{ + "name": "@polkadot/api-jsonrpc", + "version": "0.5.0", + "description": "Method definitions for the Polkadot RPC layer", + "main": "index.js", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/api.git" + }, + "keywords": [ + "Polkadot", + "JsonRPC" + ], + "author": "Jaco Greeff ", + "license": "ISC", + "bugs": { + "url": "https://github.com/polkadot-js/api/issues" + }, + "homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-jsonrpc#readme", + "scripts": { + "build": "polkadot-dev-build-babel && polkadot-dev-build-docs", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "devDependencies": { + "@polkadot/dev": "^0.9.1" + }, + "dependencies": { + "babel-runtime": "^6.26.0" + } +} diff --git a/packages/api-jsonrpc/src/chain/getHeader.js b/packages/api-jsonrpc/src/chain/getHeader.js new file mode 100644 index 000000000000..f61b399c95cf --- /dev/null +++ b/packages/api-jsonrpc/src/chain/getHeader.js @@ -0,0 +1,21 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { InterfaceMethodDefinition } from '../types'; + +/** + @name getHeader + @signature chain_getHeader (hash: HeaderHash): Header + @summary Retrieves the header for a specific block. + @description + Given a block header specified by `hash`, return the full block `Header` information. +*/ +module.exports = ({ + inputs: [ + { + name: 'hash', + type: 'HeaderHash' + } + ], + output: { type: 'Header' } +}: InterfaceMethodDefinition); diff --git a/packages/api-jsonrpc/src/chain/index.js b/packages/api-jsonrpc/src/chain/index.js new file mode 100644 index 000000000000..9bd7f6b187fb --- /dev/null +++ b/packages/api-jsonrpc/src/chain/index.js @@ -0,0 +1,15 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { InterfaceDefinition } from '../types'; + +const getHeader = require('./getHeader'); + +/** + @summary Methods to retrieve chain data. +*/ +module.exports = ({ + methods: { + getHeader + } +}: InterfaceDefinition); diff --git a/packages/api-jsonrpc/src/index.js b/packages/api-jsonrpc/src/index.js new file mode 100644 index 000000000000..49350f099459 --- /dev/null +++ b/packages/api-jsonrpc/src/index.js @@ -0,0 +1,15 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { InterfaceDefinition } from './types'; + +const chain = require('./chain'); +const state = require('./state'); + +/** + @summary Exposes the definition for the RPC endpoints for a Polkadot client node +*/ +module.exports = ({ + chain, + state +}: { [string]: InterfaceDefinition }); diff --git a/packages/api-jsonrpc/src/index.spec.js b/packages/api-jsonrpc/src/index.spec.js new file mode 100644 index 000000000000..dc997dee360f --- /dev/null +++ b/packages/api-jsonrpc/src/index.spec.js @@ -0,0 +1,10 @@ +// ISC, Copyright 2017 Jaco Greeff + +const interfaces = require('./index'); + +describe('jsonrpc', () => { + it('exports the available interfaces', () => { + expect(interfaces).toBeDefined(); + expect(Object.keys(interfaces).length).toBeGreaterThan(0); + }); +}); diff --git a/packages/api-jsonrpc/src/state/call.js b/packages/api-jsonrpc/src/state/call.js new file mode 100644 index 000000000000..1b13869d1d98 --- /dev/null +++ b/packages/api-jsonrpc/src/state/call.js @@ -0,0 +1,35 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { InterfaceMethodDefinition } from '../types'; + +/** + @name call + @signature chain_call (address: Address, method: String, data: CallData, block: HeaderHash): OutData + @summary Perform a call to a builtin on the chain. + @description + Calls a `method` at a specific `address`, passing the encoded `data`. The query is executed at the block specified by `block`. +*/ +module.exports = ({ + inputs: [ + { + name: 'address', + type: 'Address' + }, + { + name: 'method', + type: 'String' + }, + { + name: 'data', + type: 'CallData' + }, + { + name: 'block', + type: 'HeaderHash' + } + ], + output: { + type: 'OutData' + } +}: InterfaceMethodDefinition); diff --git a/packages/api-jsonrpc/src/state/getStorage.js b/packages/api-jsonrpc/src/state/getStorage.js new file mode 100644 index 000000000000..b0226654a9ab --- /dev/null +++ b/packages/api-jsonrpc/src/state/getStorage.js @@ -0,0 +1,31 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { InterfaceMethodDefinition } from '../types'; + +/** + @name getStorage + @signature chain_getStorage (address: Address, key: H256, block: HeaderHash): StorageData + @summary Retrieves the storage for an address. + @description + Retrieves the storage `key` at a specific `address`, executing the query at a specific `block`. +*/ +module.exports = ({ + inputs: [ + { + name: 'address', + type: 'Address' + }, + { + name: 'key', + type: 'H256' + }, + { + name: 'block', + type: 'HeaderHash' + } + ], + output: { + type: 'StorageData' + } +}: InterfaceMethodDefinition); diff --git a/packages/api-jsonrpc/src/state/index.js b/packages/api-jsonrpc/src/state/index.js new file mode 100644 index 000000000000..19ddab1f2615 --- /dev/null +++ b/packages/api-jsonrpc/src/state/index.js @@ -0,0 +1,17 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { InterfaceDefinition } from '../types'; + +const call = require('./call'); +const getStorage = require('./getStorage'); + +/** + @summary Query the state and state storage. +*/ +module.exports = ({ + methods: { + call, + getStorage + } +}: InterfaceDefinition); diff --git a/packages/api-jsonrpc/src/types.js b/packages/api-jsonrpc/src/types.js new file mode 100644 index 000000000000..82494bbede11 --- /dev/null +++ b/packages/api-jsonrpc/src/types.js @@ -0,0 +1,27 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +export type FormatInputType = 'Address' | 'CallData' | 'H256' | 'HeaderHash' | 'String'; + +export type FormatOutputType = 'Header' | 'OutData' | 'StorageData'; + +export type InterfaceInputType = { + name: string, + type: FormatInputType +}; + +export type InterfaceOutputType = { + type: FormatOutputType +}; + +export type InterfaceMethodDefinition = { + deprecated?: boolean, + inputs: Array, + output: InterfaceOutputType +}; + +export type InterfaceDefinition = { + methods: { + [string]: InterfaceMethodDefinition + } +}; diff --git a/packages/api-provider/LICENSE b/packages/api-provider/LICENSE new file mode 100644 index 000000000000..e4ee6869c311 --- /dev/null +++ b/packages/api-provider/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017 Jaco Greeff + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/api-provider/README.md b/packages/api-provider/README.md new file mode 100644 index 000000000000..96a7ae854a19 --- /dev/null +++ b/packages/api-provider/README.md @@ -0,0 +1,25 @@ +[![Dependency Status](https://david-dm.org/polkadot-js/api.svg?path=packages/api-provider)](https://david-dm.org/polkadot-js/api?path=packages/api-provider) +[![devDependency Status](https://david-dm.org/polkadot-js/api/dev-status.svg?path=packages/api-provider)](https://david-dm.org/polkadot-js/api?path=packages/api-provider#info=devDependencies) + +# @polkadot/api-provider + +Generic transport providers to handle the transport of method calls to and from Polkadot clients from applications interacting with it. Generally, unless you are operating at a low-level and taking care of encoding and decoding of parameters/results, it won't be directly used. API interfaces building on top these providers can support various transports with the same underlying interfaces. + +## Usage + +Installation - + +``` +npm install --save @polkadot/api-provider +``` + +Initialisation - + +```js +import HttpProvider from '@polkadot/api-provider/http'; + +const provider = new HttpProvider('http://127.0.0.1:9933'); +const version = await provider.send('client_version', []); + +console.log('clientVersion', version); +``` diff --git a/packages/api-provider/package.json b/packages/api-provider/package.json new file mode 100644 index 000000000000..64a7e6363020 --- /dev/null +++ b/packages/api-provider/package.json @@ -0,0 +1,42 @@ +{ + "name": "@polkadot/api-provider", + "version": "0.5.0", + "description": "Transport providers for the API", + "main": "index.js", + "keywords": [ + "Polkadot", + "JsonRPC" + ], + "author": "Jaco Greeff ", + "license": "ISC", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/api.git" + }, + "bugs": { + "url": "https://github.com/polkadot-js/api/issues" + }, + "homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-provider#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "devDependencies": { + "@polkadot/dev": "^0.9.1", + "mock-socket": "^7.1.0", + "nock": "^9.1.0" + }, + "dependencies": { + "@polkadot/util": "^0.5.15", + "babel-runtime": "^6.26.0", + "isomorphic-fetch": "^2.2.1" + } +} diff --git a/packages/api-provider/src/http/index.js b/packages/api-provider/src/http/index.js new file mode 100644 index 000000000000..83c37b65ff60 --- /dev/null +++ b/packages/api-provider/src/http/index.js @@ -0,0 +1,39 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { ProviderInterface } from '../types'; + +require('./polyfill'); + +const JsonRpcCoder = require('../jsonRpcCoder'); + +module.exports = class HttpProvider extends JsonRpcCoder implements ProviderInterface { + _endpoint: string; + + constructor (endpoint: string) { + super(); + + this._endpoint = endpoint; + } + + async send (method: string, params: Array): Promise { + const body = this.encodeJson(method, params); + const response = await fetch(this._endpoint, { + body, + headers: { + 'Accept': 'application/json', + 'Content-Length': `${body.length}`, + 'Content-Type': 'application/json' + }, + method: 'POST' + }); + + if (!response.ok) { + throw new Error(`[${response.status}]: ${response.statusText}`); + } + + const result = await response.json(); + + return this.decodeResponse(result); + } +}; diff --git a/packages/api-provider/src/http/index.spec.js b/packages/api-provider/src/http/index.spec.js new file mode 100644 index 000000000000..d25b4490932b --- /dev/null +++ b/packages/api-provider/src/http/index.spec.js @@ -0,0 +1,97 @@ +// ISC, Copyright 2017 Jaco Greeff + +/* global jest */ + +const { mockHttp, TEST_HTTP_URL } = require('../../test/mockHttp'); + +const Http = require('./index'); + +describe('Http', () => { + let http; + let mock; + let encodeSpy; + let decodeSpy; + + beforeEach(() => { + http = new Http(TEST_HTTP_URL); + + encodeSpy = jest.spyOn(http, 'encodeJson'); + decodeSpy = jest.spyOn(http, 'decodeResponse'); + }); + + afterEach(() => { + encodeSpy.mockRestore(); + decodeSpy.mockRestore(); + + mock.done(); + }); + + describe('send', () => { + it('encodes requests', () => { + mock = mockHttp([{ + method: 'test_encoding', + reply: { + result: 'ok' + } + }]); + + return http + .send('test_encoding', ['param']) + .then((result) => { + expect(encodeSpy).toHaveBeenCalledWith('test_encoding', ['param']); + }); + }); + + it('decodes responses', () => { + mock = mockHttp([{ + method: 'test_encoding', + reply: { + result: 'ok' + } + }]); + + return http + .send('test_encoding', ['param']) + .then((result) => { + expect(decodeSpy).toHaveBeenCalledWith({ + id: 1, + jsonrpc: '2.0', + result: 'ok' + }); + }); + }); + + it('passes the body through correctly', () => { + mock = mockHttp([{ + method: 'test_body', + reply: { + result: 'ok' + } + }]); + + return http + .send('test_body', ['param']) + .then((result) => { + expect(mock.body['test_body']).toEqual({ + id: 1, + jsonrpc: '2.0', + method: 'test_body', + params: ['param'] + }); + }); + }); + + it('throws error when !response.ok', () => { + mock = mockHttp([{ + code: 500, + method: 'test_error' + }]); + + return http + .send('test_error', []) + .catch((error) => { + expect(error.message).toMatch(/\[500\]: Internal Server/); + }); + }); + }); +}); diff --git a/packages/api-provider/src/http/polyfill.js b/packages/api-provider/src/http/polyfill.js new file mode 100644 index 000000000000..63e67c470b83 --- /dev/null +++ b/packages/api-provider/src/http/polyfill.js @@ -0,0 +1,6 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +if (typeof fetch === 'undefined') { + require('isomorphic-fetch'); +} diff --git a/packages/api-provider/src/http/polyfill.spec.js b/packages/api-provider/src/http/polyfill.spec.js new file mode 100644 index 000000000000..be6f3f3dca22 --- /dev/null +++ b/packages/api-provider/src/http/polyfill.spec.js @@ -0,0 +1,24 @@ +// ISC, Copyright 2017 Jaco Greeff + +describe('http/polyfill', () => { + let origFetch; + + beforeEach(() => { + origFetch = global.fetch; + global.fetch = null; + }); + + afterEach(() => { + global.fetch = origFetch; + }); + + it('polyfills with no exceptions (without fetch)', () => { + expect(require('./polyfill')).toBeDefined(); + }); + + it('polyfills with no exceptions (with fetch)', () => { + global.fetch = () => true; + + expect(require('./polyfill')).toBeDefined(); + }); +}); diff --git a/packages/api-provider/src/index.js b/packages/api-provider/src/index.js new file mode 100644 index 000000000000..01ec2f4c5c07 --- /dev/null +++ b/packages/api-provider/src/index.js @@ -0,0 +1,10 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +const Http = require('./http'); +const Ws = require('./ws'); + +module.exports = { + Http, + Ws +}; diff --git a/packages/api-provider/src/jsonRpcCoder.js b/packages/api-provider/src/jsonRpcCoder.js new file mode 100644 index 000000000000..496d968dd6e9 --- /dev/null +++ b/packages/api-provider/src/jsonRpcCoder.js @@ -0,0 +1,55 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { JsonRpcRequest, JsonRpcResponse } from './types'; + +const { isNumber, isUndefined } = require('@polkadot/util/is'); + +module.exports = class JsonRpcCoder { + _id: number = 0; + + decodeResponse (response: JsonRpcResponse): any { + if (!response) { + throw new Error('Empty response object received'); + } + + if (response.jsonrpc !== '2.0') { + throw new Error('Invalid jsonrpc field in decoded object'); + } + + if (!isNumber(response.id)) { + throw new Error('Invalid id field in decoded object'); + } + + if (response.error) { + const { code, message } = response.error; + + throw new Error(`[${code}]: ${message}`); + } + + if (isUndefined(response.result)) { + throw new Error('No result found in JsonRpc response'); + } + + return response.result; + } + + encodeObject (method: string, params: Array): JsonRpcRequest { + return { + id: ++this._id, + jsonrpc: '2.0', + method, + params + }; + } + + encodeJson (method: string, params: Array): string { + return JSON.stringify( + this.encodeObject(method, params) + ); + } + + get id (): number { + return this._id; + } +}; diff --git a/packages/api-provider/src/jsonRpcCoder.spec.js b/packages/api-provider/src/jsonRpcCoder.spec.js new file mode 100644 index 000000000000..9e917e7d889f --- /dev/null +++ b/packages/api-provider/src/jsonRpcCoder.spec.js @@ -0,0 +1,77 @@ +// ISC, Copyright 2017 Jaco Greeff + +const JsonRpcCoder = require('./jsonRpcCoder'); + +describe('JsonRpcCoder', () => { + let coder; + + beforeEach(() => { + coder = new JsonRpcCoder(); + }); + + describe('id', () => { + it('starts with id === 0 (nothing sent)', () => { + expect(coder.id).toEqual(0); + }); + }); + + describe('decodeResponse', () => { + it('expects a non-empty input object', () => { + expect( + () => coder.decodeResponse() + ).toThrow(/Empty response/); + }); + + it('expects a valid jsonrpc field', () => { + expect( + () => coder.decodeResponse({}) + ).toThrow(/Invalid jsonrpc/); + }); + + it('expects a valid id field', () => { + expect( + () => coder.decodeResponse({ jsonrpc: '2.0' }) + ).toThrow(/Invalid id/); + }); + + it('expects a valid result field', () => { + expect( + () => coder.decodeResponse({ id: 1, jsonrpc: '2.0' }) + ).toThrow(/No result/); + }); + + it('throws any error found', () => { + expect( + () => coder.decodeResponse({ id: 1, jsonrpc: '2.0', error: { code: 123, message: 'test error' } }) + ).toThrow(/\[123\]: test error/); + }); + + it('returns the result', () => { + expect( + coder.decodeResponse({ id: 1, jsonrpc: '2.0', result: 'some result' }) + ).toEqual('some result'); + }); + }); + + describe('encodeObject', () => { + it('encodes a valid JsonRPC object', () => { + expect( + coder.encodeObject('method', 'params') + ).toEqual({ + id: 1, + jsonrpc: '2.0', + method: 'method', + params: 'params' + }); + expect(coder.id).toEqual(1); + }); + }); + + describe('encodeJson', () => { + it('encodes a valid JsonRPC JSON string', () => { + expect( + coder.encodeJson('method', 'params') + ).toEqual('{"id":1,"jsonrpc":"2.0","method":"method","params":"params"}'); + }); + }); +}); diff --git a/packages/api-provider/src/types.js b/packages/api-provider/src/types.js new file mode 100644 index 000000000000..ab60b4d7cbd0 --- /dev/null +++ b/packages/api-provider/src/types.js @@ -0,0 +1,26 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +export type JsonRpcObject = { + id: number; + jsonrpc: '2.0'; +}; + +export type JsonRpcRequest = JsonRpcObject & { + method: string; + params: Array; +}; + +export type JsonRpcResponseBase = { + error?: { + code: number, + message: string + }; + result?: any; +} + +export type JsonRpcResponse = JsonRpcObject & JsonRpcResponseBase; + +export interface ProviderInterface { + send (method: string, params: Array): Promise; +} diff --git a/packages/api-provider/src/ws/index.js b/packages/api-provider/src/ws/index.js new file mode 100644 index 000000000000..a8a90e2be987 --- /dev/null +++ b/packages/api-provider/src/ws/index.js @@ -0,0 +1,101 @@ +// ISC, Copyright 2017 Jaco Greeff +// @flow + +import type { JsonRpcResponse, ProviderInterface } from '../types'; + +type AwaitingType = { + callback: (error: ?Error, result: any) => void +}; + +type WsMessageType = { + data: any +}; + +const JsonRpcCoder = require('../jsonRpcCoder'); + +module.exports = class WsProvider extends JsonRpcCoder implements ProviderInterface { + _autoConnect: boolean = true; + _endpoint: string; + _handlers: { [number]: AwaitingType } = {}; + _websocket: WebSocket; + + constructor (endpoint: string, autoConnect: boolean = true) { + super(); + + this._endpoint = endpoint; + this._autoConnect = autoConnect; + + if (autoConnect) { + this.connect(); + } + } + + connect = () => { + this._handlers = {}; + + this._websocket = new WebSocket(this._endpoint); + + this._websocket.onclose = this._onClose; + this._websocket.onerror = this._onError; + this._websocket.onmessage = this._onMessage; + this._websocket.onopen = this._onOpen; + } + + _onClose = () => { + // console.log('disconnected from', this._endpoint); + + if (this._autoConnect) { + setTimeout(this.connect, 1000); + } + } + + _onError = (error: Event) => { + console.error(error); + } + + _onOpen = () => { + // console.log('connected to', this._endpoint); + } + + _onMessage = (message: WsMessageType) => { + const response: JsonRpcResponse = JSON.parse(message.data); + const handler = this._handlers[response.id]; + + if (!handler) { + console.error(`Unable to find handler for id=${response.id}`); + return; + } + + try { + const result = this.decodeResponse(response); + + handler.callback(null, result); + } catch (error) { + handler.callback(error); + } + + delete this._handlers[response.id]; + } + + send (method: string, params: Array): Promise { + return new Promise((resolve, reject) => { + try { + this._websocket.send( + this.encodeObject(method, params) + ); + + this._handlers[this.id] = { + callback: (error: ?Error, result: any) => { + if (error) { + reject(error); + } else { + resolve(result); + } + } + }; + } catch (error) { + reject(error); + } + }); + } +}; diff --git a/packages/api-provider/src/ws/index.spec.js b/packages/api-provider/src/ws/index.spec.js new file mode 100644 index 000000000000..4893848af2ca --- /dev/null +++ b/packages/api-provider/src/ws/index.spec.js @@ -0,0 +1,195 @@ +// ISC, Copyright 2017 Jaco Greeff + +/* global jest */ + +const { mockWs, TEST_WS_URL } = require('../../test/mockWs'); + +const { isUndefined } = require('@polkadot/util/is'); + +const Ws = require('./index'); + +let ws; +let mock; +let encodeSpy; +let decodeSpy; + +function createWs (requests, autoConnect) { + mock = autoConnect || isUndefined(autoConnect) + ? mockWs(requests) + : null; + + ws = new Ws(TEST_WS_URL, autoConnect); + + encodeSpy = jest.spyOn(ws, 'encodeObject'); + decodeSpy = jest.spyOn(ws, 'decodeResponse'); + + return ws; +} + +describe('Ws', () => { + afterEach(() => { + encodeSpy.mockRestore(); + decodeSpy.mockRestore(); + + if (mock) { + mock.done(); + } + }); + + describe('websocket', () => { + let errorSpy; + + beforeEach(() => { + ws = createWs([]); + + errorSpy = jest.spyOn(console, 'error'); + }); + + afterEach(() => { + errorSpy.mockRestore(); + }); + + it('sets up the on* handlers', () => { + expect(ws._websocket.onclose[0]).toEqual(ws._onClose); + expect(ws._websocket.onerror[0]).toEqual(ws._onError); + expect(ws._websocket.onmessage[0]).toEqual(ws._onMessage); + expect(ws._websocket.onopen[0]).toEqual(ws._onOpen); + }); + + describe('_onClose', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('reconnects after delay', () => { + ws.connect = jest.fn(); + ws._onClose(); + + expect(ws.connect).not.toHaveBeenCalled(); + + jest.runAllTimers(); + + expect(ws.connect).toHaveBeenCalled(); + }); + + it('does not reconnect when autoConnect false', () => { + mock.done(); + ws = createWs([], false); + + ws.connect = jest.fn(); + ws._onClose(); + + expect(ws.connect).not.toHaveBeenCalled(); + + jest.runAllTimers(); + + expect(ws.connect).not.toHaveBeenCalled(); + }); + }); + + describe('_onError', () => { + it('logs the error', () => { + ws._onError('test error'); + + expect(errorSpy).toHaveBeenCalledWith('test error'); + }); + }); + + describe('_onMessage', () => { + it('fails with log when handler not found', () => { + ws._onMessage({ data: '{"id":2}' }); + + expect(errorSpy).toHaveBeenCalledWith('Unable to find handler for id=2'); + }); + }); + }); + + describe('send', () => { + it('handles internal errors', () => { + ws = createWs([], false); + + return ws + .send('test_encoding', ['param']) + .catch((error) => { + expect(error).toBeDefined(); + }); + }); + + it('encodes requests', () => { + ws = createWs([{ + id: 1, + method: 'test_encoding', + reply: { + result: 'ok' + } + }]); + + return ws + .send('test_encoding', ['param']) + .then((result) => { + expect(encodeSpy).toHaveBeenCalledWith('test_encoding', ['param']); + }); + }); + + it('decodes responses', () => { + ws = createWs([{ + id: 1, + method: 'test_encoding', + reply: { + result: 'ok' + } + }]); + + return ws + .send('test_encoding', ['param']) + .then((result) => { + expect(decodeSpy).toHaveBeenCalledWith({ + id: 1, + jsonrpc: '2.0', + result: 'ok' + }); + }); + }); + + it('passes the body through correctly', () => { + ws = createWs([{ + id: 1, + method: 'test_body', + reply: { + result: 'ok' + } + }]); + + return ws + .send('test_body', ['param']) + .then((result) => { + expect(mock.body['test_body']).toEqual({ + id: 1, + jsonrpc: '2.0', + method: 'test_body', + params: ['param'] + }); + }); + }); + + it('throws error when !response.ok', () => { + ws = createWs([{ + id: 1, + error: { + code: 666, + message: 'error' + } + }]); + + return ws + .send('test_error', []) + .catch((error) => { + expect(error.message).toMatch(/\[666\]: error/); + }); + }); + }); +}); diff --git a/packages/api-provider/test/mockHttp.js b/packages/api-provider/test/mockHttp.js new file mode 100644 index 000000000000..4a7435e32ed0 --- /dev/null +++ b/packages/api-provider/test/mockHttp.js @@ -0,0 +1,25 @@ +// ISC, Copyright 2017 Jaco Greeff + +const nock = require('nock'); + +const TEST_HTTP_URL = 'http://localhost:9944'; + +function mockHttp (requests) { + nock.cleanAll(); + + return requests.reduce((scope, request, index) => { + return scope + .post('/') + .reply(request.code || 200, (uri, body) => { + scope.body = scope.body || {}; + scope.body[request.method] = body; + + return Object.assign({ id: body.id, jsonrpc: '2.0' }, request.reply || {}); + }); + }, nock(TEST_HTTP_URL)); +} + +module.exports = { + TEST_HTTP_URL, + mockHttp +}; diff --git a/packages/api-provider/test/mockWs.js b/packages/api-provider/test/mockWs.js new file mode 100644 index 000000000000..e4f88a9bf6bb --- /dev/null +++ b/packages/api-provider/test/mockWs.js @@ -0,0 +1,50 @@ +// ISC, Copyright 2017 Jaco Greeff + +const { Server } = require('mock-socket'); + +const TEST_WS_URL = 'ws://localhost:9955'; + +let server; + +function mockWs (requests) { + server = new Server(TEST_WS_URL); + let requestCount = 0; + + server.on('message', (body) => { + const request = requests[requestCount]; + const result = request.reply; + const response = request.error + ? { + id: request.id, + jsonrpc: '2.0', + error: { + code: request.error.code, + message: request.error.message + } + } + : { + id: request.id, + jsonrpc: '2.0', + result: result.result + }; + + scope.body[request.method] = body; + requestCount++; + + server.send(JSON.stringify(response)); + }); + + const scope = { + body: {}, + requests: 0, + server, + done: () => server.stop() + }; + + return scope; +} + +module.exports = { + TEST_WS_URL, + mockWs +}; diff --git a/packages/api/LICENSE b/packages/api/LICENSE new file mode 100644 index 000000000000..e4ee6869c311 --- /dev/null +++ b/packages/api/LICENSE @@ -0,0 +1,15 @@ +ISC License (ISC) + +Copyright 2017 Jaco Greeff + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/api/README.md b/packages/api/README.md new file mode 100644 index 000000000000..dadc07d49fc4 --- /dev/null +++ b/packages/api/README.md @@ -0,0 +1,37 @@ +[![Dependency Status](https://david-dm.org/polkadot-js/api.svg?path=packages/api)](https://david-dm.org/polkadot-js/api?path=packages/api) +[![devDependency Status](https://david-dm.org/polkadot-js/api/dev-status.svg?path=packages/api)](https://david-dm.org/polkadot-js/api?path=packages/api#info=devDependencies) + +# @polkadot/api + +Warning - currently this does not actually do all that much, it is an attempt to put into code some thoughts about how to maintain the endpoints. This library provides a clean wrapper around all the methods exposed by a Polkadot network client. Methods are auto-generated for the [JsonRPC interface definitions](https://github.com/polkadot-js/api/packages/api-jsonrpc). + +## Usage + +Installation - + +``` +npm install --save @polkadot/api +``` + +Initialisation - + +```js +import Api from '@polkadot/api'; +import HttpProvider from '@polkadot/api-provider/http'; + +const provider = new HttpProvider('http://127.0.0.1:9933'); +const api = new Api(provider); +``` + +Making calls - + +```js +api.chain + .getHeader('0x1234567890') + .then((header) => console.log(header)) + .catch((error) => console.error(error)); +``` + +## Available methods + +For a list of currently exposed methods, see the [@polkadot/api-jsonrpc](https://github.com/polkadot-js/api/packages/api-jsonrpc#readme) repository. diff --git a/packages/api/package.json b/packages/api/package.json new file mode 100644 index 000000000000..7919d7279142 --- /dev/null +++ b/packages/api/package.json @@ -0,0 +1,42 @@ +{ + "name": "@polkadot/api", + "version": "0.5.0", + "description": "A JavaScript wrapper for the Polkadot JsonRPC interface", + "main": "index.js", + "keywords": [ + "Polkadot", + "JsonRPC" + ], + "author": "Jaco Greeff ", + "license": "ISC", + "engines": { + "node": ">=6.4" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polkadot-js/api.git" + }, + "bugs": { + "url": "https://github.com/polkadot-js/api/issues" + }, + "homepage": "https://github.com/polkadot-js/api/tree/master/packages/api#readme", + "scripts": { + "build": "polkadot-dev-build-babel", + "check": "eslint src && flow check", + "test": "echo \"Tests only available from root wrapper\"" + }, + "devDependencies": { + "@polkadot/dev": "^0.9.1" + }, + "dependencies": { + "@polkadot/api-format": "^0.5.0", + "@polkadot/api-jsonrpc": "^0.5.0", + "@polkadot/api-provider": "^0.5.0", + "@polkadot/util": "^0.5.15", + "babel-runtime": "^6.26.0" + } +} diff --git a/src/api.js b/packages/api/src/api.js similarity index 94% rename from src/api.js rename to packages/api/src/api.js index 2eee3b7983e3..bcffdb70ba37 100644 --- a/src/api.js +++ b/packages/api/src/api.js @@ -2,11 +2,11 @@ // @flow import type { ProviderInterface } from '@polkadot/api-provider/types'; -import type { InterfaceDefinition } from '@polkadot/jsonrpc/types'; +import type { InterfaceDefinition } from '@polkadot/api-jsonrpc/types'; import type { ApiInterface } from './types'; const { formatInputs, formatOutput } = require('@polkadot/api-format'); -const interfaces = require('@polkadot/jsonrpc'); +const interfaces = require('@polkadot/api-jsonrpc'); const isFunction = require('@polkadot/util/is/function'); const jsonrpcSignature = require('@polkadot/util/jsonrpc/signature'); diff --git a/src/api.spec.js b/packages/api/src/api.spec.js similarity index 100% rename from src/api.spec.js rename to packages/api/src/api.spec.js diff --git a/src/index.js b/packages/api/src/index.js similarity index 100% rename from src/index.js rename to packages/api/src/index.js diff --git a/src/index.spec.js b/packages/api/src/index.spec.js similarity index 100% rename from src/index.spec.js rename to packages/api/src/index.spec.js diff --git a/src/types.js b/packages/api/src/types.js similarity index 100% rename from src/types.js rename to packages/api/src/types.js diff --git a/yarn.lock b/yarn.lock index e1de0ccc7093..09c4d8e678bb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -54,24 +54,9 @@ lodash "^4.2.0" to-fast-properties "^2.0.0" -"@polkadot/api-format@^0.3.7": - version "0.3.12" - resolved "https://registry.yarnpkg.com/@polkadot/api-format/-/api-format-0.3.12.tgz#6b26f0100ba3abfad41439734eecf1e9884979e8" - dependencies: - "@polkadot/util" "^0.5.10" - babel-runtime "^6.26.0" - -"@polkadot/api-provider@^0.1.6": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@polkadot/api-provider/-/api-provider-0.1.11.tgz#7644afddbd87e112a260da86111e8618841cd05c" - dependencies: - "@polkadot/util" "^0.5.10" - babel-runtime "^6.26.0" - isomorphic-fetch "^2.2.1" - -"@polkadot/dev@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.8.1.tgz#828994b8017a7b780e2b162172551016920e5b48" +"@polkadot/dev@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@polkadot/dev/-/dev-0.9.1.tgz#140a32eb7434003792be1abf2a676b6150b42c05" dependencies: babel-cli "^6.26.0" babel-core "^6.26.0" @@ -104,13 +89,7 @@ stylelint "^8.2.0" stylelint-config-standard "^18.0.0" -"@polkadot/jsonrpc@^0.3.9": - version "0.3.18" - resolved "https://registry.yarnpkg.com/@polkadot/jsonrpc/-/jsonrpc-0.3.18.tgz#7693f2bb60e2f53e6a58202f6e8f1e0333e1d840" - dependencies: - babel-runtime "^6.26.0" - -"@polkadot/util@^0.5.10": +"@polkadot/util@^0.5.15": version "0.5.15" resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-0.5.15.tgz#0e1ef0cec9699fd9c9ec1a324eefd074fcb423a5" dependencies: @@ -118,6 +97,13 @@ bn.js "^4.11.8" keccak "^1.3.0" +JSONStream@^1.0.4: + version "1.3.1" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + abab@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" @@ -150,6 +136,10 @@ acorn@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.2.1.tgz#317ac7821826c22c702d66189ab8359675f135d7" +add-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + ajv-keywords@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" @@ -252,6 +242,10 @@ array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + array-includes@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" @@ -297,6 +291,10 @@ assert-plus@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -305,7 +303,7 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" -async@^1.4.0: +async@^1.4.0, async@^1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -1140,6 +1138,10 @@ builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -1177,6 +1179,10 @@ caniuse-lite@^1.0.30000748, caniuse-lite@^1.0.30000770: version "1.0.30000772" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000772.tgz#78129622cabfed7af1ff38b64ab680a6a0865420" +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -1192,6 +1198,14 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +"chai@>=1.9.2 <4.0.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1290,6 +1304,17 @@ clone-regexp@^1.0.0: is-regexp "^1.0.0" is-supported-regexp-flag "^1.0.0" +clone@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.3.tgz#298d7e2231660f40c003c2ed3140decf3f53085f" + +cmd-shim@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1312,15 +1337,26 @@ color-name@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" +columnify@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" dependencies: delayed-stream "~1.0.0" +command-join@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/command-join/-/command-join-2.0.0.tgz#52e8b984f4872d952ff1bdc8b98397d27c7144cf" + commander@^2.11.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.1.tgz#468635c4168d06145b9323356d1da84d14ac4a7a" + version "2.12.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" commander@~2.9.0: version "2.9.0" @@ -1328,11 +1364,18 @@ commander@~2.9.0: dependencies: graceful-readlink ">= 1.0.0" +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.6.0: +concat-stream@^1.4.10, concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1352,6 +1395,151 @@ content-type-parser@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/content-type-parser/-/content-type-parser-1.0.2.tgz#caabe80623e63638b2502fd4c7f12ff4ce2352e7" +conventional-changelog-angular@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.5.2.tgz#2b38f665fe9c5920af1a2f82f547f4babe6de57c" + dependencies: + compare-func "^1.3.1" + q "^1.4.1" + +conventional-changelog-atom@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-0.1.2.tgz#12595ad5267a6937c34cf900281b1c65198a4c63" + dependencies: + q "^1.4.1" + +conventional-changelog-cli@^1.3.2: + version "1.3.5" + resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-1.3.5.tgz#46c51496216b7406588883defa6fac589e9bb31e" + dependencies: + add-stream "^1.0.0" + conventional-changelog "^1.1.7" + lodash "^4.1.0" + meow "^3.7.0" + tempfile "^1.1.1" + +conventional-changelog-codemirror@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.2.1.tgz#299a4f7147baf350e6c8158fc54954a291c5cc09" + dependencies: + q "^1.4.1" + +conventional-changelog-core@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-1.9.3.tgz#2899fe779389a329f0ec4b2746c36ddefb98da2d" + dependencies: + conventional-changelog-writer "^2.0.2" + conventional-commits-parser "^2.0.1" + dateformat "^1.0.12" + get-pkg-repo "^1.0.0" + git-raw-commits "^1.3.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^1.2.3" + lodash "^4.0.0" + normalize-package-data "^2.3.5" + q "^1.4.1" + read-pkg "^1.1.0" + read-pkg-up "^1.0.1" + through2 "^2.0.0" + +conventional-changelog-ember@^0.2.9: + version "0.2.9" + resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-0.2.9.tgz#8ec73cc054e3ab064667fb1feb52fe8ef1b16438" + dependencies: + q "^1.4.1" + +conventional-changelog-eslint@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-0.2.1.tgz#2c2a11beb216f80649ba72834180293b687c0662" + dependencies: + q "^1.4.1" + +conventional-changelog-express@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-0.2.1.tgz#838d9e1e6c9099703b150b9c19aa2d781742bd6c" + dependencies: + q "^1.4.1" + +conventional-changelog-jquery@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz#0208397162e3846986e71273b6c79c5b5f80f510" + dependencies: + q "^1.4.1" + +conventional-changelog-jscs@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz#0479eb443cc7d72c58bf0bcf0ef1d444a92f0e5c" + dependencies: + q "^1.4.1" + +conventional-changelog-jshint@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-0.2.1.tgz#86139bb3ac99899f2b177e9617e09b37d99bcf3a" + dependencies: + compare-func "^1.3.1" + q "^1.4.1" + +conventional-changelog-writer@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-2.0.2.tgz#b5857ded1b001daf9a78b9cd40926f45c134949b" + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^1.1.0" + dateformat "^1.0.11" + handlebars "^4.0.2" + json-stringify-safe "^5.0.1" + lodash "^4.0.0" + meow "^3.3.0" + semver "^5.0.1" + split "^1.0.0" + through2 "^2.0.0" + +conventional-changelog@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-1.1.7.tgz#9151a62b1d8edb2d82711dabf5b7cf71041f82b1" + dependencies: + conventional-changelog-angular "^1.5.2" + conventional-changelog-atom "^0.1.2" + conventional-changelog-codemirror "^0.2.1" + conventional-changelog-core "^1.9.3" + conventional-changelog-ember "^0.2.9" + conventional-changelog-eslint "^0.2.1" + conventional-changelog-express "^0.2.1" + conventional-changelog-jquery "^0.1.0" + conventional-changelog-jscs "^0.1.0" + conventional-changelog-jshint "^0.2.1" + +conventional-commits-filter@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-1.1.0.tgz#1fc29af30b5edab76f54e229c411b0c663d0f9eb" + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.0.1.tgz#1f15ce6b844f7ca41495c8190c0833c30b8b1693" + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^3.3.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +conventional-recommended-bump@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-1.0.3.tgz#472b69b1b8f09c5c4ed40fe28a41e63cc04bd736" + dependencies: + concat-stream "^1.4.10" + conventional-commits-filter "^1.1.0" + conventional-commits-parser "^2.0.1" + git-raw-commits "^1.3.0" + git-semver-tags "^1.2.3" + meow "^3.3.0" + object-assign "^4.0.1" + convert-source-map@^1.4.0, convert-source-map@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" @@ -1387,6 +1575,12 @@ coveralls@^3.0.0: minimist "^1.2.0" request "^2.79.0" +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -1423,12 +1617,25 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + dependencies: + number-is-nan "^1.0.0" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" dependencies: assert-plus "^1.0.0" +dateformat@^1.0.11, dateformat@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + debug@^2.2.0, debug@^2.6.8: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -1445,6 +1652,20 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" @@ -1459,6 +1680,12 @@ default-require-extensions@^1.0.0: dependencies: strip-bom "^2.0.0" +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + dependencies: + clone "^1.0.2" + define-properties@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" @@ -1492,6 +1719,10 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" @@ -1548,6 +1779,12 @@ domutils@^1.5.1: dom-serializer "0" domelementtype "1" +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + dependencies: + is-obj "^1.0.0" + dot-prop@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" @@ -1562,6 +1799,14 @@ dox@^0.9.0: jsdoctypeparser "^1.2.0" markdown-it "~7.0.0" +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" @@ -1815,6 +2060,18 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + 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" + execall@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execall/-/execall-1.0.0.tgz#73d0904e395b3cab0658b08d09ec25307f29bb73" @@ -2012,6 +2269,14 @@ fs-extra@^3.0.1: jsonfile "^3.0.0" universalify "^0.1.0" +fs-extra@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-readdir-recursive@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -2069,6 +2334,20 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-pkg-repo@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + dependencies: + hosted-git-info "^2.1.4" + meow "^3.3.0" + normalize-package-data "^2.3.0" + parse-github-repo-url "^1.3.0" + through2 "^2.0.0" + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -2087,6 +2366,36 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +git-raw-commits@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.3.0.tgz#0bc8596e90d5ffe736f7f5546bd2d12f73abaac6" + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^3.3.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + +git-semver-tags@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-1.2.3.tgz#188b453882bf9d7a23afd31baba537dab7388d5d" + dependencies: + meow "^3.3.0" + semver "^5.0.1" + +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + dependencies: + ini "^1.3.2" + github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" @@ -2104,6 +2413,13 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -2138,6 +2454,16 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + globby@^7.0.0: version "7.1.1" resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" @@ -2153,6 +2479,22 @@ globjoin@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43" +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2165,7 +2507,7 @@ growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" -handlebars@^4.0.3: +handlebars@^4.0.2, handlebars@^4.0.3: version "4.0.11" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" dependencies: @@ -2254,7 +2596,7 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -hosted-git-info@^2.1.4: +hosted-git-info@^2.1.4, hosted-git-info@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -2328,11 +2670,11 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -ini@~1.3.0: +ini@^1.3.2, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inquirer@^3.0.6: +inquirer@^3.0.6, inquirer@^3.2.2: version "3.3.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" dependencies: @@ -2436,6 +2778,10 @@ is-extglob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" @@ -2458,6 +2804,12 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + is-hexadecimal@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz#6e084bbc92061fbb0971ec58b6ce6d404e24da69" @@ -2494,7 +2846,7 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-plain-obj@^1.1.0: +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -2510,6 +2862,10 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" @@ -2526,10 +2882,18 @@ is-resolvable@^1.0.0: dependencies: tryit "^1.0.1" -is-stream@^1.0.1, is-stream@^1.1.0: +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + is-supported-regexp-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.0.tgz#8b520c85fae7a253382d4b02652e045576e13bb8" @@ -2538,6 +2902,12 @@ is-symbol@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + dependencies: + text-extensions "^1.0.0" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -2942,7 +3312,7 @@ json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@~5.0.1: +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -2956,10 +3326,20 @@ jsonfile@^3.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -3021,6 +3401,49 @@ lcov-parse@^0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" +lerna@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-2.5.1.tgz#d07099bd3051ee799f98c753328bd69e96c6fab8" + dependencies: + async "^1.5.0" + chalk "^2.1.0" + cmd-shim "^2.0.2" + columnify "^1.5.4" + command-join "^2.0.0" + conventional-changelog-cli "^1.3.2" + conventional-recommended-bump "^1.0.1" + dedent "^0.7.0" + execa "^0.8.0" + find-up "^2.1.0" + fs-extra "^4.0.1" + get-port "^3.2.0" + glob "^7.1.2" + glob-parent "^3.1.0" + globby "^6.1.0" + graceful-fs "^4.1.11" + hosted-git-info "^2.5.0" + inquirer "^3.2.2" + is-ci "^1.0.10" + load-json-file "^3.0.0" + lodash "^4.17.4" + minimatch "^3.0.4" + npmlog "^4.1.2" + p-finally "^1.0.0" + package-json "^4.0.1" + path-exists "^3.0.0" + read-cmd-shim "^1.0.1" + read-pkg "^2.0.0" + rimraf "^2.6.1" + safe-buffer "^5.1.1" + semver "^5.4.1" + signal-exit "^3.0.2" + strong-log-transformer "^1.0.6" + temp-write "^3.3.0" + write-file-atomic "^2.3.0" + write-json-file "^2.2.0" + write-pkg "^3.1.0" + yargs "^8.0.2" + leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" @@ -3057,6 +3480,15 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" +load-json-file@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-3.0.0.tgz#7eb3735d983a7ed2262ade4ff769af5369c5c440" + dependencies: + graceful-fs "^4.1.2" + parse-json "^3.0.0" + pify "^2.0.0" + strip-bom "^3.0.0" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3064,15 +3496,32 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash@^3.7.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: +lodash@^4.0.0, lodash@^4.1.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@~4.17.2: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -3107,6 +3556,10 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + lru-cache@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" @@ -3114,6 +3567,12 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +make-dir@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.1.0.tgz#19b4369fe48c116f53c2af95ad102c0e39e85d51" + dependencies: + pify "^3.0.0" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -3173,7 +3632,7 @@ mem@^1.1.0: dependencies: mimic-fn "^1.0.0" -meow@^3.7.0: +meow@^3.3.0, meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" dependencies: @@ -3234,6 +3693,10 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" +minimist@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" + minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -3242,12 +3705,24 @@ minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" -"mkdirp@>=0.5 0", mkdirp@^0.5.1: +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" +mock-socket@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-7.1.0.tgz#482ecccafb0f0e86b8905ba2aa57c1fe73ba262d" + +modify-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2" + +moment@^2.6.0: + version "2.19.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.2.tgz#8a7f774c95a64550b4c7ebd496683908f9419dbe" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -3264,6 +3739,20 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +nock@^9.1.0: + version "9.1.3" + resolved "https://registry.yarnpkg.com/nock/-/nock-9.1.3.tgz#1ab95a973a876c9ae2a844241844e29dbb5a1d89" + dependencies: + chai ">=1.9.2 <4.0.0" + debug "^2.2.0" + deep-equal "^1.0.0" + json-stringify-safe "^5.0.1" + lodash "~4.17.2" + mkdirp "^0.5.0" + propagate "0.4.0" + qs "^6.5.1" + semver "^5.3.0" + node-abi@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.1.2.tgz#4da6caceb6685fcd31e7dd1994ef6bb7d0a9c0b2" @@ -3317,7 +3806,7 @@ nopt@^4.0.1: abbrev "1" osenv "^0.1.4" -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: +normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: @@ -3346,7 +3835,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^4.0.1, npmlog@^4.0.2: +npmlog@^4.0.1, npmlog@^4.0.2, npmlog@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -3465,6 +3954,15 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" +package-json@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + parse-entities@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890" @@ -3476,6 +3974,10 @@ parse-entities@^1.0.2: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +parse-github-repo-url@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -3501,6 +4003,10 @@ parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -3555,7 +4061,7 @@ performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" -pify@^2.0.0: +pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -3678,6 +4184,10 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -3715,6 +4225,10 @@ prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" +propagate@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/propagate/-/propagate-0.4.0.tgz#f3fcca0a6fe06736a7ba572966069617c130b481" + prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" @@ -3734,14 +4248,18 @@ punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +q@^1.4.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" -qs@~6.5.1: +qs@^6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" @@ -3749,7 +4267,7 @@ randomatic@^1.1.3: is-number "^3.0.0" kind-of "^4.0.0" -rc@^1.1.6, rc@^1.1.7: +rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: version "1.2.2" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077" dependencies: @@ -3758,6 +4276,12 @@ rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +read-cmd-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + dependencies: + graceful-fs "^4.1.2" + read-pkg-up@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" @@ -3772,7 +4296,7 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg@^1.0.0: +read-pkg@^1.0.0, read-pkg@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" dependencies: @@ -3788,7 +4312,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2: +readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -3850,6 +4374,19 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" +registry-auth-token@^3.0.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" @@ -4077,7 +4614,7 @@ sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" @@ -4145,6 +4682,12 @@ sntp@2.x.x: dependencies: hoek "4.x.x" +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + dependencies: + is-plain-obj "^1.0.0" + source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" @@ -4183,6 +4726,18 @@ specificity@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.3.2.tgz#99e6511eceef0f8d9b57924937aac2cb13d13c42" +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + dependencies: + through2 "^2.0.2" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4282,6 +4837,16 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +strong-log-transformer@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-1.0.6.tgz#f7fb93758a69a571140181277eea0c2eb1301fa3" + dependencies: + byline "^5.0.0" + duplexer "^0.1.1" + minimist "^0.1.0" + moment "^2.6.0" + through "^2.3.4" + style-search@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" @@ -4427,6 +4992,28 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + +temp-write@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.3.0.tgz#c1a96de2b36061342eae81f44ff001aec8f615a9" + dependencies: + graceful-fs "^4.1.2" + is-stream "^1.1.0" + make-dir "^1.0.0" + pify "^2.2.0" + temp-dir "^1.0.0" + uuid "^3.0.1" + +tempfile@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-1.1.1.tgz#5bcc4eaecc4ab2c707d8bc11d99ccc9a2cb287f2" + dependencies: + os-tmpdir "^1.0.0" + uuid "^2.0.1" + test-exclude@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" @@ -4437,6 +5024,10 @@ test-exclude@^4.1.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" +text-extensions@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" + text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4445,10 +5036,21 @@ throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" -through@^2.3.6: +through2@^2.0.0, through2@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -4481,6 +5083,10 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -4517,6 +5123,14 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -4609,10 +5223,20 @@ unzip-response@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-1.0.2.tgz#b984f0877fc0a89c2c773cc1ef7b5b232b5b06fe" +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + url-parse-as-address@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-as-address/-/url-parse-as-address-1.0.0.tgz#fb80901883f338b3cbed3538f5faa26adaf7f2e7" +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + user-home@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" @@ -4621,7 +5245,11 @@ util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -uuid@^3.0.0, uuid@^3.1.0: +uuid@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" @@ -4678,6 +5306,12 @@ watch@~0.18.0: exec-sh "^0.2.0" minimist "^1.2.0" +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + dependencies: + defaults "^1.0.3" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" @@ -4753,7 +5387,7 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^2.1.0: +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" dependencies: @@ -4761,6 +5395,24 @@ write-file-atomic@^2.1.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +write-json-file@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.1.0.tgz#030a9994cc9993d25b4e75a9f1a1923607291ce9" + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" @@ -4779,7 +5431,7 @@ xml-name-validator@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-2.0.1.tgz#4d8b8f1eccd3419aa362061becef515e1e559635" -xtend@4.0.1, xtend@^4.0.0, xtend@^4.0.1: +xtend@4.0.1, xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"