Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: 'weekly'
interval: "weekly"
open-pull-requests-limit: 100
- package-ecosystem: 'github-actions'
directory: '/'
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: 'weekly'
interval: "weekly"
open-pull-requests-limit: 100
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,20 @@ jobs:

- name: Run tests
run: npm run test

lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"

- name: Install dependencies
run: npm install

- name: Run tests
run: npm run lint
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
data
tmp
4 changes: 0 additions & 4 deletions .prettierrc

This file was deleted.

19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ $ npm install @neaps/tide-database
The package exports an array of all tide stations in the database:

```typescript
import { constituents, stations } from '@neaps/tide-database';
import { constituents, stations } from "@neaps/tide-database";

// Constituents is an array of all harmonic constituents used in the database with a description and speed.
console.log('Total constituents:', constituents.length);
console.log("Total constituents:", constituents.length);
console.log(constituents[0]);

// Stations is an array of all the files in `data/`
console.log('Total stations:', stations.length);
console.log("Total stations:", stations.length);
console.log(stations[0]);
```

Expand All @@ -61,6 +61,7 @@ Subordinate stations have four kinds of offsets, two to correct for water level,
## Maintenance

A GitHub Action runs monthly on the 1st of each month to automatically update NOAA tide station data. The workflow:

- Fetches the latest station list and harmonic constituents from NOAA's API
- Updates existing station files with new data
- Adds any newly discovered reference stations
Expand All @@ -80,19 +81,19 @@ This will scan all existing NOAA station files, fetch any new stations from NOAA

Releases of this database use [Semantic Versioning](https://semver.org/), with these added semantics:

* Major version changes indicate breaking changes to the data structure or APIs. However, as long as the version is "0.x", breaking changes may occur without a major version bump.
* Minor version changes indicate backward-compatible additions to the data structure or APIs, such as new fields.
* Patch version changes indicate updates to station data, and will always be the current date. For example, "0.1.20260101".
- Major version changes indicate breaking changes to the data structure or APIs. However, as long as the version is "0.x", breaking changes may occur without a major version bump.
- Minor version changes indicate backward-compatible additions to the data structure or APIs, such as new fields.
- Patch version changes indicate updates to station data, and will always be the current date. For example, "0.1.20260101".

## Releasing

Releases are created by [running the Publish action](https://github.com/neaps/tide-database/actions/workflows/publish.yml) on GitHub Actions. This action will use the major and minor `version` defined in `package.json`, and set the patch version to the current date.

## License

* All code in this repository is licensed under the [MIT License](./LICENSE).
* The `license` field of each station's JSON file specifies the license for that station.
* Unless otherwise noted, All other data is licensed under the [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/) license.
- All code in this repository is licensed under the [MIT License](./LICENSE).
- The `license` field of each station's JSON file specifies the license for that station.
- Unless otherwise noted, All other data is licensed under the [Creative Commons Attribution 4.0 International (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/) license.

If using this project, please attribute it as:

Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"scripts": {
"build": "tsc -b && tsc -p tsconfig.node.json && tsdown",
"prepare": "npm run build",
"test": "vitest"
"test": "vitest",
"lint": "prettier --check .",
"format": "prettier --write ."
},
"devDependencies": {
"@neaps/tide-predictor": "^0.2.1",
Expand All @@ -43,6 +45,7 @@
"geo-tz": "^8.1.4",
"make-fetch-happen": "^15.0.3",
"moment": "^2.30.1",
"prettier": "^3.7.4",
"sort-object-keys": "^2.0.1",
"tsdown": "^0.19.0-beta.3",
"typescript": "^5.9.3",
Expand Down
62 changes: 11 additions & 51 deletions schemas/station.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@
"offsets": {
"type": "object",
"description": "Offsets for subordinate stations relative to a reference station",
"required": [
"reference",
"height",
"time"
],
"required": ["reference", "height", "time"],
"additionalProperties": false,
"properties": {
"reference": {
Expand All @@ -34,11 +30,7 @@
"height": {
"type": "object",
"description": "Defines the values to add or multiply with water levels (depending on type)",
"required": [
"high",
"low",
"type"
],
"required": ["high", "low", "type"],
"additionalProperties": false,
"properties": {
"high": {
Expand All @@ -50,20 +42,14 @@
"description": "Height offset/multiplier for low tide - if type is 'ratio', this is a multiplier; if 'fixed', this is an offset to add (can be negative)"
},
"type": {
"enum": [
"ratio",
"fixed"
]
"enum": ["ratio", "fixed"]
}
}
},
"time": {
"type": "object",
"description": "Defines the time to add to when a high or low tide will occur",
"required": [
"high",
"low"
],
"required": ["high", "low"],
"additionalProperties": false,
"properties": {
"high": {
Expand All @@ -83,10 +69,7 @@
"id": {
"type": "string",
"description": "Unique station ID for this database only, in the format of `country/region/station-name`.",
"examples": [
"us-ma-boston",
"ar-u-puerto-madryn"
],
"examples": ["us-ma-boston", "ar-u-puerto-madryn"],
"minLength": 4
},
"name": {
Expand Down Expand Up @@ -117,10 +100,7 @@
},
"type": {
"type": "string",
"enum": [
"reference",
"subordinate"
]
"enum": ["reference", "subordinate"]
},
"latitude": {
"type": "number",
Expand All @@ -133,23 +113,15 @@
"source": {
"type": "object",
"description": "",
"required": [
"name",
"id",
"published_harmonics",
"url"
],
"required": ["name", "id", "published_harmonics", "url"],
"additionalProperties": true,
"properties": {
"name": {
"type": "string",
"name": "Name of the source, i.e. `NOAA`"
},
"id": {
"type": [
"string",
"number"
],
"type": ["string", "number"],
"description": "The identifier used by the source for this station."
},
"published_harmonics": {
Expand All @@ -166,11 +138,7 @@
"license": {
"type": "object",
"description": "Defines the license and whatever restrictions are placed on use of the data.",
"required": [
"type",
"commercial_use",
"url"
],
"required": ["type", "commercial_use", "url"],
"additionalProperties": true,
"properties": {
"type": {
Expand All @@ -196,23 +164,15 @@
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"amplitude",
"phase"
],
"required": ["name", "amplitude", "phase"],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"description": "Harmonic Constituent code (i.e. M2) - should be upper-case"
},
"description": {
"type": [
"string",
"number",
"null"
],
"type": ["string", "number", "null"],
"description": "Human-friendly description of the constituent"
},
"amplitude": {
Expand Down
76 changes: 38 additions & 38 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
import _constituents from './constituents.json' with { type: 'json' }
import _constituents from "./constituents.json" with { type: "json" };

export interface HarmonicConstituent {
name: string
description?: string
amplitude: number
phase: number
speed?: number
name: string;
description?: string;
amplitude: number;
phase: number;
speed?: number;
}

export interface Constituent {
name: string
description: string | null
speed: number
name: string;
description: string | null;
speed: number;
}

export interface Station {
// Basic station information
id: string
name: string
continent: string
country: string
region?: string
timezone: string
disclaimers: string
type: 'reference' | 'subordinate'
latitude: number
longitude: number
id: string;
name: string;
continent: string;
country: string;
region?: string;
timezone: string;
disclaimers: string;
type: "reference" | "subordinate";
latitude: number;
longitude: number;

// Data source information
source: {
name: string
id: string
published_harmonics: boolean
url: string
}
name: string;
id: string;
published_harmonics: boolean;
url: string;
};

// License information
license: {
type: string
commercial_use: boolean
url: string
notes?: string
}
type: string;
commercial_use: boolean;
url: string;
notes?: string;
};

// Harmonic constituents (empty array for subordinate stations)
harmonic_constituents: HarmonicConstituent[]
harmonic_constituents: HarmonicConstituent[];

// Subordinate station offsets (empty object for reference stations)
offsets?: {
reference: string
height: { high: number; low: number; type: 'ratio' | 'fixed' }
time: { high: number; low: number }
}
reference: string;
height: { high: number; low: number; type: "ratio" | "fixed" };
time: { high: number; low: number };
};

datums: Record<string, number>
datums: Record<string, number>;
}

export const constituents: Constituent[] = _constituents
export const constituents: Constituent[] = _constituents;

export const stations: Station[] = Object.values(
import.meta.glob('../data/**/*.json', { eager: true, import: 'default' })
)
import.meta.glob("../data/**/*.json", { eager: true, import: "default" }),
);
Loading