From 1885d43fa642d321643e2fd3bd7155b684a55be7 Mon Sep 17 00:00:00 2001 From: Rodrigo Pinto Date: Thu, 5 Dec 2024 18:25:20 -0300 Subject: [PATCH] Added more endpoints and modals - Added endpoints to create folders, upload files and unlink files and folders; - Added modals to show loading indicators, confirmation and warnings. --- packages/src/lib/components/loading.svelte | 34 ++++ packages/src/lib/utils/tahoe.js | 79 ++++++++++ packages/src/routes/+layout.svelte | 1 + packages/src/routes/api/[slug]/+server.js | 40 ----- packages/src/routes/dashboard/+page.server.js | 103 +++++++++--- packages/src/routes/dashboard/+page.svelte | 148 +++++++++++++++--- 6 files changed, 324 insertions(+), 81 deletions(-) create mode 100644 packages/src/lib/components/loading.svelte create mode 100644 packages/src/lib/utils/tahoe.js delete mode 100644 packages/src/routes/api/[slug]/+server.js diff --git a/packages/src/lib/components/loading.svelte b/packages/src/lib/components/loading.svelte new file mode 100644 index 0000000..f5b5af4 --- /dev/null +++ b/packages/src/lib/components/loading.svelte @@ -0,0 +1,34 @@ +
+ +
+ + + + + +
+ + diff --git a/packages/src/lib/utils/tahoe.js b/packages/src/lib/utils/tahoe.js new file mode 100644 index 0000000..7c6051a --- /dev/null +++ b/packages/src/lib/utils/tahoe.js @@ -0,0 +1,79 @@ +import { env } from '$env/dynamic/private' + +export const createAlias = () => { + return new Promise(async (resolve, reject) => { + try { + const url = `${env.TAHOE_API}/uri?t=mkdir` + const response = await fetch(url, { method: 'POST' }) + const capKey = await response.json() + + return resolve({ capKey }) + } catch (error) { + return reject(error) + } + }) +} + +export const listDirectories = (capKey) => { + return new Promise(async (resolve, reject) => { + try { + const url = `${env.TAHOE_API}/uri/${capKey}?t=json` + const response = await fetch(url, { method: 'GET' }) + const list = await response.json() + + return resolve({ list }) + } catch (error) { + return reject(error) + } + }) +} + +export const createDirectory = (path, dirName) => { + return new Promise(async (resolve, reject) => { + try { + const url = `${env.TAHOE_API}/uri/${path}?t=mkdir&name=${dirName}` + const response = await fetch(url, { method: 'POST' }) + + if (response.status !== 200) { + return json({ success: false, status: response.status, message: response.statusText }) + } + + const cap = await response.json() + + return resolve({ cap }) + } catch (error) { + return reject(error) + } + }) +} + +export const uploadFile = (path, file) => { + return new Promise(async (resolve, reject) => { + const url = `${env.TAHOE_API}/uri/${path}` + + try { + const response = await fetch(url, { + method: 'PUT', + body: file + }) + + return resolve() + } catch (error) { + console.log({ error }) + return reject(error) + } + }) +} + +export const unlink = (path) => { + return new Promise(async (resolve, reject) => { + try { + const url = `${env.TAHOE_API}/uri/${path}` + const response = await fetch(url, { method: 'DELETE' }) + + return resolve() + } catch (error) { + return reject(error) + } + }) +} diff --git a/packages/src/routes/+layout.svelte b/packages/src/routes/+layout.svelte index c993c27..e660e59 100644 --- a/packages/src/routes/+layout.svelte +++ b/packages/src/routes/+layout.svelte @@ -16,6 +16,7 @@ --navbar-height: 3em; --shade-background: rgba(0, 0, 0, 0.2); --shade-color: #eee; + --shade-loading: rgba(0, 0, 0, 0.3); --theme-background: white; --theme-color: #444; } diff --git a/packages/src/routes/api/[slug]/+server.js b/packages/src/routes/api/[slug]/+server.js deleted file mode 100644 index 5bf9371..0000000 --- a/packages/src/routes/api/[slug]/+server.js +++ /dev/null @@ -1,40 +0,0 @@ -import { json } from '@sveltejs/kit' -import { env } from '$env/dynamic/private' - -export const POST = async ({ params, request }) => { - const { slug } = params - const body = await request.json() - - switch (slug) { - case 'createAlias': { - try { - const url = `${env.TAHOE_API}/uri?t=mkdir` - const response = await fetch(url, { method: 'POST' }) - const capKey = await response.json() - - return json({ success: true, capKey }) - } catch (error) { - console.log({ error }) - return json({ success: false, code: 500, error }) - } - } - - case 'listDirectories': { - try { - const encodedCapKey = body.capKey.replace(/:/g, '%3A') - const url = `${env.TAHOE_API}/uri/${encodedCapKey}?t=json` - const response = await fetch(url, { method: 'GET' }) - const list = await response.json() - - return json({ success: true, list }) - } catch (error) { - console.log({ error }) - return json({ success: false, code: 500, error, message: error.cause.message }) - } - } - - default: { - return json({ success: true }) - } - } -} diff --git a/packages/src/routes/dashboard/+page.server.js b/packages/src/routes/dashboard/+page.server.js index 6ac93d3..0f18f43 100644 --- a/packages/src/routes/dashboard/+page.server.js +++ b/packages/src/routes/dashboard/+page.server.js @@ -1,15 +1,15 @@ import { fail } from '@sveltejs/kit' +import { createAlias, createDirectory, listDirectories, unlink, uploadFile } from '$lib/utils/tahoe' export const actions = { createCapKey: async ({ request, fetch }) => { try { - const response = await fetch('/api/createAlias', { method: 'POST' }) - const jsonResponse = await response.json() + const { capKey } = await createAlias() - return { endpoint: 'createCapKey', capKey: jsonResponse.capKey } - } catch (err) { - console.log({ err }) - return fail(500, { endpoint: 'createCapKey', error: err }) + return { endpoint: 'createCapKey', capKey } + } catch (error) { + console.log({ error }) + return fail(500, { endpoint: 'createCapKey', error }) } }, @@ -19,25 +19,84 @@ export const actions = { const encoded = encodeURIComponent(capKey) try { - const response = await fetch('/api/listDirectories', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ capKey: encoded }) - }) - const jsonResponse = await response.json() + const { list } = await listDirectories(capKey) - if (!jsonResponse.success) { - if (jsonResponse.message.includes('ECONNREFUSED')) { - return { error: 'Tahoe server may be offline.' } - } else { - throw new Error(jsonResponse.error) - } + return { endpoint: 'listDirectories', list, capKey } + } catch (error) { + if (error.cause.message.includes('ECONNREFUSED')) { + return { error: 'Tahoe server may be offline.' } } - return { endpoint: 'listDirectories', list: jsonResponse.list, capKey } - } catch (err) { - console.log({ err }) - return fail(500, { endpoint: 'listDirectories', error: err }) + console.log({ error }) + return fail(500, { endpoint: 'listDirectories', error }) + } + }, + + createDirectory: async ({ request, fetch }) => { + const formData = await request.formData() + const capKey = formData.get('capKey') + const encoded = encodeURIComponent(capKey) + const dirName= formData.get('dirName') + let path = formData.get('path') + + if (path.length === 0) path = '/' + if (path.slice(0, 1) !== '/') path = '/' + path + if (path.slice(-1) !== '/') path = path + '/' + + path = encoded + encodeURI(path) + + try { + const { cap } = await createDirectory(path, dirName) + + return { success: true, endpoint: 'uploadFile' } + } catch (error) { + console.log({ error }) + return fail(500, { endpoint: 'uploadFile', error}) + } + }, + + uploadFile: async ({ request, fetch }) => { + const formData = await request.formData() + const capKey = formData.get('capKey') + const encoded = encodeURIComponent(capKey) + const file = formData.get('file') + let path = formData.get('path') + + if (path.length === 0) path = '/' + if (path.slice(0, 1) !== '/') path = '/' + path + if (path.slice(-1) !== '/') path = path + '/' + + path = encoded + encodeURI(path + file.name) + + try { + await uploadFile(path, file.name, file) + + return { success: true, endpoint: 'uploadFile' } + } catch (error) { + console.log({ error }) + return fail(500, { endpoint: 'uploadFile', error}) + } + }, + + deletePath: async ({ request, fetch }) => { + const formData = await request.formData() + const capKey = formData.get('capKey') + const encoded = encodeURIComponent(capKey) + const partialPath = formData.get('path') + const slash = partialPath.slice(0, 1) === '/' ? '' : '/' + const path = encoded + slash + partialPath + + if (partialPath.length === 0) { + return { success: false, endpoint: 'deletePath', error: 'Path cannot be empty.'} + } + + try { + await unlink(path) + + return { success: true, endpoint: 'deletePath' } + } catch (error) { + console.log({ error }) + return json({ success: false, code: 500, error }) } } } diff --git a/packages/src/routes/dashboard/+page.svelte b/packages/src/routes/dashboard/+page.svelte index 478e1e3..78a3799 100644 --- a/packages/src/routes/dashboard/+page.svelte +++ b/packages/src/routes/dashboard/+page.svelte @@ -1,16 +1,25 @@