How to develop the Terra Draw project locally.
You will need to have the following installed:
.github
- used for all GitHub related configuration such as the GitHub Actions work flows.husky
- used to storing the precommit hooks that are used on the projectpackages
- source files for the packages in this projectdist
- the bundled distributed files of the projectdocs
- the demo app that is published to GitHub pagesguides
- learn how to use Terra Drawdevelopment
- the local development app that is used for developing locally (see below)common
- code that is used acrossdevelopment
anddocs
folder
It is probably useful to be aware of the precommit hooks you will face when trying to run a git commit on the project. There are two currently in use, namely:
- Uses pre-commit hook to run lint rules (eslint/prettier) on code before commit.
- Uses pre-commit hook to ensure conventional commit messages are used.
For the conventional commit precommit hook, you will need to follow the convention provided in the commitlint
config of the root package.json. This currently enforces the standard types (feat
, fix
, docs
, style
, refactor
, perf
, test
, build
, ci
, chore
, revert
), along with the package names as the scope.
Here's some example of some valid commits:
feat(terra-draw): some commit message relating to the core Terra Draw library
feat(terra-draw-openlayers-adapter): some commit relating specifically to OpenLayers adapter package
feat(terra-draw-leaflet-adapter): some commit relating specifically to Leaflet adapter package
In conventional commits, you can use the !
to indicate a breaking change like so:
feat(terra-draw)!: some breaking change commit message relating to the core Terra Draw library
This will increment the major version on release, i.e. v1.0.0 -> v2.0.0. feat
will trigger a minor release update, i.e. v1.0.0 -> v1.1.0 and fix
will trigger a patch, i.e. v1.0.0 -> v1.0.1.
Note
The library used to write the CHANGELOG and bump the appropriate package on release, commit-and-tag-version
is not able to correctly recommend the correct version when bumping the package. Instead we work around this using the bump.mjs
script which accurately determines what the new package version should be, based on the conventional commit specification. It then passes this commit-and-tag-version
via the --release-as
flag which allows you to specifically set the release version.
- TypeScript - provides strong compile time typing for JavaScript
- Jest - used for testing (see more information below)
- microbundle - used for the production bundle
- Webpack - used for bundling locally in development (
development
anddocs
folders) - esno - for running tests quickly without type checking
To build the project, you will need to install the dependencies from the project root:
npm install
You will also need to then install in the package you are interested in building. Let's go to the folder and then install in there too:
cd packages/terra-draw
npm install
Then we can run the following to build that specific package:
npm run build
One of the simplest way to start developing locally is in the packages/development
folder. This project is designed to allow quick and efficient testing of changes on the fly. It is designed to respond in real time to changes when you are developing the Terra Draw packages locally. First thing is to go into the development folder and install:
cd development/
npm install
The demo application that development builds shows all mapping libraries simultaneously side by side. You can control which mapping libraries get rendered via the development\src\config.ts
file. If you don't have the API keys for Google Maps API and Mapbox, comment out the corresponding libraries inside development\src\config.ts
.
export const Config = {
libraries: [
Libraries.Leaflet,
Libraries.MapLibre,
// Libraries.Mapbox,
// Libraries.Google,
Libraries.OpenLayers,
Libraries.ArcGIS,
] as const,
};
If you do have the API keys, refer to the README.md
file inside the development
folder to see how to set up the .env
file with the APIs keys.
If you just wanted to run one mapping library in the demo app, say for example MapLibre, you can do that like so:
export const Config = {
libraries: [
// Libraries.Leaflet,
Libraries.MapLibre,
// Libraries.Mapbox,
// Libraries.Google,
// Libraries.OpenLayers,
// Libraries.ArcGIS,
] as const,
};
After that, you can run the following command to start the watching build, inside the packages/development
folder.
npm run serve
In theory, an adapter could be created for any mapping library that can fill out the Adapter abstract class (TerraDrawBaseAdapter
).
For example, in the LeafletAdapter
we create and update a GeoJSON layer that Leaflet knows how to render to the screen.
Assuming that an adapter extends from TerraDrawBaseAdapter
, these methods would need to be implemented:
public project(...args: Parameters<Project>): ReturnType<Project>;
public unproject(
...args: Parameters<Unproject>
): ReturnType<Unproject>;
public setCursor(
...args: Parameters<SetCursor>
): ReturnType<SetCursor>;
public getLngLatFromEvent(event: PointerEvent | MouseEvent): {
lng: number;
lat: number;
} | null;
public setDraggability(enabled: boolean): void;
public setDoubleClickToZoom(enabled: boolean): void;
public getMapEventElement(): HTMLElement;
public render(
changes: TerraDrawChanges,
styling: TerraDrawStylingFunction
): void;
You can see a very basic example adapter in the terra-draw.extensions.spec.ts
file. It shows how you can create your own adapter from the publicly exposed library imports.
Modes are not just limited to drawing features, for example the built-in TerraDrawSelectMode
allows for selection and editing of geometries that have previously been drawn. The TerraDrawRenderMode
is a "view only" Mode useful for showing non-editable data alongside editable data in your application.
Assuming that a mode extends from TerraDrawBaseMode
:
/** @internal */
start() {
this.setStarted();
}
/** @internal */
stop() {
this.setStopped();
}
/** @internal */
onClick(event: TerraDrawMouseEvent) {}
/** @internal */
onMouseMove(event: TerraDrawMouseEvent) {}
/** @internal */
onKeyDown(event: TerraDrawKeyboardEvent) {}
/** @internal */
onKeyUp(event: TerraDrawKeyboardEvent) {}
/** @internal */
onDragStart(event: TerraDrawMouseEvent) {}
/** @internal */
onDrag(event: TerraDrawMouseEvent) {}
/** @internal */
onDragEnd(event: TerraDrawMouseEvent) {}
/** @internal */
styleFeature(feature: GeoJSONStoreFeatures): TerraDrawAdapterStyling {}
You can see a very basic example mode in the terra-draw.extensions.spec.ts
file. It shows how you can create your own mode from the publicly exposed library imports.
Terra Draw uses Jest as its testing framework. You can distinguish a test by its .spec.ts
file name extension.
To run the tests as they would run in CI:
npm run test
You can also check the coverage by running:
npm run test:coverage
If coverage (either lines, branches, functions or statements) falls under 80%, this script will fail.
For local development you may benefit from the nocheck
option which allows you to avoid running TypeScript type checking when running the tests. This option also only checks files which are explicitly tested (i.e. have a spec file.)
npm run test:nocheck
npm run test:nocheck:coverage
The packages/development/
directory contains an App that aims to make developing Terra Draw locally easier.
It allows you to run each mapping provider adapter in parallel, allowing for fast development and testing in the browser as you make changes. See the packages/development/
README for more information.
There are End-to-End tests that run on PR in CI (GitHub Actions). These can be seen in the packages/e2e
folder. They are currently based on the Leaflet Adapter as this exposes elements in the DOM that can be expected. If you are adding features or making significant changes, please consider adding to or updating the E2E test suite to ensure the integrity of the library and your changes.
API Docs are automatically generated from TSDoc comments in the codebase, using the TypeDoc library. If you are editing library code, please write/update the TSDoc comments with useful and correct information with the changes. You can regenerate the API docs running:
npm run docs
If you want to view them locally you can do this using the docs:serve
script which spins up a simple web server and serves the static API docs locally:
npm run docs:serve
If you wish to contribute to Terra Draw, we request that you:
- Make an issue on GitHub describing the bug you intend to fix or the feature you intend to add.
- Create a fork of the project, and work on a branch that represents the issue.
- Ensure that the work you have done is unit tested, aiming for 80% code coverage.
- Create a PR that represents this work with a conventional commit title (this ensures the automated changelog is generated correctly). Please refer to the issue from the PR and follow the PR template.
- We will address the PR and give you feedback.
Please note that we can not guarantee that all PRs will be merged. There are cases where a PR may deviate from the long-term vision for Terra Draw and hence we may have to decline it. Creating the issue in advance helps us discuss any potential issues upfront before the PR is made.
We have a code of conduct which we expect individuals interacting with the project to respect. Please refer to the full Code of Conduct.
Guides