@memberjunction/geo-core 5.34.1 → 5.35.0

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.
Files changed (39) hide show
  1. package/dist/GeoCodeSyncService.d.ts +14 -16
  2. package/dist/GeoCodeSyncService.d.ts.map +1 -1
  3. package/dist/GeoCodeSyncService.js +47 -80
  4. package/dist/GeoCodeSyncService.js.map +1 -1
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/providers/BaseGeocodingProvider.d.ts +37 -0
  10. package/dist/providers/BaseGeocodingProvider.d.ts.map +1 -0
  11. package/dist/providers/BaseGeocodingProvider.js +71 -0
  12. package/dist/providers/BaseGeocodingProvider.js.map +1 -0
  13. package/dist/providers/GeocodingProviderRegistry.d.ts +51 -0
  14. package/dist/providers/GeocodingProviderRegistry.d.ts.map +1 -0
  15. package/dist/providers/GeocodingProviderRegistry.js +125 -0
  16. package/dist/providers/GeocodingProviderRegistry.js.map +1 -0
  17. package/dist/providers/GeocodioGeocodingProvider.d.ts +17 -0
  18. package/dist/providers/GeocodioGeocodingProvider.d.ts.map +1 -0
  19. package/dist/providers/GeocodioGeocodingProvider.js +109 -0
  20. package/dist/providers/GeocodioGeocodingProvider.js.map +1 -0
  21. package/dist/providers/GoogleGeocodingProvider.d.ts +22 -0
  22. package/dist/providers/GoogleGeocodingProvider.d.ts.map +1 -0
  23. package/dist/providers/GoogleGeocodingProvider.js +110 -0
  24. package/dist/providers/GoogleGeocodingProvider.js.map +1 -0
  25. package/dist/providers/HereGeocodingProvider.d.ts +20 -0
  26. package/dist/providers/HereGeocodingProvider.d.ts.map +1 -0
  27. package/dist/providers/HereGeocodingProvider.js +107 -0
  28. package/dist/providers/HereGeocodingProvider.js.map +1 -0
  29. package/dist/providers/index.d.ts +7 -0
  30. package/dist/providers/index.d.ts.map +1 -0
  31. package/dist/providers/index.js +7 -0
  32. package/dist/providers/index.js.map +1 -0
  33. package/dist/providers/types.d.ts +76 -0
  34. package/dist/providers/types.d.ts.map +1 -0
  35. package/dist/providers/types.js +2 -0
  36. package/dist/providers/types.js.map +1 -0
  37. package/dist/types.d.ts +1 -1
  38. package/dist/types.d.ts.map +1 -1
  39. package/package.json +4 -4
@@ -0,0 +1,125 @@
1
+ import { BaseSingleton, MJGlobal } from '@memberjunction/global';
2
+ import { LogError, LogStatus } from '@memberjunction/core';
3
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
4
+ import { GoogleGeocodingProvider } from './GoogleGeocodingProvider.js';
5
+ import { GeocodioGeocodingProvider } from './GeocodioGeocodingProvider.js';
6
+ import { HereGeocodingProvider } from './HereGeocodingProvider.js';
7
+ /**
8
+ * Singleton registry of geocoding providers. Resolves the configured provider
9
+ * by name and gracefully falls back when the requested one isn't configured.
10
+ *
11
+ * Built-in providers (Google, Geocod.io, HERE) are auto-registered on first
12
+ * access. Custom providers can be registered via Register() — they should
13
+ * extend BaseGeocodingProvider and be decorated with @RegisterClass for the
14
+ * MJ class factory if you want them resolvable by name across packages.
15
+ */
16
+ export class GeocodingProviderRegistry extends BaseSingleton {
17
+ constructor() {
18
+ super();
19
+ this.providers = new Map();
20
+ this.builtInsRegistered = false;
21
+ }
22
+ static get Instance() {
23
+ return GeocodingProviderRegistry.getInstance();
24
+ }
25
+ /** Register a provider instance under its Name. */
26
+ Register(provider) {
27
+ this.providers.set(provider.Name.toLowerCase(), provider);
28
+ }
29
+ /**
30
+ * Look up a provider by name. Returns null if no provider is registered
31
+ * under that name or the provider isn't configured (no API key).
32
+ */
33
+ Get(name) {
34
+ this.ensureBuiltInsRegistered();
35
+ const provider = this.providers.get(name.toLowerCase());
36
+ if (!provider)
37
+ return null;
38
+ if (!provider.IsConfigured())
39
+ return null;
40
+ return provider;
41
+ }
42
+ /** All registered providers regardless of configuration state. */
43
+ All() {
44
+ this.ensureBuiltInsRegistered();
45
+ return Array.from(this.providers.values());
46
+ }
47
+ /** All providers that have credentials configured. */
48
+ AllConfigured() {
49
+ return this.All().filter(p => p.IsConfigured());
50
+ }
51
+ /**
52
+ * Resolve the provider to use given an optional explicit name. Resolution order:
53
+ *
54
+ * 1. If `requestedName` is supplied → return it if configured; if not, log a
55
+ * warning and continue.
56
+ * 2. The configured default from `__mj_config_apiIntegrations.geocoding.defaultProvider`.
57
+ * 3. The first configured provider in priority order: geocodio → here → google.
58
+ * (Geocod.io first because it has the most generous free tier for US data;
59
+ * HERE second for global; Google last because of ToS storage restrictions.)
60
+ * 4. null if nothing is configured.
61
+ */
62
+ Resolve(requestedName) {
63
+ this.ensureBuiltInsRegistered();
64
+ if (requestedName) {
65
+ const explicit = this.Get(requestedName);
66
+ if (explicit)
67
+ return explicit;
68
+ LogStatus(`GeocodingProviderRegistry: requested provider "${requestedName}" is not configured; falling back to default.`);
69
+ }
70
+ const configuredDefault = this.readDefaultFromConfig();
71
+ if (configuredDefault) {
72
+ const fromConfig = this.Get(configuredDefault);
73
+ if (fromConfig)
74
+ return fromConfig;
75
+ LogError(`GeocodingProviderRegistry: default provider "${configuredDefault}" from config is not configured.`);
76
+ }
77
+ for (const name of ['geocodio', 'here', 'google']) {
78
+ const fallback = this.Get(name);
79
+ if (fallback)
80
+ return fallback;
81
+ }
82
+ return null;
83
+ }
84
+ readDefaultFromConfig() {
85
+ try {
86
+ const cfg = globalThis['__mj_config_apiIntegrations'];
87
+ const geo = cfg?.['geocoding'];
88
+ const v = geo?.['defaultProvider'];
89
+ return typeof v === 'string' && v.length > 0 ? v : null;
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ }
95
+ /**
96
+ * Register the three built-in providers on first access. We do this lazily
97
+ * (rather than at module load) so consumers who only want one provider
98
+ * don't pay for class instantiation of the others until needed.
99
+ *
100
+ * Uses MJGlobal.ClassFactory to honor any @RegisterClass overrides, so
101
+ * downstream packages can substitute their own implementations.
102
+ */
103
+ ensureBuiltInsRegistered() {
104
+ if (this.builtInsRegistered)
105
+ return;
106
+ this.builtInsRegistered = true;
107
+ const factory = MJGlobal.Instance.ClassFactory;
108
+ const builtIns = [
109
+ ['google', GoogleGeocodingProvider],
110
+ ['geocodio', GeocodioGeocodingProvider],
111
+ ['here', HereGeocodingProvider]
112
+ ];
113
+ for (const [name, ctor] of builtIns) {
114
+ try {
115
+ const instance = factory.CreateInstance(BaseGeocodingProvider, name)
116
+ ?? new ctor();
117
+ this.providers.set(name, instance);
118
+ }
119
+ catch (e) {
120
+ LogError(`GeocodingProviderRegistry: failed to instantiate built-in provider "${name}": ${e instanceof Error ? e.message : String(e)}`);
121
+ }
122
+ }
123
+ }
124
+ }
125
+ //# sourceMappingURL=GeocodingProviderRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeocodingProviderRegistry.js","sourceRoot":"","sources":["../../src/providers/GeocodingProviderRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
2
+ import { GeocodeRequest, ProviderGeocodeResult, ReverseGeocodeRequest } from './types.js';
3
+ /**
4
+ * Geocod.io provider. US, Canada, UK, and Australia only — not global.
5
+ * Free tier: 2,500 lookups/day. Permanent storage permitted by ToS.
6
+ */
7
+ export declare class GeocodioGeocodingProvider extends BaseGeocodingProvider {
8
+ readonly Name = "geocodio";
9
+ readonly SupportedCountries: readonly ["US", "CA", "GB", "AU"];
10
+ readonly AllowsPersistentStorage = true;
11
+ IsConfigured(): boolean;
12
+ Geocode(req: GeocodeRequest): Promise<ProviderGeocodeResult | null>;
13
+ ReverseGeocode(req: ReverseGeocodeRequest): Promise<ProviderGeocodeResult | null>;
14
+ private getApiKey;
15
+ private toResult;
16
+ }
17
+ //# sourceMappingURL=GeocodioGeocodingProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeocodioGeocodingProvider.d.ts","sourceRoot":"","sources":["../../src/providers/GeocodioGeocodingProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAgCvF;;;GAGG;AACH,qBACa,yBAA0B,SAAQ,qBAAqB;IAChE,SAAgB,IAAI,cAAc;IAClC,SAAgB,kBAAkB,oCAAqC;IACvE,SAAgB,uBAAuB,QAAQ;IAExC,YAAY,IAAI,OAAO;IAIjB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAenE,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAS9F,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,QAAQ;CA8CnB"}
@@ -0,0 +1,109 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { RegisterClass } from '@memberjunction/global';
8
+ import { LogStatus } from '@memberjunction/core';
9
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
10
+ /**
11
+ * Geocod.io provider. US, Canada, UK, and Australia only — not global.
12
+ * Free tier: 2,500 lookups/day. Permanent storage permitted by ToS.
13
+ */
14
+ let GeocodioGeocodingProvider = class GeocodioGeocodingProvider extends BaseGeocodingProvider {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.Name = 'geocodio';
18
+ this.SupportedCountries = ['US', 'CA', 'GB', 'AU'];
19
+ this.AllowsPersistentStorage = true;
20
+ }
21
+ IsConfigured() {
22
+ return this.getApiKey() != null;
23
+ }
24
+ async Geocode(req) {
25
+ const apiKey = this.getApiKey();
26
+ if (!apiKey)
27
+ return null;
28
+ const params = new URLSearchParams({ q: req.AddressString, api_key: apiKey, limit: '1' });
29
+ if (req.CountryCode)
30
+ params.set('country', req.CountryCode);
31
+ const url = `https://api.geocod.io/v1.7/geocode?${params.toString()}`;
32
+ const data = await this.fetchJson(url);
33
+ if (!data)
34
+ return null;
35
+ if (data.error || !data.results?.length) {
36
+ if (data.error)
37
+ LogStatus(`Geocod.io: ${data.error}`);
38
+ return null;
39
+ }
40
+ return this.toResult(data.results[0]);
41
+ }
42
+ async ReverseGeocode(req) {
43
+ const apiKey = this.getApiKey();
44
+ if (!apiKey)
45
+ return null;
46
+ const url = `https://api.geocod.io/v1.7/reverse?q=${req.Latitude},${req.Longitude}&api_key=${apiKey}&limit=1`;
47
+ const data = await this.fetchJson(url);
48
+ if (!data || !data.results?.length)
49
+ return null;
50
+ return this.toResult(data.results[0]);
51
+ }
52
+ getApiKey() {
53
+ return this.resolveCredential(['GEOCODIO_API_KEY'], 'geocodio.apiKey');
54
+ }
55
+ toResult(r) {
56
+ // Geocod.io accuracy_type maps cleanly to our precision enum.
57
+ // accuracy is already 0.0–1.0.
58
+ let precision = 'city';
59
+ switch (r.accuracy_type) {
60
+ case 'rooftop':
61
+ case 'point':
62
+ case 'range_interpolation':
63
+ case 'nearest_rooftop_match':
64
+ precision = 'exact';
65
+ break;
66
+ case 'street_center':
67
+ case 'intersection':
68
+ precision = 'exact';
69
+ break;
70
+ case 'place':
71
+ precision = 'city';
72
+ break;
73
+ case 'county':
74
+ precision = 'county';
75
+ break;
76
+ case 'state':
77
+ precision = 'state_province';
78
+ break;
79
+ default:
80
+ precision = r.address_components.zip ? 'postal_code' : 'city';
81
+ }
82
+ const c = r.address_components;
83
+ const line1 = c.formatted_street
84
+ ? [c.number, c.formatted_street].filter(Boolean).join(' ')
85
+ : [c.number, c.predirectional, c.street, c.suffix].filter(Boolean).join(' ');
86
+ const line2 = c.secondaryunit
87
+ ? [c.secondaryunit, c.secondarynumber].filter(Boolean).join(' ')
88
+ : null;
89
+ return {
90
+ Latitude: r.location.lat,
91
+ Longitude: r.location.lng,
92
+ Precision: precision,
93
+ Confidence: this.normalizeConfidence(r.accuracy),
94
+ FormattedAddress: r.formatted_address,
95
+ CountryCode: c.country ?? null,
96
+ StateProvinceCode: c.state ?? null,
97
+ StateProvinceName: c.state ?? null,
98
+ City: c.city ?? null,
99
+ PostalCode: c.zip ?? null,
100
+ Line1: line1 || null,
101
+ Line2: line2
102
+ };
103
+ }
104
+ };
105
+ GeocodioGeocodingProvider = __decorate([
106
+ RegisterClass(BaseGeocodingProvider, 'geocodio')
107
+ ], GeocodioGeocodingProvider);
108
+ export { GeocodioGeocodingProvider };
109
+ //# sourceMappingURL=GeocodioGeocodingProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GeocodioGeocodingProvider.js","sourceRoot":"","sources":["../../src/providers/GeocodioGeocodingProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
2
+ import { GeocodeRequest, ProviderGeocodeResult, ReverseGeocodeRequest } from './types.js';
3
+ /**
4
+ * Google Maps Geocoding API provider.
5
+ *
6
+ * Note on persistent storage: Google Maps Platform ToS technically forbid
7
+ * indefinite storage of geocoding results unless displayed on a Google Map.
8
+ * We expose `AllowsPersistentStorage = true` for backwards compatibility
9
+ * (the existing system already persists Google results) but customers with
10
+ * strict compliance posture should use Geocod.io or HERE as the default.
11
+ */
12
+ export declare class GoogleGeocodingProvider extends BaseGeocodingProvider {
13
+ readonly Name = "google";
14
+ readonly SupportedCountries: "global";
15
+ readonly AllowsPersistentStorage = true;
16
+ IsConfigured(): boolean;
17
+ Geocode(req: GeocodeRequest): Promise<ProviderGeocodeResult | null>;
18
+ ReverseGeocode(req: ReverseGeocodeRequest): Promise<ProviderGeocodeResult | null>;
19
+ private getApiKey;
20
+ private toResult;
21
+ }
22
+ //# sourceMappingURL=GoogleGeocodingProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleGeocodingProvider.d.ts","sourceRoot":"","sources":["../../src/providers/GoogleGeocodingProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAsBvF;;;;;;;;GAQG;AACH,qBACa,uBAAwB,SAAQ,qBAAqB;IAC9D,SAAgB,IAAI,YAAY;IAChC,SAAgB,kBAAkB,EAAG,QAAQ,CAAU;IACvD,SAAgB,uBAAuB,QAAQ;IAExC,YAAY,IAAI,OAAO;IAIjB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAenE,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAS9F,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,QAAQ;CAoCnB"}
@@ -0,0 +1,110 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { RegisterClass } from '@memberjunction/global';
8
+ import { LogStatus } from '@memberjunction/core';
9
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
10
+ /**
11
+ * Google Maps Geocoding API provider.
12
+ *
13
+ * Note on persistent storage: Google Maps Platform ToS technically forbid
14
+ * indefinite storage of geocoding results unless displayed on a Google Map.
15
+ * We expose `AllowsPersistentStorage = true` for backwards compatibility
16
+ * (the existing system already persists Google results) but customers with
17
+ * strict compliance posture should use Geocod.io or HERE as the default.
18
+ */
19
+ let GoogleGeocodingProvider = class GoogleGeocodingProvider extends BaseGeocodingProvider {
20
+ constructor() {
21
+ super(...arguments);
22
+ this.Name = 'google';
23
+ this.SupportedCountries = 'global';
24
+ this.AllowsPersistentStorage = true;
25
+ }
26
+ IsConfigured() {
27
+ return this.getApiKey() != null;
28
+ }
29
+ async Geocode(req) {
30
+ const apiKey = this.getApiKey();
31
+ if (!apiKey)
32
+ return null;
33
+ const params = new URLSearchParams({ address: req.AddressString, key: apiKey });
34
+ if (req.CountryCode)
35
+ params.set('region', req.CountryCode.toLowerCase());
36
+ const url = `https://maps.googleapis.com/maps/api/geocode/json?${params.toString()}`;
37
+ const data = await this.fetchJson(url);
38
+ if (!data)
39
+ return null;
40
+ if (data.status !== 'OK' || !data.results?.length) {
41
+ LogStatus(`Google geocoder returned status "${data.status}" for "${req.AddressString}"`);
42
+ return null;
43
+ }
44
+ return this.toResult(data.results[0]);
45
+ }
46
+ async ReverseGeocode(req) {
47
+ const apiKey = this.getApiKey();
48
+ if (!apiKey)
49
+ return null;
50
+ const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${req.Latitude},${req.Longitude}&key=${apiKey}`;
51
+ const data = await this.fetchJson(url);
52
+ if (!data || data.status !== 'OK' || !data.results?.length)
53
+ return null;
54
+ return this.toResult(data.results[0]);
55
+ }
56
+ getApiKey() {
57
+ return this.resolveCredential(['GOOGLE_GEOCODING_API_KEY', 'GOOGLE_MAPS_API_KEY'], 'google.geocoding.apiKey');
58
+ }
59
+ toResult(r) {
60
+ const comp = (type, useShort = false) => {
61
+ const c = r.address_components.find(x => x.types.includes(type));
62
+ if (!c)
63
+ return null;
64
+ return useShort ? c.short_name : c.long_name;
65
+ };
66
+ const streetNumber = comp('street_number');
67
+ const route = comp('route');
68
+ const line1 = [streetNumber, route].filter(Boolean).join(' ') || null;
69
+ // Map Google's location_type to our enum + a normalized confidence proxy.
70
+ let precision = 'city';
71
+ let confidence = null;
72
+ switch (r.geometry.location_type) {
73
+ case 'ROOFTOP':
74
+ precision = 'exact';
75
+ confidence = 1.0;
76
+ break;
77
+ case 'RANGE_INTERPOLATED':
78
+ precision = 'exact';
79
+ confidence = 0.85;
80
+ break;
81
+ case 'GEOMETRIC_CENTER':
82
+ precision = 'city';
83
+ confidence = 0.5;
84
+ break;
85
+ case 'APPROXIMATE':
86
+ precision = 'state_province';
87
+ confidence = 0.3;
88
+ break;
89
+ }
90
+ return {
91
+ Latitude: r.geometry.location.lat,
92
+ Longitude: r.geometry.location.lng,
93
+ Precision: precision,
94
+ Confidence: confidence,
95
+ FormattedAddress: r.formatted_address,
96
+ CountryCode: comp('country', true),
97
+ StateProvinceCode: comp('administrative_area_level_1', true),
98
+ StateProvinceName: comp('administrative_area_level_1'),
99
+ City: comp('locality') ?? comp('postal_town'),
100
+ PostalCode: comp('postal_code'),
101
+ Line1: line1,
102
+ Line2: comp('subpremise')
103
+ };
104
+ }
105
+ };
106
+ GoogleGeocodingProvider = __decorate([
107
+ RegisterClass(BaseGeocodingProvider, 'google')
108
+ ], GoogleGeocodingProvider);
109
+ export { GoogleGeocodingProvider };
110
+ //# sourceMappingURL=GoogleGeocodingProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleGeocodingProvider.js","sourceRoot":"","sources":["../../src/providers/GoogleGeocodingProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
2
+ import { GeocodeRequest, ProviderGeocodeResult, ReverseGeocodeRequest } from './types.js';
3
+ /**
4
+ * HERE Geocoding & Search API provider. Global coverage.
5
+ * Free tier (Freemium plan): 250k requests/month. Permanent storage permitted.
6
+ *
7
+ * Uses /v1/discover for forward geocoding because it accepts free-form input
8
+ * (better for messy CRM data) and /v1/revgeocode for reverse.
9
+ */
10
+ export declare class HereGeocodingProvider extends BaseGeocodingProvider {
11
+ readonly Name = "here";
12
+ readonly SupportedCountries: "global";
13
+ readonly AllowsPersistentStorage = true;
14
+ IsConfigured(): boolean;
15
+ Geocode(req: GeocodeRequest): Promise<ProviderGeocodeResult | null>;
16
+ ReverseGeocode(req: ReverseGeocodeRequest): Promise<ProviderGeocodeResult | null>;
17
+ private getApiKey;
18
+ private toResult;
19
+ }
20
+ //# sourceMappingURL=HereGeocodingProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HereGeocodingProvider.d.ts","sourceRoot":"","sources":["../../src/providers/HereGeocodingProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAiCvF;;;;;;GAMG;AACH,qBACa,qBAAsB,SAAQ,qBAAqB;IAC5D,SAAgB,IAAI,UAAU;IAC9B,SAAgB,kBAAkB,EAAG,QAAQ,CAAU;IACvD,SAAgB,uBAAuB,QAAQ;IAExC,YAAY,IAAI,OAAO;IAIjB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAqBnE,cAAc,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC;IAS9F,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,QAAQ;CAsCnB"}
@@ -0,0 +1,107 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { RegisterClass } from '@memberjunction/global';
8
+ import { LogStatus } from '@memberjunction/core';
9
+ import { BaseGeocodingProvider } from './BaseGeocodingProvider.js';
10
+ /**
11
+ * HERE Geocoding & Search API provider. Global coverage.
12
+ * Free tier (Freemium plan): 250k requests/month. Permanent storage permitted.
13
+ *
14
+ * Uses /v1/discover for forward geocoding because it accepts free-form input
15
+ * (better for messy CRM data) and /v1/revgeocode for reverse.
16
+ */
17
+ let HereGeocodingProvider = class HereGeocodingProvider extends BaseGeocodingProvider {
18
+ constructor() {
19
+ super(...arguments);
20
+ this.Name = 'here';
21
+ this.SupportedCountries = 'global';
22
+ this.AllowsPersistentStorage = true;
23
+ }
24
+ IsConfigured() {
25
+ return this.getApiKey() != null;
26
+ }
27
+ async Geocode(req) {
28
+ const apiKey = this.getApiKey();
29
+ if (!apiKey)
30
+ return null;
31
+ // HERE's /discover requires either an `at` (lat,lng bias point) or an `in`
32
+ // (country/circle/bbox) filter. Use country bias when available, else fall
33
+ // back to a global circle centered on 0,0 with a huge radius.
34
+ const params = new URLSearchParams({ q: req.AddressString, limit: '1', apiKey });
35
+ if (req.CountryCode) {
36
+ params.set('in', `countryCode:${req.CountryCode.toUpperCase()}`);
37
+ }
38
+ else {
39
+ params.set('at', '0,0');
40
+ }
41
+ const url = `https://discover.search.hereapi.com/v1/discover?${params.toString()}`;
42
+ const data = await this.fetchJson(url);
43
+ if (!data?.items?.length) {
44
+ LogStatus(`HERE geocoder returned no results for "${req.AddressString}"`);
45
+ return null;
46
+ }
47
+ return this.toResult(data.items[0]);
48
+ }
49
+ async ReverseGeocode(req) {
50
+ const apiKey = this.getApiKey();
51
+ if (!apiKey)
52
+ return null;
53
+ const url = `https://revgeocode.search.hereapi.com/v1/revgeocode?at=${req.Latitude},${req.Longitude}&limit=1&apiKey=${apiKey}`;
54
+ const data = await this.fetchJson(url);
55
+ if (!data?.items?.length)
56
+ return null;
57
+ return this.toResult(data.items[0]);
58
+ }
59
+ getApiKey() {
60
+ return this.resolveCredential(['HERE_API_KEY', 'HERE_MAPS_API_KEY'], 'here.apiKey');
61
+ }
62
+ toResult(item) {
63
+ let precision = 'city';
64
+ switch (item.resultType) {
65
+ case 'houseNumber':
66
+ case 'place':
67
+ case 'pointOfInterest':
68
+ precision = 'exact';
69
+ break;
70
+ case 'street':
71
+ precision = 'exact';
72
+ break;
73
+ case 'postalCodePoint':
74
+ precision = 'postal_code';
75
+ break;
76
+ case 'locality':
77
+ case 'administrativeArea':
78
+ precision = item.address.city ? 'city' : 'state_province';
79
+ break;
80
+ default:
81
+ precision = 'city';
82
+ }
83
+ // HERE's queryScore is already 0.0–1.0.
84
+ const confidence = this.normalizeConfidence(item.scoring?.queryScore ?? null);
85
+ const a = item.address;
86
+ const line1 = [a.houseNumber, a.street].filter(Boolean).join(' ') || null;
87
+ return {
88
+ Latitude: item.position.lat,
89
+ Longitude: item.position.lng,
90
+ Precision: precision,
91
+ Confidence: confidence,
92
+ FormattedAddress: a.label ?? null,
93
+ CountryCode: a.countryCode ?? null,
94
+ StateProvinceCode: a.stateCode ?? null,
95
+ StateProvinceName: a.state ?? null,
96
+ City: a.city ?? null,
97
+ PostalCode: a.postalCode ?? null,
98
+ Line1: line1,
99
+ Line2: null
100
+ };
101
+ }
102
+ };
103
+ HereGeocodingProvider = __decorate([
104
+ RegisterClass(BaseGeocodingProvider, 'here')
105
+ ], HereGeocodingProvider);
106
+ export { HereGeocodingProvider };
107
+ //# sourceMappingURL=HereGeocodingProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HereGeocodingProvider.js","sourceRoot":"","sources":["../../src/providers/HereGeocodingProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export * from './types.js';
2
+ export * from './BaseGeocodingProvider.js';
3
+ export * from './GoogleGeocodingProvider.js';
4
+ export * from './GeocodioGeocodingProvider.js';
5
+ export * from './HereGeocodingProvider.js';
6
+ export * from './GeocodingProviderRegistry.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './types.js';
2
+ export * from './BaseGeocodingProvider.js';
3
+ export * from './GoogleGeocodingProvider.js';
4
+ export * from './GeocodioGeocodingProvider.js';
5
+ export * from './HereGeocodingProvider.js';
6
+ export * from './GeocodingProviderRegistry.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC"}