# Contributing to Turf

## Getting Started

One of the most important things you can do is report bugs. Please reference [how to report a bug](https://macwright.com/sites/polite.technology/reportabug) and when opening an [issue](https://github.com/Turfjs/turf/issues), follow the template.

To propose an enhancement for Turf, it's usually best to [start a discussion](https://github.com/Turfjs/turf/discussions) to work through the requirements. Unless you know exactly what you need! In which case [open an issue](https://github.com/Turfjs/turf/issues) to request it.

To make a code contribution, follow the steps for [how to contribute](#how-to-contribute).

## Architecture

- GeoJSON is the lingua franca of Turf. It should be used as the data structure for anything that can be represented as geography.
- Turf is broken into many submodules, or packages. These are found in the `packages` directory prefixed with "turf-".
- Turf packages are small, generally containing a single exported function.
- Many Turf packages depend on other lower level Turf packages.

## How to contribute

The best way for a new contributor to help with Turf is to find an open issue, fix it, and then share that back to the project via a pull request (PR). A maintainer will review your PR and get it merged with the rest of the code.

Here is a great article on how to fork a repo, and start contributing to Turf.

If you'd like to become a core contributor, just start making contributions, and inquire.

### Local Setup

Once you've cloned a Turf repository, and have a terminal open and currenty in the top-level turf directory. Run the following:
- `git checkout master` (if not already)
- `corepack enable pnpm`
  - enable pnpm as a package manager. Requires Node 16+.  Alternatively just `npm install -g pnpm`.
- `pnpm install`
  - install dependencies and build packages
- `pnpm test`
  - run all tests and linters

You're now ready to contribute.

<details>
<summary>Structure of a Turf package</summary>
<br>

Turf packages all live under the `packages` directory. For example `packages/turf-area`. Here's how they are structured.

```
turf-<PACKAGE NAME>
│   index.ts
│   bench.ts
│   test.ts
│   package.json
│   README.md
│   LICENSE
│
└───test
    │
    ├───in
    │   points.geojson
    │
    └───out
        points.geojson
```

* `index.ts` - This file contains the definition of the function including [TypeScript](https://www.typescriptlang.org/) types, function implementation, the embedded [JSDocs](http://usejsdoc.org) documentation, and finally the single exported function that the package provides.
* `bench.ts` - This file uses [Benchmark](https://benchmarkjs.com/) to establish benchmark performance tests for your function.
* `test.ts` - This file includes your [tape](https://github.com/substack/tape)
  unit tests. Tests can either be traditional code based tests, or tests that pull in data files and compare inputs to outputs (see below).
* `package.json` - The [node](http://nodejs.org) metadata container file.
  Packages imported in `index.ts` should be listed here under `dependencies`,
  and packages used in `test.ts` or `bench.ts` should be listed under
  `devDependencies`.
* `README.md` - This README is generated _automatically_ by running `pnpm run
  docs`. **DO NOT edit this file**.
* `LICENCE` - Like the README, this file should not be edited.
* `test/` - This directory holds the GeoJSON files that provide data for
  dynamic tests. Input data in `./test/in`, and expected output data in `./test/out`.
</details>

<details>
<summary>Development tips</summary>
<br>
Work in a feature branch when possible
- `git checkout -b my-feature`
- Create it right away off of master.
- This allows you to keep your local master branch clean and in sync with the official remote. This will ease your ability to keep your local repo up to date with changes other people have made while you work on your feature.

As you make code changes
- Regularly run `pnpm test` in whatever package you are working in to avoid unintended bugs.
- Occasionally run `pnpm test` at the top-level directory to run test for all packages, to make sure you haven't introduced a problem that affects another package.
</details>

## Preparing a pull request

A simple, complete pull request is more likely to get merged.

<details>
<summary>But I don't know how</summary>
<br>
If you don't know how to make a solid PR, submit a draft PR and ask for feedback.  Take on any feedback to improve the PR ready. There may be multiple rounds of feedback. While this seems tedious it greatly reduces the risk of someone else
having to revisit the same code any time soon.
</details>

### Pull Request Checklist
- Briefly summarize the need and solution. Link to the issue it's resolving if exists.
- Add tests.  Even for bug fixes. A simple test case that reproduces the issue and demonstrates it's fixed.
- Update JSDoc comments if the function signature changes or docs need improvement (See for example `packages/turf-area/index.ts`)
- Run a full `npm test` at root level, confirming no cross-package issues. If you don't catch this now, the Github CI will.

### Guidelines

- Feel free to [ask](#getting-started) if a feature/enhancement is needed/wanted before doing the work.
- Keep pull requests small and focused.
- Avoid large dependencies at all costs.
- Make sure that your code can run in the browser (ie: don't make calls to external services, don't hit the filesystem, etc.).

### Documentation

The package README.md files and https://turfjs.org API docs are auto-generated from JSDoc comments in each packages' source file.

As a contributor, all you need to do is keep the JSDoc comments up to date, and the rest is automated. For example if you change a top-level Turf functions signature (params, return type) or just want to improve the descriptiveness of the docs.

JSDoc comments are found in the top-level index file for each package (for example `packages/turf-area/index.ts`). Look for the `@name`, `@params`, `@returns`, `@example` tags.

## Code Style

We have lots of tooling dedicated to ensuring consistent code. We use [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/), and [ESLint](https://eslint.org/) to help us deliver quality code. These are checked by the build system and should be enforced at commit time by [Husky](https://typicode.github.io/husky/#/).

Most packages are written in TypeScript, while a few plain Javascript still linger. You can generally use modern Javascript when modifying Turf itself as all exported code is transpiled to (currently es2017).

Code for consumption by browsers is transpiled by Babel as described in the README.

Making sure that the monorepo packages can be managed at scale, we use [Monorepolint](https://github.com/monorepolint/monorepolint) to programmatically ensure the individual packages remain consistent.

## Documentation

- API docs for each turf package are extracted from JSDoc comments in the source code into the top-level README.md files. README's are automatically updated on commit via a pre-commit hook.

Should you want to generate new README files manually, use `pnpm run docs`:
  - **inside a package:** will generate the docs for that package.
  - **from root folder:** will generate docs for all package.

### Documentation - Examples

**Build docs for only `@turf/center`**

```bash
$ cd ./turf/packages/turf-center
$ pnpm run docs

> @turf/center@5.0.4 docs /Users/mac/Github/turf/packages/turf-center
> node ../../scripts/generate-readmes

Building Docs: @turf/center
```

**Builds docs for all packages**

```bash
$ cd ./turf
$ pnpm run docs
> @ docs /Users/mac/Github/turf
> tsx ./scripts/generate-readmes

Building Docs: @turf/along
Building Docs: @turf/area
Building Docs: @turf/bbox-clip
Building Docs: @turf/bbox-polygon
Building Docs: @turf/bbox
Building Docs: @turf/bearing
Building Docs: @turf/bezier-spline
Building Docs: @turf/boolean-clockwise
....
```

### Public website

The [turfjs.org](https://turfjs.org/) website is managed in a [separate repo](https://github.com/Turfjs/turf-www) with its own [contributing guide](https://github.com/Turfjs/turf-www/blob/master/CONTRIBUTING.md).

## Other Dependencies

  - Turf uses [pnpm](https://pnpm.io/) and [lerna](https://lernajs.io/) during the testing, packaging and publishing process.
  - Lerna will be automatically installed when you run `pnpm install` in the root directory.
  - Pnpm will need to be installed on your computer, installers are available via the pnpm website. When using [corepack](https://nodejs.org/api/corepack.html), this is automatically installed when running `pnpm`.

## Financial contributions

We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/turf).
Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.


## Credits


### Contributors

Thank you to all the people who have already contributed to turf!
<a href="graphs/contributors"><img src="https://opencollective.com/turf/contributors.svg?width=890" /></a>


### Backers

Thank you to all our backers! [[Become a backer](https://opencollective.com/turf#backer)]

<a href="https://opencollective.com/turf#backers" target="_blank"><img src="https://opencollective.com/turf/backers.svg?width=890"></a>


### Sponsors

Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/turf#sponsor))

<a href="https://opencollective.com/turf/sponsor/0/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/1/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/2/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/3/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/4/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/5/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/6/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/7/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/8/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/turf/sponsor/9/website" target="_blank"><img src="https://opencollective.com/turf/sponsor/9/avatar.svg"></a>
