@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.
- package/README.md +264 -42
- package/dist/adapters/GeoPlaces.d.ts +30 -3
- package/dist/adapters/GeoPlaces.js +5 -1
- package/dist/cjs/adapters/GeoPlaces.d.ts +30 -3
- package/dist/cjs/adapters/GeoPlaces.js +5 -4
- package/dist/cjs/client/GeoPlacesClient.d.ts +16 -4
- package/dist/cjs/client/GeoPlacesClient.js +24 -10
- package/dist/cjs/client/commands.d.ts +159 -0
- package/dist/cjs/client/commands.js +108 -0
- package/dist/cjs/errors/LocationServiceException.d.ts +28 -1
- package/dist/cjs/errors/LocationServiceException.js +31 -2
- package/dist/cjs/index.d.ts +5 -3
- package/dist/cjs/index.js +17 -1
- package/dist/cjs/maps/mapEnums.d.ts +82 -4
- package/dist/cjs/maps/mapEnums.js +98 -5
- package/dist/cjs/maps/mapStyle.d.ts +87 -10
- package/dist/cjs/maps/mapStyle.js +28 -5
- package/dist/cjs/maps/staticMap.d.ts +40 -0
- package/dist/cjs/maps/staticMap.js +4 -0
- package/dist/cjs/server/LocationServiceConnector.d.ts +23 -5
- package/dist/cjs/server/LocationServiceConnector.js +32 -14
- package/dist/cjs/transport/endpoints.js +3 -0
- package/dist/cjs/transport/http.d.ts +2 -2
- package/dist/cjs/transport/http.js +2 -2
- package/dist/cjs/types/index.d.ts +6 -5
- package/dist/cjs/utils/tokenClaims.d.ts +37 -13
- package/dist/cjs/utils/tokenClaims.js +36 -14
- package/dist/client/GeoPlacesClient.d.ts +16 -4
- package/dist/client/GeoPlacesClient.js +24 -10
- package/dist/client/commands.d.ts +159 -0
- package/dist/client/commands.js +97 -0
- package/dist/errors/LocationServiceException.d.ts +28 -1
- package/dist/errors/LocationServiceException.js +30 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +7 -2
- package/dist/maps/mapEnums.d.ts +82 -4
- package/dist/maps/mapEnums.js +97 -4
- package/dist/maps/mapStyle.d.ts +87 -10
- package/dist/maps/mapStyle.js +28 -5
- package/dist/maps/staticMap.d.ts +40 -0
- package/dist/maps/staticMap.js +4 -0
- package/dist/server/LocationServiceConnector.d.ts +23 -5
- package/dist/server/LocationServiceConnector.js +32 -14
- package/dist/transport/endpoints.js +3 -0
- package/dist/transport/http.d.ts +2 -2
- package/dist/transport/http.js +2 -2
- package/dist/types/index.d.ts +6 -5
- package/dist/utils/tokenClaims.d.ts +37 -13
- package/dist/utils/tokenClaims.js +36 -14
- package/package.json +1 -1
- package/dist/cjs/utils/roundPosition.d.ts +0 -66
- package/dist/cjs/utils/roundPosition.js +0 -109
- package/dist/utils/roundPosition.d.ts +0 -66
- package/dist/utils/roundPosition.js +0 -104
|
@@ -1,29 +1,29 @@
|
|
|
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 — `
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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.
|
|
9
|
+
*
|
|
10
|
+
* `biasDecimals` used to be here too. It sized the grid this library rounded
|
|
11
|
+
* `BiasPosition` onto, so that nearby callers shared a server cache entry; the
|
|
12
|
+
* cache is gone, the API issues no such claim, and rounding a coordinate with
|
|
13
|
+
* nothing to share it with only lowered the precision the upstream geocoder
|
|
14
|
+
* received (#51).
|
|
7
15
|
*
|
|
8
16
|
* DELIBERATELY UNVERIFIED, and that is safe. This library has no signing key
|
|
9
17
|
* and does not need one: every claim here is re-read from the application row
|
|
10
18
|
* by the API on each request, and the API's answer is the one that counts. A
|
|
11
19
|
* forged token would fail at the authorizer long before any of this mattered.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
20
|
+
* Nothing read here reaches a request at all now — it is displayed, never
|
|
21
|
+
* acted on, so a forged value misinforms only the caller who forged it.
|
|
14
22
|
*
|
|
15
23
|
* A JWT is signed, not encrypted, so the payload is plain base64url. Nothing
|
|
16
24
|
* secret is in it; these are the caller's own settings.
|
|
17
25
|
*/
|
|
18
26
|
export interface AppConfigClaims {
|
|
19
|
-
/**
|
|
20
|
-
* Bias precision this application is entitled to.
|
|
21
|
-
*
|
|
22
|
-
* Safe to act on: it only changes how a coordinate is rounded before
|
|
23
|
-
* sending, and the server re-rounds to its own configured value anyway. A
|
|
24
|
-
* stale value here costs precision, never correctness.
|
|
25
|
-
*/
|
|
26
|
-
biasDecimals?: number;
|
|
27
27
|
/**
|
|
28
28
|
* Countries this application may search, ISO 3166-1 alpha-2.
|
|
29
29
|
*
|
|
@@ -44,6 +44,30 @@ export interface AppConfigClaims {
|
|
|
44
44
|
* Sending nothing and letting the API scope the request is always correct.
|
|
45
45
|
*/
|
|
46
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;
|
|
47
71
|
}
|
|
48
72
|
/**
|
|
49
73
|
* Decode a JWT payload without verifying it.
|
|
@@ -2,22 +2,45 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Read advisory application config out of the access token (api#65).
|
|
4
4
|
*
|
|
5
|
-
* The API puts an application's own settings — `
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* The API puts an application's own settings into the JWT — `countries`,
|
|
6
|
+
* `allowedResources` and `allowedDomain` — so this library can stop
|
|
7
|
+
* hard-coding values it has no other way of knowing. The last two were in the
|
|
8
|
+
* token all along and were not surfaced until #40, so an application could
|
|
9
|
+
* only learn it lacked a route from the 403.
|
|
10
|
+
*
|
|
11
|
+
* `biasDecimals` used to be here too. It sized the grid this library rounded
|
|
12
|
+
* `BiasPosition` onto, so that nearby callers shared a server cache entry; the
|
|
13
|
+
* cache is gone, the API issues no such claim, and rounding a coordinate with
|
|
14
|
+
* nothing to share it with only lowered the precision the upstream geocoder
|
|
15
|
+
* received (#51).
|
|
8
16
|
*
|
|
9
17
|
* DELIBERATELY UNVERIFIED, and that is safe. This library has no signing key
|
|
10
18
|
* and does not need one: every claim here is re-read from the application row
|
|
11
19
|
* by the API on each request, and the API's answer is the one that counts. A
|
|
12
20
|
* forged token would fail at the authorizer long before any of this mattered.
|
|
13
|
-
*
|
|
14
|
-
*
|
|
21
|
+
* Nothing read here reaches a request at all now — it is displayed, never
|
|
22
|
+
* acted on, so a forged value misinforms only the caller who forged it.
|
|
15
23
|
*
|
|
16
24
|
* A JWT is signed, not encrypted, so the payload is plain base64url. Nothing
|
|
17
25
|
* secret is in it; these are the caller's own settings.
|
|
18
26
|
*/
|
|
19
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
28
|
exports.readAppConfigClaims = readAppConfigClaims;
|
|
29
|
+
/** A list of strings, whether the claim carries it as a list or JSON-encoded. */
|
|
30
|
+
function readStringList(value) {
|
|
31
|
+
let list = value;
|
|
32
|
+
if (typeof list === 'string') {
|
|
33
|
+
try {
|
|
34
|
+
list = JSON.parse(list);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (!Array.isArray(list))
|
|
41
|
+
return undefined;
|
|
42
|
+
return list.filter((v) => typeof v === 'string');
|
|
43
|
+
}
|
|
21
44
|
/**
|
|
22
45
|
* Decode a JWT payload without verifying it.
|
|
23
46
|
*
|
|
@@ -39,20 +62,19 @@ function readAppConfigClaims(token) {
|
|
|
39
62
|
const json = decodeURIComponent(Array.from(atob(padded), (c) => `%${c.charCodeAt(0).toString(16).padStart(2, '0')}`).join(''));
|
|
40
63
|
const payload = JSON.parse(json);
|
|
41
64
|
const claims = {};
|
|
42
|
-
if (typeof payload.biasDecimals === 'number') {
|
|
43
|
-
claims.biasDecimals = payload.biasDecimals;
|
|
44
|
-
}
|
|
45
|
-
else if (typeof payload.biasDecimals === 'string' &&
|
|
46
|
-
payload.biasDecimals.trim() !== '') {
|
|
47
|
-
const n = Number(payload.biasDecimals);
|
|
48
|
-
if (Number.isFinite(n))
|
|
49
|
-
claims.biasDecimals = n;
|
|
50
|
-
}
|
|
51
65
|
if (Array.isArray(payload.countries)) {
|
|
52
66
|
const list = payload.countries.filter((c) => typeof c === 'string');
|
|
53
67
|
if (list.length)
|
|
54
68
|
claims.countries = list;
|
|
55
69
|
}
|
|
70
|
+
// Kept when empty, unlike countries: no countries means "search the
|
|
71
|
+
// world", but no resources means an application entitled to nothing.
|
|
72
|
+
const resources = readStringList(payload.allowedResources);
|
|
73
|
+
if (resources)
|
|
74
|
+
claims.allowedResources = resources;
|
|
75
|
+
if (typeof payload.allowedDomain === 'string' && payload.allowedDomain) {
|
|
76
|
+
claims.allowedDomain = payload.allowedDomain;
|
|
77
|
+
}
|
|
56
78
|
return claims;
|
|
57
79
|
}
|
|
58
80
|
catch {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { RequestOptions } from '../transport/http.js';
|
|
2
2
|
import type { ClientConfig } from '../types/index.js';
|
|
3
3
|
import type { AppConfigClaims } from '../utils/tokenClaims.js';
|
|
4
|
+
import type { VerifyAddressResponse } from './commands.js';
|
|
4
5
|
export type SendOptions = RequestOptions;
|
|
5
6
|
/**
|
|
6
7
|
* GeoPlacesClient — AWS Location Service compatible client with custom auth.
|
|
@@ -18,17 +19,19 @@ export declare class GeoPlacesClient {
|
|
|
18
19
|
constructor(config: ClientConfig);
|
|
19
20
|
/**
|
|
20
21
|
* This application's own configuration, as carried on the access token
|
|
21
|
-
* (api#65)
|
|
22
|
+
* (api#65): the routes it may call, the domain its requests must come from,
|
|
23
|
+
* and the countries it is scoped to (#40).
|
|
22
24
|
*
|
|
23
25
|
* Provided so an application can SHOW its own settings: populate a country
|
|
24
26
|
* selector with the markets it actually serves, label a settings screen,
|
|
25
27
|
* and so on. Being a few minutes stale is cosmetic for that.
|
|
26
28
|
*
|
|
27
29
|
* It is not an entitlement check. See AppConfigClaims for why acting on
|
|
28
|
-
*
|
|
30
|
+
* any of it client-side makes requests fail that would otherwise succeed.
|
|
29
31
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
+
* Every token the API issues carries `allowedResources` and `allowedDomain`;
|
|
33
|
+
* `countries` only once a scope is configured in the portal. Returns `{}`
|
|
34
|
+
* for a token carrying none of them.
|
|
32
35
|
*/
|
|
33
36
|
getAppConfig(): AppConfigClaims;
|
|
34
37
|
/** Prefer the getToken callback (live ref) over a static token string. */
|
|
@@ -46,5 +49,14 @@ export declare class GeoPlacesClient {
|
|
|
46
49
|
* retry loop. Every failure throws LocationServiceException.
|
|
47
50
|
*/
|
|
48
51
|
send<TInput, TOutput>(command: TInput, options?: SendOptions): Promise<TOutput>;
|
|
52
|
+
/**
|
|
53
|
+
* Verify a PlaceId: `send(new VerifyAddressCommand({ PlaceId }))`, typed
|
|
54
|
+
* (#54). Resolves the full place record plus `verified`, and resolves a
|
|
55
|
+
* `verified: false` too — see VerifyAddressResponse for what may be stored.
|
|
56
|
+
*
|
|
57
|
+
* Billed per call, whether or not the address verifies: call it once per
|
|
58
|
+
* chosen PlaceId, at submit, never per keystroke.
|
|
59
|
+
*/
|
|
60
|
+
verifyAddress(placeId: string, options?: SendOptions): Promise<VerifyAddressResponse>;
|
|
49
61
|
private dispatch;
|
|
50
62
|
}
|
|
@@ -2,8 +2,8 @@ import debug from 'debug';
|
|
|
2
2
|
import { resolveEndpoint } from '../transport/endpoints.js';
|
|
3
3
|
import { isTokenRejected, noTokenAvailable } from '../transport/errors.js';
|
|
4
4
|
import { requestJson } from '../transport/http.js';
|
|
5
|
-
import { roundPositionFields } from '../utils/roundPosition.js';
|
|
6
5
|
import { readAppConfigClaims } from '../utils/tokenClaims.js';
|
|
6
|
+
import { VerifyAddressCommand } from './commands.js';
|
|
7
7
|
const log = debug('location-client:api');
|
|
8
8
|
/**
|
|
9
9
|
* GeoPlacesClient — AWS Location Service compatible client with custom auth.
|
|
@@ -20,17 +20,19 @@ export class GeoPlacesClient {
|
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
22
|
* This application's own configuration, as carried on the access token
|
|
23
|
-
* (api#65)
|
|
23
|
+
* (api#65): the routes it may call, the domain its requests must come from,
|
|
24
|
+
* and the countries it is scoped to (#40).
|
|
24
25
|
*
|
|
25
26
|
* Provided so an application can SHOW its own settings: populate a country
|
|
26
27
|
* selector with the markets it actually serves, label a settings screen,
|
|
27
28
|
* and so on. Being a few minutes stale is cosmetic for that.
|
|
28
29
|
*
|
|
29
30
|
* It is not an entitlement check. See AppConfigClaims for why acting on
|
|
30
|
-
*
|
|
31
|
+
* any of it client-side makes requests fail that would otherwise succeed.
|
|
31
32
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
33
|
+
* Every token the API issues carries `allowedResources` and `allowedDomain`;
|
|
34
|
+
* `countries` only once a scope is configured in the portal. Returns `{}`
|
|
35
|
+
* for a token carrying none of them.
|
|
34
36
|
*/
|
|
35
37
|
getAppConfig() {
|
|
36
38
|
return readAppConfigClaims(this.currentToken());
|
|
@@ -93,11 +95,23 @@ export class GeoPlacesClient {
|
|
|
93
95
|
return await this.dispatch(url, fresh, cmd, options);
|
|
94
96
|
}
|
|
95
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Verify a PlaceId: `send(new VerifyAddressCommand({ PlaceId }))`, typed
|
|
100
|
+
* (#54). Resolves the full place record plus `verified`, and resolves a
|
|
101
|
+
* `verified: false` too — see VerifyAddressResponse for what may be stored.
|
|
102
|
+
*
|
|
103
|
+
* Billed per call, whether or not the address verifies: call it once per
|
|
104
|
+
* chosen PlaceId, at submit, never per keystroke.
|
|
105
|
+
*/
|
|
106
|
+
verifyAddress(placeId, options) {
|
|
107
|
+
return this.send(new VerifyAddressCommand({ PlaceId: placeId }), options);
|
|
108
|
+
}
|
|
96
109
|
dispatch(url, token, cmd, options) {
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
110
|
+
// The caller's input goes out as the caller wrote it. `BiasPosition` used
|
|
111
|
+
// to be rounded here to a grid sized by a token claim, so nearby callers
|
|
112
|
+
// shared a server cache entry; with no cache the rounding only lowered the
|
|
113
|
+
// precision the upstream geocoder had to work with, which moves the
|
|
114
|
+
// results rather than coarsening them (#51).
|
|
101
115
|
log('Sending %s to %s', cmd.constructor?.name, url);
|
|
102
116
|
return requestJson(url, {
|
|
103
117
|
method: 'POST',
|
|
@@ -105,7 +119,7 @@ export class GeoPlacesClient {
|
|
|
105
119
|
'Content-Type': 'application/json',
|
|
106
120
|
Authorization: `Bearer ${token}`,
|
|
107
121
|
},
|
|
108
|
-
body: JSON.stringify(input),
|
|
122
|
+
body: JSON.stringify(cmd.input),
|
|
109
123
|
}, options);
|
|
110
124
|
}
|
|
111
125
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import type { GetPlaceResponse, AutocompleteCommandInput as SdkAutocompleteCommandInput, AutocompleteRequest as SdkAutocompleteRequest, GeocodeCommandInput as SdkGeocodeCommandInput, GeocodeRequest as SdkGeocodeRequest, GetPlaceCommandInput as SdkGetPlaceCommandInput, GetPlaceRequest as SdkGetPlaceRequest, ReverseGeocodeCommandInput as SdkReverseGeocodeCommandInput, ReverseGeocodeRequest as SdkReverseGeocodeRequest, SearchNearbyCommandInput as SdkSearchNearbyCommandInput, SearchNearbyRequest as SdkSearchNearbyRequest, SearchTextCommandInput as SdkSearchTextCommandInput, SearchTextRequest as SdkSearchTextRequest, SuggestCommandInput as SdkSuggestCommandInput, SuggestRequest as SdkSuggestRequest } from '@aws-sdk/client-geo-places';
|
|
2
|
+
import { AutocompleteCommand as SdkAutocompleteCommand, GeocodeCommand as SdkGeocodeCommand, GetPlaceCommand as SdkGetPlaceCommand, ReverseGeocodeCommand as SdkReverseGeocodeCommand, SearchNearbyCommand as SdkSearchNearbyCommand, SearchTextCommand as SdkSearchTextCommand, SuggestCommand as SdkSuggestCommand } from '@aws-sdk/client-geo-places';
|
|
3
|
+
/**
|
|
4
|
+
* Request fields the Location Service removes from every request (#40).
|
|
5
|
+
*
|
|
6
|
+
* `IntendedUse` chooses the price bucket the service pays, and `Key` is an
|
|
7
|
+
* Amazon Location API key that would bill someone else's account, so neither
|
|
8
|
+
* ever reaches Amazon. The SDK's inputs declare both, and this package used to
|
|
9
|
+
* re-export those commands as they were: `IntendedUse: 'Storage'` compiled,
|
|
10
|
+
* was sent, was stripped, and came back as a result with no storage rights.
|
|
11
|
+
*
|
|
12
|
+
* So the root exports every Places command as a subclass whose constructor
|
|
13
|
+
* takes the input WITHOUT these fields. Narrowing only the input types would
|
|
14
|
+
* not have been enough — the SDK's constructor references the SDK's own type,
|
|
15
|
+
* so `new SearchTextCommand({ IntendedUse })` would still have compiled.
|
|
16
|
+
*
|
|
17
|
+
* Types only. Nothing is removed at runtime: a request body is the caller's
|
|
18
|
+
* input, unchanged, and the service does the stripping. A caller who casts
|
|
19
|
+
* past the type still sends the field and still has it ignored.
|
|
20
|
+
*
|
|
21
|
+
* `test/places-commands.test.ts` reads the command list from the SDK itself,
|
|
22
|
+
* so a command the SDK adds fails there until it is narrowed here.
|
|
23
|
+
*/
|
|
24
|
+
export type NeverForwarded = 'IntendedUse' | 'Key';
|
|
25
|
+
export type AutocompleteRequest = Omit<SdkAutocompleteRequest, NeverForwarded>;
|
|
26
|
+
export type AutocompleteCommandInput = Omit<SdkAutocompleteCommandInput, NeverForwarded>;
|
|
27
|
+
export declare class AutocompleteCommand extends SdkAutocompleteCommand {
|
|
28
|
+
constructor(input: AutocompleteCommandInput);
|
|
29
|
+
}
|
|
30
|
+
export type GeocodeRequest = Omit<SdkGeocodeRequest, NeverForwarded>;
|
|
31
|
+
export type GeocodeCommandInput = Omit<SdkGeocodeCommandInput, NeverForwarded>;
|
|
32
|
+
/**
|
|
33
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
34
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
35
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
36
|
+
*
|
|
37
|
+
* @planFeature rich place data — Access, TimeZone
|
|
38
|
+
*/
|
|
39
|
+
export declare class GeocodeCommand extends SdkGeocodeCommand {
|
|
40
|
+
constructor(input: GeocodeCommandInput);
|
|
41
|
+
}
|
|
42
|
+
export type GetPlaceRequest = Omit<SdkGetPlaceRequest, NeverForwarded>;
|
|
43
|
+
export type GetPlaceCommandInput = Omit<SdkGetPlaceCommandInput, NeverForwarded>;
|
|
44
|
+
/**
|
|
45
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
46
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
47
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
48
|
+
*
|
|
49
|
+
* @planFeature rich place data — Access, Contact, Phonemes, TimeZone
|
|
50
|
+
*/
|
|
51
|
+
export declare class GetPlaceCommand extends SdkGetPlaceCommand {
|
|
52
|
+
constructor(input: GetPlaceCommandInput);
|
|
53
|
+
}
|
|
54
|
+
export type ReverseGeocodeRequest = Omit<SdkReverseGeocodeRequest, NeverForwarded>;
|
|
55
|
+
export type ReverseGeocodeCommandInput = Omit<SdkReverseGeocodeCommandInput, NeverForwarded>;
|
|
56
|
+
/**
|
|
57
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
58
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
59
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
60
|
+
*
|
|
61
|
+
* @planFeature rich place data — Access, TimeZone
|
|
62
|
+
*/
|
|
63
|
+
export declare class ReverseGeocodeCommand extends SdkReverseGeocodeCommand {
|
|
64
|
+
constructor(input: ReverseGeocodeCommandInput);
|
|
65
|
+
}
|
|
66
|
+
export type SearchNearbyRequest = Omit<SdkSearchNearbyRequest, NeverForwarded>;
|
|
67
|
+
export type SearchNearbyCommandInput = Omit<SdkSearchNearbyCommandInput, NeverForwarded>;
|
|
68
|
+
/**
|
|
69
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
70
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
71
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
72
|
+
*
|
|
73
|
+
* @planFeature rich place data — Access, Contact, Phonemes, TimeZone
|
|
74
|
+
*/
|
|
75
|
+
export declare class SearchNearbyCommand extends SdkSearchNearbyCommand {
|
|
76
|
+
constructor(input: SearchNearbyCommandInput);
|
|
77
|
+
}
|
|
78
|
+
export type SearchTextRequest = Omit<SdkSearchTextRequest, NeverForwarded>;
|
|
79
|
+
export type SearchTextCommandInput = Omit<SdkSearchTextCommandInput, NeverForwarded>;
|
|
80
|
+
/**
|
|
81
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
82
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
83
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
84
|
+
*
|
|
85
|
+
* @planFeature rich place data — Access, Contact, Phonemes, TimeZone
|
|
86
|
+
*/
|
|
87
|
+
export declare class SearchTextCommand extends SdkSearchTextCommand {
|
|
88
|
+
constructor(input: SearchTextCommandInput);
|
|
89
|
+
}
|
|
90
|
+
export type SuggestRequest = Omit<SdkSuggestRequest, NeverForwarded>;
|
|
91
|
+
export type SuggestCommandInput = Omit<SdkSuggestCommandInput, NeverForwarded>;
|
|
92
|
+
/**
|
|
93
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
94
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
95
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
96
|
+
*
|
|
97
|
+
* @planFeature rich place data — Access, Phonemes, TimeZone
|
|
98
|
+
*/
|
|
99
|
+
export declare class SuggestCommand extends SdkSuggestCommand {
|
|
100
|
+
constructor(input: SuggestCommandInput);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A PlaceId, and nothing else: the service forwards `PlaceId` alone to this
|
|
104
|
+
* route, so `Language`, `PoliticalView` and `AdditionalFeatures` would be
|
|
105
|
+
* dropped rather than honoured. The type refuses them instead (#54).
|
|
106
|
+
*/
|
|
107
|
+
export interface VerifyAddressCommandInput {
|
|
108
|
+
/**
|
|
109
|
+
* From an autocomplete, suggestion, geocode or place result — including a
|
|
110
|
+
* unit's, from a place's `SecondaryAddresses`.
|
|
111
|
+
*/
|
|
112
|
+
PlaceId: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The answer to a verify: the record `GetPlaceCommand` returns — the
|
|
116
|
+
* building's units in `SecondaryAddresses` included, `$metadata` not — plus
|
|
117
|
+
* `verified`.
|
|
118
|
+
*
|
|
119
|
+
* `verified` is true for a `PointAddress`, or a `SecondaryAddress` (a unit),
|
|
120
|
+
* and false for anything else: an interpolated address, a street, a locality,
|
|
121
|
+
* a point of interest. A `false` is still a 200 and still billed, so it
|
|
122
|
+
* resolves; it never throws.
|
|
123
|
+
*
|
|
124
|
+
* This is the one Places result an integrator may store, except a place in
|
|
125
|
+
* Japan, which may not be stored at all. Every other Places result is for
|
|
126
|
+
* display.
|
|
127
|
+
*
|
|
128
|
+
* Keep the PlaceId you sent beside it. The answer's own `PlaceId` can differ,
|
|
129
|
+
* and for a unit it does: the service fails that one on every Places route,
|
|
130
|
+
* while the one you sent verifies again.
|
|
131
|
+
*/
|
|
132
|
+
export type VerifyAddressResponse = Omit<GetPlaceResponse, 'PricingBucket'> & {
|
|
133
|
+
/**
|
|
134
|
+
* The bucket the stored record belongs to (`Stored`), not what this call
|
|
135
|
+
* was billed at. Every verify is billed on its own meter, whether the
|
|
136
|
+
* service answered it from its store or not.
|
|
137
|
+
*/
|
|
138
|
+
PricingBucket: string | undefined;
|
|
139
|
+
/** `PointAddress` or `SecondaryAddress`: the address is verified. */
|
|
140
|
+
verified: boolean;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* `POST /address/verify` (#54): resolve one PlaceId to the full place record
|
|
144
|
+
* plus `verified`. `GeoPlacesClient.verifyAddress` and
|
|
145
|
+
* `LocationServiceConnector.verifyAddress` send this.
|
|
146
|
+
*
|
|
147
|
+
* Billed per call, whether or not the address verifies. Send it once per
|
|
148
|
+
* chosen PlaceId — at submit — never per keystroke. A repeat verify of the
|
|
149
|
+
* same PlaceId may be answered from the service's own store, and is billed
|
|
150
|
+
* all the same.
|
|
151
|
+
*
|
|
152
|
+
* Not an SDK command: the route has none. It extends nothing on purpose —
|
|
153
|
+
* `ENDPOINTS` matches by `instanceof`, so a subclass of `GetPlaceCommand`
|
|
154
|
+
* would match that entry and go to `/address/place`.
|
|
155
|
+
*/
|
|
156
|
+
export declare class VerifyAddressCommand {
|
|
157
|
+
readonly input: VerifyAddressCommandInput;
|
|
158
|
+
constructor(input: VerifyAddressCommandInput);
|
|
159
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { AutocompleteCommand as SdkAutocompleteCommand, GeocodeCommand as SdkGeocodeCommand, GetPlaceCommand as SdkGetPlaceCommand, ReverseGeocodeCommand as SdkReverseGeocodeCommand, SearchNearbyCommand as SdkSearchNearbyCommand, SearchTextCommand as SdkSearchTextCommand, SuggestCommand as SdkSuggestCommand, } from '@aws-sdk/client-geo-places';
|
|
2
|
+
export class AutocompleteCommand extends SdkAutocompleteCommand {
|
|
3
|
+
constructor(input) {
|
|
4
|
+
super(input);
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
9
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
10
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
11
|
+
*
|
|
12
|
+
* @planFeature rich place data — Access, TimeZone
|
|
13
|
+
*/
|
|
14
|
+
export class GeocodeCommand extends SdkGeocodeCommand {
|
|
15
|
+
constructor(input) {
|
|
16
|
+
super(input);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
21
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
22
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
23
|
+
*
|
|
24
|
+
* @planFeature rich place data — Access, Contact, Phonemes, TimeZone
|
|
25
|
+
*/
|
|
26
|
+
export class GetPlaceCommand extends SdkGetPlaceCommand {
|
|
27
|
+
constructor(input) {
|
|
28
|
+
super(input);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
33
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
34
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
35
|
+
*
|
|
36
|
+
* @planFeature rich place data — Access, TimeZone
|
|
37
|
+
*/
|
|
38
|
+
export class ReverseGeocodeCommand extends SdkReverseGeocodeCommand {
|
|
39
|
+
constructor(input) {
|
|
40
|
+
super(input);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
45
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
46
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
47
|
+
*
|
|
48
|
+
* @planFeature rich place data — Access, Contact, Phonemes, TimeZone
|
|
49
|
+
*/
|
|
50
|
+
export class SearchNearbyCommand extends SdkSearchNearbyCommand {
|
|
51
|
+
constructor(input) {
|
|
52
|
+
super(input);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
57
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
58
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
59
|
+
*
|
|
60
|
+
* @planFeature rich place data — Access, Contact, Phonemes, TimeZone
|
|
61
|
+
*/
|
|
62
|
+
export class SearchTextCommand extends SdkSearchTextCommand {
|
|
63
|
+
constructor(input) {
|
|
64
|
+
super(input);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Accepts rich place data, a plan feature: on a plan without it these
|
|
69
|
+
* `AdditionalFeatures` are refused 403 `FeatureNotEntitledException`
|
|
70
|
+
* (`isFeatureNotEntitled` on the error; see `FEATURE_NOT_ENTITLED`).
|
|
71
|
+
*
|
|
72
|
+
* @planFeature rich place data — Access, Phonemes, TimeZone
|
|
73
|
+
*/
|
|
74
|
+
export class SuggestCommand extends SdkSuggestCommand {
|
|
75
|
+
constructor(input) {
|
|
76
|
+
super(input);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* `POST /address/verify` (#54): resolve one PlaceId to the full place record
|
|
81
|
+
* plus `verified`. `GeoPlacesClient.verifyAddress` and
|
|
82
|
+
* `LocationServiceConnector.verifyAddress` send this.
|
|
83
|
+
*
|
|
84
|
+
* Billed per call, whether or not the address verifies. Send it once per
|
|
85
|
+
* chosen PlaceId — at submit — never per keystroke. A repeat verify of the
|
|
86
|
+
* same PlaceId may be answered from the service's own store, and is billed
|
|
87
|
+
* all the same.
|
|
88
|
+
*
|
|
89
|
+
* Not an SDK command: the route has none. It extends nothing on purpose —
|
|
90
|
+
* `ENDPOINTS` matches by `instanceof`, so a subclass of `GetPlaceCommand`
|
|
91
|
+
* would match that entry and go to `/address/place`.
|
|
92
|
+
*/
|
|
93
|
+
export class VerifyAddressCommand {
|
|
94
|
+
constructor(input) {
|
|
95
|
+
this.input = input;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code of a 403 for an option the application's plan does not include
|
|
3
|
+
* (#55): a map feature such as `satellite` or `terrain`, or rich place data.
|
|
4
|
+
* The options that can earn it are tagged `@planFeature` in their
|
|
5
|
+
* documentation.
|
|
6
|
+
*
|
|
7
|
+
* The service refuses before calling upstream, so the refusal is not billed,
|
|
8
|
+
* and its message names each refused feature and the option that asked for
|
|
9
|
+
* it. It never names a plan: which plan includes which feature can change
|
|
10
|
+
* without a release of this package — see https://chaosity.cloud/pricing.
|
|
11
|
+
* Nothing in the token lists the features either, so this 403 is the first a
|
|
12
|
+
* caller hears of it; there is no check to make beforehand.
|
|
13
|
+
*/
|
|
14
|
+
export declare const FEATURE_NOT_ENTITLED = "FeatureNotEntitledException";
|
|
1
15
|
export interface LocationServiceExceptionOptions {
|
|
2
16
|
message: string;
|
|
3
17
|
code: string;
|
|
@@ -36,8 +50,21 @@ export declare class LocationServiceException extends Error {
|
|
|
36
50
|
get isRetryable(): boolean;
|
|
37
51
|
get isThrottling(): boolean;
|
|
38
52
|
get isValidation(): boolean;
|
|
39
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Any 401 or 403 — the caller must act, and retrying will not help.
|
|
55
|
+
*
|
|
56
|
+
* That is several failures with different remedies: bad or expired
|
|
57
|
+
* credentials, an `Origin` the application does not allow, a route its plan
|
|
58
|
+
* does not include, an option its plan does not include. Branch on `code`,
|
|
59
|
+
* or on `isFeatureNotEntitled` for the last, to tell them apart.
|
|
60
|
+
*/
|
|
40
61
|
get isAuth(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The application's plan does not include an option this request asked for
|
|
64
|
+
* (`FEATURE_NOT_ENTITLED`). The message names the feature; drop the option,
|
|
65
|
+
* or move the application to a plan that includes it.
|
|
66
|
+
*/
|
|
67
|
+
get isFeatureNotEntitled(): boolean;
|
|
41
68
|
get isAborted(): boolean;
|
|
42
69
|
get isTimeout(): boolean;
|
|
43
70
|
toString(): string;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The code of a 403 for an option the application's plan does not include
|
|
3
|
+
* (#55): a map feature such as `satellite` or `terrain`, or rich place data.
|
|
4
|
+
* The options that can earn it are tagged `@planFeature` in their
|
|
5
|
+
* documentation.
|
|
6
|
+
*
|
|
7
|
+
* The service refuses before calling upstream, so the refusal is not billed,
|
|
8
|
+
* and its message names each refused feature and the option that asked for
|
|
9
|
+
* it. It never names a plan: which plan includes which feature can change
|
|
10
|
+
* without a release of this package — see https://chaosity.cloud/pricing.
|
|
11
|
+
* Nothing in the token lists the features either, so this 403 is the first a
|
|
12
|
+
* caller hears of it; there is no check to make beforehand.
|
|
13
|
+
*/
|
|
14
|
+
export const FEATURE_NOT_ENTITLED = 'FeatureNotEntitledException';
|
|
1
15
|
/**
|
|
2
16
|
* The single error type this package throws.
|
|
3
17
|
*
|
|
@@ -37,10 +51,25 @@ export class LocationServiceException extends Error {
|
|
|
37
51
|
get isValidation() {
|
|
38
52
|
return this.code === 'ValidationException' || this.statusCode === 400;
|
|
39
53
|
}
|
|
40
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* Any 401 or 403 — the caller must act, and retrying will not help.
|
|
56
|
+
*
|
|
57
|
+
* That is several failures with different remedies: bad or expired
|
|
58
|
+
* credentials, an `Origin` the application does not allow, a route its plan
|
|
59
|
+
* does not include, an option its plan does not include. Branch on `code`,
|
|
60
|
+
* or on `isFeatureNotEntitled` for the last, to tell them apart.
|
|
61
|
+
*/
|
|
41
62
|
get isAuth() {
|
|
42
63
|
return this.statusCode === 401 || this.statusCode === 403;
|
|
43
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* The application's plan does not include an option this request asked for
|
|
67
|
+
* (`FEATURE_NOT_ENTITLED`). The message names the feature; drop the option,
|
|
68
|
+
* or move the application to a plan that includes it.
|
|
69
|
+
*/
|
|
70
|
+
get isFeatureNotEntitled() {
|
|
71
|
+
return this.code === FEATURE_NOT_ENTITLED;
|
|
72
|
+
}
|
|
44
73
|
get isAborted() {
|
|
45
74
|
return this.code === 'AbortedException';
|
|
46
75
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,9 +3,11 @@ export type { SendOptions } from './client/GeoPlacesClient.js';
|
|
|
3
3
|
export { DEFAULT_MAX_ATTEMPTS, DEFAULT_OVERALL_TIMEOUT_MS, DEFAULT_TIMEOUT_MS, } from './transport/http.js';
|
|
4
4
|
export type { RequestOptions } from './transport/http.js';
|
|
5
5
|
export { TOKEN_REFRESH_BUFFER_SECONDS, readTokenExpiry, } from './auth/tokenRefresh.js';
|
|
6
|
-
export { LocationServiceException } from './errors/LocationServiceException.js';
|
|
6
|
+
export { FEATURE_NOT_ENTITLED, LocationServiceException, } from './errors/LocationServiceException.js';
|
|
7
7
|
export type { LocationServiceExceptionOptions } from './errors/LocationServiceException.js';
|
|
8
8
|
export * from '@aws-sdk/client-geo-places';
|
|
9
|
+
export { AutocompleteCommand, GeocodeCommand, GetPlaceCommand, ReverseGeocodeCommand, SearchNearbyCommand, SearchTextCommand, SuggestCommand, VerifyAddressCommand, } from './client/commands.js';
|
|
10
|
+
export type { AutocompleteCommandInput, AutocompleteRequest, GeocodeCommandInput, GeocodeRequest, GetPlaceCommandInput, GetPlaceRequest, NeverForwarded, ReverseGeocodeCommandInput, ReverseGeocodeRequest, SearchNearbyCommandInput, SearchNearbyRequest, SearchTextCommandInput, SearchTextRequest, SuggestCommandInput, SuggestRequest, VerifyAddressCommandInput, VerifyAddressResponse, } from './client/commands.js';
|
|
9
11
|
export * from '@aws/amazon-location-utilities-datatypes';
|
|
10
12
|
export { GeoPlaces } from './adapters/GeoPlaces.js';
|
|
11
13
|
export type { GeoPlacesDetailOptions, GeoPlacesOptions, } from './adapters/GeoPlaces.js';
|
|
@@ -17,8 +19,8 @@ export { buildMapStyleUrl, fetchMapStyle } from './maps/mapStyle.js';
|
|
|
17
19
|
export type { MapStyleOptions } from './maps/mapStyle.js';
|
|
18
20
|
export { buildStaticMapUrl, fetchStaticMap, staticMapAccept, } from './maps/staticMap.js';
|
|
19
21
|
export type { StaticMapFileName, StaticMapOptions } from './maps/staticMap.js';
|
|
20
|
-
export { BUILDINGS, COLOR_SCHEMES, CONTOUR_DENSITIES, LABEL_SIZES, MAP_FEATURE_MODES, MAP_STYLES, SCALE_BAR_UNITS, SPRITE_VARIANTS, STATIC_MAP_STYLES, TERRAINS, TRAFFIC_MODES, TRAVEL_MODES, } from './maps/mapEnums.js';
|
|
21
|
-
export type { Buildings, ColorScheme, ContourDensity, LabelSize, MapFeatureMode, MapStyle, ScaleBarUnit, SpriteVariant, StaticMapStyle, Terrain, TrafficMode, TravelMode, } from './maps/mapEnums.js';
|
|
22
|
+
export { BUILDINGS, COLOR_SCHEMES, CONTOUR_DENSITIES, LABEL_SIZES, MAP_FEATURE_MODES, MAP_STYLES, POI_DENSITIES, SCALE_BAR_UNITS, SPRITE_VARIANTS, STATIC_MAP_STYLES, STYLE_POI_CATEGORIES, TERRAINS, TRAFFIC_MODES, TRAVEL_MODES, } from './maps/mapEnums.js';
|
|
23
|
+
export type { Buildings, ColorScheme, ContourDensity, LabelSize, MapFeatureMode, MapStyle, PoiDensity, ScaleBarUnit, SpriteVariant, StaticMapStyle, StylePoiCategory, Terrain, TrafficMode, TravelMode, } from './maps/mapEnums.js';
|
|
22
24
|
export { transformRequest } from './maps/Utils.js';
|
|
23
25
|
export type { ClientConfig, GeoPlacesCommand, MapLike } from './types/index.js';
|
|
24
26
|
export type { AppConfigClaims } from './utils/tokenClaims.js';
|