@urbackend/sdk 0.2.7 → 0.2.8

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/dist/index.d.ts CHANGED
@@ -129,161 +129,1071 @@ interface ApiResponse<T> {
129
129
  message?: string;
130
130
  }
131
131
 
132
+ /**
133
+ * Module for authentication and user management in urBackend
134
+ *
135
+ * @class AuthModule
136
+ * @description Provides complete authentication functionality including signup, login,
137
+ * profile management, password operations, email verification, social authentication,
138
+ * and session management. Manages session tokens automatically.
139
+ *
140
+ * @example
141
+ * // Initialize the auth module
142
+ * const client = new UrBackendClient({ apiKey: 'pk_live_xxx', secretKey: 'sk_live_xxx' });
143
+ * const auth = new AuthModule(client);
144
+ *
145
+ * // Sign up a new user
146
+ * const user = await auth.signUp({
147
+ * email: 'user@example.com',
148
+ * password: 'securePassword123',
149
+ * name: 'John Doe'
150
+ * });
151
+ *
152
+ * @example
153
+ * // Log in and manage session
154
+ * const session = await auth.login({
155
+ * email: 'user@example.com',
156
+ * password: 'securePassword123'
157
+ * });
158
+ * console.log('Access token:', session.accessToken);
159
+ *
160
+ * // Get current user profile
161
+ * const profile = await auth.me();
162
+ * console.log('Welcome:', profile.name);
163
+ */
132
164
  declare class AuthModule {
133
165
  private client;
134
166
  private sessionToken?;
167
+ /**
168
+ * Creates an instance of AuthModule
169
+ *
170
+ * @param {UrBackendClient} client - The urBackend client instance
171
+ *
172
+ * @example
173
+ * const client = new UrBackendClient({ apiKey: 'pk_live_xxx' });
174
+ * const auth = new AuthModule(client);
175
+ */
135
176
  constructor(client: UrBackendClient);
136
177
  /**
137
- * Create a new user account
178
+ * Creates a new user account
179
+ *
180
+ * @param {SignUpPayload} payload - User registration data
181
+ * @param {string} payload.email - User's email address
182
+ * @param {string} payload.password - User's password
183
+ * @param {string} payload.name - User's full name
184
+ * @returns {Promise<AuthUser>} Promise resolving to the created user object
185
+ *
186
+ * @throws {AuthError} If email already exists
187
+ * @throws {AuthError} If password does not meet requirements
188
+ * @throws {AuthError} If validation fails
189
+ *
190
+ * @example
191
+ * // Sign up a new user
192
+ * const user = await auth.signUp({
193
+ * email: 'john@example.com',
194
+ * password: 'StrongP@ss123',
195
+ * name: 'John Doe'
196
+ * });
197
+ * console.log('User created:', user._id);
198
+ *
199
+ * @example
200
+ * // Sign up with error handling
201
+ * try {
202
+ * const user = await auth.signUp({
203
+ * email: 'existing@email.com',
204
+ * password: 'weak',
205
+ * name: 'Test'
206
+ * });
207
+ * } catch (error) {
208
+ * if (error.message.includes('email')) {
209
+ * console.log('Email already registered');
210
+ * } else if (error.message.includes('password')) {
211
+ * console.log('Password too weak');
212
+ * }
213
+ * }
138
214
  */
139
215
  signUp(payload: SignUpPayload): Promise<AuthUser>;
140
216
  /**
141
- * Log in an existing user and store the session token
217
+ * Authenticates an existing user and stores the session token
218
+ *
219
+ * @param {LoginPayload} payload - User login credentials
220
+ * @param {string} payload.email - User's email address
221
+ * @param {string} payload.password - User's password
222
+ * @returns {Promise<AuthResponse>} Promise resolving to authentication response with tokens
223
+ *
224
+ * @throws {AuthError} If credentials are invalid
225
+ * @throws {AuthError} If account is locked or not verified
226
+ *
227
+ * @example
228
+ * // Log in a user
229
+ * const response = await auth.login({
230
+ * email: 'john@example.com',
231
+ * password: 'StrongP@ss123'
232
+ * });
233
+ * console.log('Access token:', response.accessToken);
234
+ *
235
+ * @example
236
+ * // Login with error handling
237
+ * try {
238
+ * const { accessToken, user } = await auth.login({
239
+ * email: 'user@example.com',
240
+ * password: 'wrongpassword'
241
+ * });
242
+ * } catch (error) {
243
+ * if (error.status === 401) {
244
+ * console.log('Invalid email or password');
245
+ * }
246
+ * }
142
247
  */
143
248
  login(payload: LoginPayload): Promise<AuthResponse>;
144
249
  /**
145
- * Get the current authenticated user's profile
250
+ * Retrieves the current authenticated user's profile
251
+ *
252
+ * @param {string} [token] - Optional authentication token (overrides stored token)
253
+ * @returns {Promise<AuthUser>} Promise resolving to the authenticated user's profile
254
+ *
255
+ * @throws {AuthError} If no authentication token is provided
256
+ * @throws {AuthError} If token is invalid or expired
257
+ *
258
+ * @example
259
+ * // Get current user profile (uses stored token from login)
260
+ * const user = await auth.me();
261
+ * console.log(`Hello ${user.name}, your email is ${user.email}`);
262
+ *
263
+ * @example
264
+ * // Get profile with custom token
265
+ * const user = await auth.me(customToken);
266
+ *
267
+ * @example
268
+ * // Get profile with error handling
269
+ * try {
270
+ * const user = await auth.me();
271
+ * console.log('Authenticated as:', user.email);
272
+ * } catch (error) {
273
+ * if (error.status === 401) {
274
+ * console.log('Please log in again');
275
+ * }
276
+ * }
146
277
  */
147
278
  me(token?: string): Promise<AuthUser>;
148
279
  /**
149
- * Update the current authenticated user's profile
280
+ * Updates the current authenticated user's profile
281
+ *
282
+ * @param {UpdateProfilePayload} payload - Profile data to update
283
+ * @param {string} [payload.name] - Updated name
284
+ * @param {string} [payload.email] - Updated email (may require re-verification)
285
+ * @param {string} [token] - Optional authentication token (overrides stored token)
286
+ * @returns {Promise<{ message: string }>} Promise resolving to success message
287
+ *
288
+ * @throws {AuthError} If no authentication token is provided
289
+ * @throws {AuthError} If token is invalid or expired
290
+ * @throws {AuthError} If email is already taken
291
+ *
292
+ * @example
293
+ * // Update user's name
294
+ * const result = await auth.updateProfile({ name: 'Jane Smith' });
295
+ * console.log(result.message);
296
+ *
297
+ * @example
298
+ * // Update multiple fields
299
+ * const result = await auth.updateProfile({
300
+ * name: 'Jane Doe',
301
+ * email: 'jane@newemail.com'
302
+ * });
303
+ *
304
+ * @example
305
+ * // Update with error handling
306
+ * try {
307
+ * await auth.updateProfile({ email: 'taken@email.com' });
308
+ * } catch (error) {
309
+ * console.log('Email already in use');
310
+ * }
150
311
  */
151
312
  updateProfile(payload: UpdateProfilePayload, token?: string): Promise<{
152
313
  message: string;
153
314
  }>;
154
315
  /**
155
- * Change the current authenticated user's password
316
+ * Changes the current authenticated user's password
317
+ *
318
+ * @param {ChangePasswordPayload} payload - Password change data
319
+ * @param {string} payload.currentPassword - User's current password
320
+ * @param {string} payload.newPassword - Desired new password
321
+ * @param {string} [token] - Optional authentication token (overrides stored token)
322
+ * @returns {Promise<{ message: string }>} Promise resolving to success message
323
+ *
324
+ * @throws {AuthError} If no authentication token is provided
325
+ * @throws {AuthError} If current password is incorrect
326
+ * @throws {AuthError} If new password does not meet requirements
327
+ *
328
+ * @example
329
+ * // Change password
330
+ * const result = await auth.changePassword({
331
+ * currentPassword: 'oldPassword123',
332
+ * newPassword: 'newStrongP@ss456'
333
+ * });
334
+ * console.log(result.message);
335
+ *
336
+ * @example
337
+ * // Change password with error handling
338
+ * try {
339
+ * await auth.changePassword({
340
+ * currentPassword: 'wrong',
341
+ * newPassword: 'newPassword123'
342
+ * });
343
+ * } catch (error) {
344
+ * if (error.message.includes('current password')) {
345
+ * console.log('Current password is incorrect');
346
+ * }
347
+ * }
156
348
  */
157
349
  changePassword(payload: ChangePasswordPayload, token?: string): Promise<{
158
350
  message: string;
159
351
  }>;
160
352
  /**
161
- * Verify user email with OTP
353
+ * Verifies user's email address using OTP
354
+ *
355
+ * @param {VerifyEmailPayload} payload - Email verification data
356
+ * @param {string} payload.email - User's email address
357
+ * @param {string} payload.otp - One-time password sent to email
358
+ * @returns {Promise<{ message: string }>} Promise resolving to success message
359
+ *
360
+ * @throws {AuthError} If OTP is invalid or expired
361
+ * @throws {AuthError} If email is not found
362
+ *
363
+ * @example
364
+ * // Verify email with OTP
365
+ * const result = await auth.verifyEmail({
366
+ * email: 'user@example.com',
367
+ * otp: '123456'
368
+ * });
369
+ * console.log('Email verified:', result.message);
370
+ *
371
+ * @example
372
+ * // Verify with error handling
373
+ * try {
374
+ * await auth.verifyEmail({ email: 'user@example.com', otp: '000000' });
375
+ * } catch (error) {
376
+ * console.log('Invalid OTP. Please try again.');
377
+ * }
162
378
  */
163
379
  verifyEmail(payload: VerifyEmailPayload): Promise<{
164
380
  message: string;
165
381
  }>;
166
382
  /**
167
- * Resend verification OTP
383
+ * Resends verification OTP to user's email
384
+ *
385
+ * @param {ResendOtpPayload} payload - Resend OTP request data
386
+ * @param {string} payload.email - User's email address
387
+ * @returns {Promise<{ message: string }>} Promise resolving to success message
388
+ *
389
+ * @throws {AuthError} If email is not found
390
+ * @throws {AuthError} If too many attempts
391
+ *
392
+ * @example
393
+ * // Resend verification OTP
394
+ * const result = await auth.resendVerificationOtp({
395
+ * email: 'user@example.com'
396
+ * });
397
+ * console.log('OTP resent:', result.message);
168
398
  */
169
399
  resendVerificationOtp(payload: ResendOtpPayload): Promise<{
170
400
  message: string;
171
401
  }>;
172
402
  /**
173
- * Request password reset OTP
403
+ * Requests a password reset OTP to be sent to user's email
404
+ *
405
+ * @param {RequestPasswordResetPayload} payload - Password reset request data
406
+ * @param {string} payload.email - User's email address
407
+ * @returns {Promise<{ message: string }>} Promise resolving to success message
408
+ *
409
+ * @throws {AuthError} If email is not found
410
+ * @throws {AuthError} If too many attempts
411
+ *
412
+ * @example
413
+ * // Request password reset
414
+ * const result = await auth.requestPasswordReset({
415
+ * email: 'user@example.com'
416
+ * });
417
+ * console.log('Reset OTP sent:', result.message);
174
418
  */
175
419
  requestPasswordReset(payload: RequestPasswordResetPayload): Promise<{
176
420
  message: string;
177
421
  }>;
178
422
  /**
179
- * Reset user password with OTP
423
+ * Resets user's password using OTP
424
+ *
425
+ * @param {ResetPasswordPayload} payload - Password reset data
426
+ * @param {string} payload.email - User's email address
427
+ * @param {string} payload.otp - One-time password sent via email
428
+ * @param {string} payload.newPassword - Desired new password
429
+ * @returns {Promise<{ message: string }>} Promise resolving to success message
430
+ *
431
+ * @throws {AuthError} If OTP is invalid or expired
432
+ * @throws {AuthError} If email is not found
433
+ * @throws {AuthError} If new password does not meet requirements
434
+ *
435
+ * @example
436
+ * // Reset password with OTP
437
+ * const result = await auth.resetPassword({
438
+ * email: 'user@example.com',
439
+ * otp: '123456',
440
+ * newPassword: 'NewStrongP@ss789'
441
+ * });
442
+ * console.log('Password reset:', result.message);
443
+ *
444
+ * @example
445
+ * // Reset password with error handling
446
+ * try {
447
+ * await auth.resetPassword({
448
+ * email: 'user@example.com',
449
+ * otp: 'wrong',
450
+ * newPassword: 'newPass123'
451
+ * });
452
+ * } catch (error) {
453
+ * console.log('Invalid OTP. Please request a new one.');
454
+ * }
180
455
  */
181
456
  resetPassword(payload: ResetPasswordPayload): Promise<{
182
457
  message: string;
183
458
  }>;
184
459
  /**
185
- * Get public-safe profile by username
460
+ * Retrieves a public-safe user profile by username
461
+ *
462
+ * @param {string} username - Username of the user to fetch
463
+ * @returns {Promise<AuthUser>} Promise resolving to public user profile (sensitive fields omitted)
464
+ *
465
+ * @throws {AuthError} If user with given username does not exist
466
+ *
467
+ * @example
468
+ * // Get public profile
469
+ * const profile = await auth.publicProfile('john_doe');
470
+ * console.log(`${profile.name} joined on ${profile.createdAt}`);
471
+ *
472
+ * @example
473
+ * // Display user profile on a public page
474
+ * try {
475
+ * const user = await auth.publicProfile('username');
476
+ * // Show user info (no email or private data)
477
+ * } catch (error) {
478
+ * console.log('User not found');
479
+ * }
186
480
  */
187
481
  publicProfile(username: string): Promise<AuthUser>;
188
482
  /**
189
- * Refresh the access token
190
- * @param refreshToken Optional refresh token for header mode. If omitted, uses cookie mode.
483
+ * Refreshes the access token using refresh token or cookie
484
+ *
485
+ * @param {string} [refreshToken] - Optional refresh token for header mode. If omitted, uses cookie mode.
486
+ * @returns {Promise<AuthResponse>} Promise resolving to new authentication response with fresh tokens
487
+ *
488
+ * @throws {AuthError} If refresh token is invalid or expired
489
+ *
490
+ * @example
491
+ * // Refresh token using cookie (if configured)
492
+ * const newTokens = await auth.refreshToken();
493
+ * console.log('New access token:', newTokens.accessToken);
494
+ *
495
+ * @example
496
+ * // Refresh token using explicit refresh token
497
+ * const newTokens = await auth.refreshToken(storedRefreshToken);
498
+ *
499
+ * @example
500
+ * // Auto-refresh before API calls
501
+ * try {
502
+ * await auth.me();
503
+ * } catch (error) {
504
+ * if (error.status === 401) {
505
+ * await auth.refreshToken();
506
+ * // Retry the original request
507
+ * }
508
+ * }
191
509
  */
192
510
  refreshToken(refreshToken?: string): Promise<AuthResponse>;
193
511
  /**
194
- * Returns the start URL for social authentication.
195
- * Redirect the user's browser to this URL to begin the flow.
512
+ * Returns the start URL for social authentication
513
+ *
514
+ * @param {('github' | 'google')} provider - The social authentication provider
515
+ * @returns {string} URL to redirect the user's browser to begin the OAuth flow
516
+ *
517
+ * @example
518
+ * // Redirect user to social login page
519
+ * const githubUrl = auth.socialStart('github');
520
+ * window.location.href = githubUrl;
521
+ *
522
+ * @example
523
+ * // For Node.js backend
524
+ * const googleUrl = auth.socialStart('google');
525
+ * res.redirect(googleUrl);
196
526
  */
197
527
  socialStart(provider: 'github' | 'google'): string;
198
528
  /**
199
- * Exchange social auth rtCode for a refresh token
529
+ * Exchanges social authentication rtCode for a refresh token
530
+ *
531
+ * @param {SocialExchangePayload} payload - Social exchange data
532
+ * @param {string} payload.rtCode - Return code from social provider
533
+ * @param {string} payload.provider - Social provider ('github' or 'google')
534
+ * @returns {Promise<SocialExchangeResponse>} Promise resolving to authentication response
535
+ *
536
+ * @throws {AuthError} If rtCode is invalid or expired
537
+ * @throws {AuthError} If social provider fails
538
+ *
539
+ * @example
540
+ * // After user returns from social login
541
+ * const rtCode = new URLSearchParams(window.location.search).get('rtCode');
542
+ * if (rtCode) {
543
+ * const response = await auth.socialExchange({
544
+ * rtCode: rtCode,
545
+ * provider: 'github'
546
+ * });
547
+ * console.log('Social login successful:', response.accessToken);
548
+ * }
200
549
  */
201
550
  socialExchange(payload: SocialExchangePayload): Promise<SocialExchangeResponse>;
202
551
  /**
203
- * Revoke the current session and clear local state
552
+ * Revokes the current session and clears local state
553
+ *
554
+ * @param {string} [token] - Optional authentication token (overrides stored token)
555
+ * @returns {Promise<{ success: boolean; message: string }>} Promise resolving to logout status
556
+ *
557
+ * @example
558
+ * // Log out current user
559
+ * const result = await auth.logout();
560
+ * console.log(result.message);
561
+ * // User is now logged out, session token is cleared
562
+ *
563
+ * @example
564
+ * // Log out with custom token
565
+ * const result = await auth.logout(customToken);
566
+ *
567
+ * @example
568
+ * // Logout after API calls
569
+ * try {
570
+ * await auth.logout();
571
+ * // Redirect to login page
572
+ * window.location.href = '/login';
573
+ * } catch (error) {
574
+ * console.log('Logout failed, but local session cleared');
575
+ * }
204
576
  */
205
577
  logout(token?: string): Promise<{
206
578
  success: boolean;
207
579
  message: string;
208
580
  }>;
209
581
  /**
210
- * Manually set the session token (e.g. after social auth exchange)
582
+ * Manually sets the session token (e.g., after social authentication exchange)
583
+ *
584
+ * @param {string} token - The session/access token to store
585
+ *
586
+ * @example
587
+ * // After successful social exchange
588
+ * const response = await auth.socialExchange({ rtCode, provider: 'github' });
589
+ * auth.setToken(response.accessToken);
590
+ *
591
+ * @example
592
+ * // Restore session from localStorage
593
+ * const savedToken = localStorage.getItem('authToken');
594
+ * if (savedToken) {
595
+ * auth.setToken(savedToken);
596
+ * const user = await auth.me();
597
+ * }
211
598
  */
212
599
  setToken(token: string): void;
213
600
  /**
214
- * Get the current stored session token
601
+ * Gets the current stored session token
602
+ *
603
+ * @returns {string | undefined} The current session token, if any
604
+ *
605
+ * @example
606
+ * // Get token for custom API calls
607
+ * const token = auth.getToken();
608
+ * if (token) {
609
+ * // Use token in custom API request
610
+ * fetch('/api/custom', { headers: { Authorization: `Bearer ${token}` } });
611
+ * }
612
+ *
613
+ * @example
614
+ * // Save token to localStorage for persistence
615
+ * const token = auth.getToken();
616
+ * if (token) {
617
+ * localStorage.setItem('authToken', token);
618
+ * }
215
619
  */
216
620
  getToken(): string | undefined;
217
621
  }
218
622
 
623
+ /**
624
+ * Module for database operations in urBackend
625
+ *
626
+ * @class DatabaseModule
627
+ * @description Provides CRUD (Create, Read, Update, Delete) operations for collections.
628
+ * Supports filtering, pagination, sorting, population, and expansion of related data.
629
+ *
630
+ * @example
631
+ * // Initialize the database module
632
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
633
+ * const db = new DatabaseModule(client);
634
+ *
635
+ * // Get all users
636
+ * const users = await db.getAll('users');
637
+ * console.log(users);
638
+ *
639
+ * @example
640
+ * // Insert a new document
641
+ * const newUser = await db.insert('users', {
642
+ * name: 'John Doe',
643
+ * email: 'john@example.com'
644
+ * });
645
+ * console.log('Created:', newUser._id);
646
+ */
219
647
  declare class DatabaseModule {
220
648
  private client;
649
+ /**
650
+ * Creates an instance of DatabaseModule
651
+ *
652
+ * @param {UrBackendClient} client - The authenticated urBackend client instance
653
+ *
654
+ * @example
655
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
656
+ * const db = new DatabaseModule(client);
657
+ */
221
658
  constructor(client: UrBackendClient);
222
659
  /**
223
- * Fetch all documents from a collection with optional query parameters
660
+ * Fetches all documents from a collection with optional query parameters
661
+ *
662
+ * @template T - The document type (extends DocumentData)
663
+ * @param {string} collection - Name of the collection to query
664
+ * @param {QueryParams} [params={}] - Optional query parameters for filtering, sorting, pagination
665
+ * @returns {Promise<T[]>} Promise resolving to an array of documents (empty array if none found)
666
+ *
667
+ * @throws {Error} If collection name is invalid
668
+ * @throws {Error} If authentication fails
669
+ * @throws {Error} If query parameters are malformed
670
+ *
671
+ * @example
672
+ * // Get all users
673
+ * const users = await db.getAll('users');
674
+ *
675
+ * @example
676
+ * // Get users with filters and pagination
677
+ * const activeUsers = await db.getAll('users', {
678
+ * filter: { status: 'active' },
679
+ * limit: 10,
680
+ * skip: 0,
681
+ * sort: '-createdAt'
682
+ * });
683
+ *
684
+ * @example
685
+ * // Get users with populated relations
686
+ * const usersWithPosts = await db.getAll('users', {
687
+ * populate: ['posts'],
688
+ * expand: ['profile']
689
+ * });
224
690
  */
225
691
  getAll<T extends DocumentData>(collection: string, params?: QueryParams): Promise<T[]>;
226
692
  /**
227
- * Fetch a single document by its ID
693
+ * Counts documents in a collection with optional filters
694
+ *
695
+ * @param {string} collection - Name of the collection to count
696
+ * @param {Omit<QueryParams, 'count'>} [params={}] - Optional filter parameters
697
+ * @returns {Promise<number>} Promise resolving to the total count of matching documents
698
+ *
699
+ * @throws {Error} If collection name is invalid
700
+ * @throws {Error} If authentication fails
701
+ *
702
+ * @example
703
+ * // Count all users
704
+ * const totalUsers = await db.count('users');
705
+ * console.log(`Total users: ${totalUsers}`);
706
+ *
707
+ * @example
708
+ * // Count users with filter
709
+ * const activeUsers = await db.count('users', {
710
+ * filter: { status: 'active' }
711
+ * });
712
+ *
713
+ * @example
714
+ * // Count for pagination
715
+ * const total = await db.count('products', {
716
+ * filter: { category: 'electronics' }
717
+ * });
718
+ * const totalPages = Math.ceil(total / 10);
719
+ */
720
+ count(collection: string, params?: Omit<QueryParams, 'count'>): Promise<number>;
721
+ /**
722
+ * Fetches a single document by its ID
723
+ *
724
+ * @template T - The document type (extends DocumentData)
725
+ * @param {string} collection - Name of the collection
726
+ * @param {string} id - Unique identifier of the document
727
+ * @param {Object} [options={}] - Optional parameters
728
+ * @param {string|string[]} [options.populate] - Fields to populate with related data
729
+ * @param {string|string[]} [options.expand] - Fields to expand with nested data
730
+ * @returns {Promise<T>} Promise resolving to the document
731
+ *
732
+ * @throws {NotFoundError} If document with given ID does not exist
733
+ * @throws {Error} If collection name or ID is invalid
734
+ * @throws {Error} If authentication fails
735
+ *
736
+ * @example
737
+ * // Get user by ID
738
+ * const user = await db.getOne('users', 'user_123');
739
+ * console.log(user.name);
740
+ *
741
+ * @example
742
+ * // Get user with populated posts
743
+ * const userWithPosts = await db.getOne('users', 'user_123', {
744
+ * populate: ['posts', 'comments']
745
+ * });
746
+ *
747
+ * @example
748
+ * // Get with error handling
749
+ * try {
750
+ * const user = await db.getOne('users', 'non_existent_id');
751
+ * } catch (error) {
752
+ * if (error instanceof NotFoundError) {
753
+ * console.log('User not found');
754
+ * }
755
+ * }
228
756
  */
229
757
  getOne<T extends DocumentData>(collection: string, id: string, options?: {
230
758
  populate?: string | string[];
231
759
  expand?: string | string[];
232
760
  }): Promise<T>;
233
761
  /**
234
- * Insert a new document into a collection
762
+ * Inserts a new document into a collection
763
+ *
764
+ * @template T - The document type (extends DocumentData)
765
+ * @param {string} collection - Name of the collection
766
+ * @param {InsertPayload} data - Document data to insert
767
+ * @param {string} [token] - Optional authentication token (overrides client default)
768
+ * @returns {Promise<T>} Promise resolving to the created document with generated ID
769
+ *
770
+ * @throws {Error} If collection name is invalid
771
+ * @throws {Error} If data validation fails
772
+ * @throws {Error} If authentication fails
773
+ * @throws {Error} If unique constraint violation occurs
774
+ *
775
+ * @example
776
+ * // Insert a new user
777
+ * const newUser = await db.insert('users', {
778
+ * name: 'John Doe',
779
+ * email: 'john@example.com',
780
+ * age: 25
781
+ * });
782
+ * console.log('User created:', newUser._id);
783
+ *
784
+ * @example
785
+ * // Insert with custom token
786
+ * const result = await db.insert('posts', {
787
+ * title: 'My Post',
788
+ * content: 'Hello World'
789
+ * }, customAuthToken);
790
+ *
791
+ * @example
792
+ * // Insert with error handling
793
+ * try {
794
+ * const user = await db.insert('users', { email: 'existing@email.com' });
795
+ * } catch (error) {
796
+ * if (error.message.includes('duplicate')) {
797
+ * console.log('Email already exists');
798
+ * }
799
+ * }
235
800
  */
236
801
  insert<T extends DocumentData>(collection: string, data: InsertPayload, token?: string): Promise<T>;
237
802
  /**
238
- * Update an existing document by its ID (Full replacement)
803
+ * Updates an existing document by its ID (full replacement)
804
+ *
805
+ * @template T - The document type (extends DocumentData)
806
+ * @param {string} collection - Name of the collection
807
+ * @param {string} id - Unique identifier of the document
808
+ * @param {UpdatePayload} data - Complete document data for replacement
809
+ * @param {string} [token] - Optional authentication token (overrides client default)
810
+ * @returns {Promise<T>} Promise resolving to the updated document
811
+ *
812
+ * @throws {NotFoundError} If document with given ID does not exist
813
+ * @throws {Error} If collection name or ID is invalid
814
+ * @throws {Error} If data validation fails
815
+ * @throws {Error} If authentication fails
816
+ *
817
+ * @example
818
+ * // Full update of a user
819
+ * const updatedUser = await db.update('users', 'user_123', {
820
+ * name: 'Jane Doe',
821
+ * email: 'jane@example.com',
822
+ * age: 26
823
+ * });
824
+ *
825
+ * @example
826
+ * // Update with error handling
827
+ * try {
828
+ * const result = await db.update('users', 'user_123', updatedData);
829
+ * console.log('Update successful:', result);
830
+ * } catch (error) {
831
+ * if (error instanceof NotFoundError) {
832
+ * console.log('User not found');
833
+ * }
834
+ * }
239
835
  */
240
836
  update<T extends DocumentData>(collection: string, id: string, data: UpdatePayload, token?: string): Promise<T>;
241
837
  /**
242
- * Partially update an existing document by its ID
838
+ * Partially updates an existing document by its ID (only provided fields)
839
+ *
840
+ * @template T - The document type (extends DocumentData)
841
+ * @param {string} collection - Name of the collection
842
+ * @param {string} id - Unique identifier of the document
843
+ * @param {PatchPayload} data - Partial data to update
844
+ * @param {string} [token] - Optional authentication token (overrides client default)
845
+ * @returns {Promise<T>} Promise resolving to the updated document
846
+ *
847
+ * @throws {NotFoundError} If document with given ID does not exist
848
+ * @throws {Error} If collection name or ID is invalid
849
+ * @throws {Error} If data validation fails
850
+ * @throws {Error} If authentication fails
851
+ *
852
+ * @example
853
+ * // Partial update - only update age
854
+ * const updatedUser = await db.patch('users', 'user_123', {
855
+ * age: 26
856
+ * });
857
+ *
858
+ * @example
859
+ * // Add a new field to document
860
+ * const result = await db.patch('users', 'user_123', {
861
+ * lastLogin: new Date().toISOString()
862
+ * });
863
+ *
864
+ * @example
865
+ * // Partial update with error handling
866
+ * try {
867
+ * const result = await db.patch('products', 'prod_123', {
868
+ * price: 29.99
869
+ * });
870
+ * console.log('Price updated:', result);
871
+ * } catch (error) {
872
+ * console.error('Update failed:', error.message);
873
+ * }
243
874
  */
244
875
  patch<T extends DocumentData>(collection: string, id: string, data: PatchPayload, token?: string): Promise<T>;
245
876
  /**
246
- * Delete a document by its ID
877
+ * Deletes a document by its ID
878
+ *
879
+ * @param {string} collection - Name of the collection
880
+ * @param {string} id - Unique identifier of the document to delete
881
+ * @param {string} [token] - Optional authentication token (overrides client default)
882
+ * @returns {Promise<{ deleted: boolean }>} Promise resolving to deletion status
883
+ *
884
+ * @throws {Error} If collection name or ID is invalid
885
+ * @throws {Error} If authentication fails
886
+ * @throws {Error} If user lacks permission to delete
887
+ *
888
+ * @example
889
+ * // Delete a user
890
+ * const result = await db.delete('users', 'user_123');
891
+ * if (result.deleted) {
892
+ * console.log('User deleted successfully');
893
+ * }
894
+ *
895
+ * @example
896
+ * // Delete with error handling
897
+ * try {
898
+ * const { deleted } = await db.delete('posts', 'post_456');
899
+ * if (deleted) {
900
+ * console.log('Post removed');
901
+ * }
902
+ * } catch (error) {
903
+ * console.error('Deletion failed:', error.message);
904
+ * }
905
+ *
906
+ * @example
907
+ * // Delete after checking existence
908
+ * const exists = await db.getOne('users', 'user_123').catch(() => null);
909
+ * if (exists) {
910
+ * await db.delete('users', 'user_123');
911
+ * console.log('User deleted');
912
+ * }
247
913
  */
248
914
  delete(collection: string, id: string, token?: string): Promise<{
249
915
  deleted: boolean;
250
916
  }>;
251
917
  /**
252
918
  * Internal helper to build query string from QueryParams
919
+ *
920
+ * @param {QueryParams} params - Query parameters to convert
921
+ * @returns {string} URL query string (starting with '?' if parameters exist, otherwise empty)
922
+ *
923
+ * @internal
924
+ * @private
925
+ *
926
+ * @example
927
+ * // Returns "?limit=10&sort=-createdAt"
928
+ * buildQueryString({ limit: 10, sort: '-createdAt' })
929
+ *
930
+ * @example
931
+ * // Returns "?status=active&age=25"
932
+ * buildQueryString({ filter: { status: 'active', age: 25 } })
253
933
  */
254
934
  private buildQueryString;
255
935
  }
256
936
 
937
+ /**
938
+ * Module for handling file storage operations in urBackend
939
+ *
940
+ * @class StorageModule
941
+ * @description Provides methods to upload and delete files in the urBackend storage system.
942
+ * Supports both browser (File/Blob) and Node.js (Buffer) environments.
943
+ *
944
+ * @example
945
+ * // Initialize the storage module
946
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
947
+ * const storage = new StorageModule(client);
948
+ *
949
+ * // Upload a file (Browser)
950
+ * const fileInput = document.getElementById('fileInput');
951
+ * const result = await storage.upload(fileInput.files[0], 'my-file.pdf');
952
+ * console.log(result.url);
953
+ *
954
+ * @example
955
+ * // Upload a file (Node.js)
956
+ * const fs = require('fs');
957
+ * const buffer = fs.readFileSync('./document.pdf');
958
+ * const result = await storage.upload(buffer, 'document.pdf');
959
+ */
257
960
  declare class StorageModule {
258
961
  private client;
962
+ /**
963
+ * Creates an instance of StorageModule
964
+ *
965
+ * @param {UrBackendClient} client - The authenticated urBackend client instance
966
+ *
967
+ * @example
968
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
969
+ * const storage = new StorageModule(client);
970
+ */
259
971
  constructor(client: UrBackendClient);
260
972
  /**
261
- * Upload a file to storage
973
+ * Uploads a file to the urBackend storage
974
+ *
975
+ * @param {unknown} file - The file to upload. Supports:
976
+ * - Browser: File, Blob
977
+ * - Node.js: Buffer
978
+ * @param {string} [filename] - Optional custom filename for the uploaded file
979
+ * @returns {Promise<UploadResponse>} Promise resolving to upload details including URL and file ID
980
+ *
981
+ * @throws {Error} If file is invalid or missing
982
+ * @throws {Error} If file size exceeds limits
983
+ * @throws {Error} If authentication fails
984
+ * @throws {Error} If storage quota is exceeded
985
+ *
986
+ * @example
987
+ * // Browser: Upload from file input
988
+ * const fileInput = document.querySelector('input[type="file"]');
989
+ * const file = fileInput.files[0];
990
+ * const result = await storage.upload(file, 'custom-name.pdf');
991
+ * console.log('File URL:', result.url);
992
+ *
993
+ * @example
994
+ * // Node.js: Upload Buffer
995
+ * const fs = require('fs');
996
+ * const buffer = fs.readFileSync('./image.png');
997
+ * const result = await storage.upload(buffer, 'image.png');
998
+ * console.log('Uploaded:', result.fileId);
999
+ *
1000
+ * @example
1001
+ * // Upload without custom filename (uses original name)
1002
+ * const result = await storage.upload(file);
1003
+ *
1004
+ * @example
1005
+ * // Upload with error handling
1006
+ * try {
1007
+ * const result = await storage.upload(file, 'document.pdf');
1008
+ * console.log('Upload successful:', result.url);
1009
+ * } catch (error) {
1010
+ * console.error('Upload failed:', error.message);
1011
+ * // Handle error: retry, show user message, etc.
1012
+ * }
262
1013
  */
263
1014
  upload(file: unknown, filename?: string): Promise<UploadResponse>;
264
1015
  /**
265
- * Delete a file from storage by its path
1016
+ * Deletes a file from storage by its path
1017
+ *
1018
+ * @param {string} path - The file path or URL of the file to delete
1019
+ * @returns {Promise<{ deleted: boolean }>} Promise resolving to deletion status
1020
+ *
1021
+ * @throws {Error} If path is empty or invalid
1022
+ * @throws {Error} If file does not exist
1023
+ * @throws {Error} If authentication fails
1024
+ * @throws {Error} If user lacks permission to delete the file
1025
+ *
1026
+ * @example
1027
+ * // Delete a file by path
1028
+ * const result = await storage.deleteFile('uploads/document.pdf');
1029
+ * if (result.deleted) {
1030
+ * console.log('File deleted successfully');
1031
+ * }
1032
+ *
1033
+ * @example
1034
+ * // Delete with error handling
1035
+ * try {
1036
+ * const result = await storage.deleteFile('uploads/old-file.jpg');
1037
+ * console.log('Deleted:', result.deleted);
1038
+ * } catch (error) {
1039
+ * console.error('Deletion failed:', error.message);
1040
+ * }
1041
+ *
1042
+ * @example
1043
+ * // Delete after upload
1044
+ * const uploadResult = await storage.upload(file, 'temp-file.pdf');
1045
+ * console.log('Uploaded:', uploadResult.url);
1046
+ *
1047
+ * // Later, delete the file
1048
+ * await storage.deleteFile('temp-file.pdf');
1049
+ * console.log('File cleaned up');
266
1050
  */
267
1051
  deleteFile(path: string): Promise<{
268
1052
  deleted: boolean;
269
1053
  }>;
270
1054
  }
271
1055
 
1056
+ /**
1057
+ * Module for managing database schemas in urBackend
1058
+ *
1059
+ * @class SchemaModule
1060
+ * @description Provides methods to fetch and manage collection schema definitions.
1061
+ * Schemas define the structure, validation rules, and data types for collections.
1062
+ *
1063
+ * @example
1064
+ * // Initialize the schema module
1065
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
1066
+ * const schema = new SchemaModule(client);
1067
+ *
1068
+ * // Get schema for a collection
1069
+ * const collectionSchema = await schema.getSchema('users');
1070
+ * console.log(collectionSchema.fields);
1071
+ */
272
1072
  declare class SchemaModule {
273
1073
  private client;
1074
+ /**
1075
+ * Creates an instance of SchemaModule
1076
+ *
1077
+ * @param {UrBackendClient} client - The authenticated urBackend client instance
1078
+ *
1079
+ * @example
1080
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
1081
+ * const schema = new SchemaModule(client);
1082
+ */
274
1083
  constructor(client: UrBackendClient);
275
1084
  /**
276
- * Fetch the schema definition for a collection
1085
+ * Fetches the schema definition for a specific collection
1086
+ *
1087
+ * @param {string} collection - Name of the collection to fetch schema for
1088
+ * @returns {Promise<CollectionSchema>} Promise resolving to the collection schema definition
1089
+ *
1090
+ * @throws {Error} If collection name is empty or contains only whitespace
1091
+ * @throws {Error} If collection does not exist
1092
+ * @throws {Error} If authentication fails
1093
+ *
1094
+ * @example
1095
+ * // Get schema for users collection
1096
+ * const userSchema = await schema.getSchema('users');
1097
+ * console.log(userSchema.fields);
1098
+ *
1099
+ * @example
1100
+ * // Get schema for products collection with error handling
1101
+ * try {
1102
+ * const productSchema = await schema.getSchema('products');
1103
+ * console.log('Schema fields:', Object.keys(productSchema.fields));
1104
+ * } catch (error) {
1105
+ * console.error('Failed to fetch schema:', error.message);
1106
+ * }
1107
+ *
1108
+ * @example
1109
+ * // Validate collection name before fetching
1110
+ * const collectionName = 'my_collection';
1111
+ * if (collectionName.trim()) {
1112
+ * const schemaDef = await schema.getSchema(collectionName);
1113
+ * // Use schema definition
1114
+ * }
277
1115
  */
278
1116
  getSchema(collection: string): Promise<CollectionSchema>;
279
1117
  }
280
1118
 
1119
+ /**
1120
+ * Module for handling email operations in urBackend
1121
+ *
1122
+ * @class MailModule
1123
+ * @description Provides methods to send emails using the urBackend mail service.
1124
+ * Requires a Secret Key (sk_live_...) and should be called from a server environment.
1125
+ *
1126
+ * @example
1127
+ * // Initialize the mail module
1128
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
1129
+ * const mail = new MailModule(client);
1130
+ *
1131
+ * // Send an email
1132
+ * const result = await mail.send({
1133
+ * to: 'user@example.com',
1134
+ * subject: 'Welcome!',
1135
+ * html: '<h1>Hello World</h1>'
1136
+ * });
1137
+ */
281
1138
  declare class MailModule {
282
1139
  private client;
1140
+ /**
1141
+ * Creates an instance of MailModule
1142
+ *
1143
+ * @param {UrBackendClient} client - The authenticated urBackend client instance
1144
+ *
1145
+ * @example
1146
+ * const client = new UrBackendClient({ secretKey: 'sk_live_xxx' });
1147
+ * const mail = new MailModule(client);
1148
+ */
283
1149
  constructor(client: UrBackendClient);
284
1150
  /**
285
- * Send an email using the urBackend mail service.
286
- * Note: This requires a Secret Key (sk_live_...) and should be called from a server environment.
1151
+ * Sends an email using the urBackend mail service
1152
+ *
1153
+ * @param {SendMailPayload} payload - The email content and configuration
1154
+ * @param {string} payload.to - Recipient email address
1155
+ * @param {string} payload.subject - Email subject line
1156
+ * @param {string} payload.html - HTML content of the email
1157
+ * @param {string} [payload.from] - Optional sender email address (defaults to configured sender)
1158
+ * @param {string[]} [payload.cc] - Optional CC recipient email addresses
1159
+ * @param {string[]} [payload.bcc] - Optional BCC recipient email addresses
1160
+ * @returns {Promise<SendMailResponse>} Promise resolving to email sending status and message ID
1161
+ *
1162
+ * @throws {Error} If secret key is missing or invalid
1163
+ * @throws {Error} If email validation fails
1164
+ * @throws {Error} If rate limit is exceeded
1165
+ *
1166
+ * @example
1167
+ * // Send a basic email
1168
+ * const result = await mail.send({
1169
+ * to: 'user@example.com',
1170
+ * subject: 'Welcome to urBackend',
1171
+ * html: '<h1>Welcome!</h1><p>Thanks for joining.</p>'
1172
+ * });
1173
+ * console.log(result.messageId);
1174
+ *
1175
+ * @example
1176
+ * // Send an email with CC and custom sender
1177
+ * const result = await mail.send({
1178
+ * from: 'noreply@myapp.com',
1179
+ * to: 'user@example.com',
1180
+ * cc: ['admin@example.com'],
1181
+ * subject: 'Important Update',
1182
+ * html: '<p>Your account has been updated.</p>'
1183
+ * });
1184
+ *
1185
+ * @example
1186
+ * // Send email with error handling
1187
+ * try {
1188
+ * const result = await mail.send({
1189
+ * to: 'user@example.com',
1190
+ * subject: 'Test',
1191
+ * html: '<p>Test email</p>'
1192
+ * });
1193
+ * console.log('Email sent:', result);
1194
+ * } catch (error) {
1195
+ * console.error('Failed to send email:', error);
1196
+ * }
287
1197
  */
288
1198
  send(payload: SendMailPayload): Promise<SendMailResponse>;
289
1199
  }