Skip to content

Commit

Permalink
Merge pull request #8 from upperdo/develop
Browse files Browse the repository at this point in the history
Feat: Storage Service
  • Loading branch information
acidlake committed Oct 25, 2023
2 parents 593e506 + 034937c commit 501b9ea
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 9 deletions.
15 changes: 15 additions & 0 deletions src/lib/common/constants/database.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const DATABASE_CONFIG = {
databases: {
test: {
id: 'test',
collections: {
leads: 'leads'
}
}
},
buckets: {
dev: 'dev'
}
}

export { DATABASE_CONFIG };
4 changes: 3 additions & 1 deletion src/lib/common/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import COLORS from "./colors";
import ENUMS from "./enums";
import APP_PATHS from "./paths";
import CORE from "./core";
import { DATABASE_CONFIG } from "./database";



Expand All @@ -20,6 +21,7 @@ const CONSTANTS = {
COLORS,
ENUMS,
APP_PATHS,
CORE
CORE,
DATABASE_CONFIG
}
export default CONSTANTS;
3 changes: 2 additions & 1 deletion src/lib/services/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * as AccountService from "./account";
export * as DatabaseService from "./databases";
export * as AvatarService from "./avatars";
export * as FunctionService from "./functions";
export * as FunctionService from "./functions";
export * as StorageService from "./storage";
86 changes: 86 additions & 0 deletions src/lib/services/models/StorageModel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Class for storage service
*/
class StorageModel {
/**
* The unique identifier for the document.
*/
$id!: string

/**
* Storage bucketId that the file is stored.
*/
bucketId!: string

/**
* The creation date and time of the file.
*/
$createdAt!: string

/**
* The update date and time of the file.
*/
$updatedAt!: string

/**
* File permissions list.
*/
$permissions!: any[]

/**
* Name of the file.
*/
name!: string

/**
* Signature of the file.
*/
signature!: string

/**
* The mime type of the file.
*/
mimeType!: string

/**
* The original size of the file in bytes.
*/
sizeOriginal!: number

/**
* Amount of total chunk file.
*/
chunksTotal!: number

/**
* Amount of uploaded chunk file.
*/
chunksUploaded!: number

/**
* Create a new StorageModel instance
* @param data
*/
constructor(data: Partial<StorageModel>){
Object.assign(this, data);
}

/**
* Convert the StorageModel to a plain object without the StorageModel wrapper.
* @returns {object} - The plain object with storage properties.
*/
static toPlainObject(storageModel: StorageModel): Omit<StorageModel, 'toPlainObject'> {
const { createStorageModel, ...rest } = storageModel;
// @ts-ignore
return rest;
}

createStorageModel(data: any){
const storageModel = new StorageModel(data);
return StorageModel.toPlainObject(storageModel);
}

}


export { StorageModel }
103 changes: 103 additions & 0 deletions src/lib/services/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import BackendPlatform from "$lib/platforms";
import { StorageModel } from "./models/StorageModel";
import { LoggerUtility } from "$lib/common/logger/logger_utility";

/**
* Data structure for a list of files.
* @template T - The type of files in the list.
*/
type FileListData<T> = {
total: number;
files: T[]
}

/**
* List files from a storage bucket.
*
* @param {string} bucketId - The ID of the storage bucket.
* @param {any[]} queries - Optional queries for filtering files.
* @param {string} search - Optional search query for file names.
* @param {typeof LoggerUtility} logger - The logger utility to use for logging.
* @returns {Promise<FileListData<StorageModel>>} A list of files in the specified storage bucket.
*/
async function listFiles(bucketId: string, queries?: any[], search?: string, logger: typeof LoggerUtility = LoggerUtility): Promise<FileListData<StorageModel>> {
const filePath = "lib/services/storage/ listFiles";
try{
const result = await BackendPlatform.storage.listFiles(bucketId, queries, search);

const files: FileListData<StorageModel> = {
total: result.total,
files: result.files.map((file) => new StorageModel(file).createStorageModel(file) as StorageModel)
}

return files;
}catch(error){
if(error instanceof BackendPlatform.AppwriteException){
logger.error(`Appwrite exception: ${error.message} in:`, filePath);
}else {
logger.error(`An error ocurred: ${error} in:`, filePath)
}

return {
total: 0,
files: []
} as FileListData<StorageModel>
}
}

/**
* Create a new file in a storage bucket.
*
* @param {string} bucketId - The ID of the storage bucket.
* @param {File} fileId - The file to be uploaded.
* @param {string[]} permissions - Optional permissions for the file.
* @param {typeof LoggerUtility} logger - The logger utility to use for logging.
* @returns {Promise<StorageModel | null>} The created file object, or null if an error occurs.
*/
async function createFile(bucketId: string, fileId: File, permissions?: string[], logger: typeof LoggerUtility = LoggerUtility): Promise<StorageModel| null>{
const filePath = "lib/services/storage/ createFile";
try {
const result = await BackendPlatform.storage.createFile(bucketId, BackendPlatform.ID.unique(), fileId, permissions);
const file: StorageModel = new StorageModel(result).createStorageModel(result);

return file;
}catch(error){
if(error instanceof BackendPlatform.AppwriteException){
logger.error(`Appwrite exception: ${error.message} in:`, filePath);
}else{
logger.error(`An error ocurred: ${error} in:`, filePath)
}
return null;
}
}

/**
* Get a file from a storage bucket by its ID.
*
* @param {string} bucketId - The ID of the storage bucket.
* @param {string} fileId - The ID of the file to retrieve.
* @param {typeof LoggerUtility} logger - The logger utility to use for logging.
* @returns {Promise<StorageModel | null>} The retrieved file object, or null if an error occurs.
*/
async function getFile(bucketId: string, fileId: string, logger: typeof LoggerUtility = LoggerUtility): Promise<StorageModel | null>{
const filePath = "lib/services/storage/ createFile";
try {
const result = await BackendPlatform.storage.getFile(bucketId, fileId);
const file: StorageModel = new StorageModel(result).createStorageModel(result);

return file;
}catch(error){
if(error instanceof BackendPlatform.AppwriteException){
logger.error(`Appwrite exception: ${error.message} in:`, filePath);
}else{
logger.error(`An error ocurred: ${error} in:`, filePath)
}
return null;
}
}

export {
listFiles,
createFile,
getFile
}
11 changes: 7 additions & 4 deletions src/routes/(backoffice)/dashboard/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { PageServerLoad } from "./$types";
import type { LeadData } from "$lib/common/constants/types";
import { DatabaseService } from "$lib/services";
import { DatabaseService, StorageService } from "$lib/services";
import CONSTANTS from "$lib/common/constants";

export const load: PageServerLoad = async () => {
const leads = await DatabaseService.listDocuments<LeadData>('test', 'leads');


return {
leads
leads: await DatabaseService.listDocuments<LeadData>(
CONSTANTS.DATABASE_CONFIG.databases.test.id,
CONSTANTS.DATABASE_CONFIG.databases.test.collections.leads),
files: await StorageService.listFiles(CONSTANTS.DATABASE_CONFIG.buckets.dev)
}
}
4 changes: 1 addition & 3 deletions src/routes/(backoffice)/dashboard/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<script lang="ts">
import { DebugObject } from "$lib/ui/widgets"
import DashboardPage from "$lib/features/dashboard/widgets/dashboard-page.svelte";
export let data;
$:({ leads } = data);
$:({ leads, files } = data);
</script>

<DashboardPage />

0 comments on commit 501b9ea

Please sign in to comment.