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
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

All notable changes will be documented in this file.

## 0.2.0 - Unreleased
## 0.3.0 - Unreleased

- Added dual ESM and CommonJS package entry points.
- Added `queryLocations` with fuzzy search, bounding-box filtering, proximity/radius queries, deterministic sorting, and pagination.
- Added explicit query validation and made unknown zone filters return no results instead of the full dataset.
- Added automated CommonJS, package-export, JSON Schema, query edge-case, spatial, pagination, and legacy-field compatibility tests.
- Added an API stability policy with deprecation guarantees and measurable 1.0 readiness gates.
- Retained Node.js 22 as the minimum supported runtime because earlier Node release lines are end-of-life.

## 0.2.0 - 2026-08-07

- Added canonical JSON sources, stable IDs, aliases, richer Maldives zone and location types.
- Added query helpers plus JSON, CSV, and GeoJSON distributions.
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ npm test
~~~

Please avoid unrelated formatting changes in large data files. Generated files in "dist/" are release artifacts and should not be committed.

Public API changes must follow [the API stability policy](docs/API_STABILITY.md). Add compatibility tests for new entry points, query behavior, schemas, or migration-sensitive fields.
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,46 @@ import { DATASET_METADATA } from "@boolean.mv/geo-data/metadata";
const nextCoordinatesReview = DATASET_METADATA.review.datasets.coordinates.nextReviewDue;
~~~

## CommonJS

Every JavaScript entry point also supports `require()` on supported Node.js versions:

~~~js
const { COUNTRY_BY_ISO2, queryLocations } = require("@boolean.mv/geo-data");
const { MV_LOCATIONS } = require("@boolean.mv/geo-data/maldives/zones/aa");
~~~

## Advanced location queries

`queryLocations` combines the existing zone, use, kind, coordinate, and deprecation filters with fuzzy search, spatial filtering, distance ordering, and pagination:

~~~ts
import { queryLocations } from "@boolean.mv/geo-data/query";

const typoTolerant = queryLocations({
search: "dangeti",
fuzzy: true,
minScore: 0.72,
limit: 10,
});

const nearbyResorts = queryLocations({
use: "resort",
near: { latitude: 4.1755, longitude: 73.5093 },
radiusKm: 50,
offset: 0,
limit: 25,
});

const visibleMapPoints = queryLocations({
bounds: { south: 3.8, west: 72.8, north: 4.5, east: 73.8 },
hasCoordinates: true,
limit: 1000,
});
~~~

Results contain `location`, an optional fuzzy-match `score`, and an optional `distanceKm`. The response also includes `total`, `offset`, `limit`, and `hasMore`. Limits must be between 1 and 1,000. Spatial queries exclude records without coordinates.

## JSON

The build emits framework-neutral files at:
Expand All @@ -90,6 +130,7 @@ This is reference data, not an official government service. Names, classificatio
See [data provenance](docs/data-provenance.md) for ownership, redistribution terms, and contribution guidance.
The [data maintenance policy](docs/DATA_MAINTENANCE.md) defines quarterly reviews, stable-ID rename handling, and deprecation behavior.
Deprecation and replacement metadata is preserved in typed objects, JSON, CSV, and GeoJSON outputs.
The [API stability policy](docs/API_STABILITY.md) defines compatibility guarantees from version 0.3.0 and the gates for reaching 1.0.

## Development

Expand Down
29 changes: 29 additions & 0 deletions docs/API_STABILITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# API stability

Although the package has not reached 1.0, Boolean Private Limited treats the public API as stable from version 0.3.0 onward.

## Compatibility promise

- Minor releases add exports, optional fields, query capabilities, and datasets without removing existing behavior.
- Patch releases contain compatible corrections, documentation, and maintenance changes.
- An export, field, or entry point must be deprecated for at least one minor release before removal.
- A breaking JavaScript or TypeScript API change requires a major release and a migration guide.
- Country, zone, and location IDs are never reassigned. Renames preserve the ID and retain the former name as an alias.
- Data corrections, additions, classifications, and deprecations are normal compatible updates. Applications that require an unchanged snapshot should pin an exact package version.

The legacy `Country.dialingCode`, `Country.nationality`, `MvLocation.status`, and `MvLocation.details` fields remain supported while their richer plural or structured equivalents are available.

## Runtime support

The package publishes equivalent ESM and CommonJS entry points. The minimum Node.js version follows supported Node release lines and is declared in `package.json`. Browser applications should use ESM so bundlers can select lightweight dataset and per-zone entry points.

## Path to 1.0

The project can move to 1.0 after all of the following are true:

1. The API has completed at least one quarterly review cycle without a breaking redesign.
2. At least two production applications have exercised the package and query helpers.
3. ESM, CommonJS, TypeScript declarations, schemas, and documented entry points remain covered by automated compatibility tests.
4. Any remaining pre-1.0 migration guidance is incorporated into the main documentation.

Reaching 1.0 will formalize the existing compatibility promise; it is not intended to trigger a redesign.
2 changes: 1 addition & 1 deletion docs/DATA_MODEL.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ Maldives zones distinguish administrative atolls from cities and separately reco

Coordinates are optional and identify their source and precision. Government-portal matches take precedence; uncovered locations may use exact atoll-and-name matches from Boolean Private Limited's coordinate workbook. Ambiguous names, duplicate source rows, and conflicting matches are excluded. Missing coordinates mean “not confidently matched,” never zero.

Breaking schema changes require a major version after 1.0. Before 1.0, changelogs must identify migrations.
From version 0.3.0, the package follows the compatibility guarantees in [API_STABILITY.md](API_STABILITY.md), including major-version-only breaking API changes and at least one minor release of deprecation notice.
82 changes: 80 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 22 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@boolean.mv/geo-data",
"version": "0.2.0",
"version": "0.3.0",
"description": "Typed country, nationality, and Maldives geographic reference data for web applications.",
"author": "Boolean Private Limited",
"keywords": [
Expand All @@ -21,36 +21,44 @@
"homepage": "https://github.com/booleanMV/GeoData#readme",
"type": "module",
"sideEffects": false,
"main": "./dist/index.js",
"main": "./dist/cjs/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
"import": "./dist/index.js",
"require": "./dist/cjs/index.js"
},
"./countries": {
"types": "./dist/countries.d.ts",
"import": "./dist/countries.js"
"import": "./dist/countries.js",
"require": "./dist/cjs/countries.js"
},
"./nationalities": {
"types": "./dist/nationalities.d.ts",
"import": "./dist/nationalities.js"
"import": "./dist/nationalities.js",
"require": "./dist/cjs/nationalities.js"
},
"./maldives": {
"types": "./dist/maldives.d.ts",
"import": "./dist/maldives.js"
"import": "./dist/maldives.js",
"require": "./dist/cjs/maldives.js"
},
"./maldives/zones/*": {
"types": "./dist/maldives-zones/*.d.ts",
"import": "./dist/maldives-zones/*.js"
"import": "./dist/maldives-zones/*.js",
"require": "./dist/cjs/maldives-zones/*.js"
},
"./metadata": {
"types": "./dist/metadata.d.ts",
"import": "./dist/metadata.js"
"import": "./dist/metadata.js",
"require": "./dist/cjs/metadata.js"
},
"./query": {
"types": "./dist/query.d.ts",
"import": "./dist/query.js"
"import": "./dist/query.js",
"require": "./dist/cjs/query.js"
},
"./data/*": "./dist/data/*",
"./schemas/*": "./schemas/*",
Expand All @@ -59,6 +67,8 @@
"files": [
"dist",
"schemas",
"docs",
"CHANGELOG.md",
"LICENSE",
"LICENSE-DATA.md",
"README.md"
Expand All @@ -72,13 +82,15 @@
"check:generated": "npm run build:coordinates && npm run generate && git diff --exit-code -- data/coordinates.json data/coordinate-coverage.json src/countries.ts src/nationalities.ts src/maldives.ts src/maldives-zones src/metadata.ts",
"build:coordinates": "node scripts/build-coordinates.mjs",
"sync:coordinates": "node scripts/sync-official-coordinates.mjs",
"build": "npm run build:coordinates && npm run generate && tsc -p tsconfig.json && node scripts/export-json.mjs",
"build": "npm run build:coordinates && npm run generate && tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node scripts/write-cjs-package.mjs && node scripts/export-json.mjs",
"clean": "rm -rf dist",
"test": "npm run check:review && npm run build && node --test tests/*.test.mjs",
"typecheck": "npm run generate && tsc -p tsconfig.json --noEmit",
"prepublishOnly": "npm test"
},
"devDependencies": {
"ajv": "^8.20.0",
"ajv-formats": "^3.0.1",
"typescript": "^5.9.2"
}
}
5 changes: 5 additions & 0 deletions scripts/write-cjs-package.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { mkdir, writeFile } from "node:fs/promises";

const directory = new URL("../dist/cjs/", import.meta.url);
await mkdir(directory, { recursive: true });
await writeFile(new URL("package.json", directory), '{"type":"commonjs"}\n', "utf8");
7 changes: 6 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ export type {
MvZoneType,
Nationality,
LocationFilter,
LocationQueryMatch,
LocationQueryOptions,
LocationQueryResult,
LocationUse,
Coordinates,
BoundingBox,
GeoPoint,
CountryScope,
DatasetMetadata,
DatasetReviewEntry,
Expand All @@ -21,4 +26,4 @@ export { COUNTRIES, COUNTRY_BY_ISO2, COUNTRY_BY_ISO3 } from "./countries.js";
export { NATIONALITIES, NATIONALITY_BY_ISO2 } from "./nationalities.js";
export { MV_ZONES, MV_ZONE_BY_CODE, MV_ZONE_BY_ID, MV_LOCATIONS, MV_LOCATION_BY_ID } from "./maldives.js";
export { DATASET_METADATA } from "./metadata.js";
export { getCountry, getZone, getLocation, getLocations, searchCountries, searchLocations, getNationalityOptions } from "./query.js";
export { getCountry, getZone, getLocation, getLocations, searchCountries, searchLocations, queryLocations, getNationalityOptions } from "./query.js";
Loading
Loading