diff --git a/README.md b/README.md
index e4a30ef..36d124c 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ wrangler publish
- Image thumbnail's using Cloudflare workers
- Tooltip when hovering a file with absolute time in "x days time ago" format
- Automatically load more files, when the bottom is reached (current limit is 1000 files)
+- bundle bootstrap icons instead of importing
## Known issues
diff --git a/packages/dashboard/src/api.js b/packages/dashboard/src/api.js
index 04338a8..63abd1c 100644
--- a/packages/dashboard/src/api.js
+++ b/packages/dashboard/src/api.js
@@ -51,7 +51,7 @@ const apiHandler = {
)
},
renameObject: (oldName, newName) => {
- return axios.post(`/api/buckets/${store.state.activeBucket}/rename`, {
+ return axios.post(`/api/buckets/${store.state.activeBucket}/move`, {
oldKey: encodeKey(oldName, store.state.currentFolder),
newKey: encodeKey(newName, store.state.currentFolder),
})
@@ -59,7 +59,10 @@ const apiHandler = {
multipartCreate: (file, folder) => {
return axios.post(`/api/buckets/${store.state.activeBucket}/multipart/create`, null, {
params: {
- key: encodeKey(file.name, folder)
+ key: encodeKey(file.name, folder),
+ httpMetadata: encodeKey(JSON.stringify({
+ contentType: file.type
+ }))
}
})
},
@@ -86,8 +89,16 @@ const apiHandler = {
},
uploadObjects: (file, folder, callback) => {
folder = folder || store.state.currentFolder
+ console.log(file)
+ console.log(file.type)
- return axios.post(`/api/buckets/${store.state.activeBucket}/upload?key=${encodeKey(file.name, folder)}`, file, {
+ return axios.post(`/api/buckets/${store.state.activeBucket}/upload`, file, {
+ params: {
+ key: encodeKey(file.name, folder),
+ httpMetadata: encodeKey(JSON.stringify({
+ contentType: file.type
+ }))
+ },
headers: {
'Content-Type': 'multipart/form-data',
},
@@ -97,11 +108,10 @@ const apiHandler = {
listObjects: async () => {
const prefix = getCurrentFolder()
- const response = await axios.get(`/api/buckets/${store.state.activeBucket}`, {
+ const response = await axios.get(`/api/buckets/${store.state.activeBucket}?include=customMetadata&include=httpMetadata`, {
params: {
delimiter: '/',
prefix: encodeKey(prefix),
- include: 'customMetadata'
}
})
diff --git a/packages/dashboard/src/components/FilePreview.vue b/packages/dashboard/src/components/FilePreview.vue
index eb8edb3..959cb52 100644
--- a/packages/dashboard/src/components/FilePreview.vue
+++ b/packages/dashboard/src/components/FilePreview.vue
@@ -44,6 +44,14 @@
+
+
+
+
+
+
+
+
diff --git a/packages/dashboard/src/components/email/EmailDetails.vue b/packages/dashboard/src/components/email/EmailDetails.vue
index 7aa4530..7433b27 100644
--- a/packages/dashboard/src/components/email/EmailDetails.vue
+++ b/packages/dashboard/src/components/email/EmailDetails.vue
@@ -96,8 +96,9 @@ export default {
for (const file of this.$store.state.files) {
if (file.hash === this.$route.params.file) {
apiHandler.downloadFile(file).then(response => {
+ const filename = file.key.split('.json')[0]
for (const att of response.data.attachments) {
- att.downloadUrl = `${self.$store.state.serverUrl}/api/buckets/${self.$store.state.activeBucket}/${btoa(unescape(encodeURIComponent(`${file.key}/${att.filename}`)))}`
+ att.downloadUrl = `${self.$store.state.serverUrl}/api/buckets/${self.$store.state.activeBucket}/${btoa(unescape(encodeURIComponent(`${filename}/${att.filename}`)))}`
}
self.file = response.data
})
diff --git a/packages/dashboard/src/components/email/EmailList.vue b/packages/dashboard/src/components/email/EmailList.vue
index 17c9dbe..4fea268 100644
--- a/packages/dashboard/src/components/email/EmailList.vue
+++ b/packages/dashboard/src/components/email/EmailList.vue
@@ -35,7 +35,7 @@
This bucket don't have any emails yet!
Learn how to setup the Email Explorer in the official documentation
-
https://r2explorer.dev
+
https://r2explorer.dev
@@ -70,7 +70,6 @@ export default {
this.$watch(
() => this.$route.params.folder,
(newFolder) => {
- console.log(newFolder)
if (this.$store.state.activeTab === 'email') {
this.$store.dispatch('refreshObjects')
}
diff --git a/packages/dashboard/src/main.js b/packages/dashboard/src/main.js
index 2015634..5bdebd6 100644
--- a/packages/dashboard/src/main.js
+++ b/packages/dashboard/src/main.js
@@ -18,7 +18,7 @@ require('bootstrap/js/dist/modal')
let url = window.location.origin
if (process.env.NODE_ENV === 'development') {
- axios.defaults.baseURL = 'https://my-r2-explorer.g4brym.workers.dev'
+ axios.defaults.baseURL = 'http://localhost:8787'
}
store.commit('setServerUrl', url)
diff --git a/packages/dashboard/src/preview.js b/packages/dashboard/src/preview.js
index bcb8cbd..41eff8c 100644
--- a/packages/dashboard/src/preview.js
+++ b/packages/dashboard/src/preview.js
@@ -33,6 +33,16 @@ const PreviewConfigs = [
extensions: ['csv'],
type: 'csv',
downloadType: 'text'
+ },
+ {
+ extensions: ['json'],
+ type: 'json',
+ downloadType: 'text'
+ },
+ {
+ extensions: ['html'],
+ type: 'html',
+ downloadType: 'text'
}
]
diff --git a/packages/dashboard/src/store/index.js b/packages/dashboard/src/store/index.js
index d692d36..196d881 100644
--- a/packages/dashboard/src/store/index.js
+++ b/packages/dashboard/src/store/index.js
@@ -60,10 +60,7 @@ export default createStore({
}
},
loadServerConfigs (state, data) {
- state.user = {
- username: "test@example.com"
- }
- // state.user = data.user
+ state.user = data.user
state.config = data.config
state.serverVersion = data.version
},
diff --git a/worker/src/buckets/api/renameObject.ts b/worker/src/buckets/api/moveObject.ts
similarity index 85%
rename from worker/src/buckets/api/renameObject.ts
rename to worker/src/buckets/api/moveObject.ts
index 6dfdd34..a419185 100644
--- a/worker/src/buckets/api/renameObject.ts
+++ b/worker/src/buckets/api/moveObject.ts
@@ -3,11 +3,11 @@ import {Context} from "../../interfaces";
import {OpenAPIRouteSchema} from "@cloudflare/itty-router-openapi/dist/src/types";
import {z} from "zod";
-export class RenameObject extends OpenAPIRoute {
+export class MoveObject extends OpenAPIRoute {
static schema: OpenAPIRouteSchema = {
- operationId: 'post-bucket-rename-object',
+ operationId: 'post-bucket-move-object',
tags: ['Buckets'],
- summary: 'Rename object',
+ summary: 'Move object',
parameters: {
bucket: Path(String),
},
@@ -30,7 +30,7 @@ export class RenameObject extends OpenAPIRoute {
const newKey = decodeURIComponent(escape(atob(data.body.newKey)))
const object = await bucket.get(oldKey)
- const resp = await bucket.put(newKey, object.body, {customMetadata: object.customMetadata})
+ const resp = await bucket.put(newKey, object.body, {customMetadata: object.customMetadata, httpMetadata: object.httpMetadata})
await bucket.delete(oldKey)
diff --git a/worker/src/buckets/api/multipart/createUpload.ts b/worker/src/buckets/api/multipart/createUpload.ts
index bd97f2a..8be9476 100644
--- a/worker/src/buckets/api/multipart/createUpload.ts
+++ b/worker/src/buckets/api/multipart/createUpload.ts
@@ -12,6 +12,7 @@ export class CreateUpload extends OpenAPIRoute {
bucket: Path(String),
key: Query(z.string().optional().describe('base64 encoded file key')),
customMetadata: Query(z.string().optional().describe('base64 encoded json string')),
+ httpMetadata: Query(z.string().optional().describe('base64 encoded json string')),
}
}
@@ -26,12 +27,18 @@ export class CreateUpload extends OpenAPIRoute {
const bucket = env[data.params.bucket]
const key = decodeURIComponent(escape(atob(data.query.key)))
+
let customMetadata = undefined
if (data.query.customMetadata) {
- customMetadata = decodeURIComponent(escape(atob(data.query.key)))
+ customMetadata = JSON.parse(decodeURIComponent(escape(atob(data.query.customMetadata))))
}
- const multipartUpload = await bucket.createMultipartUpload(key, {customMetadata: customMetadata});
+ let httpMetadata = undefined
+ if (data.query.httpMetadata) {
+ httpMetadata = JSON.parse(decodeURIComponent(escape(atob(data.query.httpMetadata))))
+ }
+
+ const multipartUpload = await bucket.createMultipartUpload(key, {customMetadata: customMetadata, httpMetadata: httpMetadata});
return {
uploadId: multipartUpload.uploadId,
diff --git a/worker/src/buckets/api/putObject.ts b/worker/src/buckets/api/putObject.ts
index 93d72a2..96775ea 100644
--- a/worker/src/buckets/api/putObject.ts
+++ b/worker/src/buckets/api/putObject.ts
@@ -12,6 +12,7 @@ export class PutObject extends OpenAPIRoute {
bucket: Path(String),
key: Query(z.string().optional().describe('base64 encoded file key')),
customMetadata: Query(z.string().optional().describe('base64 encoded json string')),
+ httpMetadata: Query(z.string().optional().describe('base64 encoded json string')),
},
}
@@ -26,11 +27,17 @@ export class PutObject extends OpenAPIRoute {
const bucket = env[data.params.bucket]
let key = decodeURIComponent(escape(atob(data.query.key)))
+
let customMetadata = undefined
if (data.query.customMetadata) {
- customMetadata = decodeURIComponent(escape(atob(data.query.key)))
+ customMetadata = JSON.parse(decodeURIComponent(escape(atob(data.query.customMetadata))))
}
- return await bucket.put(key, request.body, {customMetadata: customMetadata})
+ let httpMetadata = undefined
+ if (data.query.httpMetadata) {
+ httpMetadata = JSON.parse(decodeURIComponent(escape(atob(data.query.httpMetadata))))
+ }
+
+ return await bucket.put(key, request.body, {customMetadata: customMetadata, httpMetadata: httpMetadata})
}
}
diff --git a/worker/src/buckets/router.ts b/worker/src/buckets/router.ts
index 2ea9b9c..179a7cf 100644
--- a/worker/src/buckets/router.ts
+++ b/worker/src/buckets/router.ts
@@ -1,7 +1,7 @@
import {config} from "../settings";
import {ListBuckets} from "./api/listBuckets";
import {ListObjects} from "./api/listObjects";
-import {RenameObject} from "./api/renameObject";
+import {MoveObject} from "./api/moveObject";
import {CreateFolder} from "./api/createFolder";
import {PutObject} from "./api/putObject";
import {DeleteObject} from "./api/deleteObject";
@@ -22,7 +22,7 @@ export const bucketsRouter = OpenAPIRouter({
bucketsRouter.get('', ListBuckets)
bucketsRouter.get('/:bucket', ListObjects)
-bucketsRouter.post('/:bucket/rename', RenameObject)
+bucketsRouter.post('/:bucket/move', MoveObject)
bucketsRouter.post('/:bucket/folder', CreateFolder)
bucketsRouter.post('/:bucket/upload', PutObject)
bucketsRouter.post('/:bucket/multipart/create', CreateUpload)
diff --git a/worker/src/dashbord.ts b/worker/src/dashbord.ts
index ef4dc23..bc4e7b1 100644
--- a/worker/src/dashbord.ts
+++ b/worker/src/dashbord.ts
@@ -1,4 +1,6 @@
-export async function dashboardProxy(request: any, env: any, context: any) {
+import {Context} from "./interfaces";
+
+export async function dashboardProxy(request: any, env: any, context: Context) {
// Initialize the default cache
//@ts-ignore
const cache = caches.default
@@ -10,10 +12,14 @@ export async function dashboardProxy(request: any, env: any, context: any) {
path = "/"
}
- // use .match() to see if we have a cache hit, if so return the caches response early
- let result = await cache.match(request)
- if (result) {
- return result
+ let result
+
+ if (context.config.cacheAssets !== false) {
+ // use .match() to see if we have a cache hit, if so return the caches response early
+ result = await cache.match(request)
+ if (result) {
+ return result
+ }
}
let dashboardUrl = 'https://demo.r2explorer.dev'
@@ -41,7 +47,7 @@ export async function dashboardProxy(request: any, env: any, context: any) {
},
})
- if (response.status !== 200) {
+ if (response.status === 200 && context.config.cacheAssets !== false) {
// before returning the response we put a clone of our response object into the cache so it can be resolved later
context.executionContext.waitUntil(cache.put(request, result.clone()))
}
diff --git a/worker/src/interfaces.ts b/worker/src/interfaces.ts
index 1f75439..e3d230f 100644
--- a/worker/src/interfaces.ts
+++ b/worker/src/interfaces.ts
@@ -12,6 +12,7 @@ export interface R2ExplorerConfig {
targetBucket: string
},
showHiddenFiles?: string
+ cacheAssets?: boolean
// basicAuth?: BasicAuth | BasicAuth[] // TODO
}