@osise/api-client 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.
Files changed (116) hide show
  1. package/README.md +474 -0
  2. package/dist/cjs/api/admin.js +277 -0
  3. package/dist/cjs/api/admin.js.map +1 -0
  4. package/dist/cjs/api/artisans.js +277 -0
  5. package/dist/cjs/api/artisans.js.map +1 -0
  6. package/dist/cjs/api/auth.js +83 -0
  7. package/dist/cjs/api/auth.js.map +1 -0
  8. package/dist/cjs/api/consumers.js +170 -0
  9. package/dist/cjs/api/consumers.js.map +1 -0
  10. package/dist/cjs/api/index.js +22 -0
  11. package/dist/cjs/api/index.js.map +1 -0
  12. package/dist/cjs/api/jobs.js +202 -0
  13. package/dist/cjs/api/jobs.js.map +1 -0
  14. package/dist/cjs/hooks/index.js +435 -0
  15. package/dist/cjs/hooks/index.js.map +1 -0
  16. package/dist/cjs/index.js +189 -0
  17. package/dist/cjs/index.js.map +1 -0
  18. package/dist/cjs/types/admin.js +6 -0
  19. package/dist/cjs/types/admin.js.map +1 -0
  20. package/dist/cjs/types/artisan.js +6 -0
  21. package/dist/cjs/types/artisan.js.map +1 -0
  22. package/dist/cjs/types/auth.js +6 -0
  23. package/dist/cjs/types/auth.js.map +1 -0
  24. package/dist/cjs/types/common.js +6 -0
  25. package/dist/cjs/types/common.js.map +1 -0
  26. package/dist/cjs/types/consumer.js +6 -0
  27. package/dist/cjs/types/consumer.js.map +1 -0
  28. package/dist/cjs/types/enums.js +226 -0
  29. package/dist/cjs/types/enums.js.map +1 -0
  30. package/dist/cjs/types/index.js +35 -0
  31. package/dist/cjs/types/index.js.map +1 -0
  32. package/dist/cjs/types/job.js +6 -0
  33. package/dist/cjs/types/job.js.map +1 -0
  34. package/dist/cjs/utils/http-client.js +214 -0
  35. package/dist/cjs/utils/http-client.js.map +1 -0
  36. package/dist/cjs/utils/index.js +19 -0
  37. package/dist/cjs/utils/index.js.map +1 -0
  38. package/dist/cjs/utils/storage.js +105 -0
  39. package/dist/cjs/utils/storage.js.map +1 -0
  40. package/dist/esm/api/admin.js +269 -0
  41. package/dist/esm/api/admin.js.map +1 -0
  42. package/dist/esm/api/artisans.js +270 -0
  43. package/dist/esm/api/artisans.js.map +1 -0
  44. package/dist/esm/api/auth.js +79 -0
  45. package/dist/esm/api/auth.js.map +1 -0
  46. package/dist/esm/api/consumers.js +165 -0
  47. package/dist/esm/api/consumers.js.map +1 -0
  48. package/dist/esm/api/index.js +6 -0
  49. package/dist/esm/api/index.js.map +1 -0
  50. package/dist/esm/api/jobs.js +197 -0
  51. package/dist/esm/api/jobs.js.map +1 -0
  52. package/dist/esm/hooks/index.js +408 -0
  53. package/dist/esm/hooks/index.js.map +1 -0
  54. package/dist/esm/index.js +165 -0
  55. package/dist/esm/index.js.map +1 -0
  56. package/dist/esm/types/admin.js +5 -0
  57. package/dist/esm/types/admin.js.map +1 -0
  58. package/dist/esm/types/artisan.js +5 -0
  59. package/dist/esm/types/artisan.js.map +1 -0
  60. package/dist/esm/types/auth.js +5 -0
  61. package/dist/esm/types/auth.js.map +1 -0
  62. package/dist/esm/types/common.js +5 -0
  63. package/dist/esm/types/common.js.map +1 -0
  64. package/dist/esm/types/consumer.js +5 -0
  65. package/dist/esm/types/consumer.js.map +1 -0
  66. package/dist/esm/types/enums.js +223 -0
  67. package/dist/esm/types/enums.js.map +1 -0
  68. package/dist/esm/types/index.js +19 -0
  69. package/dist/esm/types/index.js.map +1 -0
  70. package/dist/esm/types/job.js +5 -0
  71. package/dist/esm/types/job.js.map +1 -0
  72. package/dist/esm/utils/http-client.js +208 -0
  73. package/dist/esm/utils/http-client.js.map +1 -0
  74. package/dist/esm/utils/index.js +3 -0
  75. package/dist/esm/utils/index.js.map +1 -0
  76. package/dist/esm/utils/storage.js +99 -0
  77. package/dist/esm/utils/storage.js.map +1 -0
  78. package/dist/types/api/admin.d.ts +188 -0
  79. package/dist/types/api/admin.d.ts.map +1 -0
  80. package/dist/types/api/artisans.d.ts +183 -0
  81. package/dist/types/api/artisans.d.ts.map +1 -0
  82. package/dist/types/api/auth.d.ts +58 -0
  83. package/dist/types/api/auth.d.ts.map +1 -0
  84. package/dist/types/api/consumers.d.ts +113 -0
  85. package/dist/types/api/consumers.d.ts.map +1 -0
  86. package/dist/types/api/index.d.ts +6 -0
  87. package/dist/types/api/index.d.ts.map +1 -0
  88. package/dist/types/api/jobs.d.ts +136 -0
  89. package/dist/types/api/jobs.d.ts.map +1 -0
  90. package/dist/types/hooks/index.d.ts +225 -0
  91. package/dist/types/hooks/index.d.ts.map +1 -0
  92. package/dist/types/index.d.ts +127 -0
  93. package/dist/types/index.d.ts.map +1 -0
  94. package/dist/types/types/admin.d.ts +226 -0
  95. package/dist/types/types/admin.d.ts.map +1 -0
  96. package/dist/types/types/artisan.d.ts +438 -0
  97. package/dist/types/types/artisan.d.ts.map +1 -0
  98. package/dist/types/types/auth.d.ts +92 -0
  99. package/dist/types/types/auth.d.ts.map +1 -0
  100. package/dist/types/types/common.d.ts +105 -0
  101. package/dist/types/types/common.d.ts.map +1 -0
  102. package/dist/types/types/consumer.d.ts +144 -0
  103. package/dist/types/types/consumer.d.ts.map +1 -0
  104. package/dist/types/types/enums.d.ts +199 -0
  105. package/dist/types/types/enums.d.ts.map +1 -0
  106. package/dist/types/types/index.d.ts +12 -0
  107. package/dist/types/types/index.d.ts.map +1 -0
  108. package/dist/types/types/job.d.ts +226 -0
  109. package/dist/types/types/job.d.ts.map +1 -0
  110. package/dist/types/utils/http-client.d.ts +65 -0
  111. package/dist/types/utils/http-client.d.ts.map +1 -0
  112. package/dist/types/utils/index.d.ts +3 -0
  113. package/dist/types/utils/index.d.ts.map +1 -0
  114. package/dist/types/utils/storage.d.ts +48 -0
  115. package/dist/types/utils/storage.d.ts.map +1 -0
  116. package/package.json +78 -0
package/README.md ADDED
@@ -0,0 +1,474 @@
1
+ # @osise/api-client
2
+
3
+ Official TypeScript SDK for the Osise API - connecting consumers with skilled artisans in Nigeria.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @osise/api-client
9
+ # or
10
+ yarn add @osise/api-client
11
+ # or
12
+ pnpm add @osise/api-client
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ### Basic Usage
18
+
19
+ ```typescript
20
+ import { OsiseClient, BrowserTokenStorage } from '@osise/api-client';
21
+
22
+ // Create client instance
23
+ const client = new OsiseClient({
24
+ baseUrl: 'https://api.osise.com',
25
+ storage: new BrowserTokenStorage(), // Persists tokens in localStorage
26
+ onAuthRequired: () => {
27
+ // Handle auth required (e.g., redirect to login)
28
+ window.location.href = '/login';
29
+ },
30
+ });
31
+
32
+ // Request OTP
33
+ const otpResponse = await client.auth.requestOtp({
34
+ phoneNumber: '+2348012345678',
35
+ purpose: 'Login',
36
+ });
37
+
38
+ // Verify OTP
39
+ const authResponse = await client.auth.verifyOtp({
40
+ phoneNumber: '+2348012345678',
41
+ code: '123456',
42
+ deviceId: 'unique-device-id',
43
+ deviceName: 'iPhone 15',
44
+ deviceType: 'iOS',
45
+ });
46
+
47
+ // Tokens are automatically stored and used for subsequent requests
48
+ console.log('Logged in as:', authResponse.data?.user.firstName);
49
+ ```
50
+
51
+ ### React Integration
52
+
53
+ ```tsx
54
+ import { OsiseProvider, useOsiseClient, useConsumerProfile, useMutation } from '@osise/api-client/react';
55
+ import { BrowserTokenStorage } from '@osise/api-client';
56
+
57
+ // Wrap your app with the provider
58
+ function App() {
59
+ return (
60
+ <OsiseProvider
61
+ config={{
62
+ baseUrl: 'https://api.osise.com',
63
+ storage: new BrowserTokenStorage(),
64
+ onAuthRequired: () => navigate('/login'),
65
+ }}
66
+ >
67
+ <MyApp />
68
+ </OsiseProvider>
69
+ );
70
+ }
71
+
72
+ // Use hooks in components
73
+ function Profile() {
74
+ const { data: profile, isLoading, error } = useConsumerProfile();
75
+
76
+ if (isLoading) return <div>Loading...</div>;
77
+ if (error) return <div>Error: {error.message}</div>;
78
+
79
+ return (
80
+ <div>
81
+ <h1>Welcome, {profile?.firstName}!</h1>
82
+ <p>Phone: {profile?.phoneNumber}</p>
83
+ </div>
84
+ );
85
+ }
86
+
87
+ // Use mutations for actions
88
+ function CreateJobButton() {
89
+ const client = useOsiseClient();
90
+
91
+ const { mutate, isLoading } = useMutation(
92
+ (data) => client.jobs.create(data),
93
+ {
94
+ onSuccess: (job) => {
95
+ console.log('Job created:', job.id);
96
+ },
97
+ onError: (error) => {
98
+ alert(error.message);
99
+ },
100
+ }
101
+ );
102
+
103
+ return (
104
+ <button
105
+ onClick={() => mutate({
106
+ serviceCategory: 'Plumbing',
107
+ title: 'Fix leaky faucet',
108
+ description: 'Kitchen faucet is leaking',
109
+ addressId: 'addr-123',
110
+ })}
111
+ disabled={isLoading}
112
+ >
113
+ Create Job
114
+ </button>
115
+ );
116
+ }
117
+ ```
118
+
119
+ ### React Native Integration
120
+
121
+ ```typescript
122
+ import { OsiseClient, SecureTokenStorage } from '@osise/api-client';
123
+ import AsyncStorage from '@react-native-async-storage/async-storage';
124
+
125
+ // Create secure storage for React Native
126
+ const storage = new SecureTokenStorage(AsyncStorage);
127
+ await storage.initialize(); // Load tokens from storage
128
+
129
+ const client = new OsiseClient({
130
+ baseUrl: 'https://api.osise.com',
131
+ storage,
132
+ });
133
+ ```
134
+
135
+ ## API Reference
136
+
137
+ ### Authentication
138
+
139
+ ```typescript
140
+ // Request OTP
141
+ await client.auth.requestOtp({
142
+ phoneNumber: '+234...',
143
+ purpose: 'Login', // or 'Registration'
144
+ deviceId: 'optional-device-id',
145
+ });
146
+
147
+ // Verify OTP
148
+ await client.auth.verifyOtp({
149
+ phoneNumber: '+234...',
150
+ code: '123456',
151
+ deviceId: 'device-id',
152
+ deviceName: 'My Phone',
153
+ deviceType: 'Android',
154
+ });
155
+
156
+ // Register new user
157
+ await client.auth.register({
158
+ phoneNumber: '+234...',
159
+ otpCode: '123456',
160
+ firstName: 'John',
161
+ lastName: 'Doe',
162
+ role: 'Consumer',
163
+ deviceId: 'device-id',
164
+ });
165
+
166
+ // Get current user
167
+ await client.auth.getCurrentUser();
168
+
169
+ // Get active sessions
170
+ await client.auth.getSessions();
171
+
172
+ // Revoke a session
173
+ await client.auth.revokeSession('session-id');
174
+
175
+ // Logout
176
+ await client.auth.logout();
177
+
178
+ // Logout all sessions
179
+ await client.auth.logoutAll();
180
+ ```
181
+
182
+ ### Consumer Features
183
+
184
+ ```typescript
185
+ // Profile
186
+ await client.consumers.getProfile();
187
+ await client.consumers.updateProfile({ firstName: 'Jane' });
188
+ await client.consumers.uploadProfilePhoto('https://uploadcare.com/...');
189
+
190
+ // Addresses
191
+ await client.consumerAddresses.getAll();
192
+ await client.consumerAddresses.create({
193
+ label: 'Home',
194
+ street: '123 Main St',
195
+ area: 'Lekki',
196
+ city: 'Lagos',
197
+ state: 'Lagos',
198
+ latitude: 6.4541,
199
+ longitude: 3.3947,
200
+ });
201
+ await client.consumerAddresses.setDefault('address-id');
202
+
203
+ // Favorites
204
+ await client.consumers.getFavorites();
205
+ await client.consumers.addFavorite('artisan-id');
206
+ await client.consumers.removeFavorite('artisan-id');
207
+
208
+ // Notification Settings
209
+ await client.consumers.getNotificationSettings();
210
+ await client.consumers.updateNotificationSettings({
211
+ pushEnabled: true,
212
+ jobUpdates: true,
213
+ });
214
+
215
+ // NDPR Compliance
216
+ await client.consumers.exportData();
217
+ await client.consumers.requestAccountDeletion({ reason: 'Moving abroad' });
218
+ ```
219
+
220
+ ### Artisan Features
221
+
222
+ ```typescript
223
+ // Profile
224
+ await client.artisans.getProfile();
225
+ await client.artisans.updateProfile({ bio: 'Experienced plumber' });
226
+
227
+ // Documents
228
+ await client.artisans.getDocuments();
229
+ await client.artisans.submitDocument({
230
+ documentType: 'Nin',
231
+ fileUrl: 'https://...',
232
+ fileName: 'nin.pdf',
233
+ fileSize: 1024,
234
+ mimeType: 'application/pdf',
235
+ });
236
+
237
+ // Guarantors
238
+ await client.artisans.getGuarantors();
239
+ await client.artisans.addGuarantor({
240
+ fullName: 'Jane Smith',
241
+ phoneNumber: '+234...',
242
+ relationship: 'Former Employer',
243
+ occupation: 'Business Owner',
244
+ address: '456 Oak St, Lagos',
245
+ });
246
+
247
+ // Bank Account
248
+ await client.artisans.getBankAccount();
249
+ await client.artisans.setBankAccount({
250
+ bankCode: '044',
251
+ accountNumber: '0123456789',
252
+ accountName: 'John Doe',
253
+ });
254
+
255
+ // Application Status
256
+ await client.artisans.getApplicationStatus();
257
+ await client.artisans.getSkillTestSlots();
258
+ await client.artisans.bookSkillTest({ slotId: 'slot-id' });
259
+
260
+ // Availability
261
+ await client.artisanAvailability.getStatus();
262
+ await client.artisanAvailability.updateStatus({ status: 'Online' });
263
+ await client.artisanAvailability.updateWorkingHours({
264
+ workingHours: [
265
+ { dayOfWeek: 'Monday', isWorking: true, startTime: '08:00', endTime: '17:00' },
266
+ // ...
267
+ ],
268
+ });
269
+ await client.artisanAvailability.updateLocation({ latitude: 6.45, longitude: 3.39 });
270
+
271
+ // Earnings
272
+ await client.artisanEarnings.getSummary();
273
+ await client.artisanEarnings.getJobEarnings({ page: 1, pageSize: 20 });
274
+ await client.artisanEarnings.getPendingEarnings();
275
+ await client.artisanEarnings.getPayouts();
276
+
277
+ // Performance
278
+ await client.artisanPerformance.getRating();
279
+ await client.artisanPerformance.getReviews();
280
+ await client.artisanPerformance.getMetrics({ period: 'month' });
281
+ await client.artisanPerformance.getAlerts();
282
+ ```
283
+
284
+ ### Jobs
285
+
286
+ ```typescript
287
+ // Consumer - Create and manage jobs
288
+ await client.jobs.create({
289
+ serviceCategory: 'Electrical',
290
+ title: 'Fix electrical outlet',
291
+ description: 'Outlet in bedroom not working',
292
+ addressId: 'address-id',
293
+ isUrgent: true,
294
+ });
295
+
296
+ await client.jobs.list({ status: 'Pending', page: 1 });
297
+ await client.jobs.get('job-id');
298
+ await client.jobs.cancel('job-id', { reason: 'Found another solution' });
299
+ await client.jobs.getTimeline('job-id');
300
+
301
+ // Quotes
302
+ await client.jobs.getQuote('job-id');
303
+ await client.jobs.respondToQuote('job-id', { decision: 'approve' });
304
+
305
+ // Payments
306
+ await client.jobs.initiatePayment('job-id', { method: 'Card' });
307
+ await client.jobs.verifyPayment('job-id', 'payment-reference');
308
+
309
+ // Ratings
310
+ await client.jobs.submitRating('job-id', {
311
+ overall: 5,
312
+ quality: 5,
313
+ punctuality: 4,
314
+ professionalism: 5,
315
+ value: 4,
316
+ reviewText: 'Great work!',
317
+ });
318
+
319
+ // Artisan - Handle assigned jobs
320
+ await client.artisanJobs.list({ status: 'Assigned' });
321
+ await client.artisanJobs.accept('job-id');
322
+ await client.artisanJobs.decline('job-id', 'Too far away');
323
+ await client.artisanJobs.startEnRoute('job-id');
324
+ await client.artisanJobs.markArrived('job-id', { latitude: 6.45, longitude: 3.39 });
325
+ await client.artisanJobs.submitQuote('job-id', {
326
+ laborCost: 5000,
327
+ materials: [
328
+ { item: 'Wire', quantity: 2, unitPrice: 500 },
329
+ ],
330
+ estimatedDuration: '2 hours',
331
+ });
332
+ await client.artisanJobs.startWork('job-id');
333
+ await client.artisanJobs.complete('job-id', 'All fixed');
334
+ ```
335
+
336
+ ### Admin Features
337
+
338
+ ```typescript
339
+ // Dashboard
340
+ await client.adminDashboard.getStats();
341
+
342
+ // Artisan Management
343
+ await client.adminArtisans.list({ search: 'John', status: 'Active' });
344
+ await client.adminArtisans.get('artisan-id');
345
+ await client.adminArtisans.suspend('artisan-id', 'Policy violation');
346
+ await client.adminArtisans.issueStrike('artisan-id', {
347
+ type: 'QualityIssue',
348
+ reason: 'Poor workmanship reported',
349
+ severity: 'warning',
350
+ });
351
+
352
+ // Application Review
353
+ await client.adminApplications.list({ verificationStatus: 'DocumentsReview' });
354
+ await client.adminApplications.reviewDocument('artisan-id', 'doc-id', {
355
+ status: 'Approved',
356
+ });
357
+ await client.adminApplications.process('artisan-id', { action: 'approve' });
358
+
359
+ // Consumer Management
360
+ await client.adminConsumers.list({ accountType: 'Business' });
361
+ await client.adminConsumers.block('consumer-id', { reason: 'Fraud' });
362
+ await client.adminConsumers.unblock('consumer-id');
363
+
364
+ // Job Management
365
+ await client.adminJobs.list();
366
+ await client.adminJobs.assignArtisan('job-id', 'artisan-id');
367
+ await client.adminJobs.resolveDispute('job-id', 'Refund issued', 5000);
368
+ ```
369
+
370
+ ## Error Handling
371
+
372
+ ```typescript
373
+ import { OsiseApiError } from '@osise/api-client';
374
+
375
+ try {
376
+ await client.auth.verifyOtp({ ... });
377
+ } catch (error) {
378
+ if (error instanceof OsiseApiError) {
379
+ if (error.isUnauthorized) {
380
+ // Token expired or invalid
381
+ } else if (error.isValidationError) {
382
+ // Validation failed - check error.errors
383
+ console.log(error.errors);
384
+ } else if (error.isRateLimited) {
385
+ // Too many requests
386
+ } else if (error.isNetworkError) {
387
+ // Network issue
388
+ } else if (error.isTimeoutError) {
389
+ // Request timed out
390
+ }
391
+
392
+ console.error(error.message, error.statusCode);
393
+ }
394
+ }
395
+ ```
396
+
397
+ ## TypeScript Support
398
+
399
+ All types are fully exported:
400
+
401
+ ```typescript
402
+ import type {
403
+ // Auth
404
+ AuthResponseDto,
405
+ UserProfileDto,
406
+ SessionDto,
407
+
408
+ // Consumer
409
+ ConsumerProfileDto,
410
+ AddressDto,
411
+
412
+ // Artisan
413
+ ArtisanProfileDto,
414
+ ApplicationStatusDto,
415
+ VerificationStatus,
416
+
417
+ // Jobs
418
+ JobRequestDto,
419
+ JobStatus,
420
+ Quote,
421
+
422
+ // Common
423
+ StandardResponse,
424
+ PagedResult,
425
+
426
+ // Enums
427
+ ServiceCategory,
428
+ PaymentMethod,
429
+ AccountType,
430
+ } from '@osise/api-client';
431
+ ```
432
+
433
+ ## Configuration Options
434
+
435
+ ```typescript
436
+ const client = new OsiseClient({
437
+ // Required
438
+ baseUrl: 'https://api.osise.com',
439
+
440
+ // Optional
441
+ timeout: 30000, // Request timeout in ms
442
+ storage: new BrowserTokenStorage(), // Token storage
443
+ headers: { 'X-Custom-Header': 'value' }, // Custom headers
444
+ autoRefresh: true, // Auto refresh tokens (default: true)
445
+
446
+ // Callbacks
447
+ onError: (error) => console.error(error),
448
+ onAuthRequired: () => redirectToLogin(),
449
+ onTokenRefresh: (accessToken, refreshToken) => {
450
+ console.log('Tokens refreshed');
451
+ },
452
+ });
453
+ ```
454
+
455
+ ## Storage Options
456
+
457
+ ```typescript
458
+ // Browser (localStorage)
459
+ import { BrowserTokenStorage } from '@osise/api-client';
460
+ const storage = new BrowserTokenStorage('osise'); // optional key prefix
461
+
462
+ // React Native (AsyncStorage)
463
+ import { SecureTokenStorage } from '@osise/api-client';
464
+ const storage = new SecureTokenStorage(AsyncStorage);
465
+ await storage.initialize();
466
+
467
+ // In-memory (SSR, testing)
468
+ import { MemoryTokenStorage } from '@osise/api-client';
469
+ const storage = new MemoryTokenStorage();
470
+ ```
471
+
472
+ ## License
473
+
474
+ MIT