bmlt-query-client 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,17 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
- "Bash(wc -l /Users/pjoyce/workspace/git/bmlt-enabled/bmlt-query-client/src/**/*.ts /Users/pjoyce/workspace/git/bmlt-enabled/bmlt-query-client/test/*.ts)"
4
+ "Bash(npm view:*)",
5
+ "Bash(npm ls *)",
6
+ "Bash(curl -s https://raw.githubusercontent.com/qmhc/unplugin-dts/main/README.md)",
7
+ "Bash(curl -s https://raw.githubusercontent.com/qmhc/unplugin-dts/main/docs/en/migration-v4-to-v5.md)",
8
+ "Bash(npm run *)",
9
+ "Bash(npm test *)",
10
+ "Bash(tar -xzf bmlt-query-client-1.4.0.tgz)",
11
+ "Bash(grep -nA 12 '\"scripts\"' /Users/patrick/workspace/git/bmlt-enabled/bmlt-query-client/package.json)",
12
+ "Bash(grep -nA 3 \"interface Format\" /Users/patrick/workspace/git/bmlt-enabled/crumb-widget/node_modules/bmlt-query-client/dist/app.d.ts)",
13
+ "Bash(grep -nA 30 \"^function makeMeeting\\\\|^function rawMeeting\\\\|^function rawFormat\\\\|^function makeFormat\\\\|^ function makeGeoMeeting\\\\|^ function makeFormat\" src/tests/unit/format.test.ts src/tests/unit/data.svelte.test.ts src/tests/unit/Controls.svelte.test.ts)",
14
+ "Bash(grep -nA 30 \"^function makeMeeting\" src/tests/unit/MapView.svelte.test.ts src/tests/unit/MeetingDetail.svelte.test.ts src/tests/unit/MeetingList.svelte.test.ts)"
5
15
  ]
6
- },
7
- "disabledMcpjsonServers": [
8
- "laravel-boost"
9
- ]
16
+ }
10
17
  }
package/CHANGELOG.md CHANGED
@@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [1.4.2] - 2026-05-19
10
+
11
+ ### Fixed
12
+
13
+ - `countUniqueGroups` now matches crouton's long-standing definition: groups are identified by `(service_body, normalized meeting name, location)` — physical coordinates for in-person/hybrid (`venue_type !== 2`), virtual link + additional info for virtual (`venue_type === 2`). The previous algorithm keyed only on `(service_body, name)`, which under-counted whenever two distinct home groups happened to share a name but met at different locations (real-world example: MCANA returned 12 groups vs. crouton's 17 for the same 30 meetings). Bug; widget headers and downstream callers now agree with crouton.
14
+
15
+ ## [1.4.1] - 2026-05-15
16
+
17
+ ### Fixed
18
+
19
+ - Republish of 1.4.0 with regenerated `dist/` files. The 1.4.0 npm tarball shipped stale type declarations (`dist/app.d.ts` was baked from a 1.3.0-era build), so TypeScript consumers still saw the old `string` types for `Meeting.weekday_tinyint`, `latitude`, `longitude`, etc. — even though the source had been updated to `number`. No source changes; this release just ensures `dist/` matches `src/`.
20
+ - Added a `prepublishOnly` script (`npm run clean && npm run build`) so future publishes always ship a fresh build.
21
+
9
22
  ## [1.4.0] - 2026-05-15
10
23
 
11
24
  ### Added
@@ -85,7 +98,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
85
98
  - Zero external runtime dependencies — p-queue and p-retry are bundled via Vite.
86
99
  - ES module only; native `fetch` API; TypeScript declarations included.
87
100
 
88
- [Unreleased]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.0...HEAD
101
+ [Unreleased]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.2...HEAD
102
+ [1.4.2]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.1...v1.4.2
103
+ [1.4.1]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.4.0...v1.4.1
89
104
  [1.4.0]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.3.0...v1.4.0
90
105
  [1.3.0]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.2.0...v1.3.0
91
106
  [1.2.0]: https://github.com/bmlt-enabled/bmlt-query-client/compare/v1.1.0...v1.2.0
package/CLAUDE.md ADDED
@@ -0,0 +1,39 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ TypeScript client library for querying BMLT (Basic Meeting List Tool) servers with built-in Nominatim geocoding. Published to NPM as `bmlt-query-client`. ESM-only, targets Node.js 20+ and modern browsers (ES2020).
8
+
9
+ ## Commands
10
+
11
+ - **Build:** `npm run build` (Vite → `dist/app.js` single ES module + type declarations)
12
+ - **Test:** `npm test` (Vitest, runs integration tests against live server `https://latest.aws.bmlt.app/main_server`)
13
+ - **Lint:** `npm run lint`
14
+ - **Format:** `npm run format` (Prettier) / `npm run format:check`
15
+ - **Type check:** `npm run type-check` (tsc --noEmit)
16
+ - **Clean:** `npm run clean` (removes dist/)
17
+
18
+ Tests hit a real BMLT server and Nominatim, so they require network access and have 15-second timeouts.
19
+
20
+ ## Architecture
21
+
22
+ **Entry point:** `src/index.ts` — re-exports everything from the modules below.
23
+
24
+ **Core modules:**
25
+
26
+ - `src/client/bmlt-client.ts` — **BmltClient** class. Main API client wrapping all BMLT endpoints (searchMeetings, getFormats, getServiceBodies, getChanges, getFieldKeys, getFieldValues, getNAWSDump, getServerInfo, getCoverageArea). Also provides geocoded search methods (searchMeetingsByAddress, searchMeetingsByCoordinates) and reverse geocoding.
27
+ - `src/client/query-builder.ts` — **MeetingQueryBuilder** (fluent/chainable query API) and **QuickSearch** (convenience presets like today(), weekend(), virtual()). QueryBuilder holds a reference to BmltClient and delegates execution.
28
+ - `src/services/geocoding.ts` — **GeocodingService** wrapping Nominatim OpenStreetMap API with rate limiting (p-queue) and retry logic (p-retry).
29
+ - `src/utils/url-builder.ts` — URL construction and parameter validation for BMLT API calls.
30
+ - `src/utils/errors.ts` — **BmltQueryError** custom error class with BmltErrorType enum, plus ErrorFactory, ErrorHandler, and RetryHandler utilities.
31
+ - `src/types/` — TypeScript interfaces and enums: BmltDataFormat, BmltEndpoint, Weekday (1-7, Sun-Sat), VenueType (1-3), SortKey, Language, request/response interfaces.
32
+
33
+ **Build output:** Vite bundles all dependencies (including p-queue, p-retry) into a single `dist/app.js` with no externals, plus `dist/app.d.ts` type declarations.
34
+
35
+ ## Code Style
36
+
37
+ - Strict TypeScript (`strict: true` in tsconfig)
38
+ - Prettier: single quotes, trailing commas (es5), 100 char print width, 2-space indent, no semicolons optional (semi: true)
39
+ - ESLint: prefer-const, no-var enforced
package/dist/app.d.ts CHANGED
@@ -304,21 +304,27 @@ export declare interface Coordinates {
304
304
  /**
305
305
  * Count unique groups across a list of meetings.
306
306
  *
307
- * A "group" is identified by the combination of service body and meeting name
308
- * (case-insensitive, trimmed), so multiple weekly meetings of the same group
309
- * count once.
307
+ * A "group" is identified by the combination of service body, meeting name
308
+ * (case-insensitive, trimmed), and meeting location physical coordinates
309
+ * for in-person/hybrid (venue_type !== 2), or the virtual meeting link plus
310
+ * additional info for virtual (venue_type === 2). Multiple weekly meetings of
311
+ * the same group count once; two distinct groups that happen to share a name
312
+ * but meet at different locations count separately. Matches the long-standing
313
+ * "group_id" definition used by crouton.
314
+ *
315
+ * Meetings missing a service body or name are skipped.
310
316
  */
311
317
  export declare function countUniqueGroups(meetings: Meeting[]): number;
312
318
 
313
319
  export declare interface CoverageArea {
314
- /** Northwest corner longitude as a numeric string */
315
- nw_corner_longitude: string;
316
- /** Northwest corner latitude as a numeric string */
317
- nw_corner_latitude: string;
318
- /** Southeast corner longitude as a numeric string */
319
- se_corner_longitude: string;
320
- /** Southeast corner latitude as a numeric string */
321
- se_corner_latitude: string;
320
+ /** Northwest corner longitude */
321
+ nw_corner_longitude: number;
322
+ /** Northwest corner latitude */
323
+ nw_corner_latitude: number;
324
+ /** Southeast corner longitude */
325
+ se_corner_longitude: number;
326
+ /** Southeast corner latitude */
327
+ se_corner_latitude: number;
322
328
  }
323
329
 
324
330
  /** A single meeting paired with the index of the list it came from */
@@ -596,10 +602,10 @@ export declare enum Language {
596
602
  export declare interface Meeting {
597
603
  /** Meeting ID */
598
604
  id_bigint: string;
599
- /** Weekday (1-7) as a numeric string */
600
- weekday_tinyint: string;
601
- /** Venue type (1=In-person, 2=Virtual, 3=Hybrid) as a numeric string */
602
- venue_type: string;
605
+ /** Weekday (1=Sunday, 7=Saturday) */
606
+ weekday_tinyint: number;
607
+ /** Venue type (1=In-person, 2=Virtual, 3=Hybrid) */
608
+ venue_type: number;
603
609
  /** Start time (24-hour format HH:MM:SS) */
604
610
  start_time: string;
605
611
  /** Duration time (HH:MM:SS) */
@@ -628,12 +634,12 @@ export declare interface Meeting {
628
634
  location_sub_province?: string;
629
635
  /** Location nation */
630
636
  location_nation?: string;
631
- /** Latitude as a numeric string */
632
- latitude: string;
633
- /** Longitude as a numeric string */
634
- longitude: string;
635
- /** Published status (0=unpublished, 1=published) as a numeric string */
636
- published: string;
637
+ /** Latitude */
638
+ latitude: number;
639
+ /** Longitude */
640
+ longitude: number;
641
+ /** Published status (0=unpublished, 1=published) */
642
+ published: number;
637
643
  /** Email contact */
638
644
  email_contact?: string;
639
645
  /** World Committee Code */
@@ -678,10 +684,10 @@ export declare interface Meeting {
678
684
  admin_notes?: string;
679
685
  /** Root server URI (for aggregator mode) */
680
686
  root_server_uri?: string;
681
- /** Distance from search point in km as a numeric string (when using geographic search; may be empty string otherwise) */
682
- distance_in_km?: string;
683
- /** Distance from search point in miles as a numeric string (when using geographic search; may be empty string otherwise) */
684
- distance_in_miles?: string;
687
+ /** Distance from search point in km (undefined when not a geographic search) */
688
+ distance_in_km?: number;
689
+ /** Distance from search point in miles (undefined when not a geographic search) */
690
+ distance_in_miles?: number;
685
691
  }
686
692
 
687
693
  export declare class MeetingQueryBuilder {
@@ -1043,18 +1049,18 @@ export declare interface SearchResultsParams extends BaseSearchParams {
1043
1049
  export declare interface ServerInfo {
1044
1050
  /** Server version (e.g. "4.2.0") */
1045
1051
  version: string;
1046
- /** Server version as integer string (e.g. "4002000") */
1047
- versionInt: string;
1052
+ /** Server version as integer (e.g. 4002000) */
1053
+ versionInt: number;
1048
1054
  /** Supported languages, comma-separated (e.g. "da,de,el,en,es") */
1049
1055
  langs: string;
1050
1056
  /** Native language code (e.g. "en") */
1051
1057
  nativeLang: string;
1052
- /** Map center longitude as a numeric string */
1053
- centerLongitude: string;
1054
- /** Map center latitude as a numeric string */
1055
- centerLatitude: string;
1056
- /** Default map zoom level as a numeric string */
1057
- centerZoom: string;
1058
+ /** Map center longitude */
1059
+ centerLongitude: number;
1060
+ /** Map center latitude */
1061
+ centerLatitude: number;
1062
+ /** Default map zoom level */
1063
+ centerZoom: number;
1058
1064
  /** Default meeting duration (HH:MM:SS) */
1059
1065
  defaultDuration: string;
1060
1066
  /** Region bias for geocoding (e.g. "us") */
@@ -1063,10 +1069,10 @@ export declare interface ServerInfo {
1063
1069
  charSet: string;
1064
1070
  /** Distance units ("mi" or "km") */
1065
1071
  distanceUnits: string;
1066
- /** Semantic admin enabled flag as a numeric string ("0" or "1") */
1067
- semanticAdmin: string;
1068
- /** Number of changes tracked per meeting as a numeric string */
1069
- changesPerMeeting: string;
1072
+ /** Semantic admin enabled flag (0 or 1) */
1073
+ semanticAdmin: number;
1074
+ /** Number of changes tracked per meeting */
1075
+ changesPerMeeting: number;
1070
1076
  /** Comma-separated list of states/provinces with meetings */
1071
1077
  meeting_states_and_provinces: string;
1072
1078
  /** Comma-separated list of counties/sub-provinces with meetings */