@chaosity/location-client 0.9.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 (50) hide show
  1. package/README.md +243 -34
  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 +18 -4
  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 +25 -5
  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 +29 -3
  27. package/dist/cjs/utils/tokenClaims.js +28 -3
  28. package/dist/client/GeoPlacesClient.d.ts +16 -4
  29. package/dist/client/GeoPlacesClient.js +18 -4
  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 +25 -5
  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 +29 -3
  49. package/dist/utils/tokenClaims.js +28 -3
  50. package/package.json +1 -1
@@ -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) — today, 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,6 +5,7 @@ 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");
@@ -94,7 +95,13 @@ function explainMissingOrigin(err, sentOrigin) {
94
95
  * ```typescript
95
96
  * // Credentials and apiUrl from the environment, Origin supplied here
96
97
  * const connector = new LocationServiceConnector({ origin: 'https://app.example.com' })
97
- * 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
+ * )
98
105
  * ```
99
106
  */
100
107
  class LocationServiceConnector {
@@ -157,17 +164,19 @@ class LocationServiceConnector {
157
164
  }
158
165
  /**
159
166
  * This application's own configuration, as carried on the access token
160
- * (api#65) — today, 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).
161
169
  *
162
170
  * Provided so an application can SHOW its own settings: populate a country
163
171
  * selector with the markets it actually serves, label a settings screen, and
164
172
  * so on. Being a few minutes stale is cosmetic for that.
165
173
  *
166
174
  * It is not an entitlement check. See AppConfigClaims for why acting on
167
- * `countries` client-side makes requests fail that would otherwise succeed.
175
+ * any of it client-side makes requests fail that would otherwise succeed.
168
176
  *
169
- * Returns `{}` when the token carries no application config, which is the
170
- * 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.
171
180
  */
172
181
  async getAppConfig() {
173
182
  return (0, tokenClaims_js_1.readAppConfigClaims)(await this.source().get());
@@ -195,6 +204,17 @@ class LocationServiceConnector {
195
204
  throw explainMissingOrigin(err, this.effectiveOrigin(options));
196
205
  }
197
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
+ }
198
218
  async dispatchWithRetry(source, url, cmd, options) {
199
219
  const token = await source.get();
200
220
  if (!token)
@@ -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;
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * Read advisory application config out of the access token (api#65).
3
3
  *
4
- * The API puts an application's own settings — today just `countries` — into
5
- * the JWT alongside `allowedDomain` and `allowedResources`, so this library can
6
- * stop hard-coding values it has no other way of knowing.
4
+ * The API puts an application's own settings into the JWT — `countries`,
5
+ * `allowedResources` and `allowedDomain` — so this library can stop
6
+ * hard-coding values it has no other way of knowing. The last two were in the
7
+ * token all along and were not surfaced until #40, so an application could
8
+ * only learn it lacked a route from the 403.
7
9
  *
8
10
  * `biasDecimals` used to be here too. It sized the grid this library rounded
9
11
  * `BiasPosition` onto, so that nearby callers shared a server cache entry; the
@@ -42,6 +44,30 @@ export interface AppConfigClaims {
42
44
  * Sending nothing and letting the API scope the request is always correct.
43
45
  */
44
46
  countries?: string[];
47
+ /**
48
+ * The routes this application may call, as the API names them — method and
49
+ * route template, such as `POST /address/autocomplete` or
50
+ * `GET /maps/static/{fileName}` (#40).
51
+ *
52
+ * So an application can ask "may I call the static-map route?" before it
53
+ * offers one, rather than only learning from the 403. It answers for the
54
+ * route, not for the options sent on it: a plan feature (`@planFeature`) is
55
+ * answered only by its own 403, and a static map's default Satellite render
56
+ * is one (#55). The same rule as `countries`
57
+ * applies, for the same reason: show it, never refuse with it. A route
58
+ * granted since the token was minted is answered by the API, which reads the
59
+ * entitlement fresh on every request.
60
+ *
61
+ * The API issues this claim JSON-encoded — a string holding the list —
62
+ * because it copies the application's stored setting. Both forms are read.
63
+ */
64
+ allowedResources?: string[];
65
+ /**
66
+ * The domain this application's requests must come from (#40). A request
67
+ * whose `Origin` is neither this host nor one of its subdomains is refused
68
+ * 403, so this is what to show next to "Origin not allowed".
69
+ */
70
+ allowedDomain?: string;
45
71
  }
46
72
  /**
47
73
  * Decode a JWT payload without verifying it.