Skip to content

Commit

Permalink
fix project exports
Browse files Browse the repository at this point in the history
  • Loading branch information
felipecsl committed Feb 22, 2025
1 parent 7e50f3f commit 6876d17
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 266 deletions.
22 changes: 1 addition & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,7 @@
"types": "dist/web.d.ts",
"type": "module",
"exports": {
"./wsJsonServer": "./dist/server/wsJsonServer.js",
"./wsJsonClient": "./dist/client/wsJsonClient.js",
"./realWsJsonClient": "./dist/client/realWsJsonClient.js",
"./mockWsJsonClient": "./dist/client/mockWsJsonClient.js",
"./alertTypes": "./dist/client/types/alertTypes.js",
"./tdaWsJsonTypes": "./dist/client/tdaWsJsonTypes.js",
"./wsJsonClientAuth": "./dist/client/wsJsonClientAuth.js",
"./wsJsonClientProxy": "./dist/client/wsJsonClientProxy.js",
"./messageTypeHelpers": "./dist/client/messageTypeHelpers.js",
"./chartMessageHandler": "./dist/client/services/chartMessageHandler.js",
"./quotesMessageHandler": "./dist/client/services/quotesMessageHandler.js",
"./positionsMessageHandler": "./dist/client/services/positionsMessageHandler.js",
"./placeOrderMessageHandler": "./dist/client/services/placeOrderMessageHandler.js",
"./createAlertMessageHandler": "./dist/client/services/createAlertMessageHandler.js",
"./orderEventsMessageHandler": "./dist/client/services/orderEventsMessageHandler.js",
"./optionSeriesMessageHandler": "./dist/client/services/optionSeriesMessageHandler.js",
"./optionQuotesMessageHandler": "./dist/client/services/optionQuotesMessageHandler.js",
"./userPropertiesMessageHandler": "./dist/client/services/userPropertiesMessageHandler.js",
"./instrumentSearchMessageHandler": "./dist/client/services/instrumentSearchMessageHandler.js",
"./optionSeriesQuotesMessageHandler": "./dist/client/services/optionSeriesQuotesMessageHandler.js",
"./optionChainDetailsMessageHandler": "./dist/client/services/optionChainDetailsMessageHandler.js"
".": "./dist/index.js"
},
"scripts": {
"prepublish": "tsc -p tsconfig.json",
Expand Down
44 changes: 9 additions & 35 deletions src/client/realWsJsonClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import debug from "debug";
import WebSocket from "isomorphic-ws";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import {
BufferedIterator,
deferredWrap,
Expand Down Expand Up @@ -103,7 +102,7 @@ const messageHandlers: WebSocketApiMessageHandler<never>[] = [
new GetWatchlistMessageHandler(),
];

export default class RealWsJsonClient implements WsJsonClient {
export class RealWsJsonClient implements WsJsonClient {
private readonly genericHandler = new GenericIncomingMessageHandler();
private buffer = new BufferedIterator<ParsedPayloadResponse>();
private iterator = new MulticastIterator(this.buffer);
Expand Down Expand Up @@ -133,6 +132,14 @@ export default class RealWsJsonClient implements WsJsonClient {
private readonly responseParser = new ResponseParser(this.genericHandler)
) {}

get accessToken() {
return this.credentials.accessToken;
}

get refreshToken() {
return this.credentials.refreshToken;
}

async authenticateWithAccessToken({
accessToken,
refreshToken,
Expand Down Expand Up @@ -369,37 +376,6 @@ export default class RealWsJsonClient implements WsJsonClient {
this.socket?.send(msg);
}

private updateDotEnvCredentials() {
const {
credentials: { accessToken, refreshToken },
} = this;
const suffix = process.env.NODE_ENV ? `.${process.env.NODE_ENV}` : "";
const envPath = `.env${suffix}`;
let envContent = "";
if (existsSync(envPath)) {
envContent = readFileSync(envPath, "utf-8");
// Remove any existing token lines
envContent = envContent
.split("\n")
.filter(
(line) =>
!line.startsWith("TOS_ACCESS_TOKEN=") &&
!line.startsWith("TOS_REFRESH_TOKEN=")
)
.join("\n");
}

// Append the new token values
const tokenLines = [
`TOS_ACCESS_TOKEN=${accessToken}`,
`TOS_REFRESH_TOKEN=${refreshToken}`,
].join("\n");

// Ensure there's a newline between existing content and new tokens
const newContent = envContent.trim() + "\n" + tokenLines + "\n";
writeFileSync(envPath, newContent);
}

private handleSchwabLoginResponse(
message: RawLoginResponse,
resolve: (value: RawLoginResponseBody) => void,
Expand All @@ -418,7 +394,6 @@ export default class RealWsJsonClient implements WsJsonClient {
if (loginResponse.refreshToken) {
this.credentials.refreshToken = loginResponse.refreshToken;
}
this.updateDotEnvCredentials();
resolve(body);
} else {
this.state = ChannelState.ERROR;
Expand All @@ -437,7 +412,6 @@ export default class RealWsJsonClient implements WsJsonClient {
const [{ body }] = message.payload;
if (loginResponse.successful) {
this.state = ChannelState.CONNECTED;
this.updateDotEnvCredentials();
resolve(body);
} else {
this.state = ChannelState.ERROR;
Expand Down
42 changes: 9 additions & 33 deletions src/client/services/chartMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,20 @@ import WebSocketApiMessageHandler, {
newPayload,
} from "./webSocketApiMessageHandler.js";

type RawPayloadResponseChartData = {
candles: {
closes: number[];
highs: number[];
lows: number[];
opens: number[];
timestamps: number[];
volumes: number[];
};
symbol: string;
export type ChartCandles = {
closes: number[];
highs: number[];
lows: number[];
opens: number[];
timestamps: number[];
volumes: number[];
};

export type RawPayloadResponseChart =
| RawPayloadResponseChartData
| {
patches: {
op: string;
path: string;
value: RawPayloadResponseChartData;
}[];
};

export type ChartResponse = {
candles: PriceItem[];
export type RawPayloadResponseChart = {
candles: ChartCandles;
symbol: string;
service: "chart";
};

export type OHLC = {
open: number;
high: number;
low: number;
close: number;
volume: number;
};

export type PriceItem = { date: Date } & OHLC;

export type ChartRequestParams = {
symbol: string;
timeAggregation: string;
Expand Down
12 changes: 2 additions & 10 deletions src/client/services/instrumentSearchMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,12 @@ import { ApiService } from "./apiService.js";
import WebSocketApiMessageHandler from "./webSocketApiMessageHandler.js";

export type RawPayloadResponseInstrumentSearch = {
instruments: {
symbol: string;
displaySymbol: string;
description: string;
}[];
instruments: InstrumentSearchMatch[];
};

export type InstrumentSearchMatch = {
symbol: string;
displaySymbol: string;
description: string;
};

Expand All @@ -21,11 +18,6 @@ type InstrumentSearchRequest = {
limit?: number;
};

export type InstrumentSearchResponse = {
instruments: InstrumentSearchMatch[];
service: "instrument_search";
};

export default class InstrumentSearchMessageHandler
implements WebSocketApiMessageHandler<InstrumentSearchRequest>
{
Expand Down
5 changes: 0 additions & 5 deletions src/client/services/optionChainDetailsMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ export type RawOptionChainDetailsResponse = {
optionSeries: OptionChainDetailsItem[];
};

export type OptionChainDetailsResponse = {
seriesDetails: OptionChainDetailsItem[];
service: "option_chain/get";
};

export type OptionChainDetailsItem = {
expiration: string; // eg "16 JUN 23"
expirationString: string; // eg "16 JUN 23 (100)"
Expand Down
38 changes: 10 additions & 28 deletions src/client/services/optionQuotesMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,16 @@ import WebSocketApiMessageHandler, {
newPayload,
} from "./webSocketApiMessageHandler.js";

export type OptionQuotesRequestParams = {
underlyingSymbol: string;
seriesNames: string[];
minStrike: number;
maxStrike: number;
export type RawOptionQuotesSnapshotBodyResponse = {
exchanges: string[];
items: OptionQuoteItem[];
};

export type OptionQuoteItem = {
symbol: string;
values: OptionQuoteItemValue;
};

export type OptionQuotesResponse =
| OptionQuotesSnapshotResponse
| OptionQuotesPatchResponse;

export type OptionQuotesSnapshotResponse = {
items: OptionQuoteItem[];
service: "quotes/options";
};

export type OptionQuotesPatchResponse = {
patches: {
op: string;
path: string;
value:
| {
exchanges: string[];
items: OptionQuoteItem[];
}
| number;
}[];
service: "quotes/options";
};

export type OptionQuoteItemValue = {
ASK?: number;
BID?: number;
Expand All @@ -48,6 +23,13 @@ export type OptionQuoteItemValue = {
VOLUME?: number;
};

export type OptionQuotesRequestParams = {
underlyingSymbol: string;
seriesNames: string[];
minStrike: number;
maxStrike: number;
};

export default class OptionQuotesMessageHandler
implements WebSocketApiMessageHandler<OptionQuotesRequestParams>
{
Expand Down
41 changes: 14 additions & 27 deletions src/client/services/optionSeriesMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,24 @@ import { newRandomId } from "../util.js";
import { ApiService } from "./apiService.js";
import WebSocketApiMessageHandler from "./webSocketApiMessageHandler.js";

export type RawOptionSeriesResponse = {
series: {
// symbol
underlying: string;
// "19 JAN 24 100"
name: string;
spc: number;
multiplier: number;
// eg "REGULAR"
expirationStyle: string;
isEuropean: boolean;
// eg "2024-01-20T12:00:00Z"
expiration: string;
lastTradeDate: string;
settlementType: string; // likely AM or PM
}[];
};

export type OptionChainResponse = {
series: OptionChainItem[];
service: "optionSeries";
};

export type OptionChainItem = {
export type OptionSeriesItem = {
// symbol
underlying: string;
// "19 JAN 24 100"
name: string;
spc: number;
multiplier: number;
// eg "REGULAR"
expirationStyle: string;
isEuropean: boolean;
lastTradeDate: Date;
expiration: Date;
settlementType: string;
// eg "2024-01-20T12:00:00Z"
expiration: string;
lastTradeDate: string;
settlementType: string; // likely AM or PM
};

export type RawOptionSeriesResponse = {
series: OptionSeriesItem[];
};

export default class OptionSeriesMessageHandler
Expand Down
14 changes: 0 additions & 14 deletions src/client/services/optionSeriesQuotesMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,10 @@ export type OptionSeriesQuote = {
};
};

export type OptionSeriesQuotesPatchResponse = {
patches: {
op: string;
path: string;
value: number | { series: OptionSeriesQuote[] };
}[];
service: "optionSeries/quotes";
};

export type OptionSeriesQuotesSnapshotResponse = {
series: OptionSeriesQuote[];
service: "optionSeries/quotes";
};

export type OptionSeriesQuotesResponse =
| OptionSeriesQuotesSnapshotResponse
| OptionSeriesQuotesPatchResponse;

export default class OptionSeriesQuotesMessageHandler
implements WebSocketApiMessageHandler<string>
{
Expand Down
24 changes: 0 additions & 24 deletions src/client/services/positionsMessageHandler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { RawPayloadRequest } from "../tdaWsJsonTypes.js";
import { DeepPartial } from "../util.js";
import { ApiService } from "./apiService.js";
import WebSocketApiMessageHandler, {
newPayload,
Expand Down Expand Up @@ -52,29 +51,6 @@ export interface Instrument {
underlyingLastPrice?: number;
}

export interface AccountPosition {
shortQuantity: number;
averagePrice: number;
currentDayProfitLoss: number;
currentDayProfitLossPercentage: number;
longQuantity: number;
settledLongQuantity: number;
settledShortQuantity: number;
instrument: Instrument;
marketValue: number;
maintenanceRequirement?: number;
lastPrice: number;
// this is a purely presentation related field that was added here so we can keep track of the
// previous last price and determine whether the price is going up or down. That way we can color
// animate price updates similarly to how TOS works.
previousPrice?: number;
}

export type PositionsResponse = {
positions: DeepPartial<AccountPosition>[];
service: "positions";
};

export default class PositionsMessageHandler
implements WebSocketApiMessageHandler<string>
{
Expand Down
Loading

0 comments on commit 6876d17

Please sign in to comment.