@routeflow/sdk 1.0.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.
Files changed (54) hide show
  1. package/README.md +304 -0
  2. package/dist/api/client.d.ts +54 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +119 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/api/mutations/auth.d.ts +57 -0
  7. package/dist/api/mutations/auth.d.ts.map +1 -0
  8. package/dist/api/mutations/auth.js +109 -0
  9. package/dist/api/mutations/auth.js.map +1 -0
  10. package/dist/api/mutations/index.d.ts +8 -0
  11. package/dist/api/mutations/index.d.ts.map +1 -0
  12. package/dist/api/mutations/index.js +29 -0
  13. package/dist/api/mutations/index.js.map +1 -0
  14. package/dist/api/mutations/runs.d.ts +41 -0
  15. package/dist/api/mutations/runs.d.ts.map +1 -0
  16. package/dist/api/mutations/runs.js +132 -0
  17. package/dist/api/mutations/runs.js.map +1 -0
  18. package/dist/api/mutations/stops.d.ts +44 -0
  19. package/dist/api/mutations/stops.d.ts.map +1 -0
  20. package/dist/api/mutations/stops.js +87 -0
  21. package/dist/api/mutations/stops.js.map +1 -0
  22. package/dist/api/mutations/users.d.ts +51 -0
  23. package/dist/api/mutations/users.d.ts.map +1 -0
  24. package/dist/api/mutations/users.js +69 -0
  25. package/dist/api/mutations/users.js.map +1 -0
  26. package/dist/api/queries/auth.d.ts +13 -0
  27. package/dist/api/queries/auth.d.ts.map +1 -0
  28. package/dist/api/queries/auth.js +29 -0
  29. package/dist/api/queries/auth.js.map +1 -0
  30. package/dist/api/queries/drivers.d.ts +22 -0
  31. package/dist/api/queries/drivers.d.ts.map +1 -0
  32. package/dist/api/queries/drivers.js +56 -0
  33. package/dist/api/queries/drivers.js.map +1 -0
  34. package/dist/api/queries/index.d.ts +8 -0
  35. package/dist/api/queries/index.d.ts.map +1 -0
  36. package/dist/api/queries/index.js +19 -0
  37. package/dist/api/queries/index.js.map +1 -0
  38. package/dist/api/queries/runs.d.ts +33 -0
  39. package/dist/api/queries/runs.d.ts.map +1 -0
  40. package/dist/api/queries/runs.js +90 -0
  41. package/dist/api/queries/runs.js.map +1 -0
  42. package/dist/api/queries/tracking.d.ts +22 -0
  43. package/dist/api/queries/tracking.d.ts.map +1 -0
  44. package/dist/api/queries/tracking.js +54 -0
  45. package/dist/api/queries/tracking.js.map +1 -0
  46. package/dist/api/types.d.ts +87 -0
  47. package/dist/api/types.d.ts.map +1 -0
  48. package/dist/api/types.js +74 -0
  49. package/dist/api/types.js.map +1 -0
  50. package/dist/index.d.ts +33 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +58 -0
  53. package/dist/index.js.map +1 -0
  54. package/package.json +47 -0
package/README.md ADDED
@@ -0,0 +1,304 @@
1
+ # @routeflow/sdk
2
+
3
+ TypeScript SDK with TanStack Query hooks for the RouteFlow API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @routeflow/sdk @tanstack/react-query
9
+ # or
10
+ yarn add @routeflow/sdk @tanstack/react-query
11
+ # or
12
+ pnpm add @routeflow/sdk @tanstack/react-query
13
+ ```
14
+
15
+ ## Setup
16
+
17
+ ### 1. Configure the SDK
18
+
19
+ Configure the SDK at your app's entry point:
20
+
21
+ ```typescript
22
+ // app/providers.tsx or similar
23
+ import { configureSDK } from '@routeflow/sdk';
24
+
25
+ configureSDK({
26
+ baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001',
27
+ getAccessToken: () => {
28
+ if (typeof window !== 'undefined') {
29
+ return localStorage.getItem('accessToken');
30
+ }
31
+ return null;
32
+ },
33
+ refreshAccessToken: async () => {
34
+ // Implement token refresh logic
35
+ const refreshToken = localStorage.getItem('refreshToken');
36
+ if (!refreshToken) return null;
37
+
38
+ const response = await fetch('/api/auth/refresh', {
39
+ method: 'POST',
40
+ body: JSON.stringify({ refreshToken }),
41
+ });
42
+ const data = await response.json();
43
+ localStorage.setItem('accessToken', data.accessToken);
44
+ return data.accessToken;
45
+ },
46
+ onUnauthorized: () => {
47
+ // Redirect to login
48
+ window.location.href = '/login';
49
+ },
50
+ });
51
+ ```
52
+
53
+ ### 2. Set up TanStack Query Provider
54
+
55
+ ```typescript
56
+ // app/providers.tsx
57
+ 'use client';
58
+
59
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
60
+ import { useState } from 'react';
61
+
62
+ export function Providers({ children }: { children: React.ReactNode }) {
63
+ const [queryClient] = useState(() => new QueryClient({
64
+ defaultOptions: {
65
+ queries: {
66
+ staleTime: 60 * 1000, // 1 minute
67
+ retry: 1,
68
+ },
69
+ },
70
+ }));
71
+
72
+ return (
73
+ <QueryClientProvider client={queryClient}>
74
+ {children}
75
+ </QueryClientProvider>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ## Usage
81
+
82
+ ### Query Hooks (GET operations)
83
+
84
+ ```typescript
85
+ import { useRuns, useRun, useDrivers, useCurrentUser } from '@routeflow/sdk';
86
+
87
+ // Get paginated list of runs
88
+ function RunsList() {
89
+ const { data, isLoading, error } = useRuns({
90
+ status: 'IN_PROGRESS',
91
+ page: 1,
92
+ limit: 10,
93
+ });
94
+
95
+ if (isLoading) return <Loading />;
96
+ if (error) return <Error message={error.message} />;
97
+
98
+ return (
99
+ <ul>
100
+ {data?.data.map(run => (
101
+ <li key={run.id}>{run.name}</li>
102
+ ))}
103
+ </ul>
104
+ );
105
+ }
106
+
107
+ // Get single run
108
+ function RunDetail({ runId }: { runId: string }) {
109
+ const { data: run, isLoading } = useRun(runId);
110
+ // ...
111
+ }
112
+
113
+ // Get current user
114
+ function Profile() {
115
+ const { data: user, isLoading } = useCurrentUser();
116
+ // ...
117
+ }
118
+
119
+ // Get drivers
120
+ function DriversList() {
121
+ const { data: drivers } = useDrivers({ onlineOnly: true });
122
+ // ...
123
+ }
124
+ ```
125
+
126
+ ### Mutation Hooks (POST/PUT/DELETE operations)
127
+
128
+ ```typescript
129
+ import {
130
+ useCreateRun,
131
+ useUpdateRun,
132
+ useDeleteRun,
133
+ useAssignDriver,
134
+ useLogin,
135
+ useLogout,
136
+ } from '@routeflow/sdk';
137
+
138
+ // Create a run
139
+ function CreateRunForm() {
140
+ const { mutate: createRun, isPending } = useCreateRun({
141
+ onSuccess: (run) => {
142
+ console.log('Created run:', run.id);
143
+ router.push(`/runs/${run.id}`);
144
+ },
145
+ onError: (error) => {
146
+ toast.error(error.message);
147
+ },
148
+ });
149
+
150
+ const handleSubmit = (data: CreateRunRequest) => {
151
+ createRun(data);
152
+ };
153
+
154
+ return <form onSubmit={handleSubmit}>...</form>;
155
+ }
156
+
157
+ // Update a run
158
+ function EditRunForm({ runId }: { runId: string }) {
159
+ const { mutate: updateRun, isPending } = useUpdateRun();
160
+
161
+ const handleSave = (data: UpdateRunRequest) => {
162
+ updateRun({ id: runId, data });
163
+ };
164
+ }
165
+
166
+ // Delete a run
167
+ function DeleteRunButton({ runId }: { runId: string }) {
168
+ const { mutate: deleteRun, isPending } = useDeleteRun({
169
+ onSuccess: () => router.push('/runs'),
170
+ });
171
+
172
+ return (
173
+ <button onClick={() => deleteRun(runId)} disabled={isPending}>
174
+ Delete
175
+ </button>
176
+ );
177
+ }
178
+
179
+ // Assign driver
180
+ function AssignDriverSelect({ runId }: { runId: string }) {
181
+ const { mutate: assignDriver } = useAssignDriver();
182
+
183
+ return (
184
+ <select onChange={(e) => assignDriver({ runId, driverId: e.target.value })}>
185
+ ...
186
+ </select>
187
+ );
188
+ }
189
+
190
+ // Login
191
+ function LoginForm() {
192
+ const { mutate: login, isPending, error } = useLogin({
193
+ onSuccess: (data) => {
194
+ localStorage.setItem('accessToken', data.accessToken);
195
+ localStorage.setItem('refreshToken', data.refreshToken);
196
+ router.push('/dashboard');
197
+ },
198
+ });
199
+
200
+ return (
201
+ <form onSubmit={(e) => {
202
+ e.preventDefault();
203
+ login({ email, password });
204
+ }}>
205
+ ...
206
+ </form>
207
+ );
208
+ }
209
+ ```
210
+
211
+ ### Tracking (Public API)
212
+
213
+ ```typescript
214
+ import { useTrackingStatus, useTrackingLocation } from '@routeflow/sdk';
215
+
216
+ // Public tracking page
217
+ function TrackingPage({ token }: { token: string }) {
218
+ const { data: status, isLoading: statusLoading } = useTrackingStatus(token);
219
+ const { data: location, isLoading: locationLoading } = useTrackingLocation(token);
220
+
221
+ if (statusLoading) return <Loading />;
222
+
223
+ return (
224
+ <div>
225
+ <h1>{status?.runName}</h1>
226
+ <p>Status: {status?.status}</p>
227
+ <p>ETA: {status?.eta?.estimatedTime}</p>
228
+ {location?.available && (
229
+ <Map lat={location.location.lat} lng={location.location.lng} />
230
+ )}
231
+ </div>
232
+ );
233
+ }
234
+ ```
235
+
236
+ ## Available Hooks
237
+
238
+ ### Queries
239
+ - `useCurrentUser()` - Get authenticated user
240
+ - `useRuns(params?)` - List runs with pagination/filters
241
+ - `useRun(id)` - Get single run
242
+ - `useDrivers(params?)` - List drivers
243
+ - `useDriver(id)` - Get single driver
244
+ - `useTrackingStatus(token)` - Public tracking status
245
+ - `useTrackingLocation(token)` - Public driver location
246
+
247
+ ### Mutations
248
+ - `useLogin()` - Login
249
+ - `useRegister()` - Register
250
+ - `useLogout()` - Logout
251
+ - `useCreateRun()` - Create run
252
+ - `useUpdateRun()` - Update run
253
+ - `useDeleteRun()` - Delete run
254
+ - `useAssignDriver()` - Assign driver to run
255
+ - `useUnassignDriver()` - Remove driver from run
256
+ - `useStartRun()` - Start run
257
+ - `useCompleteRun()` - Complete run
258
+ - `useOptimizeRoute()` - Optimize run route
259
+ - `useCreateStop()` - Add stop to run
260
+ - `useUpdateStop()` - Update stop
261
+ - `useDeleteStop()` - Delete stop
262
+ - `useUpdateStopStatus()` - Update stop status
263
+ - `useReorderStops()` - Reorder stops
264
+
265
+ ## Types
266
+
267
+ All types are re-exported from `@routeflow/types`:
268
+
269
+ ```typescript
270
+ import type {
271
+ Run,
272
+ Stop,
273
+ Driver,
274
+ User,
275
+ RunStatus,
276
+ StopStatus,
277
+ ApiResponse,
278
+ PaginatedResponse,
279
+ } from '@routeflow/sdk';
280
+ ```
281
+
282
+ ## Query Keys
283
+
284
+ For manual cache invalidation:
285
+
286
+ ```typescript
287
+ import { queryKeys } from '@routeflow/sdk';
288
+ import { useQueryClient } from '@tanstack/react-query';
289
+
290
+ const queryClient = useQueryClient();
291
+
292
+ // Invalidate all runs
293
+ queryClient.invalidateQueries({ queryKey: queryKeys.runs.all });
294
+
295
+ // Invalidate specific run
296
+ queryClient.invalidateQueries({ queryKey: queryKeys.runs.detail('run-123') });
297
+
298
+ // Invalidate all drivers
299
+ queryClient.invalidateQueries({ queryKey: queryKeys.drivers.all });
300
+ ```
301
+
302
+ ## License
303
+
304
+ MIT
@@ -0,0 +1,54 @@
1
+ import type { AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ /**
3
+ * SDK Configuration
4
+ */
5
+ export interface SDKConfig {
6
+ /** Base URL for the API (e.g., https://api.routeflow.app) */
7
+ baseURL: string;
8
+ /** Function to get the current access token */
9
+ getAccessToken: () => string | null;
10
+ /** Function to refresh the access token when expired */
11
+ refreshAccessToken?: () => Promise<string | null>;
12
+ /** Callback when authentication fails (e.g., redirect to login) */
13
+ onUnauthorized?: () => void;
14
+ /** Request timeout in milliseconds */
15
+ timeout?: number;
16
+ }
17
+ /**
18
+ * Configure the SDK with your API settings
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * configureSDK({
23
+ * baseURL: 'https://api.routeflow.app',
24
+ * getAccessToken: () => localStorage.getItem('accessToken'),
25
+ * refreshAccessToken: async () => {
26
+ * const response = await fetch('/api/refresh');
27
+ * const data = await response.json();
28
+ * return data.accessToken;
29
+ * },
30
+ * onUnauthorized: () => {
31
+ * window.location.href = '/login';
32
+ * },
33
+ * });
34
+ * ```
35
+ */
36
+ export declare function configureSDK(sdkConfig: SDKConfig): void;
37
+ /**
38
+ * Get the configured axios instance
39
+ * @throws Error if SDK is not configured
40
+ */
41
+ export declare function getApiClient(): AxiosInstance;
42
+ /**
43
+ * Get the current SDK configuration
44
+ */
45
+ export declare function getSDKConfig(): SDKConfig | null;
46
+ /**
47
+ * Check if SDK is configured
48
+ */
49
+ export declare function isSDKConfigured(): boolean;
50
+ /**
51
+ * Type-safe API request helper
52
+ */
53
+ export declare function apiRequest<T>(method: 'get' | 'post' | 'put' | 'patch' | 'delete', url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
54
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAA0C,MAAM,OAAO,CAAC;AAEvG;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,cAAc,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IACpC,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAGvD;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,aAAa,CAO5C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AA8DD;;GAEG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EACnD,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC,CAWZ"}
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.configureSDK = configureSDK;
7
+ exports.getApiClient = getApiClient;
8
+ exports.getSDKConfig = getSDKConfig;
9
+ exports.isSDKConfigured = isSDKConfigured;
10
+ exports.apiRequest = apiRequest;
11
+ const axios_1 = __importDefault(require("axios"));
12
+ let config = null;
13
+ let axiosInstance = null;
14
+ /**
15
+ * Configure the SDK with your API settings
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * configureSDK({
20
+ * baseURL: 'https://api.routeflow.app',
21
+ * getAccessToken: () => localStorage.getItem('accessToken'),
22
+ * refreshAccessToken: async () => {
23
+ * const response = await fetch('/api/refresh');
24
+ * const data = await response.json();
25
+ * return data.accessToken;
26
+ * },
27
+ * onUnauthorized: () => {
28
+ * window.location.href = '/login';
29
+ * },
30
+ * });
31
+ * ```
32
+ */
33
+ function configureSDK(sdkConfig) {
34
+ config = sdkConfig;
35
+ axiosInstance = createAxiosInstance(sdkConfig);
36
+ }
37
+ /**
38
+ * Get the configured axios instance
39
+ * @throws Error if SDK is not configured
40
+ */
41
+ function getApiClient() {
42
+ if (!axiosInstance) {
43
+ throw new Error('RouteFlow SDK not configured. Call configureSDK() before using the SDK.');
44
+ }
45
+ return axiosInstance;
46
+ }
47
+ /**
48
+ * Get the current SDK configuration
49
+ */
50
+ function getSDKConfig() {
51
+ return config;
52
+ }
53
+ /**
54
+ * Check if SDK is configured
55
+ */
56
+ function isSDKConfigured() {
57
+ return config !== null && axiosInstance !== null;
58
+ }
59
+ /**
60
+ * Create the axios instance with interceptors
61
+ */
62
+ function createAxiosInstance(sdkConfig) {
63
+ const instance = axios_1.default.create({
64
+ baseURL: sdkConfig.baseURL,
65
+ timeout: sdkConfig.timeout ?? 30000,
66
+ headers: {
67
+ 'Content-Type': 'application/json',
68
+ },
69
+ });
70
+ // Request interceptor - add auth token
71
+ instance.interceptors.request.use((requestConfig) => {
72
+ const token = sdkConfig.getAccessToken();
73
+ if (token) {
74
+ requestConfig.headers.Authorization = `Bearer ${token}`;
75
+ }
76
+ return requestConfig;
77
+ }, (error) => Promise.reject(error));
78
+ // Response interceptor - handle token refresh
79
+ instance.interceptors.response.use((response) => response, async (error) => {
80
+ const originalRequest = error.config;
81
+ // Handle 401 Unauthorized
82
+ if (error.response?.status === 401 && !originalRequest._retry) {
83
+ originalRequest._retry = true;
84
+ // Try to refresh the token
85
+ if (sdkConfig.refreshAccessToken) {
86
+ try {
87
+ const newToken = await sdkConfig.refreshAccessToken();
88
+ if (newToken && originalRequest.headers) {
89
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
90
+ return instance(originalRequest);
91
+ }
92
+ }
93
+ catch {
94
+ // Refresh failed
95
+ }
96
+ }
97
+ // Call unauthorized handler
98
+ if (sdkConfig.onUnauthorized) {
99
+ sdkConfig.onUnauthorized();
100
+ }
101
+ }
102
+ return Promise.reject(error);
103
+ });
104
+ return instance;
105
+ }
106
+ /**
107
+ * Type-safe API request helper
108
+ */
109
+ async function apiRequest(method, url, data, config) {
110
+ const client = getApiClient();
111
+ const response = await client.request({
112
+ method,
113
+ url,
114
+ data,
115
+ ...config,
116
+ });
117
+ return response.data;
118
+ }
119
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { useMutation } from '@tanstack/react-query';
2
+ import type { UseMutationOptions } from '@tanstack/react-query';
3
+ import type { LoginRequest, LoginResponse, RegisterRequest } from '../types';
4
+ type LoginMutationOptions = Omit<UseMutationOptions<LoginResponse, Error, LoginRequest, unknown>, 'mutationFn'>;
5
+ type RegisterMutationOptions = Omit<UseMutationOptions<LoginResponse, Error, RegisterRequest, unknown>, 'mutationFn'>;
6
+ type LogoutMutationOptions = Omit<UseMutationOptions<void, Error, void, unknown>, 'mutationFn'>;
7
+ /**
8
+ * Hook for login mutation
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const { mutate: login, isPending } = useLogin({
13
+ * onSuccess: (data) => {
14
+ * localStorage.setItem('accessToken', data.accessToken);
15
+ * },
16
+ * });
17
+ *
18
+ * login({ email: 'user@example.com', password: 'password' });
19
+ * ```
20
+ */
21
+ export declare function useLogin(options?: LoginMutationOptions): ReturnType<typeof useMutation<LoginResponse, Error, LoginRequest, unknown>>;
22
+ /**
23
+ * Hook for register mutation
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const { mutate: register, isPending } = useRegister({
28
+ * onSuccess: (data) => {
29
+ * localStorage.setItem('accessToken', data.accessToken);
30
+ * },
31
+ * });
32
+ *
33
+ * register({
34
+ * email: 'user@example.com',
35
+ * password: 'password',
36
+ * name: 'John Doe',
37
+ * organizationName: 'Acme Inc',
38
+ * });
39
+ * ```
40
+ */
41
+ export declare function useRegister(options?: RegisterMutationOptions): ReturnType<typeof useMutation<LoginResponse, Error, RegisterRequest, unknown>>;
42
+ /**
43
+ * Hook for logout mutation
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const { mutate: logout, isPending } = useLogout({
48
+ * onSuccess: () => {
49
+ * localStorage.removeItem('accessToken');
50
+ * window.location.href = '/login';
51
+ * },
52
+ * });
53
+ * ```
54
+ */
55
+ export declare function useLogout(options?: LogoutMutationOptions): ReturnType<typeof useMutation<void, Error, void, unknown>>;
56
+ export {};
57
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/api/mutations/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGhE,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAQ,MAAM,UAAU,CAAC;AAuBnF,KAAK,oBAAoB,GAAG,IAAI,CAC9B,kBAAkB,CAAC,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,EAC/D,YAAY,CACb,CAAC;AAEF,KAAK,uBAAuB,GAAG,IAAI,CACjC,kBAAkB,CAAC,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,EAClE,YAAY,CACb,CAAC;AAEF,KAAK,qBAAqB,GAAG,IAAI,CAC/B,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,EAC9C,YAAY,CACb,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CACtB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,UAAU,CAAC,OAAO,WAAW,CAAC,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAa7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CACzB,OAAO,CAAC,EAAE,uBAAuB,GAChC,UAAU,CAAC,OAAO,WAAW,CAAC,aAAa,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC,CAYhF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CACvB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,UAAU,CAAC,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAW5D"}
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useLogin = useLogin;
4
+ exports.useRegister = useRegister;
5
+ exports.useLogout = useLogout;
6
+ const react_query_1 = require("@tanstack/react-query");
7
+ const client_1 = require("../client");
8
+ const types_1 = require("../types");
9
+ /**
10
+ * Login mutation
11
+ */
12
+ async function login(credentials) {
13
+ return (0, client_1.apiRequest)('post', '/api/auth/login', credentials);
14
+ }
15
+ /**
16
+ * Register mutation
17
+ */
18
+ async function register(data) {
19
+ return (0, client_1.apiRequest)('post', '/api/auth/register', data);
20
+ }
21
+ /**
22
+ * Logout mutation
23
+ */
24
+ async function logout() {
25
+ return (0, client_1.apiRequest)('post', '/api/auth/logout');
26
+ }
27
+ /**
28
+ * Hook for login mutation
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const { mutate: login, isPending } = useLogin({
33
+ * onSuccess: (data) => {
34
+ * localStorage.setItem('accessToken', data.accessToken);
35
+ * },
36
+ * });
37
+ *
38
+ * login({ email: 'user@example.com', password: 'password' });
39
+ * ```
40
+ */
41
+ function useLogin(options) {
42
+ const queryClient = (0, react_query_1.useQueryClient)();
43
+ return (0, react_query_1.useMutation)({
44
+ mutationFn: login,
45
+ onSettled: (data) => {
46
+ // Update the current user in cache on success
47
+ if (data) {
48
+ queryClient.setQueryData(types_1.queryKeys.auth.me(), data.user);
49
+ }
50
+ },
51
+ ...options,
52
+ });
53
+ }
54
+ /**
55
+ * Hook for register mutation
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const { mutate: register, isPending } = useRegister({
60
+ * onSuccess: (data) => {
61
+ * localStorage.setItem('accessToken', data.accessToken);
62
+ * },
63
+ * });
64
+ *
65
+ * register({
66
+ * email: 'user@example.com',
67
+ * password: 'password',
68
+ * name: 'John Doe',
69
+ * organizationName: 'Acme Inc',
70
+ * });
71
+ * ```
72
+ */
73
+ function useRegister(options) {
74
+ const queryClient = (0, react_query_1.useQueryClient)();
75
+ return (0, react_query_1.useMutation)({
76
+ mutationFn: register,
77
+ onSettled: (data) => {
78
+ if (data) {
79
+ queryClient.setQueryData(types_1.queryKeys.auth.me(), data.user);
80
+ }
81
+ },
82
+ ...options,
83
+ });
84
+ }
85
+ /**
86
+ * Hook for logout mutation
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const { mutate: logout, isPending } = useLogout({
91
+ * onSuccess: () => {
92
+ * localStorage.removeItem('accessToken');
93
+ * window.location.href = '/login';
94
+ * },
95
+ * });
96
+ * ```
97
+ */
98
+ function useLogout(options) {
99
+ const queryClient = (0, react_query_1.useQueryClient)();
100
+ return (0, react_query_1.useMutation)({
101
+ mutationFn: logout,
102
+ onSettled: () => {
103
+ // Clear all queries
104
+ queryClient.clear();
105
+ },
106
+ ...options,
107
+ });
108
+ }
109
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/api/mutations/auth.ts"],"names":[],"mappings":";;AAwDA,4BAeC;AAqBD,kCAcC;AAeD,8BAaC;AAtID,uDAAoE;AAEpE,sCAAuC;AACvC,oCAAqC;AAGrC;;GAEG;AACH,KAAK,UAAU,KAAK,CAAC,WAAyB;IAC5C,OAAO,IAAA,mBAAU,EAAgB,MAAM,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,QAAQ,CAAC,IAAqB;IAC3C,OAAO,IAAA,mBAAU,EAAgB,MAAM,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,MAAM;IACnB,OAAO,IAAA,mBAAU,EAAO,MAAM,EAAE,kBAAkB,CAAC,CAAC;AACtD,CAAC;AAiBD;;;;;;;;;;;;;GAaG;AACH,SAAgB,QAAQ,CACtB,OAA8B;IAE9B,MAAM,WAAW,GAAG,IAAA,4BAAc,GAAE,CAAC;IAErC,OAAO,IAAA,yBAAW,EAAC;QACjB,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YAClB,8CAA8C;YAC9C,IAAI,IAAI,EAAE,CAAC;gBACT,WAAW,CAAC,YAAY,CAAO,iBAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QACD,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,WAAW,CACzB,OAAiC;IAEjC,MAAM,WAAW,GAAG,IAAA,4BAAc,GAAE,CAAC;IAErC,OAAO,IAAA,yBAAW,EAAC;QACjB,UAAU,EAAE,QAAQ;QACpB,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;YAClB,IAAI,IAAI,EAAE,CAAC;gBACT,WAAW,CAAC,YAAY,CAAO,iBAAS,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QACD,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,SAAS,CACvB,OAA+B;IAE/B,MAAM,WAAW,GAAG,IAAA,4BAAc,GAAE,CAAC;IAErC,OAAO,IAAA,yBAAW,EAAC;QACjB,UAAU,EAAE,MAAM;QAClB,SAAS,EAAE,GAAG,EAAE;YACd,oBAAoB;YACpB,WAAW,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;QACD,GAAG,OAAO;KACX,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Mutation hooks - TanStack Query mutations for POST/PUT/PATCH/DELETE operations
3
+ */
4
+ export { useLogin, useRegister, useLogout } from './auth';
5
+ export { useUpdateUser, useDeleteUser } from './users';
6
+ export { useCreateRun, useUpdateRun, useDeleteRun, useAssignDriver, useUnassignDriver, useStartRun, useCompleteRun, useOptimizeRoute, } from './runs';
7
+ export { useCreateStop, useUpdateStop, useDeleteStop, useUpdateStopStatus, useReorderStops, } from './stops';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/mutations/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,gBAAgB,GACjB,MAAM,QAAQ,CAAC;AAChB,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,eAAe,GAChB,MAAM,SAAS,CAAC"}