@chaosity/location-client 0.8.0 → 0.10.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 (54) hide show
  1. package/README.md +264 -42
  2. package/dist/adapters/GeoPlaces.d.ts +30 -3
  3. package/dist/adapters/GeoPlaces.js +5 -1
  4. package/dist/cjs/adapters/GeoPlaces.d.ts +30 -3
  5. package/dist/cjs/adapters/GeoPlaces.js +5 -4
  6. package/dist/cjs/client/GeoPlacesClient.d.ts +16 -4
  7. package/dist/cjs/client/GeoPlacesClient.js +24 -10
  8. package/dist/cjs/client/commands.d.ts +159 -0
  9. package/dist/cjs/client/commands.js +108 -0
  10. package/dist/cjs/errors/LocationServiceException.d.ts +28 -1
  11. package/dist/cjs/errors/LocationServiceException.js +31 -2
  12. package/dist/cjs/index.d.ts +5 -3
  13. package/dist/cjs/index.js +17 -1
  14. package/dist/cjs/maps/mapEnums.d.ts +82 -4
  15. package/dist/cjs/maps/mapEnums.js +98 -5
  16. package/dist/cjs/maps/mapStyle.d.ts +87 -10
  17. package/dist/cjs/maps/mapStyle.js +28 -5
  18. package/dist/cjs/maps/staticMap.d.ts +40 -0
  19. package/dist/cjs/maps/staticMap.js +4 -0
  20. package/dist/cjs/server/LocationServiceConnector.d.ts +23 -5
  21. package/dist/cjs/server/LocationServiceConnector.js +32 -14
  22. package/dist/cjs/transport/endpoints.js +3 -0
  23. package/dist/cjs/transport/http.d.ts +2 -2
  24. package/dist/cjs/transport/http.js +2 -2
  25. package/dist/cjs/types/index.d.ts +6 -5
  26. package/dist/cjs/utils/tokenClaims.d.ts +37 -13
  27. package/dist/cjs/utils/tokenClaims.js +36 -14
  28. package/dist/client/GeoPlacesClient.d.ts +16 -4
  29. package/dist/client/GeoPlacesClient.js +24 -10
  30. package/dist/client/commands.d.ts +159 -0
  31. package/dist/client/commands.js +97 -0
  32. package/dist/errors/LocationServiceException.d.ts +28 -1
  33. package/dist/errors/LocationServiceException.js +30 -1
  34. package/dist/index.d.ts +5 -3
  35. package/dist/index.js +7 -2
  36. package/dist/maps/mapEnums.d.ts +82 -4
  37. package/dist/maps/mapEnums.js +97 -4
  38. package/dist/maps/mapStyle.d.ts +87 -10
  39. package/dist/maps/mapStyle.js +28 -5
  40. package/dist/maps/staticMap.d.ts +40 -0
  41. package/dist/maps/staticMap.js +4 -0
  42. package/dist/server/LocationServiceConnector.d.ts +23 -5
  43. package/dist/server/LocationServiceConnector.js +32 -14
  44. package/dist/transport/endpoints.js +3 -0
  45. package/dist/transport/http.d.ts +2 -2
  46. package/dist/transport/http.js +2 -2
  47. package/dist/types/index.d.ts +6 -5
  48. package/dist/utils/tokenClaims.d.ts +37 -13
  49. package/dist/utils/tokenClaims.js +36 -14
  50. package/package.json +1 -1
  51. package/dist/cjs/utils/roundPosition.d.ts +0 -66
  52. package/dist/cjs/utils/roundPosition.js +0 -109
  53. package/dist/utils/roundPosition.d.ts +0 -66
  54. package/dist/utils/roundPosition.js +0 -104
@@ -41,10 +41,28 @@
41
41
  * client-side mirror and every value below was additionally confirmed against
42
42
  * the live geo-maps API on 2026-08-26. If the API starts rejecting something
43
43
  * listed here, its generated list is the authority.
44
+ *
45
+ * SOME VALUES ARE PLAN FEATURES
46
+ *
47
+ * A list tagged `@planFeature <feature>` holds values the application's plan
48
+ * must include — every value, or only the ones named after the dash (#55). A
49
+ * value the plan lacks is refused 403 `FeatureNotEntitledException`, naming
50
+ * the feature, so a picker built from `MAP_STYLES` offers Satellite to an
51
+ * application that will be refused it. Leave those out of a picker, or mark
52
+ * them. Which plan includes which feature is not this file's to say — it can
53
+ * change without a release: see https://chaosity.cloud/pricing. A list with no
54
+ * tag is open to every plan.
44
55
  */
45
56
  Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.MAP_FEATURE_MODES = exports.SCALE_BAR_UNITS = exports.LABEL_SIZES = exports.SPRITE_VARIANTS = exports.TRAVEL_MODES = exports.TRAFFIC_MODES = exports.CONTOUR_DENSITIES = exports.BUILDINGS = exports.TERRAINS = exports.COLOR_SCHEMES = exports.STATIC_MAP_STYLES = exports.MAP_STYLES = void 0;
47
- /** Map styles for the style descriptor. */
57
+ exports.STYLE_POI_CATEGORIES = exports.POI_DENSITIES = exports.MAP_FEATURE_MODES = exports.SCALE_BAR_UNITS = exports.LABEL_SIZES = exports.SPRITE_VARIANTS = exports.TRAVEL_MODES = exports.TRAFFIC_MODES = exports.CONTOUR_DENSITIES = exports.BUILDINGS = exports.TERRAINS = exports.COLOR_SCHEMES = exports.STATIC_MAP_STYLES = exports.MAP_STYLES = void 0;
58
+ /**
59
+ * Map styles for the style descriptor.
60
+ *
61
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
62
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
63
+ *
64
+ * @planFeature satellite — Hybrid, Satellite
65
+ */
48
66
  exports.MAP_STYLES = [
49
67
  'Hybrid',
50
68
  'Monochrome',
@@ -56,13 +74,35 @@ exports.MAP_STYLES = [
56
74
  *
57
75
  * `/maps/static/*` takes only Satellite and Standard. Passing Hybrid or
58
76
  * Monochrome there is a 400, so the two lists are not interchangeable.
77
+ *
78
+ * A static map with no `style` is a Satellite render, so it needs the
79
+ * `satellite` feature as well.
80
+ *
81
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
82
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
83
+ *
84
+ * @planFeature satellite — Satellite
59
85
  */
60
86
  exports.STATIC_MAP_STYLES = ['Satellite', 'Standard'];
61
87
  /** Light or dark cartography. Not applicable to the raster styles. */
62
88
  exports.COLOR_SCHEMES = ['Dark', 'Light'];
63
- /** Terrain overlay. `Hillshade` is shaded relief; `Terrain3D` is elevation. */
89
+ /**
90
+ * Terrain overlay. `Hillshade` is shaded relief; `Terrain3D` is elevation.
91
+ *
92
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
93
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
94
+ *
95
+ * @planFeature terrain
96
+ */
64
97
  exports.TERRAINS = ['Hillshade', 'Terrain3D'];
65
- /** 3D building extrusions. One value today, kept a list for when that changes. */
98
+ /**
99
+ * 3D building extrusions. A list, like the others, for when Amazon adds a value.
100
+ *
101
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
102
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
103
+ *
104
+ * @planFeature buildings
105
+ */
66
106
  exports.BUILDINGS = ['Buildings3D'];
67
107
  /**
68
108
  * Elevation contour line density.
@@ -70,6 +110,11 @@ exports.BUILDINGS = ['Buildings3D'];
70
110
  * All three work. An earlier version of this library documented `Medium` as
71
111
  * "the only value currently supported by the AWS SDK", which was wrong — `High`
72
112
  * and `Low` were both confirmed against the live API on 2026-08-26.
113
+ *
114
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
115
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
116
+ *
117
+ * @planFeature contours
73
118
  */
74
119
  exports.CONTOUR_DENSITIES = ['High', 'Low', 'Medium'];
75
120
  /**
@@ -77,9 +122,21 @@ exports.CONTOUR_DENSITIES = ['High', 'Low', 'Medium'];
77
122
  *
78
123
  * `Congestion` was previously missing from this library's types, so it could
79
124
  * not be requested from TypeScript even though the API accepts it.
125
+ *
126
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
127
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
128
+ *
129
+ * @planFeature traffic
80
130
  */
81
131
  exports.TRAFFIC_MODES = ['All', 'Congestion'];
82
- /** Routing overlays. Sent as a comma-separated list; each entry is checked. */
132
+ /**
133
+ * Routing overlays. Sent as a comma-separated list; each entry is checked.
134
+ *
135
+ * Refused on a plan without it: 403 `FeatureNotEntitledException`, see
136
+ * `FEATURE_NOT_ENTITLED` and the note at the top of this file.
137
+ *
138
+ * @planFeature travel-modes
139
+ */
83
140
  exports.TRAVEL_MODES = ['Transit', 'Truck'];
84
141
  /** Sprite sheet variant. One value today. */
85
142
  exports.SPRITE_VARIANTS = ['Default'];
@@ -101,3 +158,39 @@ exports.SCALE_BAR_UNITS = [
101
158
  * `setPoiVisibility` instead.
102
159
  */
103
160
  exports.MAP_FEATURE_MODES = ['Disabled', 'Enabled'];
161
+ /**
162
+ * How many points of interest the style descriptor draws (#40). `Off` removes
163
+ * the poi layers outright; the others thin them out or add more.
164
+ *
165
+ * Standard and Hybrid accept it; Monochrome and Satellite answer 400 naming
166
+ * the parameter, as they do for `STYLE_POI_CATEGORIES`. That is the API's rule
167
+ * to answer, like every combination rule above.
168
+ */
169
+ exports.POI_DENSITIES = [
170
+ 'Default',
171
+ 'Dense',
172
+ 'Off',
173
+ 'Sparse',
174
+ 'VeryDense',
175
+ 'VerySparse',
176
+ ];
177
+ /**
178
+ * The categories of point of interest a style descriptor can be limited to
179
+ * (#40). Sent as a comma-separated list; only the named categories are drawn.
180
+ *
181
+ * Not `PoiCategory`: that name is already this package's type for
182
+ * `setPoiVisibility`'s layer groups, which hide categories on a map already
183
+ * loaded. This one asks the API for a descriptor that draws only these — the
184
+ * SDK's name qualified the way `TRAFFIC_MODES` and `SPRITE_VARIANTS` are.
185
+ */
186
+ exports.STYLE_POI_CATEGORIES = [
187
+ 'Accommodations',
188
+ 'BusinessAndServices',
189
+ 'Entertainment',
190
+ 'FacilitiesAndBuildings',
191
+ 'FoodAndDrink',
192
+ 'LeisureAndOutdoor',
193
+ 'Shopping',
194
+ 'SightsAndMuseums',
195
+ 'Transportation',
196
+ ];
@@ -1,6 +1,6 @@
1
1
  import type { StyleSpecification } from 'maplibre-gl';
2
2
  import type { RequestOptions } from '../transport/http.js';
3
- import type { Buildings, ColorScheme, ContourDensity, MapStyle, Terrain, TrafficMode, TravelMode } from './mapEnums.js';
3
+ import type { Buildings, ColorScheme, ContourDensity, MapStyle, PoiDensity, StylePoiCategory, Terrain, TrafficMode, TravelMode } from './mapEnums.js';
4
4
  /**
5
5
  * Options for building an AWS Location Service map style URL.
6
6
  * All parameters map directly to query parameters supported by the style descriptor endpoint.
@@ -8,15 +8,46 @@ import type { Buildings, ColorScheme, ContourDensity, MapStyle, Terrain, Traffic
8
8
  * Values are CASE SENSITIVE — the API rejects a wrong-cased one with a 400 that
9
9
  * names the right spelling. Import the arrays from `mapEnums` to build pickers
10
10
  * rather than typing the values, and the case is right by construction.
11
+ *
12
+ * The options tagged `@planFeature` are PLAN FEATURES, each tag naming its
13
+ * feature (#55). An application whose plan does not include one is
14
+ * refused 403 `FeatureNotEntitledException` — `isFeatureNotEntitled` on the
15
+ * error — before anything is drawn, and the message names the feature and the
16
+ * option that asked for it. `colorScheme`, `poiDensity` and `poiCategories`
17
+ * are open to every plan, as are the Standard and Monochrome styles. Which plan
18
+ * includes which feature is not this package's to say, since it can change
19
+ * without a release: see https://chaosity.cloud/pricing.
11
20
  */
12
21
  export interface MapStyleOptions {
13
22
  /** Color scheme for the map (default: Light). Not applicable to Satellite/Hybrid styles. */
14
23
  colorScheme?: ColorScheme;
15
- /** ISO 3166-1 alpha-3 country code for political boundary perspective (e.g. 'IND', 'TUR'). */
24
+ /**
25
+ * ISO 3166-1 alpha-3 country code for political boundary perspective
26
+ * (e.g. 'IND', 'TUR').
27
+ *
28
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
29
+ * `FEATURE_NOT_ENTITLED`).
30
+ *
31
+ * @planFeature political-view
32
+ */
16
33
  politicalView?: string;
17
- /** Terrain overlay type. */
34
+ /**
35
+ * Terrain overlay type.
36
+ *
37
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
38
+ * `FEATURE_NOT_ENTITLED`).
39
+ *
40
+ * @planFeature terrain
41
+ */
18
42
  terrain?: Terrain;
19
- /** Enable 3D building extrusions. */
43
+ /**
44
+ * Enable 3D building extrusions.
45
+ *
46
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
47
+ * `FEATURE_NOT_ENTITLED`).
48
+ *
49
+ * @planFeature buildings
50
+ */
20
51
  buildings?: Buildings;
21
52
  /**
22
53
  * Elevation contour line density.
@@ -24,6 +55,11 @@ export interface MapStyleOptions {
24
55
  * All of High, Low and Medium work. This was previously typed as `'Medium'`
25
56
  * alone, documented as "the only value currently supported by the AWS SDK",
26
57
  * which was wrong — the other two were confirmed against the live API.
58
+ *
59
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
60
+ * `FEATURE_NOT_ENTITLED`).
61
+ *
62
+ * @planFeature contours
27
63
  */
28
64
  contourDensity?: ContourDensity;
29
65
  /**
@@ -34,21 +70,48 @@ export interface MapStyleOptions {
34
70
  *
35
71
  * Valid on its own, but NOT with every style: `Satellite` + `All` answers
36
72
  * 400 "Traffic is not supported for style." Amazon owns that rule.
73
+ *
74
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
75
+ * `FEATURE_NOT_ENTITLED`).
76
+ *
77
+ * @planFeature traffic
37
78
  */
38
79
  traffic?: TrafficMode;
39
- /** Travel mode overlays for routing-specific features. */
80
+ /**
81
+ * Travel mode overlays for routing-specific features.
82
+ *
83
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
84
+ * `FEATURE_NOT_ENTITLED`).
85
+ *
86
+ * @planFeature travel-modes
87
+ */
40
88
  travelModes?: TravelMode[];
89
+ /**
90
+ * How many points of interest to draw; `Off` draws none. Standard and
91
+ * Hybrid only — Monochrome and Satellite answer 400.
92
+ */
93
+ poiDensity?: PoiDensity;
94
+ /**
95
+ * Draw only these categories of point of interest. Standard and Hybrid
96
+ * only, like `poiDensity`.
97
+ */
98
+ poiCategories?: StylePoiCategory[];
41
99
  }
42
100
  /**
43
101
  * Build a map style descriptor URL for the Location Service API.
44
102
  *
103
+ * MapLibre fetches this URL itself, so a refusal of it never reaches this
104
+ * package's error type — see `fetchMapStyle` for what it looks like instead.
105
+ *
45
106
  * @param apiUrl - Base URL of the Location Service API
46
- * @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
47
- * @param options - Optional style parameters
107
+ * @param mapStyle - Map style name: 'Standard' or 'Monochrome', or 'Satellite'
108
+ * or 'Hybrid', which need the `satellite` plan feature (see `MAP_STYLES`)
109
+ * @param options - Optional style parameters; those tagged `@planFeature` need
110
+ * that feature of the application's plan
48
111
  * @returns Full style descriptor URL
49
112
  *
50
113
  * @example
51
- * const url = buildMapStyleUrl(API_URL, 'Standard', { colorScheme: 'Dark', terrain: 'Hillshade' })
114
+ * const url = buildMapStyleUrl(API_URL, 'Standard', { colorScheme: 'Dark' })
52
115
  * map.setStyle(url)
53
116
  */
54
117
  export declare function buildMapStyleUrl(apiUrl: string, mapStyle: MapStyle, options?: MapStyleOptions): string;
@@ -63,10 +126,24 @@ export declare function buildMapStyleUrl(apiUrl: string, mapStyle: MapStyle, opt
63
126
  * `map.setStyle()`. Tile, glyph, and sprite requests still go through `transformRequest`
64
127
  * for authentication — this only pre-processes the descriptor itself.
65
128
  *
129
+ * A REFUSED OPTION. This is the path that surfaces a plan refusal as this
130
+ * package's error: an option tagged `@planFeature` that the application's plan
131
+ * does not include rejects with a `LocationServiceException` whose
132
+ * `isFeatureNotEntitled` is true (code `FeatureNotEntitledException`, status
133
+ * 403), and whose message names the feature and the option. What MapLibre
134
+ * fetches for itself — a URL from `buildMapStyleUrl` handed to `setStyle`, and
135
+ * the tiles — is refused the same way when it asks for a feature the plan
136
+ * lacks, but the refusal arrives as a MapLibre `error` event instead:
137
+ * `event.error.status` is 403, and `event.error.body` is a `Blob` holding the
138
+ * same `{ message, code }` JSON.
139
+ *
66
140
  * @param apiUrl - Base URL of the Location Service API
67
- * @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
141
+ * @param mapStyle - Map style name: 'Standard' or 'Monochrome', or 'Satellite'
142
+ * or 'Hybrid', which need the `satellite` plan feature (see `MAP_STYLES`)
68
143
  * @param getToken - Callback returning the current auth token
69
- * @param options - Style options; `language` is applied to the descriptor, all others become URL params
144
+ * @param options - Style options; `language` is applied to the descriptor, all
145
+ * others become URL params. Those tagged `@planFeature` need that feature of
146
+ * the application's plan
70
147
  * @param request - Transport options: `signal` to cancel, `timeoutMs`, `overallTimeoutMs`, `retry`
71
148
  * @returns Modified MapLibre StyleSpecification object
72
149
  *
@@ -8,13 +8,18 @@ const mapLanguage_js_1 = require("./mapLanguage.js");
8
8
  /**
9
9
  * Build a map style descriptor URL for the Location Service API.
10
10
  *
11
+ * MapLibre fetches this URL itself, so a refusal of it never reaches this
12
+ * package's error type — see `fetchMapStyle` for what it looks like instead.
13
+ *
11
14
  * @param apiUrl - Base URL of the Location Service API
12
- * @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
13
- * @param options - Optional style parameters
15
+ * @param mapStyle - Map style name: 'Standard' or 'Monochrome', or 'Satellite'
16
+ * or 'Hybrid', which need the `satellite` plan feature (see `MAP_STYLES`)
17
+ * @param options - Optional style parameters; those tagged `@planFeature` need
18
+ * that feature of the application's plan
14
19
  * @returns Full style descriptor URL
15
20
  *
16
21
  * @example
17
- * const url = buildMapStyleUrl(API_URL, 'Standard', { colorScheme: 'Dark', terrain: 'Hillshade' })
22
+ * const url = buildMapStyleUrl(API_URL, 'Standard', { colorScheme: 'Dark' })
18
23
  * map.setStyle(url)
19
24
  */
20
25
  function buildMapStyleUrl(apiUrl, mapStyle, options = {}) {
@@ -33,6 +38,10 @@ function buildMapStyleUrl(apiUrl, mapStyle, options = {}) {
33
38
  params.set('traffic', options.traffic);
34
39
  if (options.travelModes?.length)
35
40
  params.set('travel-modes', options.travelModes.join(','));
41
+ if (options.poiDensity)
42
+ params.set('poi-density', options.poiDensity);
43
+ if (options.poiCategories?.length)
44
+ params.set('poi-categories', options.poiCategories.join(','));
36
45
  const qs = params.toString();
37
46
  return `${apiUrl}/maps/${mapStyle}/descriptor${qs ? `?${qs}` : ''}`;
38
47
  }
@@ -47,10 +56,24 @@ function buildMapStyleUrl(apiUrl, mapStyle, options = {}) {
47
56
  * `map.setStyle()`. Tile, glyph, and sprite requests still go through `transformRequest`
48
57
  * for authentication — this only pre-processes the descriptor itself.
49
58
  *
59
+ * A REFUSED OPTION. This is the path that surfaces a plan refusal as this
60
+ * package's error: an option tagged `@planFeature` that the application's plan
61
+ * does not include rejects with a `LocationServiceException` whose
62
+ * `isFeatureNotEntitled` is true (code `FeatureNotEntitledException`, status
63
+ * 403), and whose message names the feature and the option. What MapLibre
64
+ * fetches for itself — a URL from `buildMapStyleUrl` handed to `setStyle`, and
65
+ * the tiles — is refused the same way when it asks for a feature the plan
66
+ * lacks, but the refusal arrives as a MapLibre `error` event instead:
67
+ * `event.error.status` is 403, and `event.error.body` is a `Blob` holding the
68
+ * same `{ message, code }` JSON.
69
+ *
50
70
  * @param apiUrl - Base URL of the Location Service API
51
- * @param mapStyle - Map style name (e.g. 'Standard', 'Monochrome', 'Satellite', 'Hybrid')
71
+ * @param mapStyle - Map style name: 'Standard' or 'Monochrome', or 'Satellite'
72
+ * or 'Hybrid', which need the `satellite` plan feature (see `MAP_STYLES`)
52
73
  * @param getToken - Callback returning the current auth token
53
- * @param options - Style options; `language` is applied to the descriptor, all others become URL params
74
+ * @param options - Style options; `language` is applied to the descriptor, all
75
+ * others become URL params. Those tagged `@planFeature` need that feature of
76
+ * the application's plan
54
77
  * @param request - Transport options: `signal` to cancel, `timeoutMs`, `overallTimeoutMs`, `retry`
55
78
  * @returns Modified MapLibre StyleSpecification object
56
79
  *
@@ -31,6 +31,17 @@ import type { ColorScheme, LabelSize, MapFeatureMode, ScaleBarUnit, StaticMapSty
31
31
  */
32
32
  /** `map`, or `map@2x` for a retina render. There is no file extension. */
33
33
  export type StaticMapFileName = 'map' | 'map@2x';
34
+ /**
35
+ * Render options for `buildStaticMapUrl` and `fetchStaticMap`.
36
+ *
37
+ * The options tagged `@planFeature` are PLAN FEATURES (#55): a Satellite
38
+ * `style` — which is also what an omitted `style` renders — needs `satellite`,
39
+ * and `politicalView` needs `political-view`. An application whose plan does
40
+ * not include one is refused 403 `FeatureNotEntitledException` —
41
+ * `isFeatureNotEntitled` on the error — and the message names the feature and
42
+ * the option. Every other option is open to every plan. Which plan includes
43
+ * which feature: https://chaosity.cloud/pricing.
44
+ */
34
45
  export interface StaticMapOptions {
35
46
  /** Pixels, 64-1500. */
36
47
  width: number;
@@ -46,6 +57,16 @@ export interface StaticMapOptions {
46
57
  radius?: number;
47
58
  padding?: number;
48
59
  cropLabels?: boolean;
60
+ /**
61
+ * `Standard` or `Satellite`. Omitted, the render is Satellite — the
62
+ * service's default — so pass `'Standard'` for a render every plan may
63
+ * request.
64
+ *
65
+ * Satellite is refused on a plan without it: 403
66
+ * `FeatureNotEntitledException` (see `FEATURE_NOT_ENTITLED`).
67
+ *
68
+ * @planFeature satellite — Satellite
69
+ */
49
70
  style?: StaticMapStyle;
50
71
  colorScheme?: ColorScheme;
51
72
  labelSize?: LabelSize;
@@ -58,6 +79,21 @@ export interface StaticMapOptions {
58
79
  scaleBarUnit?: ScaleBarUnit;
59
80
  /** Defaults to `map`. */
60
81
  fileName?: StaticMapFileName;
82
+ /**
83
+ * ISO 3166-1 alpha-3 country whose view of disputed borders to draw.
84
+ *
85
+ * Refused on a plan without it: 403 `FeatureNotEntitledException` (see
86
+ * `FEATURE_NOT_ENTITLED`).
87
+ *
88
+ * @planFeature political-view
89
+ */
90
+ politicalView?: string;
91
+ /** Label language, a BCP-47 tag such as `fr` or `zh-Hant`. */
92
+ language?: string;
93
+ /** Markers and lines in Amazon Location's compact overlay syntax. */
94
+ compactOverlay?: string;
95
+ /** A GeoJSON FeatureCollection to draw, as JSON text. */
96
+ geoJsonOverlay?: string;
61
97
  }
62
98
  /**
63
99
  * The Accept header this request must send.
@@ -72,6 +108,10 @@ export declare function buildStaticMapUrl(apiUrl: string, options: StaticMapOpti
72
108
  /**
73
109
  * Fetch a static map as a Blob.
74
110
  *
111
+ * A refused plan feature — a Satellite `style`, the default when none is
112
+ * given, or a `politicalView` — rejects with a `LocationServiceException`
113
+ * whose `isFeatureNotEntitled` is true, as `fetchMapStyle` does.
114
+ *
75
115
  * @param apiUrl Base URL of the Location Service API
76
116
  * @param options Render options; exactly one of center / boundingBox / boundedPositions
77
117
  * @param getToken Callback returning the current auth token
@@ -53,6 +53,10 @@ function buildStaticMapUrl(apiUrl, options) {
53
53
  /**
54
54
  * Fetch a static map as a Blob.
55
55
  *
56
+ * A refused plan feature — a Satellite `style`, the default when none is
57
+ * given, or a `politicalView` — rejects with a `LocationServiceException`
58
+ * whose `isFeatureNotEntitled` is true, as `fetchMapStyle` does.
59
+ *
56
60
  * @param apiUrl Base URL of the Location Service API
57
61
  * @param options Render options; exactly one of center / boundingBox / boundedPositions
58
62
  * @param getToken Callback returning the current auth token
@@ -1,3 +1,4 @@
1
+ import type { VerifyAddressResponse } from '../client/commands.js';
1
2
  import type { RequestOptions } from '../transport/http.js';
2
3
  import type { AppConfigClaims } from '../utils/tokenClaims.js';
3
4
  export interface ConnectorConfig {
@@ -56,7 +57,13 @@ export interface SendOptions extends RequestOptions {
56
57
  * ```typescript
57
58
  * // Credentials and apiUrl from the environment, Origin supplied here
58
59
  * const connector = new LocationServiceConnector({ origin: 'https://app.example.com' })
59
- * const result = await connector.send(new SearchTextCommand({ QueryText: 'Space Needle' }))
60
+ * const result = await connector.send(
61
+ * new SearchTextCommand({
62
+ * QueryText: 'Space Needle',
63
+ * // SearchText takes exactly one of BiasPosition, Filter.BoundingBox or Filter.Circle.
64
+ * BiasPosition: [-122.3493, 47.6205],
65
+ * }),
66
+ * )
60
67
  * ```
61
68
  */
62
69
  export declare class LocationServiceConnector {
@@ -77,17 +84,19 @@ export declare class LocationServiceConnector {
77
84
  private buildSource;
78
85
  /**
79
86
  * This application's own configuration, as carried on the access token
80
- * (api#65) — bias precision, and the countries it is scoped to.
87
+ * (api#65): the routes it may call, the domain its requests must come from,
88
+ * and the countries it is scoped to (#40).
81
89
  *
82
90
  * Provided so an application can SHOW its own settings: populate a country
83
91
  * selector with the markets it actually serves, label a settings screen, and
84
92
  * so on. Being a few minutes stale is cosmetic for that.
85
93
  *
86
94
  * It is not an entitlement check. See AppConfigClaims for why acting on
87
- * `countries` client-side makes requests fail that would otherwise succeed.
95
+ * any of it client-side makes requests fail that would otherwise succeed.
88
96
  *
89
- * Returns `{}` when the token carries no application config, which is the
90
- * case until one is configured in the portal.
97
+ * Every token the API issues carries `allowedResources` and `allowedDomain`;
98
+ * `countries` only once a scope is configured in the portal. Returns `{}`
99
+ * for a token carrying none of them.
91
100
  */
92
101
  getAppConfig(): Promise<AppConfigClaims>;
93
102
  /**
@@ -99,6 +108,15 @@ export declare class LocationServiceConnector {
99
108
  */
100
109
  private effectiveOrigin;
101
110
  send<TInput, TOutput>(command: TInput, options?: SendOptions): Promise<TOutput>;
111
+ /**
112
+ * Verify a PlaceId: `send(new VerifyAddressCommand({ PlaceId }))`, typed
113
+ * (#54). Resolves the full place record plus `verified`, and resolves a
114
+ * `verified: false` too — see VerifyAddressResponse for what may be stored.
115
+ *
116
+ * Billed per call, whether or not the address verifies: call it once per
117
+ * chosen PlaceId, never per keystroke.
118
+ */
119
+ verifyAddress(placeId: string, options?: SendOptions): Promise<VerifyAddressResponse>;
102
120
  private dispatchWithRetry;
103
121
  private dispatch;
104
122
  }
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LocationServiceConnector = void 0;
7
7
  const debug_1 = __importDefault(require("debug"));
8
+ const commands_js_1 = require("../client/commands.js");
8
9
  const LocationServiceException_js_1 = require("../errors/LocationServiceException.js");
9
10
  const endpoints_js_1 = require("../transport/endpoints.js");
10
11
  const errors_js_1 = require("../transport/errors.js");
11
12
  const http_js_1 = require("../transport/http.js");
12
- const roundPosition_js_1 = require("../utils/roundPosition.js");
13
13
  const tokenClaims_js_1 = require("../utils/tokenClaims.js");
14
14
  const getClientConfig_js_1 = require("./getClientConfig.js");
15
15
  const log = (0, debug_1.default)('location-client:connector');
@@ -95,7 +95,13 @@ function explainMissingOrigin(err, sentOrigin) {
95
95
  * ```typescript
96
96
  * // Credentials and apiUrl from the environment, Origin supplied here
97
97
  * const connector = new LocationServiceConnector({ origin: 'https://app.example.com' })
98
- * const result = await connector.send(new SearchTextCommand({ QueryText: 'Space Needle' }))
98
+ * const result = await connector.send(
99
+ * new SearchTextCommand({
100
+ * QueryText: 'Space Needle',
101
+ * // SearchText takes exactly one of BiasPosition, Filter.BoundingBox or Filter.Circle.
102
+ * BiasPosition: [-122.3493, 47.6205],
103
+ * }),
104
+ * )
99
105
  * ```
100
106
  */
101
107
  class LocationServiceConnector {
@@ -158,17 +164,19 @@ class LocationServiceConnector {
158
164
  }
159
165
  /**
160
166
  * This application's own configuration, as carried on the access token
161
- * (api#65) — bias precision, and the countries it is scoped to.
167
+ * (api#65): the routes it may call, the domain its requests must come from,
168
+ * and the countries it is scoped to (#40).
162
169
  *
163
170
  * Provided so an application can SHOW its own settings: populate a country
164
171
  * selector with the markets it actually serves, label a settings screen, and
165
172
  * so on. Being a few minutes stale is cosmetic for that.
166
173
  *
167
174
  * It is not an entitlement check. See AppConfigClaims for why acting on
168
- * `countries` client-side makes requests fail that would otherwise succeed.
175
+ * any of it client-side makes requests fail that would otherwise succeed.
169
176
  *
170
- * Returns `{}` when the token carries no application config, which is the
171
- * case until one is configured in the portal.
177
+ * Every token the API issues carries `allowedResources` and `allowedDomain`;
178
+ * `countries` only once a scope is configured in the portal. Returns `{}`
179
+ * for a token carrying none of them.
172
180
  */
173
181
  async getAppConfig() {
174
182
  return (0, tokenClaims_js_1.readAppConfigClaims)(await this.source().get());
@@ -196,6 +204,17 @@ class LocationServiceConnector {
196
204
  throw explainMissingOrigin(err, this.effectiveOrigin(options));
197
205
  }
198
206
  }
207
+ /**
208
+ * Verify a PlaceId: `send(new VerifyAddressCommand({ PlaceId }))`, typed
209
+ * (#54). Resolves the full place record plus `verified`, and resolves a
210
+ * `verified: false` too — see VerifyAddressResponse for what may be stored.
211
+ *
212
+ * Billed per call, whether or not the address verifies: call it once per
213
+ * chosen PlaceId, never per keystroke.
214
+ */
215
+ verifyAddress(placeId, options) {
216
+ return this.send(new commands_js_1.VerifyAddressCommand({ PlaceId: placeId }), options);
217
+ }
199
218
  async dispatchWithRetry(source, url, cmd, options) {
200
219
  const token = await source.get();
201
220
  if (!token)
@@ -220,13 +239,12 @@ class LocationServiceConnector {
220
239
  }
221
240
  }
222
241
  dispatch(url, token, cmd, options) {
223
- // The token is resolved before the request is shaped, so the precision this
224
- // application is entitled to is available (api#65). Absent claim -> the
225
- // 3 dp floor, which is what every application gets until one is configured
226
- // otherwise. Recomputed per attempt because a refreshed token may carry
227
- // different claims.
228
- const { biasDecimals } = (0, tokenClaims_js_1.readAppConfigClaims)(token);
229
- const input = (0, roundPosition_js_1.roundPositionFields)(cmd.input, biasDecimals);
242
+ // The caller's input goes out as the caller wrote it — nothing in the body
243
+ // is derived from the token any more. `BiasPosition` used to be rounded
244
+ // here to a grid sized by a token claim, so nearby callers shared a server
245
+ // cache entry; with no cache the rounding only lowered the precision the
246
+ // upstream geocoder had to work with, which moves the results rather than
247
+ // coarsening them (#51).
230
248
  // Every system header is set exactly ONCE, and the caller's own spelling of
231
249
  // each is dropped first.
232
250
  //
@@ -251,7 +269,7 @@ class LocationServiceConnector {
251
269
  Authorization: `Bearer ${token}`,
252
270
  };
253
271
  log('Sending %s request to %s', cmd.constructor?.name, url);
254
- return (0, http_js_1.requestJson)(url, { method: 'POST', headers, body: JSON.stringify(input) }, options);
272
+ return (0, http_js_1.requestJson)(url, { method: 'POST', headers, body: JSON.stringify(cmd.input) }, options);
255
273
  }
256
274
  }
257
275
  exports.LocationServiceConnector = LocationServiceConnector;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveEndpoint = resolveEndpoint;
4
4
  const client_geo_places_1 = require("@aws-sdk/client-geo-places");
5
+ const commands_js_1 = require("../client/commands.js");
5
6
  const LocationServiceException_js_1 = require("../errors/LocationServiceException.js");
6
7
  /**
7
8
  * Command class -> API path.
@@ -20,6 +21,8 @@ const ENDPOINTS = new Map([
20
21
  [client_geo_places_1.SearchNearbyCommand, '/address/search/nearby'],
21
22
  [client_geo_places_1.SearchTextCommand, '/address/search/text'],
22
23
  [client_geo_places_1.SuggestCommand, '/address/suggestion'],
24
+ // This package's own: the route has no AWS command (#54).
25
+ [commands_js_1.VerifyAddressCommand, '/address/verify'],
23
26
  ]);
24
27
  function resolveEndpoint(command) {
25
28
  for (const [CommandClass, endpoint] of ENDPOINTS) {
@@ -4,8 +4,8 @@ export declare const DEFAULT_TIMEOUT_MS = 10000;
4
4
  * Ceiling for the WHOLE call — every attempt plus every wait between them.
5
5
  *
6
6
  * `timeoutMs` bounds an attempt, not a call, and the gap between those two is
7
- * where the caller's own deadline disappears. The API answers a spent quota
8
- * with `Retry-After: 60`, which the retry loop honoured literally: two waits of
7
+ * where the caller's own deadline disappears. Nothing bounds the `Retry-After`
8
+ * a 429 carries, and the retry loop honoured one of 60 s literally: two waits of
9
9
  * a minute each, so one call could sit for ~120 s — past any Lambda budget,
10
10
  * past any HTTP gateway, and until now uncancellable (#37).
11
11
  *
@@ -17,8 +17,8 @@ exports.DEFAULT_TIMEOUT_MS = 10000;
17
17
  * Ceiling for the WHOLE call — every attempt plus every wait between them.
18
18
  *
19
19
  * `timeoutMs` bounds an attempt, not a call, and the gap between those two is
20
- * where the caller's own deadline disappears. The API answers a spent quota
21
- * with `Retry-After: 60`, which the retry loop honoured literally: two waits of
20
+ * where the caller's own deadline disappears. Nothing bounds the `Retry-After`
21
+ * a 429 carries, and the retry loop honoured one of 60 s literally: two waits of
22
22
  * a minute each, so one call could sit for ~120 s — past any Lambda budget,
23
23
  * past any HTTP gateway, and until now uncancellable (#37).
24
24
  *
@@ -42,11 +42,12 @@ export interface ClientConfig {
42
42
  refreshToken?: () => Promise<string | undefined>;
43
43
  }
44
44
  /**
45
- * Minimal interface for AWS SDK command objects.
46
- * All AWS SDK commands (AutocompleteCommand, SearchTextCommand, etc.) extend
47
- * Smithy's Command base class which has an `input` property containing the
48
- * request parameters. This interface captures what we actually need from
49
- * commands without coupling to Smithy internals.
45
+ * Minimal interface for a command object: the AWS SDK's, and this package's
46
+ * own `VerifyAddressCommand` (#54). The SDK's commands (AutocompleteCommand,
47
+ * SearchTextCommand, etc.) extend Smithy's Command base class, which has an
48
+ * `input` property containing the request parameters; `VerifyAddressCommand`
49
+ * has the same `input` and nothing else. This interface captures what we
50
+ * actually need from commands without coupling to Smithy internals.
50
51
  */
51
52
  export interface GeoPlacesCommand {
52
53
  readonly input: object;