@seaverse/data-service-sdk 0.5.1 → 0.6.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.
package/dist/index.cjs CHANGED
@@ -343,8 +343,9 @@ async function initializeWithToken(tokenResponse) {
343
343
  // Sign in with custom token
344
344
  const auth = getAuth(app);
345
345
  await signInWithCustomToken(auth, tokenResponse.custom_token);
346
- // Get Firestore instance
347
- const db = getFirestore(app);
346
+ // Get Firestore instance with correct database ID
347
+ // IMPORTANT: Must specify database_id, not just use default!
348
+ const db = getFirestore(app, tokenResponse.database_id);
348
349
  return {
349
350
  app,
350
351
  auth,
@@ -354,10 +355,272 @@ async function initializeWithToken(tokenResponse) {
354
355
  };
355
356
  }
356
357
 
358
+ /**
359
+ * Firestore Path Helper Functions
360
+ *
361
+ * These helper functions generate correct Firestore paths that match
362
+ * the security rules. Use these instead of manually constructing paths
363
+ * to avoid permission-denied errors.
364
+ *
365
+ * 🚨 IMPORTANT: These paths are designed to work with SeaVerse Firestore Rules
366
+ *
367
+ * Permission Levels:
368
+ * - publicRead: Read-only for all users, write for admins only
369
+ * - publicData: Read/write for all authenticated users
370
+ * - userData: Read/write only for the data owner
371
+ */
372
+ /**
373
+ * Generate path for publicRead data (read-only for users, write for admins)
374
+ *
375
+ * @param appId - Your application ID
376
+ * @param collection - Collection name (e.g., 'announcements', 'config')
377
+ * @returns Firestore path string
378
+ *
379
+ * @example
380
+ * ```typescript
381
+ * // Read system announcements
382
+ * const path = getPublicReadPath('my-app', 'announcements');
383
+ * // Returns: 'appData/my-app/publicRead/announcements'
384
+ *
385
+ * const snapshot = await getDocs(collection(db, path));
386
+ * ```
387
+ */
388
+ function getPublicReadPath(appId, collectionName) {
389
+ validateSegment('appId', appId);
390
+ validateSegment('collectionName', collectionName);
391
+ return `appData/${appId}/publicRead/${collectionName}`;
392
+ }
393
+ /**
394
+ * Generate path for publicData (read/write for all authenticated users)
395
+ *
396
+ * @param appId - Your application ID
397
+ * @param collection - Collection name (e.g., 'posts', 'comments')
398
+ * @returns Firestore path string
399
+ *
400
+ * @example
401
+ * ```typescript
402
+ * // Write a public post
403
+ * const path = getPublicDataPath('my-app', 'posts');
404
+ * // Returns: 'appData/my-app/publicData/posts'
405
+ *
406
+ * await addDoc(collection(db, path), {
407
+ * _appId: appId,
408
+ * _createdAt: serverTimestamp(),
409
+ * _createdBy: userId,
410
+ * title: 'My Post'
411
+ * });
412
+ * ```
413
+ */
414
+ function getPublicDataPath(appId, collectionName) {
415
+ validateSegment('appId', appId);
416
+ validateSegment('collectionName', collectionName);
417
+ return `appData/${appId}/publicData/${collectionName}`;
418
+ }
419
+ /**
420
+ * Generate path for userData (private, read/write only by owner)
421
+ *
422
+ * @param appId - Your application ID
423
+ * @param userId - User ID who owns this data
424
+ * @param collection - Collection name (e.g., 'notes', 'settings')
425
+ * @returns Firestore path string
426
+ *
427
+ * @example
428
+ * ```typescript
429
+ * // Write private user notes
430
+ * const path = getUserDataPath('my-app', 'user-123', 'notes');
431
+ * // Returns: 'appData/my-app/userData/user-123/notes'
432
+ *
433
+ * await addDoc(collection(db, path), {
434
+ * _appId: appId,
435
+ * _createdAt: serverTimestamp(),
436
+ * _createdBy: userId,
437
+ * content: 'Private note'
438
+ * });
439
+ * ```
440
+ */
441
+ function getUserDataPath(appId, userId, collectionName) {
442
+ validateSegment('appId', appId);
443
+ validateSegment('userId', userId);
444
+ validateSegment('collectionName', collectionName);
445
+ return `appData/${appId}/userData/${userId}/${collectionName}`;
446
+ }
447
+ /**
448
+ * Generate path for a specific document in publicRead
449
+ *
450
+ * @param appId - Your application ID
451
+ * @param collection - Collection name
452
+ * @param docId - Document ID
453
+ * @returns Firestore document path string
454
+ *
455
+ * @example
456
+ * ```typescript
457
+ * const path = getPublicReadDocPath('my-app', 'announcements', 'announcement-1');
458
+ * // Returns: 'appData/my-app/publicRead/announcements/announcement-1'
459
+ *
460
+ * const docSnap = await getDoc(doc(db, path));
461
+ * ```
462
+ */
463
+ function getPublicReadDocPath(appId, collectionName, docId) {
464
+ validateSegment('appId', appId);
465
+ validateSegment('collectionName', collectionName);
466
+ validateSegment('docId', docId);
467
+ return `appData/${appId}/publicRead/${collectionName}/${docId}`;
468
+ }
469
+ /**
470
+ * Generate path for a specific document in publicData
471
+ *
472
+ * @param appId - Your application ID
473
+ * @param collection - Collection name
474
+ * @param docId - Document ID
475
+ * @returns Firestore document path string
476
+ *
477
+ * @example
478
+ * ```typescript
479
+ * const path = getPublicDataDocPath('my-app', 'posts', 'post-123');
480
+ * // Returns: 'appData/my-app/publicData/posts/post-123'
481
+ *
482
+ * const docSnap = await getDoc(doc(db, path));
483
+ * ```
484
+ */
485
+ function getPublicDataDocPath(appId, collectionName, docId) {
486
+ validateSegment('appId', appId);
487
+ validateSegment('collectionName', collectionName);
488
+ validateSegment('docId', docId);
489
+ return `appData/${appId}/publicData/${collectionName}/${docId}`;
490
+ }
491
+ /**
492
+ * Generate path for a specific document in userData
493
+ *
494
+ * @param appId - Your application ID
495
+ * @param userId - User ID who owns this data
496
+ * @param collection - Collection name
497
+ * @param docId - Document ID
498
+ * @returns Firestore document path string
499
+ *
500
+ * @example
501
+ * ```typescript
502
+ * const path = getUserDataDocPath('my-app', 'user-123', 'notes', 'note-456');
503
+ * // Returns: 'appData/my-app/userData/user-123/notes/note-456'
504
+ *
505
+ * const docSnap = await getDoc(doc(db, path));
506
+ * ```
507
+ */
508
+ function getUserDataDocPath(appId, userId, collectionName, docId) {
509
+ validateSegment('appId', appId);
510
+ validateSegment('userId', userId);
511
+ validateSegment('collectionName', collectionName);
512
+ validateSegment('docId', docId);
513
+ return `appData/${appId}/userData/${userId}/${collectionName}/${docId}`;
514
+ }
515
+ /**
516
+ * Validate a path segment to ensure it doesn't contain invalid characters
517
+ *
518
+ * @param name - Parameter name for error messages
519
+ * @param value - The segment value to validate
520
+ * @throws Error if the segment is invalid
521
+ */
522
+ function validateSegment(name, value) {
523
+ if (!value || typeof value !== 'string') {
524
+ throw new Error(`${name} must be a non-empty string`);
525
+ }
526
+ if (value.includes('/')) {
527
+ throw new Error(`${name} cannot contain forward slashes (/). Got: "${value}"`);
528
+ }
529
+ if (value.trim() !== value) {
530
+ throw new Error(`${name} cannot start or end with whitespace. Got: "${value}"`);
531
+ }
532
+ }
533
+ /**
534
+ * Path builder for advanced use cases
535
+ * Provides a fluent interface for building Firestore paths
536
+ *
537
+ * @example
538
+ * ```typescript
539
+ * // Build a path step by step
540
+ * const builder = new PathBuilder('my-app');
541
+ * const path = builder.publicData('posts').build();
542
+ * // Returns: 'appData/my-app/publicData/posts'
543
+ *
544
+ * // With document ID
545
+ * const docPath = builder.publicData('posts').doc('post-123').build();
546
+ * // Returns: 'appData/my-app/publicData/posts/post-123'
547
+ * ```
548
+ */
549
+ class PathBuilder {
550
+ constructor(appId) {
551
+ this.appId = appId;
552
+ this.segments = ['appData'];
553
+ validateSegment('appId', appId);
554
+ this.segments.push(appId);
555
+ }
556
+ /**
557
+ * Add publicRead collection to path
558
+ */
559
+ publicRead(collectionName) {
560
+ validateSegment('collectionName', collectionName);
561
+ this.segments.push('publicRead', collectionName);
562
+ return this;
563
+ }
564
+ /**
565
+ * Add publicData collection to path
566
+ */
567
+ publicData(collectionName) {
568
+ validateSegment('collectionName', collectionName);
569
+ this.segments.push('publicData', collectionName);
570
+ return this;
571
+ }
572
+ /**
573
+ * Add userData collection to path
574
+ */
575
+ userData(userId, collectionName) {
576
+ validateSegment('userId', userId);
577
+ validateSegment('collectionName', collectionName);
578
+ this.segments.push('userData', userId, collectionName);
579
+ return this;
580
+ }
581
+ /**
582
+ * Add document ID to path
583
+ */
584
+ doc(docId) {
585
+ validateSegment('docId', docId);
586
+ this.segments.push(docId);
587
+ return this;
588
+ }
589
+ /**
590
+ * Build the final path string
591
+ */
592
+ build() {
593
+ return this.segments.join('/');
594
+ }
595
+ }
596
+ /**
597
+ * Common path patterns as constants for frequently used paths
598
+ */
599
+ const PATH_PATTERNS = {
600
+ /**
601
+ * Base pattern for all SeaVerse data
602
+ */
603
+ APP_DATA: 'appData',
604
+ /**
605
+ * Permission layers
606
+ */
607
+ PUBLIC_READ: 'publicRead',
608
+ PUBLIC_DATA: 'publicData',
609
+ USER_DATA: 'userData',
610
+ };
611
+
357
612
  exports.DEFAULT_BASE_URL = DEFAULT_BASE_URL;
358
613
  exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
359
614
  exports.DataServiceClient = DataServiceClient;
360
615
  exports.ENDPOINTS = ENDPOINTS;
616
+ exports.PATH_PATTERNS = PATH_PATTERNS;
617
+ exports.PathBuilder = PathBuilder;
361
618
  exports.getFirebaseConfig = getFirebaseConfig;
619
+ exports.getPublicDataDocPath = getPublicDataDocPath;
620
+ exports.getPublicDataPath = getPublicDataPath;
621
+ exports.getPublicReadDocPath = getPublicReadDocPath;
622
+ exports.getPublicReadPath = getPublicReadPath;
623
+ exports.getUserDataDocPath = getUserDataDocPath;
624
+ exports.getUserDataPath = getUserDataPath;
362
625
  exports.initializeWithToken = initializeWithToken;
363
626
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/config.ts","../src/client.ts","../src/helpers.ts"],"sourcesContent":[null,null,null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/config.ts","../src/client.ts","../src/helpers.ts","../src/path-helpers.ts"],"sourcesContent":[null,null,null,null],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -518,5 +518,190 @@ declare function initializeWithToken(tokenResponse: FirestoreTokenResponse): Pro
518
518
  appId: string;
519
519
  }>;
520
520
 
521
- export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT, DataServiceClient, ENDPOINTS, getFirebaseConfig, initializeWithToken };
521
+ /**
522
+ * Firestore Path Helper Functions
523
+ *
524
+ * These helper functions generate correct Firestore paths that match
525
+ * the security rules. Use these instead of manually constructing paths
526
+ * to avoid permission-denied errors.
527
+ *
528
+ * 🚨 IMPORTANT: These paths are designed to work with SeaVerse Firestore Rules
529
+ *
530
+ * Permission Levels:
531
+ * - publicRead: Read-only for all users, write for admins only
532
+ * - publicData: Read/write for all authenticated users
533
+ * - userData: Read/write only for the data owner
534
+ */
535
+ /**
536
+ * Generate path for publicRead data (read-only for users, write for admins)
537
+ *
538
+ * @param appId - Your application ID
539
+ * @param collection - Collection name (e.g., 'announcements', 'config')
540
+ * @returns Firestore path string
541
+ *
542
+ * @example
543
+ * ```typescript
544
+ * // Read system announcements
545
+ * const path = getPublicReadPath('my-app', 'announcements');
546
+ * // Returns: 'appData/my-app/publicRead/announcements'
547
+ *
548
+ * const snapshot = await getDocs(collection(db, path));
549
+ * ```
550
+ */
551
+ declare function getPublicReadPath(appId: string, collectionName: string): string;
552
+ /**
553
+ * Generate path for publicData (read/write for all authenticated users)
554
+ *
555
+ * @param appId - Your application ID
556
+ * @param collection - Collection name (e.g., 'posts', 'comments')
557
+ * @returns Firestore path string
558
+ *
559
+ * @example
560
+ * ```typescript
561
+ * // Write a public post
562
+ * const path = getPublicDataPath('my-app', 'posts');
563
+ * // Returns: 'appData/my-app/publicData/posts'
564
+ *
565
+ * await addDoc(collection(db, path), {
566
+ * _appId: appId,
567
+ * _createdAt: serverTimestamp(),
568
+ * _createdBy: userId,
569
+ * title: 'My Post'
570
+ * });
571
+ * ```
572
+ */
573
+ declare function getPublicDataPath(appId: string, collectionName: string): string;
574
+ /**
575
+ * Generate path for userData (private, read/write only by owner)
576
+ *
577
+ * @param appId - Your application ID
578
+ * @param userId - User ID who owns this data
579
+ * @param collection - Collection name (e.g., 'notes', 'settings')
580
+ * @returns Firestore path string
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * // Write private user notes
585
+ * const path = getUserDataPath('my-app', 'user-123', 'notes');
586
+ * // Returns: 'appData/my-app/userData/user-123/notes'
587
+ *
588
+ * await addDoc(collection(db, path), {
589
+ * _appId: appId,
590
+ * _createdAt: serverTimestamp(),
591
+ * _createdBy: userId,
592
+ * content: 'Private note'
593
+ * });
594
+ * ```
595
+ */
596
+ declare function getUserDataPath(appId: string, userId: string, collectionName: string): string;
597
+ /**
598
+ * Generate path for a specific document in publicRead
599
+ *
600
+ * @param appId - Your application ID
601
+ * @param collection - Collection name
602
+ * @param docId - Document ID
603
+ * @returns Firestore document path string
604
+ *
605
+ * @example
606
+ * ```typescript
607
+ * const path = getPublicReadDocPath('my-app', 'announcements', 'announcement-1');
608
+ * // Returns: 'appData/my-app/publicRead/announcements/announcement-1'
609
+ *
610
+ * const docSnap = await getDoc(doc(db, path));
611
+ * ```
612
+ */
613
+ declare function getPublicReadDocPath(appId: string, collectionName: string, docId: string): string;
614
+ /**
615
+ * Generate path for a specific document in publicData
616
+ *
617
+ * @param appId - Your application ID
618
+ * @param collection - Collection name
619
+ * @param docId - Document ID
620
+ * @returns Firestore document path string
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * const path = getPublicDataDocPath('my-app', 'posts', 'post-123');
625
+ * // Returns: 'appData/my-app/publicData/posts/post-123'
626
+ *
627
+ * const docSnap = await getDoc(doc(db, path));
628
+ * ```
629
+ */
630
+ declare function getPublicDataDocPath(appId: string, collectionName: string, docId: string): string;
631
+ /**
632
+ * Generate path for a specific document in userData
633
+ *
634
+ * @param appId - Your application ID
635
+ * @param userId - User ID who owns this data
636
+ * @param collection - Collection name
637
+ * @param docId - Document ID
638
+ * @returns Firestore document path string
639
+ *
640
+ * @example
641
+ * ```typescript
642
+ * const path = getUserDataDocPath('my-app', 'user-123', 'notes', 'note-456');
643
+ * // Returns: 'appData/my-app/userData/user-123/notes/note-456'
644
+ *
645
+ * const docSnap = await getDoc(doc(db, path));
646
+ * ```
647
+ */
648
+ declare function getUserDataDocPath(appId: string, userId: string, collectionName: string, docId: string): string;
649
+ /**
650
+ * Path builder for advanced use cases
651
+ * Provides a fluent interface for building Firestore paths
652
+ *
653
+ * @example
654
+ * ```typescript
655
+ * // Build a path step by step
656
+ * const builder = new PathBuilder('my-app');
657
+ * const path = builder.publicData('posts').build();
658
+ * // Returns: 'appData/my-app/publicData/posts'
659
+ *
660
+ * // With document ID
661
+ * const docPath = builder.publicData('posts').doc('post-123').build();
662
+ * // Returns: 'appData/my-app/publicData/posts/post-123'
663
+ * ```
664
+ */
665
+ declare class PathBuilder {
666
+ private appId;
667
+ private segments;
668
+ constructor(appId: string);
669
+ /**
670
+ * Add publicRead collection to path
671
+ */
672
+ publicRead(collectionName: string): this;
673
+ /**
674
+ * Add publicData collection to path
675
+ */
676
+ publicData(collectionName: string): this;
677
+ /**
678
+ * Add userData collection to path
679
+ */
680
+ userData(userId: string, collectionName: string): this;
681
+ /**
682
+ * Add document ID to path
683
+ */
684
+ doc(docId: string): this;
685
+ /**
686
+ * Build the final path string
687
+ */
688
+ build(): string;
689
+ }
690
+ /**
691
+ * Common path patterns as constants for frequently used paths
692
+ */
693
+ declare const PATH_PATTERNS: {
694
+ /**
695
+ * Base pattern for all SeaVerse data
696
+ */
697
+ readonly APP_DATA: "appData";
698
+ /**
699
+ * Permission layers
700
+ */
701
+ readonly PUBLIC_READ: "publicRead";
702
+ readonly PUBLIC_DATA: "publicData";
703
+ readonly USER_DATA: "userData";
704
+ };
705
+
706
+ export { DEFAULT_BASE_URL, DEFAULT_TIMEOUT, DataServiceClient, ENDPOINTS, PATH_PATTERNS, PathBuilder, getFirebaseConfig, getPublicDataDocPath, getPublicDataPath, getPublicReadDocPath, getPublicReadPath, getUserDataDocPath, getUserDataPath, initializeWithToken };
522
707
  export type { ApiError, ApiResponse, DataServiceClientOptions, FirebaseConfig, FirestoreTokenResponse, GenerateFirestoreTokenRequest, GenerateGuestFirestoreTokenRequest };