@safercity/sdk 0.2.1 → 0.3.1

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 CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  Official SaferCity API client for TypeScript/JavaScript.
4
4
 
5
+ ## What's New in v0.3.1
6
+
7
+ - **Simplified Return Types** - Domain methods now return the API response body directly instead of wrapping in `ApiResponse<T>`. For example, `client.health.check()` returns `Promise<{ status: string; timestamp: string }>` directly. No more `result.data.data.id` — just `result.data.id`.
8
+ - **Strongly Typed Errors** - All SDK methods throw `SaferCityApiError` on non-2xx responses with typed `status`, `error`, `message`, and `details` fields. Error handling is unchanged from v0.3.0.
9
+ - **Low-Level Access Preserved** - `client._client.get()` and `ServerClient.get()` still return the full `ApiResponse<T>` with `{ data, status, headers }` for cases where you need HTTP metadata.
10
+
11
+ ## What's New in v0.3.0
12
+
13
+ - **Typed SDK via OpenAPI Codegen** - All request/response types are now auto-generated from the API's OpenAPI spec using `@hey-api/openapi-ts`. This guarantees 1:1 type alignment between the SDK and API — no more manual type mismatches.
14
+ - **Re-exported Generated Types** - All generated API types (request bodies, response shapes, error types) are re-exported from `@safercity/sdk` for direct use in your application.
15
+ - **Correct Field Names** - Request bodies now use the exact API field names (`emailAddress` not `email`, `panicType` not `panicTypeId`, `phoneNumber` not `phone`).
16
+ - **Simplified Return Types** - Domain methods now return the API response body directly instead of wrapping in `ApiResponse<T>`. Access `result.data.id` instead of `result.data.data.id`.
17
+ - **Richer Response Types** - Response types now include the full API response structure (e.g., `{ success: boolean; data: {...}; message?: string }`).
18
+
5
19
  ## What's New in v0.2.0
6
20
 
7
21
  - **User-Scoped Client** - The main client is now user-scoped (Stripe publishable key pattern). Admin operations moved to `ServerClient`.
@@ -86,19 +100,22 @@ const client = createSaferCityClient({
86
100
  });
87
101
 
88
102
  // Health check
89
- const { data: health } = await client.health.check();
103
+ const health = await client.health.check();
90
104
  console.log('API Status:', health.status);
91
105
 
92
106
  // Get user (auto-resolves userId from client if not passed)
93
- const { data: user } = await client.users.get();
94
- console.log('User:', user);
107
+ const user = await client.users.get();
108
+ console.log('User:', user.data.firstName);
95
109
 
96
110
  // Create panic (userId is optional if set on client)
97
- const { data: panic } = await client.panics.create({
111
+ const panic = await client.panics.create({
112
+ userId: 'user-123',
113
+ panicType: 'emergency',
98
114
  latitude: -26.2041,
99
115
  longitude: 28.0473,
100
116
  });
101
- console.log('Panic created:', panic.id);
117
+
118
+ console.log('Panic created:', panic.data.id);
102
119
  ```
103
120
 
104
121
  ## Server Client
@@ -120,13 +137,15 @@ const client = createServerClient({
120
137
 
121
138
  // All requests are automatically authenticated with OAuth tokens
122
139
  // Tokens are refreshed automatically before expiration
123
- const { data: users } = await client.users.list(); // Admin only
124
- const { data: panic } = await client.panics.create({
140
+ const users = await client.users.list(); // Admin only
141
+ const panic = await client.panics.create({
125
142
  userId: 'user-123',
143
+ panicType: 'emergency',
126
144
  latitude: -26.2041,
127
145
  longitude: 28.0473,
128
146
  });
129
147
 
148
+
130
149
  // ServerClient has ALL endpoints including admin-only ones:
131
150
  // - client.oauth.*
132
151
  // - client.tenants.*
@@ -257,9 +276,9 @@ for await (const event of client.panics.streamUpdates('panic-123')) {
257
276
  - `client.auth.check()` - Check if authenticated (optional auth)
258
277
 
259
278
  ### Users (User-Scoped)
260
- - `client.users.create(body)` - Create user
279
+ - `client.users.create(body)` - Create user (`emailAddress`, `firstName`, `lastName`, `phoneNumber?`, `password?`)
261
280
  - `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`)
281
+ - `client.users.update(userId?, body)` - Update user (`emailAddress?`, `firstName?`, `lastName?`, `phoneNumber?`, `password?`)
263
282
 
264
283
  ### Panics
265
284
  - `client.panics.create(body)` - Create panic
@@ -270,7 +289,7 @@ for await (const event of client.panics.streamUpdates('panic-123')) {
270
289
  - `client.panics.streamUpdates(panicId, options?)` - Stream updates (SSE)
271
290
 
272
291
  ### Panic Information
273
- - `client.panicInformation.create(body)` - Create panic profile
292
+ - `client.panicInformation.create(body)` - Create panic profile (`userId`, `phoneNumber`, `firstName`, `lastName`, `idNumber`, `duressCode`, `emergencyContacts?`)
274
293
  - `client.panicInformation.get(id)` - Get profile by ID
275
294
  - `client.panicInformation.getByUser(userId?)` - Get profile by user ID
276
295
  - `client.panicInformation.update(id, body)` - Update profile
@@ -281,7 +300,7 @@ for await (const event of client.panics.streamUpdates('panic-123')) {
281
300
  - `client.subscriptions.listTypes()` - List subscription types
282
301
  - `client.subscriptions.create(body)` - Create subscription
283
302
  - `client.subscriptions.list(query?)` - List subscriptions for a user
284
- - `client.subscriptions.subscribeUser(body)` - Shorthand to subscribe a user
303
+ - `client.subscriptions.subscribeUser(body)` - Shorthand to subscribe a user (`userId`, `isPremium`, `startDate?`, `endDate?`, `notes?`)
285
304
 
286
305
  ### Notifications
287
306
  - `client.notifications.createSubscriber(body)` - Create subscriber
@@ -331,6 +350,40 @@ const client = createSaferCityClient({
331
350
  });
332
351
  ```
333
352
 
353
+ ## Type Generation
354
+
355
+ The SDK types are auto-generated from the API's OpenAPI specification using `@hey-api/openapi-ts`.
356
+
357
+ ### Regenerating Types
358
+
359
+ If the API schema changes, regenerate the types:
360
+
361
+ ```bash
362
+ # Start the API server locally first
363
+ bun run dev
364
+
365
+ # Fetch the latest OpenAPI spec and regenerate types
366
+ bun run -C packages/sdk/client generate:all
367
+
368
+ # Or step by step:
369
+ bun run -C packages/sdk/client fetch:openapi # Fetches from http://localhost:3000/openapi
370
+ bun run -C packages/sdk/client generate # Generates types from openapi.json
371
+ ```
372
+
373
+ ### Using Generated Types
374
+
375
+ All generated types are re-exported from `@safercity/sdk`:
376
+
377
+ ```typescript
378
+ import type {
379
+ UserCreateBody,
380
+ PanicCreatedResponse,
381
+ CreatePanicBody,
382
+ GetV1UsersByUserIdResponse,
383
+ PanicInformationResponse,
384
+ } from '@safercity/sdk';
385
+ ```
386
+
334
387
  ## Related Packages
335
388
 
336
389
  - `@safercity/sdk-react` - React hooks with TanStack Query