Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
191
cloud/maplefile-backend/pkg/maplefile/client/files.go
Normal file
191
cloud/maplefile-backend/pkg/maplefile/client/files.go
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
// Package client provides a Go SDK for interacting with the MapleFile API.
|
||||
package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CreatePendingFile creates a new file in pending state.
|
||||
func (c *Client) CreatePendingFile(ctx context.Context, input *CreateFileInput) (*PendingFile, error) {
|
||||
var resp PendingFile
|
||||
if err := c.doRequest(ctx, "POST", "/api/v1/files/pending", input, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// GetFile returns a single file by ID.
|
||||
func (c *Client) GetFile(ctx context.Context, id string) (*File, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s", id)
|
||||
var resp File
|
||||
if err := c.doRequest(ctx, "GET", path, nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// UpdateFile updates a file's metadata.
|
||||
func (c *Client) UpdateFile(ctx context.Context, id string, input *UpdateFileInput) (*File, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s", id)
|
||||
var resp File
|
||||
if err := c.doRequest(ctx, "PUT", path, input, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// DeleteFile soft-deletes a file.
|
||||
func (c *Client) DeleteFile(ctx context.Context, id string) error {
|
||||
path := fmt.Sprintf("/api/v1/file/%s", id)
|
||||
return c.doRequest(ctx, "DELETE", path, nil, nil, true)
|
||||
}
|
||||
|
||||
// DeleteMultipleFiles deletes multiple files at once.
|
||||
func (c *Client) DeleteMultipleFiles(ctx context.Context, fileIDs []string) error {
|
||||
input := DeleteMultipleFilesInput{FileIDs: fileIDs}
|
||||
return c.doRequest(ctx, "POST", "/api/v1/files/delete-multiple", input, nil, true)
|
||||
}
|
||||
|
||||
// GetPresignedUploadURL gets a presigned URL for uploading file content.
|
||||
func (c *Client) GetPresignedUploadURL(ctx context.Context, fileID string) (*PresignedURL, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s/upload-url", fileID)
|
||||
var resp PresignedURL
|
||||
if err := c.doRequest(ctx, "GET", path, nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// CompleteFileUpload marks the file upload as complete and transitions it to active state.
|
||||
func (c *Client) CompleteFileUpload(ctx context.Context, fileID string, input *CompleteUploadInput) (*File, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s/complete", fileID)
|
||||
var resp File
|
||||
if err := c.doRequest(ctx, "POST", path, input, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// GetPresignedDownloadURL gets a presigned URL for downloading file content.
|
||||
func (c *Client) GetPresignedDownloadURL(ctx context.Context, fileID string) (*PresignedDownloadResponse, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s/download-url", fileID)
|
||||
var resp PresignedDownloadResponse
|
||||
if err := c.doRequest(ctx, "GET", path, nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// ReportDownloadCompleted reports that a file download has completed.
|
||||
func (c *Client) ReportDownloadCompleted(ctx context.Context, fileID string) error {
|
||||
path := fmt.Sprintf("/api/v1/file/%s/download-completed", fileID)
|
||||
return c.doRequest(ctx, "POST", path, nil, nil, true)
|
||||
}
|
||||
|
||||
// ArchiveFile archives a file.
|
||||
func (c *Client) ArchiveFile(ctx context.Context, id string) (*File, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s/archive", id)
|
||||
var resp File
|
||||
if err := c.doRequest(ctx, "PUT", path, nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// RestoreFile restores an archived file.
|
||||
func (c *Client) RestoreFile(ctx context.Context, id string) (*File, error) {
|
||||
path := fmt.Sprintf("/api/v1/file/%s/restore", id)
|
||||
var resp File
|
||||
if err := c.doRequest(ctx, "PUT", path, nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// ListFilesByCollection returns all files in a collection.
|
||||
func (c *Client) ListFilesByCollection(ctx context.Context, collectionID string) ([]*File, error) {
|
||||
path := fmt.Sprintf("/api/v1/collection/%s/files", collectionID)
|
||||
var resp struct {
|
||||
Files []*File `json:"files"`
|
||||
}
|
||||
if err := c.doRequest(ctx, "GET", path, nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Files, nil
|
||||
}
|
||||
|
||||
// ListRecentFiles returns the user's recent files.
|
||||
func (c *Client) ListRecentFiles(ctx context.Context) ([]*File, error) {
|
||||
var resp struct {
|
||||
Files []*File `json:"files"`
|
||||
}
|
||||
if err := c.doRequest(ctx, "GET", "/api/v1/files/recent", nil, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp.Files, nil
|
||||
}
|
||||
|
||||
// SyncFiles fetches file changes since the given cursor.
|
||||
func (c *Client) SyncFiles(ctx context.Context, input *SyncInput) (*FileSyncResponse, error) {
|
||||
var resp FileSyncResponse
|
||||
if err := c.doRequest(ctx, "POST", "/api/v1/files/sync", input, &resp, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
||||
// UploadToPresignedURL uploads data to an S3 presigned URL.
|
||||
// This is a helper method for uploading encrypted file content directly to S3.
|
||||
func (c *Client) UploadToPresignedURL(ctx context.Context, presignedURL string, data []byte, contentType string) error {
|
||||
req, err := http.NewRequestWithContext(ctx, "PUT", presignedURL, bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create upload request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", contentType)
|
||||
req.ContentLength = int64(len(data))
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upload to presigned URL: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return fmt.Errorf("upload failed with status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DownloadFromPresignedURL downloads data from an S3 presigned URL.
|
||||
// This is a helper method for downloading encrypted file content directly from S3.
|
||||
func (c *Client) DownloadFromPresignedURL(ctx context.Context, presignedURL string) ([]byte, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, "GET", presignedURL, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create download request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to download from presigned URL: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
return nil, fmt.Errorf("download failed with status %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read download response: %w", err)
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue