@happyvertical/geo 0.80.0 → 0.80.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.
package/dist/index.js CHANGED
@@ -1,290 +1,406 @@
1
1
  import { loadEnvConfig } from "@happyvertical/utils";
2
- class GeoError extends Error {
3
- /**
4
- * @param message - Human-readable error description
5
- * @param code - Machine-readable error code (e.g. 'RATE_LIMIT', 'AUTH_ERROR')
6
- * @param provider - Provider that raised the error ('google' | 'openstreetmap')
7
- */
8
- constructor(message, code, provider) {
9
- super(message);
10
- this.code = code;
11
- this.provider = provider;
12
- this.name = "GeoError";
13
- }
14
- }
15
- class RateLimitError extends GeoError {
16
- /**
17
- * @param provider - Provider that raised the error
18
- * @param retryAfter - Seconds to wait before retrying (if known)
19
- */
20
- constructor(provider, retryAfter) {
21
- super(
22
- `Rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ""}`,
23
- "RATE_LIMIT",
24
- provider
25
- );
26
- this.name = "RateLimitError";
27
- }
28
- }
29
- class InvalidQueryError extends GeoError {
30
- /**
31
- * @param query - The invalid query string
32
- * @param provider - Provider that raised the error
33
- */
34
- constructor(query, provider) {
35
- super(`Invalid query: ${query}`, "INVALID_QUERY", provider);
36
- this.name = "InvalidQueryError";
37
- }
38
- }
39
- class AuthenticationError extends GeoError {
40
- /**
41
- * @param provider - Provider that raised the error
42
- */
43
- constructor(provider) {
44
- super("Authentication failed", "AUTH_ERROR", provider);
45
- this.name = "AuthenticationError";
46
- }
47
- }
48
- class NoResultsError extends GeoError {
49
- /**
50
- * @param query - The query that produced no results
51
- * @param provider - Provider that raised the error
52
- */
53
- constructor(query, provider) {
54
- super(`No results found for query: ${query}`, "NO_RESULTS", provider);
55
- this.name = "NoResultsError";
56
- }
57
- }
2
+ //#region src/shared/types.ts
3
+ /**
4
+ * Base error class for geo operations.
5
+ * All geo-specific errors extend this class and include a machine-readable `code`
6
+ * and the `provider` name that produced the error.
7
+ */
8
+ var GeoError = class extends Error {
9
+ code;
10
+ provider;
11
+ /**
12
+ * @param message - Human-readable error description
13
+ * @param code - Machine-readable error code (e.g. 'RATE_LIMIT', 'AUTH_ERROR')
14
+ * @param provider - Provider that raised the error ('google' | 'openstreetmap')
15
+ */
16
+ constructor(message, code, provider) {
17
+ super(message);
18
+ this.code = code;
19
+ this.provider = provider;
20
+ this.name = "GeoError";
21
+ }
22
+ };
23
+ /**
24
+ * Thrown when the provider's rate limit has been exceeded.
25
+ */
26
+ var RateLimitError = class extends GeoError {
27
+ /**
28
+ * @param provider - Provider that raised the error
29
+ * @param retryAfter - Seconds to wait before retrying (if known)
30
+ */
31
+ constructor(provider, retryAfter) {
32
+ super(`Rate limit exceeded${retryAfter ? `, retry after ${retryAfter}s` : ""}`, "RATE_LIMIT", provider);
33
+ this.name = "RateLimitError";
34
+ }
35
+ };
36
+ /**
37
+ * Thrown when the geocoding query is empty or malformed.
38
+ */
39
+ var InvalidQueryError = class extends GeoError {
40
+ /**
41
+ * @param query - The invalid query string
42
+ * @param provider - Provider that raised the error
43
+ */
44
+ constructor(query, provider) {
45
+ super(`Invalid query: ${query}`, "INVALID_QUERY", provider);
46
+ this.name = "InvalidQueryError";
47
+ }
48
+ };
49
+ /**
50
+ * Thrown when the provider rejects the API key or credentials.
51
+ */
52
+ var AuthenticationError = class extends GeoError {
53
+ /**
54
+ * @param provider - Provider that raised the error
55
+ */
56
+ constructor(provider) {
57
+ super("Authentication failed", "AUTH_ERROR", provider);
58
+ this.name = "AuthenticationError";
59
+ }
60
+ };
61
+ /**
62
+ * Thrown when a geocoding query returns zero results.
63
+ */
64
+ var NoResultsError = class extends GeoError {
65
+ /**
66
+ * @param query - The query that produced no results
67
+ * @param provider - Provider that raised the error
68
+ */
69
+ constructor(query, provider) {
70
+ super(`No results found for query: ${query}`, "NO_RESULTS", provider);
71
+ this.name = "NoResultsError";
72
+ }
73
+ };
74
+ //#endregion
75
+ //#region src/shared/utils.ts
76
+ /**
77
+ * Map Google Maps place types to standardized location types.
78
+ * Checks types in priority order: address, city, region, country, point_of_interest.
79
+ *
80
+ * @param types - Array of Google Maps place type strings (e.g. 'street_address', 'locality')
81
+ * @returns The standardized location type
82
+ */
58
83
  function mapGooglePlaceType(types) {
59
- if (!types || types.length === 0) return "unknown";
60
- if (types.includes("street_address") || types.includes("premise")) {
61
- return "address";
62
- }
63
- if (types.includes("locality") || types.includes("postal_town")) {
64
- return "city";
65
- }
66
- if (types.includes("administrative_area_level_1") || types.includes("administrative_area_level_2")) {
67
- return "region";
68
- }
69
- if (types.includes("country")) {
70
- return "country";
71
- }
72
- if (types.includes("point_of_interest") || types.includes("establishment")) {
73
- return "point_of_interest";
74
- }
75
- return "unknown";
84
+ if (!types || types.length === 0) return "unknown";
85
+ if (types.includes("street_address") || types.includes("premise")) return "address";
86
+ if (types.includes("locality") || types.includes("postal_town")) return "city";
87
+ if (types.includes("administrative_area_level_1") || types.includes("administrative_area_level_2")) return "region";
88
+ if (types.includes("country")) return "country";
89
+ if (types.includes("point_of_interest") || types.includes("establishment")) return "point_of_interest";
90
+ return "unknown";
76
91
  }
92
+ /**
93
+ * Map OpenStreetMap place types to standardized location types.
94
+ * Uses both the Nominatim `type` and `addresstype` fields for classification.
95
+ *
96
+ * @param type - Nominatim result type (e.g. 'house', 'city', 'state')
97
+ * @param addressType - Nominatim addresstype field (optional secondary classifier)
98
+ * @returns The standardized location type
99
+ */
77
100
  function mapOSMPlaceType(type, addressType) {
78
- const checkType = (type || "").toLowerCase();
79
- const checkAddressType = (addressType || "").toLowerCase();
80
- if (checkType === "house" || checkType === "building" || checkAddressType === "house") {
81
- return "address";
82
- }
83
- if (checkType === "city" || checkType === "town" || checkType === "village" || checkType === "hamlet" || checkAddressType === "city" || checkAddressType === "town" || checkAddressType === "village") {
84
- return "city";
85
- }
86
- if (checkType === "state" || checkType === "province" || checkType === "region" || checkAddressType === "state") {
87
- return "region";
88
- }
89
- if (checkType === "country" || checkAddressType === "country") {
90
- return "country";
91
- }
92
- if (checkType === "attraction" || checkType === "tourism" || checkType === "amenity") {
93
- return "point_of_interest";
94
- }
95
- return "unknown";
101
+ const checkType = (type || "").toLowerCase();
102
+ const checkAddressType = (addressType || "").toLowerCase();
103
+ if (checkType === "house" || checkType === "building" || checkAddressType === "house") return "address";
104
+ if (checkType === "city" || checkType === "town" || checkType === "village" || checkType === "hamlet" || checkAddressType === "city" || checkAddressType === "town" || checkAddressType === "village") return "city";
105
+ if (checkType === "state" || checkType === "province" || checkType === "region" || checkAddressType === "state") return "region";
106
+ if (checkType === "country" || checkAddressType === "country") return "country";
107
+ if (checkType === "attraction" || checkType === "tourism" || checkType === "amenity") return "point_of_interest";
108
+ return "unknown";
96
109
  }
110
+ /**
111
+ * Normalize a country code to uppercase ISO 3166-1 format.
112
+ * Returns 'XX' for undefined, empty, or unrecognized inputs.
113
+ *
114
+ * @param code - Country code string (alpha-2 or alpha-3)
115
+ * @returns Uppercase country code, or 'XX' if unknown
116
+ */
97
117
  function normalizeCountryCode(code) {
98
- if (!code) return "XX";
99
- const normalized = code.toUpperCase().trim();
100
- if (normalized.length === 2) {
101
- return normalized;
102
- }
103
- return normalized.length === 3 ? normalized : "XX";
118
+ if (!code) return "XX";
119
+ const normalized = code.toUpperCase().trim();
120
+ if (normalized.length === 2) return normalized;
121
+ return normalized.length === 3 ? normalized : "XX";
104
122
  }
123
+ /**
124
+ * Validate that a latitude value is within the valid range (-90 to 90).
125
+ *
126
+ * @param lat - Latitude value to validate
127
+ * @returns `true` if the value is a number between -90 and 90 inclusive
128
+ */
105
129
  function isValidLatitude(lat) {
106
- return typeof lat === "number" && lat >= -90 && lat <= 90;
130
+ return typeof lat === "number" && lat >= -90 && lat <= 90;
107
131
  }
132
+ /**
133
+ * Validate that a longitude value is within the valid range (-180 to 180).
134
+ *
135
+ * @param lng - Longitude value to validate
136
+ * @returns `true` if the value is a number between -180 and 180 inclusive
137
+ */
108
138
  function isValidLongitude(lng) {
109
- return typeof lng === "number" && lng >= -180 && lng <= 180;
139
+ return typeof lng === "number" && lng >= -180 && lng <= 180;
110
140
  }
141
+ /**
142
+ * Validate that both latitude and longitude are within their valid ranges.
143
+ *
144
+ * @param latitude - Latitude value (-90 to 90)
145
+ * @param longitude - Longitude value (-180 to 180)
146
+ * @returns Object with `valid: true` if both are valid, or `valid: false` with an `error` message
147
+ */
111
148
  function validateCoordinates(latitude, longitude) {
112
- if (!isValidLatitude(latitude)) {
113
- return {
114
- valid: false,
115
- error: `Invalid latitude: ${latitude}. Must be between -90 and 90.`
116
- };
117
- }
118
- if (!isValidLongitude(longitude)) {
119
- return {
120
- valid: false,
121
- error: `Invalid longitude: ${longitude}. Must be between -180 and 180.`
122
- };
123
- }
124
- return { valid: true };
149
+ if (!isValidLatitude(latitude)) return {
150
+ valid: false,
151
+ error: `Invalid latitude: ${latitude}. Must be between -90 and 90.`
152
+ };
153
+ if (!isValidLongitude(longitude)) return {
154
+ valid: false,
155
+ error: `Invalid longitude: ${longitude}. Must be between -180 and 180.`
156
+ };
157
+ return { valid: true };
125
158
  }
159
+ //#endregion
160
+ //#region src/static-maps.ts
161
+ /**
162
+ * Generate Mapbox static map URL
163
+ */
126
164
  function getMapboxUrl(latitude, longitude, options) {
127
- const token = options.mapboxToken ?? process.env.MAPBOX_ACCESS_TOKEN ?? process.env.MAPBOX_TOKEN;
128
- if (!token) {
129
- throw new Error(
130
- "Mapbox access token required. Provide via options.mapboxToken or MAPBOX_ACCESS_TOKEN env var."
131
- );
132
- }
133
- const width = options.width ?? 1200;
134
- const height = options.height ?? 630;
135
- const zoom = options.zoom ?? 14;
136
- const style = options.mapboxStyle ?? "streets-v12";
137
- const scale = options.scale ?? 1;
138
- const showMarker = options.showMarker ?? true;
139
- let overlay = "";
140
- if (showMarker) {
141
- const color = (options.markerColor ?? "e74c3c").replace("#", "");
142
- overlay = `pin-l+${color}(${longitude},${latitude})/`;
143
- }
144
- if (options.markers?.length) {
145
- const markerOverlays = options.markers.map((m) => {
146
- const color = (m.color ?? "e74c3c").replace("#", "");
147
- const size = m.size === "small" ? "s" : m.size === "large" ? "l" : "m";
148
- const label = m.label ? `-${m.label}` : "";
149
- return `pin-${size}${label}+${color}(${m.longitude},${m.latitude})`;
150
- });
151
- overlay = markerOverlays.join(",") + "/";
152
- }
153
- const retinaStr = scale === 2 ? "@2x" : "";
154
- return `https://api.mapbox.com/styles/v1/mapbox/${style}/static/${overlay}${longitude},${latitude},${zoom}/${width}x${height}${retinaStr}?access_token=${token}`;
165
+ const token = options.mapboxToken ?? process.env.MAPBOX_ACCESS_TOKEN ?? process.env.MAPBOX_TOKEN;
166
+ if (!token) throw new Error("Mapbox access token required. Provide via options.mapboxToken or MAPBOX_ACCESS_TOKEN env var.");
167
+ const width = options.width ?? 1200;
168
+ const height = options.height ?? 630;
169
+ const zoom = options.zoom ?? 14;
170
+ const style = options.mapboxStyle ?? "streets-v12";
171
+ const scale = options.scale ?? 1;
172
+ const showMarker = options.showMarker ?? true;
173
+ let overlay = "";
174
+ if (showMarker) overlay = `pin-l+${(options.markerColor ?? "e74c3c").replace("#", "")}(${longitude},${latitude})/`;
175
+ if (options.markers?.length) overlay = options.markers.map((m) => {
176
+ const color = (m.color ?? "e74c3c").replace("#", "");
177
+ return `pin-${m.size === "small" ? "s" : m.size === "large" ? "l" : "m"}${m.label ? `-${m.label}` : ""}+${color}(${m.longitude},${m.latitude})`;
178
+ }).join(",") + "/";
179
+ return `https://api.mapbox.com/styles/v1/mapbox/${style}/static/${overlay}${longitude},${latitude},${zoom}/${width}x${height}${scale === 2 ? "@2x" : ""}?access_token=${token}`;
155
180
  }
181
+ /**
182
+ * Generate Google Maps static map URL
183
+ */
156
184
  function getGoogleUrl(latitude, longitude, options) {
157
- const apiKey = options.googleApiKey ?? process.env.GOOGLE_MAPS_API_KEY ?? process.env.GOOGLE_API_KEY;
158
- if (!apiKey) {
159
- throw new Error(
160
- "Google Maps API key required. Provide via options.googleApiKey or GOOGLE_MAPS_API_KEY env var."
161
- );
162
- }
163
- const width = options.width ?? 1200;
164
- const height = options.height ?? 630;
165
- const zoom = options.zoom ?? 14;
166
- const mapType = options.googleMapType ?? "roadmap";
167
- const scale = options.scale ?? 1;
168
- const showMarker = options.showMarker ?? true;
169
- const params = new URLSearchParams({
170
- center: `${latitude},${longitude}`,
171
- zoom: zoom.toString(),
172
- size: `${width}x${height}`,
173
- maptype: mapType,
174
- scale: scale.toString(),
175
- key: apiKey
176
- });
177
- if (showMarker) {
178
- const color = (options.markerColor ?? "red").replace("#", "0x");
179
- params.append("markers", `color:${color}|${latitude},${longitude}`);
180
- }
181
- if (options.markers?.length) {
182
- for (const m of options.markers) {
183
- const color = (m.color ?? "red").replace("#", "0x");
184
- const size = m.size ?? "medium";
185
- const label = m.label ? `|label:${m.label.charAt(0).toUpperCase()}` : "";
186
- params.append(
187
- "markers",
188
- `color:${color}|size:${size}${label}|${m.latitude},${m.longitude}`
189
- );
190
- }
191
- }
192
- return `https://maps.googleapis.com/maps/api/staticmap?${params.toString()}`;
185
+ const apiKey = options.googleApiKey ?? process.env.GOOGLE_MAPS_API_KEY ?? process.env.GOOGLE_API_KEY;
186
+ if (!apiKey) throw new Error("Google Maps API key required. Provide via options.googleApiKey or GOOGLE_MAPS_API_KEY env var.");
187
+ const width = options.width ?? 1200;
188
+ const height = options.height ?? 630;
189
+ const zoom = options.zoom ?? 14;
190
+ const mapType = options.googleMapType ?? "roadmap";
191
+ const scale = options.scale ?? 1;
192
+ const showMarker = options.showMarker ?? true;
193
+ const params = new URLSearchParams({
194
+ center: `${latitude},${longitude}`,
195
+ zoom: zoom.toString(),
196
+ size: `${width}x${height}`,
197
+ maptype: mapType,
198
+ scale: scale.toString(),
199
+ key: apiKey
200
+ });
201
+ if (showMarker) {
202
+ const color = (options.markerColor ?? "red").replace("#", "0x");
203
+ params.append("markers", `color:${color}|${latitude},${longitude}`);
204
+ }
205
+ if (options.markers?.length) for (const m of options.markers) {
206
+ const color = (m.color ?? "red").replace("#", "0x");
207
+ const size = m.size ?? "medium";
208
+ const label = m.label ? `|label:${m.label.charAt(0).toUpperCase()}` : "";
209
+ params.append("markers", `color:${color}|size:${size}${label}|${m.latitude},${m.longitude}`);
210
+ }
211
+ return `https://maps.googleapis.com/maps/api/staticmap?${params.toString()}`;
193
212
  }
213
+ /**
214
+ * Generate a static map URL
215
+ *
216
+ * Returns a URL that can be used directly in <img> tags or fetched for processing.
217
+ *
218
+ * @param latitude - Center latitude
219
+ * @param longitude - Center longitude
220
+ * @param options - Map options
221
+ * @returns URL string for the static map
222
+ *
223
+ * @example Mapbox (default)
224
+ * ```typescript
225
+ * const url = getStaticMapUrl(53.5461, -113.4938, {
226
+ * provider: 'mapbox',
227
+ * zoom: 14,
228
+ * mapboxStyle: 'streets-v12'
229
+ * });
230
+ * ```
231
+ *
232
+ * @example Google Maps
233
+ * ```typescript
234
+ * const url = getStaticMapUrl(53.5461, -113.4938, {
235
+ * provider: 'google',
236
+ * zoom: 14,
237
+ * googleMapType: 'roadmap'
238
+ * });
239
+ * ```
240
+ *
241
+ * @example With custom markers
242
+ * ```typescript
243
+ * const url = getStaticMapUrl(53.5461, -113.4938, {
244
+ * showMarker: false, // Hide center marker
245
+ * markers: [
246
+ * { latitude: 53.5461, longitude: -113.4938, color: 'blue', label: 'A' },
247
+ * { latitude: 53.5500, longitude: -113.4900, color: 'green', label: 'B' }
248
+ * ]
249
+ * });
250
+ * ```
251
+ */
194
252
  function getStaticMapUrl(latitude, longitude, options = {}) {
195
- const provider = options.provider ?? "mapbox";
196
- switch (provider) {
197
- case "google":
198
- return getGoogleUrl(latitude, longitude, options);
199
- case "mapbox":
200
- default:
201
- return getMapboxUrl(latitude, longitude, options);
202
- }
253
+ switch (options.provider ?? "mapbox") {
254
+ case "google": return getGoogleUrl(latitude, longitude, options);
255
+ default: return getMapboxUrl(latitude, longitude, options);
256
+ }
203
257
  }
258
+ /**
259
+ * Fetch a static map image
260
+ *
261
+ * Downloads the map image and returns it as a Buffer.
262
+ *
263
+ * @param latitude - Center latitude
264
+ * @param longitude - Center longitude
265
+ * @param options - Map options
266
+ * @returns Promise resolving to the map image result
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * const result = await fetchStaticMap(53.5461, -113.4938, {
271
+ * provider: 'mapbox',
272
+ * width: 1200,
273
+ * height: 630
274
+ * });
275
+ *
276
+ * await fs.writeFile('map.png', result.buffer);
277
+ * console.log(`Fetched ${result.width}x${result.height} map`);
278
+ * ```
279
+ */
204
280
  async function fetchStaticMap(latitude, longitude, options = {}) {
205
- const width = options.width ?? 1200;
206
- const height = options.height ?? 630;
207
- const url = getStaticMapUrl(latitude, longitude, options);
208
- const response = await fetch(url);
209
- if (!response.ok) {
210
- const errorText = await response.text();
211
- throw new Error(
212
- `Failed to fetch static map: ${response.status} ${response.statusText} - ${errorText}`
213
- );
214
- }
215
- const arrayBuffer = await response.arrayBuffer();
216
- const buffer = Buffer.from(arrayBuffer);
217
- return {
218
- buffer,
219
- width,
220
- height,
221
- mimeType: "image/png",
222
- url
223
- };
281
+ const width = options.width ?? 1200;
282
+ const height = options.height ?? 630;
283
+ const url = getStaticMapUrl(latitude, longitude, options);
284
+ const response = await fetch(url);
285
+ if (!response.ok) {
286
+ const errorText = await response.text();
287
+ throw new Error(`Failed to fetch static map: ${response.status} ${response.statusText} - ${errorText}`);
288
+ }
289
+ const arrayBuffer = await response.arrayBuffer();
290
+ return {
291
+ buffer: Buffer.from(arrayBuffer),
292
+ width,
293
+ height,
294
+ mimeType: "image/png",
295
+ url
296
+ };
224
297
  }
298
+ /**
299
+ * Generate OG-sized static map URL (1200x630)
300
+ *
301
+ * Convenience function for generating Open Graph / social media sized maps.
302
+ *
303
+ * @param latitude - Center latitude
304
+ * @param longitude - Center longitude
305
+ * @param options - Map options (width/height ignored, set to 1200x630)
306
+ * @returns URL string for the static map
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * const url = getOGMapUrl(53.5461, -113.4938);
311
+ * // Returns 1200x630 map URL
312
+ * ```
313
+ */
225
314
  function getOGMapUrl(latitude, longitude, options = {}) {
226
- return getStaticMapUrl(latitude, longitude, {
227
- ...options,
228
- width: 1200,
229
- height: 630
230
- });
315
+ return getStaticMapUrl(latitude, longitude, {
316
+ ...options,
317
+ width: 1200,
318
+ height: 630
319
+ });
231
320
  }
321
+ //#endregion
322
+ //#region src/index.ts
323
+ /**
324
+ * Geo package entry point
325
+ * Provides standardized geographical information interface
326
+ */
327
+ /**
328
+ * Type guard for Google Maps options
329
+ */
232
330
  function isGoogleMapsOptions(options) {
233
- return options.provider === "google";
331
+ return options.provider === "google";
234
332
  }
333
+ /**
334
+ * Type guard for OpenStreetMap options
335
+ */
235
336
  function isOpenStreetMapOptions(options) {
236
- return options.provider === "openstreetmap";
337
+ return options.provider === "openstreetmap";
237
338
  }
339
+ /**
340
+ * Factory function to create a geo adapter instance
341
+ *
342
+ * Supports configuration via environment variables using the pattern:
343
+ * - HAVE_GEO_PROVIDER → provider ('google' | 'openstreetmap')
344
+ * - GOOGLE_MAPS_API_KEY → apiKey (for Google Maps provider)
345
+ *
346
+ * User-provided options always take precedence over environment variables.
347
+ *
348
+ * @param options - Configuration options for the geo provider (optional)
349
+ * @returns Promise resolving to a geo adapter that implements GeoAdapter
350
+ *
351
+ * @example
352
+ * ```typescript
353
+ * // Create Google Maps adapter with explicit options
354
+ * const googleGeo = await getGeoAdapter({
355
+ * provider: 'google',
356
+ * apiKey: process.env.GOOGLE_MAPS_API_KEY!
357
+ * });
358
+ *
359
+ * // Create adapter using environment variables
360
+ * // HAVE_GEO_PROVIDER=google
361
+ * // GOOGLE_MAPS_API_KEY=your-api-key
362
+ * const geoFromEnv = await getGeoAdapter();
363
+ *
364
+ * // Create OpenStreetMap adapter
365
+ * const osmGeo = await getGeoAdapter({
366
+ * provider: 'openstreetmap'
367
+ * });
368
+ *
369
+ * // Use the adapter
370
+ * const locations = await googleGeo.lookup('Eiffel Tower');
371
+ * const coords = await osmGeo.reverseGeocode(48.8584, 2.2945);
372
+ * ```
373
+ */
238
374
  async function getGeoAdapter(options = {}) {
239
- const config = loadEnvConfig(options, {
240
- packageName: "geo",
241
- schema: {
242
- provider: "string",
243
- timeout: "number",
244
- maxResults: "number",
245
- rateLimitDelay: "number",
246
- userAgent: "string"
247
- }
248
- });
249
- if (config.provider === "google" && !config.apiKey) {
250
- const apiKey = process.env.GOOGLE_MAPS_API_KEY;
251
- if (apiKey) {
252
- config.apiKey = apiKey;
253
- }
254
- }
255
- if (!config.provider) {
256
- throw new Error(
257
- "Provider is required. Set via options.provider or HAVE_GEO_PROVIDER environment variable."
258
- );
259
- }
260
- const fullOptions = config;
261
- if (isGoogleMapsOptions(fullOptions)) {
262
- const { GoogleMapsProvider } = await import("./chunks/google-Ci3_ec7t.js");
263
- return new GoogleMapsProvider(fullOptions);
264
- }
265
- if (isOpenStreetMapOptions(fullOptions)) {
266
- const { OpenStreetMapProvider } = await import("./chunks/openstreetmap-DEPHzMUV.js");
267
- return new OpenStreetMapProvider(fullOptions);
268
- }
269
- throw new Error(`Unsupported provider: ${fullOptions.provider}`);
375
+ const config = loadEnvConfig(options, {
376
+ packageName: "geo",
377
+ schema: {
378
+ provider: "string",
379
+ timeout: "number",
380
+ maxResults: "number",
381
+ rateLimitDelay: "number",
382
+ userAgent: "string"
383
+ }
384
+ });
385
+ if (config.provider === "google" && !config.apiKey) {
386
+ const apiKey = process.env.GOOGLE_MAPS_API_KEY;
387
+ if (apiKey) config.apiKey = apiKey;
388
+ }
389
+ if (!config.provider) throw new Error("Provider is required. Set via options.provider or HAVE_GEO_PROVIDER environment variable.");
390
+ const fullOptions = config;
391
+ if (isGoogleMapsOptions(fullOptions)) {
392
+ const { GoogleMapsProvider } = await import("./chunks/google-CZUa1ho0.js");
393
+ return new GoogleMapsProvider(fullOptions);
394
+ }
395
+ if (isOpenStreetMapOptions(fullOptions)) {
396
+ const { OpenStreetMapProvider } = await import("./chunks/openstreetmap-St4Kw-vS.js");
397
+ return new OpenStreetMapProvider(fullOptions);
398
+ }
399
+ throw new Error(`Unsupported provider: ${fullOptions.provider}`);
270
400
  }
271
- const PACKAGE_VERSION_INITIALIZED = true;
272
- export {
273
- AuthenticationError,
274
- GeoError,
275
- InvalidQueryError,
276
- NoResultsError,
277
- PACKAGE_VERSION_INITIALIZED,
278
- RateLimitError,
279
- fetchStaticMap,
280
- getGeoAdapter,
281
- getOGMapUrl,
282
- getStaticMapUrl,
283
- isValidLatitude,
284
- isValidLongitude,
285
- mapGooglePlaceType,
286
- mapOSMPlaceType,
287
- normalizeCountryCode,
288
- validateCoordinates
289
- };
290
- //# sourceMappingURL=index.js.map
401
+ /** @internal */
402
+ var PACKAGE_VERSION_INITIALIZED = true;
403
+ //#endregion
404
+ export { AuthenticationError, GeoError, InvalidQueryError, NoResultsError, PACKAGE_VERSION_INITIALIZED, RateLimitError, fetchStaticMap, getGeoAdapter, getOGMapUrl, getStaticMapUrl, isValidLatitude, isValidLongitude, mapGooglePlaceType, mapOSMPlaceType, normalizeCountryCode, validateCoordinates };
405
+
406
+ //# sourceMappingURL=index.js.map