Skip to content

Commit 43ebaa4

Browse files
authored
feat(setGlobalConfig): add setGlobalConfig function (#133)
* feat(setGlobalConfig): add setGlobalConfig function * chore: remove unneeded todo note * docs(setGlobalConfig): add docs for setGlobalConfig * fix(setGlobalConfig): merge multiple levels deep * Merges config multiple levels deep. Also fixes docs and tests.
1 parent bc20d16 commit 43ebaa4

10 files changed

+282
-8
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ symbol, topHoldings, upgradeDowngradeHistory),
7070
[coming soon](https://github.com/gadicc/node-yahoo-finance2/issues/8).
7171

7272
Extras: [`quoteCombine`](./docs/other/quoteCombine.md).
73+
Utils: [`setGlobalConfig`](./docs/utils/setGlobalConfig.md).
7374

7475
See the [Full Documentation](./docs/README.md).
7576

docs/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
1. [Common Options](#common-options)
66
1. [Modules](#modules)
77
1. [Other Methods](#other)
8+
1. [Util Methods](#utils)
89
1. [Error Handling](#error-handling)
910
1. [Validation](./validation.md)
1011
1. [Concurrency](./concurrency.md)
@@ -44,6 +45,9 @@ const result = await yahooFinance.module(query, queryOpts, moduleOpts);
4445

4546
1. [quoteCombine](./other/quoteCombine.md) - debounce and combine multiple quote calls.
4647

48+
<a name="utils"></a>
49+
1. [setGlobalConfig](./utils/setGlobalConfig.md) - set global config options.
50+
4751
<a name="error-handling"></a>
4852
## Error Handling
4953

docs/other/setGlobalConfig.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# setGlobalConfig
2+
3+
This util function sets global config options, merging with the defaults. These options are then the defaults used for every request. It is the **recommended** way of setting global config. Setting global config directly is not recommended.
4+
5+
## Usage:
6+
7+
```js
8+
import yahooFinance from 'yahoo-finance2';
9+
10+
yahooFinance.setGlobalConfig({
11+
queue: {
12+
// some options here
13+
}
14+
});
15+
```
16+
17+
Notes:
18+
19+
- Config provided to this function is validated.
20+
21+
- Options are merged infinite levels deep:
22+
```js
23+
import yahooFinance from 'yahoo-finance2';
24+
25+
yahooFinance.setGlobalConfig({
26+
queue: {
27+
concurrency: 2,
28+
// timeout is still set
29+
}
30+
});
31+
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"scripts": {
2929
"coverage": "jest --coverage",
3030
"lint": "eslint . --ext .js,.ts",
31-
"schema": "ts-json-schema-generator -f tsconfig.json -p 'src/modules/**/*.ts' -t '*' | node bin/schema-tweak.js > schema.json",
31+
"schema": "ts-json-schema-generator -f tsconfig.json -p 'src/{modules,typings}/**/*.ts' -t '*' | node bin/schema-tweak.js > schema.json",
3232
"generateSchema": "yarn schema",
3333
"prepublishOnly": "tsc && yarn generateSchema",
3434
"test": "jest",

schema.json

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2074,6 +2074,18 @@
20742074
],
20752075
"type": "object"
20762076
},
2077+
"Options": {
2078+
"additionalProperties": false,
2079+
"properties": {
2080+
"queue": {
2081+
"$ref": "#/definitions/QueueOptions"
2082+
},
2083+
"validation": {
2084+
"$ref": "#/definitions/ValidationOptions"
2085+
}
2086+
},
2087+
"type": "object"
2088+
},
20772089
"OptionsOptions": {
20782090
"additionalProperties": false,
20792091
"properties": {
@@ -2188,6 +2200,18 @@
21882200
],
21892201
"type": "object"
21902202
},
2203+
"PartialOptions": {
2204+
"additionalProperties": false,
2205+
"properties": {
2206+
"queue": {
2207+
"$ref": "#/definitions/QueueOptions"
2208+
},
2209+
"validation": {
2210+
"$ref": "#/definitions/ValidationOptions"
2211+
}
2212+
},
2213+
"type": "object"
2214+
},
21912215
"PeriodRange": {
21922216
"additionalProperties": false,
21932217
"properties": {
@@ -2380,6 +2404,112 @@
23802404
],
23812405
"type": "object"
23822406
},
2407+
"Queue": {
2408+
"additionalProperties": false,
2409+
"properties": {
2410+
"_queue": {
2411+
"items": {
2412+
"additionalProperties": false,
2413+
"properties": {
2414+
"func": {
2415+
"additionalProperties": false,
2416+
"properties": {
2417+
"arguments": {},
2418+
"caller": {
2419+
"$ref": "#/definitions/interface-2073358172-9814-11278-2073358172-0-212312"
2420+
},
2421+
"length": {
2422+
"yahooFinanceType": "number"
2423+
},
2424+
"prototype": {}
2425+
},
2426+
"required": [
2427+
"prototype",
2428+
"length",
2429+
"arguments",
2430+
"caller"
2431+
],
2432+
"type": "object"
2433+
},
2434+
"reject": {
2435+
"additionalProperties": false,
2436+
"properties": {
2437+
"arguments": {},
2438+
"caller": {
2439+
"$ref": "#/definitions/interface-2073358172-9814-11278-2073358172-0-212312"
2440+
},
2441+
"length": {
2442+
"yahooFinanceType": "number"
2443+
},
2444+
"prototype": {}
2445+
},
2446+
"required": [
2447+
"prototype",
2448+
"length",
2449+
"arguments",
2450+
"caller"
2451+
],
2452+
"type": "object"
2453+
},
2454+
"resolve": {
2455+
"additionalProperties": false,
2456+
"properties": {
2457+
"arguments": {},
2458+
"caller": {
2459+
"$ref": "#/definitions/interface-2073358172-9814-11278-2073358172-0-212312"
2460+
},
2461+
"length": {
2462+
"yahooFinanceType": "number"
2463+
},
2464+
"prototype": {}
2465+
},
2466+
"required": [
2467+
"prototype",
2468+
"length",
2469+
"arguments",
2470+
"caller"
2471+
],
2472+
"type": "object"
2473+
}
2474+
},
2475+
"required": [
2476+
"func",
2477+
"resolve",
2478+
"reject"
2479+
],
2480+
"type": "object"
2481+
},
2482+
"type": "array"
2483+
},
2484+
"_running": {
2485+
"yahooFinanceType": "number"
2486+
},
2487+
"concurrency": {
2488+
"yahooFinanceType": "number"
2489+
}
2490+
},
2491+
"required": [
2492+
"concurrency",
2493+
"_running",
2494+
"_queue"
2495+
],
2496+
"type": "object"
2497+
},
2498+
"QueueOptions": {
2499+
"additionalProperties": false,
2500+
"properties": {
2501+
"_queue": {
2502+
"$ref": "#/definitions/Queue"
2503+
},
2504+
"concurrency": {
2505+
"yahooFinanceType": "number"
2506+
},
2507+
"timeout": {
2508+
"yahooFinanceType": "number"
2509+
}
2510+
},
2511+
"type": "object"
2512+
},
23832513
"Quote": {
23842514
"anyOf": [
23852515
{
@@ -6058,6 +6188,22 @@
60586188
],
60596189
"type": "object"
60606190
},
6191+
"ValidationOptions": {
6192+
"additionalProperties": false,
6193+
"properties": {
6194+
"logErrors": {
6195+
"type": "boolean"
6196+
},
6197+
"logOptionsErrors": {
6198+
"type": "boolean"
6199+
}
6200+
},
6201+
"required": [
6202+
"logErrors",
6203+
"logOptionsErrors"
6204+
],
6205+
"type": "object"
6206+
},
60616207
"Yearly": {
60626208
"additionalProperties": false,
60636209
"properties": {
@@ -6077,6 +6223,26 @@
60776223
"earnings"
60786224
],
60796225
"type": "object"
6226+
},
6227+
"interface-2073358172-9814-11278-2073358172-0-212312": {
6228+
"additionalProperties": false,
6229+
"properties": {
6230+
"arguments": {},
6231+
"caller": {
6232+
"$ref": "#/definitions/interface-2073358172-9814-11278-2073358172-0-212312"
6233+
},
6234+
"length": {
6235+
"yahooFinanceType": "number"
6236+
},
6237+
"prototype": {}
6238+
},
6239+
"required": [
6240+
"prototype",
6241+
"length",
6242+
"arguments",
6243+
"caller"
6244+
],
6245+
"type": "object"
60806246
}
60816247
}
60826248
}

src/lib/options.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
// TODO, keep defaults there too?
2-
import type { ValidationOptions } from "./validateAndCoerceTypes";
3-
import type { QueueOptions } from "./queue";
2+
// import type { ValidationOptions } from "./validateAndCoerceTypes";
3+
// import type { QueueOptions } from "./queue";
44

5-
export interface Options {
6-
queue: QueueOptions;
7-
validation: ValidationOptions;
8-
}
5+
import { Options } from "../typings/interfaces";
96

107
const options: Options = {
118
queue: {

src/lib/setGlobalConfig.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import testYf from "../../tests/testYf";
2+
import options from "./options";
3+
import setGlobalConfig from "./setGlobalConfig";
4+
const yf = testYf({ setGlobalConfig });
5+
6+
describe("setGlobalConfig", () => {
7+
const optionsBackup = JSON.parse(JSON.stringify(options));
8+
beforeEach(() => {
9+
yf._opts = JSON.parse(JSON.stringify(optionsBackup));
10+
});
11+
12+
it("sets config options and passes validation", () => {
13+
const configOverrides = { queue: { concurrency: 10, timeout: 90 } };
14+
yf.setGlobalConfig(configOverrides);
15+
expect(yf._opts).toEqual({ ...optionsBackup, ...configOverrides });
16+
});
17+
it("sets config options multiple levels deep", () => {
18+
const configOverrides = { queue: { concurrency: 10 } };
19+
yf.setGlobalConfig(configOverrides);
20+
expect(yf._opts.queue).toEqual({
21+
concurrency: 10,
22+
timeout: optionsBackup.queue.timeout,
23+
});
24+
});
25+
it("should throw on invalid config", () => {
26+
expect(() => yf.setGlobalConfig({ queue: { abc: "" } })).toThrow(
27+
/yahooFinance.setGlobalConfig called with invalid options\./
28+
);
29+
});
30+
});

src/lib/setGlobalConfig.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { Options } from "../typings/interfaces";
2+
import { ModuleThis } from "./moduleCommon";
3+
import validateAndCoerceTypes from "./validateAndCoerceTypes";
4+
5+
export default function setGlobalConfig(
6+
this: ModuleThis,
7+
config: Partial<Options>
8+
): void {
9+
validateAndCoerceTypes({
10+
object: config,
11+
source: "setGlobalConfig",
12+
type: "options",
13+
options: this._opts.validation,
14+
schemaKey: "#/definitions/PartialOptions",
15+
});
16+
mergeObjects(this._opts, config as Obj);
17+
}
18+
19+
type Obj = Record<string, string | ObjRecurse>;
20+
21+
// This is fine, since this is just a hack for recursive types
22+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
23+
interface ObjRecurse extends Obj {}
24+
25+
function mergeObjects(original: Obj, objToMerge: Obj) {
26+
const ownKeys: (keyof typeof objToMerge)[] = Reflect.ownKeys(
27+
objToMerge
28+
) as string[];
29+
for (const key of ownKeys) {
30+
if (typeof objToMerge[key] === "object") {
31+
mergeObjects(original[key] as Obj, objToMerge[key] as Obj);
32+
} else {
33+
original[key] = objToMerge[key];
34+
}
35+
}
36+
}

src/lib/yahooFinanceFetch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Queue from "./queue";
22

3-
import type { Options } from "./options";
3+
import type { Options } from "../typings/interfaces";
44
import type { QueueOptions } from "./queue";
55

66
import errors from "./errors";

src/typings/interfaces.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { QueueOptions } from "../lib/queue";
2+
import { ValidationOptions } from "../lib/validateAndCoerceTypes";
3+
4+
export interface PartialOptions {
5+
queue?: QueueOptions;
6+
validation?: ValidationOptions;
7+
}
8+
9+
export type Options = Required<PartialOptions>;

0 commit comments

Comments
 (0)