@chaosity/location-client 0.1.2 → 0.1.3
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 +145 -144
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
# @chaosity/location-client
|
|
2
2
|
|
|
3
|
-
AWS Location Service compatible client with custom authentication.
|
|
4
|
-
|
|
5
|
-
## Built on AWS Official Libraries
|
|
6
|
-
|
|
7
|
-
This client uses:
|
|
8
|
-
- [`@aws/amazon-location-client`](https://github.com/aws-geospatial/amazon-location-client-js) - AWS Location Client with all commands
|
|
9
|
-
- [`@aws/amazon-location-utilities-datatypes`](https://github.com/aws-geospatial/amazon-location-utilities-datatypes-js) - Data type conversions (GeoJSON, etc.)
|
|
10
|
-
|
|
11
|
-
## Key Difference from AWS SDK
|
|
12
|
-
|
|
13
|
-
**Only difference**: Authentication method
|
|
14
|
-
- AWS SDK: Uses AWS SigV4 (IAM credentials)
|
|
15
|
-
- This client: Uses Bearer token (OAuth2)
|
|
16
|
-
|
|
17
|
-
**Everything else is identical**:
|
|
18
|
-
- Same command classes from AWS Location Client
|
|
19
|
-
- Same request/response types
|
|
20
|
-
- Same data type conversions
|
|
3
|
+
AWS Location Service compatible client with custom Bearer token authentication.
|
|
21
4
|
|
|
22
5
|
## Installation
|
|
23
6
|
|
|
@@ -25,20 +8,26 @@ This client uses:
|
|
|
25
8
|
npm install @chaosity/location-client
|
|
26
9
|
```
|
|
27
10
|
|
|
28
|
-
##
|
|
11
|
+
## Key Features
|
|
29
12
|
|
|
30
|
-
|
|
13
|
+
- **Custom Authentication**: Uses Bearer tokens instead of AWS SigV4
|
|
14
|
+
- **AWS SDK Commands**: Full access to all AWS Location Service commands
|
|
15
|
+
- **Data Type Utilities**: Built-in GeoJSON conversion utilities
|
|
16
|
+
- **MapLibre Integration**: Adapter for MapLibre GL Geocoder
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### Basic Client Usage
|
|
31
21
|
|
|
32
22
|
```typescript
|
|
33
|
-
import { GeoPlacesClient,
|
|
23
|
+
import { GeoPlacesClient, SuggestCommand } from '@chaosity/location-client'
|
|
34
24
|
|
|
35
25
|
const client = new GeoPlacesClient({
|
|
36
26
|
apiUrl: 'https://api.example.com',
|
|
37
27
|
token: 'your-bearer-token'
|
|
38
28
|
})
|
|
39
29
|
|
|
40
|
-
|
|
41
|
-
const command = new places.SuggestCommand({
|
|
30
|
+
const command = new SuggestCommand({
|
|
42
31
|
QueryText: 'Vancouver',
|
|
43
32
|
MaxResults: 5
|
|
44
33
|
})
|
|
@@ -46,173 +35,185 @@ const command = new places.SuggestCommand({
|
|
|
46
35
|
const response = await client.send(command)
|
|
47
36
|
```
|
|
48
37
|
|
|
49
|
-
###
|
|
38
|
+
### Server-Side Authentication (Next.js Server Action)
|
|
50
39
|
|
|
51
40
|
```typescript
|
|
52
|
-
|
|
53
|
-
import maplibregl from 'maplibre-gl'
|
|
54
|
-
|
|
55
|
-
const map = new maplibregl.Map({ /* ... */ })
|
|
56
|
-
const client = new GeoPlacesClient({ apiUrl, token })
|
|
57
|
-
const geoPlaces = new GeoPlaces(client, map)
|
|
58
|
-
|
|
59
|
-
// Use with MapLibre Geocoder
|
|
60
|
-
const results = await geoPlaces.forwardGeocode({ query: 'Vancouver' })
|
|
61
|
-
|
|
62
|
-
// Or use AWS utilities directly for data conversion
|
|
63
|
-
const featureCollection = placeToFeatureCollection(response)
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Available Commands
|
|
67
|
-
|
|
68
|
-
All commands from AWS Location Client:
|
|
69
|
-
- `places.AutocompleteCommand`
|
|
70
|
-
- `places.GeocodeCommand`
|
|
71
|
-
- `places.GetPlaceCommand`
|
|
72
|
-
- `places.ReverseGeocodeCommand`
|
|
73
|
-
- `places.SearchNearbyCommand`
|
|
74
|
-
- `places.SearchTextCommand`
|
|
75
|
-
- `places.SuggestCommand`
|
|
76
|
-
- `maps.*` - All Maps commands
|
|
77
|
-
- `routes.*` - All Routes commands
|
|
78
|
-
|
|
79
|
-
## Data Type Utilities
|
|
80
|
-
|
|
81
|
-
All utilities from `@aws/amazon-location-utilities-datatypes`:
|
|
82
|
-
- `placeToFeatureCollection` - Convert places to GeoJSON
|
|
83
|
-
- `routeToFeatureCollection` - Convert routes to GeoJSON
|
|
84
|
-
- `devicePositionsToFeatureCollection` - Convert device positions to GeoJSON
|
|
85
|
-
- `geofencesToFeatureCollection` - Convert geofences to GeoJSON
|
|
86
|
-
- `featureCollectionToGeofence` - Convert GeoJSON to geofences
|
|
87
|
-
|
|
88
|
-
Refer to [AWS Location Client docs](https://github.com/aws-geospatial/amazon-location-client-js) and [Data Types docs](https://github.com/aws-geospatial/amazon-location-utilities-datatypes-js) for complete documentation.
|
|
89
|
-
|
|
90
|
-
## ⚠️ Security Notice
|
|
91
|
-
|
|
92
|
-
**NEVER expose `client_id` and `client_secret` in browser code!**
|
|
93
|
-
|
|
94
|
-
- `TokenProvider` is for **server-side use only** (Next.js Server Actions, API routes, backend services)
|
|
95
|
-
- Client credentials must be stored in environment variables on the server
|
|
96
|
-
- Browser code should only receive the JWT token from your backend
|
|
97
|
-
|
|
98
|
-
## Installation
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
npm install @chaosity/location-client maplibre-gl
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
## Quick Start
|
|
105
|
-
|
|
106
|
-
### Recommended: Server Action (Next.js)
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
// lib/actions/location-auth.ts (Server-side only)
|
|
41
|
+
// app/actions/location.ts
|
|
110
42
|
'use server'
|
|
111
43
|
|
|
112
|
-
export async function
|
|
113
|
-
const response = await fetch('https://api.
|
|
44
|
+
export async function getLocationConfig() {
|
|
45
|
+
const response = await fetch('https://api.example.com/auth/token', {
|
|
114
46
|
method: 'POST',
|
|
115
47
|
headers: { 'Content-Type': 'application/json' },
|
|
116
48
|
body: JSON.stringify({
|
|
117
|
-
grant_type: 'client_credentials',
|
|
118
49
|
client_id: process.env.LOCATION_CLIENT_ID!,
|
|
119
|
-
client_secret: process.env.LOCATION_CLIENT_SECRET
|
|
50
|
+
client_secret: process.env.LOCATION_CLIENT_SECRET!,
|
|
51
|
+
grant_type: 'client_credentials'
|
|
120
52
|
})
|
|
121
53
|
})
|
|
122
54
|
|
|
123
55
|
const data = await response.json()
|
|
124
|
-
return {
|
|
56
|
+
return {
|
|
57
|
+
apiUrl: 'https://api.example.com',
|
|
58
|
+
token: data.access_token
|
|
59
|
+
}
|
|
125
60
|
}
|
|
61
|
+
```
|
|
126
62
|
|
|
127
|
-
|
|
128
|
-
'use client'
|
|
129
|
-
import { GeoPlaces } from '@chaosity/location-client'
|
|
130
|
-
import { getLocationToken } from '@/lib/actions/location-auth'
|
|
63
|
+
### MapLibre Integration
|
|
131
64
|
|
|
132
|
-
|
|
133
|
-
|
|
65
|
+
```typescript
|
|
66
|
+
import { GeoPlaces } from '@chaosity/location-client'
|
|
67
|
+
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder'
|
|
68
|
+
import maplibregl from 'maplibre-gl'
|
|
134
69
|
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
map.addControl(geocoder)
|
|
138
|
-
```
|
|
70
|
+
const map = new maplibregl.Map({ /* ... */ })
|
|
71
|
+
const geoPlaces = new GeoPlaces(apiUrl, token, map)
|
|
139
72
|
|
|
140
|
-
|
|
73
|
+
// Add geocoder control
|
|
74
|
+
const geocoder = new MaplibreGeocoder(geoPlaces, {
|
|
75
|
+
maplibregl,
|
|
76
|
+
showResultsWhileTyping: true,
|
|
77
|
+
limit: 30
|
|
78
|
+
})
|
|
141
79
|
|
|
142
|
-
|
|
143
|
-
// lib/actions/location-auth.ts (Server-side only)
|
|
144
|
-
'use server'
|
|
145
|
-
import { AuthClient } from '@chaosity/location-client'
|
|
80
|
+
map.addControl(geocoder, 'top-left')
|
|
146
81
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
82
|
+
// Handle result selection
|
|
83
|
+
geocoder.on('result', async (event) => {
|
|
84
|
+
const { id, result_type } = event.result
|
|
85
|
+
if (result_type === 'Place') {
|
|
86
|
+
const details = await geoPlaces.searchByPlaceId(id)
|
|
87
|
+
console.log('Place details:', details)
|
|
88
|
+
}
|
|
89
|
+
})
|
|
156
90
|
```
|
|
157
91
|
|
|
158
92
|
## API Reference
|
|
159
93
|
|
|
160
|
-
###
|
|
94
|
+
### GeoPlacesClient
|
|
161
95
|
|
|
162
|
-
|
|
96
|
+
Main client for executing commands.
|
|
163
97
|
|
|
164
98
|
```typescript
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
99
|
+
const client = new GeoPlacesClient({
|
|
100
|
+
apiUrl: string,
|
|
101
|
+
token: string
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
await client.send(command)
|
|
169
105
|
```
|
|
170
106
|
|
|
171
|
-
###
|
|
107
|
+
### GeoPlaces Adapter
|
|
108
|
+
|
|
109
|
+
MapLibre Geocoder adapter for search and geocoding.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
const geoPlaces = new GeoPlaces(apiUrl, token, map)
|
|
113
|
+
|
|
114
|
+
// Forward geocoding (search)
|
|
115
|
+
await geoPlaces.forwardGeocode({ query: 'Vancouver' })
|
|
116
|
+
|
|
117
|
+
// Reverse geocoding (coordinates to address)
|
|
118
|
+
await geoPlaces.reverseGeocode({ query: [-123.12, 49.28] })
|
|
119
|
+
|
|
120
|
+
// Get place details by ID
|
|
121
|
+
await geoPlaces.searchByPlaceId('place-id')
|
|
122
|
+
```
|
|
172
123
|
|
|
173
|
-
|
|
124
|
+
### Available Commands
|
|
174
125
|
|
|
175
|
-
|
|
126
|
+
All AWS Location Service commands from `@aws-sdk/client-geo-places`:
|
|
176
127
|
|
|
177
128
|
```typescript
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
129
|
+
import {
|
|
130
|
+
SuggestCommand,
|
|
131
|
+
GeocodeCommand,
|
|
132
|
+
ReverseGeocodeCommand,
|
|
133
|
+
GetPlaceCommand,
|
|
134
|
+
SearchTextCommand,
|
|
135
|
+
SearchNearbyCommand
|
|
136
|
+
} from '@chaosity/location-client'
|
|
184
137
|
```
|
|
185
138
|
|
|
186
|
-
###
|
|
139
|
+
### Data Type Utilities
|
|
187
140
|
|
|
188
|
-
|
|
141
|
+
GeoJSON conversion utilities from `@aws/amazon-location-utilities-datatypes`:
|
|
189
142
|
|
|
190
143
|
```typescript
|
|
191
|
-
|
|
192
|
-
|
|
144
|
+
import {
|
|
145
|
+
placeToFeatureCollection,
|
|
146
|
+
routeToFeatureCollection,
|
|
147
|
+
devicePositionsToFeatureCollection
|
|
148
|
+
} from '@chaosity/location-client'
|
|
193
149
|
```
|
|
194
150
|
|
|
195
|
-
|
|
151
|
+
## Security Best Practices
|
|
152
|
+
|
|
153
|
+
⚠️ **NEVER expose client credentials in browser code!**
|
|
154
|
+
|
|
155
|
+
- Store `client_id` and `client_secret` in server environment variables
|
|
156
|
+
- Use Server Actions or API routes to fetch tokens
|
|
157
|
+
- Only send the JWT token to the browser
|
|
158
|
+
- Tokens should be short-lived and refreshed as needed
|
|
196
159
|
|
|
197
|
-
|
|
160
|
+
## Example: Complete MapLibre Setup
|
|
198
161
|
|
|
199
162
|
```typescript
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
163
|
+
'use client'
|
|
164
|
+
|
|
165
|
+
import { GeoPlaces } from '@chaosity/location-client'
|
|
166
|
+
import { getLocationConfig } from '@/lib/actions/location'
|
|
167
|
+
import maplibregl from 'maplibre-gl'
|
|
168
|
+
import MaplibreGeocoder from '@maplibre/maplibre-gl-geocoder'
|
|
169
|
+
|
|
170
|
+
export default function MapComponent() {
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
async function initMap() {
|
|
173
|
+
// Get config from server
|
|
174
|
+
const { apiUrl, token } = await getLocationConfig()
|
|
175
|
+
|
|
176
|
+
// Initialize map
|
|
177
|
+
const map = new maplibregl.Map({
|
|
178
|
+
container: 'map',
|
|
179
|
+
style: `${apiUrl}/maps/Standard/descriptor`,
|
|
180
|
+
center: [-123.12, 49.28],
|
|
181
|
+
zoom: 10,
|
|
182
|
+
transformRequest: (url) => {
|
|
183
|
+
if (url.startsWith(apiUrl)) {
|
|
184
|
+
return {
|
|
185
|
+
url,
|
|
186
|
+
headers: { 'Authorization': `Bearer ${token}` }
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return { url }
|
|
190
|
+
}
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
// Add geocoder
|
|
194
|
+
const geoPlaces = new GeoPlaces(apiUrl, token, map)
|
|
195
|
+
const geocoder = new MaplibreGeocoder(geoPlaces, { maplibregl })
|
|
196
|
+
map.addControl(geocoder, 'top-left')
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
initMap()
|
|
200
|
+
}, [])
|
|
201
|
+
|
|
202
|
+
return <div id="map" style={{ width: '100%', height: '600px' }} />
|
|
203
|
+
}
|
|
205
204
|
```
|
|
206
205
|
|
|
207
|
-
##
|
|
206
|
+
## TypeScript Support
|
|
207
|
+
|
|
208
|
+
Full TypeScript support with types from AWS SDK:
|
|
208
209
|
|
|
209
|
-
|
|
210
|
+
```typescript
|
|
211
|
+
import type { SuggestCommandOutput } from '@aws-sdk/client-geo-places'
|
|
210
212
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
- `GetPlaceCommand` - Get place details by ID
|
|
213
|
+
const response: SuggestCommandOutput = await client.send(
|
|
214
|
+
new SuggestCommand({ QueryText: 'Vancouver' })
|
|
215
|
+
)
|
|
216
|
+
```
|
|
216
217
|
|
|
217
218
|
## License
|
|
218
219
|
|
package/package.json
CHANGED