Skip to content

Commit

Permalink
Add RecommendationBySymbolModule
Browse files Browse the repository at this point in the history
  • Loading branch information
eddie-atkinson committed Jun 4, 2024
1 parent df0633d commit 589fcf0
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/modules/recommendationsBySymbol.tb.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import recommendationsBySymbol from "./recommendationsBySymbol.tb.js";
import testSymbols from "../../tests/testSymbols.js";
import testYf from "../../tests/testYf.js";

const yf = testYf({ recommendationsBySymbol });

describe("recommendationsBySymbol", () => {
// make sure it passes validation for some symbols
describe("passes validation", () => {
const symbols = testSymbols({
skip: [
// 404 Not Found
"ADH",
"BTC-USD",
"GC=F",
"APS.AX",
],
});

it.each(symbols)("for symbol '%s'", async (symbol) => {
const devel = `recommendationsBySymbol-${symbol}.json`;
await yf.recommendationsBySymbol(symbol, {}, { devel });
});
});

// make sure it passes validation for multiple symbols
it(`passes validation for multiple symbols ("AAPL" and "BMW.DE")`, async () => {
const devel = `recommendationsBySymbol-AAPL-BMW.DE.json`;
await yf.recommendationsBySymbol(["AAPL", "BMW.DE"], {}, { devel });
});

it("returns an array for an array", async () => {
const devel = "recommendationsBySymbol-AAPL-BMW.DE.json";
const results = await yf.recommendationsBySymbol(
["AAPL", "BMW.DE"],
{},
{ devel }
);
expect(results.length).toBe(2);
expect(results[0].symbol).toBe("AAPL");
expect(results[1].symbol).toBe("BMW.DE");
});

it("returns single for a string", async () => {
const devel = "recommendationsBySymbol-AAPL.json";
const result = await yf.recommendationsBySymbol("AAPL", {}, { devel });
expect(Array.isArray(result)).toBe(false);
expect(result.symbol).toBe("AAPL");
});

if (process.env.FETCH_DEVEL !== "nocache")
it("throws on weird result", () => {
const devel = "weirdJsonResult.fake.json";
return expect(
yf.recommendationsBySymbol("AAPL", {}, { devel })
).rejects.toThrow(/^Unexpected result/);
});
});
106 changes: 106 additions & 0 deletions src/modules/recommendationsBySymbol.tb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Static, Type } from "@sinclair/typebox";
import type {
ModuleOptions,
ModuleOptionsWithValidateFalse,
ModuleOptionsWithValidateTrue,
ModuleThis,
} from "../lib/moduleCommon.js";
import { YahooNumber } from "../lib/yahooFinanceTypes.js";

const RecommendationsBySymbolResponse = Type.Object(
{
recommendedSymbols: Type.Array(
Type.Object(
{
score: YahooNumber, // 0.1927
symbol: Type.String(), // "BMW.DE"
},
{
additionalProperties: Type.Any(),
}
)
),
symbol: Type.String(),
},
{
additionalProperties: Type.Any(),
}
);

const RecommendationsBySymbolResponseArray = Type.Array(
RecommendationsBySymbolResponse
);

const RecommendationsBySymbolOptions = Type.Object({});

type RecommendationsBySymbolResponse = Static<
typeof RecommendationsBySymbolResponse
>;

type RecommendationsBySymbolOptions = Static<
typeof RecommendationsBySymbolOptions
>;

type RecommendationsBySymbolResponseArray = Static<
typeof RecommendationsBySymbolResponseArray
>;

const queryOptionsDefaults: RecommendationsBySymbolOptions = {};

export default function recommendationsBySymbol(
this: ModuleThis,
query: string,
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptionsWithValidateTrue
): Promise<RecommendationsBySymbolResponse>;

export default function recommendationsBySymbol(
this: ModuleThis,
query: string | string[],
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptionsWithValidateTrue
): Promise<RecommendationsBySymbolResponseArray>;

export default function recommendationsBySymbol(
this: ModuleThis,
query: string | string[],
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptionsWithValidateFalse
): Promise<any>;

export default function recommendationsBySymbol(
this: ModuleThis,
query: string | string[],
queryOptionsOverrides?: RecommendationsBySymbolOptions,
moduleOptions?: ModuleOptions
): Promise<any> {
const symbols = typeof query === "string" ? query : query.join(",");

return this._moduleExecTypebox({
moduleName: "recommendationsBySymbol",

query: {
url:
"https://${YF_QUERY_HOST}/v6/finance/recommendationsbysymbol/" +
symbols,
schema: RecommendationsBySymbolOptions,
defaults: queryOptionsDefaults,
overrides: queryOptionsOverrides,
},

result: {
schema: RecommendationsBySymbolResponseArray,
transformWith(result: any) {
if (!result.finance)
throw new Error("Unexpected result: " + JSON.stringify(result));
return result.finance.result;
},
},

moduleOptions,
}).then((results: RecommendationsBySymbolResponseArray) => {
return typeof query === "string"
? (results[0] as RecommendationsBySymbolResponse)
: (results as RecommendationsBySymbolResponseArray);
});
}

0 comments on commit 589fcf0

Please sign in to comment.