├── .eslintrc.js ├── .gitignore ├── .gitmodules ├── .jsdoc.json ├── CHANGELOG.md ├── README.md ├── examples ├── connect.js └── websocket.js ├── lib ├── connect.ts ├── index.ts ├── ticker.ts └── utils.ts ├── package-lock.json ├── package.json ├── test ├── fullMode_binary.packet ├── ltpMode_binary.packet ├── quoteMode_binary.packet ├── test.js └── test_ticker.js ├── tsconfig.json ├── types ├── connect.d.ts ├── index.d.ts └── ticker.d.ts └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "overrides": [ 7 | ], 8 | "parserOptions": { 9 | "ecmaVersion": "latest", 10 | "sourceType": "module" 11 | }, 12 | "rules": { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node 2 | 3 | ### Node ### 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | dist 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # node-waf configuration 29 | .lock-wscript 30 | 31 | # Compiled binary addons (http://nodejs.org/api/addons.html) 32 | build/Release 33 | 34 | # Dependency directories 35 | node_modules 36 | jspm_packages 37 | 38 | # Optional npm cache directory 39 | .npm 40 | 41 | # Optional REPL history 42 | .node_repl_history 43 | 44 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test/kiteconnect-mocks"] 2 | path = test/kiteconnect-mocks 3 | url = https://github.com/zerodha/kiteconnect-mocks 4 | -------------------------------------------------------------------------------- /.jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true, 4 | "dictionaries": ["jsdoc"] 5 | }, 6 | "source": { 7 | "include": ["lib", "package.json", "README.md"], 8 | "includePattern": ".ts$", 9 | "excludePattern": "(node_modules/|docs)" 10 | }, 11 | "plugins": [ 12 | "plugins/markdown" 13 | ], 14 | "templates": { 15 | "cleverLinks": false, 16 | "monospaceLinks": true, 17 | "useLongnameInNav": false 18 | }, 19 | "opts": { 20 | "destination": "./docs/", 21 | "encoding": "utf8", 22 | "private": true, 23 | "recurse": true, 24 | "sort": false, 25 | "template": "./node_modules/minami" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Kite v4 2 | 3 | ### Breaking changes 4 | - Upgrade deps and set minimum nodejs version to 8.0.0+ 5 | - Return promise instead of throwing error on generateSession and renewAccessToken 6 | - Handle gtt payload validation and throw proper error 7 | - Change ticker response attributes naming as per [kite connect doc](https://kite.trade/docs/connect/v3/websocket/#quote-packet-structure) 8 | 9 | ### New features 10 | - Order margin call : [orderMargins](https://github.com/zerodha/kiteconnectjs/blob/master/lib/connect.js#L704) 11 | - Basket order margin call : [orderBasketMargins](https://github.com/zerodha/kiteconnectjs/blob/master/lib/connect.js#L727) 12 | - Add OI param to `getHistoricalData` 13 | - Add global constant for postion types `POSITION_TYPE_DAY`, `POSITION_TYPE_OVERNIGHT` and `EXCHANGE_BCD` 14 | 15 | ### Fixes 16 | - Remove `order_id` param from complete tradebook fetch `getTrades` 17 | - Fix `cancelMF` order_id param struct 18 | - Handle price conversion for BCD segment in ticker 19 | - Remove un-used `headers` param for `parseHistorical` 20 | - Update comment block for `getQuote, getOHLC, getLTP, placeOrder and placeMFOrder` 21 | 22 | 23 | # Kite v3 24 | 25 | ### New features 26 | - method: `getProfile` 27 | - method: `getOHLC` 28 | - method: `getLTP` 29 | - method: `getInstrumentsMargins` 30 | - Added MF API calls 31 | - method: `getMFOrders` 32 | - method: `getMFHoldings` 33 | - method: `placeMFOrder` 34 | - method: `cancelMFOrder` 35 | - method: `getMFSIPS` 36 | - method: `placeMFSIP` 37 | - method: `modifyMFSIP` 38 | - method: `cancelMFSIP` 39 | - method: `getMFInstruments` 40 | - method: `exitOrder` 41 | - method: `renewAccessToken` 42 | - method: `invalidateRefreshToken` 43 | - constants for products, order type, transaction type, variety, validity, exchanges and margin segments 44 | 45 | ### API method name changes 46 | 47 | | v2 | v3 | 48 | | ------------------------- | ------------------------- | 49 | | requestAccessToken | generateSession | 50 | | invalidateToken | invalidateAccessToken | 51 | | setSessionHook | setSessionExpiryHook | 52 | | loginUrl | getLoginURL | 53 | | margins | getMargins | 54 | | orderPlace | placeOrder | 55 | | orderModify | modifyOrder | 56 | | orderCancel | cancelOrder | 57 | | orders | getOrders | 58 | | orders(order_id) | getOrderHistory | 59 | | trades | getTrades | 60 | | trades(order_id) | getOrderTrades | 61 | | holdings | getHoldings | 62 | | positions | getPositions | 63 | | productModify | convertPosition | 64 | | instruments | getInstruments | 65 | | historical | getHistoricalData | 66 | | triggerRange | getTriggerRange | 67 | 68 | ### Params and other changes 69 | - `KiteConnect` takes all the params as object including `api_key` 70 | - `convertPosition` method takes all the params as object 71 | - All success response returns only `data` field in response instead with envelope 72 | - All error thrown are in the format of `{"message": "Unknown error", "error_type": "GeneralException", "data": null}` 73 | - [Changes in `generateSession` response structure](https://kite.trade/docs/connect/v3/user/#response-attributes) 74 | - [Changes in `getPositions` response structure](https://kite.trade/docs/connect/v3/portfolio/#response-attributes_1) 75 | - [Changes in `getQuote` response structure](https://kite.trade/docs/connect/v3/market-quotes/#retrieving-full-market-quotes) 76 | - [Changes in `placeOrder` params](https://kite.trade/docs/connect/v3/orders/#bracket-order-bo-parameters) 77 | - Changes in `getHistoricalData` params 78 | - All datetime string fields has been converted to `Date` object. 79 | - `getOrders`, `getOrderHistory`, `getTrades`, `getOrderTrades`, `getMFOrders` responses fields `order_timestamp`, `exchange_timestamp`, `fill_timestamp` 80 | - `getMFSIPS` fields `created`, `last_instalment` 81 | - `generateSession` field `login_time` 82 | - `getQuote` fields `timestamp`, `last_trade_time` 83 | - `getInstruments` field `expiry` 84 | - `getMFInstruments` field `last_price_date` 85 | 86 | ### KiteTicker changes 87 | - `KiteTicker` receives param `access_token` instead of `public_token` 88 | - New params addedd to `KiteTicker` initializer 89 | - `reconnect` - Toggle auto reconnect on/off 90 | - `max_retry` - Max retry count for auto reconnect 91 | - `max_delay` - Max delay between subsequent retries 92 | - Auto reconnect is enabled by default 93 | - Renamed callback `reconnecting` to `reconnect` 94 | - Added new callbacks 95 | - `error` - when socket connection is closed with error. Error is received as a first param 96 | - `close` - when socket connection is closed cleanly 97 | - `order_update` - When order update (postback) is received for the connected user (Data object is received as first argument) 98 | 99 | 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Kite Connect API Javascript client - v4 2 | 3 | The official Javascript node client for communicating with the [Kite Connect API](https://kite.trade). 4 | 5 | Kite Connect is a set of REST-like APIs that expose many capabilities required to build a complete investment and trading platform. Execute orders in real time, manage user portfolio, stream live market data (WebSockets), and more, with the simple HTTP API collection. 6 | 7 | [Zerodha Technology](http://zerodha.com) (c) 2018. Licensed under the MIT License. 8 | 9 | ## Documentation 10 | 11 | - [Javascript client documentation](https://kite.trade/docs/kiteconnectjs/v3) 12 | - [Kite Connect HTTP API documentation](https://kite.trade/docs/connect/v3) 13 | 14 | ## Requirements 15 | 16 | - NodeJS v8.0.0+ 17 | 18 | ## Installation 19 | 20 | Install via [npm](https://www.npmjs.com/package/kiteconnect) 21 | 22 | npm install kiteconnect@latest 23 | 24 | Or via Yarn 25 | 26 | yarn add kiteconnect 27 | 28 | ## Breaking changes - v4 29 | 30 | `v4` is a **breaking** major release with multiple internal modification to improve user experience.
31 | 32 | Below are the breaking changes: 33 | 34 | - Upgrade deps and set minimum nodejs version to 8.0.0+ 35 | - Return promise instead of throwing error on generateSession and renewAccessToken 36 | - Handle gtt payload validation and throw proper error 37 | - Change ticker response attributes naming as per [kite connect doc](https://kite.trade/docs/connect/v3/websocket/#quote-packet-structure) 38 | 39 | ## Getting started with API 40 | 41 | ```javascript 42 | var KiteConnect = require("kiteconnect").KiteConnect; 43 | 44 | var kc = new KiteConnect({ 45 | api_key: "your_api_key", 46 | }); 47 | 48 | kc.generateSession("request_token", "api_secret") 49 | .then(function (response) { 50 | init(); 51 | }) 52 | .catch(function (err) { 53 | console.log(err); 54 | }); 55 | 56 | function init() { 57 | // Fetch equity margins. 58 | // You can have other api calls here. 59 | kc.getMargins() 60 | .then(function (response) { 61 | // You got user's margin details. 62 | }) 63 | .catch(function (err) { 64 | // Something went wrong. 65 | }); 66 | } 67 | ``` 68 | 69 | ## API promises 70 | 71 | All API calls returns a promise which you can use to call methods like `.then(...)` and `.catch(...)`. 72 | 73 | ```javascript 74 | kiteConnectApiCall 75 | .then(function (v) { 76 | // On success 77 | }) 78 | .catch(function (e) { 79 | // On rejected 80 | }); 81 | ``` 82 | 83 | ## Getting started WebSocket client 84 | 85 | ```javascript 86 | var KiteTicker = require("kiteconnect").KiteTicker; 87 | var ticker = new KiteTicker({ 88 | api_key: "api_key", 89 | access_token: "access_token", 90 | }); 91 | 92 | ticker.connect(); 93 | ticker.on("ticks", onTicks); 94 | ticker.on("connect", subscribe); 95 | 96 | function onTicks(ticks) { 97 | console.log("Ticks", ticks); 98 | } 99 | 100 | function subscribe() { 101 | var items = [738561]; 102 | ticker.subscribe(items); 103 | ticker.setMode(ticker.modeFull, items); 104 | } 105 | ``` 106 | 107 | ## Auto re-connect WebSocket client 108 | 109 | Optionally you can enable client side auto re-connection to automatically reconnect if the connection is dropped. 110 | It is very useful at times when client side network is unreliable and patchy. 111 | 112 | All you need to do is enable auto re-connection with preferred interval and time. For example 113 | 114 | ```javascript 115 | // Enable auto reconnect with 5 second interval and retry for maximum of 20 times. 116 | ticker.autoReconnect(true, 20, 5); 117 | 118 | // You can also set re-connection times to -1 for infinite re-connections 119 | ticker.autoReconnect(true, -1, 5); 120 | ``` 121 | 122 | - Event `reconnecting` is called when auto re-connection is triggered and event callback carries two additional params `reconnection interval set` and `current re-connection count`. 123 | 124 | - Event `noreconnect` is called when number of auto re-connections exceeds the maximum re-connection count set. For example if maximum re-connection count is set as `20` then after 20th re-connection this event will be triggered. Also note that the current process is exited when this event is triggered. 125 | 126 | - Event `connect` will be triggered again when re-connection succeeds. 127 | 128 | Here is an example demonstrating auto reconnection. 129 | 130 | ```javascript 131 | var KiteTicker = require("kiteconnect").KiteTicker; 132 | var ticker = new KiteTicker({ 133 | api_key: "api_key", 134 | access_token: "access_token", 135 | }); 136 | 137 | // set autoreconnect with 10 maximum reconnections and 5 second interval 138 | ticker.autoReconnect(true, 10, 5); 139 | ticker.connect(); 140 | ticker.on("ticks", onTicks); 141 | ticker.on("connect", subscribe); 142 | 143 | ticker.on("noreconnect", function () { 144 | console.log("noreconnect"); 145 | }); 146 | 147 | ticker.on("reconnecting", function (reconnect_interval, reconnections) { 148 | console.log( 149 | "Reconnecting: attempt - ", 150 | reconnections, 151 | " innterval - ", 152 | reconnect_interval 153 | ); 154 | }); 155 | 156 | function onTicks(ticks) { 157 | console.log("Ticks", ticks); 158 | } 159 | 160 | function subscribe() { 161 | var items = [738561]; 162 | ticker.subscribe(items); 163 | ticker.setMode(ticker.modeFull, items); 164 | } 165 | ``` 166 | 167 | ## Run unit tests 168 | 169 | ``` 170 | npm run test 171 | ``` 172 | 173 | ## Generate documentation 174 | 175 | ``` 176 | $ npm install -g jsdoc 177 | $ jsdoc -r ./lib -d ./docs 178 | ``` 179 | 180 | ## Changelog 181 | 182 | [Check CHANGELOG.md](CHANGELOG.md) 183 | 184 | ## A typical web application 185 | 186 | In a typical web application where a new instance of 187 | views, controllers etc. are created per incoming HTTP 188 | request, you will need to initialise a new instance of 189 | Kite client per request as well. This is because each 190 | individual instance represents a single user that's 191 | authenticated, unlike an **admin** API where you may 192 | use one instance to manage many users. 193 | 194 | Hence, in your web application, typically: 195 | 196 | - You will initialise an instance of the Kite client 197 | - Redirect the user to the `login_url()` 198 | - At the redirect url endpoint, obtain the 199 | `request_token` from the query parameters 200 | - Initialise a new instance of Kite client, 201 | use `request_access_token()` to obtain the `access_token` 202 | along with authenticated user data 203 | - Store this response in a session and use the 204 | stored `access_token` and initialise instances 205 | of Kite client for subsequent API calls. 206 | -------------------------------------------------------------------------------- /examples/connect.js: -------------------------------------------------------------------------------- 1 | var KiteConnect = require("kiteconnect").KiteConnect; 2 | 3 | var api_key = "api_key", 4 | secret = "api_secret", 5 | request_token = "request_token", 6 | access_token = ""; 7 | 8 | var options = { 9 | "api_key": api_key, 10 | "debug": false 11 | }; 12 | 13 | let kc = new KiteConnect(options); 14 | kc.setSessionExpiryHook(sessionHook); 15 | 16 | if(!access_token) { 17 | kc.generateSession(request_token, secret) 18 | .then(function(response) { 19 | console.log("Response", response); 20 | init(); 21 | }) 22 | .catch(function(err) { 23 | console.log(err); 24 | }) 25 | } else { 26 | kc.setAccessToken(access_token); 27 | init(); 28 | } 29 | 30 | function init() { 31 | console.log(kc.getLoginURL()) 32 | 33 | getProfile(); 34 | getMargins(); 35 | getMargins("equity"); 36 | getPositions(); 37 | convertPosition(); 38 | getHoldings(); 39 | getOrders(); 40 | getOrderHistory(); 41 | getTrades(); 42 | getOrderTrades(); 43 | getInstruments(); 44 | getInstruments("NFO"); 45 | getQuote(["NSE:RELIANCE"]); 46 | getOHLC(["NSE:RELIANCE"]); 47 | getLTP(["NSE:RELIANCE"]); 48 | getHistoricalData(779521, "day", new Date("2018-01-01 18:05:00"), new Date("2018-01-10 18:05:37")); 49 | getHistoricalData(779521, "day", "2018-01-01 18:05:00", "2018-01-10 18:05:37"); 50 | getMFInstruments(); 51 | getMFOrders(); 52 | getMFSIPS(); 53 | 54 | regularOrderPlace("regular"); 55 | icebergTTLOrderPlace("iceberg"); 56 | modifyOrder("regular"); 57 | cancelOrder("regular"); 58 | 59 | getGTT(); 60 | getGTT("some_trigger_id"); 61 | placeGTT(); 62 | modifyGTT(); 63 | deleteGTT("some_trigger_id"); 64 | 65 | orderMargins(); 66 | basketMargins(); 67 | 68 | invalidateAccessToken() 69 | } 70 | 71 | function sessionHook() { 72 | console.log("User loggedout"); 73 | } 74 | 75 | function getProfile() { 76 | kc.getProfile() 77 | .then(function(response) { 78 | console.log(response) 79 | }).catch(function(err) { 80 | console.log(err); 81 | }); 82 | } 83 | 84 | function getMargins(segment) { 85 | kc.getMargins(segment) 86 | .then(function(response) { 87 | console.log(response); 88 | }).catch(function(err) { 89 | console.log(err); 90 | }); 91 | } 92 | 93 | function getPositions() { 94 | kc.getPositions() 95 | .then(function(response) { 96 | console.log(response); 97 | }).catch(function(err) { 98 | console.log(err); 99 | }); 100 | } 101 | 102 | function getHoldings() { 103 | kc.getHoldings() 104 | .then(function(response) { 105 | console.log(response); 106 | }).catch(function(err) { 107 | console.log(err.response); 108 | }); 109 | } 110 | 111 | function getOrders() { 112 | kc.getOrders() 113 | .then(function(response) { 114 | console.log(response); 115 | }).catch(function(err) { 116 | console.log(err); 117 | }); 118 | } 119 | 120 | function getOrderHistory() { 121 | kc.getOrders() 122 | .then(function(response) { 123 | if (response.length === 0) { 124 | console.log("No orders.") 125 | return 126 | } 127 | 128 | kc.getOrderHistory(response[0].order_id) 129 | .then(function(response) { 130 | console.log(response); 131 | }).catch(function(err) { 132 | console.log(err); 133 | }); 134 | }).catch(function(err) { 135 | console.log(err); 136 | }); 137 | } 138 | 139 | function getTrades() { 140 | kc.getTrades() 141 | .then(function(response) { 142 | console.log(response); 143 | }).catch(function(err) { 144 | console.log(err); 145 | }); 146 | } 147 | 148 | function getOrderTrades() { 149 | kc.getOrders() 150 | .then(function(response) { 151 | var completedOrdersID; 152 | for (var order of response) { 153 | if (order.status === kc.STATUS_COMPLETE) { 154 | completedOrdersID = order.order_id; 155 | break; 156 | } 157 | } 158 | 159 | if (!completedOrdersID) { 160 | console.log("No completed orders.") 161 | return 162 | } 163 | 164 | kc.getOrderTrades(completedOrdersID) 165 | .then(function(response) { 166 | console.log(response); 167 | }).catch(function(err) { 168 | console.log(err); 169 | }); 170 | }).catch(function(err) { 171 | console.log(err); 172 | }); 173 | } 174 | 175 | function getInstruments(exchange) { 176 | kc.getInstruments(exchange).then(function(response) { 177 | console.log(response); 178 | }).catch(function(err) { 179 | console.log(err); 180 | }) 181 | } 182 | 183 | function getQuote(instruments) { 184 | kc.getQuote(instruments).then(function(response) { 185 | console.log(response); 186 | }).catch(function(err) { 187 | console.log(err); 188 | }) 189 | } 190 | 191 | function getOHLC(instruments) { 192 | kc.getOHLC(instruments).then(function(response) { 193 | console.log(response); 194 | }).catch(function(err) { 195 | console.log(err); 196 | }) 197 | } 198 | 199 | function getLTP(instruments) { 200 | kc.getLTP(instruments).then(function(response) { 201 | console.log(response); 202 | }).catch(function(err) { 203 | console.log(err); 204 | }) 205 | } 206 | 207 | function getHistoricalData(instrument_token, interval, from_date, to_date, continuous) { 208 | kc.getHistoricalData(instrument_token, interval, from_date, to_date, continuous) 209 | .then(function(response) { 210 | console.log(response); 211 | }).catch(function(err) { 212 | console.log(err); 213 | }); 214 | } 215 | 216 | function getMFInstruments() { 217 | kc.getMFInstruments() 218 | .then(function(response) { 219 | console.log(response); 220 | }).catch(function(err) { 221 | console.log(err); 222 | }); 223 | } 224 | 225 | function getMFOrders() { 226 | kc.getMFOrders() 227 | .then(function(response) { 228 | console.log(response); 229 | }).catch(function(err) { 230 | console.log(err); 231 | }); 232 | } 233 | 234 | function getMFSIPS() { 235 | kc.getMFSIPS() 236 | .then(function(response) { 237 | console.log(response); 238 | }).catch(function(err) { 239 | console.log(err); 240 | }); 241 | } 242 | 243 | function invalidateAccessToken(access_token) { 244 | kc.invalidateAccessToken(access_token) 245 | .then(function(response) { 246 | console.log(response); 247 | testOrders(); 248 | }).catch(function(err) { 249 | console.log(err.response); 250 | }); 251 | } 252 | 253 | function regularOrderPlace(variety) { 254 | kc.placeOrder(variety, { 255 | "exchange": "NSE", 256 | "tradingsymbol": "RELIANCE", 257 | "transaction_type": "BUY", 258 | "quantity": 1, 259 | "product": "MIS", 260 | "order_type": "MARKET" 261 | }).then(function(resp) { 262 | console.log(resp); 263 | }).catch(function(err) { 264 | console.log(err); 265 | }); 266 | } 267 | 268 | function icebergTTLOrderPlace(variety) { 269 | kc.placeOrder(variety, { 270 | "exchange": "NSE", 271 | "tradingsymbol": "SBIN", 272 | "transaction_type": "BUY", 273 | "quantity": 1000, 274 | "product": "CNC", 275 | "order_type": "LIMIT", 276 | "validity":"TTL", 277 | "price":432, 278 | "validity_ttl":10, 279 | "iceberg_legs":5, 280 | "iceberg_quantity":200 281 | }).then(function(resp) { 282 | console.log(resp); 283 | }).catch(function(err) { 284 | console.log(err); 285 | }); 286 | } 287 | 288 | function modifyOrder(variety) { 289 | var tradingsymbol = "RELIANCE"; 290 | var exchange = "NSE"; 291 | var instrument = exchange + ":" + tradingsymbol; 292 | 293 | function modify(variety, order_id) { 294 | kc.modifyOrder(variety, order_id, { 295 | quantity: 2 296 | }).then(function(resp) { 297 | console.log(resp); 298 | }).catch(function(err) { 299 | console.log(err); 300 | }); 301 | } 302 | 303 | kc.getLTP([instrument]) 304 | .then(function(resp) { 305 | kc.placeOrder(variety, { 306 | "exchange": exchange, 307 | "tradingsymbol": tradingsymbol, 308 | "transaction_type": "BUY", 309 | "quantity": 1, 310 | "product": "MIS", 311 | "order_type": "LIMIT", 312 | "price": resp[instrument].last_price - 5 313 | }).then(function(resp) { 314 | modify(variety, resp.order_id); 315 | }).catch(function(err) { 316 | console.log("Order place error", err); 317 | }); 318 | }).catch(function(err) { 319 | console.log(err); 320 | }); 321 | } 322 | 323 | function cancelOrder(variety) { 324 | var tradingsymbol = "RELIANCE"; 325 | var exchange = "NSE"; 326 | var instrument = exchange + ":" + tradingsymbol; 327 | 328 | function cancel(variety, order_id) { 329 | kc.cancelOrder(variety, order_id) 330 | .then(function(resp) { 331 | console.log(resp); 332 | }).catch(function(err) { 333 | console.log(err); 334 | }); 335 | } 336 | 337 | kc.getLTP([instrument]) 338 | .then(function(resp) { 339 | kc.placeOrder(variety, { 340 | "exchange": exchange, 341 | "tradingsymbol": tradingsymbol, 342 | "transaction_type": "BUY", 343 | "quantity": 1, 344 | "product": "MIS", 345 | "order_type": "LIMIT", 346 | "price": resp[instrument].last_price - 5 347 | }).then(function(resp) { 348 | cancel(variety, resp.order_id); 349 | }).catch(function(err) { 350 | console.log("Order place error", err); 351 | }); 352 | }).catch(function(err) { 353 | console.log(err); 354 | }); 355 | } 356 | 357 | function getGTT(trigger_id) { 358 | if (trigger_id) { 359 | kc.getGTTs().then(function (resp) { 360 | console.log(resp) 361 | }).catch(function (error) { 362 | console.log(error) 363 | }) 364 | } else { 365 | kc.getGTT(trigger_id).then(function (resp) { 366 | console.log(resp) 367 | }).catch(function (error) { 368 | console.log(error) 369 | }) 370 | } 371 | } 372 | 373 | function placeGTT() { 374 | kc.placeGTT({ 375 | trigger_type: kc.GTT_TYPE_OCO, 376 | tradingsymbol: "SBIN", 377 | exchange: "NSE", 378 | trigger_values: [300, 400], 379 | last_price: 318, 380 | orders: [{ 381 | transaction_type: kc.TRANSACTION_TYPE_SELL, 382 | quantity: 1, 383 | product: kc.PRODUCT_CNC, 384 | order_type: kc.ORDER_TYPE_LIMIT, 385 | price: 300 386 | }, { 387 | transaction_type: kc.TRANSACTION_TYPE_SELL, 388 | quantity: 1, 389 | product: kc.PRODUCT_CNC, 390 | order_type: kc.ORDER_TYPE_LIMIT, 391 | price: 400 392 | }] 393 | }).then(function (resp) { 394 | console.log(resp) 395 | }).catch(function (error) { 396 | console.log(error) 397 | }) 398 | } 399 | 400 | function modifyGTT(trigger_id) { 401 | kc.modifyGTT(trigger_id, { 402 | trigger_type: kc.GTT_TYPE_OCO, 403 | tradingsymbol: "SBIN", 404 | exchange: "NSE", 405 | trigger_values: [301, 401], 406 | last_price: 318, 407 | orders: [{ 408 | transaction_type: kc.TRANSACTION_TYPE_SELL, 409 | quantity: 1, 410 | product: kc.PRODUCT_CNC, 411 | order_type: kc.ORDER_TYPE_LIMIT, 412 | price: 300 413 | }, { 414 | transaction_type: kc.TRANSACTION_TYPE_SELL, 415 | quantity: 1, 416 | product: kc.PRODUCT_CNC, 417 | order_type: kc.ORDER_TYPE_LIMIT, 418 | price: 400 419 | }] 420 | }).then(function (resp) { 421 | console.log(resp) 422 | }).catch(function (error) { 423 | console.log(error) 424 | }) 425 | } 426 | 427 | function deleteGTT(trigger_id) { 428 | kc.deleteGTT(trigger_id).then(function (resp) { 429 | console.log(resp) 430 | }).catch(function (error) { 431 | console.log(error) 432 | }) 433 | } 434 | 435 | function convertPosition() { 436 | kc.convertPosition({ 437 | exchange:"MCX", 438 | tradingsymbol:"GOLDPETAL21JUNFUT", 439 | transaction_type:"BUY", 440 | position_type:"day", 441 | quantity:4, 442 | old_product:"MIS", 443 | new_product:"NRML" 444 | }).then(function (resp) { 445 | console.log(resp) 446 | }).catch(function (error) { 447 | console.log(error) 448 | }) 449 | } 450 | 451 | function orderMargins() { 452 | kc.orderMargins([{ 453 | "exchange": "NFO", 454 | "tradingsymbol": "NIFTY21JUN15400PE", 455 | "transaction_type": "BUY", 456 | "variety": "regular", 457 | "product": "MIS", 458 | "order_type": "MARKET", 459 | "quantity": 75 460 | }, 461 | { 462 | "exchange": "NFO", 463 | "tradingsymbol": "NIFTY21JUN14450PE", 464 | "transaction_type": "SELL", 465 | "variety": "regular", 466 | "product": "MIS", 467 | "order_type": "MARKET", 468 | "quantity": 150 469 | }], "compact").then(function(resp) { 470 | console.log(resp); 471 | }).catch(function(err) { 472 | console.log(err); }); 473 | } 474 | 475 | function basketMargins() { 476 | kc.orderBasketMargins([{ 477 | "exchange": "NFO", 478 | "tradingsymbol": "NIFTY21JUN15400PE", 479 | "transaction_type": "BUY", 480 | "variety": "regular", 481 | "product": "MIS", 482 | "order_type": "MARKET", 483 | "quantity": 75 484 | }, 485 | { 486 | "exchange": "NFO", 487 | "tradingsymbol": "NIFTY21JUN14450PE", 488 | "transaction_type": "SELL", 489 | "variety": "regular", 490 | "product": "MIS", 491 | "order_type": "MARKET", 492 | "quantity": 150 493 | }], true, "compact").then(function (resp) { 494 | console.log(resp); 495 | }).catch(function(err) { 496 | console.log(err); }); 497 | } -------------------------------------------------------------------------------- /examples/websocket.js: -------------------------------------------------------------------------------- 1 | var KiteTicker = require("kiteconnect").KiteTicker; 2 | var ticker = new KiteTicker({ 3 | api_key: "api_key", 4 | access_token: "access_token" 5 | }); 6 | 7 | 8 | ticker.connect(); 9 | ticker.on('ticks', onTicks); 10 | ticker.on('connect', subscribe); 11 | ticker.on('disconnect', onDisconnect); 12 | ticker.on('error', onError); 13 | ticker.on('close', onClose); 14 | ticker.on('order_update', onTrade); 15 | 16 | function onTicks(ticks) { 17 | console.log("Ticks", ticks); 18 | } 19 | 20 | function subscribe() { 21 | var items = [738561]; 22 | ticker.subscribe(items); 23 | ticker.setMode(ticker.modeFull, items); 24 | } 25 | 26 | function onDisconnect(error) { 27 | console.log("Closed connection on disconnect", error); 28 | } 29 | 30 | function onError(error) { 31 | console.log("Closed connection on error", error); 32 | } 33 | 34 | function onClose(reason) { 35 | console.log("Closed connection on close", reason); 36 | } 37 | 38 | function onTrade(order) { 39 | console.log("Order update", order); 40 | } 41 | -------------------------------------------------------------------------------- /lib/connect.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import axios from "axios"; 4 | import csvParse from "papaparse"; 5 | import sha256 from "crypto-js/sha256"; 6 | import querystring from "querystring"; 7 | import utils from "./utils"; 8 | 9 | /** 10 | * @classdesc API client class. In production, you may initialise a single instance of this class per `api_key`. 11 | * This module provides an easy to use abstraction over the HTTP APIs. 12 | * The HTTP calls have been converted to methods and their JSON responses. 13 | * See the **[Kite Connect API documentation](https://kite.trade/docs/connect/v3/)** 14 | * for the complete list of APIs, supported parameters and values, and response formats. 15 | * 16 | * Getting started with API 17 | * ------------------------ 18 | * ~~~~ 19 | * 20 | * const KiteConnect = require("kiteconnect").KiteConnect; 21 | * 22 | * const kc = new KiteConnect({api_key: "your_api_key"}); 23 | * 24 | * kc.generateSession("request_token", "api_secret") 25 | * .then(function(response) { 26 | * init(); 27 | * }) 28 | * .catch(function(err) { 29 | * console.log(err); 30 | * }) 31 | * 32 | * function init() { 33 | * // Fetch equity margins. 34 | * // You can have other api calls here. 35 | * 36 | * kc.getMargins() 37 | * .then(function(response) { 38 | * // You got user's margin details. 39 | * }).catch(function(err) { 40 | * // Something went wrong. 41 | * }); 42 | * } 43 | * ~~~~ 44 | * 45 | * API promises 46 | * ------------- 47 | * All API calls returns a promise which you can use to call methods like `.then(...)` and `.catch(...)`. 48 | * 49 | * ~~~~ 50 | * kiteConnectApiCall 51 | * .then(function(v) { 52 | * // On success 53 | * }) 54 | * .catch(function(e) { 55 | * // On rejected 56 | * }); 57 | * ~~~~ 58 | * 59 | * @constructor 60 | * @name KiteConnect 61 | * 62 | * @param {Object} params Init params. 63 | * @param {string} params.api_key API key issued to you. 64 | * @param {string} [params.access_token=null] Token obtained after the login flow in 65 | * exchange for the `request_token`. Pre-login, this will default to null, 66 | * but once you have obtained it, you should persist it in a database or session to pass 67 | * to the Kite Connect class initialisation for subsequent requests. 68 | * @param {string} [params.root="https://api.kite.trade"] API end point root. Unless you explicitly 69 | * want to send API requests to a non-default endpoint, this can be ignored. 70 | * @param {string} [params.login_uri="https://kite.zerodha.com/connect/login"] Kite connect login url 71 | * @param {bool} [params.debug=false] If set to true, will console log requests and responses. 72 | * @param {number} [params.timeout=7000] Time (milliseconds) for which the API client will wait 73 | * for a request to complete before it fails. 74 | * 75 | * @example Initialize KiteConnect object 76 | * const kc = KiteConnect("my_api_key", {timeout: 10, debug: false}) 77 | */ 78 | const KiteConnect = function(params) { 79 | const self = this; 80 | const defaults = { 81 | "root": "https://api.kite.trade", 82 | "login": "https://kite.zerodha.com/connect/login", 83 | "debug": false, 84 | "timeout": 7000 85 | }; 86 | 87 | self.api_key = params.api_key; 88 | self.root = params.root || defaults.root; 89 | self.timeout = params.timeout || defaults.timeout; 90 | self.debug = params.debug || defaults.debug; 91 | self.access_token = params.access_token || null; 92 | self.default_login_uri = defaults.login; 93 | self.session_expiry_hook = null; 94 | 95 | const kiteVersion = 3; // Kite version to send in header 96 | const userAgent = utils.getUserAgent(); // User agent to be sent with every request 97 | 98 | const routes = { 99 | "api.token": "/session/token", 100 | "api.token.invalidate": "/session/token", 101 | "api.token.renew": "/session/refresh_token", 102 | "user.profile": "/user/profile", 103 | "user.margins": "/user/margins", 104 | "user.margins.segment": "/user/margins/{segment}", 105 | 106 | "orders": "/orders", 107 | "trades": "/trades", 108 | "order.info": "/orders/{order_id}", 109 | "order.place": "/orders/{variety}", 110 | "order.modify": "/orders/{variety}/{order_id}", 111 | "order.cancel": "/orders/{variety}/{order_id}", 112 | "order.trades": "/orders/{order_id}/trades", 113 | "order.margins": "/margins/orders", 114 | "order.margins.basket": "/margins/basket", 115 | 116 | "portfolio.positions": "/portfolio/positions", 117 | "portfolio.holdings": "/portfolio/holdings", 118 | "portfolio.holdings.auction": "/portfolio/holdings/auctions", 119 | "portfolio.positions.convert": "/portfolio/positions", 120 | 121 | "mf.orders": "/mf/orders", 122 | "mf.order.info": "/mf/orders/{order_id}", 123 | "mf.order.place": "/mf/orders", 124 | "mf.order.cancel": "/mf/orders/{order_id}", 125 | 126 | "mf.sips": "/mf/sips", 127 | "mf.sip.info": "/mf/sips/{sip_id}", 128 | "mf.sip.place": "/mf/sips", 129 | "mf.sip.modify": "/mf/sips/{sip_id}", 130 | "mf.sip.cancel": "/mf/sips/{sip_id}", 131 | 132 | "mf.holdings": "/mf/holdings", 133 | "mf.instruments": "/mf/instruments", 134 | 135 | "market.instruments.all": "/instruments", 136 | "market.instruments": "/instruments/{exchange}", 137 | "market.historical": "/instruments/historical/{instrument_token}/{interval}", 138 | "market.trigger_range": "/instruments/trigger_range/{transaction_type}", 139 | 140 | "market.quote": "/quote", 141 | "market.quote.ohlc": "/quote/ohlc", 142 | "market.quote.ltp": "/quote/ltp", 143 | 144 | "gtt.triggers": "/gtt/triggers", 145 | "gtt.trigger_info": "/gtt/triggers/{trigger_id}", 146 | "gtt.place": "/gtt/triggers", 147 | "gtt.modify": "/gtt/triggers/{trigger_id}", 148 | "gtt.delete": "/gtt/triggers/{trigger_id}" 149 | }; 150 | 151 | const requestInstance = axios.create({ 152 | baseURL: self.root, 153 | timeout: self.timeout, 154 | headers: { 155 | "X-Kite-Version": kiteVersion, 156 | "User-Agent": userAgent 157 | }, 158 | paramsSerializer: function(params) { 159 | return querystring.stringify(params); 160 | } 161 | }); 162 | 163 | // Add a request interceptor 164 | requestInstance.interceptors.request.use(function(request) { 165 | if (self.debug) console.log(request); 166 | return request; 167 | }); 168 | 169 | // Add a response interceptor 170 | requestInstance.interceptors.response.use(function(response) { 171 | if (self.debug) console.log(response); 172 | 173 | const contentType = response.headers["content-type"]; 174 | if (contentType === "application/json" && typeof response.data === "object") { 175 | // Throw incase of error 176 | if (response.data.error_type) throw response.data; 177 | 178 | // Return success data 179 | return response.data.data; 180 | } else if (contentType === "text/csv") { 181 | // Return the response directly 182 | return response.data 183 | } else { 184 | return { 185 | "error_type": "DataException", 186 | "message": "Unknown content type (" + contentType + ") with response: (" + response.data + ")" 187 | }; 188 | } 189 | }, function (error) { 190 | let resp = { 191 | "message": "Unknown error", 192 | "error_type": "GeneralException", 193 | "data": null 194 | }; 195 | 196 | if (error.response) { 197 | // The request was made and the server responded with a status code 198 | // that falls out of the range of 2xx 199 | if (error.response.data && error.response.data.error_type) { 200 | if (error.response.data.error_type === "TokenException" && self.session_expiry_hook) { 201 | self.session_expiry_hook() 202 | } 203 | 204 | resp = error.response.data; 205 | } else { 206 | resp.error_type = "NetworkException"; 207 | resp.message = error.response.statusText; 208 | } 209 | } else if (error.request) { 210 | // The request was made but no response was received 211 | // `error.request` is an instance of XMLHttpRequest in the browser and an instance of 212 | // http.ClientRequest in node.js 213 | resp.error_type = "NetworkException"; 214 | resp.message = "No response from server with error code: " + error.code; 215 | } else if (error.message) { 216 | resp = error 217 | } 218 | 219 | return Promise.reject(resp); 220 | }); 221 | 222 | // Constants 223 | // Products 224 | /** 225 | * @memberOf KiteConnect 226 | */ 227 | self.PRODUCT_MIS = "MIS"; 228 | /** 229 | * @memberOf KiteConnect 230 | */ 231 | self.PRODUCT_CNC = "CNC"; 232 | /** 233 | * @memberOf KiteConnect 234 | */ 235 | self.PRODUCT_NRML = "NRML"; 236 | /** 237 | * @memberOf KiteConnect 238 | */ 239 | self.PRODUCT_CO = "CO"; 240 | /** 241 | * @memberOf KiteConnect 242 | */ 243 | self.PRODUCT_BO = "BO"; 244 | 245 | // Order types 246 | /** 247 | * @memberOf KiteConnect 248 | */ 249 | self.ORDER_TYPE_MARKET = "MARKET"; 250 | /** 251 | * @memberOf KiteConnect 252 | */ 253 | self.ORDER_TYPE_LIMIT = "LIMIT"; 254 | /** 255 | * @memberOf KiteConnect 256 | */ 257 | self.ORDER_TYPE_SLM = "SL-M"; 258 | /** 259 | * @memberOf KiteConnect 260 | */ 261 | self.ORDER_TYPE_SL = "SL"; 262 | 263 | // varities 264 | /** 265 | * @memberOf KiteConnect 266 | */ 267 | self.VARIETY_REGULAR = "regular"; 268 | /** 269 | * @memberOf KiteConnect 270 | */ 271 | self.VARIETY_BO = "bo"; 272 | /** 273 | * @memberOf KiteConnect 274 | */ 275 | self.VARIETY_CO = "co"; 276 | /** 277 | * @memberOf KiteConnect 278 | */ 279 | self.VARIETY_AMO = "amo"; 280 | /** 281 | * @memberOf KiteConnect 282 | */ 283 | self.VARIETY_ICEBERG = "iceberg"; 284 | 285 | /** 286 | * @memberOf KiteConnect 287 | */ 288 | self.VARIETY_AUCTION = "auction"; 289 | 290 | // Transaction type 291 | /** 292 | * @memberOf KiteConnect 293 | */ 294 | self.TRANSACTION_TYPE_BUY = "BUY"; 295 | /** 296 | * @memberOf KiteConnect 297 | */ 298 | self.TRANSACTION_TYPE_SELL = "SELL"; 299 | 300 | // Validity 301 | /** 302 | * @memberOf KiteConnect 303 | */ 304 | self.VALIDITY_DAY = "DAY"; 305 | /** 306 | * @memberOf KiteConnect 307 | */ 308 | self.VALIDITY_IOC = "IOC"; 309 | /** 310 | * @memberOf KiteConnect 311 | */ 312 | self.VALIDITY_TTL = "TTL"; 313 | 314 | // Exchanges 315 | /** 316 | * @memberOf KiteConnect 317 | */ 318 | self.EXCHANGE_NSE = "NSE"; 319 | /** 320 | * @memberOf KiteConnect 321 | */ 322 | self.EXCHANGE_BSE = "BSE"; 323 | /** 324 | * @memberOf KiteConnect 325 | */ 326 | self.EXCHANGE_NFO = "NFO"; 327 | /** 328 | * @memberOf KiteConnect 329 | */ 330 | self.EXCHANGE_CDS = "CDS"; 331 | /** 332 | * @memberof KiteConnect 333 | */ 334 | self.EXCHANGE_BCD = "BCD"; 335 | /** 336 | * @memberof KiteConnect 337 | */ 338 | self.EXCHANGE_BFO = "BFO"; 339 | /** 340 | * @memberOf KiteConnect 341 | */ 342 | self.EXCHANGE_MCX = "MCX"; 343 | 344 | // Margins segments 345 | /** 346 | * @memberOf KiteConnect 347 | */ 348 | self.MARGIN_EQUITY = "equity"; 349 | /** 350 | * @memberOf KiteConnect 351 | */ 352 | self.MARGIN_COMMODITY = "commodity"; 353 | 354 | /** 355 | * @memberOf KiteConnect 356 | */ 357 | self.STATUS_CANCELLED = "CANCELLED"; 358 | /** 359 | * @memberOf KiteConnect 360 | */ 361 | self.STATUS_REJECTED = "REJECTED"; 362 | /** 363 | * @memberOf KiteConnect 364 | */ 365 | self.STATUS_COMPLETE = "COMPLETE"; 366 | /** 367 | * @memberOf KiteConnect 368 | */ 369 | self.GTT_TYPE_OCO = "two-leg"; 370 | /** 371 | * @memberOf KiteConnect 372 | */ 373 | self.GTT_TYPE_SINGLE = "single"; 374 | /** 375 | * @memberOf KiteConnect 376 | */ 377 | self.GTT_STATUS_ACTIVE = "active"; 378 | /** 379 | * @memberOf KiteConnect 380 | */ 381 | self.GTT_STATUS_TRIGGERED = "triggered"; 382 | /** 383 | * @memberOf KiteConnect 384 | */ 385 | self.GTT_STATUS_DISABLED = "disabled"; 386 | /** 387 | * @memberOf KiteConnect 388 | */ 389 | self.GTT_STATUS_EXPIRED = "expired"; 390 | /** 391 | * @memberOf KiteConnect 392 | */ 393 | self.GTT_STATUS_CANCELLED = "cancelled"; 394 | /** 395 | * @memberOf KiteConnect 396 | */ 397 | self.GTT_STATUS_REJECTED = "rejected"; 398 | /** 399 | * @memberOf KiteConnect 400 | */ 401 | self.GTT_STATUS_DELETED = "deleted"; 402 | 403 | /** 404 | * @memberOf KiteConnect 405 | */ 406 | self.POSITION_TYPE_DAY = "day"; 407 | 408 | /** 409 | * @memberOf KiteConnect 410 | */ 411 | self.POSITION_TYPE_OVERNIGHT = "overnight"; 412 | 413 | /** 414 | * Set `access_token` received after a successful authentication. 415 | * @method setAccessToken 416 | * @memberOf KiteConnect 417 | * @instance 418 | * @param {string} access_token Token obtained in exchange for `request_token`. 419 | * Once you have obtained `access_token`, you should persist it in a database or session to pass 420 | * to the Kite Connect class initialisation for subsequent requests. 421 | */ 422 | self.setAccessToken = function(access_token) { 423 | self.access_token = access_token; 424 | }; 425 | 426 | /** 427 | * Set a callback hook for session (`TokenException` -- timeout, expiry etc.) errors. 428 | * `access_token` (login session) can become invalid for a number of 429 | * reasons, but it doesn't make sense for the client to try and catch it during every API call. 430 | * 431 | * A callback method that handles session errors can be set here and when the client encounters 432 | * a token error at any point, it'll be called. 433 | * 434 | * This callback, for instance, can log the user out of the UI, 435 | * clear session cookies, or initiate a fresh login. 436 | * @method setSessionExpiryHook 437 | * @memberOf KiteConnect 438 | * @instance 439 | * @param {function} cb Callback 440 | */ 441 | self.setSessionExpiryHook = function(cb) { 442 | self.session_expiry_hook = cb; 443 | }; 444 | 445 | /** 446 | * Get the remote login url to which a user should be redirected to initiate the login flow. 447 | * @method getLoginURL 448 | * @memberOf KiteConnect 449 | * @instance 450 | */ 451 | self.getLoginURL = function() { 452 | return self.default_login_uri + "?api_key=" + self.api_key + "&v=" + kiteVersion; 453 | }; 454 | 455 | /** 456 | * Do the token exchange with the `request_token` obtained after the login flow, 457 | * and retrieve the `access_token` required for all subsequent requests. The 458 | * response contains not just the `access_token`, but metadata for 459 | * the user who has authenticated. 460 | * @method generateSession 461 | * @memberOf KiteConnect 462 | * @instance 463 | * 464 | * @param {string} request_token Token obtained from the GET parameters after a successful login redirect. 465 | * @param {string} api_secret API secret issued with the API key. 466 | */ 467 | self.generateSession = function(request_token, api_secret) { 468 | return new Promise(function (resolve, reject) { 469 | const checksum = sha256(self.api_key + request_token + api_secret).toString(); 470 | const p = _post("api.token", { 471 | api_key: self.api_key, 472 | request_token: request_token, 473 | checksum: checksum 474 | }, null, formatGenerateSession); 475 | 476 | p.then(function(resp: any) { 477 | // Set access token. 478 | if (resp && resp.access_token) { 479 | self.setAccessToken(resp.access_token); 480 | } 481 | return resolve(resp); 482 | }).catch(function(err) { 483 | return reject(err); 484 | }); 485 | }); 486 | }; 487 | 488 | /** 489 | * Kill the session by invalidating the access token. 490 | * If access_token is passed then it will be set as current access token and get in validated. 491 | * @method invalidateAccessToken 492 | * @memberOf KiteConnect 493 | * @instance 494 | * @param {string} [access_token] Token to invalidate. Default is the active `access_token`. 495 | */ 496 | self.invalidateAccessToken = function(access_token) { 497 | access_token = access_token || this.access_token; 498 | 499 | return _delete("api.token.invalidate", { 500 | api_key: self.api_key, 501 | access_token: access_token 502 | }); 503 | }; 504 | 505 | /** 506 | * Renew access token by active refresh token. 507 | * Renewed access token is implicitly set. 508 | * @method renewAccessToken 509 | * @memberOf KiteConnect 510 | * @instance 511 | * 512 | * @param {string} refresh_token Token obtained from previous successful login. 513 | * @param {string} api_secret API secret issued with the API key. 514 | */ 515 | self.renewAccessToken = function(refresh_token, api_secret) { 516 | return new Promise(function (resolve, reject) { 517 | const checksum = sha256(self.api_key + refresh_token + api_secret).toString(); 518 | 519 | const p = _post("api.token.renew", { 520 | api_key: self.api_key, 521 | refresh_token: refresh_token, 522 | checksum: checksum 523 | }); 524 | 525 | p.then(function(resp: any) { 526 | if (resp && resp.access_token) { 527 | self.setAccessToken(resp.access_token); 528 | } 529 | return resolve(resp); 530 | }).catch(function(err) { 531 | return reject(err); 532 | }); 533 | }); 534 | }; 535 | 536 | /** 537 | * Invalidate the refresh token. 538 | * @method invalidateRefreshToken 539 | * @memberOf KiteConnect 540 | * @instance 541 | * @param {string} refresh_token Token to invalidate. 542 | */ 543 | self.invalidateRefreshToken = function(refresh_token) { 544 | return _delete("api.token.invalidate", { 545 | api_key: this.api_key, 546 | refresh_token: refresh_token 547 | }); 548 | }; 549 | 550 | /** 551 | * Get user profile details. 552 | * @method getProfile 553 | * @memberOf KiteConnect 554 | * @instance 555 | */ 556 | self.getProfile = function() { 557 | return _get("user.profile"); 558 | } 559 | 560 | /** 561 | * Get account balance and cash margin details for a particular segment. 562 | * @method getMargins 563 | * @memberOf KiteConnect 564 | * @instance 565 | * @param {string} [segment] trading segment (eg: equity or commodity). 566 | */ 567 | self.getMargins = function(segment) { 568 | if (segment) { 569 | return _get("user.margins.segment", {"segment": segment}); 570 | } else { 571 | return _get("user.margins"); 572 | } 573 | }; 574 | 575 | /** 576 | * Place an order. 577 | * @method placeOrder 578 | * @memberOf KiteConnect 579 | * @instance 580 | * @param {string} variety Order variety (ex. bo, co, amo, regular). 581 | * @param {string} params Order params. 582 | * @param {string} params.exchange Exchange in which instrument is listed (NSE, BSE, NFO, BFO, CDS, MCX). 583 | * @param {string} params.tradingsymbol Tradingsymbol of the instrument (ex. RELIANCE, INFY). 584 | * @param {string} params.transaction_type Transaction type (BUY or SELL). 585 | * @param {number} params.quantity Order quantity 586 | * @param {string} params.product Product code (NRML, MIS, CNC). 587 | * @param {string} params.order_type Order type (LIMIT, SL, SL-M, MARKET). 588 | * @param {string} [params.validity] Order validity (DAY, IOC). 589 | * @param {number} [params.price] Order Price 590 | * @param {number} [params.disclosed_quantity] Disclosed quantity 591 | * @param {number} [params.trigger_price] Trigger price 592 | * @param {number} [params.squareoff] Square off value (only for bracket orders) 593 | * @param {number} [params.stoploss] Stoploss value (only for bracket orders) 594 | * @param {number} [params.trailing_stoploss] Trailing stoploss value (only for bracket orders) 595 | * @param {number} [params.validity_ttl] Order validity in minutes for TTL validity orders 596 | * @param {number} [params.iceberg_legs] Total number of legs for iceberg order variety 597 | * @param {number} [params.iceberg_quantity] Split quantity for each iceberg leg order 598 | * @param {number} [params.auction_number] A unique identifier for a particular auction 599 | * @param {string} [params.tag] An optional tag to apply to an order to identify it (alphanumeric, max 20 chars) 600 | */ 601 | self.placeOrder = function (variety, params) { 602 | params.variety = variety; 603 | return _post("order.place", params); 604 | }; 605 | 606 | /** 607 | * Modify an order 608 | * @method modifyOrder 609 | * @memberOf KiteConnect 610 | * @instance 611 | * @param {string} variety Order variety (ex. bo, co, amo, regular). 612 | * @param {string} order_id ID of the order. 613 | * @param {Object} params Order modify params. 614 | * @param {number} [params.quantity] Order quantity 615 | * @param {number} [params.price] Order Price 616 | * @param {string} [params.order_type] Order type (NRML, SL, SL-M, MARKET). 617 | * @param {string} [params.validity] Order validity (DAY, IOC). 618 | * @param {number} [params.disclosed_quantity] Disclosed quantity 619 | * @param {number} [params.trigger_price] Trigger price 620 | * @param {string} [params.parent_order_id] Parent order id incase of multilegged orders. 621 | */ 622 | self.modifyOrder = function(variety, order_id, params) { 623 | params.variety = variety; 624 | params.order_id = order_id; 625 | return _put("order.modify", params); 626 | }; 627 | 628 | /** 629 | * Cancel an order 630 | * @method cancelOrder 631 | * @memberOf KiteConnect 632 | * @instance 633 | * @param {string} variety Order variety (ex. bo, co, amo) 634 | * @param {string} order_id ID of the order. 635 | * @param {Object} [params] Order params. 636 | regular). 637 | * @param {string} [params.parent_order_id] Parent order id incase of multilegged orders. 638 | */ 639 | self.cancelOrder = function (variety, order_id, params) { 640 | params = params || {}; 641 | params.variety = variety; 642 | params.order_id = order_id; 643 | return _delete("order.cancel", params); 644 | }; 645 | 646 | /** 647 | * Exit an order 648 | * @method exitOrder 649 | * @memberOf KiteConnect 650 | * @instance 651 | * @param {string} variety Order variety (ex. bo, co, amo) 652 | * @param {string} order_id ID of the order. 653 | * @param {Object} [params] Order params. 654 | * @param {string} [params.parent_order_id] Parent order id incase of multilegged orders. 655 | */ 656 | self.exitOrder = function (variety, order_id, params) { 657 | return self.cancelOrder(variety, order_id, params); 658 | }; 659 | 660 | /** 661 | * Get list of orders. 662 | * @method getOrders 663 | * @memberOf KiteConnect 664 | * @instance 665 | */ 666 | self.getOrders = function() { 667 | return _get("orders", null, null, formatResponse); 668 | }; 669 | 670 | /** 671 | * Get list of order history. 672 | * @method getOrderHistory 673 | * @memberOf KiteConnect 674 | * @instance 675 | * @param {string} order_id ID of the order whose order details to be retrieved. 676 | */ 677 | self.getOrderHistory = function(order_id) { 678 | return _get("order.info", {"order_id": order_id}, null, formatResponse); 679 | }; 680 | 681 | /** 682 | * Retrieve the list of trades executed. 683 | * @method getTrades 684 | * @memberOf KiteConnect 685 | * @instance 686 | */ 687 | self.getTrades = function() { 688 | return _get("trades", null, null, formatResponse); 689 | }; 690 | 691 | /** 692 | * Retrieve the list of trades a particular order). 693 | * An order can be executed in tranches based on market conditions. 694 | * These trades are individually recorded under an order. 695 | * @method getOrderTrades 696 | * @memberOf KiteConnect 697 | * @instance 698 | * @param {string} order_id ID of the order whose trades are to be retrieved. 699 | */ 700 | self.getOrderTrades = function(order_id) { 701 | return _get("order.trades", {"order_id": order_id}, null, formatResponse); 702 | }; 703 | 704 | /** 705 | * Fetch required margin for order/list of orders 706 | * @method orderMargins 707 | * @memberOf KiteConnect 708 | * @instance 709 | * @param {Object[]} orders Margin fetch orders. 710 | * @param {string} orders[].exchange Name of the exchange(eg. NSE, BSE, NFO, CDS, MCX) 711 | * @param {string} orders[].tradingsymbol Trading symbol of the instrument 712 | * @param {string} orders[].transaction_type eg. BUY, SELL 713 | * @param {string} orders[].variety Order variety (regular, amo, bo, co etc.) 714 | * @param {string} orders[].product Margin product to use for the order 715 | * @param {string} orders[].order_type Order type (MARKET, LIMIT etc.) 716 | * @param {number} orders[].quantity Quantity of the order 717 | * @param {number} orders[].price Price at which the order is going to be placed (LIMIT orders) 718 | * @param {number} orders[].trigger_price Trigger price (for SL, SL-M, CO orders) 719 | * @param {string} mode (optional) Compact mode will only give the total margins 720 | */ 721 | self.orderMargins = function(orders, mode=null) { 722 | return _post("order.margins", orders, null, null, true, 723 | {"mode":mode}); 724 | } 725 | 726 | /** 727 | * Fetch basket margin for list of orders 728 | * @method orderBasketMargins 729 | * @memberOf KiteConnect 730 | * @instance 731 | * @param {Object[]} orders Margin fetch orders. 732 | * @param {string} orders[].exchange Name of the exchange(eg. NSE, BSE, NFO, CDS, MCX) 733 | * @param {string} orders[].tradingsymbol Trading symbol of the instrument 734 | * @param {string} orders[].transaction_type eg. BUY, SELL 735 | * @param {string} orders[].variety Order variety (regular, amo, bo, co etc.) 736 | * @param {string} orders[].product Margin product to use for the order 737 | * @param {string} orders[].order_type Order type (MARKET, LIMIT etc.) 738 | * @param {number} orders[].quantity Quantity of the order 739 | * @param {number} orders[].price Price at which the order is going to be placed (LIMIT orders) 740 | * @param {number} orders[].trigger_price Trigger price (for SL, SL-M, CO orders) 741 | * @param {string} consider_positions Boolean to consider users positions while calculating margins 742 | * @param {string} mode (optional) Compact mode will only give the total margins 743 | */ 744 | self.orderBasketMargins = function(orders, consider_positions=true, mode=null) { 745 | return _post("order.margins.basket", orders, null, null, true, 746 | {"consider_positions":consider_positions, "mode":mode}); 747 | } 748 | 749 | /** 750 | * Retrieve the list of equity holdings. 751 | * @method getHoldings 752 | * @memberOf KiteConnect 753 | * @instance 754 | */ 755 | self.getHoldings = function() { 756 | return _get("portfolio.holdings"); 757 | }; 758 | 759 | /** 760 | * Retrieves list of available instruments for a auction session. 761 | * @method getAuctionInstruments 762 | * @memberOf KiteConnect 763 | * @instance 764 | */ 765 | self.getAuctionInstruments = function() { 766 | return _get("portfolio.holdings.auction"); 767 | } 768 | 769 | /** 770 | * Retrieve positions. 771 | * @method getPositions 772 | * @memberOf KiteConnect 773 | * @instance 774 | */ 775 | self.getPositions = function() { 776 | return _get("portfolio.positions"); 777 | }; 778 | 779 | /** 780 | * Modify an open position's product type. 781 | * @method convertPosition 782 | * @memberOf KiteConnect 783 | * @instance 784 | * @param {Object} params params. 785 | * @param {string} params.exchange Exchange in which instrument is listed (NSE, BSE, NFO, BFO, CDS, MCX). 786 | * @param {string} params.tradingsymbol Tradingsymbol of the instrument (ex. RELIANCE, INFY). 787 | * @param {string} params.transaction_type Transaction type (BUY or SELL). 788 | * @param {string} params.position_type Position type (overnight, day). 789 | * @param {string} params.quantity Position quantity 790 | * @param {string} params.old_product Current product code (NRML, MIS, CNC). 791 | * @param {string} params.new_product New Product code (NRML, MIS, CNC). 792 | */ 793 | self.convertPosition = function(params) { 794 | return _put("portfolio.positions.convert", params); 795 | }; 796 | 797 | /** 798 | * Retrieve the list of market instruments available to trade. 799 | * Note that the results could be large, several hundred KBs in size, 800 | * with tens of thousands of entries in the list. 801 | * Response is array for objects. For example 802 | * ~~~~ 803 | * { 804 | * instrument_token: '131098372', 805 | * exchange_token: '512103', 806 | * tradingsymbol: 'NIDHGRN', 807 | * name: 'NIDHI GRANITES', 808 | * last_price: '0.0', 809 | * expiry: '', 810 | * strike: '0.0', 811 | * tick_size: '0.05', 812 | * lot_size: '1', 813 | * instrument_type: 'EQ', 814 | * segment: 'BSE', 815 | * exchange: 'BSE' }, ...] 816 | * ~~~~ 817 | * 818 | * @method getInstruments 819 | * @memberOf KiteConnect 820 | * @instance 821 | * @param {Array} [segment] Filter instruments based on exchange (NSE, BSE, NFO, BFO, CDS, MCX). 822 | * If no `segment` is specified, all instruments are returned. 823 | */ 824 | self.getInstruments = function(exchange) { 825 | if(exchange) { 826 | return _get("market.instruments", { 827 | "exchange": exchange 828 | }, null, transformInstrumentsResponse); 829 | } else { 830 | return _get("market.instruments.all", null, null, transformInstrumentsResponse); 831 | } 832 | }; 833 | 834 | /** 835 | * Retrieve quote and market depth for list of instruments. 836 | * @method getQuote 837 | * @memberOf KiteConnect 838 | * @instance 839 | * @param {Array} instruments is a list of instruments, Instrument are in the format of `exchange:tradingsymbol`. 840 | * For example NSE:INFY and for list of instruments ["NSE:RELIANCE", "NSE:SBIN", ..] 841 | */ 842 | self.getQuote = function(instruments) { 843 | return _get("market.quote", {"i": instruments}, null, formatQuoteResponse); 844 | }; 845 | 846 | /** 847 | * Retrieve OHLC for list of instruments. 848 | * @method getOHLC 849 | * @memberOf KiteConnect 850 | * @instance 851 | * @param {Array} instruments is a list of instruments, Instrument are in the format of `exchange:tradingsymbol`. 852 | * For example NSE:INFY and for list of instruments ["NSE:RELIANCE", "NSE:SBIN", ..] 853 | */ 854 | self.getOHLC = function(instruments) { 855 | return _get("market.quote.ohlc", {"i": instruments}); 856 | }; 857 | 858 | /** 859 | * Retrieve LTP for list of instruments. 860 | * @method getLTP 861 | * @memberOf KiteConnect 862 | * @instance 863 | * @param {Array} instruments is a list of instruments, Instrument are in the format of `exchange:tradingsymbol`. 864 | * For example NSE:INFY and for list of instruments ["NSE:RELIANCE", "NSE:SBIN", ..] 865 | */ 866 | self.getLTP = function(instruments) { 867 | return _get("market.quote.ltp", {"i": instruments}); 868 | }; 869 | 870 | 871 | /** 872 | * Retrieve historical data (candles) for an instrument. 873 | * Although the actual response JSON from the API does not have field 874 | * names such has 'open', 'high' etc., this functin call structures 875 | * the data into an array of objects with field names. For example: 876 | * 877 | * ~~~~ 878 | * [{ 879 | * date: '2015-02-10T00:00:00+0530', 880 | * open: 277.5, 881 | * high: 290.8, 882 | * low: 275.7, 883 | * close: 287.3, 884 | * volume: 22589681 885 | * }, ....] 886 | * ~~~~ 887 | * 888 | * @method getHistoricalData 889 | * @memberOf KiteConnect 890 | * @instance 891 | * @param {string} instrument_token Instrument identifier (retrieved from the instruments()) call. 892 | * @param {string} interval candle interval (minute, day, 5 minute etc.) 893 | * @param {string|Date} from_date From date (String in format of 'yyyy-mm-dd HH:MM:SS' or Date object). 894 | * @param {string|Date} to_date To date (String in format of 'yyyy-mm-dd HH:MM:SS' or Date object). 895 | * @param {bool} [continuous=false] is a bool flag to get continuous data for futures and options instruments. Defaults to false. 896 | * @param {bool} [oi=false] is a bool flag to include OI data for futures and options instruments. Defaults to false. 897 | */ 898 | self.getHistoricalData = function(instrument_token, interval, from_date, to_date, continuous, oi) { 899 | continuous = continuous ? 1 : 0; 900 | oi = oi ? 1 : 0; 901 | if (typeof to_date === "object") to_date = _getDateTimeString(to_date) 902 | if (typeof from_date === "object") from_date = _getDateTimeString(from_date) 903 | 904 | return _get("market.historical", { 905 | instrument_token: instrument_token, 906 | interval: interval, 907 | from: from_date, 908 | to: to_date, 909 | continuous: continuous, 910 | oi: oi 911 | }, null, parseHistorical); 912 | }; 913 | 914 | // Convert Date object to string of format yyyy-mm-dd HH:MM:SS 915 | function _getDateTimeString(date) { 916 | const isoString = date.toISOString(); 917 | return isoString.replace("T", " ").split(".")[0]; 918 | } 919 | 920 | /** 921 | * Retrieve the buy/sell trigger range for Cover Orders. 922 | * @method getTriggerRange 923 | * @memberOf KiteConnect 924 | * @instance 925 | * @param {string} exchange Exchange in which instrument is listed (NSE, BSE, NFO, BFO, CDS, MCX). 926 | * @param {string} tradingsymbol Tranding symbol of the instrument (ex. RELIANCE, INFY). 927 | * @param {string} transaction_type Transaction type (BUY or SELL). 928 | */ 929 | self.getTriggerRange = function(transaction_type, instruments) { 930 | return _get("market.trigger_range", 931 | { 932 | "i": instruments, 933 | "transaction_type": transaction_type.toLowerCase() 934 | } 935 | ); 936 | }; 937 | 938 | /** 939 | * Get list of mutual fund orders. 940 | * @method getMFOrders 941 | * @memberOf KiteConnect 942 | * @instance 943 | * @param {string} [order_id] ID of the order (optional) whose order details are to be retrieved. 944 | * If no `order_id` is specified, all orders for the day are returned. 945 | */ 946 | self.getMFOrders = function (order_id) { 947 | if (order_id) { 948 | return _get("mf.order.info", { "order_id": order_id }, null, formatResponse); 949 | } else { 950 | return _get("mf.orders", null, null, formatResponse); 951 | } 952 | }; 953 | 954 | 955 | /** 956 | * Place a mutual fund order. 957 | * @method placeMFOrder 958 | * @memberOf KiteConnect 959 | * @instance 960 | * @param {string} params Order params. 961 | * @param {string} params.tradingsymbol Tradingsymbol (ISIN) of the fund. 962 | * @param {string} params.transaction_type Transaction type (BUY or SELL). 963 | * @param {string} [params.quantity] Quantity to SELL. Not applicable on BUYs. 964 | * @param {string} [params.amount] Amount worth of units to purchase. Not applicable on SELLs 965 | * @param {string} [params.tag] An optional tag to apply to an order to identify it (alphanumeric, max 20 chars) 966 | */ 967 | self.placeMFOrder = function (params) { 968 | return _post("mf.order.place", params); 969 | } 970 | 971 | /** 972 | * Cancel a mutual fund order. 973 | * @method cancelMFOrder 974 | * @memberOf KiteConnect 975 | * @instance 976 | * @param {string} order_id ID of the order. 977 | */ 978 | self.cancelMFOrder = function (order_id) { 979 | return _delete("mf.order.cancel", { "order_id": order_id }) 980 | } 981 | 982 | /** 983 | * Get list of mutual fund SIPS. 984 | * @method getMFSIPS 985 | * @memberOf KiteConnect 986 | * @instance 987 | * @param {string} sip_id ID of the SIP. 988 | */ 989 | self.getMFSIPS = function (sip_id) { 990 | if (sip_id) { 991 | return _get("mf.sip.info", {"sip_id": sip_id}, null, formatResponse); 992 | } else { 993 | return _get("mf.sips", null, null, formatResponse); 994 | } 995 | } 996 | 997 | /** 998 | * Place a mutual fund SIP. 999 | * @method placeMFSIP 1000 | * @memberOf KiteConnect 1001 | * @instance 1002 | * @param {string} params Order params. 1003 | * @param {string} params.tradingsymbol Tradingsymbol (ISIN) of the fund. 1004 | * @param {string} params.amount Amount worth of units to purchase. 1005 | * @param {string} params.instalments Number of instalments to trigger. If set to -1, instalments are triggered at fixed intervals until the SIP is cancelled 1006 | * @param {string} params.frequency Order frequency. weekly, monthly, or quarterly. 1007 | * @param {string} [params.initial_amount] Amount worth of units to purchase before the SIP starts. 1008 | * @param {string} [params.instalment_day] If frequency is monthly, the day of the month (1, 5, 10, 15, 20, 25) to trigger the order on. 1009 | * @param {string} [params.tag] An optional tag to apply to an order to identify it (alphanumeric, max 20 chars) 1010 | */ 1011 | self.placeMFSIP = function (params) { 1012 | return _post("mf.sip.place", params); 1013 | } 1014 | 1015 | /** 1016 | * Modify a mutual fund SIP. 1017 | * @method modifyMFSIP 1018 | * @memberOf KiteConnect 1019 | * @instance 1020 | * @param {string} sip_id ID of the SIP. 1021 | * @param {string} params Order params. 1022 | * @param {string} [params.instalments] Number of instalments to trigger. If set to -1, instalments are triggered at fixed intervals until the SIP is cancelled 1023 | * @param {string} [params.frequency] Order frequency. weekly, monthly, or quarterly. 1024 | * @param {string} [params.instalment_day] If frequency is monthly, the day of the month (1, 5, 10, 15, 20, 25) to trigger the order on. 1025 | * @param {string} [params.status] Pause or unpause an SIP (active or paused). 1026 | */ 1027 | self.modifyMFSIP = function (sip_id, params) { 1028 | params.sip_id = sip_id; 1029 | return _put("mf.sip.modify", params); 1030 | } 1031 | 1032 | /** 1033 | * Cancel a mutual fund SIP. 1034 | * @method cancelMFSIP 1035 | * @memberOf KiteConnect 1036 | * @instance 1037 | * @param {string} sip_id ID of the SIP. 1038 | */ 1039 | self.cancelMFSIP = function (sip_id) { 1040 | return _delete("mf.sip.cancel", {"sip_id": sip_id}); 1041 | } 1042 | 1043 | /** 1044 | * Get list of mutual fund holdings. 1045 | * @method getMFHoldings 1046 | * @memberOf KiteConnect 1047 | * @instance 1048 | */ 1049 | self.getMFHoldings = function () { 1050 | return _get("mf.holdings"); 1051 | } 1052 | 1053 | /** 1054 | * Get list of mutual fund instruments. 1055 | * @method getMFInstruments 1056 | * @memberOf KiteConnect 1057 | * @instance 1058 | */ 1059 | self.getMFInstruments = function () { 1060 | return _get("mf.instruments", null, null, transformMFInstrumentsResponse); 1061 | } 1062 | 1063 | /** 1064 | * Get GTTs list 1065 | * @method getGTTs 1066 | * @memberOf KiteConnect 1067 | * @instance 1068 | */ 1069 | self.getGTTs = function () { 1070 | return _get("gtt.triggers", null, null, formatResponse); 1071 | } 1072 | 1073 | /** 1074 | * Get list of order history. 1075 | * @method getGTT 1076 | * @memberOf KiteConnect 1077 | * @instance 1078 | * @param {string} trigger_id GTT trigger ID 1079 | */ 1080 | self.getGTT = function (trigger_id) { 1081 | return _get("gtt.trigger_info", { "trigger_id": trigger_id }, null, formatResponse); 1082 | }; 1083 | 1084 | // Get API params from user defined GTT params. 1085 | self._getGTTPayload = function (params) { 1086 | if (params.trigger_type !== self.GTT_TYPE_OCO && params.trigger_type !== self.GTT_TYPE_SINGLE) { 1087 | throw new Error("Invalid `params.trigger_type`") 1088 | } 1089 | if (params.trigger_type === self.GTT_TYPE_OCO && params.trigger_values.length !== 2) { 1090 | throw new Error("Invalid `trigger_values` for `OCO` order type") 1091 | } 1092 | if (params.trigger_type === self.GTT_TYPE_SINGLE && params.trigger_values.length !== 1) { 1093 | throw new Error("Invalid `trigger_values` for `single` order type") 1094 | } 1095 | let condition = { 1096 | exchange: params.exchange, 1097 | tradingsymbol: params.tradingsymbol, 1098 | trigger_values: params.trigger_values, 1099 | last_price: parseFloat(params.last_price) 1100 | } 1101 | let orders = [] as any[]; 1102 | for (let o of params.orders) { 1103 | orders.push({ 1104 | transaction_type: o.transaction_type, 1105 | order_type: o.order_type, 1106 | product: o.product, 1107 | quantity: parseInt(o.quantity), 1108 | price: parseFloat(o.price), 1109 | exchange: params.exchange, 1110 | tradingsymbol: params.tradingsymbol 1111 | }) 1112 | } 1113 | return { condition, orders } 1114 | }; 1115 | 1116 | /** 1117 | * Place GTT. 1118 | * @method placeGTT 1119 | * @memberOf KiteConnect 1120 | * @instance 1121 | * @param {string} params.trigger_type GTT type, its either `self.GTT_TYPE_OCO` or `self.GTT_TYPE_SINGLE`. 1122 | * @param {string} params.tradingsymbol Tradingsymbol of the instrument (ex. RELIANCE, INFY). 1123 | * @param {string} params.exchange Exchange in which instrument is listed (NSE, BSE, NFO, BFO, CDS, MCX). 1124 | * @param {number[]} params.trigger_values List of trigger values, number of items depends on trigger type. 1125 | * @param {number} params.last_price Price at which trigger is created. This is usually the last price of the instrument. 1126 | * @param {Object[]} params.orders List of orders. 1127 | * @param {string} params.orders.transaction_type Transaction type (BUY or SELL). 1128 | * @param {number} params.orders.quantity Order quantity 1129 | * @param {string} params.orders.product Product code (NRML, MIS, CNC). 1130 | * @param {string} params.orders.order_type Order type (NRML, SL, SL-M, MARKET). 1131 | * @param {number} params.orders.price Order price. 1132 | */ 1133 | self.placeGTT = function (params) { 1134 | let payload = self._getGTTPayload(params) 1135 | return _post("gtt.place", { 1136 | condition: JSON.stringify(payload.condition), 1137 | orders: JSON.stringify(payload.orders), 1138 | type: params.trigger_type 1139 | }); 1140 | }; 1141 | 1142 | /** 1143 | * Place GTT. 1144 | * @method modifyGTT 1145 | * @memberOf KiteConnect 1146 | * @instance 1147 | * @param {string} trigger_id GTT trigger ID. 1148 | * @param {Object} params Modify params 1149 | * @param {string} params.trigger_type GTT type, its either `self.GTT_TYPE_OCO` or `self.GTT_TYPE_SINGLE`. 1150 | * @param {string} params.tradingsymbol Tradingsymbol of the instrument (ex. RELIANCE, INFY). 1151 | * @param {string} params.exchange Exchange in which instrument is listed (NSE, BSE, NFO, BFO, CDS, MCX). 1152 | * @param {number[]} params.trigger_values List of trigger values, number of items depends on trigger type. 1153 | * @param {number} params.last_price Price at which trigger is created. This is usually the last price of the instrument. 1154 | * @param {Object[]} params.orders List of orders. 1155 | * @param {string} params.orders.transaction_type Transaction type (BUY or SELL). 1156 | * @param {number} params.orders.quantity Order quantity 1157 | * @param {string} params.orders.product Product code (NRML, MIS, CNC). 1158 | * @param {string} params.orders.order_type Order type (NRML, SL, SL-M, MARKET). 1159 | * @param {number} params.orders.price Order price. 1160 | */ 1161 | self.modifyGTT = function (trigger_id, params) { 1162 | let payload = self._getGTTPayload(params) 1163 | return _put("gtt.modify", { 1164 | trigger_id: trigger_id, 1165 | type: params.trigger_type, 1166 | condition: JSON.stringify(payload.condition), 1167 | orders: JSON.stringify(payload.orders) 1168 | }); 1169 | }; 1170 | 1171 | /** 1172 | * Get list of order history. 1173 | * @method deleteGTT 1174 | * @memberOf KiteConnect 1175 | * @instance 1176 | * @param {string} trigger_id GTT ID 1177 | */ 1178 | self.deleteGTT = function (trigger_id) { 1179 | return _delete("gtt.delete", { "trigger_id": trigger_id }, null, null); 1180 | }; 1181 | 1182 | /** 1183 | * Validate postback data checksum 1184 | * @method validatePostback 1185 | * @memberOf KiteConnect 1186 | * @instance 1187 | * @param {object} postback_data Postback data received. Must be an json object with required keys order_id, checksum and order_timestamp 1188 | * @param {string} api_secret Api secret of the app 1189 | * @returns {bool} Return true if checksum matches else false 1190 | * @throws Throws an error if the @postback_data or @api_secret is invalid 1191 | */ 1192 | self.validatePostback = function(postback_data, api_secret) { 1193 | if (!postback_data || !postback_data.checksum || !postback_data.order_id || 1194 | !postback_data.order_timestamp || !api_secret) { 1195 | throw new Error("Invalid postback data or api_secret"); 1196 | } 1197 | 1198 | const inputString = postback_data.order_id + postback_data.order_timestamp + api_secret; 1199 | let checksum; 1200 | try { 1201 | checksum = sha256(inputString).toString(); 1202 | } catch (e) { 1203 | throw(e) 1204 | } 1205 | 1206 | if (postback_data.checksum === checksum) { 1207 | return true; 1208 | } else { 1209 | return false; 1210 | } 1211 | } 1212 | 1213 | // Format generate session response 1214 | function formatGenerateSession(data) { 1215 | if (!data.data || typeof data.data !== "object") return data; 1216 | 1217 | if (data.data.login_time) { 1218 | data.data.login_time = new Date(data.data.login_time); 1219 | } 1220 | 1221 | return data; 1222 | } 1223 | 1224 | function formatQuoteResponse(data) { 1225 | if (!data.data || typeof data.data !== "object") return data; 1226 | 1227 | for (const k in data.data) { 1228 | const item = data.data[k]; 1229 | for (const field of ["timestamp", "last_trade_time"]) { 1230 | if (item[field] && item[field].length === 19) { 1231 | item[field] = new Date(item[field]); 1232 | } 1233 | } 1234 | } 1235 | 1236 | return data; 1237 | } 1238 | 1239 | // Format response ex. datetime string to date 1240 | function formatResponse(data) { 1241 | if (!data.data || typeof data.data !== "object") return data; 1242 | let list: any = []; 1243 | if (data.data instanceof Array) { 1244 | list = data.data; 1245 | } else { 1246 | list = [data.data] 1247 | } 1248 | 1249 | const results: any[] = []; 1250 | const fields = ["order_timestamp", "exchange_timestamp", "created", "last_instalment", "fill_timestamp"]; 1251 | 1252 | for (const item of list) { 1253 | for (const field of fields) { 1254 | if (item[field] && item[field].length === 19) { 1255 | item[field] = new Date(item[field]); 1256 | } 1257 | } 1258 | 1259 | results.push(item); 1260 | } 1261 | 1262 | if (data.data instanceof Array) { 1263 | data.data = results; 1264 | } else { 1265 | data.data = results[0]; 1266 | } 1267 | 1268 | return data; 1269 | } 1270 | 1271 | function parseHistorical(jsonData) { 1272 | // Return if its an error 1273 | if (jsonData.error_type) return jsonData; 1274 | 1275 | const results = [] as any[]; 1276 | for(let i=0; i= read_timeout) { 291 | // reset current_ws_url incase current connection times out 292 | // This is determined when last heart beat received time interval 293 | // exceeds read_timeout value 294 | current_ws_url = null; 295 | if (ws) ws.close(); 296 | clearInterval(read_timer); 297 | triggerDisconnect(); 298 | } 299 | }, read_timeout * 1000); 300 | }; 301 | 302 | ws.onmessage = function (e) { 303 | // Binary tick data. 304 | if (e.data instanceof ArrayBuffer) { 305 | // Trigger on message event when binary message is received 306 | trigger("message", [e.data]); 307 | if (e.data.byteLength > 2) { 308 | const d = parseBinary(e.data); 309 | if (d) trigger("ticks", [d]); 310 | } 311 | } else { 312 | parseTextMessage(e.data) 313 | } 314 | 315 | // Set last read time to check for connection timeout 316 | last_read = new Date(); 317 | }; 318 | 319 | ws.onerror = function (e) { 320 | trigger("error", [e]); 321 | 322 | // Force close to avoid ghost connections 323 | if (this && this.readyState == this.OPEN) this.close(); 324 | }; 325 | 326 | ws.onclose = function (e) { 327 | trigger("close", [e]); 328 | 329 | // the ws id doesn't match the current global id, 330 | // meaning it's a ghost close event. just ignore. 331 | if (current_ws_url && (this.url != current_ws_url)) return; 332 | 333 | triggerDisconnect(e); 334 | }; 335 | }; 336 | 337 | /** 338 | * @memberOf KiteTicker 339 | * @method disconnect 340 | * @instance 341 | */ 342 | this.disconnect = function () { 343 | if (ws && ws.readyState != ws.CLOSING && ws.readyState != ws.CLOSED) { 344 | ws.close(); 345 | } 346 | } 347 | 348 | /** 349 | * Check if the ticker is connected 350 | * @memberOf KiteTicker 351 | * @method connected 352 | * @instance 353 | * @returns {bool} 354 | */ 355 | this.connected = function () { 356 | if (ws && ws.readyState == ws.OPEN) { 357 | return true; 358 | } else { 359 | return false; 360 | } 361 | }; 362 | 363 | /** 364 | * Register websocket event callbacks 365 | * Available events 366 | * ~~~~ 367 | * connect - when connection is successfully established. 368 | * ticks - when ticks are available (Arrays of `ticks` object as the first argument). 369 | * disconnect - when socket connection is disconnected. Error is received as a first param. 370 | * error - when socket connection is closed with error. Error is received as a first param. 371 | * close - when socket connection is closed cleanly. 372 | * reconnect - When reconnecting (current re-connection count and reconnect interval as arguments respectively). 373 | * noreconnect - When re-connection fails after n number times. 374 | * order_update - When order update (postback) is received for the connected user (Data object is received as first argument). 375 | * message - when binary message is received from the server. 376 | * ~~~~ 377 | * 378 | * @memberOf KiteTicker 379 | * @method on 380 | * @instance 381 | * 382 | * @example 383 | * ticker.on("ticks", callback); 384 | * ticker.on("connect", callback); 385 | * ticker.on("disconnect", callback); 386 | */ 387 | this.on = function (e, callback) { 388 | if (triggers.hasOwnProperty(e)) { 389 | triggers[e].push(callback); 390 | } 391 | }; 392 | 393 | /** 394 | * Subscribe to array of tokens 395 | * @memberOf KiteTicker 396 | * @method subscribe 397 | * @instance 398 | * @param {array} tokens Array of tokens to be subscribed 399 | * 400 | * @example 401 | * ticker.subscribe([738561]); 402 | */ 403 | this.subscribe = function (tokens) { 404 | if (tokens.length > 0) { 405 | send({ "a": mSubscribe, "v": tokens }); 406 | } 407 | return tokens; 408 | }; 409 | 410 | /** 411 | * Unsubscribe to array of tokens 412 | * @memberOf KiteTicker 413 | * @method unsubscribe 414 | * @instance 415 | * @param {array} tokens Array of tokens to be subscribed 416 | * 417 | * @example 418 | * ticker.unsubscribe([738561]); 419 | */ 420 | this.unsubscribe = function (tokens) { 421 | if (tokens.length > 0) { 422 | send({ "a": mUnSubscribe, "v": tokens }); 423 | } 424 | return tokens; 425 | }; 426 | 427 | /** 428 | * Set modes to array of tokens 429 | * @memberOf KiteTicker 430 | * @method setMode 431 | * @instance 432 | * @param {string} mode - mode to set 433 | * @param {array} tokens Array of tokens to be subscribed 434 | * 435 | * @example 436 | * ticker.setMode(ticker.modeFull, [738561]); 437 | */ 438 | this.setMode = function (mode, tokens) { 439 | if (tokens.length > 0) { 440 | send({ "a": mSetMode, "v": [mode, tokens] }); 441 | } 442 | return tokens; 443 | }; 444 | 445 | /** 446 | * Parse received binary message 447 | * @memberOf KiteTicker 448 | * @method parseBinary 449 | * @instance 450 | * @param {ArrayBufferTypes} binpacks - tick buffer packets 451 | */ 452 | 453 | this.parseBinary = function (binpacks) { 454 | return parseBinary(binpacks); 455 | } 456 | 457 | function autoReconnect(t, max_retry, max_delay) { 458 | auto_reconnect = (t == true); 459 | 460 | // Set default values 461 | max_retry = max_retry || defaultReconnectMaxRetries; 462 | max_delay = max_delay || defaultReconnectMaxDelay; 463 | 464 | // Set reconnect constraints 465 | reconnect_max_tries = max_retry >= maximumReconnectMaxRetries ? maximumReconnectMaxRetries : max_retry; 466 | reconnect_max_delay = max_delay <= minimumReconnectMaxDelay ? minimumReconnectMaxDelay : max_delay; 467 | } 468 | 469 | function triggerDisconnect(e?) { 470 | ws = null; 471 | trigger("disconnect", [e]); 472 | if (auto_reconnect) attemptReconnection(); 473 | } 474 | 475 | // send a message via the socket 476 | // automatically encodes json if possible 477 | function send(message) { 478 | if (!ws || ws.readyState != ws.OPEN) return; 479 | 480 | try { 481 | if (typeof (message) == "object") { 482 | message = JSON.stringify(message); 483 | } 484 | ws.send(message); 485 | } catch (e) { ws.close(); }; 486 | } 487 | 488 | // trigger event callbacks 489 | function trigger(e, args?) { 490 | if (!triggers[e]) return 491 | for (let n = 0; n < triggers[e].length; n++) { 492 | triggers[e][n].apply(triggers[e][n], args ? args : []); 493 | } 494 | } 495 | 496 | function parseTextMessage(data) { 497 | try { 498 | data = JSON.parse(data) 499 | } catch (e) { 500 | return 501 | } 502 | 503 | if (data.type === "order") { 504 | trigger("order_update", [data.data]); 505 | } 506 | } 507 | 508 | // parse received binary message. each message is a combination of multiple tick packets 509 | // [2-bytes num packets][size1][tick1][size2][tick2] ... 510 | function parseBinary(binpacks) { 511 | const packets = splitPackets(binpacks), 512 | ticks: any[] = []; 513 | 514 | for (let n = 0; n < packets.length; n++) { 515 | const bin: any = packets[n], 516 | instrument_token = buf2long(bin.slice(0, 4)), 517 | segment = instrument_token & 0xff; 518 | 519 | let tradable = true; 520 | if (segment === Indices) tradable = false; 521 | 522 | // Add price divisor based on segment 523 | let divisor = 100.0; 524 | if (segment === NseCD) { 525 | divisor = 10000000.0; 526 | 527 | } else if (segment == BseCD) { 528 | divisor = 10000.0; 529 | } 530 | 531 | // Parse LTP 532 | if (bin.byteLength === 8) { 533 | ticks.push({ 534 | tradable: tradable, 535 | mode: modeLTP, 536 | instrument_token: instrument_token, 537 | last_price: buf2long(bin.slice(4, 8)) / divisor 538 | }); 539 | // Parse indices quote and full mode 540 | } else if (bin.byteLength === 28 || bin.byteLength === 32) { 541 | let mode = modeQuote; 542 | if (bin.byteLength === 32) mode = modeFull; 543 | 544 | const tick: any = { 545 | tradable: tradable, 546 | mode: mode, 547 | instrument_token: instrument_token, 548 | last_price: buf2long(bin.slice(4, 8)) / divisor, 549 | ohlc: { 550 | high: buf2long(bin.slice(8, 12)) / divisor, 551 | low: buf2long(bin.slice(12, 16)) / divisor, 552 | open: buf2long(bin.slice(16, 20)) / divisor, 553 | close: buf2long(bin.slice(20, 24)) / divisor 554 | }, 555 | change: buf2long(bin.slice(24, 28)) 556 | }; 557 | 558 | // Compute the change price using close price and last price 559 | if (tick.ohlc.close != 0) { 560 | tick.change = (tick.last_price - tick.ohlc.close) * 100 / tick.ohlc.close; 561 | } 562 | 563 | // Full mode with timestamp in seconds 564 | if (bin.byteLength === 32) { 565 | tick.exchange_timestamp = null; 566 | const timestamp = buf2long(bin.slice(28, 32)); 567 | if (timestamp) tick.exchange_timestamp = new Date(timestamp * 1000); 568 | } 569 | 570 | ticks.push(tick); 571 | } else if (bin.byteLength === 44 || bin.byteLength === 184) { 572 | let mode = modeQuote; 573 | if (bin.byteLength === 184) mode = modeFull; 574 | 575 | const tick = { 576 | tradable: tradable, 577 | mode: mode, 578 | instrument_token: instrument_token, 579 | last_price: buf2long(bin.slice(4, 8)) / divisor, 580 | last_traded_quantity: buf2long(bin.slice(8, 12)), 581 | average_traded_price: buf2long(bin.slice(12, 16)) / divisor, 582 | volume_traded: buf2long(bin.slice(16, 20)), 583 | total_buy_quantity: buf2long(bin.slice(20, 24)), 584 | total_sell_quantity: buf2long(bin.slice(24, 28)), 585 | ohlc: { 586 | open: buf2long(bin.slice(28, 32)) / divisor, 587 | high: buf2long(bin.slice(32, 36)) / divisor, 588 | low: buf2long(bin.slice(36, 40)) / divisor, 589 | close: buf2long(bin.slice(40, 44)) / divisor 590 | } 591 | } as any; 592 | 593 | // Compute the change price using close price and last price 594 | if (tick.ohlc.close != 0) { 595 | tick.change = (tick.last_price - tick.ohlc.close) * 100 / tick.ohlc.close; 596 | } 597 | 598 | // Parse full mode 599 | if (bin.byteLength === 184) { 600 | // Parse last trade time 601 | tick.last_trade_time = null; 602 | const last_trade_time = buf2long(bin.slice(44, 48)); 603 | if (last_trade_time) tick.last_trade_time = new Date(last_trade_time * 1000); 604 | 605 | // Parse timestamp 606 | tick.exchange_timestamp = null; 607 | const timestamp = buf2long(bin.slice(60, 64)); 608 | if (timestamp) tick.exchange_timestamp = new Date(timestamp * 1000); 609 | 610 | // Parse OI 611 | tick.oi = buf2long(bin.slice(48, 52)); 612 | tick.oi_day_high = buf2long(bin.slice(52, 56)); 613 | tick.oi_day_low = buf2long(bin.slice(56, 60)); 614 | tick.depth = { 615 | buy: [], 616 | sell: [] 617 | }; 618 | 619 | let s = 0, depth = bin.slice(64, 184); 620 | for (let i = 0; i < 10; i++) { 621 | s = i * 12; 622 | tick.depth[i < 5 ? "buy" : "sell"].push({ 623 | quantity: buf2long(depth.slice(s, s + 4)), 624 | price: buf2long(depth.slice(s + 4, s + 8)) / divisor, 625 | orders: buf2long(depth.slice(s + 8, s + 10)) 626 | }); 627 | } 628 | } 629 | 630 | ticks.push(tick); 631 | } 632 | } 633 | 634 | return ticks; 635 | } 636 | 637 | // split one long binary message into individual tick packets 638 | function splitPackets(bin) { 639 | // number of packets 640 | let num = buf2long(bin.slice(0, 2)), 641 | j = 2, 642 | packets: any[] = []; 643 | 644 | for (let i = 0; i < num; i++) { 645 | // first two bytes is the packet length 646 | const size = buf2long(bin.slice(j, j + 2)), 647 | packet = bin.slice(j + 2, j + 2 + size); 648 | 649 | packets.push(packet); 650 | 651 | j += 2 + size; 652 | } 653 | 654 | return packets; 655 | } 656 | 657 | function attemptReconnection() { 658 | // Try reconnecting only so many times. 659 | if (current_reconnection_count > reconnect_max_tries) { 660 | trigger("noreconnect"); 661 | process.exit(1); 662 | } 663 | 664 | if (current_reconnection_count > 0) { 665 | last_reconnect_interval = Math.pow(2, current_reconnection_count); 666 | } else if (!last_reconnect_interval) { 667 | last_reconnect_interval = 1; 668 | } 669 | 670 | if (last_reconnect_interval > reconnect_max_delay) { 671 | last_reconnect_interval = reconnect_max_delay; 672 | } 673 | 674 | current_reconnection_count++; 675 | 676 | trigger("reconnect", [current_reconnection_count, last_reconnect_interval]); 677 | 678 | setTimeout(function () { 679 | self.connect(); 680 | }, last_reconnect_interval * 1000); 681 | } 682 | 683 | // Big endian byte array to long. 684 | function buf2long(buf) { 685 | let b = new Uint8Array(buf), 686 | val = 0, 687 | len = b.length; 688 | 689 | for (let i = 0, j = len - 1; i < len; i++, j--) { 690 | val += b[j] << (i * 8); 691 | } 692 | 693 | return val; 694 | } 695 | const self = this; 696 | }; 697 | 698 | export default KiteTicker; 699 | -------------------------------------------------------------------------------- /lib/utils.ts: -------------------------------------------------------------------------------- 1 | import packageInfo from '../package.json'; 2 | 3 | function getPackageInfo() { 4 | return packageInfo; 5 | } 6 | 7 | function getUserAgent() { 8 | return "kiteconnectjs/" + packageInfo.version; 9 | } 10 | 11 | export default { 12 | getPackageInfo, 13 | getUserAgent 14 | }; 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kiteconnect", 3 | "version": "4.1.0", 4 | "description": "The official JS client library for the Kite Connect trading APIs", 5 | "main": "./dist/", 6 | "types": "./types/index.d.ts", 7 | "scripts": { 8 | "generate-docs": "node_modules/.bin/jsdoc --configure .jsdoc.json --verbose", 9 | "build": "tsc", 10 | "test": "tsc && mocha" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/zerodhatech/kiteconnectjs.git" 15 | }, 16 | "keywords": [ 17 | "kiteconnect", 18 | "kite", 19 | "zerodha", 20 | "rainmatter", 21 | "trading", 22 | "api", 23 | "stock", 24 | "market" 25 | ], 26 | "author": "Vivek R", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/zerodhatech/kiteconnectjs/issues" 30 | }, 31 | "homepage": "https://github.com/zerodhatech/kiteconnectjs#readme", 32 | "dependencies": { 33 | "axios": "^0.21.2", 34 | "chai": "^4.3.6", 35 | "crypto-js": "^4.0.0", 36 | "mocha": "^10.0.0", 37 | "nock": "^13.2.4", 38 | "papaparse": "^5.3.1", 39 | "ws": "^6.2.2" 40 | }, 41 | "devDependencies": { 42 | "@types/crypto-js": "^4.1.1", 43 | "@types/node": "^18.11.18", 44 | "@types/papaparse": "^5.3.5", 45 | "eslint": "^8.30.0", 46 | "jsdoc": "^3.4.0", 47 | "minami": "^1.1.1", 48 | "typescript": "^4.9.4" 49 | }, 50 | "engines": { 51 | "node": ">=8.0.0" 52 | }, 53 | "engineStrict": true 54 | } 55 | -------------------------------------------------------------------------------- /test/fullMode_binary.packet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedster0629/React/7d55f732d31b156660eae3fa4ee856ad3eaed5e0/test/fullMode_binary.packet -------------------------------------------------------------------------------- /test/ltpMode_binary.packet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedster0629/React/7d55f732d31b156660eae3fa4ee856ad3eaed5e0/test/ltpMode_binary.packet -------------------------------------------------------------------------------- /test/quoteMode_binary.packet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tedster0629/React/7d55f732d31b156660eae3fa4ee856ad3eaed5e0/test/quoteMode_binary.packet -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const nock = require("nock"); 4 | const expect = require("chai").expect; 5 | const path = require("path"); 6 | const fs = require("fs"); 7 | const KiteConnect = require("../dist/connect.js").default; 8 | 9 | const mockDir = "./kiteconnect-mocks"; 10 | 11 | // run testsuite 12 | testSuite(); 13 | 14 | function parseJson(fileName){ 15 | // read and parse mock json file 16 | var rawdata = fs.readFileSync(path.join(__dirname, mockDir, fileName)); 17 | var mockData= JSON.parse(rawdata); 18 | return mockData; 19 | } 20 | 21 | function testSuite(){ 22 | 23 | var kc = new KiteConnect({"api_key":"your api_key"}); 24 | 25 | // Chaining the mock requests 26 | nock(kc.root) 27 | // getProfile 28 | .get("/user/profile") 29 | .reply(200, parseJson("profile.json")) 30 | 31 | // getMargins 32 | .get("/user/margins") 33 | .reply(200, parseJson("margins.json")) 34 | 35 | // getMargins(segment) 36 | .get("/user/margins/test") 37 | .query({ segment: "test" }) 38 | .reply(200, parseJson("margins_equity.json")) 39 | 40 | // placeOrder 41 | .post("/orders/test") 42 | .reply(200, parseJson("order_response.json")) 43 | 44 | // modifyOrder 45 | .put("/orders/test/100") 46 | .reply(200, parseJson("order_modify.json")) 47 | 48 | // cancelOrder 49 | .delete("/orders/test/100") 50 | .query({ variety: "test", order_id: 100 }) 51 | .reply(200, parseJson("order_cancel.json")) 52 | 53 | // getOrders 54 | .get("/orders") 55 | .reply(200, parseJson("orders.json")) 56 | 57 | // getOrderHistory 58 | .get("/orders/100") 59 | .query({ order_id: "100" }) 60 | .reply(200, parseJson("order_info.json")) 61 | 62 | // getTrades 63 | .get("/trades") 64 | .reply(200, parseJson("trades.json")) 65 | 66 | // getOrderTrades 67 | .get("/orders/100/trades") 68 | .query({ order_id: 100 }) 69 | .reply(200, parseJson("order_trades.json")) 70 | 71 | // getHoldings 72 | .get("/portfolio/holdings") 73 | .reply(200, parseJson("holdings.json")) 74 | 75 | // getHoldings 76 | .get("/portfolio/holdings/auctions") 77 | .reply(200, parseJson("auctions_list.json")) 78 | 79 | // getPositions 80 | .get("/portfolio/positions") 81 | .reply(200, parseJson("positions.json")) 82 | 83 | // convertPosition 84 | .put("/portfolio/positions") 85 | .reply(200, parseJson("convert_position.json")) 86 | 87 | // placeMFOrder 88 | .post("/mf/orders") 89 | .reply(200, parseJson("mf_order_response.json")) 90 | 91 | // cancelMFOrder 92 | .delete("/mf/orders/100") 93 | .query({ order_id: 100 }) 94 | .reply(200, parseJson("mf_order_cancel.json")) 95 | 96 | // getMFOrders 97 | .get("/mf/orders") 98 | .reply(200, parseJson("mf_orders.json")) 99 | 100 | // getMFOrders(order_id) 101 | .get("/mf/orders/100") 102 | .query({ order_id: 100 }) 103 | .reply(200, parseJson("mf_orders_info.json")) 104 | 105 | // placeMFSIP 106 | .post("/mf/sips") 107 | .reply(200, parseJson("mf_sip_place.json")) 108 | 109 | // modifyMFSIP 110 | .put("/mf/sips/100") 111 | .reply(200, parseJson("mf_sip_modify.json")) 112 | 113 | // cancelMFSIP 114 | .delete("/mf/sips/100") 115 | .query({ sip_id: 100 }) 116 | .reply(200, parseJson("mf_sip_cancel.json")) 117 | 118 | // getMFSIPS 119 | .get("/mf/sips") 120 | .reply(200, parseJson("mf_sips.json")) 121 | 122 | // getMFSIPS(sip_id) 123 | .get("/mf/sips/100") 124 | .query({ sip_id: 100 }) 125 | .reply(200, parseJson("mf_sip_info.json")) 126 | 127 | // getMFHoldings 128 | .get("/mf/holdings") 129 | .reply(200, parseJson("mf_holdings.json")) 130 | 131 | // getHistoricalData 132 | .get("/instruments/historical/100/minute") 133 | .query({ instrument_token: "100" , interval: "minute", 134 | from: "2022-06-01 09:15:00", to: "2022-06-01 15:30:00", 135 | continuous: 0, oi:0}) 136 | .reply(200, parseJson("historical_minute.json")) 137 | 138 | // getQuote 139 | .get("/quote") 140 | .query({ i:"NSE:INFY"}) 141 | .reply(200, parseJson("quote.json")) 142 | 143 | // getLTP 144 | .get("/quote/ltp") 145 | .query({ i: "NSE:INFY" }) 146 | .reply(200, parseJson("ltp.json")) 147 | 148 | // getOHLC 149 | .get("/quote/ohlc") 150 | .query({ i:"NSE:INFY"}) 151 | .reply(200, parseJson("quote.json")) 152 | 153 | // placeGTT 154 | .post("/gtt/triggers") 155 | .reply(200, parseJson("gtt_place_order.json")) 156 | 157 | // modifyGTT 158 | .put("/gtt/triggers/100") 159 | .reply(200, parseJson("gtt_modify_order.json")) 160 | 161 | // deleteGTT 162 | .delete("/gtt/triggers/100") 163 | .query({ trigger_id: 100 }) 164 | .reply(200, parseJson("gtt_delete_order.json")) 165 | 166 | // getGTTs 167 | .get("/gtt/triggers") 168 | .reply(200, parseJson("gtt_get_orders.json")) 169 | 170 | // getGTT(trigger_id) 171 | .get("/gtt/triggers/100") 172 | .query({ trigger_id:100}) 173 | .reply(200, parseJson("gtt_get_order.json")) 174 | 175 | // orderMargins 176 | .post("/margins/orders") 177 | .query({ mode: null }) 178 | .reply(200, parseJson("order_margins.json")) 179 | 180 | 181 | // fetch user profile detail 182 | describe("getProfile", function() { 183 | it("fetch user profile detail", (done) => { 184 | kc.getProfile() 185 | .then(function(response) { 186 | expect(response).to.have.property("user_id"); 187 | expect(response).to.have.property("user_name"); 188 | return done(); 189 | }).catch(done); 190 | }) 191 | }); 192 | 193 | // fetch user fund detail 194 | describe("getMargins", function() { 195 | it("fetch equity and commodity segment funds", (done) => { 196 | kc.getMargins() 197 | .then(function(response) { 198 | expect(response).to.have.property("equity"); 199 | expect(response).to.have.property("commodity"); 200 | return done(); 201 | }).catch(done); 202 | }) 203 | it("fetch equity specific segment funds", (done) => { 204 | kc.getMargins("test") 205 | .then(function(response) { 206 | expect(response).to.have.property("enabled"); 207 | return done(); 208 | }).catch(done); 209 | }) 210 | }); 211 | 212 | // Order APIs 213 | // Place market and limit order 214 | describe("placeOrder", function() { 215 | it("Place market order", (done) => { 216 | kc.placeOrder("test", { 217 | "exchange": "NSE", 218 | "tradingsymbol": "SBIN", 219 | "transaction_type": "BUY", 220 | "quantity": 1, 221 | "product": "MIS", 222 | "order_type": "MARKET"}) 223 | .then(function(response) { 224 | expect(response).to.have.property("order_id"); 225 | return done(); 226 | }).catch(done); 227 | }) 228 | }); 229 | 230 | // modify open pending order 231 | describe("modifyOrder", function() { 232 | it("Modify an open order", (done) => { 233 | kc.modifyOrder("test", 100,{ 234 | "price":10}) 235 | .then(function(response) { 236 | expect(response).to.have.property("order_id"); 237 | return done(); 238 | }).catch(done); 239 | }) 240 | }); 241 | 242 | // cancel an open pending order 243 | describe("cancelOrder", function() { 244 | it("cancel an open pending order", (done) => { 245 | kc.cancelOrder("test", 100) 246 | .then(function(response) { 247 | expect(response).to.have.property("order_id"); 248 | return done(); 249 | }).catch(done); 250 | }) 251 | }); 252 | 253 | // Retrieve complete orderbook 254 | describe("getOrders", function() { 255 | it("Retrieve the list of all orders under orderbook", (done) => { 256 | kc.getOrders() 257 | .then(function(response) { 258 | expect(response).to.be.an("array"); 259 | expect(response).to.have.nested.property("[0].order_id"); 260 | expect(response).to.have.nested.property("[0].status"); 261 | expect(response).to.have.nested.property("[0].tradingsymbol"); 262 | return done(); 263 | }).catch(done); 264 | }) 265 | }); 266 | 267 | // Retrieve the history of a given order 268 | describe("getOrderHistory", function() { 269 | it("Retrieve the history of a given order", (done) => { 270 | kc.getOrderHistory(100) 271 | .then(function(response) { 272 | expect(response).to.have.nested.property("[0].order_id"); 273 | expect(response).to.have.nested.property("[0].status"); 274 | return done(); 275 | }).catch(done); 276 | }) 277 | }); 278 | 279 | // Retrieve the list of all executed trades 280 | describe("getTrades", function() { 281 | it("Retrieve the list of all executed trades for the day", (done) => { 282 | kc.getTrades() 283 | .then(function(response) { 284 | expect(response).to.be.an("array"); 285 | expect(response).to.have.nested.property("[0].order_id"); 286 | expect(response).to.have.nested.property("[0].exchange_timestamp"); 287 | return done(); 288 | }).catch(done); 289 | }) 290 | }); 291 | 292 | // Retrieve all the trades generated by an order 293 | describe("getOrderTrades", function() { 294 | it("Retrieve all the trades generated by an order", (done) => { 295 | kc.getOrderTrades(100) 296 | .then(function(response) { 297 | expect(response).to.be.an("array"); 298 | return done(); 299 | }).catch(done); 300 | }) 301 | }); 302 | 303 | // Portfolio APIs 304 | // Retrieve the list of equity holdings 305 | describe("getHoldings", function() { 306 | it("Retrieve the list of equity holdings", (done) => { 307 | kc.getHoldings() 308 | .then(function(response) { 309 | expect(response).to.be.an("array"); 310 | expect(response).to.have.nested.property("[0].tradingsymbol"); 311 | expect(response).to.have.nested.property("[0].average_price"); 312 | return done(); 313 | }).catch(done); 314 | }) 315 | }); 316 | 317 | // Retrieves list of available instruments for a auction session 318 | describe("getAuctionInstruments", function() { 319 | it("Retrieves list of available instruments for a auction session", (done) => { 320 | kc.getAuctionInstruments() 321 | .then(function(response) { 322 | expect(response).to.be.an("array"); 323 | expect(response).to.have.nested.property("[0].auction_number"); 324 | expect(response).to.have.nested.property("[0].instrument_token"); 325 | expect(response).to.have.nested.property("[0].tradingsymbol"); 326 | return done(); 327 | }).catch(done); 328 | }) 329 | }); 330 | 331 | // Retrieve the list of positions 332 | describe("getPositions", function() { 333 | it("Retrieve the list of positions", (done) => { 334 | kc.getPositions() 335 | .then(function(response) { 336 | expect(response).to.have.property("net"); 337 | expect(response).to.have.property("day"); 338 | return done(); 339 | }).catch(done); 340 | }) 341 | }); 342 | 343 | // convert existing position 344 | describe("convertPosition", function() { 345 | it("convert existing position", (done) => { 346 | kc.convertPosition ({ 347 | "tradingsymbol": "SBIN", 348 | "exchange":"NSE", 349 | "transaction_type":"BUY", 350 | "position_type":"day", 351 | "quantity":1, 352 | "old_product":"CNC", 353 | "new_product":"MIS" 354 | }) 355 | .then(function(response) { 356 | expect(response).to.equal(true); 357 | return done(); 358 | }).catch(done); 359 | }) 360 | }); 361 | 362 | // MF APIs 363 | // Place MF Order 364 | describe("placeMFOrder", function() { 365 | it("Place MF order", (done) => { 366 | kc.placeMFOrder({ 367 | "tradingsymbol": "INF174K01LS2", 368 | "transaction_type": "BUY", 369 | "amount" : 1000}) 370 | .then(function(response) { 371 | expect(response).to.have.property("order_id"); 372 | return done(); 373 | }).catch(done); 374 | }) 375 | }); 376 | 377 | // cancel an open pending MF order 378 | describe("cancelMFOrder", function() { 379 | it("cancel an open pending MF order", (done) => { 380 | kc.cancelMFOrder(100) 381 | .then(function(response) { 382 | expect(response).to.have.property("order_id"); 383 | return done(); 384 | }).catch(done); 385 | }) 386 | }); 387 | 388 | // Retrieve the list of all MF orders (open and executed) over the last 7 days 389 | describe("getMFOrders", function() { 390 | it("Retrieve the list of all MF orders from orderbook", (done) => { 391 | kc.getMFOrders() 392 | .then(function(response) { 393 | expect(response).to.be.an("array") 394 | return done(); 395 | }).catch(done); 396 | }) 397 | }); 398 | 399 | // Retrieve the detail of a given MF order 400 | describe("getMFOrders", function() { 401 | it("Retrieve the detail of a given MF order", (done) => { 402 | kc.getMFOrders(100) 403 | .then(function(response) { 404 | expect(response).to.have.property("order_timestamp"); 405 | expect(response).to.have.property("status"); 406 | return done(); 407 | }).catch(done); 408 | }) 409 | }); 410 | 411 | // Place MF SIP Order 412 | describe("placeMFSIP", function() { 413 | it("Place MF SIP Order", (done) => { 414 | kc.placeMFSIP({ 415 | "tradingsymbol": "INF174K01LS2", 416 | "frequency" : "monthly", 417 | "instalment_day": 1, 418 | "instalments" : -1, 419 | "initial_amount" : 5000, 420 | "amount" : 1000 421 | }) 422 | .then(function(response) { 423 | expect(response).to.have.property("sip_id"); 424 | return done(); 425 | }).catch(done); 426 | }) 427 | }); 428 | 429 | // modify open pending MF SIP order 430 | describe("modifyMFSIP", function() { 431 | it("modify open pending NF SIP order", (done) => { 432 | kc.modifyMFSIP(100,{ 433 | "instalments":12}) 434 | .then(function(response) { 435 | expect(response).to.have.property("sip_id"); 436 | return done(); 437 | }).catch(done); 438 | }) 439 | }); 440 | 441 | // cancel an open pending MF SIP order 442 | describe("cancelMFSIP", function() { 443 | it("cancel an open pending MF SIP order", (done) => { 444 | kc.cancelMFSIP(100) 445 | .then(function(response) { 446 | expect(response).to.have.property("sip_id"); 447 | return done(); 448 | }).catch(done); 449 | }) 450 | }); 451 | 452 | // Retrieve complete SIP orderbook 453 | describe("getMFSIPS", function() { 454 | it("Retrieve complete SIP orderbook", (done) => { 455 | kc.getMFSIPS() 456 | .then(function(response) { 457 | expect(response).to.be.an("array"); 458 | expect(response).to.have.nested.property("[0].status"); 459 | expect(response).to.have.nested.property("[0].created"); 460 | return done(); 461 | }).catch(done); 462 | }) 463 | }); 464 | 465 | // Retrieve the detail of a given SIP order 466 | describe("getMFSIPS", function() { 467 | it("Retrieve the detail of a given SIP order", (done) => { 468 | kc.getMFSIPS(100) 469 | .then(function(response) { 470 | expect(response).to.have.property("status"); 471 | expect(response).to.have.property("created"); 472 | return done(); 473 | }).catch(done); 474 | }) 475 | }); 476 | 477 | // Retrieve complete MF holdings 478 | describe("getMFHoldings", function() { 479 | it("Retrieve complete MF holdings", (done) => { 480 | kc.getMFHoldings() 481 | .then(function(response) { 482 | expect(response).to.be.an("array"); 483 | expect(response).to.have.nested.property("[0].folio"); 484 | expect(response).to.have.nested.property("[0].fund"); 485 | return done(); 486 | }).catch(done); 487 | }) 488 | }); 489 | 490 | // Historical candle APIs 491 | describe("getHistoricalData", function() { 492 | // for intraday candle 493 | it("Fetch historical data for minute(intraday) candle", (done) => { 494 | kc.getHistoricalData(100, "minute", 495 | "2022-06-01 09:15:00", "2022-06-01 15:30:00") 496 | .then(function(response) { 497 | expect(response).to.have.nested.property("[0].date"); 498 | expect(response).to.have.nested.property("[0].open"); 499 | expect(response).to.have.nested.property("[0].close"); 500 | expect(response).to.have.nested.property("[0].volume"); 501 | return done(); 502 | }).catch(done); 503 | }) 504 | }); 505 | 506 | // Market quotes and instruments 507 | // Retrieve full market quotes for instruments 508 | describe("getQuote", function() { 509 | it("Retrieve full market quotes for instruments", (done) => { 510 | kc.getQuote("NSE:INFY") 511 | .then(function(response) { 512 | expect(response).to.have.property("NSE:INFY"); 513 | expect(response).to.have.nested.property("NSE:INFY.last_price"); 514 | expect(response).to.have.nested.property("NSE:INFY.depth"); 515 | expect(response).to.have.nested.property("NSE:INFY.ohlc"); 516 | return done(); 517 | }).catch(done); 518 | }) 519 | }); 520 | 521 | // Retrieve LTP quotes for instruments 522 | describe("getLTP", function() { 523 | it("Retrieve LTP quotes for instruments", (done) => { 524 | kc.getLTP("NSE:INFY") 525 | .then(function(response) { 526 | expect(response).to.have.property("NSE:INFY"); 527 | expect(response).to.have.nested.property("NSE:INFY.instrument_token"); 528 | expect(response).to.have.nested.property("NSE:INFY.last_price"); 529 | return done(); 530 | }).catch(done); 531 | }) 532 | }); 533 | 534 | // Retrieve OHLC quotes for instruments 535 | describe("getOHLC", function() { 536 | it("Retrieve OHLC quotes for instruments", (done) => { 537 | kc.getOHLC("NSE:INFY") 538 | .then(function(response) { 539 | expect(response).to.have.property("NSE:INFY"); 540 | expect(response).to.have.nested.property("NSE:INFY.last_price"); 541 | expect(response).to.have.nested.property("NSE:INFY.ohlc"); 542 | return done(); 543 | }).catch(done); 544 | }) 545 | }); 546 | 547 | // GTT APIs 548 | // Place a GTT 549 | describe("placeGTT", function() { 550 | it("Place an GTT OCO order", (done) => { 551 | kc.placeGTT({ 552 | trigger_type: kc.GTT_TYPE_OCO, 553 | tradingsymbol: "SBIN", 554 | exchange: "NSE", 555 | trigger_values: [350, 450], 556 | last_price: 400, 557 | orders: [{ 558 | transaction_type: kc.TRANSACTION_TYPE_SELL, 559 | quantity: 1, 560 | product: kc.PRODUCT_CNC, 561 | order_type: kc.ORDER_TYPE_LIMIT, 562 | price: 350 563 | }, { 564 | transaction_type: kc.TRANSACTION_TYPE_SELL, 565 | quantity: 1, 566 | product: kc.PRODUCT_CNC, 567 | order_type: kc.ORDER_TYPE_LIMIT, 568 | price: 450 569 | }] 570 | } 571 | ) 572 | .then(function(response) { 573 | expect(response).to.have.property("trigger_id"); 574 | return done(); 575 | }).catch(done); 576 | }) 577 | }); 578 | 579 | //Retrieve a list of all GTTs visible in GTT order book 580 | describe("getGTTs", function() { 581 | it("Fetch list of all GTTs visible in GTT order book", (done) => { 582 | kc.getGTTs() 583 | .then(function(response) { 584 | expect(response).to.have.nested.property("[0].id"); 585 | expect(response).to.have.nested.property("[0].created_at"); 586 | expect(response).to.have.nested.property("[0].user_id"); 587 | expect(response).to.have.nested.property("[0].status"); 588 | return done(); 589 | }).catch(done); 590 | }) 591 | }); 592 | 593 | // Retrieve an individual trigger 594 | describe("getGTT", function() { 595 | it("Fetch specific gtt order detail using trigger_id", (done) => { 596 | kc.getGTT(100) 597 | .then(function(response) { 598 | expect(response).to.have.property("id"); 599 | expect(response).to.have.property("type"); 600 | expect(response).to.have.property("status"); 601 | expect(response).to.have.property("condition"); 602 | return done(); 603 | }).catch(done); 604 | }) 605 | }); 606 | 607 | // Modify an active GTT 608 | describe("modifyGTT", function() { 609 | it("Modify an open GTT order using trigger_id", (done) => { 610 | kc.modifyGTT(100, { 611 | trigger_type: kc.GTT_TYPE_OCO, 612 | tradingsymbol: "SBIN", 613 | exchange: "NSE", 614 | trigger_values: [358, 458], 615 | last_price: 400, 616 | orders: [{ 617 | transaction_type: kc.TRANSACTION_TYPE_SELL, 618 | quantity: 1, 619 | product: kc.PRODUCT_CNC, 620 | order_type: kc.ORDER_TYPE_LIMIT, 621 | price: 358 622 | }, { 623 | transaction_type: kc.TRANSACTION_TYPE_SELL, 624 | quantity: 1, 625 | product: kc.PRODUCT_CNC, 626 | order_type: kc.ORDER_TYPE_LIMIT, 627 | price: 458 628 | }]}) 629 | .then(function(response) { 630 | expect(response).to.have.property("trigger_id"); 631 | return done(); 632 | }).catch(done); 633 | }) 634 | }); 635 | 636 | // Delete an active GTT 637 | describe("deleteGTT", function() { 638 | it("Delete a GTT using trigger_id", (done) => { 639 | kc.deleteGTT(100) 640 | .then(function(response) { 641 | expect(response).to.have.property("trigger_id"); 642 | return done(); 643 | }).catch(done); 644 | }) 645 | }); 646 | 647 | // Margin APIs 648 | // fetch order Margin detail 649 | describe("orderMargins", function() { 650 | it("Fetch order margin detail", (done) => { 651 | kc.orderMargins([ 652 | { 653 | "exchange": "NSE", 654 | "tradingsymbol": "SBIN", 655 | "transaction_type": "BUY", 656 | "variety": "regular", 657 | "product": "MIS", 658 | "order_type": "MARKET", 659 | "quantity": 1 660 | } 661 | ]) 662 | .then(function(response) { 663 | expect(response).to.have.nested.property("[0].type"); 664 | expect(response).to.have.nested.property("[0].var"); 665 | expect(response).to.have.nested.property("[0].span"); 666 | expect(response).to.have.nested.property("[0].exposure"); 667 | // Order charges 668 | expect(response).to.have.nested.property("[0].charges.total"); 669 | expect(response).to.have.nested.property("[0].charges.transaction_tax"); 670 | expect(response).to.have.nested.property("[0].charges.gst.total"); 671 | return done(); 672 | }).catch(done); 673 | }) 674 | }); 675 | } 676 | -------------------------------------------------------------------------------- /test/test_ticker.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const path = require("path"); 4 | const fs = require("fs"); 5 | const expect = require("chai").expect; 6 | var KiteTicker = require("../dist/ticker.js").default; 7 | 8 | 9 | // Ticker binary packets 10 | var ltpPacket = "ltpMode_binary.packet"; 11 | var quotePacket = "quoteMode_binary.packet"; 12 | var fullPacket = "fullMode_binary.packet"; 13 | 14 | function testTicker() { 15 | var ticker = new KiteTicker({ 16 | api_key: "api_key", 17 | access_token: "access_token", 18 | }); 19 | 20 | // Fetch ltp mode tick data 21 | describe("ltpModeTick", function() { 22 | it("Fetch ltp mode tick data", () => { 23 | var tickData = ticker.parseBinary(toArrayBuffer(ltpPacket)); 24 | expect(tickData).to.be.an("array"); 25 | expect(tickData[0].mode).to.equal("ltp"); 26 | expect(tickData).to.have.nested.property("[0].instrument_token"); 27 | expect(tickData).to.have.nested.property("[0].last_price"); 28 | }) 29 | }); 30 | 31 | // Fetch quote mode tick data 32 | describe("quoteModeTick", function() { 33 | it("Fetch quote mode tick data", () => { 34 | var tickData = ticker.parseBinary(toArrayBuffer(quotePacket)); 35 | expect(tickData).to.be.an("array"); 36 | expect(tickData[0].mode).to.equal("quote"); 37 | expect(tickData).to.have.nested.property("[0].instrument_token"); 38 | expect(tickData).to.have.nested.property("[0].ohlc"); 39 | expect(tickData).to.have.nested.property("[0].volume_traded"); 40 | 41 | }) 42 | }); 43 | 44 | // Fetch Full mode tick data 45 | describe("fullModeTick", function() { 46 | it("Fetch full mode tick data", () => { 47 | var tickData = ticker.parseBinary(toArrayBuffer(fullPacket)); 48 | expect(tickData).to.be.an("array"); 49 | expect(tickData[0].mode).to.equal("full"); 50 | expect(tickData).to.have.nested.property("[0].exchange_timestamp"); 51 | expect(tickData).to.have.nested.property("[0].last_trade_time"); 52 | expect(tickData).to.have.nested.property("[0].depth"); 53 | 54 | }) 55 | }); 56 | } 57 | 58 | // Read binary packets 59 | function readBufferPacket(fileName) { 60 | var rawData = fs.readFileSync(path.join(__dirname, "./", fileName)); 61 | return rawData; 62 | } 63 | 64 | // Convert buffer to binary buffer array 65 | function toArrayBuffer(tickerMode) { 66 | var buf = readBufferPacket(tickerMode); 67 | var ab = new ArrayBuffer(buf.length); 68 | var view = new Uint8Array(ab); 69 | for (let i = 0; i < buf.length; ++i) { 70 | view[i] = buf[i]; 71 | } 72 | return ab; 73 | } 74 | 75 | // Run ticker tests 76 | testTicker() -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "resolveJsonModule": true, 4 | /* Visit https://aka.ms/tsconfig to read more about this file */ 5 | 6 | /* Projects */ 7 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 8 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 9 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 10 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 11 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 12 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 13 | 14 | /* Language and Environment */ 15 | "outDir": "dist", 16 | "noImplicitThis": false, 17 | "noImplicitAny": false, 18 | "target": "es2015", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 19 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 20 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 21 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 22 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 23 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 24 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 25 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 26 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 27 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 28 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 29 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 30 | 31 | /* Modules */ 32 | "module": "commonjs", /* Specify what module code is generated. */ 33 | // "rootDir": "./", /* Specify the root folder within your source files. */ 34 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 35 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 36 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 37 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 38 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 39 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 40 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 41 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 42 | // "resolveJsonModule": true, /* Enable importing .json files. */ 43 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 44 | 45 | /* JavaScript Support */ 46 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 47 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 48 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 49 | 50 | /* Emit */ 51 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 52 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 53 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 54 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 55 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 56 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 57 | // "removeComments": true, /* Disable emitting comments. */ 58 | // "noEmit": true, /* Disable emitting files from a compilation. */ 59 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 60 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 61 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 62 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 63 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 64 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 65 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 66 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 67 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 68 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 69 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 70 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 71 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 72 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 73 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 74 | 75 | /* Interop Constraints */ 76 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 77 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 78 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ 79 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 80 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 81 | 82 | /* Type Checking */ 83 | "strict": true, /* Enable all strict type-checking options. */ 84 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 85 | // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 86 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 87 | // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 88 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 89 | // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 90 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 91 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 92 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 93 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 94 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 95 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 96 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 97 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 98 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 99 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 100 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 101 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 102 | 103 | /* Completeness */ 104 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 105 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 106 | }, 107 | "include": ["lib/**/*.ts"], 108 | "exclude": ["node_modules", "test"] 109 | } 110 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | import KiteConnect from './connect'; 2 | import KiteTicker from './ticker'; 3 | 4 | export { KiteConnect, KiteTicker }; -------------------------------------------------------------------------------- /types/ticker.d.ts: -------------------------------------------------------------------------------- 1 | type KiteTickerParams = { 2 | /** 3 | * API key issued you. 4 | */ 5 | api_key: string; 6 | /** 7 | * Access token obtained after successful login flow. 8 | */ 9 | access_token: string; 10 | /** 11 | * Enable/Disable auto reconnect. Enabled by default. 12 | */ 13 | reconnect?: boolean; 14 | /** 15 | * is maximum number re-connection attempts. Defaults to 50 attempts and maximum up to 300 attempts. 16 | */ 17 | max_retry?: number; 18 | /** 19 | * in seconds is the maximum delay after which subsequent re-connection interval will become constant. Defaults to 60s and minimum acceptable value is 5s. 20 | */ 21 | max_delay?: number; 22 | }; 23 | 24 | type Ticker = { 25 | /** 26 | * Set mode full 27 | */ 28 | modeFull: 'full'; 29 | /** 30 | * this.modeLTP 31 | */ 32 | modeLTP: 'ltp'; 33 | /** 34 | * this.modeQuote 35 | */ 36 | modeQuote: 'quote'; 37 | 38 | /** 39 | * Auto reconnect settings 40 | * @param Enable or disable auto disconnect, defaults to false 41 | * @param max_retry is maximum number re-connection attempts. Defaults to 50 attempts and maximum up to 300 attempts. 42 | * @param max_delay in seconds is the maximum delay after which subsequent re-connection interval will become constant. Defaults to 60s and minimum acceptable value is 5s. 43 | * @returns 44 | */ 45 | autoReconnect: ( 46 | Enable: boolean, 47 | max_retry?: number, 48 | max_delay?: number 49 | ) => void; 50 | /** 51 | * Initiate a websocket connection 52 | */ 53 | connect: () => void; 54 | /** 55 | * Check if the ticker is connected 56 | */ 57 | connected: () => boolean; 58 | /** 59 | * Check if the ticker is connected 60 | */ 61 | disconnect: () => boolean; 62 | /** 63 | * Register websocket event callbacks 64 | * Available events 65 | * ~~~~ 66 | * connect - when connection is successfully established. 67 | * ticks - when ticks are available (Arrays of `ticks` object as the first argument). 68 | * disconnect - when socket connection is disconnected. Error is received as a first param. 69 | * error - when socket connection is closed with error. Error is received as a first param. 70 | * close - when socket connection is closed cleanly. 71 | * reconnect - When reconnecting (current re-connection count and reconnect interval as arguments respectively). 72 | * noreconnect - When re-connection fails after n number times. 73 | * order_update - When order update (postback) is received for the connected user (Data object is received as first argument). 74 | * message - when binary message is received from the server. 75 | * ~~~~ 76 | * 77 | * @example 78 | * ticker.on("ticks", callback); 79 | * ticker.on("connect", callback); 80 | * ticker.on("disconnect", callback); 81 | */ 82 | on: ( 83 | event: 84 | | 'connect' 85 | | 'ticks' 86 | | 'disconnect' 87 | | 'error' 88 | | 'close' 89 | | 'reconnect' 90 | | 'noreconnect' 91 | | 'order_update', 92 | callback: Function 93 | ) => void; 94 | /** 95 | * Set modes to array of tokens 96 | * @param mode mode to set 97 | * @param tokens Array of tokens to be subscribed 98 | * 99 | * @example 100 | * ticker.setMode(ticker.modeFull, [738561]); 101 | */ 102 | setMode: (mode: 'ltp' | 'quote' | 'full', tokens: number[]) => number[]; 103 | /** 104 | * Subscribe to array of tokens 105 | * @param tokens Array of tokens to be subscribed 106 | * 107 | * @example 108 | * ticker.subscribe([738561]); 109 | */ 110 | subscribe: (tokens: number[]) => number[]; 111 | /** 112 | * Unsubscribe to array of tokens 113 | * @param tokens Array of tokens to be unsubscribed 114 | * 115 | * @example 116 | * ticker.unsubscribe([738561]); 117 | */ 118 | unsubscribe: (tokens: number[]) => number[]; 119 | }; 120 | 121 | type KiteTicker = { 122 | /** 123 | * The WebSocket client for connecting to Kite connect streaming quotes service. 124 | * 125 | * Getting started: 126 | * --------------- 127 | * 128 | * import { KiteTicker } from "kiteconnect"; 129 | * const ticker = new KiteTicker({ 130 | * api_key: "api_key", 131 | * access_token: "access_token" 132 | * }); 133 | * 134 | * ticker.connect(); 135 | * ticker.on("ticks", onTicks); 136 | * ticker.on("connect", subscribe); 137 | * 138 | * function onTicks(ticks) { 139 | * console.log("Ticks", ticks); 140 | * } 141 | * 142 | * function subscribe() { 143 | * const items = [738561]; 144 | * ticker.subscribe(items); 145 | * ticker.setMode(ticker.modeFull, items); 146 | * } 147 | * 148 | * Tick structure (passed to the tick callback you assign): 149 | * --------------------------- 150 | * [{ tradable: true, 151 | * mode: 'full', 152 | * instrument_token: 208947, 153 | * last_price: 3939, 154 | * last_quantity: 1, 155 | * average_price: 3944.77, 156 | * volume: 28940, 157 | * buy_quantity: 4492, 158 | * sell_quantity: 4704, 159 | * ohlc: { open: 3927, high: 3955, low: 3927, close: 3906 }, 160 | * change: 0.8448540706605223, 161 | * last_trade_time: 1515491369, 162 | * timestamp: 1515491373, 163 | * oi: 24355, 164 | * oi_day_high: 0, 165 | * oi_day_low: 0, 166 | * depth: 167 | * buy: [{ 168 | * quantity: 59, 169 | * price: 3223, 170 | * orders: 5 171 | * }, 172 | * { 173 | * quantity: 164, 174 | * price: 3222, 175 | * orders: 15 176 | * }, 177 | * { 178 | * quantity: 123, 179 | * price: 3221, 180 | * orders: 7 181 | * }, 182 | * { 183 | * quantity: 48, 184 | * price: 3220, 185 | * orders: 7 186 | * }, 187 | * { 188 | * quantity: 33, 189 | * price: 3219, 190 | * orders: 5 191 | * }], 192 | * sell: [{ 193 | * quantity: 115, 194 | * price: 3224, 195 | * orders: 15 196 | * }, 197 | * { 198 | * quantity: 50, 199 | * price: 3225, 200 | * orders: 5 201 | * }, 202 | * { 203 | * quantity: 175, 204 | * price: 3226, 205 | * orders: 14 206 | * }, 207 | * { 208 | * quantity: 49, 209 | * price: 3227, 210 | * orders: 10 211 | * }, 212 | * { 213 | * quantity: 106, 214 | * price: 3228, 215 | * orders: 13 216 | * }] 217 | * } 218 | * }, ...] 219 | * 220 | * Auto reconnection 221 | * ----------------- 222 | * Auto reonnection is enabled by default and it can be disabled by passing `reconnect` param while initialising `KiteTicker`. 223 | * 224 | * Auto reonnection mechanism is based on [Exponential backoff](https://en.wikipedia.org/wiki/Exponential_backoff) algorithm in which 225 | * next retry interval will be increased exponentially. `max_delay` and `max_tries` params can be used to tweak 226 | * the alogrithm where `max_delay` is the maximum delay after which subsequent reconnection interval will become constant and 227 | * `max_tries` is maximum number of retries before it quits reconnection. 228 | * For example if `max_delay` is 60 seconds and `max_tries` is 50 then the first reconnection interval starts from 229 | * minimum interval which is 2 seconds and keep increasing up to 60 seconds after which it becomes constant and when reconnection attempt 230 | * is reached upto 50 then it stops reconnecting. 231 | * Callback `reconnect` will be called with current reconnect attempt and next reconnect interval and 232 | * `on_noreconnect` is called when reconnection attempts reaches max retries. 233 | * 234 | * Here is an example demonstrating auto reconnection. 235 | * 236 | * import { KiteTicker } from "kiteconnect"; 237 | * const ticker = new KiteTicker({ 238 | * api_key: "api_key", 239 | * access_token: "access_token" 240 | * }); 241 | * 242 | * // set autoreconnect with 10 maximum reconnections and 5 second interval 243 | * ticker.autoReconnect(true, 10, 5) 244 | * ticker.connect(); 245 | * ticker.on("ticks", onTicks); 246 | * ticker.on("connect", subscribe); 247 | * 248 | * ticker.on("noreconnect", function() { 249 | * console.log("noreconnect"); 250 | * }); 251 | * 252 | * ticker.on("reconnect", function(reconnect_count, reconnect_interval) { 253 | * console.log("Reconnecting: attempt - ", reconnect_count, " interval - ", reconnect_interval); 254 | * }); 255 | * 256 | * ticker.on("message", function(binary_msg){ 257 | * console.log("Binary message", binary_msg); 258 | * }); 259 | * 260 | * function onTicks(ticks) { 261 | * console.log("Ticks", ticks); 262 | * } 263 | * 264 | * function subscribe() { 265 | * const items = [738561]; 266 | * ticker.subscribe(items); 267 | * ticker.setMode(ticker.modeFull, items); 268 | * } 269 | * 270 | */ 271 | new (params: KiteTickerParams): Ticker; 272 | }; 273 | 274 | declare const KiteTicker: KiteTicker; 275 | export default KiteTicker; -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@babel/parser@^7.9.4": 6 | version "7.12.16" 7 | resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.12.16.tgz" 8 | integrity sha512-c/+u9cqV6F0+4Hpq01jnJO+GLp2DdT63ppz9Xa+6cHaajM9VFzK/iDXiKK65YtpeVwu+ctfS6iqlMqRgQRzeCw== 9 | 10 | "@eslint/eslintrc@^1.4.0": 11 | version "1.4.0" 12 | resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz" 13 | integrity sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A== 14 | dependencies: 15 | ajv "^6.12.4" 16 | debug "^4.3.2" 17 | espree "^9.4.0" 18 | globals "^13.19.0" 19 | ignore "^5.2.0" 20 | import-fresh "^3.2.1" 21 | js-yaml "^4.1.0" 22 | minimatch "^3.1.2" 23 | strip-json-comments "^3.1.1" 24 | 25 | "@humanwhocodes/config-array@^0.11.8": 26 | version "0.11.8" 27 | resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz" 28 | integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== 29 | dependencies: 30 | "@humanwhocodes/object-schema" "^1.2.1" 31 | debug "^4.1.1" 32 | minimatch "^3.0.5" 33 | 34 | "@humanwhocodes/module-importer@^1.0.1": 35 | version "1.0.1" 36 | resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" 37 | integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== 38 | 39 | "@humanwhocodes/object-schema@^1.2.1": 40 | version "1.2.1" 41 | resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" 42 | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== 43 | 44 | "@nodelib/fs.scandir@2.1.5": 45 | version "2.1.5" 46 | resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" 47 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 48 | dependencies: 49 | "@nodelib/fs.stat" "2.0.5" 50 | run-parallel "^1.1.9" 51 | 52 | "@nodelib/fs.stat@2.0.5": 53 | version "2.0.5" 54 | resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" 55 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 56 | 57 | "@nodelib/fs.walk@^1.2.8": 58 | version "1.2.8" 59 | resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" 60 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 61 | dependencies: 62 | "@nodelib/fs.scandir" "2.1.5" 63 | fastq "^1.6.0" 64 | 65 | "@types/crypto-js@^4.1.1": 66 | version "4.1.1" 67 | resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz" 68 | integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== 69 | 70 | "@types/node@*", "@types/node@^18.11.18": 71 | version "18.11.18" 72 | resolved "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz" 73 | integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== 74 | 75 | "@types/papaparse@^5.3.5": 76 | version "5.3.5" 77 | resolved "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.5.tgz" 78 | integrity sha512-R1icl/hrJPFRpuYj9PVG03WBAlghJj4JW9Py5QdR8FFSxaLmZRyu7xYDCCBZIJNfUv3MYaeBbhBoX958mUTAaw== 79 | dependencies: 80 | "@types/node" "*" 81 | 82 | "@ungap/promise-all-settled@1.1.2": 83 | version "1.1.2" 84 | resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" 85 | integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== 86 | 87 | acorn-jsx@^5.3.2: 88 | version "5.3.2" 89 | resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" 90 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 91 | 92 | "acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.8.0: 93 | version "8.8.1" 94 | resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz" 95 | integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== 96 | 97 | ajv@^6.10.0, ajv@^6.12.4: 98 | version "6.12.6" 99 | resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" 100 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 101 | dependencies: 102 | fast-deep-equal "^3.1.1" 103 | fast-json-stable-stringify "^2.0.0" 104 | json-schema-traverse "^0.4.1" 105 | uri-js "^4.2.2" 106 | 107 | ansi-colors@4.1.1: 108 | version "4.1.1" 109 | resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" 110 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 111 | 112 | ansi-regex@^5.0.1: 113 | version "5.0.1" 114 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" 115 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 116 | 117 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 118 | version "4.3.0" 119 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 120 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 121 | dependencies: 122 | color-convert "^2.0.1" 123 | 124 | anymatch@~3.1.2: 125 | version "3.1.2" 126 | resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" 127 | integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== 128 | dependencies: 129 | normalize-path "^3.0.0" 130 | picomatch "^2.0.4" 131 | 132 | argparse@^1.0.7: 133 | version "1.0.10" 134 | resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" 135 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 136 | dependencies: 137 | sprintf-js "~1.0.2" 138 | 139 | argparse@^2.0.1: 140 | version "2.0.1" 141 | resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" 142 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 143 | 144 | assertion-error@^1.1.0: 145 | version "1.1.0" 146 | resolved "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" 147 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 148 | 149 | async-limiter@~1.0.0: 150 | version "1.0.1" 151 | resolved "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz" 152 | integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== 153 | 154 | axios@^0.21.2: 155 | version "0.21.4" 156 | resolved "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz" 157 | integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== 158 | dependencies: 159 | follow-redirects "^1.14.0" 160 | 161 | balanced-match@^1.0.0: 162 | version "1.0.2" 163 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" 164 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 165 | 166 | binary-extensions@^2.0.0: 167 | version "2.2.0" 168 | resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" 169 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 170 | 171 | bluebird@^3.7.2: 172 | version "3.7.2" 173 | resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz" 174 | integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== 175 | 176 | brace-expansion@^1.1.7: 177 | version "1.1.11" 178 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" 179 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 180 | dependencies: 181 | balanced-match "^1.0.0" 182 | concat-map "0.0.1" 183 | 184 | brace-expansion@^2.0.1: 185 | version "2.0.1" 186 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" 187 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 188 | dependencies: 189 | balanced-match "^1.0.0" 190 | 191 | braces@~3.0.2: 192 | version "3.0.2" 193 | resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" 194 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 195 | dependencies: 196 | fill-range "^7.0.1" 197 | 198 | browser-stdout@1.3.1: 199 | version "1.3.1" 200 | resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz" 201 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 202 | 203 | callsites@^3.0.0: 204 | version "3.1.0" 205 | resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" 206 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 207 | 208 | camelcase@^6.0.0: 209 | version "6.3.0" 210 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" 211 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 212 | 213 | catharsis@^0.8.11: 214 | version "0.8.11" 215 | resolved "https://registry.npmjs.org/catharsis/-/catharsis-0.8.11.tgz" 216 | integrity sha512-a+xUyMV7hD1BrDQA/3iPV7oc+6W26BgVJO05PGEoatMyIuPScQKsde6i3YorWX1qs+AZjnJ18NqdKoCtKiNh1g== 217 | dependencies: 218 | lodash "^4.17.14" 219 | 220 | chai@^4.3.6: 221 | version "4.3.6" 222 | resolved "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz" 223 | integrity sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q== 224 | dependencies: 225 | assertion-error "^1.1.0" 226 | check-error "^1.0.2" 227 | deep-eql "^3.0.1" 228 | get-func-name "^2.0.0" 229 | loupe "^2.3.1" 230 | pathval "^1.1.1" 231 | type-detect "^4.0.5" 232 | 233 | chalk@^4.0.0, chalk@^4.1.0: 234 | version "4.1.2" 235 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" 236 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 237 | dependencies: 238 | ansi-styles "^4.1.0" 239 | supports-color "^7.1.0" 240 | 241 | check-error@^1.0.2: 242 | version "1.0.2" 243 | resolved "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" 244 | integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== 245 | 246 | chokidar@3.5.3: 247 | version "3.5.3" 248 | resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" 249 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 250 | dependencies: 251 | anymatch "~3.1.2" 252 | braces "~3.0.2" 253 | glob-parent "~5.1.2" 254 | is-binary-path "~2.1.0" 255 | is-glob "~4.0.1" 256 | normalize-path "~3.0.0" 257 | readdirp "~3.6.0" 258 | optionalDependencies: 259 | fsevents "~2.3.2" 260 | 261 | cliui@^7.0.2: 262 | version "7.0.4" 263 | resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" 264 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 265 | dependencies: 266 | string-width "^4.2.0" 267 | strip-ansi "^6.0.0" 268 | wrap-ansi "^7.0.0" 269 | 270 | color-convert@^2.0.1: 271 | version "2.0.1" 272 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 273 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 274 | dependencies: 275 | color-name "~1.1.4" 276 | 277 | color-name@~1.1.4: 278 | version "1.1.4" 279 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 280 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 281 | 282 | concat-map@0.0.1: 283 | version "0.0.1" 284 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" 285 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 286 | 287 | cross-spawn@^7.0.2: 288 | version "7.0.3" 289 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" 290 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 291 | dependencies: 292 | path-key "^3.1.0" 293 | shebang-command "^2.0.0" 294 | which "^2.0.1" 295 | 296 | crypto-js@^4.0.0: 297 | version "4.1.1" 298 | resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz" 299 | integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== 300 | 301 | debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@4.3.4: 302 | version "4.3.4" 303 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" 304 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 305 | dependencies: 306 | ms "2.1.2" 307 | 308 | decamelize@^4.0.0: 309 | version "4.0.0" 310 | resolved "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz" 311 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 312 | 313 | deep-eql@^3.0.1: 314 | version "3.0.1" 315 | resolved "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" 316 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 317 | dependencies: 318 | type-detect "^4.0.0" 319 | 320 | deep-is@^0.1.3: 321 | version "0.1.4" 322 | resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" 323 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 324 | 325 | diff@5.0.0: 326 | version "5.0.0" 327 | resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" 328 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 329 | 330 | doctrine@^3.0.0: 331 | version "3.0.0" 332 | resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" 333 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 334 | dependencies: 335 | esutils "^2.0.2" 336 | 337 | emoji-regex@^8.0.0: 338 | version "8.0.0" 339 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" 340 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 341 | 342 | entities@~2.0.0: 343 | version "2.0.3" 344 | resolved "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz" 345 | integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ== 346 | 347 | escalade@^3.1.1: 348 | version "3.1.1" 349 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" 350 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 351 | 352 | escape-string-regexp@^2.0.0: 353 | version "2.0.0" 354 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" 355 | integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== 356 | 357 | escape-string-regexp@^4.0.0: 358 | version "4.0.0" 359 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 360 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 361 | 362 | escape-string-regexp@4.0.0: 363 | version "4.0.0" 364 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" 365 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 366 | 367 | eslint-scope@^7.1.1: 368 | version "7.1.1" 369 | resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" 370 | integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== 371 | dependencies: 372 | esrecurse "^4.3.0" 373 | estraverse "^5.2.0" 374 | 375 | eslint-utils@^3.0.0: 376 | version "3.0.0" 377 | resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" 378 | integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== 379 | dependencies: 380 | eslint-visitor-keys "^2.0.0" 381 | 382 | eslint-visitor-keys@^2.0.0: 383 | version "2.1.0" 384 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" 385 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 386 | 387 | eslint-visitor-keys@^3.3.0: 388 | version "3.3.0" 389 | resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" 390 | integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== 391 | 392 | eslint@^8.30.0, eslint@>=5: 393 | version "8.30.0" 394 | resolved "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz" 395 | integrity sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ== 396 | dependencies: 397 | "@eslint/eslintrc" "^1.4.0" 398 | "@humanwhocodes/config-array" "^0.11.8" 399 | "@humanwhocodes/module-importer" "^1.0.1" 400 | "@nodelib/fs.walk" "^1.2.8" 401 | ajv "^6.10.0" 402 | chalk "^4.0.0" 403 | cross-spawn "^7.0.2" 404 | debug "^4.3.2" 405 | doctrine "^3.0.0" 406 | escape-string-regexp "^4.0.0" 407 | eslint-scope "^7.1.1" 408 | eslint-utils "^3.0.0" 409 | eslint-visitor-keys "^3.3.0" 410 | espree "^9.4.0" 411 | esquery "^1.4.0" 412 | esutils "^2.0.2" 413 | fast-deep-equal "^3.1.3" 414 | file-entry-cache "^6.0.1" 415 | find-up "^5.0.0" 416 | glob-parent "^6.0.2" 417 | globals "^13.19.0" 418 | grapheme-splitter "^1.0.4" 419 | ignore "^5.2.0" 420 | import-fresh "^3.0.0" 421 | imurmurhash "^0.1.4" 422 | is-glob "^4.0.0" 423 | is-path-inside "^3.0.3" 424 | js-sdsl "^4.1.4" 425 | js-yaml "^4.1.0" 426 | json-stable-stringify-without-jsonify "^1.0.1" 427 | levn "^0.4.1" 428 | lodash.merge "^4.6.2" 429 | minimatch "^3.1.2" 430 | natural-compare "^1.4.0" 431 | optionator "^0.9.1" 432 | regexpp "^3.2.0" 433 | strip-ansi "^6.0.1" 434 | strip-json-comments "^3.1.0" 435 | text-table "^0.2.0" 436 | 437 | espree@^9.4.0: 438 | version "9.4.1" 439 | resolved "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz" 440 | integrity sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg== 441 | dependencies: 442 | acorn "^8.8.0" 443 | acorn-jsx "^5.3.2" 444 | eslint-visitor-keys "^3.3.0" 445 | 446 | esquery@^1.4.0: 447 | version "1.4.0" 448 | resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" 449 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 450 | dependencies: 451 | estraverse "^5.1.0" 452 | 453 | esrecurse@^4.3.0: 454 | version "4.3.0" 455 | resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" 456 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 457 | dependencies: 458 | estraverse "^5.2.0" 459 | 460 | estraverse@^5.1.0, estraverse@^5.2.0: 461 | version "5.3.0" 462 | resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" 463 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 464 | 465 | esutils@^2.0.2: 466 | version "2.0.3" 467 | resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" 468 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 469 | 470 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 471 | version "3.1.3" 472 | resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" 473 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 474 | 475 | fast-json-stable-stringify@^2.0.0: 476 | version "2.1.0" 477 | resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" 478 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 479 | 480 | fast-levenshtein@^2.0.6: 481 | version "2.0.6" 482 | resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" 483 | integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== 484 | 485 | fastq@^1.6.0: 486 | version "1.14.0" 487 | resolved "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz" 488 | integrity sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg== 489 | dependencies: 490 | reusify "^1.0.4" 491 | 492 | file-entry-cache@^6.0.1: 493 | version "6.0.1" 494 | resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" 495 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 496 | dependencies: 497 | flat-cache "^3.0.4" 498 | 499 | fill-range@^7.0.1: 500 | version "7.0.1" 501 | resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" 502 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 503 | dependencies: 504 | to-regex-range "^5.0.1" 505 | 506 | find-up@^5.0.0, find-up@5.0.0: 507 | version "5.0.0" 508 | resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" 509 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 510 | dependencies: 511 | locate-path "^6.0.0" 512 | path-exists "^4.0.0" 513 | 514 | flat-cache@^3.0.4: 515 | version "3.0.4" 516 | resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" 517 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 518 | dependencies: 519 | flatted "^3.1.0" 520 | rimraf "^3.0.2" 521 | 522 | flat@^5.0.2: 523 | version "5.0.2" 524 | resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" 525 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 526 | 527 | flatted@^3.1.0: 528 | version "3.2.7" 529 | resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" 530 | integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== 531 | 532 | follow-redirects@^1.14.0: 533 | version "1.15.1" 534 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz" 535 | integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== 536 | 537 | fs.realpath@^1.0.0: 538 | version "1.0.0" 539 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" 540 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 541 | 542 | get-caller-file@^2.0.5: 543 | version "2.0.5" 544 | resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" 545 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 546 | 547 | get-func-name@^2.0.0: 548 | version "2.0.0" 549 | resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" 550 | integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== 551 | 552 | glob-parent@^6.0.2: 553 | version "6.0.2" 554 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" 555 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== 556 | dependencies: 557 | is-glob "^4.0.3" 558 | 559 | glob-parent@~5.1.2: 560 | version "5.1.2" 561 | resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" 562 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 563 | dependencies: 564 | is-glob "^4.0.1" 565 | 566 | glob@^7.1.3, glob@7.2.0: 567 | version "7.2.0" 568 | resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" 569 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 570 | dependencies: 571 | fs.realpath "^1.0.0" 572 | inflight "^1.0.4" 573 | inherits "2" 574 | minimatch "^3.0.4" 575 | once "^1.3.0" 576 | path-is-absolute "^1.0.0" 577 | 578 | globals@^13.19.0: 579 | version "13.19.0" 580 | resolved "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz" 581 | integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== 582 | dependencies: 583 | type-fest "^0.20.2" 584 | 585 | graceful-fs@^4.1.9: 586 | version "4.2.6" 587 | resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" 588 | integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== 589 | 590 | grapheme-splitter@^1.0.4: 591 | version "1.0.4" 592 | resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" 593 | integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== 594 | 595 | has-flag@^4.0.0: 596 | version "4.0.0" 597 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 598 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 599 | 600 | he@1.2.0: 601 | version "1.2.0" 602 | resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" 603 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 604 | 605 | ignore@^5.2.0: 606 | version "5.2.4" 607 | resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" 608 | integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== 609 | 610 | import-fresh@^3.0.0, import-fresh@^3.2.1: 611 | version "3.3.0" 612 | resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" 613 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 614 | dependencies: 615 | parent-module "^1.0.0" 616 | resolve-from "^4.0.0" 617 | 618 | imurmurhash@^0.1.4: 619 | version "0.1.4" 620 | resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" 621 | integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== 622 | 623 | inflight@^1.0.4: 624 | version "1.0.6" 625 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" 626 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 627 | dependencies: 628 | once "^1.3.0" 629 | wrappy "1" 630 | 631 | inherits@2: 632 | version "2.0.4" 633 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 634 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 635 | 636 | is-binary-path@~2.1.0: 637 | version "2.1.0" 638 | resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" 639 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 640 | dependencies: 641 | binary-extensions "^2.0.0" 642 | 643 | is-extglob@^2.1.1: 644 | version "2.1.1" 645 | resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" 646 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 647 | 648 | is-fullwidth-code-point@^3.0.0: 649 | version "3.0.0" 650 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" 651 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 652 | 653 | is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: 654 | version "4.0.3" 655 | resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" 656 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 657 | dependencies: 658 | is-extglob "^2.1.1" 659 | 660 | is-number@^7.0.0: 661 | version "7.0.0" 662 | resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" 663 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 664 | 665 | is-path-inside@^3.0.3: 666 | version "3.0.3" 667 | resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" 668 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== 669 | 670 | is-plain-obj@^2.1.0: 671 | version "2.1.0" 672 | resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz" 673 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 674 | 675 | is-unicode-supported@^0.1.0: 676 | version "0.1.0" 677 | resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" 678 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 679 | 680 | isexe@^2.0.0: 681 | version "2.0.0" 682 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" 683 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 684 | 685 | js-sdsl@^4.1.4: 686 | version "4.2.0" 687 | resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz" 688 | integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== 689 | 690 | js-yaml@^4.1.0, js-yaml@4.1.0: 691 | version "4.1.0" 692 | resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" 693 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 694 | dependencies: 695 | argparse "^2.0.1" 696 | 697 | js2xmlparser@^4.0.1: 698 | version "4.0.1" 699 | resolved "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz" 700 | integrity sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw== 701 | dependencies: 702 | xmlcreate "^2.0.3" 703 | 704 | jsdoc@^3.4.0: 705 | version "3.6.6" 706 | resolved "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.6.tgz" 707 | integrity sha512-znR99e1BHeyEkSvgDDpX0sTiTu+8aQyDl9DawrkOGZTTW8hv0deIFXx87114zJ7gRaDZKVQD/4tr1ifmJp9xhQ== 708 | dependencies: 709 | "@babel/parser" "^7.9.4" 710 | bluebird "^3.7.2" 711 | catharsis "^0.8.11" 712 | escape-string-regexp "^2.0.0" 713 | js2xmlparser "^4.0.1" 714 | klaw "^3.0.0" 715 | markdown-it "^10.0.0" 716 | markdown-it-anchor "^5.2.7" 717 | marked "^0.8.2" 718 | mkdirp "^1.0.4" 719 | requizzle "^0.2.3" 720 | strip-json-comments "^3.1.0" 721 | taffydb "2.6.2" 722 | underscore "~1.10.2" 723 | 724 | json-schema-traverse@^0.4.1: 725 | version "0.4.1" 726 | resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" 727 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 728 | 729 | json-stable-stringify-without-jsonify@^1.0.1: 730 | version "1.0.1" 731 | resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" 732 | integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== 733 | 734 | json-stringify-safe@^5.0.1: 735 | version "5.0.1" 736 | resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" 737 | integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== 738 | 739 | klaw@^3.0.0: 740 | version "3.0.0" 741 | resolved "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz" 742 | integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== 743 | dependencies: 744 | graceful-fs "^4.1.9" 745 | 746 | levn@^0.4.1: 747 | version "0.4.1" 748 | resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" 749 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 750 | dependencies: 751 | prelude-ls "^1.2.1" 752 | type-check "~0.4.0" 753 | 754 | linkify-it@^2.0.0: 755 | version "2.2.0" 756 | resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz" 757 | integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw== 758 | dependencies: 759 | uc.micro "^1.0.1" 760 | 761 | locate-path@^6.0.0: 762 | version "6.0.0" 763 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" 764 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 765 | dependencies: 766 | p-locate "^5.0.0" 767 | 768 | lodash.merge@^4.6.2: 769 | version "4.6.2" 770 | resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" 771 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 772 | 773 | lodash.set@^4.3.2: 774 | version "4.3.2" 775 | resolved "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz" 776 | integrity sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg== 777 | 778 | lodash@^4.17.14: 779 | version "4.17.20" 780 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz" 781 | integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== 782 | 783 | log-symbols@4.1.0: 784 | version "4.1.0" 785 | resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" 786 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 787 | dependencies: 788 | chalk "^4.1.0" 789 | is-unicode-supported "^0.1.0" 790 | 791 | loupe@^2.3.1: 792 | version "2.3.4" 793 | resolved "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz" 794 | integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ== 795 | dependencies: 796 | get-func-name "^2.0.0" 797 | 798 | markdown-it-anchor@^5.2.7: 799 | version "5.3.0" 800 | resolved "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz" 801 | integrity sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA== 802 | 803 | markdown-it@*, markdown-it@^10.0.0: 804 | version "10.0.0" 805 | resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz" 806 | integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg== 807 | dependencies: 808 | argparse "^1.0.7" 809 | entities "~2.0.0" 810 | linkify-it "^2.0.0" 811 | mdurl "^1.0.1" 812 | uc.micro "^1.0.5" 813 | 814 | marked@^0.8.2: 815 | version "0.8.2" 816 | resolved "https://registry.npmjs.org/marked/-/marked-0.8.2.tgz" 817 | integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw== 818 | 819 | mdurl@^1.0.1: 820 | version "1.0.1" 821 | resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" 822 | integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4= sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== 823 | 824 | minami@^1.1.1: 825 | version "1.2.3" 826 | resolved "https://registry.npmjs.org/minami/-/minami-1.2.3.tgz" 827 | integrity sha1-mbbc37LwpU2hycj3qjoyd4eq+fg= sha512-3f2QqqbUC1usVux0FkQMFYB73yd9JIxmHSn1dWQacizL6hOUaNu6mA3KxZ9SfiCc4qgcgq+5XP59+hP7URa1Dw== 828 | 829 | minimatch@^3.0.4: 830 | version "3.1.2" 831 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 832 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 833 | dependencies: 834 | brace-expansion "^1.1.7" 835 | 836 | minimatch@^3.0.5: 837 | version "3.1.2" 838 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 839 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 840 | dependencies: 841 | brace-expansion "^1.1.7" 842 | 843 | minimatch@^3.1.2: 844 | version "3.1.2" 845 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" 846 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 847 | dependencies: 848 | brace-expansion "^1.1.7" 849 | 850 | minimatch@5.0.1: 851 | version "5.0.1" 852 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" 853 | integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== 854 | dependencies: 855 | brace-expansion "^2.0.1" 856 | 857 | mkdirp@^1.0.4: 858 | version "1.0.4" 859 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" 860 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 861 | 862 | mocha@^10.0.0: 863 | version "10.0.0" 864 | resolved "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz" 865 | integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== 866 | dependencies: 867 | "@ungap/promise-all-settled" "1.1.2" 868 | ansi-colors "4.1.1" 869 | browser-stdout "1.3.1" 870 | chokidar "3.5.3" 871 | debug "4.3.4" 872 | diff "5.0.0" 873 | escape-string-regexp "4.0.0" 874 | find-up "5.0.0" 875 | glob "7.2.0" 876 | he "1.2.0" 877 | js-yaml "4.1.0" 878 | log-symbols "4.1.0" 879 | minimatch "5.0.1" 880 | ms "2.1.3" 881 | nanoid "3.3.3" 882 | serialize-javascript "6.0.0" 883 | strip-json-comments "3.1.1" 884 | supports-color "8.1.1" 885 | workerpool "6.2.1" 886 | yargs "16.2.0" 887 | yargs-parser "20.2.4" 888 | yargs-unparser "2.0.0" 889 | 890 | ms@2.1.2: 891 | version "2.1.2" 892 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" 893 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 894 | 895 | ms@2.1.3: 896 | version "2.1.3" 897 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 898 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 899 | 900 | nanoid@3.3.3: 901 | version "3.3.3" 902 | resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz" 903 | integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== 904 | 905 | natural-compare@^1.4.0: 906 | version "1.4.0" 907 | resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" 908 | integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 909 | 910 | nock@^13.2.4: 911 | version "13.2.4" 912 | resolved "https://registry.npmjs.org/nock/-/nock-13.2.4.tgz" 913 | integrity sha512-8GPznwxcPNCH/h8B+XZcKjYPXnUV5clOKCjAqyjsiqA++MpNx9E9+t8YPp0MbThO+KauRo7aZJ1WuIZmOrT2Ug== 914 | dependencies: 915 | debug "^4.1.0" 916 | json-stringify-safe "^5.0.1" 917 | lodash.set "^4.3.2" 918 | propagate "^2.0.0" 919 | 920 | normalize-path@^3.0.0, normalize-path@~3.0.0: 921 | version "3.0.0" 922 | resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" 923 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 924 | 925 | once@^1.3.0: 926 | version "1.4.0" 927 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 928 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 929 | dependencies: 930 | wrappy "1" 931 | 932 | optionator@^0.9.1: 933 | version "0.9.1" 934 | resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" 935 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 936 | dependencies: 937 | deep-is "^0.1.3" 938 | fast-levenshtein "^2.0.6" 939 | levn "^0.4.1" 940 | prelude-ls "^1.2.1" 941 | type-check "^0.4.0" 942 | word-wrap "^1.2.3" 943 | 944 | p-limit@^3.0.2: 945 | version "3.1.0" 946 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" 947 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 948 | dependencies: 949 | yocto-queue "^0.1.0" 950 | 951 | p-locate@^5.0.0: 952 | version "5.0.0" 953 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" 954 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 955 | dependencies: 956 | p-limit "^3.0.2" 957 | 958 | papaparse@^5.3.1: 959 | version "5.3.2" 960 | resolved "https://registry.npmjs.org/papaparse/-/papaparse-5.3.2.tgz" 961 | integrity sha512-6dNZu0Ki+gyV0eBsFKJhYr+MdQYAzFUGlBMNj3GNrmHxmz1lfRa24CjFObPXtjcetlOv5Ad299MhIK0znp3afw== 962 | 963 | parent-module@^1.0.0: 964 | version "1.0.1" 965 | resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" 966 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 967 | dependencies: 968 | callsites "^3.0.0" 969 | 970 | path-exists@^4.0.0: 971 | version "4.0.0" 972 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" 973 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 974 | 975 | path-is-absolute@^1.0.0: 976 | version "1.0.1" 977 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" 978 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 979 | 980 | path-key@^3.1.0: 981 | version "3.1.1" 982 | resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" 983 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 984 | 985 | pathval@^1.1.1: 986 | version "1.1.1" 987 | resolved "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz" 988 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 989 | 990 | picomatch@^2.0.4, picomatch@^2.2.1: 991 | version "2.3.1" 992 | resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" 993 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 994 | 995 | prelude-ls@^1.2.1: 996 | version "1.2.1" 997 | resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" 998 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 999 | 1000 | propagate@^2.0.0: 1001 | version "2.0.1" 1002 | resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz" 1003 | integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== 1004 | 1005 | punycode@^2.1.0: 1006 | version "2.1.1" 1007 | resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" 1008 | integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 1009 | 1010 | queue-microtask@^1.2.2: 1011 | version "1.2.3" 1012 | resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" 1013 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 1014 | 1015 | randombytes@^2.1.0: 1016 | version "2.1.0" 1017 | resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" 1018 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 1019 | dependencies: 1020 | safe-buffer "^5.1.0" 1021 | 1022 | readdirp@~3.6.0: 1023 | version "3.6.0" 1024 | resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" 1025 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1026 | dependencies: 1027 | picomatch "^2.2.1" 1028 | 1029 | regexpp@^3.2.0: 1030 | version "3.2.0" 1031 | resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" 1032 | integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 1033 | 1034 | require-directory@^2.1.1: 1035 | version "2.1.1" 1036 | resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" 1037 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1038 | 1039 | requizzle@^0.2.3: 1040 | version "0.2.3" 1041 | resolved "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz" 1042 | integrity sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ== 1043 | dependencies: 1044 | lodash "^4.17.14" 1045 | 1046 | resolve-from@^4.0.0: 1047 | version "4.0.0" 1048 | resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" 1049 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1050 | 1051 | reusify@^1.0.4: 1052 | version "1.0.4" 1053 | resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" 1054 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 1055 | 1056 | rimraf@^3.0.2: 1057 | version "3.0.2" 1058 | resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" 1059 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1060 | dependencies: 1061 | glob "^7.1.3" 1062 | 1063 | run-parallel@^1.1.9: 1064 | version "1.2.0" 1065 | resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" 1066 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 1067 | dependencies: 1068 | queue-microtask "^1.2.2" 1069 | 1070 | safe-buffer@^5.1.0: 1071 | version "5.2.1" 1072 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" 1073 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1074 | 1075 | serialize-javascript@6.0.0: 1076 | version "6.0.0" 1077 | resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" 1078 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 1079 | dependencies: 1080 | randombytes "^2.1.0" 1081 | 1082 | shebang-command@^2.0.0: 1083 | version "2.0.0" 1084 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" 1085 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1086 | dependencies: 1087 | shebang-regex "^3.0.0" 1088 | 1089 | shebang-regex@^3.0.0: 1090 | version "3.0.0" 1091 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" 1092 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1093 | 1094 | sprintf-js@~1.0.2: 1095 | version "1.0.3" 1096 | resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" 1097 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== 1098 | 1099 | string-width@^4.1.0, string-width@^4.2.0: 1100 | version "4.2.3" 1101 | resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" 1102 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1103 | dependencies: 1104 | emoji-regex "^8.0.0" 1105 | is-fullwidth-code-point "^3.0.0" 1106 | strip-ansi "^6.0.1" 1107 | 1108 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1109 | version "6.0.1" 1110 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" 1111 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1112 | dependencies: 1113 | ansi-regex "^5.0.1" 1114 | 1115 | strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@3.1.1: 1116 | version "3.1.1" 1117 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" 1118 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1119 | 1120 | supports-color@^7.1.0: 1121 | version "7.2.0" 1122 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 1123 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1124 | dependencies: 1125 | has-flag "^4.0.0" 1126 | 1127 | supports-color@8.1.1: 1128 | version "8.1.1" 1129 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" 1130 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1131 | dependencies: 1132 | has-flag "^4.0.0" 1133 | 1134 | taffydb@2.6.2: 1135 | version "2.6.2" 1136 | resolved "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz" 1137 | integrity sha1-fLy2S1oUG2ou/CxdLGe04VCyomg= sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA== 1138 | 1139 | text-table@^0.2.0: 1140 | version "0.2.0" 1141 | resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" 1142 | integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== 1143 | 1144 | to-regex-range@^5.0.1: 1145 | version "5.0.1" 1146 | resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" 1147 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1148 | dependencies: 1149 | is-number "^7.0.0" 1150 | 1151 | type-check@^0.4.0, type-check@~0.4.0: 1152 | version "0.4.0" 1153 | resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" 1154 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1155 | dependencies: 1156 | prelude-ls "^1.2.1" 1157 | 1158 | type-detect@^4.0.0, type-detect@^4.0.5: 1159 | version "4.0.8" 1160 | resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" 1161 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 1162 | 1163 | type-fest@^0.20.2: 1164 | version "0.20.2" 1165 | resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" 1166 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1167 | 1168 | typescript@^4.9.4: 1169 | version "4.9.4" 1170 | resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz" 1171 | integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== 1172 | 1173 | uc.micro@^1.0.1, uc.micro@^1.0.5: 1174 | version "1.0.6" 1175 | resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" 1176 | integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== 1177 | 1178 | underscore@~1.10.2: 1179 | version "1.10.2" 1180 | resolved "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz" 1181 | integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== 1182 | 1183 | uri-js@^4.2.2: 1184 | version "4.4.1" 1185 | resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" 1186 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1187 | dependencies: 1188 | punycode "^2.1.0" 1189 | 1190 | which@^2.0.1: 1191 | version "2.0.2" 1192 | resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" 1193 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1194 | dependencies: 1195 | isexe "^2.0.0" 1196 | 1197 | word-wrap@^1.2.3: 1198 | version "1.2.3" 1199 | resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" 1200 | integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== 1201 | 1202 | workerpool@6.2.1: 1203 | version "6.2.1" 1204 | resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz" 1205 | integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== 1206 | 1207 | wrap-ansi@^7.0.0: 1208 | version "7.0.0" 1209 | resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" 1210 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1211 | dependencies: 1212 | ansi-styles "^4.0.0" 1213 | string-width "^4.1.0" 1214 | strip-ansi "^6.0.0" 1215 | 1216 | wrappy@1: 1217 | version "1.0.2" 1218 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 1219 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1220 | 1221 | ws@^6.2.2: 1222 | version "6.2.2" 1223 | resolved "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz" 1224 | integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== 1225 | dependencies: 1226 | async-limiter "~1.0.0" 1227 | 1228 | xmlcreate@^2.0.3: 1229 | version "2.0.3" 1230 | resolved "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz" 1231 | integrity sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ== 1232 | 1233 | y18n@^5.0.5: 1234 | version "5.0.8" 1235 | resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" 1236 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1237 | 1238 | yargs-parser@^20.2.2, yargs-parser@20.2.4: 1239 | version "20.2.4" 1240 | resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz" 1241 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1242 | 1243 | yargs-unparser@2.0.0: 1244 | version "2.0.0" 1245 | resolved "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz" 1246 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1247 | dependencies: 1248 | camelcase "^6.0.0" 1249 | decamelize "^4.0.0" 1250 | flat "^5.0.2" 1251 | is-plain-obj "^2.1.0" 1252 | 1253 | yargs@16.2.0: 1254 | version "16.2.0" 1255 | resolved "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz" 1256 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1257 | dependencies: 1258 | cliui "^7.0.2" 1259 | escalade "^3.1.1" 1260 | get-caller-file "^2.0.5" 1261 | require-directory "^2.1.1" 1262 | string-width "^4.2.0" 1263 | y18n "^5.0.5" 1264 | yargs-parser "^20.2.2" 1265 | 1266 | yocto-queue@^0.1.0: 1267 | version "0.1.0" 1268 | resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" 1269 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1270 | --------------------------------------------------------------------------------