@safercity/sdk 0.1.3 → 0.2.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 +54 -47
- package/dist/index.cjs +274 -91
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +375 -150
- package/dist/index.d.ts +375 -150
- package/dist/index.js +274 -91
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Official SaferCity API client for TypeScript/JavaScript.
|
|
4
4
|
|
|
5
|
+
## What's New in v0.2.0
|
|
6
|
+
|
|
7
|
+
- **User-Scoped Client** - The main client is now user-scoped (Stripe publishable key pattern). Admin operations moved to `ServerClient`.
|
|
8
|
+
- **Panic Information** - Full CRUD for user panic profiles and emergency contacts.
|
|
9
|
+
- **Proxy Enhancements** - Added allowlist/blocklist support for proxy endpoints.
|
|
10
|
+
- **Automatic Scoping** - Client now tracks `userId` and automatically scopes requests.
|
|
11
|
+
- **Path Alignment** - All SDK paths now match the latest API schema (singular `/v1/panic`, etc.).
|
|
12
|
+
|
|
5
13
|
## What's New in v0.1.3
|
|
6
14
|
|
|
7
15
|
- **OAuth endpoint path fix** - Fixed paths (`/oauth/*` → `/v1/oauth/*`)
|
|
@@ -46,10 +54,12 @@ const client = createSaferCityClient({
|
|
|
46
54
|
baseUrl: 'https://api.safercity.com',
|
|
47
55
|
token: externalAuthToken,
|
|
48
56
|
tenantId: 'your-tenant-id',
|
|
57
|
+
userId: 'user-123', // optional, for auto-scoping
|
|
49
58
|
});
|
|
50
59
|
|
|
51
|
-
// Update token when
|
|
60
|
+
// Update token or user when they change
|
|
52
61
|
client.setToken(newToken);
|
|
62
|
+
client.setUserId(newUserId);
|
|
53
63
|
```
|
|
54
64
|
|
|
55
65
|
### Cookie Mode
|
|
@@ -60,6 +70,7 @@ Browser with `credentials: include`. For first-party web apps using session cook
|
|
|
60
70
|
const client = createSaferCityClient({
|
|
61
71
|
baseUrl: 'https://api.safercity.com',
|
|
62
72
|
tenantId: 'your-tenant-id',
|
|
73
|
+
userId: 'user-123', // optional
|
|
63
74
|
});
|
|
64
75
|
```
|
|
65
76
|
|
|
@@ -78,13 +89,12 @@ const client = createSaferCityClient({
|
|
|
78
89
|
const { data: health } = await client.health.check();
|
|
79
90
|
console.log('API Status:', health.status);
|
|
80
91
|
|
|
81
|
-
// Get user
|
|
82
|
-
const { data: user } = await client.users.get(
|
|
92
|
+
// Get user (auto-resolves userId from client if not passed)
|
|
93
|
+
const { data: user } = await client.users.get();
|
|
83
94
|
console.log('User:', user);
|
|
84
95
|
|
|
85
|
-
// Create panic
|
|
96
|
+
// Create panic (userId is optional if set on client)
|
|
86
97
|
const { data: panic } = await client.panics.create({
|
|
87
|
-
userId: 'user-123',
|
|
88
98
|
latitude: -26.2041,
|
|
89
99
|
longitude: 28.0473,
|
|
90
100
|
});
|
|
@@ -110,13 +120,24 @@ const client = createServerClient({
|
|
|
110
120
|
|
|
111
121
|
// All requests are automatically authenticated with OAuth tokens
|
|
112
122
|
// Tokens are refreshed automatically before expiration
|
|
113
|
-
const { data: users } = await client.users.list();
|
|
123
|
+
const { data: users } = await client.users.list(); // Admin only
|
|
114
124
|
const { data: panic } = await client.panics.create({
|
|
115
125
|
userId: 'user-123',
|
|
116
126
|
latitude: -26.2041,
|
|
117
127
|
longitude: 28.0473,
|
|
118
128
|
});
|
|
119
129
|
|
|
130
|
+
// ServerClient has ALL endpoints including admin-only ones:
|
|
131
|
+
// - client.oauth.*
|
|
132
|
+
// - client.tenants.*
|
|
133
|
+
// - client.credentials.*
|
|
134
|
+
// - client.users.list()
|
|
135
|
+
// - client.users.delete()
|
|
136
|
+
// - client.users.updateStatus()
|
|
137
|
+
// - client.panics.list()
|
|
138
|
+
// - client.subscriptions.stats()
|
|
139
|
+
// - client.panicInformation.list()
|
|
140
|
+
|
|
120
141
|
// Low-level requests still work too
|
|
121
142
|
const response = await client.get('/v1/custom-endpoint');
|
|
122
143
|
|
|
@@ -207,26 +228,15 @@ interface ProxyConfig {
|
|
|
207
228
|
pathPrefix?: string; // default: "/api/safercity"
|
|
208
229
|
forwardHeaders?: string[]; // default: ["content-type", "accept", "x-request-id"]
|
|
209
230
|
fetch?: typeof fetch;
|
|
231
|
+
allowedEndpoints?: EndpointPattern[]; // Explicit allowlist
|
|
232
|
+
blockedEndpoints?: EndpointPattern[]; // Explicit blocklist
|
|
210
233
|
}
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
## OAuth Token Flow
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
const client = createSaferCityClient({
|
|
217
|
-
baseUrl: 'https://api.safercity.com',
|
|
218
|
-
});
|
|
219
234
|
|
|
220
|
-
|
|
221
|
-
const { data: tokens } = await client.oauth.token({
|
|
222
|
-
grant_type: 'client_credentials',
|
|
223
|
-
tenantId: 'your-tenant-id',
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
// Set token on client
|
|
227
|
-
client.setToken(tokens.access_token);
|
|
235
|
+
type EndpointPattern = string | { method?: string; path: string };
|
|
228
236
|
```
|
|
229
237
|
|
|
238
|
+
Allowlist takes precedence over blocklist. Patterns match by path prefix (case-insensitive).
|
|
239
|
+
|
|
230
240
|
## Streaming (SSE)
|
|
231
241
|
|
|
232
242
|
Stream real-time panic updates:
|
|
@@ -246,54 +256,51 @@ for await (const event of client.panics.streamUpdates('panic-123')) {
|
|
|
246
256
|
- `client.auth.whoami()` - Get current auth context
|
|
247
257
|
- `client.auth.check()` - Check if authenticated (optional auth)
|
|
248
258
|
|
|
249
|
-
###
|
|
250
|
-
- `client.oauth.token(body)` - Get access token
|
|
251
|
-
- `client.oauth.refresh(body)` - Refresh token
|
|
252
|
-
- `client.oauth.introspect(body)` - Introspect token
|
|
253
|
-
- `client.oauth.revoke(body)` - Revoke token
|
|
254
|
-
|
|
255
|
-
### Tenants
|
|
256
|
-
- `client.tenants.create(body)` - Create a new tenant
|
|
257
|
-
- `client.tenants.list(query?)` - List tenants
|
|
258
|
-
|
|
259
|
-
### Credentials
|
|
260
|
-
- `client.credentials.setup(body)` - Exchange setup token for credentials
|
|
261
|
-
- `client.credentials.list()` - List credentials
|
|
262
|
-
- `client.credentials.revoke(credentialId)` - Revoke credential
|
|
263
|
-
|
|
264
|
-
### Users
|
|
259
|
+
### Users (User-Scoped)
|
|
265
260
|
- `client.users.create(body)` - Create user
|
|
266
|
-
- `client.users.
|
|
267
|
-
- `client.users.
|
|
268
|
-
- `client.users.update(userId, body)` - Update user
|
|
269
|
-
- `client.users.updateStatus(userId, body)` - Update user status
|
|
270
|
-
- `client.users.delete(userId)` - Delete user
|
|
261
|
+
- `client.users.get(userId?)` - Get user by ID (defaults to client's `userId`)
|
|
262
|
+
- `client.users.update(userId?, body)` - Update user (defaults to client's `userId`)
|
|
271
263
|
|
|
272
264
|
### Panics
|
|
273
265
|
- `client.panics.create(body)` - Create panic
|
|
274
266
|
- `client.panics.get(panicId, query?)` - Get panic
|
|
275
267
|
- `client.panics.updateLocation(panicId, body)` - Update location
|
|
276
268
|
- `client.panics.cancel(panicId, body)` - Cancel panic
|
|
269
|
+
- `client.panics.types(userId?)` - Get available panic types for a user
|
|
277
270
|
- `client.panics.streamUpdates(panicId, options?)` - Stream updates (SSE)
|
|
278
271
|
|
|
272
|
+
### Panic Information
|
|
273
|
+
- `client.panicInformation.create(body)` - Create panic profile
|
|
274
|
+
- `client.panicInformation.get(id)` - Get profile by ID
|
|
275
|
+
- `client.panicInformation.getByUser(userId?)` - Get profile by user ID
|
|
276
|
+
- `client.panicInformation.update(id, body)` - Update profile
|
|
277
|
+
- `client.panicInformation.delete(id)` - Delete profile
|
|
278
|
+
- `client.panicInformation.validateEligibility(userId?)` - Check if user is eligible for panic services
|
|
279
|
+
|
|
279
280
|
### Subscriptions
|
|
280
281
|
- `client.subscriptions.listTypes()` - List subscription types
|
|
281
282
|
- `client.subscriptions.create(body)` - Create subscription
|
|
282
|
-
- `client.subscriptions.list(query?)` - List subscriptions
|
|
283
|
+
- `client.subscriptions.list(query?)` - List subscriptions for a user
|
|
284
|
+
- `client.subscriptions.subscribeUser(body)` - Shorthand to subscribe a user
|
|
283
285
|
|
|
284
286
|
### Notifications
|
|
285
287
|
- `client.notifications.createSubscriber(body)` - Create subscriber
|
|
286
288
|
- `client.notifications.trigger(body)` - Trigger notification
|
|
287
|
-
- `client.notifications.
|
|
288
|
-
- `client.notifications.
|
|
289
|
+
- `client.notifications.bulkTrigger(body)` - Bulk trigger notifications
|
|
290
|
+
- `client.notifications.getPreferences(userId?)` - Get user preferences
|
|
291
|
+
- `client.notifications.updatePreferences(userId?, body)` - Update preferences
|
|
289
292
|
|
|
290
293
|
### Location Safety
|
|
291
|
-
- `client.locationSafety.check(
|
|
294
|
+
- `client.locationSafety.check(body)` - Check location safety (POST)
|
|
295
|
+
|
|
296
|
+
### Banner
|
|
297
|
+
- `client.banner.get(body)` - Get crime banner data for a location
|
|
292
298
|
|
|
293
299
|
### Crimes
|
|
294
300
|
- `client.crimes.list(query?)` - List crimes
|
|
295
301
|
- `client.crimes.categories()` - Get crime categories
|
|
296
302
|
- `client.crimes.types()` - Get crime types
|
|
303
|
+
- `client.crimes.categoriesWithTypes()` - Get categories with nested types
|
|
297
304
|
|
|
298
305
|
## Error Handling
|
|
299
306
|
|