# Contributing to yahoo-finance2 Interesting in helping out? You're the best! This guide will help you get all set up with the correct tools and important things to know for the project. 1. [Setup](#setup) 1. [Cloning](#cloning) 1. [Required Tools](#tools) 1. [Important Things to Know](#nb) 1. [Schema generation](#schema) 1. [Testing](#testing) 1. [Linting and Formatting](#linting) 1. [Documentation](#docs) 1. [Committing Changes](#commits) 1. [Other](#other) ## Setup ### Cloning the project 1. Install [git](https://git-scm.com/) if you haven't already. 1. Change to the directory where you want to keep these files. 1. `git clone https://github.com/gadicc/yahoo-finance2.git` 1. `cd yahoo-finance2` **Default branch: dev** All PRs should be submitted against the `dev` branch (github default). ### Required Tools: Deno & editor plugins We use the [deno](https://deno.com/) runtime for development. It can be installed with a single command and replaces node, npm, eslint, prettier, tsc, jest; is super fast and relieves us of many pain points. The library is still published in npm and runs on node and other runtimes. **vscode:** Make sure you have the official [Deno extension](https://marketplace.visualstudio.com/items?itemName=denoland.vscode-deno) installed. This includes the language server for super fast typescript, linting, formatting, etc, and will use the project settings in `.vscode/settings.json`. ## Import things to know ### Schema Generation To deliver a type-safe experience, we need to validate all input to ensure it conforms to what we expect. The single source of truth are the **typescript interfaces** in each module file. These are compiled into JSON schemas which are then used for runtime validation. In VSCode, this is done for you automatically. Otherwise, run `deno task schema` after changing a file, or `deno task schema --watch` to recompile after file changes. This only affects `.ts` files that contain a `@yf-schema` keyword. CI runs `deno task schema:check` and will fail your PR if committed `.schema.json` files don't match the interfaces — run `deno task schema` before committing interface changes. ### Testing `deno task test` The test task runs with the `test` Deno permission set from `deno.json`, which limits file access to HTTP fixtures, limits environment access to `FETCH_DEVEL*` controls, and limits network access to the Yahoo hosts used by the library. Run focused tests with `deno task test path/to/file.test.ts`. Use `deno task test:serial path/to/file.test.ts` when debugging or limiting live Yahoo request concurrency. NB: HTTP requests are cached to disk. This ensures we can re-run all tests quickly and consistently across repos (my dev box does 1,252 tests in 793ms). We use the [fetch-mock-cache](https://www.npmjs.com/package/fetch-mock-cache) library for this. Make sure the test `describe()` block calls `setupCache()`, imported from [tests/common.ts](./tests/common.ts), which may also be a useful read for those interested. Normal test runs use fetch-mock-cache's `auto` mode: existing fixtures are replayed, while a cache miss makes a live request and records a new fixture. This is what creates a fixture when a test is first added or after its existing fixture is deleted. Set the environment variable `FETCH_DEVEL=nocache` to force-run all network tests without the cache. Set `FETCH_DEVEL=recache` to do the same, but also rewrite the cache for any failing tests. In both cases, skipped for ids ending `.static` or `.fake`, which are fixtures we never want to update because they rely on time-sensitive data or made up data, respectively. You can also simply delete a test file to force its recreation on the next test run, just make sure not to delete `.static.json` or `.fake.json` files, and consider if anything actually changed that justifies committing the new file to the repo. #### Country-specific getCrumb fixtures Yahoo's cookie, consent, and crumb flow can vary by request geography. We keep country-specific captures as dated, append-only fixture profiles so one VPN capture never overwrites another flow. The country code records where the response was observed; tests assert the captured redirect/request sequence, not that Yahoo always serves that sequence to everyone in that country. Connect a VPN, independently verify its exit country, and then run: ```bash deno task fixtures:capture:getcrumb --country GB ``` The command records a new profile such as `gb-20260808`, compacts response data that getCrumb never consumes, and immediately replays the compacted fixtures. It refuses to overwrite an existing profile; use `--profile` with a dated suffix when two distinct flows are observed on the same day. Before committing, inspect every generated fixture. Do not keep rate limits, timeouts, upstream 5xx responses, unrelated interstitials, redirects outside the expected Yahoo hosts, or authenticated/user-specific cookies. Copy the profile entry printed by the command into `COMMITTED_PROFILES` in `src/lib/getCrumb.geo.test.ts`, then disconnect the VPN and run: ```bash deno task test:serial src/lib/getCrumb.geo.test.ts ``` Committed geographic profiles always replay from cache, even under the generic `FETCH_DEVEL=recache` workflow. If a new country's normalized request sequence and relevant cookie/header shape are identical to an existing profile, do not commit duplicate fixtures solely to add another country label. Cloudflare Workers coverage lives in `tests/cloudflare` and tests the generated npm package inside Workers Vitest. Run `deno task test:cloudflare` after changes that affect npm output or runtime detection. If you change the Cloudflare harness dependencies or need to regenerate its lockfile, use `deno task lock:cloudflare`; it pins lockfile generation to the npm behavior CI expects. ### Linting, formatting Done automatically for you in VSCode with the official Deno extension. If you use a different editor, see if it also has a Deno extension, otherwise, please run `deno lint` and `deno fmt` before submitting pull requests. ### Documentation We have two kinds of docs. The [explainer docs](./docs/) and [API docs](https://jsr.io/@gadicc/yahoo-finance2/doc). The latter are generated automatically on publish. However, you can build them locally too if you want to check their appearance before commit. `deno task docs:gen` will build the docs to a directory called `jsdocs`; `deno task docs:watch` will rebuild the docs on file changes (just make sure to reload the commmand if you change the deno.json `exports`), and `deno task docs:open` will open your browser to the docs on POSIX compliant systems. ### Commiting Changes **Commit Messages** Commit messages should follow the [conventionalcommits](https://www.conventionalcommits.org/) standard (basically Angular). This is important as we use [semantic-release](https://github.com/semantic-release/semantic-release) to automate [release](https://github.com/gadicc/yahoo-finance2/releases) (with their release notes) when we merge back to release branches like `main`, `2.x`, `next`, `next-major`, etc. Tags like `fix`, `feat`, `BREAKING CHANGE` affect the resulting semver version and release channel. ### Other Let us know if anything here could have been explained better. ### Adding a new module Checklist: 1. **Create the module file**: Create `src/modules/myModule.ts`. Make sure to mark exported interfaces for schema generation with a `// @yf-schema` comment. 2. **Generate schemas**: Run `deno task schema` to generate the matching `myModule.schema.json`. 3. **Write tests**: Test the module under `src/modules/myModule.test.ts`. Use `setupCache()` from `tests/common.ts` if it touches Yahoo HTTP responses. New HTTP cache fixtures will be recorded under `tests/fixtures/http`. 4. **Wire the exports**: - Export your module in `src/modules/index.ts`. - Add a key/value mapping under `exports` in `deno.json`. 5. **Document & Link**: Add JSDoc comments to the module exports (which will render on JSR) and add it to the "Available modules" list in the main `README.md`.