@safercity/sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,463 @@
1
+ import * as _safercity_sdk_core from '@safercity/sdk-core';
2
+ import { SaferCityConfig, StreamAdapter, BaseClient, EventSourceOptions, ServerSentEvent } from '@safercity/sdk-core';
3
+ export { ApiError, ApiResponse, AuthTokens, EventSourceOptions, FetchStreamAdapter, MemoryTokenStorage, RequestOptions, SaferCityApiError, SaferCityConfig, SaferCityJwtPayload, ServerSentEvent, StreamAdapter, TokenStorage, WebStreamAdapter, createAuthHeader, createStreamAdapter, getJwtExpiration, isTokenExpired, parseJwtPayload } from '@safercity/sdk-core';
4
+
5
+ interface SaferCityClientOptions extends SaferCityConfig {
6
+ /**
7
+ * Custom stream adapter for SSE (auto-detected if not provided)
8
+ */
9
+ streamAdapter?: StreamAdapter;
10
+ }
11
+ /**
12
+ * Create a SaferCity API client
13
+ */
14
+ declare function createSaferCityClient(options: SaferCityClientOptions): {
15
+ /**
16
+ * Access the underlying base client for custom requests
17
+ */
18
+ _client: BaseClient;
19
+ /**
20
+ * Update authentication token
21
+ */
22
+ setToken: (token: string | undefined) => void;
23
+ /**
24
+ * Update tenant ID
25
+ */
26
+ setTenantId: (tenantId: string | undefined) => void;
27
+ /**
28
+ * Get current configuration
29
+ */
30
+ getConfig: () => Readonly<SaferCityConfig>;
31
+ health: {
32
+ /**
33
+ * Check API health status
34
+ */
35
+ check: () => Promise<_safercity_sdk_core.ApiResponse<{
36
+ status: string;
37
+ timestamp: string;
38
+ panicProviders?: {
39
+ healthy: boolean;
40
+ stats?: unknown;
41
+ providers?: unknown;
42
+ };
43
+ }>>;
44
+ };
45
+ auth: {
46
+ /**
47
+ * Get current authentication context
48
+ */
49
+ whoami: () => Promise<_safercity_sdk_core.ApiResponse<{
50
+ tenantId: string | null;
51
+ environment: string;
52
+ scopes: string[];
53
+ sessionId: string;
54
+ }>>;
55
+ /**
56
+ * Check if authenticated (optional auth)
57
+ */
58
+ check: () => Promise<_safercity_sdk_core.ApiResponse<{
59
+ authenticated: boolean;
60
+ tenantId: string | null;
61
+ }>>;
62
+ };
63
+ oauth: {
64
+ /**
65
+ * Get access token
66
+ */
67
+ token: (body: {
68
+ grant_type: "client_credentials" | "refresh_token";
69
+ tenantId?: string;
70
+ userId?: string;
71
+ refresh_token?: string;
72
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
73
+ access_token: string;
74
+ token_type: string;
75
+ expires_in: number;
76
+ refresh_token?: string;
77
+ }>>;
78
+ /**
79
+ * Refresh access token
80
+ */
81
+ refresh: (body: {
82
+ refresh_token: string;
83
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
84
+ access_token: string;
85
+ token_type: string;
86
+ expires_in: number;
87
+ refresh_token?: string;
88
+ }>>;
89
+ /**
90
+ * Introspect token
91
+ */
92
+ introspect: (body: {
93
+ token: string;
94
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
95
+ active: boolean;
96
+ tenantId?: string;
97
+ sub?: string;
98
+ scope?: string;
99
+ exp?: number;
100
+ }>>;
101
+ /**
102
+ * Revoke token
103
+ */
104
+ revoke: (body: {
105
+ token: string;
106
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
107
+ success: boolean;
108
+ }>>;
109
+ };
110
+ tenants: {
111
+ /**
112
+ * Create a new tenant
113
+ */
114
+ create: (body: {
115
+ name: string;
116
+ domain?: string;
117
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
118
+ tenantId: string;
119
+ name: string;
120
+ setupToken: string;
121
+ }>>;
122
+ /**
123
+ * List tenants (admin)
124
+ */
125
+ list: (query?: {
126
+ limit?: number;
127
+ cursor?: string;
128
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
129
+ tenants: Array<{
130
+ id: string;
131
+ name: string;
132
+ }>;
133
+ hasNext: boolean;
134
+ cursor?: string;
135
+ }>>;
136
+ };
137
+ credentials: {
138
+ /**
139
+ * Exchange setup token for credentials
140
+ */
141
+ setup: (body: {
142
+ setupToken: string;
143
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
144
+ clientId: string;
145
+ clientSecret: string;
146
+ tenantId: string;
147
+ }>>;
148
+ /**
149
+ * List credentials
150
+ */
151
+ list: () => Promise<_safercity_sdk_core.ApiResponse<{
152
+ credentials: Array<{
153
+ id: string;
154
+ clientId: string;
155
+ createdAt: string;
156
+ lastUsed?: string;
157
+ }>;
158
+ }>>;
159
+ /**
160
+ * Revoke credential
161
+ */
162
+ revoke: (credentialId: string) => Promise<_safercity_sdk_core.ApiResponse<{
163
+ success: boolean;
164
+ }>>;
165
+ };
166
+ users: {
167
+ /**
168
+ * Create user
169
+ */
170
+ create: (body: {
171
+ email?: string;
172
+ phone?: string;
173
+ firstName?: string;
174
+ lastName?: string;
175
+ metadata?: Record<string, unknown>;
176
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
177
+ id: string;
178
+ email?: string;
179
+ phone?: string;
180
+ }>>;
181
+ /**
182
+ * List users
183
+ */
184
+ list: (query?: {
185
+ limit?: number;
186
+ cursor?: string;
187
+ status?: string;
188
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
189
+ users: Array<{
190
+ id: string;
191
+ email?: string;
192
+ phone?: string;
193
+ status: string;
194
+ }>;
195
+ hasNext: boolean;
196
+ cursor?: string;
197
+ }>>;
198
+ /**
199
+ * Get user by ID
200
+ */
201
+ get: (userId: string) => Promise<_safercity_sdk_core.ApiResponse<{
202
+ id: string;
203
+ email?: string;
204
+ phone?: string;
205
+ firstName?: string;
206
+ lastName?: string;
207
+ status: string;
208
+ metadata?: Record<string, unknown>;
209
+ }>>;
210
+ /**
211
+ * Update user
212
+ */
213
+ update: (userId: string, body: {
214
+ email?: string;
215
+ phone?: string;
216
+ firstName?: string;
217
+ lastName?: string;
218
+ metadata?: Record<string, unknown>;
219
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
220
+ id: string;
221
+ }>>;
222
+ /**
223
+ * Update user status
224
+ */
225
+ updateStatus: (userId: string, body: {
226
+ status: string;
227
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
228
+ id: string;
229
+ status: string;
230
+ }>>;
231
+ /**
232
+ * Delete user
233
+ */
234
+ delete: (userId: string) => Promise<_safercity_sdk_core.ApiResponse<{
235
+ success: boolean;
236
+ }>>;
237
+ };
238
+ panics: {
239
+ /**
240
+ * Create panic
241
+ */
242
+ create: (body: {
243
+ userId: string;
244
+ panicTypeId?: string;
245
+ latitude: number;
246
+ longitude: number;
247
+ accuracy?: number;
248
+ metadata?: Record<string, unknown>;
249
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
250
+ id: string;
251
+ status: string;
252
+ createdAt: string;
253
+ }>>;
254
+ /**
255
+ * Get panic by ID
256
+ */
257
+ get: (panicId: string, query?: {
258
+ userId?: string;
259
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
260
+ id: string;
261
+ userId: string;
262
+ status: string;
263
+ latitude: number;
264
+ longitude: number;
265
+ createdAt: string;
266
+ updatedAt?: string;
267
+ }>>;
268
+ /**
269
+ * List panics
270
+ */
271
+ list: (query?: {
272
+ userId?: string;
273
+ status?: string;
274
+ limit?: number;
275
+ cursor?: string;
276
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
277
+ panics: Array<{
278
+ id: string;
279
+ userId: string;
280
+ status: string;
281
+ createdAt: string;
282
+ }>;
283
+ hasNext: boolean;
284
+ cursor?: string;
285
+ }>>;
286
+ /**
287
+ * Update panic location
288
+ */
289
+ updateLocation: (panicId: string, body: {
290
+ userId: string;
291
+ latitude: number;
292
+ longitude: number;
293
+ accuracy?: number;
294
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
295
+ id: string;
296
+ latitude: number;
297
+ longitude: number;
298
+ }>>;
299
+ /**
300
+ * Cancel panic
301
+ */
302
+ cancel: (panicId: string, body: {
303
+ userId: string;
304
+ reason?: string;
305
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
306
+ id: string;
307
+ status: string;
308
+ cancelledAt: string;
309
+ }>>;
310
+ /**
311
+ * Stream panic updates (SSE)
312
+ */
313
+ streamUpdates: (panicId: string, options?: EventSourceOptions) => AsyncIterable<ServerSentEvent>;
314
+ };
315
+ subscriptions: {
316
+ /**
317
+ * List subscription types
318
+ */
319
+ listTypes: () => Promise<_safercity_sdk_core.ApiResponse<{
320
+ types: Array<{
321
+ id: string;
322
+ name: string;
323
+ description?: string;
324
+ price?: number;
325
+ }>;
326
+ }>>;
327
+ /**
328
+ * Create subscription
329
+ */
330
+ create: (body: {
331
+ userId: string;
332
+ subscriptionTypeId: string;
333
+ status?: string;
334
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
335
+ id: string;
336
+ userId: string;
337
+ subscriptionTypeId: string;
338
+ status: string;
339
+ }>>;
340
+ /**
341
+ * List subscriptions
342
+ */
343
+ list: (query?: {
344
+ userId?: string;
345
+ status?: string;
346
+ limit?: number;
347
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
348
+ subscriptions: Array<{
349
+ id: string;
350
+ userId: string;
351
+ subscriptionTypeId: string;
352
+ status: string;
353
+ }>;
354
+ }>>;
355
+ /**
356
+ * Get subscription stats
357
+ */
358
+ stats: () => Promise<_safercity_sdk_core.ApiResponse<{
359
+ total: number;
360
+ active: number;
361
+ byType: Record<string, number>;
362
+ }>>;
363
+ };
364
+ notifications: {
365
+ /**
366
+ * Create subscriber
367
+ */
368
+ createSubscriber: (body: {
369
+ userId: string;
370
+ email?: string;
371
+ phone?: string;
372
+ data?: Record<string, unknown>;
373
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
374
+ subscriberId: string;
375
+ }>>;
376
+ /**
377
+ * Trigger notification
378
+ */
379
+ trigger: (body: {
380
+ userId: string;
381
+ workflowId: string;
382
+ payload?: Record<string, unknown>;
383
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
384
+ transactionId: string;
385
+ status: string;
386
+ }>>;
387
+ /**
388
+ * Get user preferences
389
+ */
390
+ getPreferences: (userId: string) => Promise<_safercity_sdk_core.ApiResponse<{
391
+ preferences: Record<string, unknown>;
392
+ }>>;
393
+ /**
394
+ * Update user preferences
395
+ */
396
+ updatePreferences: (userId: string, body: {
397
+ preferences: Record<string, unknown>;
398
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
399
+ success: boolean;
400
+ }>>;
401
+ };
402
+ locationSafety: {
403
+ /**
404
+ * Check location safety
405
+ */
406
+ check: (query: {
407
+ latitude: number;
408
+ longitude: number;
409
+ radius?: number;
410
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
411
+ safetyScore: number;
412
+ riskLevel: string;
413
+ factors: Array<{
414
+ type: string;
415
+ impact: number;
416
+ }>;
417
+ }>>;
418
+ };
419
+ crimes: {
420
+ /**
421
+ * List crimes
422
+ */
423
+ list: (query?: {
424
+ latitude?: number;
425
+ longitude?: number;
426
+ radius?: number;
427
+ type?: string;
428
+ from?: string;
429
+ to?: string;
430
+ limit?: number;
431
+ }) => Promise<_safercity_sdk_core.ApiResponse<{
432
+ crimes: Array<{
433
+ id: string;
434
+ type: string;
435
+ latitude: number;
436
+ longitude: number;
437
+ occurredAt: string;
438
+ }>;
439
+ }>>;
440
+ /**
441
+ * Get crime categories
442
+ */
443
+ categories: () => Promise<_safercity_sdk_core.ApiResponse<{
444
+ categories: Array<{
445
+ id: string;
446
+ name: string;
447
+ }>;
448
+ }>>;
449
+ /**
450
+ * Get crime types
451
+ */
452
+ types: () => Promise<_safercity_sdk_core.ApiResponse<{
453
+ types: Array<{
454
+ id: string;
455
+ name: string;
456
+ categoryId: string;
457
+ }>;
458
+ }>>;
459
+ };
460
+ };
461
+ type SaferCityClient = ReturnType<typeof createSaferCityClient>;
462
+
463
+ export { type SaferCityClient, type SaferCityClientOptions, createSaferCityClient };
package/dist/index.js ADDED
@@ -0,0 +1,238 @@
1
+ import { BaseClient, createStreamAdapter } from '@safercity/sdk-core';
2
+ export { FetchStreamAdapter, MemoryTokenStorage, SaferCityApiError, WebStreamAdapter, createAuthHeader, createStreamAdapter, getJwtExpiration, isTokenExpired, parseJwtPayload } from '@safercity/sdk-core';
3
+
4
+ function createSaferCityClient(options) {
5
+ const baseClient = new BaseClient(options);
6
+ const streamAdapter = options.streamAdapter ?? createStreamAdapter(options.fetch);
7
+ return {
8
+ /**
9
+ * Access the underlying base client for custom requests
10
+ */
11
+ _client: baseClient,
12
+ /**
13
+ * Update authentication token
14
+ */
15
+ setToken: (token) => baseClient.setToken(token),
16
+ /**
17
+ * Update tenant ID
18
+ */
19
+ setTenantId: (tenantId) => baseClient.setTenantId(tenantId),
20
+ /**
21
+ * Get current configuration
22
+ */
23
+ getConfig: () => baseClient.getConfig(),
24
+ // ==================
25
+ // Health & System
26
+ // ==================
27
+ health: {
28
+ /**
29
+ * Check API health status
30
+ */
31
+ check: () => baseClient.get("/health")
32
+ },
33
+ // ==================
34
+ // Authentication
35
+ // ==================
36
+ auth: {
37
+ /**
38
+ * Get current authentication context
39
+ */
40
+ whoami: () => baseClient.get("/auth/whoami"),
41
+ /**
42
+ * Check if authenticated (optional auth)
43
+ */
44
+ check: () => baseClient.get("/auth/optional")
45
+ },
46
+ // ==================
47
+ // OAuth
48
+ // ==================
49
+ oauth: {
50
+ /**
51
+ * Get access token
52
+ */
53
+ token: (body) => baseClient.post("/oauth/token", body),
54
+ /**
55
+ * Refresh access token
56
+ */
57
+ refresh: (body) => baseClient.post("/oauth/refresh", body),
58
+ /**
59
+ * Introspect token
60
+ */
61
+ introspect: (body) => baseClient.post("/oauth/introspect", body),
62
+ /**
63
+ * Revoke token
64
+ */
65
+ revoke: (body) => baseClient.post("/oauth/revoke", body)
66
+ },
67
+ // ==================
68
+ // Tenants
69
+ // ==================
70
+ tenants: {
71
+ /**
72
+ * Create a new tenant
73
+ */
74
+ create: (body) => baseClient.post("/v1/tenants", body),
75
+ /**
76
+ * List tenants (admin)
77
+ */
78
+ list: (query) => baseClient.get("/v1/tenants", { query })
79
+ },
80
+ // ==================
81
+ // Credentials
82
+ // ==================
83
+ credentials: {
84
+ /**
85
+ * Exchange setup token for credentials
86
+ */
87
+ setup: (body) => baseClient.post("/v1/credentials", body),
88
+ /**
89
+ * List credentials
90
+ */
91
+ list: () => baseClient.get("/v1/credentials"),
92
+ /**
93
+ * Revoke credential
94
+ */
95
+ revoke: (credentialId) => baseClient.delete(`/v1/credentials/${credentialId}`)
96
+ },
97
+ // ==================
98
+ // Users
99
+ // ==================
100
+ users: {
101
+ /**
102
+ * Create user
103
+ */
104
+ create: (body) => baseClient.post("/v1/users", body),
105
+ /**
106
+ * List users
107
+ */
108
+ list: (query) => baseClient.get("/v1/users", { query }),
109
+ /**
110
+ * Get user by ID
111
+ */
112
+ get: (userId) => baseClient.get(`/v1/users/${userId}`),
113
+ /**
114
+ * Update user
115
+ */
116
+ update: (userId, body) => baseClient.put(`/v1/users/${userId}`, body),
117
+ /**
118
+ * Update user status
119
+ */
120
+ updateStatus: (userId, body) => baseClient.patch(`/v1/users/${userId}/status`, body),
121
+ /**
122
+ * Delete user
123
+ */
124
+ delete: (userId) => baseClient.delete(`/v1/users/${userId}`)
125
+ },
126
+ // ==================
127
+ // Panics
128
+ // ==================
129
+ panics: {
130
+ /**
131
+ * Create panic
132
+ */
133
+ create: (body) => baseClient.post("/v1/panics", body),
134
+ /**
135
+ * Get panic by ID
136
+ */
137
+ get: (panicId, query) => baseClient.get(`/v1/panics/${panicId}`, { query }),
138
+ /**
139
+ * List panics
140
+ */
141
+ list: (query) => baseClient.get("/v1/panics", { query }),
142
+ /**
143
+ * Update panic location
144
+ */
145
+ updateLocation: (panicId, body) => baseClient.put(`/v1/panics/${panicId}/location`, body),
146
+ /**
147
+ * Cancel panic
148
+ */
149
+ cancel: (panicId, body) => baseClient.put(`/v1/panics/${panicId}/cancel`, body),
150
+ /**
151
+ * Stream panic updates (SSE)
152
+ */
153
+ streamUpdates: (panicId, options2) => {
154
+ const config = baseClient.getConfig();
155
+ const url = `${config.baseUrl}/v1/panics/${panicId}/stream`;
156
+ return streamAdapter.createEventSource(url, {
157
+ ...options2,
158
+ headers: {
159
+ ...options2?.headers,
160
+ ...config.token ? { Authorization: `Bearer ${config.token}` } : {}
161
+ }
162
+ });
163
+ }
164
+ },
165
+ // ==================
166
+ // Subscriptions
167
+ // ==================
168
+ subscriptions: {
169
+ /**
170
+ * List subscription types
171
+ */
172
+ listTypes: () => baseClient.get("/v1/subscriptions/types"),
173
+ /**
174
+ * Create subscription
175
+ */
176
+ create: (body) => baseClient.post("/v1/subscriptions", body),
177
+ /**
178
+ * List subscriptions
179
+ */
180
+ list: (query) => baseClient.get("/v1/subscriptions", { query }),
181
+ /**
182
+ * Get subscription stats
183
+ */
184
+ stats: () => baseClient.get("/v1/subscriptions/stats")
185
+ },
186
+ // ==================
187
+ // Notifications
188
+ // ==================
189
+ notifications: {
190
+ /**
191
+ * Create subscriber
192
+ */
193
+ createSubscriber: (body) => baseClient.post("/v1/notifications/subscribers", body),
194
+ /**
195
+ * Trigger notification
196
+ */
197
+ trigger: (body) => baseClient.post("/v1/notifications/trigger", body),
198
+ /**
199
+ * Get user preferences
200
+ */
201
+ getPreferences: (userId) => baseClient.get(`/v1/notifications/preferences/${userId}`),
202
+ /**
203
+ * Update user preferences
204
+ */
205
+ updatePreferences: (userId, body) => baseClient.put(`/v1/notifications/preferences/${userId}`, body)
206
+ },
207
+ // ==================
208
+ // Location Safety
209
+ // ==================
210
+ locationSafety: {
211
+ /**
212
+ * Check location safety
213
+ */
214
+ check: (query) => baseClient.get("/v1/location-safety", { query })
215
+ },
216
+ // ==================
217
+ // Crimes
218
+ // ==================
219
+ crimes: {
220
+ /**
221
+ * List crimes
222
+ */
223
+ list: (query) => baseClient.get("/v1/crimes", { query }),
224
+ /**
225
+ * Get crime categories
226
+ */
227
+ categories: () => baseClient.get("/v1/crime-categories"),
228
+ /**
229
+ * Get crime types
230
+ */
231
+ types: () => baseClient.get("/v1/crime-types")
232
+ }
233
+ };
234
+ }
235
+
236
+ export { createSaferCityClient };
237
+ //# sourceMappingURL=index.js.map
238
+ //# sourceMappingURL=index.js.map