@tastytrade/api 0.0.1

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.
Files changed (67) hide show
  1. package/.env +5 -0
  2. package/.eslintrc.cjs +18 -0
  3. package/.vscode/launch.json +24 -0
  4. package/LICENSE +21 -0
  5. package/README.md +21 -0
  6. package/dist/account-streamer.d.ts +92 -0
  7. package/dist/account-streamer.js +394 -0
  8. package/dist/models/tastytrade-session.d.ts +5 -0
  9. package/dist/models/tastytrade-session.js +23 -0
  10. package/dist/quote-streamer.d.ts +11 -0
  11. package/dist/quote-streamer.js +63 -0
  12. package/dist/services/account-status-service.d.ts +6 -0
  13. package/dist/services/account-status-service.js +64 -0
  14. package/dist/services/accounts-and-customers-service.d.ts +10 -0
  15. package/dist/services/accounts-and-customers-service.js +116 -0
  16. package/dist/services/balances-and-positions-service.d.ts +8 -0
  17. package/dist/services/balances-and-positions-service.js +93 -0
  18. package/dist/services/instruments-service.d.ts +28 -0
  19. package/dist/services/instruments-service.js +370 -0
  20. package/dist/services/margin-requirements-service.d.ts +7 -0
  21. package/dist/services/margin-requirements-service.js +76 -0
  22. package/dist/services/market-metrics-service.d.ts +8 -0
  23. package/dist/services/market-metrics-service.js +91 -0
  24. package/dist/services/net-liquidating-value-history-service.d.ts +7 -0
  25. package/dist/services/net-liquidating-value-history-service.js +77 -0
  26. package/dist/services/orders-service.d.ts +17 -0
  27. package/dist/services/orders-service.js +208 -0
  28. package/dist/services/risk-parameters-service.d.ts +7 -0
  29. package/dist/services/risk-parameters-service.js +76 -0
  30. package/dist/services/session-service.d.ts +9 -0
  31. package/dist/services/session-service.js +113 -0
  32. package/dist/services/symbol-search-service.d.ts +6 -0
  33. package/dist/services/symbol-search-service.js +63 -0
  34. package/dist/services/tastytrade-http-client.d.ts +13 -0
  35. package/dist/services/tastytrade-http-client.js +137 -0
  36. package/dist/services/transactions-service.d.ts +8 -0
  37. package/dist/services/transactions-service.js +91 -0
  38. package/dist/services/watchlists-service.d.ts +14 -0
  39. package/dist/services/watchlists-service.js +170 -0
  40. package/dist/tastytrade-api.d.ts +40 -0
  41. package/dist/tastytrade-api.js +56 -0
  42. package/dist/utils/json-util.d.ts +14 -0
  43. package/dist/utils/json-util.js +43 -0
  44. package/dist/utils/response-util.d.ts +1 -0
  45. package/dist/utils/response-util.js +21 -0
  46. package/lib/account-streamer.ts +394 -0
  47. package/lib/models/tastytrade-session.ts +13 -0
  48. package/lib/quote-streamer.ts +40 -0
  49. package/lib/services/account-status-service.ts +15 -0
  50. package/lib/services/accounts-and-customers-service.ts +35 -0
  51. package/lib/services/balances-and-positions-service.ts +29 -0
  52. package/lib/services/instruments-service.ts +138 -0
  53. package/lib/services/margin-requirements-service.ts +19 -0
  54. package/lib/services/market-metrics-service.ts +24 -0
  55. package/lib/services/net-liquidating-value-history-service.ts +20 -0
  56. package/lib/services/orders-service.ts +80 -0
  57. package/lib/services/risk-parameters-service.ts +19 -0
  58. package/lib/services/session-service.ts +35 -0
  59. package/lib/services/symbol-search-service.ts +14 -0
  60. package/lib/services/tastytrade-http-client.ts +65 -0
  61. package/lib/services/transactions-service.ts +27 -0
  62. package/lib/services/watchlists-service.ts +58 -0
  63. package/lib/tastytrade-api.ts +65 -0
  64. package/lib/utils/json-util.ts +44 -0
  65. package/lib/utils/response-util.ts +15 -0
  66. package/package.json +35 -0
  67. package/tsconfig.json +71 -0
@@ -0,0 +1,24 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class MarketMetricsService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Default
9
+ async getMarketMetrics(queryParams = {}){
10
+ //Returns an array of volatility data for given symbols.
11
+ const marketMetrics = (await this.httpClient.getData('/market-metrics', {}, queryParams))
12
+ return extractResponseData(marketMetrics)
13
+ }
14
+ async getHistoricalDividendData(symbol: string){
15
+ //Get historical dividend data
16
+ const historicalDividendData = (await this.httpClient.getData(`/market-metrics/historic-corporate-events/dividends/${symbol}`, {}, {}))
17
+ return extractResponseData(historicalDividendData)
18
+ }
19
+ async getHistoricalEarningsData(symbol: string, queryParams = {}){
20
+ //Get historical earnings data
21
+ const historicalEarningsData = (await this.httpClient.getData(`/market-metrics/historic-corporate-events/earnings-reports/${symbol}`, {}, queryParams))
22
+ return extractResponseData(historicalEarningsData)
23
+ }
24
+ }
@@ -0,0 +1,20 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class NetLiquidatingValueHistoryService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Default
9
+ async getNetLiquidatingValueHistory(accountNumber: string, queryParams = {}){
10
+ //Returns a list of account net liquidating value snapshots.
11
+ const netLiquidatingValueHistory = (await this.httpClient.getData(`/accounts/${accountNumber}/net-liq/history`, {}, queryParams))
12
+ return extractResponseData(netLiquidatingValueHistory)
13
+ }
14
+
15
+ async getNetLiquidatingValue(accountNumber: string){
16
+ //Returns a list of account net liquidating value snapshots.
17
+ const netLiquidatingValue = await this.httpClient.getData(`/accounts/${accountNumber}/net-liq`)
18
+ return extractResponseData(netLiquidatingValue)
19
+ }
20
+ }
@@ -0,0 +1,80 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class OrderService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Orders: Allows an API client to view, filter, create, cancel and replace orders.
9
+ async postReconfirmOrder(accountNumber: string, orderId: number){
10
+ //Reconfirm an order
11
+ const reconfirmOrder = await this.httpClient.postData(`/accounts/${accountNumber}/orders/${orderId}/reconfirm`, {}, {})
12
+ return extractResponseData(reconfirmOrder)
13
+ }
14
+
15
+ async replacementOrderDryRun(accountNumber: string, orderId: number, replacementOrder: object){
16
+ //Runs through preflights for cancel-replace and edit without routing
17
+ const replacementOrderDryRun = await this.httpClient.postData(`/accounts/${accountNumber}/orders/${orderId}/dry-run`, replacementOrder, {})
18
+ return extractResponseData(replacementOrderDryRun)
19
+ }
20
+
21
+ async getOrder(accountNumber: string, orderId: number){
22
+ //Returns an order based on the orderId
23
+ const order = await this.httpClient.getData(`/accounts/${accountNumber}/orders/${orderId}`, {}, {})
24
+ return extractResponseData(order)
25
+ }
26
+
27
+ async cancelOrder(accountNumber: string, orderId: number){
28
+ //Requests order cancellation
29
+ const order = await this.httpClient.deleteData(`/accounts/${accountNumber}/orders/${orderId}`, {})
30
+ return extractResponseData(order)
31
+ }
32
+
33
+ async replaceOrder(accountNumber: string, orderId: number, replacementOrder : object){
34
+ //Replaces a live order with a new one. Subsequent fills of the original order will abort the replacement.
35
+ const order = await this.httpClient.putData(`/accounts/${accountNumber}/orders/${orderId}`, replacementOrder , {})
36
+ return extractResponseData(order)
37
+ }
38
+
39
+ async editOrder(accountNumber: string, orderId: number, order : object){
40
+ //Edit price and execution properties of a live order by replacement. Subsequent fills of the original order will abort the replacement.
41
+ const orderResponse = await this.httpClient.patchData(`/accounts/${accountNumber}/orders/${orderId}`, order , {})
42
+ return extractResponseData(orderResponse)
43
+ }
44
+
45
+ async getLiveOrders(accountNumber: string){
46
+ //Returns a list of live orders for the resource
47
+ const liveOrders = await this.httpClient.getData(`/accounts/${accountNumber}/orders/live`, {}, {})
48
+ return extractResponseData(liveOrders)
49
+ }
50
+
51
+ async getOrders(accountNumber: string, queryParams = {}){
52
+ //Returns a paginated list of the customer's orders (as identified by the provided authentication token) based on sort param. If no sort is passed in, it defaults to descending order.
53
+ const orders = await this.httpClient.getData(`/accounts/${accountNumber}/orders`, {}, queryParams)
54
+ return extractResponseData(orders)
55
+ }
56
+
57
+ async createOrder(accountNumber: string, order: object){
58
+ //Accepts a json document containing parameters to create an order for the client.
59
+ const orderResponse = await this.httpClient.postData(`/accounts/${accountNumber}/orders`, order , {})
60
+ return extractResponseData(orderResponse)
61
+ }
62
+
63
+ async postOrderDryRun(accountNumber: string, order: object){
64
+ //Accepts a json document containing parameters to create an order and then runs the prefights without placing the order.
65
+ const orderDryRun = await this.httpClient.postData(`/accounts/${accountNumber}/orders/dry-run`, order , {})
66
+ return extractResponseData(orderDryRun)
67
+ }
68
+
69
+ async getLiveOrdersForCustomer(customerId: string){
70
+ //Returns a list of live orders for the resource
71
+ const liveOrders = await this.httpClient.getData(`/customers/${customerId}/orders/live`, {}, {})
72
+ return extractResponseData(liveOrders)
73
+ }
74
+
75
+ async getCustomerOrders(customerId: string, queryParams = {}){
76
+ //Returns a paginated list of the customer's orders (as identified by the provided authentication token) based on sort param. If no sort is passed in, it defaults to descending order.
77
+ const customerOrders = await this.httpClient.getData(`/customers/${customerId}/orders`, {}, queryParams)
78
+ return extractResponseData(customerOrders)
79
+ }
80
+ }
@@ -0,0 +1,19 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class RiskParametersService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Accounts: Operations about accounts
9
+ async getEffectiveMarginRequirements(accountNumber: string, underlyingSymbol: string){
10
+ //Get effective margin requirements for account
11
+ const effectiveMarginRequirements = (await this.httpClient.getData(`/accounts/${accountNumber}/margin-requirements/${underlyingSymbol}/effective`, {}, {}))
12
+ return extractResponseData(effectiveMarginRequirements)
13
+ }
14
+ async getPositionLimit(accountNumber: string){
15
+ //Get the position limit
16
+ const positionLimit = (await this.httpClient.getData(`/accounts/${accountNumber}/position-limit`, {}, {}))
17
+ return extractResponseData(positionLimit)
18
+ }
19
+ }
@@ -0,0 +1,35 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class SessionService {
5
+ constructor(public httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ // Sessions: Allows an API client to interact with their session, or create a new one.
9
+ async login(usernameOrEmail: string, password: string, rememberMe = false) {
10
+ // Create a new user session.
11
+ const params = { login: usernameOrEmail, password, rememberMe }
12
+ const sessionResponse = await this.httpClient.postData('/sessions', params, {})
13
+ const sessionData = extractResponseData(sessionResponse)
14
+ this.httpClient.session.authToken = sessionData["session-token"]
15
+ return sessionData
16
+ }
17
+
18
+ async loginWithRememberToken(usernameOrEmail: string, rememberToken: string, rememberMe = false){
19
+ // Creates a session using the remember token.
20
+ const params = { login: usernameOrEmail, rememberToken, rememberMe }
21
+ const sessionData = extractResponseData(await this.httpClient.postData('/sessions', params, {}))
22
+ this.httpClient.session.authToken = sessionData["session-token"]
23
+ return sessionData
24
+ }
25
+
26
+ async validate() {
27
+ const response = await this.httpClient.postData('/sessions/validate', {}, {});
28
+ return extractResponseData(response);
29
+ }
30
+ async logout(){
31
+ const response = await this.httpClient.deleteData('/sessions', {});// added this for the integration tests?
32
+ this.httpClient.session.clear()
33
+ return extractResponseData(response);
34
+ }
35
+ }
@@ -0,0 +1,14 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class SymbolSearchService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Default
9
+ async getSymbolData(symbol: string){
10
+ //Returns an array of symbol data.
11
+ const symbolData = (await this.httpClient.getData(`/symbols/search/${symbol}`, {}, {}))
12
+ return extractResponseData(symbolData)
13
+ }
14
+ }
@@ -0,0 +1,65 @@
1
+ import TastytradeSession from "../models/tastytrade-session"
2
+ import axios from "axios"
3
+ import qs from 'qs'
4
+ import { recursiveDasherizeKeys } from "../utils/json-util"
5
+ import _ from 'lodash'
6
+
7
+ const ParamsSerializer = {
8
+ serialize: function (queryParams: object) {
9
+ return qs.stringify(queryParams, { arrayFormat: 'brackets' })
10
+ }
11
+ }
12
+
13
+ export default class TastytradeHttpClient{
14
+ public readonly session: TastytradeSession
15
+
16
+ constructor(private readonly baseUrl: string) {
17
+ this.session = new TastytradeSession()
18
+ }
19
+
20
+ private getDefaultHeaders(): any {
21
+ return {
22
+ "Content-Type": "application/json",
23
+ "Accept": "application/json",
24
+ "Authorization": this.session.authToken,
25
+ };
26
+ }
27
+
28
+ private async executeRequest(method: string, url: string, data: object = {}, headers: object = {}, params: object = {}) {
29
+ const dasherizedParams = recursiveDasherizeKeys(params)
30
+ const dasherizedData = recursiveDasherizeKeys(data)
31
+ const mergedHeaders = { ...headers, ...this.getDefaultHeaders() }
32
+
33
+ const config = _.omitBy({
34
+ method,
35
+ url,
36
+ baseURL: this.baseUrl,
37
+ data: dasherizedData,
38
+ headers: mergedHeaders,
39
+ params: dasherizedParams,
40
+ paramsSerializer: ParamsSerializer
41
+ }, _.isEmpty)
42
+
43
+ return axios.request(config)
44
+ }
45
+
46
+ async getData(url: string, headers: object = {}, queryParams: object = {}): Promise<any> {
47
+ return this.executeRequest('get', url, {}, headers, queryParams);
48
+ }
49
+
50
+ async postData(url: string, data: object, headers: object): Promise<any> {
51
+ return this.executeRequest('post', url, data, headers);
52
+ }
53
+
54
+ async putData(url: string, data: object, headers: object): Promise<any> {
55
+ return this.executeRequest('put', url, data, headers);
56
+ }
57
+
58
+ async patchData(url: string, data: object, headers: object): Promise<any> {
59
+ return this.executeRequest('patch', url, data, headers);
60
+ }
61
+
62
+ async deleteData(url: string, headers: object): Promise<any> {
63
+ return this.executeRequest('delete', url, headers);
64
+ }
65
+ }
@@ -0,0 +1,27 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class TransactionsService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Accounts: Operations about Accounts
9
+ async getTransaction(accountNumber: string, id: string){
10
+ //Retrieve a transaction by account number and ID
11
+ const symbolData = (await this.httpClient.getData(`/accounts/${accountNumber}/transactions/${id}`, {}, {}))
12
+ return extractResponseData(symbolData)
13
+ }
14
+ async getTotalFees(accountNumber: string){
15
+ //Return the total fees for an account for a given day
16
+ const totalFees = (await this.httpClient.getData(`/accounts/${accountNumber}/transactions/total-fees`, {}, {}))
17
+ return extractResponseData(totalFees)
18
+ }
19
+
20
+ //Transactions: Operations about transactions
21
+ async getAccountTransactions(accountNumber: string, queryParams = {}){
22
+ //Returns a paginated list of the account's transactions (as identified by the provided authentication token)
23
+ //based on sort param. If no sort is passed in, it defaults to descending order.
24
+ const accountTransactions = (await this.httpClient.getData(`/accounts/${accountNumber}/transactions`, {}, queryParams))
25
+ return extractResponseData(accountTransactions)
26
+ }
27
+ }
@@ -0,0 +1,58 @@
1
+ import extractResponseData from "../utils/response-util";
2
+ import TastytradeHttpClient from "./tastytrade-http-client";
3
+
4
+ export default class WatchlistsService {
5
+ constructor(private httpClient: TastytradeHttpClient) {
6
+ }
7
+
8
+ //Pairs Watchlists: Allows an API client to fetch pairs watchlists.
9
+ async getPairsWatchlists(){
10
+ //Returns a list of all tastyworks pairs watchlists
11
+ const pairsWatchlists = await this.httpClient.getData(`/pairs-watchlists`, {}, {})
12
+ return extractResponseData(pairsWatchlists)
13
+ }
14
+ async getPairsWatchlist(pairsWatchlistName: string){
15
+ //Returns a requested tastyworks pairs watchlist
16
+ const pairsWatchlist = await this.httpClient.getData(`/pairs-watchlists/${pairsWatchlistName}`, {}, {})
17
+ return extractResponseData(pairsWatchlist)
18
+ }
19
+
20
+ //Public Watchlists: Allows an API client to fetch tastyworks watchlists.
21
+ async getPublicWatchlists(countsOnly = false){
22
+ //Returns a list of all tastyworks watchlists
23
+ const publicWatchlists = await this.httpClient.getData(`/public-watchlists`, {}, {'counts-only': countsOnly })
24
+ return extractResponseData(publicWatchlists)
25
+ }
26
+ async getPublicWatchlist(watchlistName: string){
27
+ //Returns a requested tastyworks watchlist
28
+ const publicWatchlist = await this.httpClient.getData(`/public-watchlists/${watchlistName}`, {}, {})
29
+ return extractResponseData(publicWatchlist)
30
+ }
31
+
32
+ //User Watchlists: Allows an API client to fetch a user's watchlists.
33
+ async createAccountWatchlist(watchlist: object){
34
+ //Create an account watchlist
35
+ const accountWatchlist = await this.httpClient.postData(`/watchlists`, watchlist, {})
36
+ return extractResponseData(accountWatchlist)
37
+ }
38
+ async getAllWatchlists(){
39
+ //Returns a list of all watchlists for the given account
40
+ const allWatchlists = await this.httpClient.getData(`/watchlists`, {}, {})
41
+ return extractResponseData(allWatchlists)
42
+ }
43
+ async replaceWatchlist(watchlistName: string, replacementWatchlist: object){
44
+ //Replace all properties of an account watchlist
45
+ const watchlist = await this.httpClient.putData(`/watchlists/${watchlistName}`, replacementWatchlist , {})
46
+ return extractResponseData(watchlist)
47
+ }
48
+ async deleteWatchlist(watchlistName: string){
49
+ //Delete a watchlist for the given account
50
+ const watchlist = await this.httpClient.deleteData(`/watchlists/${watchlistName}`, {})
51
+ return extractResponseData(watchlist)
52
+ }
53
+ async getSingleWatchlist(watchlistName: string){
54
+ //Returns a requested account watchlist
55
+ const singleWatchlist = await this.httpClient.getData(`/watchlists/${watchlistName}`, {}, {})
56
+ return extractResponseData(singleWatchlist)
57
+ }
58
+ }
@@ -0,0 +1,65 @@
1
+ import TastytradeHttpClient from "./services/tastytrade-http-client"
2
+ import { AccountStreamer, STREAMER_STATE, Disposer, StreamerStateObserver } from './account-streamer'
3
+ import QuoteStreamer from "./quote-streamer"
4
+
5
+ //Services:
6
+ import SessionService from "./services/session-service"
7
+ import AccountStatusService from "./services/account-status-service"
8
+ import AccountsAndCustomersService from "./services/accounts-and-customers-service"
9
+ import BalancesAndPositionsService from "./services/balances-and-positions-service"
10
+ import InstrumentsService from "./services/instruments-service"
11
+ import MarginRequirementsService from "./services/margin-requirements-service"
12
+ import MarketMetricsService from "./services/market-metrics-service"
13
+ import NetLiquidatingValueHistoryService from "./services/net-liquidating-value-history-service"
14
+ import OrderService from "./services/orders-service"
15
+ import RiskParametersService from "./services/risk-parameters-service"
16
+ import SymbolSearchService from "./services/symbol-search-service"
17
+ import TransactionsService from "./services/transactions-service"
18
+ import WatchlistsService from "./services/watchlists-service"
19
+ import TastytradeSession from "./models/tastytrade-session"
20
+
21
+ export default class TastytradeClient {
22
+ public readonly httpClient: TastytradeHttpClient
23
+
24
+ public readonly accountStreamer: AccountStreamer
25
+
26
+ public readonly sessionService: SessionService
27
+ public readonly accountStatusService: AccountStatusService
28
+ public readonly accountsAndCustomersService: AccountsAndCustomersService
29
+ public readonly balancesAndPositionsService: BalancesAndPositionsService
30
+ public readonly instrumentsService: InstrumentsService
31
+ public readonly marginRequirementsService: MarginRequirementsService
32
+ public readonly marketMetricsService: MarketMetricsService
33
+ public readonly netLiquidatingValueHistoryService: NetLiquidatingValueHistoryService
34
+ public readonly orderService: OrderService
35
+ public readonly riskParametersService: RiskParametersService
36
+ public readonly symbolSearchService: SymbolSearchService
37
+ public readonly transactionsService: TransactionsService
38
+ public readonly watchlistsService: WatchlistsService
39
+
40
+ constructor(readonly baseUrl: string, readonly accountStreamerUrl: string) {
41
+ this.httpClient = new TastytradeHttpClient(baseUrl)
42
+ this.accountStreamer = new AccountStreamer(accountStreamerUrl, this.session)
43
+
44
+ this.sessionService = new SessionService(this.httpClient)
45
+ this.accountStatusService = new AccountStatusService(this.httpClient)
46
+ this.accountsAndCustomersService = new AccountsAndCustomersService(this.httpClient)
47
+ this.balancesAndPositionsService = new BalancesAndPositionsService(this.httpClient)
48
+ this.instrumentsService = new InstrumentsService(this.httpClient)
49
+ this.marginRequirementsService = new MarginRequirementsService(this.httpClient)
50
+ this.marketMetricsService = new MarketMetricsService(this.httpClient)
51
+ this.netLiquidatingValueHistoryService = new NetLiquidatingValueHistoryService(this.httpClient)
52
+ this.orderService = new OrderService(this.httpClient)
53
+ this.riskParametersService = new RiskParametersService(this.httpClient)
54
+ this.symbolSearchService = new SymbolSearchService(this.httpClient)
55
+ this.transactionsService = new TransactionsService(this.httpClient)
56
+ this.watchlistsService = new WatchlistsService(this.httpClient)
57
+ }
58
+
59
+ get session(): TastytradeSession {
60
+ return this.httpClient.session
61
+ }
62
+ }
63
+
64
+ export { QuoteStreamer }
65
+ export { AccountStreamer, STREAMER_STATE, Disposer, StreamerStateObserver }
@@ -0,0 +1,44 @@
1
+ import _ from 'lodash'
2
+
3
+ export type BasicJsonValue = boolean | number | string | null | undefined
4
+ export type JsonValue = BasicJsonValue | JsonArray | JsonMap
5
+ export interface JsonMap {
6
+ [key: string]: JsonValue | undefined
7
+ }
8
+ export type JsonArray = JsonValue[]
9
+
10
+ export class JsonBuilder {
11
+ public constructor(public readonly json: JsonMap = {}) {}
12
+
13
+ public add(key: string, value: JsonValue, serializeEmpty = false): this {
14
+ if ((_.isNil(value) || value === '') && !serializeEmpty) {
15
+ return this
16
+ }
17
+
18
+ this.json[key] = value
19
+ return this
20
+ }
21
+ }
22
+
23
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
+ export function recursiveDasherizeKeys(body: any) {
25
+ let dasherized = _.mapKeys(body, (_value, key) => dasherize(key))
26
+
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ dasherized = _.mapValues(dasherized, (value: any) => {
29
+ if (_.isPlainObject(value)) {
30
+ return recursiveDasherizeKeys(value)
31
+ }
32
+
33
+ return value
34
+ })
35
+
36
+ return dasherized
37
+ }
38
+
39
+ export function dasherize(target: string): string {
40
+ // prettier-ignore
41
+ return target
42
+ .replace(/([A-Z])/g, (_match, p1: string, _offset, _whole) => `-${p1.toLowerCase()}`)
43
+ .replace(/\s/g, '-')
44
+ }
@@ -0,0 +1,15 @@
1
+ import _ from 'lodash'
2
+
3
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
+ export default function extractResponseData(httpResponse: any){
5
+ if (_.has(httpResponse, 'data.data.items')) {
6
+ return _.get(httpResponse, 'data.data.items')
7
+ } else if (_.has(httpResponse, 'data.data')){
8
+ return _.get(httpResponse, 'data.data')
9
+ }else{
10
+ return httpResponse
11
+ }
12
+ }
13
+
14
+ // add login parser here
15
+ // create unit tests for login parser, extractreponsedata
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@tastytrade/api",
3
+ "version": "0.0.1",
4
+ "main": "dist/tastytrade-api.js",
5
+ "typings": "dist/tastytrade-api.d.ts",
6
+ "repository": "https://github.com/tastytrade/tastytrade-api-js",
7
+ "license": "MIT",
8
+ "description": "Typescript impelementation of tastytrade api",
9
+ "scripts": {
10
+ "build": "tsc -p tsconfig.json",
11
+ "test": "jest -i --restoreMocks",
12
+ "unit-test": "jest --testPathPattern=tests/unit",
13
+ "integration-test": "jest --testPathPattern=tests/integration",
14
+ "lint": "eslint lib/** tests/**"
15
+ },
16
+ "dependencies": {
17
+ "@dxfeed/api": "^1.1.0",
18
+ "@types/lodash": "^4.14.182",
19
+ "@types/qs": "^6.9.7",
20
+ "axios": "^1.3.4",
21
+ "lodash": "^4.17.21",
22
+ "qs": "^6.11.1"
23
+ },
24
+ "devDependencies": {
25
+ "@types/jest": "^29.5.0",
26
+ "@types/node": "17.0.27",
27
+ "@typescript-eslint/eslint-plugin": "^5.57.1",
28
+ "@typescript-eslint/parser": "^5.57.1",
29
+ "dotenv": "^16.0.3",
30
+ "eslint": "^8.14.0",
31
+ "jest": "^29.5.0",
32
+ "ts-jest": "^29.0.5",
33
+ "typescript": "4.6.3"
34
+ }
35
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,71 @@
1
+ {
2
+ "compilerOptions": {
3
+ /* Visit https://aka.ms/tsconfig.json to read more about this file */
4
+
5
+ /* Basic Options */
6
+ // "incremental": true, /* Enable incremental compilation */
7
+ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
8
+ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
9
+ // "lib": [], /* Specify library files to be included in the compilation. */
10
+ "allowJs": true, /* Allow javascript files to be compiled. */
11
+ // "checkJs": true, /* Report errors in .js files. */
12
+ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
13
+ "declaration": true, /* Generates corresponding '.d.ts' file. */
14
+ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
15
+ // "sourceMap": true, /* Generates corresponding '.map' file. */
16
+ // "outFile": "./", /* Concatenate and emit output to single file. */
17
+ "outDir": "./dist", /* Redirect output structure to the directory. */
18
+ // "rootDir": "./lib", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
19
+ // "composite": true, /* Enable project compilation */
20
+ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
21
+ // "removeComments": true, /* Do not emit comments to output. */
22
+ // "noEmit": true, /* Do not emit outputs. */
23
+ // "importHelpers": true, /* Import emit helpers from 'tslib'. */
24
+ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
25
+ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
26
+
27
+ /* Strict Type-Checking Options */
28
+ "strict": true, /* Enable all strict type-checking options. */
29
+ // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
30
+ // "strictNullChecks": true, /* Enable strict null checks. */
31
+ // "strictFunctionTypes": true, /* Enable strict checking of function types. */
32
+ // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
33
+ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
34
+ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
35
+ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
36
+
37
+ /* Additional Checks */
38
+ // "noUnusedLocals": true, /* Report errors on unused locals. */
39
+ // "noUnusedParameters": true, /* Report errors on unused parameters. */
40
+ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
41
+ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
42
+
43
+ /* Module Resolution Options */
44
+ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
45
+ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
46
+ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
47
+ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
48
+ // "typeRoots": [], /* List of folders to include type definitions from. */
49
+ // "types": [], /* Type declaration files to be included in compilation. */
50
+ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
51
+ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
52
+ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
53
+ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
54
+
55
+ /* Source Map Options */
56
+ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
57
+ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
58
+ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
59
+ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
60
+
61
+ /* Experimental Options */
62
+ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
63
+ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
64
+
65
+ /* Advanced Options */
66
+ "skipLibCheck": true, /* Skip type checking of declaration files. */
67
+ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
68
+ },
69
+ "include": ["lib/**/*"],
70
+ "exclude": ["node_modules", "dist", "tests/**/*", "examples"]
71
+ }