@safercity/sdk 0.3.2 → 0.4.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/CHANGELOG.md +56 -0
- package/README.md +16 -6
- package/dist/index.cjs +32 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2081 -2003
- package/dist/index.d.ts +2081 -2003
- package/dist/index.js +32 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# @safercity/sdk
|
|
2
|
+
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **100% Codegen Types** - All request bodies, query params, and response types in `client.ts` and `server.ts` now reference generated OpenAPI types from `types.gen.ts`. Zero inline/manual type literals remain. Future API changes auto-propagate via `bun run generate:all`.
|
|
8
|
+
- **Subscription SDK Realignment** - Removed `subscriptions.subscribeUser()` (dead route). Updated `subscriptions.create()` to use `isPremium` flag. Added lifecycle methods to `ServerClient`: `getByUser()`, `update()`, and `switch()`.
|
|
9
|
+
- **Panic SDK Enhancements** - Added `panics.createPremium()` for CellFind provider integration and `panics.eligibility()` for pre-panic validation. Expanded `updateLocation()` and `cancel()` with additional metadata fields.
|
|
10
|
+
|
|
11
|
+
### Breaking Changes
|
|
12
|
+
|
|
13
|
+
- `subscriptions.subscribeUser()` removed — use `subscriptions.create({ isPremium: true })` instead.
|
|
14
|
+
- `subscriptions.create()` body shape changed from `{ subscriptionTypeId }` to `{ isPremium, startDate?, endDate?, notes? }`.
|
|
15
|
+
|
|
16
|
+
## 0.3.2
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- **Proxy Mode Enhanced** - `ProxyModeConfig` now supports `tenantId`, `userId`, and custom `headers`.
|
|
21
|
+
- **Banner API Fix** - Fixed `banner.get()` parameter from `radius` to `days`.
|
|
22
|
+
|
|
23
|
+
## 0.3.1
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- **Simplified Return Types** - Domain methods return API body directly instead of `ApiResponse<T>` wrapper.
|
|
28
|
+
- **Strongly Typed Errors** - All methods throw `SaferCityApiError` on non-2xx responses.
|
|
29
|
+
|
|
30
|
+
## 0.3.0
|
|
31
|
+
|
|
32
|
+
### Minor Changes
|
|
33
|
+
|
|
34
|
+
- **Typed SDK via OpenAPI Codegen** - All types auto-generated from the API's OpenAPI spec.
|
|
35
|
+
- **Re-exported Generated Types** - All generated API types available from `@safercity/sdk`.
|
|
36
|
+
|
|
37
|
+
## 0.2.0
|
|
38
|
+
|
|
39
|
+
### Minor Changes
|
|
40
|
+
|
|
41
|
+
- **User-Scoped Client** - Client now user-scoped. Admin operations moved to `ServerClient`.
|
|
42
|
+
- **Panic Information** - Full CRUD for user panic profiles.
|
|
43
|
+
- **Proxy Enhancements** - Allowlist/blocklist support for proxy endpoints.
|
|
44
|
+
|
|
45
|
+
## 0.1.3
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- **OAuth endpoint path fix** - Fixed paths (`/oauth/*` -> `/v1/oauth/*`).
|
|
50
|
+
- **ServerClient domain helpers** - Added typed domain helpers.
|
|
51
|
+
|
|
52
|
+
## 0.1.0
|
|
53
|
+
|
|
54
|
+
### Minor Changes
|
|
55
|
+
|
|
56
|
+
- Initial release with client SDK, server client, proxy middleware, and streaming support.
|
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Official SaferCity API client for TypeScript/JavaScript.
|
|
4
4
|
|
|
5
|
+
## What's New in v0.4.0
|
|
6
|
+
|
|
7
|
+
- **100% Codegen Types** - All request bodies, query params, and response types in `client.ts` and `server.ts` now reference the generated OpenAPI types from `types.gen.ts`. Zero inline/manual type literals remain. Future API changes auto-propagate via `bun run generate:all`.
|
|
8
|
+
- **Subscription SDK Realignment** - Removed `client.subscriptions.subscribeUser()` (dead route). Updated `client.subscriptions.create()` to use `isPremium` flag. Added lifecycle methods to `ServerClient`: `getByUser()`, `update()`, and `switch()`.
|
|
9
|
+
- **Panic SDK Enhancements** - Added `client.panics.createPremium()` for CellFind provider integration and `client.panics.eligibility()` for pre-panic validation. Expanded `updateLocation()` and `cancel()` with additional metadata fields.
|
|
10
|
+
- **Breaking Changes** - `subscriptions.subscribeUser()` removed. `subscriptions.create()` body shape changed to `isPremium`-based.
|
|
11
|
+
|
|
5
12
|
## What's New in v0.3.2
|
|
6
13
|
|
|
7
14
|
- **Proxy Mode Enhanced** - `ProxyModeConfig` now supports `tenantId`, `userId`, and custom `headers`. White-label apps can pass tenant context through the proxy without exposing credentials.
|
|
@@ -172,7 +179,9 @@ const panic = await client.panics.create({
|
|
|
172
179
|
// - client.users.delete()
|
|
173
180
|
// - client.users.updateStatus()
|
|
174
181
|
// - client.panics.list()
|
|
175
|
-
// - client.subscriptions.
|
|
182
|
+
// - client.subscriptions.getByUser(userId)
|
|
183
|
+
// - client.subscriptions.update(id, body)
|
|
184
|
+
// - client.subscriptions.switch(id, body)
|
|
176
185
|
// - client.panicInformation.list()
|
|
177
186
|
|
|
178
187
|
// Low-level requests still work too
|
|
@@ -300,9 +309,11 @@ for await (const event of client.panics.streamUpdates('panic-123')) {
|
|
|
300
309
|
|
|
301
310
|
### Panics
|
|
302
311
|
- `client.panics.create(body)` - Create panic
|
|
312
|
+
- `client.panics.createPremium(body)` - Create premium panic with CellFind provider
|
|
303
313
|
- `client.panics.get(panicId, query?)` - Get panic
|
|
304
|
-
- `client.panics.updateLocation(panicId, body)` - Update location
|
|
305
|
-
- `client.panics.cancel(panicId, body)` - Cancel panic
|
|
314
|
+
- `client.panics.updateLocation(panicId, body)` - Update location (supports `accuracy`, `speed`, `batteryLevel`, etc.)
|
|
315
|
+
- `client.panics.cancel(panicId, body)` - Cancel panic (supports `reason`, `cancelledByUser`)
|
|
316
|
+
- `client.panics.eligibility(userId?)` - Check panic eligibility (subscription + profile)
|
|
306
317
|
- `client.panics.types(userId?)` - Get available panic types for a user
|
|
307
318
|
- `client.panics.streamUpdates(panicId, options?)` - Stream updates (SSE)
|
|
308
319
|
|
|
@@ -316,9 +327,8 @@ for await (const event of client.panics.streamUpdates('panic-123')) {
|
|
|
316
327
|
|
|
317
328
|
### Subscriptions
|
|
318
329
|
- `client.subscriptions.listTypes()` - List subscription types
|
|
319
|
-
- `client.subscriptions.create(body)` - Create subscription
|
|
320
|
-
- `client.subscriptions.list(query?)` - List subscriptions
|
|
321
|
-
- `client.subscriptions.subscribeUser(body)` - Shorthand to subscribe a user (`userId`, `isPremium`, `startDate?`, `endDate?`, `notes?`)
|
|
330
|
+
- `client.subscriptions.create(body)` - Create subscription (`userId`, `isPremium`, `startDate?`, `endDate?`, `notes?`)
|
|
331
|
+
- `client.subscriptions.list(query?)` - List subscriptions (supports `status`, `subscriptionTypeId`, `sortBy`, `search`, etc.)
|
|
322
332
|
|
|
323
333
|
### Notifications
|
|
324
334
|
- `client.notifications.createSubscriber(body)` - Create subscriber
|
package/dist/index.cjs
CHANGED
|
@@ -128,6 +128,23 @@ function createSaferCityClient(options) {
|
|
|
128
128
|
* Get available panic types for a user
|
|
129
129
|
*/
|
|
130
130
|
types: (userId2) => baseClient.get(`/v1/panic/types/${resolveUserId(userId2)}`).then((r) => r.data),
|
|
131
|
+
/**
|
|
132
|
+
* Create a premium panic with CellFind provider
|
|
133
|
+
*/
|
|
134
|
+
createPremium: async (body) => {
|
|
135
|
+
const response = await baseClient.post("/v1/premium_panic", {
|
|
136
|
+
...body,
|
|
137
|
+
userId: resolveUserId(body.userId)
|
|
138
|
+
}).then((r) => r.data);
|
|
139
|
+
return response;
|
|
140
|
+
},
|
|
141
|
+
/**
|
|
142
|
+
* Check panic eligibility for a user.
|
|
143
|
+
* Validates subscription status and panic profile completeness.
|
|
144
|
+
*/
|
|
145
|
+
eligibility: (userId2) => baseClient.get(
|
|
146
|
+
`/v1/panic-information/validation/${resolveUserId(userId2)}`
|
|
147
|
+
).then((r) => r.data),
|
|
131
148
|
/**
|
|
132
149
|
* Stream panic updates (SSE)
|
|
133
150
|
*/
|
|
@@ -189,7 +206,7 @@ function createSaferCityClient(options) {
|
|
|
189
206
|
*/
|
|
190
207
|
listTypes: () => baseClient.get("/v1/subscriptions/types").then((r) => r.data),
|
|
191
208
|
/**
|
|
192
|
-
* Create subscription
|
|
209
|
+
* Create subscription (subscribe user with premium flag)
|
|
193
210
|
*/
|
|
194
211
|
create: async (body) => {
|
|
195
212
|
const response = await baseClient.post("/v1/subscriptions", {
|
|
@@ -209,16 +226,6 @@ function createSaferCityClient(options) {
|
|
|
209
226
|
}
|
|
210
227
|
}).then((r) => r.data);
|
|
211
228
|
return response;
|
|
212
|
-
},
|
|
213
|
-
/**
|
|
214
|
-
* Subscribe a user to a subscription type
|
|
215
|
-
*/
|
|
216
|
-
subscribeUser: async (body) => {
|
|
217
|
-
const response = await baseClient.post(
|
|
218
|
-
"/v1/subscriptions/subscribe-user",
|
|
219
|
-
{ ...body, userId: resolveUserId(body.userId) }
|
|
220
|
-
).then((r) => r.data);
|
|
221
|
-
return response;
|
|
222
229
|
}
|
|
223
230
|
},
|
|
224
231
|
// ==================
|
|
@@ -516,7 +523,11 @@ var ServerClient = class extends sdkCore.BaseClient {
|
|
|
516
523
|
/**
|
|
517
524
|
* Get available panic types for a user
|
|
518
525
|
*/
|
|
519
|
-
types: (userId) => this.get(`/v1/panic/types/${userId}`).then((r) => r.data)
|
|
526
|
+
types: (userId) => this.get(`/v1/panic/types/${userId}`).then((r) => r.data),
|
|
527
|
+
/**
|
|
528
|
+
* Create a premium panic with CellFind provider
|
|
529
|
+
*/
|
|
530
|
+
createPremium: (body) => this.post("/v1/premium_panic", body).then((r) => r.data)
|
|
520
531
|
};
|
|
521
532
|
}
|
|
522
533
|
// ==================
|
|
@@ -532,7 +543,7 @@ var ServerClient = class extends sdkCore.BaseClient {
|
|
|
532
543
|
*/
|
|
533
544
|
listTypes: () => this.get("/v1/subscriptions/types").then((r) => r.data),
|
|
534
545
|
/**
|
|
535
|
-
* Create subscription
|
|
546
|
+
* Create subscription (subscribe user with premium flag)
|
|
536
547
|
*/
|
|
537
548
|
create: (body) => this.post("/v1/subscriptions", body).then((r) => r.data),
|
|
538
549
|
/**
|
|
@@ -540,13 +551,17 @@ var ServerClient = class extends sdkCore.BaseClient {
|
|
|
540
551
|
*/
|
|
541
552
|
list: (query) => this.get("/v1/subscriptions", { query }).then((r) => r.data),
|
|
542
553
|
/**
|
|
543
|
-
* Get
|
|
554
|
+
* Get subscriptions for a specific user
|
|
555
|
+
*/
|
|
556
|
+
getByUser: (userId) => this.get(`/v1/subscriptions/user/${userId}`).then((r) => r.data),
|
|
557
|
+
/**
|
|
558
|
+
* Update subscription fields (endDate, notes)
|
|
544
559
|
*/
|
|
545
|
-
|
|
560
|
+
update: (subscriptionId, body) => this.patch(`/v1/subscriptions/${subscriptionId}`, body).then((r) => r.data),
|
|
546
561
|
/**
|
|
547
|
-
*
|
|
562
|
+
* Switch subscription plan (upgrade/downgrade)
|
|
548
563
|
*/
|
|
549
|
-
|
|
564
|
+
switch: (subscriptionId, body) => this.put(`/v1/subscriptions/${subscriptionId}/switch`, body).then((r) => r.data)
|
|
550
565
|
};
|
|
551
566
|
}
|
|
552
567
|
// ==================
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/server.ts","../src/proxy.ts"],"names":["BaseClient","createStreamAdapter","userId","options","TokenManager"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * SaferCity API Client\n * \n * Client SDK for interacting with the SaferCity multi-tenant API.\n * Provides typed methods for user-scoped endpoints with streaming support.\n * \n * Admin-only operations (tenants, credentials, oauth, user management)\n * are available exclusively through the ServerClient.\n */\n\nimport {\n BaseClient,\n type SaferCityConfig,\n type StreamAdapter,\n createStreamAdapter,\n type ServerSentEvent,\n type EventSourceOptions,\n} from '@safercity/sdk-core';\n\nimport type {\n CreatePanicBody,\n CreatePanicInformationBody,\n GetAuthOptionalResponse,\n GetAuthWhoamiResponse,\n GetHealthResponse,\n GetV1CrimeCategoriesResponse,\n GetV1CrimeTypesResponse,\n GetV1CrimesListResponse,\n GetV1NotificationsPreferencesByUserIdResponse,\n GetV1PanicInformationValidationByUserIdResponse,\n GetV1SubscriptionsResponse,\n GetV1SubscriptionsTypesResponse,\n GetV1UsersByUserIdResponse,\n LocationUpdateResponse,\n PanicCancelledResponse,\n PanicCreatedResponse,\n PanicInformationCreatedResponse,\n PanicInformationResponse,\n PanicResponse,\n PostV1BannerResponse,\n PostV1LocationsSafetyCheckResponse,\n PostV1NotificationsBulkTriggerResponse,\n PostV1NotificationsSubscribersResponse,\n PostV1NotificationsTriggerResponse,\n PostV1SubscriptionsSubscribeUserData,\n PostV1SubscriptionsSubscribeUserResponse,\n PostV1SubscriptionsResponse,\n PostV1UsersResponse,\n PutV1NotificationsPreferencesByUserIdResponse,\n PutV1UsersByUserIdResponse,\n UpdatePanicInformationBody,\n UserCreateBody,\n UserUpdateBody,\n} from './generated/types.gen';\n\n// ==================\n// Types\n// ==================\n\nexport type PanicInformationRecord = PanicInformationResponse['data'];\n\nexport interface SaferCityClientOptions extends SaferCityConfig {\n /**\n * User ID for user-scoped operations\n */\n userId?: string;\n /**\n * Custom stream adapter for SSE (auto-detected if not provided)\n */\n streamAdapter?: StreamAdapter;\n}\n\n/**\n * Create a SaferCity API client\n * \n * This client exposes user-scoped endpoints only.\n * For admin/server operations, use `createServerClient` instead.\n */\nexport function createSaferCityClient(options: SaferCityClientOptions) {\n const baseClient = new BaseClient(options);\n const streamAdapter = options.streamAdapter ?? createStreamAdapter(options.fetch);\n let userId = options.userId;\n\n const resolveUserId = (explicit?: string): string => {\n const resolved = explicit ?? userId;\n if (!resolved) {\n throw new Error(\n 'userId is required. Either pass it as a parameter or set it on the client via setUserId() or in the provider config.'\n );\n }\n return resolved;\n };\n \n return {\n /**\n * Access the underlying base client for custom requests\n */\n _client: baseClient,\n \n /**\n * Update authentication token\n */\n setToken: (token: string | undefined) => baseClient.setToken(token),\n \n /**\n * Update tenant ID\n */\n setTenantId: (tenantId: string | undefined) => baseClient.setTenantId(tenantId),\n\n /**\n * Update user ID\n */\n setUserId: (nextUserId: string | undefined) => {\n userId = nextUserId;\n },\n\n /**\n * Get current user ID\n */\n getUserId: () => userId,\n \n /**\n * Get current configuration\n */\n getConfig: () => baseClient.getConfig(),\n\n // ==================\n // Health & System\n // ==================\n \n health: {\n /**\n * Check API health status\n */\n check: () => baseClient.get<GetHealthResponse>('/health').then((r) => r.data),\n },\n\n // ==================\n // Authentication\n // ==================\n \n auth: {\n /**\n * Get current authentication context\n */\n whoami: () => baseClient.get<GetAuthWhoamiResponse>('/auth/whoami').then((r) => r.data),\n \n /**\n * Check if authenticated (optional auth)\n */\n check: () => baseClient.get<GetAuthOptionalResponse>('/auth/optional').then((r) => r.data),\n },\n\n // ==================\n // Users (user-scoped)\n // ==================\n \n users: {\n /**\n * Create user (used by tenant apps to register users)\n */\n create: (body: UserCreateBody) =>\n baseClient.post<PostV1UsersResponse>('/v1/users', body).then((r) => r.data),\n \n /**\n * Get user by ID\n */\n get: (userId?: string) =>\n baseClient.get<GetV1UsersByUserIdResponse>(`/v1/users/${resolveUserId(userId)}`).then((r) => r.data),\n \n /**\n * Update user (user can update self)\n */\n update: (userId: string | undefined, body: UserUpdateBody) =>\n baseClient.put<PutV1UsersByUserIdResponse>(`/v1/users/${resolveUserId(userId)}`, body).then((r) => r.data),\n },\n\n // ==================\n // Panics\n // ==================\n \n panics: {\n /**\n * Create panic\n */\n create: async (body: Omit<CreatePanicBody, 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PanicCreatedResponse>('/v1/panic', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Get panic by ID\n */\n get: (panicId: string, query?: { userId?: string }) =>\n baseClient\n .get<PanicResponse>(`/v1/panic/${panicId}`, {\n query: {\n ...query,\n userId: resolveUserId(query?.userId),\n },\n })\n .then((r) => r.data),\n \n /**\n * Update panic location\n */\n updateLocation: async (panicId: string, body: {\n userId?: string;\n latitude: number;\n longitude: number;\n accuracy?: number;\n }) => {\n const response = await baseClient\n .put<LocationUpdateResponse>(`/v1/panic/${panicId}/location`, {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Cancel panic\n */\n cancel: async (panicId: string, body: { userId?: string; reason?: string }) => {\n const response = await baseClient\n .put<PanicCancelledResponse>(`/v1/panic/${panicId}/cancel`, {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Get available panic types for a user\n */\n types: (userId?: string) =>\n baseClient\n .get<{\n types: Array<{ id: string; name: string; description?: string }>;\n }>(`/v1/panic/types/${resolveUserId(userId)}`)\n .then((r) => r.data),\n \n /**\n * Stream panic updates (SSE)\n */\n streamUpdates: (\n panicId: string,\n options?: EventSourceOptions\n ): AsyncIterable<ServerSentEvent> => {\n const config = baseClient.getConfig();\n const url = `${config.baseUrl}/v1/panic/${panicId}/stream`;\n \n return streamAdapter.createEventSource(url, {\n ...options,\n headers: {\n ...options?.headers,\n ...(config.token ? { Authorization: `Bearer ${config.token}` } : {}),\n },\n });\n },\n },\n\n // ==================\n // Panic Information\n // ==================\n \n panicInformation: {\n /**\n * Create panic information profile\n */\n create: async (body: Omit<CreatePanicInformationBody, 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PanicInformationCreatedResponse>('/v1/panic-information', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n\n /**\n * Get panic information by ID\n */\n get: (id: string) =>\n baseClient.get<PanicInformationResponse>(`/v1/panic-information/${id}`).then((r) => r.data),\n\n /**\n * Get panic information by user ID\n */\n getByUser: (userId?: string) =>\n baseClient\n .get<PanicInformationResponse>(`/v1/panic-information/user/${resolveUserId(userId)}`)\n .then((r) => r.data),\n\n /**\n * Update panic information\n */\n update: (id: string, body: UpdatePanicInformationBody) =>\n baseClient\n .put<PanicInformationCreatedResponse>(`/v1/panic-information/${id}`, body)\n .then((r) => r.data),\n\n /**\n * Delete panic information\n */\n delete: (id: string) =>\n baseClient\n .delete<{\n success: boolean;\n message: string;\n }>(`/v1/panic-information/${id}`)\n .then((r) => r.data),\n\n /**\n * Validate user eligibility for panic services\n */\n validateEligibility: (userId?: string) =>\n baseClient\n .get<GetV1PanicInformationValidationByUserIdResponse>(\n `/v1/panic-information/validation/${resolveUserId(userId)}`\n )\n .then((r) => r.data),\n },\n\n // ==================\n // Subscriptions\n // ==================\n \n subscriptions: {\n /**\n * List subscription types\n */\n listTypes: () =>\n baseClient.get<GetV1SubscriptionsTypesResponse>('/v1/subscriptions/types').then((r) => r.data),\n \n /**\n * Create subscription\n */\n create: async (body: {\n userId?: string;\n subscriptionTypeId: string;\n status?: string;\n }) => {\n const response = await baseClient\n .post<PostV1SubscriptionsResponse>('/v1/subscriptions', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * List subscriptions\n */\n list: async (query?: {\n userId?: string;\n status?: string;\n limit?: number;\n }) => {\n const response = await baseClient\n .get<GetV1SubscriptionsResponse>('/v1/subscriptions', {\n query: {\n ...query,\n userId: resolveUserId(query?.userId),\n },\n })\n .then((r) => r.data);\n return response;\n },\n\n /**\n * Subscribe a user to a subscription type\n */\n subscribeUser: async (body: Omit<PostV1SubscriptionsSubscribeUserData['body'], 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PostV1SubscriptionsSubscribeUserResponse>(\n '/v1/subscriptions/subscribe-user',\n { ...body, userId: resolveUserId(body.userId) }\n )\n .then((r) => r.data);\n return response;\n },\n },\n\n // ==================\n // Notifications\n // ==================\n \n notifications: {\n /**\n * Create subscriber\n */\n createSubscriber: async (body: {\n userId?: string;\n email?: string;\n phone?: string;\n data?: Record<string, unknown>;\n }) => {\n const response = await baseClient\n .post<PostV1NotificationsSubscribersResponse>('/v1/notifications/subscribers', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Trigger notification\n */\n trigger: async (body: {\n userId?: string;\n workflowId: string;\n payload?: Record<string, unknown>;\n }) => {\n const response = await baseClient\n .post<PostV1NotificationsTriggerResponse>('/v1/notifications/trigger', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Bulk trigger notifications\n */\n bulkTrigger: (body: {\n userIds: string[];\n workflowId: string;\n payload?: Record<string, unknown>;\n }) =>\n baseClient\n .post<PostV1NotificationsBulkTriggerResponse>(\n '/v1/notifications/bulk-trigger',\n body\n )\n .then((r) => r.data),\n \n /**\n * Get user preferences\n */\n getPreferences: (userId?: string) =>\n baseClient\n .get<GetV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${resolveUserId(userId)}`\n )\n .then((r) => r.data),\n \n /**\n * Update user preferences\n */\n updatePreferences: (userId: string | undefined, body: {\n preferences: Record<string, unknown>;\n }) =>\n baseClient\n .put<PutV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${resolveUserId(userId)}`,\n body\n )\n .then((r) => r.data),\n },\n\n // ==================\n // Location Safety\n // ==================\n \n locationSafety: {\n /**\n * Check location safety\n */\n check: (body: { latitude: number; longitude: number; radius?: number }) =>\n baseClient\n .post<PostV1LocationsSafetyCheckResponse>('/v1/locations/safety-check', body)\n .then((r) => r.data),\n },\n\n // ==================\n // Banner\n // ==================\n \n banner: {\n /**\n * Get crime banner data for a location\n */\n get: (body: { latitude: number; longitude: number; days?: number }) =>\n baseClient.post<PostV1BannerResponse>('/v1/banner', body).then((r) => r.data),\n },\n\n // ==================\n // Crimes\n // ==================\n \n crimes: {\n /**\n * List crimes\n */\n list: (query?: {\n latitude?: number;\n longitude?: number;\n radius?: number;\n type?: string;\n from?: string;\n to?: string;\n limit?: number;\n }) => baseClient.get<GetV1CrimesListResponse>('/v1/crimes/list', { query }).then((r) => r.data),\n \n /**\n * Get crime categories\n */\n categories: () =>\n baseClient.get<GetV1CrimeCategoriesResponse>('/v1/crime-categories').then((r) => r.data),\n \n /**\n * Get crime types\n */\n types: () =>\n baseClient.get<GetV1CrimeTypesResponse>('/v1/crime-types').then((r) => r.data),\n\n /**\n * Get crime categories with their types\n */\n categoriesWithTypes: () =>\n baseClient\n .get<{\n categories: Array<{\n id: string;\n name: string;\n types: Array<{ id: string; name: string }>;\n }>;\n }>('/v1/crime-categories/withTypes')\n .then((r) => r.data),\n },\n };\n}\n\nexport type SaferCityClient = ReturnType<typeof createSaferCityClient>;\n","/**\n * Server-side SaferCity Client\n * \n * For backend applications that need to authenticate with OAuth client credentials.\n * Handles automatic token management and refresh.\n */\n\nimport {\n TokenManager,\n type OAuthCredentials,\n type TokenStorage,\n BaseClient,\n type SaferCityConfig,\n} from '@safercity/sdk-core';\n\nimport type {\n CreatePanicBody,\n CreatePanicInformationBody,\n GetAuthOptionalResponse,\n GetAuthWhoamiResponse,\n GetHealthResponse,\n GetV1CrimeCategoriesResponse,\n GetV1CrimeTypesResponse,\n GetV1CrimesListResponse,\n GetV1NotificationsPreferencesByUserIdResponse,\n GetV1PanicInformationValidationByUserIdResponse,\n GetV1SubscriptionsResponse,\n GetV1SubscriptionsTypesResponse,\n GetV1UsersByUserIdResponse,\n GetV1UsersResponse,\n LocationUpdateResponse,\n PanicCancelledResponse,\n PanicCreatedResponse,\n PanicInformationCreatedResponse,\n PanicInformationListResponse,\n PanicInformationResponse,\n PanicListResponse,\n PanicResponse,\n PostV1BannerResponse,\n PostV1LocationsSafetyCheckResponse,\n PostV1NotificationsBulkTriggerResponse,\n PostV1NotificationsSubscribersResponse,\n PostV1NotificationsTriggerResponse,\n PostV1OauthIntrospectResponse,\n PostV1OauthRevokeResponse,\n PostV1OauthTokenResponse,\n PostV1SubscriptionsResponse,\n PostV1SubscriptionsSubscribeUserData,\n PostV1SubscriptionsSubscribeUserResponse,\n PostV1TenantsResponse,\n PostV1UsersResponse,\n PutV1NotificationsPreferencesByUserIdResponse,\n PutV1UsersByUserIdResponse,\n TenantCreateBody,\n UpdatePanicInformationBody,\n UserCreateBody,\n UserUpdateBody,\n} from './generated/types.gen';\n\nexport interface ServerClientConfig\n extends Pick<SaferCityConfig, 'baseUrl' | 'timeout' | 'fetch'> {\n /**\n * OAuth credentials for authentication\n */\n auth: OAuthCredentials;\n\n /**\n * Custom token storage (defaults to in-memory)\n */\n tokenStore?: TokenStorage;\n}\n\n/**\n * Server client that wraps the base client with automatic OAuth token management\n */\nexport class ServerClient extends BaseClient {\n private tokenManager: TokenManager;\n\n constructor(config: ServerClientConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n \n super({\n baseUrl,\n ...(config.timeout != null && { timeout: config.timeout }),\n ...(config.fetch != null && { fetch: config.fetch }),\n });\n\n this.tokenManager = new TokenManager({\n credentials: config.auth,\n baseUrl,\n storage: config.tokenStore,\n fetch: config.fetch,\n });\n }\n\n /**\n * Get a valid access token\n */\n async getAccessToken(): Promise<string> {\n return this.tokenManager.getToken();\n }\n\n /**\n * Force refresh the token\n */\n async refreshToken(): Promise<string> {\n return this.tokenManager.forceRefresh();\n }\n\n /**\n * Clear stored tokens\n */\n clearTokens(): void {\n this.tokenManager.clear();\n }\n\n /**\n * Make an authenticated request\n * Automatically adds the Authorization header with a valid token\n */\n protected override async request<T>(\n method: string,\n path: string,\n options?: Parameters<BaseClient['request']>[2]\n ): Promise<{ data: T; status: number; headers: Headers }> {\n // Get token and add to headers\n const token = await this.getAccessToken();\n \n const authHeaders = {\n ...options?.headers,\n Authorization: `Bearer ${token}`,\n };\n\n return super.request<T>(method, path, {\n ...options,\n headers: authHeaders,\n });\n }\n\n // ==================\n // Health & System\n // ==================\n\n /**\n * Check API health status\n */\n get health() {\n return {\n check: () => this.get<GetHealthResponse>('/health').then(r => r.data),\n };\n }\n\n // ==================\n // Authentication\n // ==================\n\n /**\n * Authentication helpers\n */\n get auth() {\n return {\n /**\n * Get current authentication context\n */\n whoami: () => this.get<GetAuthWhoamiResponse>('/auth/whoami').then(r => r.data),\n\n /**\n * Check if authenticated (optional auth)\n */\n check: () => this.get<GetAuthOptionalResponse>('/auth/optional').then(r => r.data),\n };\n }\n\n // ==================\n // OAuth\n // ==================\n\n /**\n * OAuth helpers\n */\n get oauth() {\n return {\n /**\n * Get access token\n */\n token: (body: {\n grant_type: 'client_credentials' | 'refresh_token';\n tenantId?: string;\n userId?: string;\n refresh_token?: string;\n }) => this.post<PostV1OauthTokenResponse>('/v1/oauth/token', body).then(r => r.data),\n\n /**\n * Refresh access token\n */\n refresh: (body: { refresh_token: string }) =>\n this.post<{\n access_token: string;\n token_type: string;\n expires_in: number;\n refresh_token?: string;\n }>('/v1/oauth/refresh', body).then(r => r.data),\n\n /**\n * Introspect token\n */\n introspect: (body: { token: string }) =>\n this.post<PostV1OauthIntrospectResponse>('/v1/oauth/introspect', body).then(r => r.data),\n\n /**\n * Revoke token\n */\n revoke: (body: { token: string }) =>\n this.post<PostV1OauthRevokeResponse>('/v1/oauth/revoke', body).then(r => r.data),\n };\n }\n\n // ==================\n // Tenants\n // ==================\n\n /**\n * Tenant helpers\n */\n get tenants() {\n return {\n /**\n * Create a new tenant\n */\n create: (body: TenantCreateBody) =>\n this.post<PostV1TenantsResponse>('/v1/tenants', body).then(r => r.data),\n\n /**\n * List tenants (admin)\n */\n list: (query?: { limit?: number; cursor?: string }) =>\n this.get<{\n tenants: Array<{ id: string; name: string }>;\n hasNext: boolean;\n cursor?: string;\n }>('/v1/tenants', { query }).then(r => r.data),\n };\n }\n\n // ==================\n // Credentials\n // ==================\n\n /**\n * Credential helpers\n */\n get credentials() {\n return {\n /**\n * Exchange setup token for credentials\n */\n setup: (body: { setupToken: string }) =>\n this.post<{\n clientId: string;\n clientSecret: string;\n tenantId: string;\n }>('/v1/credentials', body).then(r => r.data),\n\n /**\n * List credentials\n */\n list: () =>\n this.get<{\n credentials: Array<{\n id: string;\n clientId: string;\n createdAt: string;\n lastUsed?: string;\n }>;\n }>('/v1/credentials').then(r => r.data),\n\n /**\n * Revoke credential\n */\n revoke: (credentialId: string) =>\n this.delete<{ success: boolean }>(`/v1/credentials/${credentialId}`).then(r => r.data),\n };\n }\n\n // ==================\n // Users\n // ==================\n\n /**\n * User helpers\n */\n get users() {\n return {\n /**\n * Create user\n */\n create: (body: UserCreateBody) =>\n this.post<PostV1UsersResponse>('/v1/users', body).then(r => r.data),\n\n /**\n * List users\n */\n list: (query?: { limit?: number; cursor?: string; status?: string }) =>\n this.get<GetV1UsersResponse>('/v1/users', { query }).then(r => r.data),\n\n /**\n * Get user by ID\n */\n get: (userId: string) =>\n this.get<GetV1UsersByUserIdResponse>(`/v1/users/${userId}`).then(r => r.data),\n\n /**\n * Update user\n */\n update: (userId: string, body: UserUpdateBody) =>\n this.put<PutV1UsersByUserIdResponse>(`/v1/users/${userId}`, body).then(r => r.data),\n\n /**\n * Update user status\n */\n updateStatus: (userId: string, body: { status: string }) =>\n this.patch<{ id: string; status: string }>(`/v1/users/${userId}/status`, body).then(r => r.data),\n\n /**\n * Delete user\n */\n delete: (userId: string) =>\n this.delete<{ success: boolean }>(`/v1/users/${userId}`).then(r => r.data),\n };\n }\n\n // ==================\n // Panics\n // ==================\n\n /**\n * Panic helpers (streaming not available in server client)\n */\n get panics() {\n return {\n /**\n * Create panic\n */\n create: (body: CreatePanicBody) =>\n this.post<PanicCreatedResponse>('/v1/panic', body).then(r => r.data),\n\n /**\n * Get panic by ID\n */\n get: (panicId: string, query?: { userId?: string }) =>\n this.get<PanicResponse>(`/v1/panic/${panicId}`, { query }).then(r => r.data),\n\n /**\n * List panics\n */\n list: (query?: {\n userId?: string;\n status?: string;\n limit?: number;\n cursor?: string;\n }) => this.get<PanicListResponse>('/v1/panic', { query }).then(r => r.data),\n\n /**\n * Update panic location\n */\n updateLocation: (panicId: string, body: {\n userId: string;\n latitude: number;\n longitude: number;\n accuracy?: number;\n }) => this.put<LocationUpdateResponse>(`/v1/panic/${panicId}/location`, body).then(r => r.data),\n\n /**\n * Cancel panic\n */\n cancel: (panicId: string, body: { userId: string; reason?: string }) =>\n this.put<PanicCancelledResponse>(`/v1/panic/${panicId}/cancel`, body).then(r => r.data),\n\n /**\n * Get available panic types for a user\n */\n types: (userId: string) =>\n this.get<{\n types: Array<{ id: string; name: string; description?: string }>;\n }>(`/v1/panic/types/${userId}`).then(r => r.data),\n };\n }\n\n // ==================\n // Subscriptions\n // ==================\n\n /**\n * Subscription helpers\n */\n get subscriptions() {\n return {\n /**\n * List subscription types\n */\n listTypes: () =>\n this.get<GetV1SubscriptionsTypesResponse>('/v1/subscriptions/types').then(r => r.data),\n\n /**\n * Create subscription\n */\n create: (body: {\n userId: string;\n subscriptionTypeId: string;\n status?: string;\n }) => this.post<PostV1SubscriptionsResponse>('/v1/subscriptions', body).then(r => r.data),\n\n /**\n * List subscriptions\n */\n list: (query?: {\n userId?: string;\n status?: string;\n limit?: number;\n }) => this.get<GetV1SubscriptionsResponse>('/v1/subscriptions', { query }).then(r => r.data),\n\n /**\n * Get subscription stats\n */\n stats: () =>\n this.get<{\n total: number;\n active: number;\n byType: Record<string, number>;\n }>('/v1/subscriptions/stats').then(r => r.data),\n\n /**\n * Subscribe a user to a subscription type\n */\n subscribeUser: (body: PostV1SubscriptionsSubscribeUserData['body']) =>\n this.post<PostV1SubscriptionsSubscribeUserResponse>('/v1/subscriptions/subscribe-user', body).then(r => r.data),\n };\n }\n\n // ==================\n // Notifications\n // ==================\n\n /**\n * Notification helpers\n */\n get notifications() {\n return {\n /**\n * Create subscriber\n */\n createSubscriber: (body: {\n userId: string;\n email?: string;\n phone?: string;\n data?: Record<string, unknown>;\n }) => this.post<PostV1NotificationsSubscribersResponse>('/v1/notifications/subscribers', body).then(r => r.data),\n\n /**\n * Trigger notification\n */\n trigger: (body: {\n userId: string;\n workflowId: string;\n payload?: Record<string, unknown>;\n }) => this.post<PostV1NotificationsTriggerResponse>('/v1/notifications/trigger', body).then(r => r.data),\n\n /**\n * Bulk trigger notifications\n */\n bulkTrigger: (body: {\n userIds: string[];\n workflowId: string;\n payload?: Record<string, unknown>;\n }) => this.post<PostV1NotificationsBulkTriggerResponse>('/v1/notifications/bulk-trigger', body).then(r => r.data),\n\n /**\n * Get user preferences\n */\n getPreferences: (userId: string) =>\n this.get<GetV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${userId}`\n ).then(r => r.data),\n\n /**\n * Update user preferences\n */\n updatePreferences: (userId: string, body: {\n preferences: Record<string, unknown>;\n }) => this.put<PutV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${userId}`,\n body\n ).then(r => r.data),\n };\n }\n\n // ==================\n // Panic Information\n // ==================\n\n /**\n * Panic information helpers\n */\n get panicInformation() {\n return {\n /**\n * Create panic information profile\n */\n create: (body: CreatePanicInformationBody) =>\n this.post<PanicInformationCreatedResponse>('/v1/panic-information', body).then(r => r.data),\n\n /**\n * List panic information records\n */\n list: (query?: { limit?: number; offset?: number; userId?: string; idNumber?: string }) =>\n this.get<PanicInformationListResponse>('/v1/panic-information', { query }).then(r => r.data),\n\n /**\n * Get panic information by ID\n */\n get: (id: string) => this.get<PanicInformationResponse>(`/v1/panic-information/${id}`).then(r => r.data),\n\n /**\n * Get panic information by user ID\n */\n getByUser: (userId: string) =>\n this.get<PanicInformationResponse>(`/v1/panic-information/user/${userId}`).then(r => r.data),\n\n /**\n * Update panic information\n */\n update: (id: string, body: UpdatePanicInformationBody) =>\n this.put<PanicInformationCreatedResponse>(`/v1/panic-information/${id}`, body).then(r => r.data),\n\n /**\n * Delete panic information\n */\n delete: (id: string) => this.delete<{\n success: boolean;\n message: string;\n }>(`/v1/panic-information/${id}`).then(r => r.data),\n\n /**\n * Validate user eligibility for panic services\n */\n validateEligibility: (userId: string) =>\n this.get<GetV1PanicInformationValidationByUserIdResponse>(\n `/v1/panic-information/validation/${userId}`\n ).then(r => r.data),\n };\n }\n\n // ==================\n // Location Safety\n // ==================\n\n /**\n * Location safety helpers\n */\n get locationSafety() {\n return {\n /**\n * Check location safety\n */\n check: (body: { latitude: number; longitude: number; radius?: number }) =>\n this.post<PostV1LocationsSafetyCheckResponse>('/v1/locations/safety-check', body).then(r => r.data),\n };\n }\n\n // ==================\n // Banner\n // ==================\n\n /**\n * Banner helpers\n */\n get banner() {\n return {\n /**\n * Get crime banner data for a location\n */\n get: (body: { latitude: number; longitude: number; days?: number }) =>\n this.post<PostV1BannerResponse>('/v1/banner', body).then(r => r.data),\n };\n }\n\n // ==================\n // Crimes\n // ==================\n\n /**\n * Crime helpers\n */\n get crimes() {\n return {\n /**\n * List crimes\n */\n list: (query?: {\n latitude?: number;\n longitude?: number;\n radius?: number;\n type?: string;\n from?: string;\n to?: string;\n limit?: number;\n }) => this.get<GetV1CrimesListResponse>('/v1/crimes/list', { query }).then(r => r.data),\n\n /**\n * Get crime categories\n */\n categories: () => this.get<GetV1CrimeCategoriesResponse>('/v1/crime-categories').then(r => r.data),\n\n /**\n * Get crime types\n */\n types: () => this.get<GetV1CrimeTypesResponse>('/v1/crime-types').then(r => r.data),\n\n /**\n * Get crime categories with their types\n */\n categoriesWithTypes: () =>\n this.get<{\n categories: Array<{\n id: string;\n name: string;\n types: Array<{ id: string; name: string }>;\n }>;\n }>('/v1/crime-categories/withTypes').then(r => r.data),\n };\n }\n}\n\n/**\n * Create a server-side SaferCity client with automatic OAuth token management\n * \n * @example\n * ```typescript\n * const client = createServerClient({\n * auth: {\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * },\n * });\n * \n * // All requests are automatically authenticated\n * const users = await client.get('/v1/users');\n * ```\n */\nexport function createServerClient(config: ServerClientConfig): ServerClient {\n return new ServerClient(config);\n}\n\nexport type { OAuthCredentials, TokenStorage };\n","/**\n * Proxy Middleware Helpers\n * \n * Helpers for creating proxy endpoints that forward requests to SaferCity API\n * with automatic tenant authentication.\n */\n\nimport { TokenManager, type TokenStorage } from '@safercity/sdk-core';\n\nexport type EndpointPattern = string | { method?: string; path: string };\n\nexport interface ProxyConfig {\n /**\n * OAuth client ID\n */\n clientId: string;\n \n /**\n * OAuth client secret\n */\n clientSecret: string;\n \n /**\n * SaferCity API base URL\n * @default \"https://api.safercity.com\"\n */\n baseUrl?: string;\n \n /**\n * Tenant ID (optional, can be extracted from request)\n */\n tenantId?: string;\n \n /**\n * Custom token storage\n */\n tokenStore?: TokenStorage;\n \n /**\n * Path prefix to strip from incoming requests\n * @default \"/api/safercity\"\n */\n pathPrefix?: string;\n \n /**\n * Headers to forward from the original request\n * @default [\"content-type\", \"accept\", \"x-request-id\"]\n */\n forwardHeaders?: string[];\n \n /**\n * Custom fetch implementation\n */\n fetch?: typeof fetch;\n\n /**\n * Explicitly allowed endpoints for proxy forwarding\n */\n allowedEndpoints?: EndpointPattern[];\n\n /**\n * Explicitly blocked endpoints for proxy forwarding\n */\n blockedEndpoints?: EndpointPattern[];\n}\n\n// Singleton token manager to share across requests\nconst tokenManagers = new Map<string, TokenManager>();\n\nfunction getTokenManager(config: ProxyConfig): TokenManager {\n const key = `${config.clientId}:${config.baseUrl ?? \"default\"}`;\n \n let manager = tokenManagers.get(key);\n if (!manager) {\n manager = new TokenManager({\n credentials: {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n tenantId: config.tenantId,\n },\n baseUrl: config.baseUrl ?? \"https://api.safercity.com\",\n storage: config.tokenStore,\n fetch: config.fetch,\n });\n tokenManagers.set(key, manager);\n }\n \n return manager;\n}\n\nfunction isPathPrefixMatch(path: string, pattern: string): boolean {\n const normalizedPath = path.toLowerCase();\n const normalizedPattern = pattern.toLowerCase();\n\n if (normalizedPattern.length === 0) {\n return normalizedPath.length === 0;\n }\n\n return normalizedPath.startsWith(normalizedPattern);\n}\n\nfunction matchesEndpointPattern(method: string, path: string, pattern: EndpointPattern): boolean {\n if (typeof pattern === \"string\") {\n return isPathPrefixMatch(path, pattern);\n }\n\n const methodMatches = pattern.method\n ? pattern.method.toUpperCase() === method.toUpperCase()\n : true;\n\n return methodMatches && isPathPrefixMatch(path, pattern.path);\n}\n\nexport function isEndpointAllowed(method: string, path: string, config: ProxyConfig): boolean {\n const hasAllowlist = Array.isArray(config.allowedEndpoints);\n const hasBlocklist = Array.isArray(config.blockedEndpoints);\n\n if (!hasAllowlist && !hasBlocklist) {\n return true;\n }\n\n if (hasAllowlist) {\n return (config.allowedEndpoints ?? []).some((pattern) =>\n matchesEndpointPattern(method, path, pattern)\n );\n }\n\n return !(config.blockedEndpoints ?? []).some((pattern) =>\n matchesEndpointPattern(method, path, pattern)\n );\n}\n\n/**\n * Create a Next.js App Router handler for proxying SaferCity API requests\n * \n * @example\n * ```typescript\n * // app/api/safercity/[...path]/route.ts\n * import { createNextHandler } from \"@safercity/sdk\";\n * \n * const handler = createNextHandler({\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * });\n * \n * export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };\n * ```\n */\nexport function createNextHandler(config: ProxyConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n const pathPrefix = config.pathPrefix ?? \"/api/safercity\";\n const forwardHeaders = config.forwardHeaders ?? [\"content-type\", \"accept\", \"x-request-id\"];\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n \n return async function handler(request: Request): Promise<Response> {\n const tokenManager = getTokenManager(config);\n \n try {\n // Get access token\n const token = await tokenManager.getToken();\n \n // Build target URL\n const url = new URL(request.url);\n const path = url.pathname.replace(new RegExp(`^${pathPrefix}`), \"\");\n const targetUrl = `${baseUrl}${path}${url.search}`;\n\n if (!isEndpointAllowed(request.method, path, config)) {\n return new Response(\n JSON.stringify({\n error: \"endpoint_blocked\",\n message: `Endpoint ${request.method} ${path} is not allowed through this proxy`,\n }),\n {\n status: 403,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n }\n \n // Build headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n \n // Forward specified headers\n for (const header of forwardHeaders) {\n const value = request.headers.get(header);\n if (value) {\n headers[header] = value;\n }\n }\n \n // Forward tenant ID header if present\n const tenantIdHeader = request.headers.get(\"x-tenant-id\");\n if (tenantIdHeader) {\n headers[\"X-Tenant-ID\"] = tenantIdHeader;\n } else if (config.tenantId) {\n headers[\"X-Tenant-ID\"] = config.tenantId;\n }\n \n // Forward request body for non-GET requests\n let body: BodyInit | undefined;\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n body = await request.text();\n }\n \n // Make proxied request\n const response = await fetchFn(targetUrl, {\n method: request.method,\n headers,\n body,\n });\n \n // Return response with CORS headers\n const responseHeaders = new Headers(response.headers);\n responseHeaders.set(\"Access-Control-Allow-Origin\", \"*\");\n responseHeaders.set(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, PATCH, OPTIONS\");\n responseHeaders.set(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization, X-Tenant-ID\");\n \n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n });\n } catch (error) {\n console.error(\"[SaferCity Proxy] Error:\", error);\n \n return new Response(\n JSON.stringify({\n error: \"proxy_error\",\n message: error instanceof Error ? error.message : \"Proxy request failed\",\n }),\n {\n status: 502,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n }\n };\n}\n\n/**\n * Express/Node.js compatible request type\n */\ninterface ExpressRequest {\n method: string;\n path: string;\n url: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n query?: Record<string, string>;\n}\n\n/**\n * Express/Node.js compatible response type\n */\ninterface ExpressResponse {\n status(code: number): ExpressResponse;\n set(headers: Record<string, string>): ExpressResponse;\n json(data: unknown): void;\n send(data: string | ArrayBuffer | Uint8Array): void;\n}\n\n/**\n * Express next function type\n */\ntype NextFunction = (error?: unknown) => void;\n\n/**\n * Create an Express middleware for proxying SaferCity API requests\n * \n * @example\n * ```typescript\n * // Express middleware\n * import express from \"express\";\n * import { createExpressMiddleware } from \"@safercity/sdk\";\n * \n * const app = express();\n * \n * app.use(\n * \"/api/safercity\",\n * createExpressMiddleware({\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * })\n * );\n * ```\n */\nexport function createExpressMiddleware(config: ProxyConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n const forwardHeaders = config.forwardHeaders ?? [\"content-type\", \"accept\", \"x-request-id\"];\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n \n return async function middleware(\n req: ExpressRequest,\n res: ExpressResponse,\n next: NextFunction\n ): Promise<void> {\n const tokenManager = getTokenManager(config);\n \n try {\n // Get access token\n const token = await tokenManager.getToken();\n \n // Build target URL\n const targetUrl = `${baseUrl}${req.path}${req.url.includes(\"?\") ? req.url.slice(req.url.indexOf(\"?\")) : \"\"}`;\n\n if (!isEndpointAllowed(req.method, req.path, config)) {\n res.status(403).json({\n error: \"endpoint_blocked\",\n message: `Endpoint ${req.method} ${req.path} is not allowed through this proxy`,\n });\n return;\n }\n \n // Build headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n \n // Forward specified headers\n for (const header of forwardHeaders) {\n const value = req.headers[header.toLowerCase()];\n if (value) {\n headers[header] = Array.isArray(value) ? value[0] : value;\n }\n }\n \n // Forward tenant ID header if present\n const tenantIdHeader = req.headers[\"x-tenant-id\"];\n if (tenantIdHeader) {\n headers[\"X-Tenant-ID\"] = Array.isArray(tenantIdHeader) ? tenantIdHeader[0] : tenantIdHeader;\n } else if (config.tenantId) {\n headers[\"X-Tenant-ID\"] = config.tenantId;\n }\n \n // Prepare body\n let body: string | undefined;\n if (req.method !== \"GET\" && req.method !== \"HEAD\" && req.body) {\n body = typeof req.body === \"string\" ? req.body : JSON.stringify(req.body);\n }\n \n // Make proxied request\n const response = await fetchFn(targetUrl, {\n method: req.method,\n headers,\n body,\n });\n \n // Get response body\n const contentType = response.headers.get(\"content-type\");\n const responseBody = contentType?.includes(\"application/json\")\n ? await response.json()\n : await response.text();\n \n // Set response headers\n res.status(response.status);\n res.set({\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, PATCH, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type, Authorization, X-Tenant-ID\",\n \"Content-Type\": contentType ?? \"application/json\",\n });\n \n // Send response\n if (typeof responseBody === \"string\") {\n res.send(responseBody);\n } else {\n res.json(responseBody);\n }\n } catch (error) {\n console.error(\"[SaferCity Proxy] Error:\", error);\n next(error);\n }\n };\n}\n\n/**\n * Create a generic proxy handler that works with any framework\n * Returns a function that takes a request and returns a response\n * \n * @example\n * ```typescript\n * const proxy = createProxyHandler({\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * });\n * \n * // Use with any framework\n * const response = await proxy({\n * method: \"GET\",\n * path: \"/v1/users\",\n * headers: {},\n * });\n * ```\n */\nexport function createProxyHandler(config: ProxyConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n \n return async function proxy(request: {\n method: string;\n path: string;\n headers?: Record<string, string>;\n body?: unknown;\n query?: Record<string, string>;\n }): Promise<{\n status: number;\n headers: Record<string, string>;\n body: unknown;\n }> {\n const tokenManager = getTokenManager(config);\n\n if (!isEndpointAllowed(request.method, request.path, config)) {\n return {\n status: 403,\n headers: {},\n body: {\n error: \"endpoint_blocked\",\n message: `Endpoint ${request.method} ${request.path} is not allowed through this proxy`,\n },\n };\n }\n \n // Get access token\n const token = await tokenManager.getToken();\n \n // Build target URL\n let targetUrl = `${baseUrl}${request.path}`;\n if (request.query && Object.keys(request.query).length > 0) {\n const params = new URLSearchParams(request.query);\n targetUrl += `?${params.toString()}`;\n }\n \n // Build headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n ...request.headers,\n };\n \n // Add tenant ID if configured\n if (config.tenantId) {\n headers[\"X-Tenant-ID\"] = config.tenantId;\n }\n \n // Make request\n const response = await fetchFn(targetUrl, {\n method: request.method,\n headers,\n body: request.body ? JSON.stringify(request.body) : undefined,\n });\n \n // Parse response\n const contentType = response.headers.get(\"content-type\");\n const body = contentType?.includes(\"application/json\")\n ? await response.json()\n : await response.text();\n \n // Extract response headers\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n \n return {\n status: response.status,\n headers: responseHeaders,\n body,\n };\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/server.ts","../src/proxy.ts"],"names":["BaseClient","createStreamAdapter","userId","options","TokenManager"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * SaferCity API Client\n * \n * Client SDK for interacting with the SaferCity multi-tenant API.\n * Provides typed methods for user-scoped endpoints with streaming support.\n * \n * Admin-only operations (tenants, credentials, oauth, user management)\n * are available exclusively through the ServerClient.\n */\n\nimport {\n BaseClient,\n type SaferCityConfig,\n type StreamAdapter,\n createStreamAdapter,\n type ServerSentEvent,\n type EventSourceOptions,\n} from '@safercity/sdk-core';\n\nimport type {\n CreatePanicBody,\n CreatePanicInformationBody,\n GetAuthOptionalResponse,\n GetAuthWhoamiResponse,\n GetHealthResponse,\n GetV1CrimeCategoriesResponse,\n GetV1CrimeTypesResponse,\n GetV1CrimesListResponse,\n GetV1NotificationsPreferencesByUserIdResponse,\n GetV1PanicInformationValidationByUserIdResponse,\n GetV1SubscriptionsResponse,\n GetV1SubscriptionsTypesResponse,\n GetV1UsersByUserIdResponse,\n LocationUpdateResponse,\n PanicCancelledResponse,\n PanicCreatedResponse,\n PanicInformationCreatedResponse,\n PanicInformationResponse,\n PanicResponse,\n PostV1BannerResponse,\n PostV1LocationsSafetyCheckResponse,\n PostV1NotificationsBulkTriggerResponse,\n PostV1NotificationsSubscribersResponse,\n PostV1NotificationsTriggerResponse,\n PostV1SubscriptionsResponse,\n PostV1UsersResponse,\n PutV1NotificationsPreferencesByUserIdResponse,\n PutV1UsersByUserIdResponse,\n UpdatePanicInformationBody,\n UserCreateBody,\n UserUpdateBody,\n UpdatePanicLocationBody,\n CancelPanicBody,\n PostV1SubscriptionsData,\n GetV1SubscriptionsData,\n PostV1NotificationsSubscribersData,\n PostV1NotificationsTriggerData,\n PostV1NotificationsBulkTriggerData,\n PutV1NotificationsPreferencesByUserIdData,\n PostV1LocationsSafetyCheckData,\n PostV1BannerData,\n GetV1CrimesListData,\n GetV1CrimeCategoriesWithTypesResponse,\n DeleteV1PanicInformationByIdResponse,\n\n PostV1PremiumPanicData,\n} from './generated/types.gen';\n\n// ==================\n// Types\n// ==================\n\nexport type PanicInformationRecord = PanicInformationResponse['data'];\n\nexport interface SaferCityClientOptions extends SaferCityConfig {\n /**\n * User ID for user-scoped operations\n */\n userId?: string;\n /**\n * Custom stream adapter for SSE (auto-detected if not provided)\n */\n streamAdapter?: StreamAdapter;\n}\n\n/**\n * Create a SaferCity API client\n * \n * This client exposes user-scoped endpoints only.\n * For admin/server operations, use `createServerClient` instead.\n */\nexport function createSaferCityClient(options: SaferCityClientOptions) {\n const baseClient = new BaseClient(options);\n const streamAdapter = options.streamAdapter ?? createStreamAdapter(options.fetch);\n let userId = options.userId;\n\n const resolveUserId = (explicit?: string): string => {\n const resolved = explicit ?? userId;\n if (!resolved) {\n throw new Error(\n 'userId is required. Either pass it as a parameter or set it on the client via setUserId() or in the provider config.'\n );\n }\n return resolved;\n };\n \n return {\n /**\n * Access the underlying base client for custom requests\n */\n _client: baseClient,\n \n /**\n * Update authentication token\n */\n setToken: (token: string | undefined) => baseClient.setToken(token),\n \n /**\n * Update tenant ID\n */\n setTenantId: (tenantId: string | undefined) => baseClient.setTenantId(tenantId),\n\n /**\n * Update user ID\n */\n setUserId: (nextUserId: string | undefined) => {\n userId = nextUserId;\n },\n\n /**\n * Get current user ID\n */\n getUserId: () => userId,\n \n /**\n * Get current configuration\n */\n getConfig: () => baseClient.getConfig(),\n\n // ==================\n // Health & System\n // ==================\n \n health: {\n /**\n * Check API health status\n */\n check: () => baseClient.get<GetHealthResponse>('/health').then((r) => r.data),\n },\n\n // ==================\n // Authentication\n // ==================\n \n auth: {\n /**\n * Get current authentication context\n */\n whoami: () => baseClient.get<GetAuthWhoamiResponse>('/auth/whoami').then((r) => r.data),\n \n /**\n * Check if authenticated (optional auth)\n */\n check: () => baseClient.get<GetAuthOptionalResponse>('/auth/optional').then((r) => r.data),\n },\n\n // ==================\n // Users (user-scoped)\n // ==================\n \n users: {\n /**\n * Create user (used by tenant apps to register users)\n */\n create: (body: UserCreateBody) =>\n baseClient.post<PostV1UsersResponse>('/v1/users', body).then((r) => r.data),\n \n /**\n * Get user by ID\n */\n get: (userId?: string) =>\n baseClient.get<GetV1UsersByUserIdResponse>(`/v1/users/${resolveUserId(userId)}`).then((r) => r.data),\n \n /**\n * Update user (user can update self)\n */\n update: (userId: string | undefined, body: UserUpdateBody) =>\n baseClient.put<PutV1UsersByUserIdResponse>(`/v1/users/${resolveUserId(userId)}`, body).then((r) => r.data),\n },\n\n // ==================\n // Panics\n // ==================\n \n panics: {\n /**\n * Create panic\n */\n create: async (body: Omit<CreatePanicBody, 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PanicCreatedResponse>('/v1/panic', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Get panic by ID\n */\n get: (panicId: string, query?: { userId?: string }) =>\n baseClient\n .get<PanicResponse>(`/v1/panic/${panicId}`, {\n query: {\n ...query,\n userId: resolveUserId(query?.userId),\n },\n })\n .then((r) => r.data),\n \n /**\n * Update panic location\n */\n updateLocation: async (panicId: string, body: Omit<UpdatePanicLocationBody, 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .put<LocationUpdateResponse>(`/v1/panic/${panicId}/location`, {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Cancel panic\n */\n cancel: async (panicId: string, body: Omit<CancelPanicBody, 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .put<PanicCancelledResponse>(`/v1/panic/${panicId}/cancel`, {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Get available panic types for a user\n */\n types: (userId?: string) =>\n baseClient\n .get<unknown>(`/v1/panic/types/${resolveUserId(userId)}`)\n .then((r) => r.data),\n \n /**\n * Create a premium panic with CellFind provider\n */\n createPremium: async (body: Omit<PostV1PremiumPanicData['body'], 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PanicCreatedResponse>('/v1/premium_panic', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n\n /**\n * Check panic eligibility for a user.\n * Validates subscription status and panic profile completeness.\n */\n eligibility: (userId?: string) =>\n baseClient\n .get<GetV1PanicInformationValidationByUserIdResponse>(\n `/v1/panic-information/validation/${resolveUserId(userId)}`\n )\n .then((r) => r.data),\n\n /**\n * Stream panic updates (SSE)\n */\n streamUpdates: (\n panicId: string,\n options?: EventSourceOptions\n ): AsyncIterable<ServerSentEvent> => {\n const config = baseClient.getConfig();\n const url = `${config.baseUrl}/v1/panic/${panicId}/stream`;\n \n return streamAdapter.createEventSource(url, {\n ...options,\n headers: {\n ...options?.headers,\n ...(config.token ? { Authorization: `Bearer ${config.token}` } : {}),\n },\n });\n },\n },\n\n // ==================\n // Panic Information\n // ==================\n \n panicInformation: {\n /**\n * Create panic information profile\n */\n create: async (body: Omit<CreatePanicInformationBody, 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PanicInformationCreatedResponse>('/v1/panic-information', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n\n /**\n * Get panic information by ID\n */\n get: (id: string) =>\n baseClient.get<PanicInformationResponse>(`/v1/panic-information/${id}`).then((r) => r.data),\n\n /**\n * Get panic information by user ID\n */\n getByUser: (userId?: string) =>\n baseClient\n .get<PanicInformationResponse>(`/v1/panic-information/user/${resolveUserId(userId)}`)\n .then((r) => r.data),\n\n /**\n * Update panic information\n */\n update: (id: string, body: UpdatePanicInformationBody) =>\n baseClient\n .put<PanicInformationCreatedResponse>(`/v1/panic-information/${id}`, body)\n .then((r) => r.data),\n\n /**\n * Delete panic information\n */\n delete: (id: string) =>\n baseClient\n .delete<DeleteV1PanicInformationByIdResponse>(`/v1/panic-information/${id}`)\n .then((r) => r.data),\n\n /**\n * Validate user eligibility for panic services\n */\n validateEligibility: (userId?: string) =>\n baseClient\n .get<GetV1PanicInformationValidationByUserIdResponse>(\n `/v1/panic-information/validation/${resolveUserId(userId)}`\n )\n .then((r) => r.data),\n },\n\n // ==================\n // Subscriptions\n // ==================\n \n subscriptions: {\n /**\n * List subscription types\n */\n listTypes: () =>\n baseClient.get<GetV1SubscriptionsTypesResponse>('/v1/subscriptions/types').then((r) => r.data),\n \n /**\n * Create subscription (subscribe user with premium flag)\n */\n create: async (body: Omit<PostV1SubscriptionsData['body'], 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PostV1SubscriptionsResponse>('/v1/subscriptions', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * List subscriptions\n */\n list: async (query?: NonNullable<GetV1SubscriptionsData['query']> & { userId?: string }) => {\n const response = await baseClient\n .get<GetV1SubscriptionsResponse>('/v1/subscriptions', {\n query: {\n ...query,\n userId: resolveUserId(query?.userId),\n },\n })\n .then((r) => r.data);\n return response;\n },\n\n },\n\n // ==================\n // Notifications\n // ==================\n \n notifications: {\n /**\n * Create subscriber\n */\n createSubscriber: async (body: Omit<PostV1NotificationsSubscribersData['body'], 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PostV1NotificationsSubscribersResponse>('/v1/notifications/subscribers', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Trigger notification\n */\n trigger: async (body: Omit<PostV1NotificationsTriggerData['body'], 'userId'> & { userId?: string }) => {\n const response = await baseClient\n .post<PostV1NotificationsTriggerResponse>('/v1/notifications/trigger', {\n ...body,\n userId: resolveUserId(body.userId),\n })\n .then((r) => r.data);\n return response;\n },\n \n /**\n * Bulk trigger notifications\n */\n bulkTrigger: (body: PostV1NotificationsBulkTriggerData['body']) =>\n baseClient\n .post<PostV1NotificationsBulkTriggerResponse>(\n '/v1/notifications/bulk-trigger',\n body\n )\n .then((r) => r.data),\n \n /**\n * Get user preferences\n */\n getPreferences: (userId?: string) =>\n baseClient\n .get<GetV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${resolveUserId(userId)}`\n )\n .then((r) => r.data),\n \n /**\n * Update user preferences\n */\n updatePreferences: (userId: string | undefined, body: PutV1NotificationsPreferencesByUserIdData['body']) =>\n baseClient\n .put<PutV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${resolveUserId(userId)}`,\n body\n )\n .then((r) => r.data),\n },\n\n // ==================\n // Location Safety\n // ==================\n \n locationSafety: {\n /**\n * Check location safety\n */\n check: (body: PostV1LocationsSafetyCheckData['body']) =>\n baseClient\n .post<PostV1LocationsSafetyCheckResponse>('/v1/locations/safety-check', body)\n .then((r) => r.data),\n },\n\n // ==================\n // Banner\n // ==================\n \n banner: {\n /**\n * Get crime banner data for a location\n */\n get: (body: PostV1BannerData['body']) =>\n baseClient.post<PostV1BannerResponse>('/v1/banner', body).then((r) => r.data),\n },\n\n // ==================\n // Crimes\n // ==================\n \n crimes: {\n /**\n * List crimes\n */\n list: (query?: GetV1CrimesListData['query']) => baseClient.get<GetV1CrimesListResponse>('/v1/crimes/list', { query }).then((r) => r.data),\n \n /**\n * Get crime categories\n */\n categories: () =>\n baseClient.get<GetV1CrimeCategoriesResponse>('/v1/crime-categories').then((r) => r.data),\n \n /**\n * Get crime types\n */\n types: () =>\n baseClient.get<GetV1CrimeTypesResponse>('/v1/crime-types').then((r) => r.data),\n\n /**\n * Get crime categories with their types\n */\n categoriesWithTypes: () =>\n baseClient\n .get<GetV1CrimeCategoriesWithTypesResponse>('/v1/crime-categories/withTypes')\n .then((r) => r.data),\n },\n };\n}\n\nexport type SaferCityClient = ReturnType<typeof createSaferCityClient>;\n","/**\n * Server-side SaferCity Client\n * \n * For backend applications that need to authenticate with OAuth client credentials.\n * Handles automatic token management and refresh.\n */\n\nimport {\n TokenManager,\n type OAuthCredentials,\n type TokenStorage,\n BaseClient,\n type SaferCityConfig,\n} from '@safercity/sdk-core';\n\nimport type {\n CancelPanicBody,\n CreatePanicBody,\n CreatePanicInformationBody,\n DeleteV1PanicInformationByIdResponse,\n GetAuthOptionalResponse,\n GetAuthWhoamiResponse,\n GetHealthResponse,\n GetV1CrimeCategoriesResponse,\n GetV1CrimeCategoriesWithTypesResponse,\n GetV1CrimeTypesResponse,\n GetV1CrimesListData,\n GetV1CrimesListResponse,\n GetV1NotificationsPreferencesByUserIdResponse,\n GetV1PanicData,\n GetV1PanicInformationData,\n GetV1PanicInformationValidationByUserIdResponse,\n GetV1SubscriptionsData,\n GetV1SubscriptionsResponse,\n GetV1SubscriptionsTypesResponse,\n GetV1SubscriptionsUserByUserIdResponse,\n GetV1UsersByUserIdResponse,\n GetV1UsersData,\n GetV1UsersResponse,\n LocationUpdateResponse,\n OAuthIntrospectBody,\n OAuthRevokeBody,\n OAuthTokenRequestBody,\n PanicCancelledResponse,\n PanicCreatedResponse,\n PanicInformationCreatedResponse,\n PanicInformationListResponse,\n PanicInformationResponse,\n PanicListResponse,\n PanicResponse,\n PatchV1SubscriptionsBySubscriptionIdData,\n PatchV1SubscriptionsBySubscriptionIdResponse,\n PostV1BannerData,\n PostV1BannerResponse,\n PostV1LocationsSafetyCheckData,\n PostV1LocationsSafetyCheckResponse,\n PostV1NotificationsBulkTriggerData,\n PostV1NotificationsBulkTriggerResponse,\n PostV1NotificationsSubscribersData,\n PostV1NotificationsSubscribersResponse,\n PostV1NotificationsTriggerData,\n PostV1NotificationsTriggerResponse,\n PostV1OauthIntrospectResponse,\n PostV1OauthRevokeResponse,\n PostV1OauthTokenResponse,\n PostV1PremiumPanicData,\n PostV1SubscriptionsData,\n PostV1SubscriptionsResponse,\n PostV1TenantsResponse,\n PostV1UsersResponse,\n PutV1NotificationsPreferencesByUserIdData,\n PutV1NotificationsPreferencesByUserIdResponse,\n PutV1SubscriptionsBySubscriptionIdSwitchData,\n PutV1SubscriptionsBySubscriptionIdSwitchResponse,\n PutV1UsersByUserIdResponse,\n TenantCreateBody,\n UpdatePanicInformationBody,\n UpdatePanicLocationBody,\n UserCreateBody,\n UserUpdateBody,\n} from './generated/types.gen';\n\nexport interface ServerClientConfig\n extends Pick<SaferCityConfig, 'baseUrl' | 'timeout' | 'fetch'> {\n /**\n * OAuth credentials for authentication\n */\n auth: OAuthCredentials;\n\n /**\n * Custom token storage (defaults to in-memory)\n */\n tokenStore?: TokenStorage;\n}\n\n/**\n * Server client that wraps the base client with automatic OAuth token management\n */\nexport class ServerClient extends BaseClient {\n private tokenManager: TokenManager;\n\n constructor(config: ServerClientConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n \n super({\n baseUrl,\n ...(config.timeout != null && { timeout: config.timeout }),\n ...(config.fetch != null && { fetch: config.fetch }),\n });\n\n this.tokenManager = new TokenManager({\n credentials: config.auth,\n baseUrl,\n storage: config.tokenStore,\n fetch: config.fetch,\n });\n }\n\n /**\n * Get a valid access token\n */\n async getAccessToken(): Promise<string> {\n return this.tokenManager.getToken();\n }\n\n /**\n * Force refresh the token\n */\n async refreshToken(): Promise<string> {\n return this.tokenManager.forceRefresh();\n }\n\n /**\n * Clear stored tokens\n */\n clearTokens(): void {\n this.tokenManager.clear();\n }\n\n /**\n * Make an authenticated request\n * Automatically adds the Authorization header with a valid token\n */\n protected override async request<T>(\n method: string,\n path: string,\n options?: Parameters<BaseClient['request']>[2]\n ): Promise<{ data: T; status: number; headers: Headers }> {\n // Get token and add to headers\n const token = await this.getAccessToken();\n \n const authHeaders = {\n ...options?.headers,\n Authorization: `Bearer ${token}`,\n };\n\n return super.request<T>(method, path, {\n ...options,\n headers: authHeaders,\n });\n }\n\n // ==================\n // Health & System\n // ==================\n\n /**\n * Check API health status\n */\n get health() {\n return {\n check: () => this.get<GetHealthResponse>('/health').then(r => r.data),\n };\n }\n\n // ==================\n // Authentication\n // ==================\n\n /**\n * Authentication helpers\n */\n get auth() {\n return {\n /**\n * Get current authentication context\n */\n whoami: () => this.get<GetAuthWhoamiResponse>('/auth/whoami').then(r => r.data),\n\n /**\n * Check if authenticated (optional auth)\n */\n check: () => this.get<GetAuthOptionalResponse>('/auth/optional').then(r => r.data),\n };\n }\n\n // ==================\n // OAuth\n // ==================\n\n /**\n * OAuth helpers\n */\n get oauth() {\n return {\n /**\n * Get access token\n */\n token: (body: OAuthTokenRequestBody) => this.post<PostV1OauthTokenResponse>('/v1/oauth/token', body).then(r => r.data),\n\n /**\n * Refresh access token\n */\n refresh: (body: { refresh_token: string }) =>\n this.post<PostV1OauthTokenResponse>('/v1/oauth/refresh', body).then(r => r.data),\n\n /**\n * Introspect token\n */\n introspect: (body: OAuthIntrospectBody) =>\n this.post<PostV1OauthIntrospectResponse>('/v1/oauth/introspect', body).then(r => r.data),\n\n /**\n * Revoke token\n */\n revoke: (body: OAuthRevokeBody) =>\n this.post<PostV1OauthRevokeResponse>('/v1/oauth/revoke', body).then(r => r.data),\n };\n }\n\n // ==================\n // Tenants\n // ==================\n\n /**\n * Tenant helpers\n */\n get tenants() {\n return {\n /**\n * Create a new tenant\n */\n create: (body: TenantCreateBody) =>\n this.post<PostV1TenantsResponse>('/v1/tenants', body).then(r => r.data),\n\n /**\n * List tenants (admin)\n */\n list: (query?: { limit?: number; cursor?: string }) =>\n this.get<{\n tenants: Array<{ id: string; name: string }>;\n hasNext: boolean;\n cursor?: string;\n }>('/v1/tenants', { query }).then(r => r.data),\n };\n }\n\n // ==================\n // Credentials\n // ==================\n\n /**\n * Credential helpers\n */\n get credentials() {\n return {\n /**\n * Exchange setup token for credentials\n */\n setup: (body: { setupToken: string }) =>\n this.post<{\n clientId: string;\n clientSecret: string;\n tenantId: string;\n }>('/v1/credentials', body).then(r => r.data),\n\n /**\n * List credentials\n */\n list: () =>\n this.get<{\n credentials: Array<{\n id: string;\n clientId: string;\n createdAt: string;\n lastUsed?: string;\n }>;\n }>('/v1/credentials').then(r => r.data),\n\n /**\n * Revoke credential\n */\n revoke: (credentialId: string) =>\n this.delete<{ success: boolean }>(`/v1/credentials/${credentialId}`).then(r => r.data),\n };\n }\n\n // ==================\n // Users\n // ==================\n\n /**\n * User helpers\n */\n get users() {\n return {\n /**\n * Create user\n */\n create: (body: UserCreateBody) =>\n this.post<PostV1UsersResponse>('/v1/users', body).then(r => r.data),\n\n /**\n * List users\n */\n list: (query?: GetV1UsersData['query']) =>\n this.get<GetV1UsersResponse>('/v1/users', { query }).then(r => r.data),\n\n /**\n * Get user by ID\n */\n get: (userId: string) =>\n this.get<GetV1UsersByUserIdResponse>(`/v1/users/${userId}`).then(r => r.data),\n\n /**\n * Update user\n */\n update: (userId: string, body: UserUpdateBody) =>\n this.put<PutV1UsersByUserIdResponse>(`/v1/users/${userId}`, body).then(r => r.data),\n\n /**\n * Update user status\n */\n updateStatus: (userId: string, body: { status: string }) =>\n this.patch<{ id: string; status: string }>(`/v1/users/${userId}/status`, body).then(r => r.data),\n\n /**\n * Delete user\n */\n delete: (userId: string) =>\n this.delete<{ success: boolean }>(`/v1/users/${userId}`).then(r => r.data),\n };\n }\n\n // ==================\n // Panics\n // ==================\n\n /**\n * Panic helpers (streaming not available in server client)\n */\n get panics() {\n return {\n /**\n * Create panic\n */\n create: (body: CreatePanicBody) =>\n this.post<PanicCreatedResponse>('/v1/panic', body).then(r => r.data),\n\n /**\n * Get panic by ID\n */\n get: (panicId: string, query?: { userId?: string }) =>\n this.get<PanicResponse>(`/v1/panic/${panicId}`, { query }).then(r => r.data),\n\n /**\n * List panics\n */\n list: (query?: GetV1PanicData['query']) => this.get<PanicListResponse>('/v1/panic', { query }).then(r => r.data),\n\n /**\n * Update panic location\n */\n updateLocation: (panicId: string, body: UpdatePanicLocationBody) => this.put<LocationUpdateResponse>(`/v1/panic/${panicId}/location`, body).then(r => r.data),\n\n /**\n * Cancel panic\n */\n cancel: (panicId: string, body: CancelPanicBody) => this.put<PanicCancelledResponse>(`/v1/panic/${panicId}/cancel`, body).then(r => r.data),\n\n /**\n * Get available panic types for a user\n */\n types: (userId: string) =>\n this.get<{\n types: Array<{ id: string; name: string; description?: string }>;\n }>(`/v1/panic/types/${userId}`).then(r => r.data),\n\n /**\n * Create a premium panic with CellFind provider\n */\n createPremium: (body: PostV1PremiumPanicData['body']) =>\n this.post<PanicCreatedResponse>('/v1/premium_panic', body).then(r => r.data),\n };\n }\n\n // ==================\n // Subscriptions\n // ==================\n\n /**\n * Subscription helpers\n */\n get subscriptions() {\n return {\n /**\n * List subscription types\n */\n listTypes: () =>\n this.get<GetV1SubscriptionsTypesResponse>('/v1/subscriptions/types').then(r => r.data),\n\n /**\n * Create subscription (subscribe user with premium flag)\n */\n create: (body: PostV1SubscriptionsData['body']) => this.post<PostV1SubscriptionsResponse>('/v1/subscriptions', body).then(r => r.data),\n\n /**\n * List subscriptions\n */\n list: (query?: GetV1SubscriptionsData['query']) => this.get<GetV1SubscriptionsResponse>('/v1/subscriptions', { query }).then(r => r.data),\n\n /**\n * Get subscriptions for a specific user\n */\n getByUser: (userId: string) =>\n this.get<GetV1SubscriptionsUserByUserIdResponse>(`/v1/subscriptions/user/${userId}`).then(r => r.data),\n\n /**\n * Update subscription fields (endDate, notes)\n */\n update: (subscriptionId: string, body: PatchV1SubscriptionsBySubscriptionIdData['body']) => this.patch<PatchV1SubscriptionsBySubscriptionIdResponse>(`/v1/subscriptions/${subscriptionId}`, body).then(r => r.data),\n\n /**\n * Switch subscription plan (upgrade/downgrade)\n */\n switch: (subscriptionId: string, body: PutV1SubscriptionsBySubscriptionIdSwitchData['body']) => this.put<PutV1SubscriptionsBySubscriptionIdSwitchResponse>(`/v1/subscriptions/${subscriptionId}/switch`, body).then(r => r.data),\n };\n }\n\n // ==================\n // Notifications\n // ==================\n\n /**\n * Notification helpers\n */\n get notifications() {\n return {\n /**\n * Create subscriber\n */\n createSubscriber: (body: PostV1NotificationsSubscribersData['body']) => this.post<PostV1NotificationsSubscribersResponse>('/v1/notifications/subscribers', body).then(r => r.data),\n\n /**\n * Trigger notification\n */\n trigger: (body: PostV1NotificationsTriggerData['body']) => this.post<PostV1NotificationsTriggerResponse>('/v1/notifications/trigger', body).then(r => r.data),\n\n /**\n * Bulk trigger notifications\n */\n bulkTrigger: (body: PostV1NotificationsBulkTriggerData['body']) => this.post<PostV1NotificationsBulkTriggerResponse>('/v1/notifications/bulk-trigger', body).then(r => r.data),\n\n /**\n * Get user preferences\n */\n getPreferences: (userId: string) =>\n this.get<GetV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${userId}`\n ).then(r => r.data),\n\n /**\n * Update user preferences\n */\n updatePreferences: (userId: string, body: PutV1NotificationsPreferencesByUserIdData['body']) => this.put<PutV1NotificationsPreferencesByUserIdResponse>(\n `/v1/notifications/preferences/${userId}`,\n body\n ).then(r => r.data),\n };\n }\n\n // ==================\n // Panic Information\n // ==================\n\n /**\n * Panic information helpers\n */\n get panicInformation() {\n return {\n /**\n * Create panic information profile\n */\n create: (body: CreatePanicInformationBody) =>\n this.post<PanicInformationCreatedResponse>('/v1/panic-information', body).then(r => r.data),\n\n /**\n * List panic information records\n */\n list: (query?: GetV1PanicInformationData['query']) =>\n this.get<PanicInformationListResponse>('/v1/panic-information', { query }).then(r => r.data),\n\n /**\n * Get panic information by ID\n */\n get: (id: string) => this.get<PanicInformationResponse>(`/v1/panic-information/${id}`).then(r => r.data),\n\n /**\n * Get panic information by user ID\n */\n getByUser: (userId: string) =>\n this.get<PanicInformationResponse>(`/v1/panic-information/user/${userId}`).then(r => r.data),\n\n /**\n * Update panic information\n */\n update: (id: string, body: UpdatePanicInformationBody) =>\n this.put<PanicInformationCreatedResponse>(`/v1/panic-information/${id}`, body).then(r => r.data),\n\n /**\n * Delete panic information\n */\n delete: (id: string) => this.delete<DeleteV1PanicInformationByIdResponse>(`/v1/panic-information/${id}`).then(r => r.data),\n\n /**\n * Validate user eligibility for panic services\n */\n validateEligibility: (userId: string) =>\n this.get<GetV1PanicInformationValidationByUserIdResponse>(\n `/v1/panic-information/validation/${userId}`\n ).then(r => r.data),\n };\n }\n\n // ==================\n // Location Safety\n // ==================\n\n /**\n * Location safety helpers\n */\n get locationSafety() {\n return {\n /**\n * Check location safety\n */\n check: (body: PostV1LocationsSafetyCheckData['body']) =>\n this.post<PostV1LocationsSafetyCheckResponse>('/v1/locations/safety-check', body).then(r => r.data),\n };\n }\n\n // ==================\n // Banner\n // ==================\n\n /**\n * Banner helpers\n */\n get banner() {\n return {\n /**\n * Get crime banner data for a location\n */\n get: (body: PostV1BannerData['body']) =>\n this.post<PostV1BannerResponse>('/v1/banner', body).then(r => r.data),\n };\n }\n\n // ==================\n // Crimes\n // ==================\n\n /**\n * Crime helpers\n */\n get crimes() {\n return {\n /**\n * List crimes\n */\n list: (query?: GetV1CrimesListData['query']) => this.get<GetV1CrimesListResponse>('/v1/crimes/list', { query }).then(r => r.data),\n\n /**\n * Get crime categories\n */\n categories: () => this.get<GetV1CrimeCategoriesResponse>('/v1/crime-categories').then(r => r.data),\n\n /**\n * Get crime types\n */\n types: () => this.get<GetV1CrimeTypesResponse>('/v1/crime-types').then(r => r.data),\n\n /**\n * Get crime categories with their types\n */\n categoriesWithTypes: () =>\n this.get<GetV1CrimeCategoriesWithTypesResponse>('/v1/crime-categories/withTypes').then(r => r.data),\n };\n }\n}\n\n/**\n * Create a server-side SaferCity client with automatic OAuth token management\n * \n * @example\n * ```typescript\n * const client = createServerClient({\n * auth: {\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * },\n * });\n * \n * // All requests are automatically authenticated\n * const users = await client.get('/v1/users');\n * ```\n */\nexport function createServerClient(config: ServerClientConfig): ServerClient {\n return new ServerClient(config);\n}\n\nexport type { OAuthCredentials, TokenStorage };\n","/**\n * Proxy Middleware Helpers\n * \n * Helpers for creating proxy endpoints that forward requests to SaferCity API\n * with automatic tenant authentication.\n */\n\nimport { TokenManager, type TokenStorage } from '@safercity/sdk-core';\n\nexport type EndpointPattern = string | { method?: string; path: string };\n\nexport interface ProxyConfig {\n /**\n * OAuth client ID\n */\n clientId: string;\n \n /**\n * OAuth client secret\n */\n clientSecret: string;\n \n /**\n * SaferCity API base URL\n * @default \"https://api.safercity.com\"\n */\n baseUrl?: string;\n \n /**\n * Tenant ID (optional, can be extracted from request)\n */\n tenantId?: string;\n \n /**\n * Custom token storage\n */\n tokenStore?: TokenStorage;\n \n /**\n * Path prefix to strip from incoming requests\n * @default \"/api/safercity\"\n */\n pathPrefix?: string;\n \n /**\n * Headers to forward from the original request\n * @default [\"content-type\", \"accept\", \"x-request-id\"]\n */\n forwardHeaders?: string[];\n \n /**\n * Custom fetch implementation\n */\n fetch?: typeof fetch;\n\n /**\n * Explicitly allowed endpoints for proxy forwarding\n */\n allowedEndpoints?: EndpointPattern[];\n\n /**\n * Explicitly blocked endpoints for proxy forwarding\n */\n blockedEndpoints?: EndpointPattern[];\n}\n\n// Singleton token manager to share across requests\nconst tokenManagers = new Map<string, TokenManager>();\n\nfunction getTokenManager(config: ProxyConfig): TokenManager {\n const key = `${config.clientId}:${config.baseUrl ?? \"default\"}`;\n \n let manager = tokenManagers.get(key);\n if (!manager) {\n manager = new TokenManager({\n credentials: {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n tenantId: config.tenantId,\n },\n baseUrl: config.baseUrl ?? \"https://api.safercity.com\",\n storage: config.tokenStore,\n fetch: config.fetch,\n });\n tokenManagers.set(key, manager);\n }\n \n return manager;\n}\n\nfunction isPathPrefixMatch(path: string, pattern: string): boolean {\n const normalizedPath = path.toLowerCase();\n const normalizedPattern = pattern.toLowerCase();\n\n if (normalizedPattern.length === 0) {\n return normalizedPath.length === 0;\n }\n\n return normalizedPath.startsWith(normalizedPattern);\n}\n\nfunction matchesEndpointPattern(method: string, path: string, pattern: EndpointPattern): boolean {\n if (typeof pattern === \"string\") {\n return isPathPrefixMatch(path, pattern);\n }\n\n const methodMatches = pattern.method\n ? pattern.method.toUpperCase() === method.toUpperCase()\n : true;\n\n return methodMatches && isPathPrefixMatch(path, pattern.path);\n}\n\nexport function isEndpointAllowed(method: string, path: string, config: ProxyConfig): boolean {\n const hasAllowlist = Array.isArray(config.allowedEndpoints);\n const hasBlocklist = Array.isArray(config.blockedEndpoints);\n\n if (!hasAllowlist && !hasBlocklist) {\n return true;\n }\n\n if (hasAllowlist) {\n return (config.allowedEndpoints ?? []).some((pattern) =>\n matchesEndpointPattern(method, path, pattern)\n );\n }\n\n return !(config.blockedEndpoints ?? []).some((pattern) =>\n matchesEndpointPattern(method, path, pattern)\n );\n}\n\n/**\n * Create a Next.js App Router handler for proxying SaferCity API requests\n * \n * @example\n * ```typescript\n * // app/api/safercity/[...path]/route.ts\n * import { createNextHandler } from \"@safercity/sdk\";\n * \n * const handler = createNextHandler({\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * });\n * \n * export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH };\n * ```\n */\nexport function createNextHandler(config: ProxyConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n const pathPrefix = config.pathPrefix ?? \"/api/safercity\";\n const forwardHeaders = config.forwardHeaders ?? [\"content-type\", \"accept\", \"x-request-id\"];\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n \n return async function handler(request: Request): Promise<Response> {\n const tokenManager = getTokenManager(config);\n \n try {\n // Get access token\n const token = await tokenManager.getToken();\n \n // Build target URL\n const url = new URL(request.url);\n const path = url.pathname.replace(new RegExp(`^${pathPrefix}`), \"\");\n const targetUrl = `${baseUrl}${path}${url.search}`;\n\n if (!isEndpointAllowed(request.method, path, config)) {\n return new Response(\n JSON.stringify({\n error: \"endpoint_blocked\",\n message: `Endpoint ${request.method} ${path} is not allowed through this proxy`,\n }),\n {\n status: 403,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n }\n \n // Build headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n \n // Forward specified headers\n for (const header of forwardHeaders) {\n const value = request.headers.get(header);\n if (value) {\n headers[header] = value;\n }\n }\n \n // Forward tenant ID header if present\n const tenantIdHeader = request.headers.get(\"x-tenant-id\");\n if (tenantIdHeader) {\n headers[\"X-Tenant-ID\"] = tenantIdHeader;\n } else if (config.tenantId) {\n headers[\"X-Tenant-ID\"] = config.tenantId;\n }\n \n // Forward request body for non-GET requests\n let body: BodyInit | undefined;\n if (request.method !== \"GET\" && request.method !== \"HEAD\") {\n body = await request.text();\n }\n \n // Make proxied request\n const response = await fetchFn(targetUrl, {\n method: request.method,\n headers,\n body,\n });\n \n // Return response with CORS headers\n const responseHeaders = new Headers(response.headers);\n responseHeaders.set(\"Access-Control-Allow-Origin\", \"*\");\n responseHeaders.set(\"Access-Control-Allow-Methods\", \"GET, POST, PUT, DELETE, PATCH, OPTIONS\");\n responseHeaders.set(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization, X-Tenant-ID\");\n \n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n });\n } catch (error) {\n console.error(\"[SaferCity Proxy] Error:\", error);\n \n return new Response(\n JSON.stringify({\n error: \"proxy_error\",\n message: error instanceof Error ? error.message : \"Proxy request failed\",\n }),\n {\n status: 502,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }\n );\n }\n };\n}\n\n/**\n * Express/Node.js compatible request type\n */\ninterface ExpressRequest {\n method: string;\n path: string;\n url: string;\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n query?: Record<string, string>;\n}\n\n/**\n * Express/Node.js compatible response type\n */\ninterface ExpressResponse {\n status(code: number): ExpressResponse;\n set(headers: Record<string, string>): ExpressResponse;\n json(data: unknown): void;\n send(data: string | ArrayBuffer | Uint8Array): void;\n}\n\n/**\n * Express next function type\n */\ntype NextFunction = (error?: unknown) => void;\n\n/**\n * Create an Express middleware for proxying SaferCity API requests\n * \n * @example\n * ```typescript\n * // Express middleware\n * import express from \"express\";\n * import { createExpressMiddleware } from \"@safercity/sdk\";\n * \n * const app = express();\n * \n * app.use(\n * \"/api/safercity\",\n * createExpressMiddleware({\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * })\n * );\n * ```\n */\nexport function createExpressMiddleware(config: ProxyConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n const forwardHeaders = config.forwardHeaders ?? [\"content-type\", \"accept\", \"x-request-id\"];\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n \n return async function middleware(\n req: ExpressRequest,\n res: ExpressResponse,\n next: NextFunction\n ): Promise<void> {\n const tokenManager = getTokenManager(config);\n \n try {\n // Get access token\n const token = await tokenManager.getToken();\n \n // Build target URL\n const targetUrl = `${baseUrl}${req.path}${req.url.includes(\"?\") ? req.url.slice(req.url.indexOf(\"?\")) : \"\"}`;\n\n if (!isEndpointAllowed(req.method, req.path, config)) {\n res.status(403).json({\n error: \"endpoint_blocked\",\n message: `Endpoint ${req.method} ${req.path} is not allowed through this proxy`,\n });\n return;\n }\n \n // Build headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n \n // Forward specified headers\n for (const header of forwardHeaders) {\n const value = req.headers[header.toLowerCase()];\n if (value) {\n headers[header] = Array.isArray(value) ? value[0] : value;\n }\n }\n \n // Forward tenant ID header if present\n const tenantIdHeader = req.headers[\"x-tenant-id\"];\n if (tenantIdHeader) {\n headers[\"X-Tenant-ID\"] = Array.isArray(tenantIdHeader) ? tenantIdHeader[0] : tenantIdHeader;\n } else if (config.tenantId) {\n headers[\"X-Tenant-ID\"] = config.tenantId;\n }\n \n // Prepare body\n let body: string | undefined;\n if (req.method !== \"GET\" && req.method !== \"HEAD\" && req.body) {\n body = typeof req.body === \"string\" ? req.body : JSON.stringify(req.body);\n }\n \n // Make proxied request\n const response = await fetchFn(targetUrl, {\n method: req.method,\n headers,\n body,\n });\n \n // Get response body\n const contentType = response.headers.get(\"content-type\");\n const responseBody = contentType?.includes(\"application/json\")\n ? await response.json()\n : await response.text();\n \n // Set response headers\n res.status(response.status);\n res.set({\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, PATCH, OPTIONS\",\n \"Access-Control-Allow-Headers\": \"Content-Type, Authorization, X-Tenant-ID\",\n \"Content-Type\": contentType ?? \"application/json\",\n });\n \n // Send response\n if (typeof responseBody === \"string\") {\n res.send(responseBody);\n } else {\n res.json(responseBody);\n }\n } catch (error) {\n console.error(\"[SaferCity Proxy] Error:\", error);\n next(error);\n }\n };\n}\n\n/**\n * Create a generic proxy handler that works with any framework\n * Returns a function that takes a request and returns a response\n * \n * @example\n * ```typescript\n * const proxy = createProxyHandler({\n * clientId: process.env.SAFERCITY_CLIENT_ID!,\n * clientSecret: process.env.SAFERCITY_CLIENT_SECRET!,\n * });\n * \n * // Use with any framework\n * const response = await proxy({\n * method: \"GET\",\n * path: \"/v1/users\",\n * headers: {},\n * });\n * ```\n */\nexport function createProxyHandler(config: ProxyConfig) {\n const baseUrl = config.baseUrl ?? \"https://api.safercity.com\";\n const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n \n return async function proxy(request: {\n method: string;\n path: string;\n headers?: Record<string, string>;\n body?: unknown;\n query?: Record<string, string>;\n }): Promise<{\n status: number;\n headers: Record<string, string>;\n body: unknown;\n }> {\n const tokenManager = getTokenManager(config);\n\n if (!isEndpointAllowed(request.method, request.path, config)) {\n return {\n status: 403,\n headers: {},\n body: {\n error: \"endpoint_blocked\",\n message: `Endpoint ${request.method} ${request.path} is not allowed through this proxy`,\n },\n };\n }\n \n // Get access token\n const token = await tokenManager.getToken();\n \n // Build target URL\n let targetUrl = `${baseUrl}${request.path}`;\n if (request.query && Object.keys(request.query).length > 0) {\n const params = new URLSearchParams(request.query);\n targetUrl += `?${params.toString()}`;\n }\n \n // Build headers\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n ...request.headers,\n };\n \n // Add tenant ID if configured\n if (config.tenantId) {\n headers[\"X-Tenant-ID\"] = config.tenantId;\n }\n \n // Make request\n const response = await fetchFn(targetUrl, {\n method: request.method,\n headers,\n body: request.body ? JSON.stringify(request.body) : undefined,\n });\n \n // Parse response\n const contentType = response.headers.get(\"content-type\");\n const body = contentType?.includes(\"application/json\")\n ? await response.json()\n : await response.text();\n \n // Extract response headers\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n \n return {\n status: response.status,\n headers: responseHeaders,\n body,\n };\n };\n}\n"]}
|