@spotsdev/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 (79) hide show
  1. package/dist/api/client.d.ts +12 -0
  2. package/dist/api/client.js +68 -0
  3. package/dist/api/mutations/clubs.d.ts +47 -0
  4. package/dist/api/mutations/clubs.js +95 -0
  5. package/dist/api/mutations/conversations.d.ts +45 -0
  6. package/dist/api/mutations/conversations.js +110 -0
  7. package/dist/api/mutations/index.d.ts +13 -0
  8. package/dist/api/mutations/index.js +38 -0
  9. package/dist/api/mutations/notifications.d.ts +38 -0
  10. package/dist/api/mutations/notifications.js +64 -0
  11. package/dist/api/mutations/orders.d.ts +73 -0
  12. package/dist/api/mutations/orders.js +116 -0
  13. package/dist/api/mutations/posts.d.ts +123 -0
  14. package/dist/api/mutations/posts.js +229 -0
  15. package/dist/api/mutations/products.d.ts +81 -0
  16. package/dist/api/mutations/products.js +102 -0
  17. package/dist/api/mutations/spots.d.ts +59 -0
  18. package/dist/api/mutations/spots.js +129 -0
  19. package/dist/api/mutations/users.d.ts +71 -0
  20. package/dist/api/mutations/users.js +173 -0
  21. package/dist/api/queries/auth.d.ts +37 -0
  22. package/dist/api/queries/auth.js +61 -0
  23. package/dist/api/queries/clubs.d.ts +52 -0
  24. package/dist/api/queries/clubs.js +116 -0
  25. package/dist/api/queries/conversations.d.ts +52 -0
  26. package/dist/api/queries/conversations.js +83 -0
  27. package/dist/api/queries/index.d.ts +26 -0
  28. package/dist/api/queries/index.js +65 -0
  29. package/dist/api/queries/misc.d.ts +54 -0
  30. package/dist/api/queries/misc.js +129 -0
  31. package/dist/api/queries/notifications.d.ts +34 -0
  32. package/dist/api/queries/notifications.js +62 -0
  33. package/dist/api/queries/orders.d.ts +45 -0
  34. package/dist/api/queries/orders.js +93 -0
  35. package/dist/api/queries/posts.d.ts +55 -0
  36. package/dist/api/queries/posts.js +130 -0
  37. package/dist/api/queries/products.d.ts +52 -0
  38. package/dist/api/queries/products.js +89 -0
  39. package/dist/api/queries/spots.d.ts +78 -0
  40. package/dist/api/queries/spots.js +168 -0
  41. package/dist/api/queries/templates.d.ts +42 -0
  42. package/dist/api/queries/templates.js +86 -0
  43. package/dist/api/queries/users.d.ts +90 -0
  44. package/dist/api/queries/users.js +187 -0
  45. package/dist/api/services/index.d.ts +2 -0
  46. package/dist/api/services/index.js +8 -0
  47. package/dist/api/services/marketplace.d.ts +129 -0
  48. package/dist/api/services/marketplace.js +168 -0
  49. package/dist/api/types.d.ts +54 -0
  50. package/dist/api/types.js +34 -0
  51. package/dist/index.d.ts +38 -0
  52. package/dist/index.js +73 -0
  53. package/package.json +57 -0
  54. package/src/api/client.ts +78 -0
  55. package/src/api/mutations/clubs.ts +107 -0
  56. package/src/api/mutations/conversations.ts +124 -0
  57. package/src/api/mutations/index.ts +29 -0
  58. package/src/api/mutations/notifications.ts +70 -0
  59. package/src/api/mutations/orders.ts +174 -0
  60. package/src/api/mutations/posts.ts +278 -0
  61. package/src/api/mutations/products.ts +160 -0
  62. package/src/api/mutations/spots.ts +146 -0
  63. package/src/api/mutations/users.ts +197 -0
  64. package/src/api/queries/auth.ts +67 -0
  65. package/src/api/queries/clubs.ts +135 -0
  66. package/src/api/queries/conversations.ts +94 -0
  67. package/src/api/queries/index.ts +48 -0
  68. package/src/api/queries/misc.ts +140 -0
  69. package/src/api/queries/notifications.ts +66 -0
  70. package/src/api/queries/orders.ts +119 -0
  71. package/src/api/queries/posts.ts +142 -0
  72. package/src/api/queries/products.ts +123 -0
  73. package/src/api/queries/spots.ts +201 -0
  74. package/src/api/queries/templates.ts +95 -0
  75. package/src/api/queries/users.ts +206 -0
  76. package/src/api/services/index.ts +6 -0
  77. package/src/api/services/marketplace.ts +265 -0
  78. package/src/api/types.ts +144 -0
  79. package/src/index.ts +63 -0
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Marketplace API Service
3
+ *
4
+ * Plain async functions for products and orders.
5
+ * Can be used in tests or non-React environments.
6
+ */
7
+
8
+ import { getApiClient } from '../client';
9
+ import type {
10
+ Product,
11
+ ProductType,
12
+ ProductStatus,
13
+ OrderStatus,
14
+ ApiResponse,
15
+ PaginatedResponse,
16
+ } from '../types';
17
+ import type { ProductWithSpot } from '../queries/products';
18
+ import type { OrderWithDetails } from '../queries/orders';
19
+
20
+ // Re-export for convenience
21
+ export type { ProductWithSpot, OrderWithDetails };
22
+
23
+ export interface CreateProductInput {
24
+ name: string;
25
+ description?: string;
26
+ type: ProductType;
27
+ price: number;
28
+ currency?: string;
29
+ stockQuantity?: number;
30
+ lowStockAlert?: number;
31
+ deliveryRadius?: number;
32
+ prepTimeMinutes?: number;
33
+ eventDate?: string;
34
+ imageUrl?: string;
35
+ }
36
+
37
+ export interface UpdateProductInput {
38
+ name?: string;
39
+ description?: string;
40
+ price?: number;
41
+ stockQuantity?: number;
42
+ lowStockAlert?: number;
43
+ status?: ProductStatus;
44
+ deliveryRadius?: number;
45
+ prepTimeMinutes?: number;
46
+ eventDate?: string;
47
+ imageUrl?: string;
48
+ }
49
+
50
+ export interface CreateOrderInput {
51
+ spotId: string;
52
+ items: Array<{ productId: string; quantity: number }>;
53
+ notes?: string;
54
+ }
55
+
56
+ // ============================================================================
57
+ // PRODUCTS SERVICE
58
+ // ============================================================================
59
+
60
+ export const productsService = {
61
+ /**
62
+ * List products for a spot
63
+ */
64
+ async listBySpot(
65
+ spotId: string,
66
+ params?: { type?: ProductType; status?: ProductStatus; limit?: number; page?: number }
67
+ ): Promise<PaginatedResponse<Product>> {
68
+ const client = getApiClient();
69
+ const queryParams = new URLSearchParams();
70
+ if (params?.type) queryParams.set('type', params.type);
71
+ if (params?.status) queryParams.set('status', params.status);
72
+ if (params?.limit) queryParams.set('limit', String(params.limit));
73
+ if (params?.page) queryParams.set('page', String(params.page));
74
+ const response = await client.get<ApiResponse<PaginatedResponse<Product>>>(
75
+ `/api/v1/spots/${spotId}/products?${queryParams}`
76
+ );
77
+ return response.data.data;
78
+ },
79
+
80
+ /**
81
+ * Get product by ID
82
+ */
83
+ async getById(productId: string): Promise<ProductWithSpot> {
84
+ const client = getApiClient();
85
+ const response = await client.get<ApiResponse<ProductWithSpot>>(
86
+ `/api/v1/products/${productId}`
87
+ );
88
+ return response.data.data;
89
+ },
90
+
91
+ /**
92
+ * Get product by slug
93
+ */
94
+ async getBySlug(spotId: string, slug: string): Promise<ProductWithSpot> {
95
+ const client = getApiClient();
96
+ const response = await client.get<ApiResponse<ProductWithSpot>>(
97
+ `/api/v1/spots/${spotId}/products/slug/${slug}`
98
+ );
99
+ return response.data.data;
100
+ },
101
+
102
+ /**
103
+ * Create a product (requires owner auth)
104
+ */
105
+ async create(spotId: string, data: CreateProductInput): Promise<Product> {
106
+ const client = getApiClient();
107
+ const response = await client.post<ApiResponse<Product>>(
108
+ `/api/v1/spots/${spotId}/products`,
109
+ data
110
+ );
111
+ return response.data.data;
112
+ },
113
+
114
+ /**
115
+ * Update a product (requires owner auth)
116
+ */
117
+ async update(productId: string, data: UpdateProductInput): Promise<Product> {
118
+ const client = getApiClient();
119
+ const response = await client.put<ApiResponse<Product>>(
120
+ `/api/v1/products/${productId}`,
121
+ data
122
+ );
123
+ return response.data.data;
124
+ },
125
+
126
+ /**
127
+ * Delete a product (requires owner auth)
128
+ */
129
+ async delete(productId: string): Promise<void> {
130
+ const client = getApiClient();
131
+ await client.delete(`/api/v1/products/${productId}`);
132
+ },
133
+
134
+ /**
135
+ * Adjust stock (requires owner auth)
136
+ */
137
+ async adjustStock(
138
+ productId: string,
139
+ quantity: number,
140
+ reason: 'RESTOCK' | 'ADJUSTMENT',
141
+ notes?: string
142
+ ): Promise<Product> {
143
+ const client = getApiClient();
144
+ const response = await client.post<ApiResponse<Product>>(
145
+ `/api/v1/products/${productId}/stock`,
146
+ { quantity, reason, notes }
147
+ );
148
+ return response.data.data;
149
+ },
150
+ };
151
+
152
+ // ============================================================================
153
+ // ORDERS SERVICE
154
+ // ============================================================================
155
+
156
+ export const ordersService = {
157
+ /**
158
+ * Create an order
159
+ */
160
+ async create(data: CreateOrderInput): Promise<OrderWithDetails> {
161
+ const client = getApiClient();
162
+ const response = await client.post<ApiResponse<OrderWithDetails>>(
163
+ '/api/v1/orders',
164
+ data
165
+ );
166
+ return response.data.data;
167
+ },
168
+
169
+ /**
170
+ * Get order by ID
171
+ */
172
+ async getById(orderId: string): Promise<OrderWithDetails> {
173
+ const client = getApiClient();
174
+ const response = await client.get<ApiResponse<OrderWithDetails>>(
175
+ `/api/v1/orders/${orderId}`
176
+ );
177
+ return response.data.data;
178
+ },
179
+
180
+ /**
181
+ * List my orders (as buyer)
182
+ */
183
+ async listMyOrders(
184
+ params?: { status?: OrderStatus; limit?: number; page?: number }
185
+ ): Promise<PaginatedResponse<OrderWithDetails>> {
186
+ const client = getApiClient();
187
+ const queryParams = new URLSearchParams();
188
+ if (params?.status) queryParams.set('status', params.status);
189
+ if (params?.limit) queryParams.set('limit', String(params.limit));
190
+ if (params?.page) queryParams.set('page', String(params.page));
191
+ const response = await client.get<ApiResponse<PaginatedResponse<OrderWithDetails>>>(
192
+ `/api/v1/users/me/orders?${queryParams}`
193
+ );
194
+ return response.data.data;
195
+ },
196
+
197
+ /**
198
+ * List spot orders (as seller)
199
+ */
200
+ async listSpotOrders(
201
+ spotId: string,
202
+ params?: { status?: OrderStatus; limit?: number; page?: number }
203
+ ): Promise<PaginatedResponse<OrderWithDetails>> {
204
+ const client = getApiClient();
205
+ const queryParams = new URLSearchParams();
206
+ if (params?.status) queryParams.set('status', params.status);
207
+ if (params?.limit) queryParams.set('limit', String(params.limit));
208
+ if (params?.page) queryParams.set('page', String(params.page));
209
+ const response = await client.get<ApiResponse<PaginatedResponse<OrderWithDetails>>>(
210
+ `/api/v1/seller/spots/${spotId}/orders?${queryParams}`
211
+ );
212
+ return response.data.data;
213
+ },
214
+
215
+ /**
216
+ * Update order status (as seller)
217
+ */
218
+ async updateStatus(orderId: string, status: OrderStatus): Promise<OrderWithDetails> {
219
+ const client = getApiClient();
220
+ const response = await client.put<ApiResponse<OrderWithDetails>>(
221
+ `/api/v1/orders/${orderId}/status`,
222
+ { status }
223
+ );
224
+ return response.data.data;
225
+ },
226
+
227
+ /**
228
+ * Cancel order (as buyer)
229
+ */
230
+ async cancel(orderId: string): Promise<OrderWithDetails> {
231
+ const client = getApiClient();
232
+ const response = await client.post<ApiResponse<OrderWithDetails>>(
233
+ `/api/v1/orders/${orderId}/cancel`
234
+ );
235
+ return response.data.data;
236
+ },
237
+ };
238
+
239
+ // ============================================================================
240
+ // PAYMENTS SERVICE
241
+ // ============================================================================
242
+
243
+ export const paymentsService = {
244
+ /**
245
+ * Create Stripe PaymentIntent
246
+ */
247
+ async createStripeIntent(orderId: string): Promise<{ clientSecret: string; paymentIntentId: string }> {
248
+ const client = getApiClient();
249
+ const response = await client.post<ApiResponse<{ clientSecret: string; paymentIntentId: string }>>(
250
+ `/api/v1/payments/stripe/intent/${orderId}`
251
+ );
252
+ return response.data.data;
253
+ },
254
+
255
+ /**
256
+ * Create Coinbase charge
257
+ */
258
+ async createCoinbaseCharge(orderId: string): Promise<{ chargeId: string; chargeCode: string; hostedUrl: string }> {
259
+ const client = getApiClient();
260
+ const response = await client.post<ApiResponse<{ chargeId: string; chargeCode: string; hostedUrl: string }>>(
261
+ `/api/v1/payments/coinbase/charge/${orderId}`
262
+ );
263
+ return response.data.data;
264
+ },
265
+ };
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Spots SDK Types
3
+ *
4
+ * Type sources:
5
+ * - Entity types (User, Spot, Post, etc.) → import from @prisma/client
6
+ * - DTO types (CreatePostDto, etc.) → import from @spotsdev/types
7
+ *
8
+ * This file provides type aliases for SDK convenience while maintaining
9
+ * single sources of truth:
10
+ * - Prisma schema for entities
11
+ * - OpenAPI spec for DTOs
12
+ */
13
+
14
+ // ============================================================================
15
+ // API RESPONSE TYPES
16
+ // ============================================================================
17
+
18
+ /**
19
+ * Standard API response wrapper from ResponseInterceptor
20
+ * All API responses are wrapped in this format
21
+ */
22
+ export interface ApiResponse<T> {
23
+ success: boolean;
24
+ data: T;
25
+ timestamp: string;
26
+ }
27
+
28
+ /**
29
+ * Paginated response for list endpoints
30
+ * Used inside ApiResponse.data for paginated queries
31
+ */
32
+ export interface PaginatedResponse<T> {
33
+ data: T[];
34
+ meta: {
35
+ total: number;
36
+ page: number;
37
+ limit: number;
38
+ totalPages: number;
39
+ hasNextPage: boolean;
40
+ hasPreviousPage: boolean;
41
+ };
42
+ }
43
+
44
+ // ============================================================================
45
+ // RE-EXPORTS FROM SOURCES
46
+ // ============================================================================
47
+
48
+ // Re-export all DTO types from @spotsdev/types (OpenAPI generated)
49
+ export * from '@spotsdev/types';
50
+
51
+ // Re-export entity types from @prisma/client
52
+ export type {
53
+ // Models
54
+ User,
55
+ Spot,
56
+ SpotPost,
57
+ PostReply,
58
+ PostResponse,
59
+ PostUpvote,
60
+ PostReport,
61
+ Club,
62
+ ClubMember,
63
+ Conversation,
64
+ Message,
65
+ Notification,
66
+ PostTemplate,
67
+ Vibe,
68
+ Interest,
69
+ Intention,
70
+ LifeSituation,
71
+ FavoriteSpot,
72
+ SpotImage,
73
+ SpotVibe,
74
+ SpotIntention,
75
+ SpotClaim,
76
+ SpotSubscription,
77
+ City,
78
+ // Marketplace Models
79
+ Product,
80
+ Order,
81
+ OrderItem,
82
+ Payment,
83
+ InventoryLog,
84
+ StripeConnectAccount,
85
+ // Enums
86
+ SpotType,
87
+ SpotPostType,
88
+ AccountStatus,
89
+ ClaimStatus,
90
+ ResponseStatus,
91
+ ReportReason,
92
+ ReportStatus,
93
+ NotificationType,
94
+ // Marketplace Enums
95
+ ProductType,
96
+ ProductStatus,
97
+ OrderStatus,
98
+ PaymentProvider,
99
+ PaymentStatus,
100
+ FulfillmentType,
101
+ InventoryChangeReason,
102
+ } from '@prisma/client';
103
+
104
+ // ============================================================================
105
+ // SDK TYPE ALIASES
106
+ // These provide convenient names that match SDK usage patterns
107
+ // ============================================================================
108
+
109
+ import type {
110
+ SendOtpDto,
111
+ VerifyOtpDto,
112
+ CreatePostDto,
113
+ CreateReplyDto,
114
+ CreateResponseDto,
115
+ UpdateResponseDto,
116
+ UpdateUserDto,
117
+ UpvoteResponseDto,
118
+ VerifyOtpWrappedResponseDto,
119
+ CreateConversationDto,
120
+ CreateMessageDto,
121
+ ClaimSpotDto,
122
+ } from '@spotsdev/types';
123
+
124
+ import type { SpotPost, PostTemplate } from '@prisma/client';
125
+
126
+ // Request type aliases (map to DTOs)
127
+ export type SendOtpRequest = SendOtpDto;
128
+ export type VerifyOtpRequest = VerifyOtpDto;
129
+ export type CreatePostRequest = CreatePostDto;
130
+ export type CreateReplyRequest = CreateReplyDto;
131
+ export type RespondToPostRequest = CreateResponseDto;
132
+ export type UpdateResponseRequest = UpdateResponseDto;
133
+ export type UpdateProfileRequest = UpdateUserDto;
134
+ export type CreateConversationRequest = CreateConversationDto;
135
+ export type SendMessageRequest = CreateMessageDto;
136
+ export type ClaimSpotRequest = ClaimSpotDto;
137
+
138
+ // Response type aliases
139
+ export type UpvoteResponse = UpvoteResponseDto;
140
+ export type AuthResponse = VerifyOtpWrappedResponseDto;
141
+
142
+ // Entity type aliases (for backward compatibility)
143
+ export type Post = SpotPost;
144
+ export type Template = PostTemplate;
package/src/index.ts ADDED
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Spots SDK
3
+ *
4
+ * TypeScript SDK for the Spots API with TanStack Query hooks.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { configureSDK, useCurrentUser, useSpots, useCreatePost } from '@spots/sdk';
9
+ *
10
+ * // Configure SDK with your API base URL and token management
11
+ * configureSDK({
12
+ * baseURL: 'https://spots-api-psi.vercel.app',
13
+ * getAccessToken: () => localStorage.getItem('accessToken'),
14
+ * refreshAccessToken: async () => {
15
+ * // Your token refresh logic
16
+ * return newAccessToken;
17
+ * },
18
+ * onUnauthorized: () => {
19
+ * // Handle unauthorized access
20
+ * window.location.href = '/login';
21
+ * },
22
+ * });
23
+ *
24
+ * // Use hooks in your components
25
+ * function App() {
26
+ * const { data: user } = useCurrentUser();
27
+ * const { data: spots } = useSpots();
28
+ * const { mutate: createPost } = useCreatePost();
29
+ * // ...
30
+ * }
31
+ * ```
32
+ */
33
+
34
+ // ============================================================================
35
+ // API CLIENT
36
+ // ============================================================================
37
+
38
+ export { configureSDK, getApiClient, getConfig } from './api/client';
39
+ export type { SDKConfig } from './api/client';
40
+
41
+ // ============================================================================
42
+ // TYPES
43
+ // ============================================================================
44
+
45
+ export * from './api/types';
46
+
47
+ // ============================================================================
48
+ // QUERY HOOKS
49
+ // ============================================================================
50
+
51
+ export * from './api/queries';
52
+
53
+ // ============================================================================
54
+ // MUTATION HOOKS
55
+ // ============================================================================
56
+
57
+ export * from './api/mutations';
58
+
59
+ // ============================================================================
60
+ // SERVICES (Plain async functions for testing/non-React)
61
+ // ============================================================================
62
+
63
+ export * from './api/services';