@rezamirzapour/pod-sdk 1.0.5 → 1.0.7

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/README.md CHANGED
@@ -31,7 +31,7 @@
31
31
  | **CMS Tags & Tree** | `sdk.tags` / `sdk.cms.tags` | `tags` | Manage tag categories and hierarchical tag trees (nodes, parent updates, ancestors, codes). |
32
32
  | **CustomPost** | `sdk.customPost` | - | Search timeline by metadata `<T>`, custom post CRUD, and high-level typed repository. |
33
33
  | **SSO** | `sdk.sso` | - | OAuth2 handshake, OTP dispatch with digital RSA signature, OTP verify, token generation, and user profile. |
34
- | **Podspace** | `sdk.podspace` | - | File upload (FormData) and public/private download URL resolution. |
34
+ | **Podspace** | `sdk.podspace` | `public-apis` | Complete Cloud Storage: file/image uploads, resumable chunked uploads, folders, versions, share links, workspaces, trash, tags, & metadata. |
35
35
  | **Podform** | `sdk.podform` | - | Survey & form response submission, question/form structure retrieval. |
36
36
  | **Notification** | `sdk.notification` | - | SMS delivery and bulk messaging with tracking. |
37
37
  | **Social** | `sdk.social` | - | User comments, reactions (likes/dislikes), rates, and social post interactions. |
@@ -604,9 +604,259 @@ export async function getPublishedPosts() {
604
604
 
605
605
  ---
606
606
 
607
+ ## Deep Dive 5: Podspace Cloud Storage (Official Swagger API)
608
+
609
+ The **Podspace** module provides complete enterprise integration with the official POD Podspace Cloud Storage service ([Swagger documentation: `podspace.sandpod.ir/api/docs`](http://podspace.sandpod.ir/api/docs)). It supports standard and resumable uploads, public/private files, dynamic CDN image transformations, folder hierarchy, file versioning, public share links, trash recovery, team workspaces, user groups, and custom metadata.
610
+
611
+ ### Sub-Services Architecture
612
+
613
+ All Podspace operations are accessible via specialized, modular sub-services under `podSdk.podspace`:
614
+
615
+ ```typescript
616
+ podSdk.podspace.files // File details, rename, move, copy, search, versions, zip
617
+ podSdk.podspace.folders // Folder creation, nested paths, children, actions
618
+ podSdk.podspace.resumable // Chunked/large file upload (tus protocol: create, append, finalize)
619
+ podSdk.podspace.links // Public/password-protected shareable download links
620
+ podSdk.podspace.shares // Sharing files/folders with specific users & permissions
621
+ podSdk.podspace.trash // Recycle bin: list, restore, empty, auto-cleanup
622
+ podSdk.podspace.bookmarks // Starred / favorite files and folders
623
+ podSdk.podspace.tags // File & folder tagging
624
+ podSdk.podspace.metadata // Custom key-value metadata & descriptions
625
+ podSdk.podspace.userGroups // Group storage, member uploads & quota usage
626
+ podSdk.podspace.workspaces // Team workspaces & member roles
627
+ podSdk.podspace.me // User storage usage, plans, personal/chat folders
628
+ ```
629
+
630
+ > [!TIP]
631
+ > Commonly used methods (`uploadFile`, `downloadFile`, `getFileUrl`, `getImageUrl`, `getThumbnailUrl`, `createFolder`, `searchFiles`) are also directly available on `podSdk.podspace` for maximum developer convenience.
632
+
633
+ ---
634
+
635
+ ### Key Usage Examples
636
+
637
+ #### 1. File Upload & CDN URLs (100% Backward Compatible)
638
+
639
+ ```typescript
640
+ // app/actions/upload.ts
641
+ 'use server';
642
+
643
+ import { podSdk } from '@/lib/pod';
644
+
645
+ export async function uploadDocument(formData: FormData) {
646
+ // Supports both positional args (formData, path, isPublic) and options object
647
+ const res = await podSdk.podspace.uploadFile(formData, {
648
+ path: '/documents/invoices',
649
+ isPublic: true,
650
+ });
651
+
652
+ if (res.hasError) {
653
+ throw new Error(res.message || 'Upload failed');
654
+ }
655
+
656
+ const file = res.result;
657
+
658
+ // Resolve direct download URL
659
+ const downloadUrl = podSdk.podspace.getFileUrl(file.hash, true);
660
+
661
+ return {
662
+ hash: file.hash,
663
+ name: file.name,
664
+ size: file.size,
665
+ url: downloadUrl,
666
+ };
667
+ }
668
+ ```
669
+
670
+ #### 2. Image & Thumbnail CDN URL Helper
671
+
672
+ ```typescript
673
+ // Helper functions generate instant CDN URLs without network calls:
674
+ const fullImageUrl = podSdk.podspace.getImageUrl(imageHash, {
675
+ isPublic: true,
676
+ size: '1200x800',
677
+ quality: 85,
678
+ crop: true,
679
+ });
680
+
681
+ const thumbUrl = podSdk.podspace.getThumbnailUrl(imageHash, {
682
+ isPublic: true,
683
+ size: '150x150',
684
+ });
685
+ ```
686
+
687
+ #### 3. Base64 Image Upload
688
+
689
+ ```typescript
690
+ // Upload image directly from a Base64 data URL
691
+ const uploadRes = await podSdk.podspace.uploadImageBase64({
692
+ base64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAE...',
693
+ filename: 'avatar.png',
694
+ path: '/avatars',
695
+ isPublic: true,
696
+ });
697
+ ```
698
+
699
+ #### 4. Resumable Chunked Upload (Large Files)
700
+
701
+ For reliable multi-gigabyte uploads with pause/resume support:
702
+
703
+ ```typescript
704
+ // Step 1: Initialize resumable session
705
+ const session = await podSdk.podspace.resumable.create({
706
+ filename: 'presentation.mp4',
707
+ fileSize: totalBytes,
708
+ path: '/videos',
709
+ isPublic: false,
710
+ });
711
+
712
+ const uploadUrl = session.uploadUrl;
713
+
714
+ // Step 2: Check current server offset if resuming
715
+ const offset = await podSdk.podspace.resumable.getStatus(uploadUrl);
716
+
717
+ // Step 3: Append chunks
718
+ await podSdk.podspace.resumable.append({
719
+ uploadUrl,
720
+ offset,
721
+ chunk: chunkBuffer,
722
+ });
723
+
724
+ // Step 4: Finalize when all bytes are uploaded
725
+ const completedFile = await podSdk.podspace.resumable.finalizeUpload(uploadUrl);
726
+ ```
727
+
728
+ #### 5. Folder Hierarchy & Listing
729
+
730
+ ```typescript
731
+ // Create a folder
732
+ await podSdk.podspace.folders.createFolder({
733
+ name: 'Reports-2026',
734
+ path: '/finance',
735
+ });
736
+
737
+ // Recursively create nested directory paths
738
+ await podSdk.podspace.folders.createDirectories('/finance/2026/Q1/receipts');
739
+
740
+ // List folder contents with pagination
741
+ const contents = await podSdk.podspace.folders.getFolderChildren({
742
+ path: '/finance/Reports-2026',
743
+ offset: 0,
744
+ size: 50,
745
+ });
746
+ ```
747
+
748
+ #### 6. Shareable Public / Password-Protected Links
749
+
750
+ ```typescript
751
+ // Create an expiring, password-protected download link
752
+ const linkRes = await podSdk.podspace.links.createLink(fileHash, {
753
+ type: 'DOWNLOAD',
754
+ password: 'SecurePassword123!',
755
+ expiresAt: Date.now() + 7 * 24 * 3600 * 1000, // 7 days
756
+ });
757
+
758
+ // Share with a specific user
759
+ await podSdk.podspace.shares.shareWithUser(fileHash, {
760
+ username: 'john_doe',
761
+ permission: 'READ',
762
+ });
763
+ ```
764
+
765
+ #### 7. File Versions & Rollback
766
+
767
+ ```typescript
768
+ // List previous versions of a file
769
+ const versions = await podSdk.podspace.files.getFileVersions(fileHash);
770
+
771
+ // Rollback to a specific historical version
772
+ await podSdk.podspace.files.rollbackFileVersion(fileHash, versionId);
773
+ ```
774
+
775
+ #### 8. Trash & Recycling
776
+
777
+ ```typescript
778
+ // Move file or folder to trash
779
+ await podSdk.podspace.files.trashEntity(fileHash);
780
+
781
+ // List recycle bin
782
+ const trashItems = await podSdk.podspace.trash.getTrashList({ size: 20 });
783
+
784
+ // Restore or permanently delete
785
+ await podSdk.podspace.trash.restore(fileHash);
786
+ await podSdk.podspace.trash.deletePermanently(fileHash);
787
+ ```
788
+
789
+ ---
790
+
791
+ ### Podspace Methods Reference
792
+
793
+ | Sub-Service | Method | HTTP | Path | Description |
794
+ | :--- | :--- | :--- | :--- | :--- |
795
+ | **Upload / Download** | `uploadFile(formData, params)` | `POST` | `/api/files` | Upload single file with metadata. |
796
+ | | `uploadMultipleFiles(formData, params)` | `POST` | `/api/files/batch` | Upload multiple files simultaneously. |
797
+ | | `uploadImageBase64(params)` | `POST` | `/api/images/base64` | Upload base64 encoded image. |
798
+ | | `replaceFile(hash, formData)` | `PUT` | `/api/files/{hash}` | Overwrite existing file content. |
799
+ | | `uploadByLink(params)` | `POST` | `/api/files/link` | Download remote file into Podspace. |
800
+ | | `downloadFile(hash, opts)` | `GET` | `/api/files/{hash}` | Download raw binary file. |
801
+ | | `downloadImage(hash, opts)` | `GET` | `/api/images/{hash}` | Download transformed image. |
802
+ | | `downloadThumbnail(hash, opts)` | `GET` | `/api/images/thumbnails/{hash}` | Download image thumbnail. |
803
+ | | `downloadFilesAsZip(hashes)` | `POST` | `/api/files/zip` | Batch download files as a ZIP archive. |
804
+ | | `getFileUrl(hash, isPublic)` | - | Client Helper | Generates direct file CDN link. |
805
+ | | `getImageUrl(hash, opts)` | - | Client Helper | Generates transformed image CDN link. |
806
+ | | `getThumbnailUrl(hash, opts)` | - | Client Helper | Generates thumbnail CDN link. |
807
+ | **Files** | `getFileDetail(hash)` | `GET` | `/api/files/{hash}/metadata` | Fetch full metadata for file. |
808
+ | | `getFileDetailByPath(path)` | `GET` | `/api/files/path` | Fetch metadata by absolute path. |
809
+ | | `checkEntityExist(hash)` | `GET` | `/api/entities/{hash}/exist` | Check existence of file/folder. |
810
+ | | `renameEntity(hash, newName)` | `PUT` | `/api/entities/{hash}/rename` | Rename file or folder. |
811
+ | | `moveEntity(hash, targetPath)` | `PUT` | `/api/entities/{hash}/move` | Move file or folder. |
812
+ | | `copyEntity(hash, targetPath)` | `POST` | `/api/entities/{hash}/copy` | Duplicate file or folder. |
813
+ | | `trashEntity(hash)` | `DELETE` | `/api/entities/{hash}` | Move file/folder to trash. |
814
+ | | `searchFiles(params)` | `GET` | `/api/files/search` | Search files by name, type, date, or tags. |
815
+ | | `getFileVersions(hash)` | `GET` | `/api/files/{hash}/versions` | List all historical versions. |
816
+ | | `rollbackFileVersion(hash, id)` | `POST` | `/api/files/{hash}/versions/{id}/rollback` | Rollback to specific version. |
817
+ | | `compressToZip(params)` | `POST` | `/api/files/compress` | Compress files into a ZIP archive. |
818
+ | | `extractZip(params)` | `POST` | `/api/files/extract` | Extract ZIP archive in Podspace. |
819
+ | **Folders** | `createFolder(params)` | `POST` | `/api/folders` | Create a new folder. |
820
+ | | `createDirectories(path)` | `POST` | `/api/folders/directories` | Create nested directory tree. |
821
+ | | `getFolderChildren(params)` | `GET` | `/api/folders/{hash}/children` | List folder contents. |
822
+ | | `getRecentFolders(params)` | `GET` | `/api/folders/recent` | List recently accessed folders. |
823
+ | **Resumable** | `create(params)` | `POST` | `/api/files/resumable` | Initialize resumable upload. |
824
+ | | `append(params)` | `PATCH` | `{uploadUrl}` | Upload chunk to offset. |
825
+ | | `getStatus(uploadUrl)` | `HEAD` | `{uploadUrl}` | Get current uploaded byte offset. |
826
+ | | `finalizeUpload(uploadUrl)` | `POST` | `{uploadUrl}/finalize` | Complete resumable upload. |
827
+ | **Links** | `createLink(hash, params)` | `POST` | `/api/entities/{hash}/links` | Create shareable download link. |
828
+ | | `getUserLinks(params)` | `GET` | `/api/links` | List all created links. |
829
+ | | `revokeLink(linkHash)` | `DELETE` | `/api/links/{linkHash}` | Deactivate share link. |
830
+ | **Shares** | `shareWithUser(hash, params)` | `POST` | `/api/entities/{hash}/shares` | Share with another user. |
831
+ | | `makePublic(hash, isPublic)` | `PUT` | `/api/entities/{hash}/public` | Toggle public/private access. |
832
+ | | `getSharedWithMe(params)` | `GET` | `/api/shares/shared-with-me` | List items shared with user. |
833
+ | **Trash** | `getTrashList(params)` | `GET` | `/api/trash` | List items in recycle bin. |
834
+ | | `restore(hash)` | `POST` | `/api/trash/{hash}/restore` | Restore file/folder. |
835
+ | | `deletePermanently(hash)` | `DELETE` | `/api/trash/{hash}` | Permanently destroy file/folder. |
836
+ | | `emptyTrash()` | `DELETE` | `/api/trash` | Empty entire recycle bin. |
837
+ | **Bookmarks** | `getBookmarks(params)` | `GET` | `/api/bookmarks` | List starred files/folders. |
838
+ | | `addBookmark(hash)` | `POST` | `/api/bookmarks/{hash}` | Star a file or folder. |
839
+ | | `removeBookmark(hash)` | `DELETE` | `/api/bookmarks/{hash}` | Unstar a file or folder. |
840
+ | **Tags** | `addTags(hash, tags)` | `POST` | `/api/entities/{hash}/tags` | Add tags to entity. |
841
+ | | `getEntityTags(hash)` | `GET` | `/api/entities/{hash}/tags` | List entity tags. |
842
+ | | `getEntitiesByTag(tag)` | `GET` | `/api/tags/{tag}/entities` | Search entities by tag. |
843
+ | **Metadata** | `setMetadata(hash, metadata)` | `PUT` | `/api/entities/{hash}/metadata` | Set custom key-value metadata. |
844
+ | | `setDescription(hash, desc)` | `PUT` | `/api/entities/{hash}/description` | Set entity description. |
845
+ | **User Groups** | `createUserGroup(params)` | `POST` | `/api/user-groups` | Create user group. |
846
+ | | `uploadToUserGroup(group, fd)`| `POST` | `/api/user-groups/{group}/files` | Upload file to user group. |
847
+ | | `getUserGroupUsage(group)` | `GET` | `/api/user-groups/{group}/usage` | Get storage quota & usage. |
848
+ | **Workspaces** | `createWorkspace(params)` | `POST` | `/api/workspaces` | Create team workspace. |
849
+ | | `getWorkspaceMembers(id)` | `GET` | `/api/workspaces/{id}/members` | List workspace members. |
850
+ | **Me** | `getUser()` | `GET` | `/api/users/me` | Current user profile. |
851
+ | | `getUserUsageReport()` | `GET` | `/api/users/me/usage` | Total storage usage report. |
852
+ | | `getPersonalFolder()` | `GET` | `/api/users/me/personal-folder` | Get or create root personal folder. |
853
+ | | `getOrCreateChatFolder()` | `GET` | `/api/users/me/chat-folder` | Get or create chat attachments folder. |
854
+
855
+ ---
856
+
607
857
  ## Other POD Microservices
608
858
 
609
- ### 4. POD SSO (OTP Handshake with Web Crypto RSA Signature)
859
+ ### 1. POD SSO (OTP Handshake with Web Crypto RSA Signature)
610
860
 
611
861
  ```typescript
612
862
  // app/actions/auth.ts
@@ -649,28 +899,7 @@ export async function getProfile(accessToken: string) {
649
899
 
650
900
  ---
651
901
 
652
- ### 5. Podspace (File Uploads & CDN URLs)
653
-
654
- ```typescript
655
- // app/actions/upload.ts
656
- 'use server';
657
-
658
- import { podSdk } from '@/lib/pod';
659
-
660
- export async function uploadFile(formData: FormData) {
661
- const res = await podSdk.podspace.uploadFile(formData, '/uploads', true);
662
- if (res.hasError) {
663
- throw new Error(res.message || 'Upload failed');
664
- }
665
-
666
- const publicUrl = podSdk.podspace.getFileUrl(res.result.hash, true);
667
- return { url: publicUrl, hash: res.result.hash };
668
- }
669
- ```
670
-
671
- ---
672
-
673
- ### 6. Notification (SMS Delivery)
902
+ ### 2. Notification (SMS Delivery)
674
903
 
675
904
  ```typescript
676
905
  // app/actions/notify.ts
@@ -688,7 +917,7 @@ export async function sendSms(phoneNumber: string, text: string) {
688
917
 
689
918
  ---
690
919
 
691
- ### 7. Social (Comments & Likes)
920
+ ### 3. Social (Comments & Likes)
692
921
 
693
922
  ```typescript
694
923
  // app/actions/social.ts
@@ -710,7 +939,7 @@ export async function likePost(postId: number) {
710
939
 
711
940
  ---
712
941
 
713
- ### 8. IUMS (Identity & University Management Service)
942
+ ### 4. IUMS (Identity & University Management Service)
714
943
 
715
944
  ```typescript
716
945
  // app/actions/iums.ts