@tastytrade/api 2.1.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,6 +43,7 @@ exports.AccountStreamer = exports.STREAMER_STATE = void 0;
43
43
  var isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
44
44
  var lodash_1 = __importDefault(require("lodash"));
45
45
  var json_util_1 = require("./utils/json-util");
46
+ var constants_1 = require("./utils/constants");
46
47
  var STREAMER_STATE;
47
48
  (function (STREAMER_STATE) {
48
49
  STREAMER_STATE[STREAMER_STATE["Open"] = 0] = "Open";
@@ -231,7 +232,10 @@ var AccountStreamer = /** @class */ (function () {
231
232
  if (this.startPromise !== null) {
232
233
  return [2 /*return*/, this.startPromise];
233
234
  }
234
- websocket = (this.websocket = new isomorphic_ws_1.default(this.url));
235
+ this.websocket = new isomorphic_ws_1.default(this.url, [], {
236
+ minVersion: constants_1.MinTlsVersion // TLS Config
237
+ });
238
+ websocket = this.websocket;
235
239
  this.lastCloseEvent = null;
236
240
  this.lastErrorEvent = null;
237
241
  websocket.addEventListener('open', this.handleOpen);
@@ -7,6 +7,7 @@ exports.CandleType = exports.MarketDataSubscriptionType = void 0;
7
7
  var isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
8
8
  var lodash_1 = __importDefault(require("lodash"));
9
9
  var uuid_1 = require("uuid");
10
+ var constants_1 = require("./utils/constants");
10
11
  var MarketDataSubscriptionType;
11
12
  (function (MarketDataSubscriptionType) {
12
13
  MarketDataSubscriptionType["Candle"] = "Candle";
@@ -80,7 +81,9 @@ var MarketDataStreamer = /** @class */ (function () {
80
81
  throw new Error('MarketDataStreamer is attempting to connect when an existing websocket is already connected');
81
82
  }
82
83
  this.token = token;
83
- this.webSocket = new isomorphic_ws_1.default(url);
84
+ this.webSocket = new isomorphic_ws_1.default(url, [], {
85
+ minVersion: constants_1.MinTlsVersion // TLS Config
86
+ });
84
87
  this.webSocket.onopen = this.onOpen.bind(this);
85
88
  this.webSocket.onerror = this.onError.bind(this);
86
89
  this.webSocket.onmessage = this.handleMessageReceived.bind(this);
@@ -320,7 +323,7 @@ var MarketDataStreamer = /** @class */ (function () {
320
323
  this.errorListeners.forEach(function (listener) { return listener(error); });
321
324
  };
322
325
  MarketDataStreamer.prototype.handleMessageReceived = function (data) {
323
- var messageData = lodash_1.default.get(data, 'data', data);
326
+ var messageData = lodash_1.default.get(data, 'data', '{}');
324
327
  var jsonData = JSON.parse(messageData);
325
328
  switch (jsonData.type) {
326
329
  case 'AUTH_STATE':
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
40
40
  };
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
42
  var response_util_1 = __importDefault(require("../utils/response-util"));
43
- // create the central class that aggregates all services from dmoss
43
+ // create the central class that aggregates all services
44
44
  var AccountStatusService = /** @class */ (function () {
45
45
  function AccountStatusService(httpClient) {
46
46
  this.httpClient = httpClient;
@@ -6,11 +6,13 @@ export default class OrderService {
6
6
  replacementOrderDryRun(accountNumber: string, orderId: number, replacementOrder: object): Promise<any>;
7
7
  getOrder(accountNumber: string, orderId: number): Promise<any>;
8
8
  cancelOrder(accountNumber: string, orderId: number): Promise<any>;
9
+ cancelComplexOrder(accountNumber: string, orderId: number): Promise<any>;
9
10
  replaceOrder(accountNumber: string, orderId: number, replacementOrder: object): Promise<any>;
10
11
  editOrder(accountNumber: string, orderId: number, order: object): Promise<any>;
11
12
  getLiveOrders(accountNumber: string): Promise<any>;
12
13
  getOrders(accountNumber: string, queryParams?: {}): Promise<any>;
13
14
  createOrder(accountNumber: string, order: object): Promise<any>;
15
+ createComplexOrder(accountNumber: string, order: object): Promise<any>;
14
16
  postOrderDryRun(accountNumber: string, order: object): Promise<any>;
15
17
  getLiveOrdersForCustomer(customerId: string): Promise<any>;
16
18
  getCustomerOrders(customerId: string, queryParams?: {}): Promise<any>;
@@ -97,6 +97,19 @@ var OrderService = /** @class */ (function () {
97
97
  });
98
98
  });
99
99
  };
100
+ OrderService.prototype.cancelComplexOrder = function (accountNumber, orderId) {
101
+ return __awaiter(this, void 0, void 0, function () {
102
+ var order;
103
+ return __generator(this, function (_a) {
104
+ switch (_a.label) {
105
+ case 0: return [4 /*yield*/, this.httpClient.deleteData("/accounts/".concat(accountNumber, "/complex-orders/").concat(orderId), {})];
106
+ case 1:
107
+ order = _a.sent();
108
+ return [2 /*return*/, (0, response_util_1.default)(order)];
109
+ }
110
+ });
111
+ });
112
+ };
100
113
  OrderService.prototype.replaceOrder = function (accountNumber, orderId, replacementOrder) {
101
114
  return __awaiter(this, void 0, void 0, function () {
102
115
  var order;
@@ -163,6 +176,19 @@ var OrderService = /** @class */ (function () {
163
176
  });
164
177
  });
165
178
  };
179
+ OrderService.prototype.createComplexOrder = function (accountNumber, order) {
180
+ return __awaiter(this, void 0, void 0, function () {
181
+ var orderResponse;
182
+ return __generator(this, function (_a) {
183
+ switch (_a.label) {
184
+ case 0: return [4 /*yield*/, this.httpClient.postData("/accounts/".concat(accountNumber, "/complex-orders"), order, {})];
185
+ case 1:
186
+ orderResponse = _a.sent();
187
+ return [2 /*return*/, (0, response_util_1.default)(orderResponse)];
188
+ }
189
+ });
190
+ });
191
+ };
166
192
  OrderService.prototype.postOrderDryRun = function (accountNumber, order) {
167
193
  return __awaiter(this, void 0, void 0, function () {
168
194
  var orderDryRun;
@@ -2,6 +2,7 @@ import TastytradeSession from "../models/tastytrade-session";
2
2
  export default class TastytradeHttpClient {
3
3
  private readonly baseUrl;
4
4
  readonly session: TastytradeSession;
5
+ private readonly httpsAgent;
5
6
  constructor(baseUrl: string);
6
7
  private getDefaultHeaders;
7
8
  private executeRequest;
@@ -55,6 +55,8 @@ var axios_1 = __importDefault(require("axios"));
55
55
  var qs_1 = __importDefault(require("qs"));
56
56
  var json_util_1 = require("../utils/json-util");
57
57
  var lodash_1 = __importDefault(require("lodash"));
58
+ var https_1 = __importDefault(require("https"));
59
+ var constants_1 = require("../utils/constants");
58
60
  var ParamsSerializer = {
59
61
  serialize: function (queryParams) {
60
62
  return qs_1.default.stringify(queryParams, { arrayFormat: 'brackets' });
@@ -64,12 +66,14 @@ var TastytradeHttpClient = /** @class */ (function () {
64
66
  function TastytradeHttpClient(baseUrl) {
65
67
  this.baseUrl = baseUrl;
66
68
  this.session = new tastytrade_session_1.default();
69
+ this.httpsAgent = new https_1.default.Agent({ minVersion: constants_1.MinTlsVersion });
67
70
  }
68
71
  TastytradeHttpClient.prototype.getDefaultHeaders = function () {
69
72
  return {
70
73
  "Content-Type": "application/json",
71
74
  "Accept": "application/json",
72
75
  "Authorization": this.session.authToken,
76
+ "User-Agent": 'tastytrade-sdk-js'
73
77
  };
74
78
  };
75
79
  TastytradeHttpClient.prototype.executeRequest = function (method, url, data, headers, params) {
@@ -89,7 +93,8 @@ var TastytradeHttpClient = /** @class */ (function () {
89
93
  data: dasherizedData,
90
94
  headers: mergedHeaders,
91
95
  params: dasherizedParams,
92
- paramsSerializer: ParamsSerializer
96
+ paramsSerializer: ParamsSerializer,
97
+ httpsAgent: this.httpsAgent
93
98
  }, lodash_1.default.isEmpty);
94
99
  return [2 /*return*/, axios_1.default.request(config)];
95
100
  });
@@ -0,0 +1 @@
1
+ export declare const MinTlsVersion = "TLSv1.2";
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MinTlsVersion = void 0;
4
+ exports.MinTlsVersion = 'TLSv1.2';
@@ -3,6 +3,7 @@ import _ from 'lodash'
3
3
  import type { JsonMap, JsonValue } from './utils/json-util'
4
4
  import { JsonBuilder } from './utils/json-util'
5
5
  import TastytradeSession from './models/tastytrade-session'
6
+ import { MinTlsVersion } from './utils/constants'
6
7
 
7
8
  export enum STREAMER_STATE {
8
9
  Open = 0,
@@ -123,7 +124,10 @@ export class AccountStreamer {
123
124
  return this.startPromise
124
125
  }
125
126
 
126
- const websocket = (this.websocket = new WebSocket(this.url))
127
+ this.websocket = new WebSocket(this.url, [], {
128
+ minVersion: MinTlsVersion // TLS Config
129
+ })
130
+ const websocket = this.websocket
127
131
  this.lastCloseEvent = null
128
132
  this.lastErrorEvent = null
129
133
  websocket.addEventListener('open', this.handleOpen)
@@ -300,7 +304,7 @@ export class AccountStreamer {
300
304
  this.queued = []
301
305
  }
302
306
 
303
- private readonly handleOpen = (event: Event) => {
307
+ private readonly handleOpen = (event: WebSocket.Event) => {
304
308
  if (this.startResolve === null) {
305
309
  return
306
310
  }
@@ -315,7 +319,7 @@ export class AccountStreamer {
315
319
  this.scheduleHeartbeatTimer()
316
320
  }
317
321
 
318
- private readonly handleClose = (event: CloseEvent) => {
322
+ private readonly handleClose = (event: WebSocket.CloseEvent) => {
319
323
  this.logger.info('AccountStreamer closed', event)
320
324
  if (this.websocket === null) {
321
325
  return
@@ -326,7 +330,7 @@ export class AccountStreamer {
326
330
  this.teardown()
327
331
  }
328
332
 
329
- private readonly handleError = (event: Event) => {
333
+ private readonly handleError = (event: WebSocket.ErrorEvent) => {
330
334
  if (this.websocket === null) {
331
335
  return
332
336
  }
@@ -344,7 +348,7 @@ export class AccountStreamer {
344
348
  this.teardown()
345
349
  }
346
350
 
347
- private readonly handleMessage = (event: MessageEvent) => {
351
+ private readonly handleMessage = (event: WebSocket.MessageEvent) => {
348
352
  const json = JSON.parse(event.data as string) as JsonMap
349
353
 
350
354
  if (json.results !== undefined) {
@@ -1,6 +1,7 @@
1
1
  import WebSocket from 'isomorphic-ws'
2
2
  import _ from 'lodash'
3
3
  import { v4 as uuidv4 } from 'uuid'
4
+ import { MinTlsVersion } from './utils/constants'
4
5
 
5
6
  export enum MarketDataSubscriptionType {
6
7
  Candle = 'Candle',
@@ -89,7 +90,9 @@ export default class MarketDataStreamer {
89
90
  }
90
91
 
91
92
  this.token = token
92
- this.webSocket = new WebSocket(url)
93
+ this.webSocket = new WebSocket(url, [], {
94
+ minVersion: MinTlsVersion // TLS Config
95
+ })
93
96
  this.webSocket.onopen = this.onOpen.bind(this)
94
97
  this.webSocket.onerror = this.onError.bind(this)
95
98
  this.webSocket.onmessage = this.handleMessageReceived.bind(this)
@@ -343,9 +346,9 @@ export default class MarketDataStreamer {
343
346
  this.errorListeners.forEach(listener => listener(error))
344
347
  }
345
348
 
346
- private handleMessageReceived(data: string) {
347
- const messageData = _.get(data, 'data', data)
348
- const jsonData = JSON.parse(messageData)
349
+ private handleMessageReceived(data: WebSocket.MessageEvent) {
350
+ const messageData = _.get(data, 'data', '{}')
351
+ const jsonData = JSON.parse(messageData as string)
349
352
  switch (jsonData.type) {
350
353
  case 'AUTH_STATE':
351
354
  this.handleAuthStateMessage(jsonData)
@@ -1,7 +1,7 @@
1
1
  import extractResponseData from "../utils/response-util";
2
2
  import TastytradeHttpClient from "./tastytrade-http-client";
3
3
 
4
- // create the central class that aggregates all services from dmoss
4
+ // create the central class that aggregates all services
5
5
  export default class AccountStatusService {
6
6
  constructor(private httpClient: TastytradeHttpClient) {
7
7
  }
@@ -30,6 +30,12 @@ export default class OrderService {
30
30
  return extractResponseData(order)
31
31
  }
32
32
 
33
+ async cancelComplexOrder(accountNumber: string, orderId: number){
34
+ //Requests order cancellation
35
+ const order = await this.httpClient.deleteData(`/accounts/${accountNumber}/complex-orders/${orderId}`, {})
36
+ return extractResponseData(order)
37
+ }
38
+
33
39
  async replaceOrder(accountNumber: string, orderId: number, replacementOrder : object){
34
40
  //Replaces a live order with a new one. Subsequent fills of the original order will abort the replacement.
35
41
  const order = await this.httpClient.putData(`/accounts/${accountNumber}/orders/${orderId}`, replacementOrder , {})
@@ -60,6 +66,12 @@ export default class OrderService {
60
66
  return extractResponseData(orderResponse)
61
67
  }
62
68
 
69
+ async createComplexOrder(accountNumber: string, order: object){
70
+ //Accepts a json document containing parameters to create an order for the client.
71
+ const orderResponse = await this.httpClient.postData(`/accounts/${accountNumber}/complex-orders`, order , {})
72
+ return extractResponseData(orderResponse)
73
+ }
74
+
63
75
  async postOrderDryRun(accountNumber: string, order: object){
64
76
  //Accepts a json document containing parameters to create an order and then runs the prefights without placing the order.
65
77
  const orderDryRun = await this.httpClient.postData(`/accounts/${accountNumber}/orders/dry-run`, order , {})
@@ -3,6 +3,8 @@ import axios from "axios"
3
3
  import qs from 'qs'
4
4
  import { recursiveDasherizeKeys } from "../utils/json-util"
5
5
  import _ from 'lodash'
6
+ import https from 'https'
7
+ import { MinTlsVersion } from "../utils/constants"
6
8
 
7
9
  const ParamsSerializer = {
8
10
  serialize: function (queryParams: object) {
@@ -12,9 +14,11 @@ const ParamsSerializer = {
12
14
 
13
15
  export default class TastytradeHttpClient{
14
16
  public readonly session: TastytradeSession
17
+ private readonly httpsAgent: https.Agent
15
18
 
16
19
  constructor(private readonly baseUrl: string) {
17
20
  this.session = new TastytradeSession()
21
+ this.httpsAgent = new https.Agent({ minVersion: MinTlsVersion })
18
22
  }
19
23
 
20
24
  private getDefaultHeaders(): any {
@@ -22,6 +26,7 @@ export default class TastytradeHttpClient{
22
26
  "Content-Type": "application/json",
23
27
  "Accept": "application/json",
24
28
  "Authorization": this.session.authToken,
29
+ "User-Agent": 'tastytrade-sdk-js'
25
30
  };
26
31
  }
27
32
 
@@ -37,7 +42,8 @@ export default class TastytradeHttpClient{
37
42
  data: dasherizedData,
38
43
  headers: mergedHeaders,
39
44
  params: dasherizedParams,
40
- paramsSerializer: ParamsSerializer
45
+ paramsSerializer: ParamsSerializer,
46
+ httpsAgent: this.httpsAgent
41
47
  }, _.isEmpty)
42
48
 
43
49
  return axios.request(config)
@@ -0,0 +1 @@
1
+ export const MinTlsVersion = 'TLSv1.2'
package/package.json CHANGED
@@ -1,18 +1,22 @@
1
1
  {
2
2
  "name": "@tastytrade/api",
3
- "version": "2.1.2",
3
+ "version": "3.1.0",
4
4
  "main": "dist/tastytrade-api.js",
5
5
  "typings": "dist/tastytrade-api.d.ts",
6
6
  "repository": "https://github.com/tastytrade/tastytrade-api-js",
7
7
  "license": "MIT",
8
8
  "description": "Typescript impelementation of tastytrade api",
9
+ "engines": {
10
+ "npm": ">=9.0.0",
11
+ "node": ">=20.0.0"
12
+ },
9
13
  "scripts": {
10
14
  "build": "tsc -p tsconfig.json",
11
15
  "test": "jest -i --restoreMocks",
12
16
  "unit-test": "jest --testPathPattern=tests/unit",
13
17
  "integration-test": "jest --testPathPattern=tests/integration",
14
18
  "lint": "eslint lib/** tests/**",
15
- "prepublishOnly": "npm run test && npm run build",
19
+ "prepublishOnly": "npm run unit-test && npm run build",
16
20
  "postpack": "git tag -a $npm_package_version -m $npm_package_version && git push origin $npm_package_version"
17
21
  },
18
22
  "dependencies": {
@@ -26,9 +30,11 @@
26
30
  "ws": "^8.13.0"
27
31
  },
28
32
  "devDependencies": {
33
+ "@types/axios": "^0.14.0",
29
34
  "@types/jest": "^29.5.0",
30
- "@types/node": "17.0.27",
35
+ "@types/node": "20.9.0",
31
36
  "@types/uuid": "^9.0.2",
37
+ "@types/ws": "^8.5.9",
32
38
  "@typescript-eslint/eslint-plugin": "^5.57.1",
33
39
  "@typescript-eslint/parser": "^5.57.1",
34
40
  "dotenv": "^16.0.3",